What if two chains disagree?
Consensus is how many computers that do not trust each other agree on one history. A fork is when two valid chains both continue from the same block.
Forks happen by accident, so every chain needs a rule for choosing between them. The rule here is to follow the valid chain with the most work.
By the end of this lesson
Note
I can choose the valid chain with the most work from several chains.
Key words
| Word | What it means |
|---|---|
| Fork | two chains that share blocks and then differ |
| Consensus | agreement on one history |
| Work | the total mining effort stored in a chain |
| Valid chain | a chain whose every check passes |
| Dropped block | a block on a chain that was not followed |
The cells students fill in are left blank in this preview.
Two blocks can be found at once
Nobody is in charge of the chain. Two computers can each mine a block that follows block 1, at about the same moment. Both blocks are valid.
Now the network holds two chains. They share blocks 0 and 1 and differ after that. Each computer sees one of them first.
Build two chains and compare them
docker exec jupyter python3 steps/fork.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Worked example: what the lab printed
| Chain | Blocks | Difficulty | Work | Valid |
|---|---|---|---|---|
| A | 3 | 2 | 768 | Yes |
| B | 4 | 2 | 1,024 | Yes |
The cells students fill in are left blank in this preview.
Follow the valid chain with the most work
The rule has two steps. First, throw away any chain that fails a check. A long chain that was tampered with is worth nothing.
Second, among valid chains, follow the one with the most work. At one difficulty, work is the number of blocks times 16 for each zero. Everybody who applies the rule to the same chains makes the same choice.
Try it: compare the work of two chains
chains = [
{"name": "A", "blocks": 5, "difficulty": 2},
{"name": "B", "blocks": 3, "difficulty": 3},
]
best = None
best_work = 0
for chain in chains:
work = chain["blocks"] * 16 ** chain["difficulty"]
print(chain["name"], "work:", work)
if work > best_work:
best = chain["name"]
best_work = work
print("follow chain", best)
# Change B to 2 blocks at difficulty 2 and run again.
A common mistake
Warning
Many people think the longest chain always wins. A chain wins by work, and only if it is valid. Three blocks at a higher difficulty can hold more work than five at a lower one. A chain with a changed block loses however long it is.
The losing chain's blocks are dropped
Once a computer follows chain B, the extra block on chain A is dropped. Its payments go back to waiting, so they may appear in a later block, or not at all.
This is why one block on top is not final. A payment is safer once more blocks sit above it, because redoing them would cost more work.