Theory: How to side-step soft-consensus

in #steem4 years ago

I believe both 0.22.2 could, and 0.22.888(8) can, be side-stepped given the right shuffle round formation. Let's assume we have two subsequence rounds, first A, then B:

Shuffle Round AShuffle Round B
1jayplay.witnesscryptoking777
2matreshkasteemhunt
3bukiohoasen
4rlawlstn123zzan.witnesses
5triple.aaafuture.witness
6justyymaiyude
7steemhuntbukio
8parserlawlstn123
9ocd-witnesssegye.witness
10menacamelsteem-dragon
11segye.witnessmatreshka
12dev.supportersklye
13skuld2000.witparse
14zzan.witnessesdev.supporters
15maiyudetriple.aaa
16future.witnessjustyy
17hoasenindo.witness
18indo.witnessskuld2000.wit
19hinomaru-jpmenacamel
20steem-dragonjayplay.witness
21cryptoking777hinomaru-jp

Let's also assume that the block signed by witness A-21 (cryptoking777) and B-1 (cryptoking777), is not applying the softfork logic.

They need not be the same witness, but in this example they are. This means that a transaction containing a censored operation would be accepted by two distinct rounds, and thus irreversible.

This means, in order to find this kind of shuffle formation, someone who wants to side-step the majority softfork logic only needs to broadcast the desired operation roughly every 126 seconds (two 63 second rounds).

If A-21 accepts the transaction, they return a trx_id. The broadcaster keeps track of this trx_id and checks after the next round if it becomes irreversible. And it would become irreversible if B-1 produces a block that agrees with A-21.

In a nutshell: Do one broadcast in one round then check if the transaction persists the next round. Repeat. Eventually, you might find the correct pair of sequential shuffle rounds.

Questions:

Was this possible in 0.22.2?

Yes. I believe this was possible in both softforks. There's no fundamental difference between them, other than the list of accounts.

Does this mean the exchanges weren't needed to overpower 0.22.2?

I believe so.

Why didn't you post about this back in 0.22.2?

In that scenario, only Steemit, Inc. was affected by this, so it wasn't potentially a widespread issue that warranted a post. I was already in hot water for my opinions. I wasn't about to "take their side" on this over a theory.

I also did talk about this openly, off-chain, if it came up. It never came up between me and anyone at remaining at Steemit, inc.

Is it possible to verify the code against the version being signaled?

No. A witness can report a version that they do not run depending on their skill or access to someone with the required skill.

Sort:  

Ok I am doing some phone math with me so bare with me. Let’s say only 1 witness is running this code.

There is a 1/21 chance they are in the last position and a 1/21 chance they are in the first position in the next round. 1/21 * 1/21 = 0.00226757 probability of this happening.

123 second per 2 complete rounds / 0.00226757 = 54243 second before this occurs = 15.068 hours.

So we could expect this transaction to go through in less than one day. Interesting. This would obviously be faster if more than 1 witness are running this code.

Also, if you're ok with the possibility of more than one transaction getting accepted, you can shorten the wait to 66 seconds, if it's well-timed so that the transaction is broadcasted in the final block of the round.

The problem with doing this is if you're doing transfers, there's a chance that while one transfer is being reversed, and you move on to the next round attempt, both are accepted.

So 126 is good for attempting one-and-only-one transaction. Otherwise 66 is good, but slightly risky. And blindly spamming is probably also fine, but overkill, and not much more risky.

This makes me think it might be possible to predict a beneficial shuffle formation:

https://steemit.com/steem/@dantheman/steem-witness-scheduling-algorithm

Especially this point:

After 21 witnesses have been selected, they are shuffled using the block time as a seed to a random number generator.

Yes that would be a major improvement. So you think it might be possible that if a libre witness is randomly assigned to spot 21 of 21, they could create a block that makes the below-20 witness mine first in the subsequent block?

Is there any protection to the other top 20 witnesses pretending the libre witness was offline and discarding those blocks?

Is there any protection to the other top 20 witnesses pretending the libre witness was offline and discarding those blocks?

I believe they are already "protected" otherwise that would cause a fork.

Oh wow. Great find. I can’t believe you were able to dig that up.

Check it out:

https://steemd.com/b/42329700
https://steemd.com/b/42329701

Two sequential blocks from backup witnesses. How could this happen unless the were from two different shuffle rounds?

Problem is, the first block did not contain censored ops, so this opportunity was wasted.

It would have to be two different rounds I would think. For a given block, is there a way to know which spot in a round it is?

I was thinking about this some more. You would want to submit the operation on the last block of the round, but you would first need to know when that is, otherwise your timing would be off. Correct?

So this means that there is still benefit to voting for community witnesses on Steem, since that increases the chance of this type of repetition approach to work.

Yes, that's a good point.

Is there a good guide to how Steem consensus and witness shuffling / selection works?

Found Steem Witness Scheduling Algorithm by @dantheman. Not sure what has changed in the last 4 years since PoW mining was removed.

So did @dantheman foresee this when picking the one from the non-top-20 witnesses?

Soft consensus is not intended to be as air-tight as hard consensus. So it's not surprising this is possible. I believe the fact that it is possible means that DPoS is not as broken as people say it is.

Meaning: Steem is censorship resistant. Soft consensus censorship is not absolute censorship.

Also a merged pull request from 2016 titled New witness scheduling algorithm. By @arhag

This would be technically challenging to pull off, but I am guessing if there are widespread seizures, someone will implement a user-friendly implementation.

Is the last witness of a round, always a non top 20 witness? Or is it random?

It's random.

Do you need some custom Json to do this? I'm not a dev, so really don't know how to make this happen. Seems like some folks have a need though, so I hope they can figger it out.

No, but they do need some kind of automation to be efficient. I fully expect the ones effected to figure it out, if necessary. They know the platform better than anyone.

Well, I doubt anyone will go to the time and trouble to add my little account to the list of evil hackers. If they do I'll try to figger this out too.

I wouldn't be surprised if Justin added everyone to the list who has posted to hive at this point.

Just noding my head like the technicality of the post did not just scramble my brain.

Definitely need to learn more of how blockchains work on the backend.

Hmmmm. Correct me if I am wrong, but this seems like a pretty big issue? If just a few witnesses are running rogue code, can they permit all kinds of transactions if statistically they wait for themselves to witness back to back blocks?

This would only work for letting an otherwise valid transaction through when the majority of the top 20 witnesses are blocking it via a soft fork. If the transaction violated any "hard fork" rules it would not be accepted regardless of the round shuffling.

Correct. In fact, when HF17 introduced eternal content edit, it became possible to use this technique to edit posts. The hardfork allowed it, but no witness ran code to allow it.

By HF19, some witnesses did allow it, but it was still random if it would persist to irreversibility.

I tested it before the UI allowed it and sometimes I could get an edit irreversible. So that's one reason I think this would work now.