Consensus Critical Voting Considerations

Apr 9, 2016

Weekly Dev Report

Attended the Blockchain Workshops NYC
and spoke rather briefly about Bitcoin… If you were there I think you might
agree with me that allowing people to present slides at the beginning of a
“panel” wasn’t a good idea.

Consensus Critical Voting Considerations

Blacklisting — Coins could be blacklisted based on them voting the “wrong”
way.

Implementation Complexity — How much new code is needed, both to vote, and
count the votes?

Efficiency — Both in terms of block-chain space, and network bandwidth.

Secondly, implementations are being discussed, which I think roughly fall into
two main categories:

Per-Transaction

It’s technically quite simple to make every transaction a vote, e.g. by using
bits in the per-txin nSequence field, or with extra transaction data (something
segwit may allow in the future); nSequence is by far the simplest for both
consensus code and wallets to implement.

However, this has both privacy and blacklisting downsides. The best we can do
given the current state of crypto (no ZK-SNARKS) is randomly sample votes. In
this method, the default behavior would be for txouts to be non-voting when
spent unless H(txout:n + blkhash) < target. In English, we’d be using the block
hash of the block containing the txout as a random number generator, with only
a random subset of txouts - say 1% or 10% - being counted. This means that if
you’re spending a txout, most of the time you don’t vote at all - leaving the
voting field empty. The subset of times when you can vote do count, but linking
together coins based on consistent voting patterns becomes harder. A big
disadvantage of this from a social point of view is likely to be variance - if
you are making transactions relatively infrequently, you might get unlucky and
have very few opportunities to vote. It’d be nice to make the variance
adjustable, but as txouts may be created by someone other than the user who
wants to vote (when they’re not change) implementing that becomes very complex
quite quickly (you’d have to make the variance setting part of the
scriptPubKey, yuck).

It’s not clear how much this would discourage blacklisting, as votes are still
publicly visible. On the other hand, if blacklisting is your threat model,
we’ve probably got bigger things to worry about right now.

Message Based

Here we’re talking about schemes where transactions themselves aren’t the
vehicle for voting. Non-consensus coin voting already exists of course, in
the form of sites like Bitcoinocracy; they work by
having coin owners sign messages with their scriptPubKeys indicating their
vote.

Unlike per-transaction votes, because these messages aren’t valid transactions,
they can be signed with keys that can’t be used to spend the coins. For
example, consider the following scriptPubKey:

Due to the CLTV in the second branch of the IF statement, vote-pubkey can only
be used to sign transactions with nLockTime set to block height 499,999 - about
4,000 years into the future. Thus the voting pubkey can only be used to sign
voting messages, not valid transactions. Equally, Johnson Lau suggested that
one of the invalid opcodes could be used as well, which usefully generalizes to
all kinds of message signing:

For example, you could imagine a Bitcoin exchange making use of this technique
to keep the keys used for actually spending coins in cold storage, which still
allowing solvency-audit-related messages to be signed on a more frequent basis
(obviously, this may reduce the value of the solvency audit in some cases!).

However, is this relevant to consensus voting? For the vote to be actually
enforced by consensus, the vote must be recorded in the block-chain itself; if
it’s not recorded in the block-chain full nodes have no way of knowing if they
have a full copy of all relevant votes. We also want a vote that’s weighted by
something meaningful, like coin days destroyed; signing a message is free.
However, this means we have a double-spend problem: we only want a given output
to be allowed to vote once.

We’re not doing an message-based votes for bandwidth reasons: nSequence voting
takes no extra space in transactions directly, and if extra transactions being
made to vote is your concern, it’s easy to reduce that impact greatly with the
probabilistic sampling technique mentioned above.

I also don’t think privacy is a good argument for off-chain techniques: without
moon-math like ZK-SNARKs, the best we can do is again probabilistic sampling,
and that technique is relevant regardless of how the votes are cast.

Blacklisting concerns are a reasonable reason for off-chain voting: by
separating voting from spending coins we can vote well after spending, makes
blacklisting harder to accomplish. But this means we can’t just add a new “has
voted” flag to the UTXO set - we’re counting votes for UTXO’s that don’t exist
anymore. Keeping a index of txouts that have voted is also completely
untenable. Our only option is to set a delay where votes are only allowed to be
counted in blocks X blocks after being spent, and that delay itself sets
requirements on how soon we can prune blocks (for a reasonable implementation).

That’s not to mention all the other issues like the need for new P2P messages
to pass votes around; wallets need to store votes, broadcasting them later;
blocks need a new way of committing to votes; sybil attack on the network can
now censor votes; etc.

My Opinion

I think our only reasonable option in the near future for consensus-enforced
voting is the per-transaction, nSequence-based scheme, preferably using
probabilistic sampling for privacy. It’d also be a reasonable idea to do a
pre-deployment “trial run” to gage interest by designing a voting
specification, and inviting holders to create transactions that cast votes (the
IsStandard() rules currently say nothing about nSequence).

I wish there was a way to solve the blacklisting issue right now, but let’s
look at it from another perspective: if blacklisting was effective right now,
what would that say about Bitcoin? I don’t believe we’d see the big exchanges
and merchants blacklisting coins based on block-size votes - the PR impact would
be horrible, and it’d just drive business to more reasonable, anti-censorship,
alternatives (we’re not even talking about illegal activity after all).

Now suppose miners tried to blacklist transactions. If only a few % of miners
do it, it’s ineffective. On the other hand, if a significant % of miners are
blacklisting transactions - say >30% - we’re already at the point where those
miners are proving that Bitcoin is insecure due to mining centralization: those
same miners could just as easily conspire to drive their competitors - possibly
competitors with different opinions on the block-size debate - out of business
via selfish mining. Do miners really want to risk the negative PR impact, and
thus price impact, of proving to the world that Bitcoin is too centralized to
be secure?