2

I'm newbie studying blockchain and Ethereum. While I'm studying, I've got a question.

What will happen in the case of conflict of two different states on smart contract, e.g. from the network partitioning attack such as eclipse?

From the network partitioning attack, the Ethereum network will be separated into two groups, and the states of smart contract would be proceeded into two different states. And I wonder, after the end of attack, to make consensus, what will happen to resolve the conflict in Ethereum?

1 Answer 1

6

People have been explaining this since Bitcoin emerged on the scene but it's a little difficult to grasp at first and usually takes a few explanations from a few angles, so I'll try for an overview that zeros in on your specific question.

Bear with me as I layer a few concepts.

Blockchain consensus is mainly concerned with reaching an agreement about the order of approximately simultaneous transactions by a decentralized method, without reference to external clocks or other centralized actors. The problem is that transactions broadcast across a network arrive at the nodes in a slightly different order due to network latency. The challenge is unavoidable because we can't make everything faster than everything else. The real-time order of discovery is subjective to each node.

We can't use time-stamps because that would require a centralized source of authority about the "correct" time. In a Proof-of-Work system like Ethereum, a miner wins the privilege, for a short period of time, of deciding the canonical order of transactions and which transaction "made it" into a block. It is costly and difficult to acquire this privilege and especially costly and difficult to hold on to the privilege for a long period of time, by design. That helps mitigate possible abuse of the privilege, e.g. censorship - unreasonably blocking transactions to/from someone the miner doesn't like.

The transactions themselves are always deterministic. That is, given the same initial conditions and the same inputs, the result is always the same. That means the "state" of the accounts and the contracts can be computed from the sequence of transactions going all the way back to the beginning. Nothing ever happens that isn't a transaction, so all the nodes can work out the state themselves by replaying all the transactions in the correct order. That's what's happening when a node syncs (setting aside fast-sync and other shortcuts).

The conditions you describe are routine occurrences at the head of the chain. A miner can find a nonce that works for a block without knowledge that another miner already did. The blocks from two miners will be broadcast (gossip) across the network, and they will have two different ideas. It might be the same transactions in a different order or different transactions. In any case, the two states will be divergent.

I think it's important to understand that both states are "valid" because if one was invalid the nodes would just reject it. So, in all cases of divergence, each is a valid interpretation of the pending transactions, a mined block, and so on. Indeed, miners will get to work mining on both chains. This situation is resolved by the longest chain rule. When a node hears about two chains, they usually follow the longest chain. They "usually" do because they know everyone else will. I don't say "always" because no one controls what the other nodes do.

Such divergence isn't necessarily resolved right away but eventually, one chain will be longer than the other, the miners will start following it, the nodes will hear about the longer chain (highest block number) and see that it is valid.

For some nodes, that means reorganization. They have to discard old ideas about certain blocks, accept the canonical blocks, and recompute what happened. This is the only way they come into consensus with the majority of the network, which is what they want.

You don't have to do anything special inside your contract to deal with this. The blockchain and the contract are always internally consistent. There is a history of inputs and a set of results that must arise from those inputs because it's the only correct interpretation of history. Internally, if the contract receives something and sends something and then the history is revised and the transaction isn't mined yet (in the revised history), nothing is misplaced because nothing happened.

From an external point of view, history and the state are subject to change, so it's important to wait for confirmations. The probability of a possible reorganization diminishes exponentially with each block mined. So, if you're in the off-chain world and thinking about trading cash for ether, or something the contract indicated, it's best to wait for a few blocks to stack up so you can see if the contract still says you were paid.

In the scenario you described, it would be a large-scale reorganization. The on-chain state, including the contracts, would be internally consistent, but not necessarily what the minority of nodes thought it was. Although this may sound a little dire, there is a possibility that transactions would not be lost.

In the routine forks, nodes everywhere know about most of the pending transactions (subject to propagation latency). When two miners find the same block, they may select different transactions or order the transactions differently but the pending transactions are not lost if a block is rejected - provided everyone still knows about them so miners can include them in a later block.

If the break went on for an extended period of time, then members of both networks would assume the transactions were mined (they've seen them in the blocks) and discard them from the pending pool. When the networks come back together, there would be loss of transactions. It would be like they never happened.

Such a situation would cause a lot of inconvenience to external systems that thought they were synchronized and didn't anticipate that such a large-scale reorganization is possible. If one is doing very serious things, it is advisable to anticipate the possibility and create an automated response, in advance. Nodes can receive "cancelled" events that indicate a previously-reported event did not, in fact, happen because of reorganization. This is a gimme and you don't have to deal with in your contract code. If your contract seemed to emit an event, perchance for a server or client to do something, the node will include a corresponding "cancelled" event if/when a reorganization makes the earlier emission invalid. Of course, the listener needs to know what to do.

Hope it helps.

1
  • 1
    Thank you for your detail and kindful answer. It's a really big help for me :)
    – Ilak
    Commented Aug 12, 2020 at 5:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.