Adding a price to something that was free
Nothing in the Harbourgate register resists being rewritten. The structure makes an edit visible, and at difficulty 0 making it invisible again costs four hash computations. Difficulty does not improve the hash, the link or the detection. It adds an expense to producing a block, and therefore to reproducing one, which is the only thing that was missing.
★ What you walk out with tonight. A working account of the mining loop, including why the nonce cannot be calculated and has to be searched for. Your own measured mean from your own trials, taken in this browser and compared against a mean with a trial count beside it. And a habit that outlives the subject: no cost figure without an n.
Self-studyThe words that will keep coming back4 min▶
- Nonce. The field a block carries that can be set to anything without changing what the block says.
- Difficulty. How many zero characters a block's hash is required to begin with.
- Target. The required prefix itself. At difficulty 3 it is three zeros and nothing else is asked of the hash.
- Attempt. One nonce tried and one hash computed. The unit every cost on this page is counted in.
- mine. Count the nonce upwards until the hash meets the target. Returns the nonce, the hash and the attempts it took.
- Expected attempts. 16 to the power of the difficulty, because each hex character lands on zero about one time in sixteen.
- Trial. One block mined from scratch. A mean is only worth reading with the number of trials beside it.
- Spread. The distance between the smallest and largest run measured. At these difficulties it is enormous.
A free field, a required prefix, and no shortcut between them
12 min liveFour of a block's five hashed fields are pinned by something outside the miner's control. The nonce is pinned by nothing. It exists so that a block's digest can be moved without the block saying anything different, which is the only way a hash can be searched for rather than merely computed.
LiveWhy the target is a prefix and not something cleverer4 min▶
Requiring a run of leading zeros is arbitrary, cheap to state and instant to check. A verifier looks at the first few characters and is done, which matters because every participant checks every block and nobody should have to redo the search to confirm it. The asymmetry is the whole design: expensive to find, trivial to confirm.
The prefix also gives a clean knob. Each additional zero character multiplies the expected number of attempts by sixteen, because a hexadecimal character lands on zero about one time in sixteen. That is where 16 to the power of the difficulty comes from, and it is the only arithmetic in the mechanism.
LiveMining changes the block without changing the record3 min▶
When the loop stops, the block that gets stored has a different nonce from the one it started with and a hash that meets the target. The entry, the position, the timestamp and the previous hash are exactly what they were. Nothing a reader of the register cares about was touched, which is why the nonce can be spent freely on the search.
That also explains why the attempts figure is not stored anywhere useful. The block carries the nonce that worked, and a nonce of 40,000 does not prove 40,000 attempts were made, only that this one was accepted. Counting attempts requires instrumenting the search, which is what the box below does.
Self-studyWhat difficulty does not do3 min▶
It does not make the hash harder to compute, does not make collisions less likely, does not stop anyone editing a block, and does not change what verification reports when they do. A tampered register at difficulty 4 fails in exactly the same two ways it failed at difficulty 0, with exactly the same index and kind.
What changes is the repair bill. Every block from the edit to the end has to be searched for again rather than computed once, and that is a deterrent rather than a prohibition. Session 5 puts the number on it.
Take the mean yourself, then compare it with one
16 min liveBelow is the measured table for this engine. Each row is many independent blocks mined from scratch, and the trial count is part of the figure rather than a footnote to it. Read the mean against the expectation, then read the last two columns, because those are the ones that decide whether a single number means anything.
...
LiveWatch which number settles and which one does not4 min▶
Run twenty trials, then a hundred, and keep an eye on two tiles. The mean wanders early and then stops moving much. The largest run does the opposite: it only ever goes up, and it jumps whenever an unlucky block turns up, which is why a maximum taken over a hundred trials and a maximum taken over a thousand are not comparable quantities.
This is the practical reason to report n. Two people quoting a mean can be compared. Two people quoting a worst case cannot be, unless they both say how long they looked.
LiveHow many trials is enough3 min▶
There is no clean answer, and the table above shows why the question bites. The trial counts fall as the difficulty rises, from 500 at difficulty 1 down to 120 and 150, because each trial costs sixteen times more than the one on the row above. So the rows with the widest spread are exactly the rows measured the fewest times.
The honest way to present that is to publish the n alongside the mean and let a reader judge, which is what the table does. The dishonest way is to run until the number looks tidy and then stop, which produces a table of the same shape and cannot be told apart from the outside.
Self-studyWhere the disagreement really is4 min▶
One camp says the mean is the only summary worth quoting. Costs add up, and over many blocks the total is the number of blocks times the mean, so the mean is the quantity that predicts a budget. A median tells you about one lucky block and cannot be multiplied by anything useful.
The other camp says the mean of a distribution shaped like this one is dragged around by rare enormous draws and describes almost none of the blocks actually mined. A typical block at difficulty 3 costs much less than 4,115 attempts, and quoting the mean to somebody who is about to mine one block overstates what they should expect while saying nothing at all about the tail they should actually fear.
Both are right about their own question, which is why the argument keeps happening between people who are not asking the same one. Take your own median in the box above alongside your mean and look at the gap, then decide which of the two questions your reader is asking before you publish either.
One draw is close to uninformative
7 min liveThe first time this bench was run, it was run once. Both numbers below are real results from the real engine and both were available to be quoted as the cost of mining. One of them is a long way below the measured mean and the other a long way above it, and nothing inside either run says which.
LiveWhy the single run cannot warn you4 min▶
A lucky run and an unlucky run are produced by identical code doing identical work, and the result carries no flag saying which it was. There is no variance estimate to be had from one observation, so the only way to know a number is atypical is to have others to compare it with. That is not a statistical nicety here, it is the entire content of the measurement.
Take one draw in the box above and write it down. Then take another. The second number is usually a more effective argument than any amount of explanation, because the two are often nothing like each other and both came out of the same loop a second apart.
LiveWhat to do when you only get one run3 min▶
Sometimes a measurement genuinely cannot be repeated: a migration that runs once, an incident that happened once. The answer is not to pretend the single figure is a mean. It is to report it as what it is, one observation, and to say what the expected value was if anything predicts it.
For mining there is such a prediction, which is 16 to the power of the difficulty, so a single run can at least be placed against an expectation. Reporting 12,462 alongside an expectation of 4,096 is honest. Reporting 12,462 as the cost is not, and the difference is one clause.
Self-studyThe same failure outside this subject3 min▶
A query timing taken once after a warm cache, a model evaluated on one train and test split, a page load measured on the developer's own laptop, a retry that succeeded first time. All of these are single draws presented as costs, and all of them are defended with the same sentence, which is that the number came from a real run.
The number being real is not the issue. The issue is that it was one of many numbers the same process produces, and no reader can tell that from the figure alone. Attaching an n is cheap and it makes the claim checkable, which is why its absence is worth treating as information about the person quoting it.
Difficulty is a dial on expected cost, not on cost
6 min liveRaising the difficulty by one multiplies what a block should cost by sixteen. It does not put a floor under any individual block. The measured ranges overlap heavily, and a block mined at difficulty 4 can land in fewer attempts than the average block at difficulty 3.
LiveWhy the spread does not hurt the design4 min▶
An attacker rewriting a register does not mine one block, they mine every block from the edit to the end, and the luck averages out across them. A run of four blocks is much more predictable than any one of them, and a run of four hundred is close to the mean. The variance that makes a single number useless is the same variance that becomes irrelevant at scale.
So the spread is a problem for the person quoting a figure, not for the mechanism. That is an unusual shape and it is worth holding on to, because the instinct on seeing a range of 149 to 339,789 is to conclude the system is unreliable rather than that the measurement was reported honestly.
LiveReading a range before you read a mean3 min▶
At difficulty 3 the measured range runs from 40 attempts to 17,343 around a mean of 4,115, which is a factor of more than 400 from end to end. Knowing that first changes how you read the mean: it stops being a description of a typical block and becomes a description of a long-run average, which is a different claim with different uses.
The habit generalises. When a table offers you a mean and a range, read the range first and then decide whether the mean is answering your question. If the range is narrow, the mean is a prediction. If it is 400 times wide, the mean is a budget line.
Self-studyDifficulty 1 and 2 both have a smallest run of 13 min▶
Across 500 trials at difficulty 1 and 300 at difficulty 2, some block landed on its very first attempt in each case. That is not an error in the bench, it is the expected consequence of a search whose first draw has the same chance as every other draw.
It also makes a nice test of whether somebody has internalised the mechanism. If a block can be mined in one attempt at difficulty 2, no observer can conclude anything about the work done by looking at a single valid block. What they can check is that the block meets the target, which is all a verifier ever claims to do.
Build a trial harness and quote your own number
13 min hands onConsole open on this page. Mining one block is two lines; the work is in refusing to stop at one block. The prev value below is the word placeholder, because the search behaves identically whatever sits in that field.
Check the hash before you measure anything with it
Run CHAIN.selfTest().ok first. An attempt count produced by a wrong hash function is a measurement of nothing, and it will look exactly as plausible as a correct one.
Mine one block and read the whole result
Call CHAIN.mine(block, 1) and look at all three fields that come back. Then confirm the target yourself with result.hash.slice(0, 1) rather than trusting the function that just told you it had succeeded.
Take five single draws and put them side by side
Run five separate trials at difficulty 2 and write the five numbers down in a row. Before you compute anything, say which of the five you would have quoted if you had only run once, and what that choice would have cost the reader.
Grow n and watch the mean stop moving
Run trials(20, 2), then trials(100, 2), then trials(300, 2), recording the mean each time. Write down the n at which you would be willing to put the number in a document, and why that n and not the one below it.
Compare against the measured row, both halves of it
Put your difficulty 2 mean next to 277 over 300 trials, and your range next to 1 and 2,147. Expect the mean to be close and the range to disagree, because a maximum depends on how long you looked.
Sort your runs and take the median too
Sort the array, take the middle value, and write down the gap between your median and your mean. Then decide which of the two you would publish for a reader who is about to mine exactly one block, and which for a reader budgeting a thousand.
The habit to keep. Every cost claim carries a mean and a trial count, or it is an anecdote. When somebody hands you a figure without an n, the question is not whether the number is right. It is how many times they looked, and whether they would have stopped looking if the number had been less convenient.
Three questions
You mine one block at difficulty 3 and it takes 12,462 attempts. What may you conclude about what difficulty 3 costs?
12,462 is exactly what the first run of this bench produced at difficulty 3, and it would have been quoted as the cost if nobody had run it again. Attempts are counted in hashes rather than seconds, so machine speed does not enter into it at all.
Why does the mining loop have to count nonces upwards rather than calculate one?
The loop is pure guessing and the order of the guesses is arbitrary; starting anywhere works equally well. What makes the search necessary is the absence of any gradient to climb, which is the same property that makes a near miss useless to an attacker.
Difficulty 4 was measured at a mean of 74,190 attempts over 150 trials, with runs from 149 to 339,789. What did raising the difficulty buy?
Each extra zero multiplies the expectation by sixteen and widens the range at the same time. The measured bars overlap heavily, so any claim about a particular block is unsupportable. Over many blocks the luck averages out, which is why the mechanism works despite a figure nobody should quote from one run.
Homework
Twenty five minutes, half of it on this engine and half of it on a number somebody in your organisation already relies on.
Measure a difficulty 4 row of your own
Choose your own trial count, run it, and record the mean, the median, the smallest run, the largest run and the n you chose. Bring the n and your reason for stopping there, because that decision is the part nobody usually writes down.
Find a cost figure quoted without an n
A benchmark, a load time, a throughput claim, a "this takes about". Write what you would need to see before believing it, and whether a second measurement is available to you today. Bring one example to session 5.