What verify was never asked to do
Read the signature of the function. CHAIN.verify(chain) takes one chain. It recomputes every hash and checks every link inside that one chain, and it reports where the first failure is. There is no second argument, and there was never going to be one, because nothing inside a single chain contains information about any other chain. Tonight makes that limitation visible by running into it deliberately.
★ What you walk out with tonight. Two branches on screen, both verifying clean, and the sentence that goes with them: validity is local and does not choose between histories. The selection rule described as a machine would evaluate it, with judgement removed on purpose. Depth measured live, as blocks that would have to be redone. And one honest blank where a number would normally go.
Self-studyThe words that will keep coming back4 min▶
- Branch. One of two or more continuations of the same shared history. Each is a complete chain in its own right.
- Local validity. What
verify()tests. Internal consistency of one chain, with no view of any other. - Selection rule. The test each holder applies to decide which branch is the accepted one. Takes the branches and nothing else.
- Accepted history. The branch the rule currently selects. A status a chain has, not a property inside it.
- Reorganisation. The accepted history changing from one branch to another. Entries leave; none of them becomes invalid.
- Depth. How many blocks sit after an entry. The only quantity that changes as an entry ages.
- Blocks to redo. Depth plus the block itself. Deterministic, countable, and measured live in part 4.
- Finality. How settled an entry is. A quantity that strengthens with depth, and never a message that arrives.
Both branches verify. Read the output.
12 min liveThe shared trunk is blocks 0 to 3 of the register you have been reading since session 1, up to and including consignment 42 signed over to Ardwick Cold Store. From there the port authority and the buyer each continue with entries of their own. Both continuations are built with makeChain and checked with verify, in this page, and both are clean.
...
...
LiveNothing in a block points sideways4 min▶
A block records its position, its timestamp, its entry, the hash of the block below it and its nonce. Five fields, all of them looking down or inward. There is no field that names a competitor, no field that records how many other holders agreed, and no field that says this is the real one.
So the information needed to choose between branches does not exist inside either branch. It has to be manufactured by a rule applied from outside, over both of them at once, and that is a strictly separate piece of machinery from everything built in sessions 1 to 7.
LivePress both buttons in turn and watch nothing break3 min▶
Extend branch A three times and branch B once. Both still verify. Extend B four times so it overtakes A. Both still verify. There is no combination of presses that produces a problem from verify, because nothing either branch does is capable of making the other one inconsistent.
That is worth noticing as a practitioner rather than nodding at as a concept. Any monitoring built on verification alone will be silent through every reorganisation your system ever has.
Self-studyWhy the trunk blocks are byte identical3 min▶
Both branches are built from the same first four entries with the same fixed timestamps, so blocks 0 to 3 hash to the same four values in both, down to the last character. That is what makes the picture a fork rather than two unrelated registers: the branches share a prefix exactly, and diverge at a known index.
It also means the cost of abandoning a branch is bounded by where the split is, not by the length of the register. A holder switching branches keeps everything below the split and discards only what is above it.
A rule a machine can evaluate, and what it throws away
13 min liveEvery holder has to reach the same answer alone, from the branches in front of them, with nobody to ask. That constraint is what determines the shape of the rule before anybody decides what the rule should say. Work out what a function is allowed to take as input, and most of the candidate rules disappear.
Applying the rule has a consequence that is easy to state and genuinely unsettling once you sit with it. The entries in the branch that loses are not rejected, not flagged, and not invalid. They simply stop being in the history everybody is using.
LiveWhat longest chain actually computes4 min▶
Strip the phrase back to the arithmetic. For each branch, total the work accumulated in its blocks. Take the larger total. If the totals tie, keep whichever you already had and wait. That is a function of two arrays, it returns the same answer on every machine, and it needs no clock, no network poll and no opinion.
Stated over a raw count of blocks instead, the same function is inflatable wherever blocks are cheap to produce, which is why the work version is the one that survives. Session 4 is why a block is expensive and this session is what that expense is spent on.
LiveWrite the read-then-act rule before you need it3 min▶
A process that reads the register and does something physical has a decision to make that most such processes have never made explicitly: how deep an entry must be before it acts. The default, which is act on sight, is a choice too, and it is the one with the reorganisation risk fully accepted and nobody informed.
Make the depth different for different actions. Recording that somebody looked at a consignment and releasing that consignment from a cold store are not the same class of decision, and one of them cannot be undone by a later entry.
Self-studyWhere the disagreement really is4 min▶
Suppose a branch wins the rule cleanly and everybody can see it was produced to displace a particular entry. One camp says the rule stands, and that this is not a hard case but the defining one. A rule that is followed except when the outcome is disliked was never a rule; it was a preference with extra steps, and the first time it is overridden every holder learns that somebody can override it, which is the property the whole arrangement exists to avoid. The cost of honouring the rule in a bad case is the price of it meaning anything in the ordinary ones.
The other camp says that treating the rule as the product rather than as a means is a category error. The rule exists to produce a usable shared history, and when it plainly fails to, the holders are entitled to coordinate and say so. Every real system has an intervention path, formal or otherwise, and pretending otherwise does not remove it, it just leaves it undocumented and available to whoever is best organised on the day.
Both positions are held by people who have operated these systems. They agree entirely on the mechanics and disagree about what a rule is for, and the answer decides whether your operating procedure has an escalation path in it or deliberately does not.
Finality, measured as blocks to redo
9 min liveSession 5 counted this for one case: an edit at block 2 of the six block register forces blocks 2, 3, 4 and 5 to be redone, which is four blocks. The general shape is the same count for every position, and it is not the random part. Displacing an entry means producing a branch that wins the rule, and the deeper the entry sits, the more blocks that branch has to contain.
The count is one half. The other half is what those blocks cost, and session 4 established the only honest way to state that: a mean across many independent blocks, with the trial count beside it. At difficulty 2 the measured mean was 277 attempts per block over 300 trials, against an expected 256, with a range from 1 to 2,147. The box below runs the whole thing for each position, over independent variants rather than repeats of the same draw.
...
LiveWhy the rows are variants and not repeats4 min▶
reforge is deterministic. Give it the same chain, the same index and the same difficulty and it searches the same nonces in the same order and returns the same number, every time. Running it twelve times on one register measures nothing and would look exactly like a careful bench.
So each of the twelve runs in a row uses a different register: the entries carry a distinct run marker, which changes every block hash and therefore every search. Twelve independent draws, one mean, and the trial count printed beside it, because session 4 showed what a single draw is worth.
LiveRead the spread, not just the mean3 min▶
The minimum and maximum printed on each row will be far apart, and at twelve trials the mean itself moves noticeably between presses. That is the honest picture. Press the button three times and watch the same row report three different means.
Anybody quoting you a single figure for the cost of displacing an entry is quoting one draw from a distribution with a long tail. The count of blocks is the part you can rely on.
Self-studyDepth in a register that keeps growing3 min▶
Six blocks makes the table readable and understates the effect. In a register that gains entries continuously, the blocks-to-redo figure for any given entry increases on its own, without anybody doing anything, simply because entries keep arriving on top of it.
That is the mechanism behind every confirmation count anybody has ever quoted at you. The number itself is a risk appetite dressed as a technical fact, and two organisations reading the same register can reasonably pick different ones for different actions.
The number that is not on this page
6 min liveEverything measured in these sessions prices one machine working alone. Every mean, every spread, every blocks-to-redo count comes from one browser searching for nonces with nobody competing. There is a case that changes the problem qualitatively, and the honest thing to do with it is describe the mechanism and then stop.
LiveWhy it is a different problem and not a bigger one4 min▶
The depth argument works because an attacker redoing old blocks is racing everybody else, who are adding new ones. Falling behind is the normal outcome and the gap widens, which is what makes depth mean anything at all.
Give one party more capacity than the rest combined and the race reverses. They are not trying to catch a gap that grows; they are closing one that shrinks. The quantity that made depth protective is gone, and what remains is a question about capacity rather than about arithmetic. That is a qualitative change, not a larger number in the same table.
LiveWhat to say when somebody asks for the number3 min▶
Say that nothing measured here bounds it, and that you are not going to supply a figure you have not measured. It is an unsatisfying answer and it is the only defensible one from this material.
Then move the conversation to what can be answered: who holds the copies, whether their interests differ, and what your process does if an entry it acted on leaves the accepted history. Those are answerable at Harbourgate, tonight, with names in them.
Build both, verify both, then count
13 min hands onConsole open on this page. The first four lines are the whole argument of the session, and they take about ten seconds.
Verify both and say the sentence
Both return true. Say out loud what that means and what it does not: each chain is internally consistent, and neither result is an opinion about the other. If the sentence needs the word invalid anywhere, rewrite it.
Confirm the split point
Compare block 3 across the two branches, then block 4. The first matches exactly and the second does not. Name the index where the histories diverge without looking at the entries.
Extend one branch and apply the rule by hand
Add a second entry to B so it is longer. State which branch the rule selects and which entry has just left the accepted history. Then say whether anything about that entry changed, and answer honestly.
Count blocks to redo for every position
Without running anything, write the blocks-to-redo figure for an entry at each index of a six block register. Then check it against the table above. The count is arithmetic and you should get it right on paper.
Run reforge twice and compare
Run the last console line, then run it again with one word changed in one of the trunk entries. Two different totals for the same amount of work. Write down why quoting either as the cost would be wrong.
Write your depth rule
Pick one action your organisation takes on the strength of a record. Choose the depth required before acting, write the sentence, and add what you are accepting by choosing that number rather than a larger one. Keep it for session 10.
The habit to keep. When somebody shows you a verification result as evidence that a history is the right one, ask how many chains the function took as arguments. One chain in means the answer is about internal consistency, and the question you asked was about something else entirely.
Three questions
Two branches of the same register are built and verify() returns ok on both. What has verification decided?
Validity is local. The function has one argument and every field it inspects looks down or inward, so the information needed to choose between branches is not present in either of them. Choosing is a separate rule applied from outside over both at once.
An entry was in the accepted history this morning and is not in it this afternoon. What happened to it?
Invalid and absent are different words. A rejected entry fails arithmetic, is reported with an index, and stays wrong. An entry that leaves the accepted history is still correctly hashed, still correctly linked and still signed, and its departure raises no alarm anywhere, which is what makes it the more unsettling of the two.
Somebody asks how much protection depth gives against a party with more capacity than everyone else combined. What can be answered from the material measured here?
Depth is protective because an attacker redoing old blocks falls behind holders adding new ones. Reverse the capacity and the race reverses with it, which is a different problem rather than a larger number in the same table. The figures on these pages come from one browser with no competitor, so quoting them as a bound would be quoting the wrong measurement.
Homework
Twenty five minutes, on a process that already reads a record and then does something.
Find your act-on-sight process
Name one process that acts the moment a record appears. Write what it does in the physical world, and what would have to happen if that record later left the accepted history. If the answer is that nothing could be done, that is the finding.
Set two depths, not one
Pick one reversible action and one irreversible one. Choose a required depth for each, in writing, with the reason. Bring both to session 9, which is about code that runs on the register and therefore inherits every property tonight established.