A Deterministic Tiebreaker for Bitcoin Block Selection: Enhancing Fairness and Convergence

A Deterministic Tiebreaker for Bitcoin Block Selection: Enhancing Fairness and Convergence

Abstract

Bitcoin’s current first-seen rule for resolving competing blocks of equal length favors miners with superior network propagation, amplifying the risks of selfish mining and prolonging accidental chain forks.
We propose a simple, backwards-compatible change: when two blocks compete at the same height, miners compute a deterministic tiebreaker using the hash of their concatenated block hashes, H(A || B), and select the winner based on a fixed threshold.
This approach ensures a fair, latency-independent resolution, reduces fork duration, and maintains resistance to selfish mining without altering miner incentives or requiring a hard fork.

4 Likes

While not deterministic, the current implementation in BCHN is not first seen, but favors blocks that have a block header timestamp that most closely matches the time the node received the block

(see line ~4000 in validation.cpp)

This was implemented to mitigate “selfish mining attack”
https://arxiv.org/pdf/1311.0243v1

2 Likes

On second look I don’t see any code that actually does the switch. It seems it was never completed, just added logging

2 Likes

Nice, but that still favors better-connected pools.

My proposal would reduce the advantage pools with better propagation would have over others to just the few seconds during which network could add +1 block and lock it in. If that doesn’t happen then uppon announcement of some late block B, it would have 50:50 fighting chance.

3 Likes

Your idea seems super interesting and promising (“deterministic”) at first glance.

I will deep-read it 4 times to properly understand it and comment on later.

Thanks for the work! :+1:

3 Likes

Am I a mathematical idiot, or isn’t half of 2^256 actually 2^255, not 2^128?

Edit: ie you’re essentially coinflipping the first bit in a 256 bit string as either 1 or 0.

Edit 2: Other than that, my first instinct is this is an excellent idea. Simple & effective.

3 Likes

Lol yeah, brain fart, I’ll add the fix

2 Likes

Why not just take the lower of the two hashes (if interpreted as a 256-bit integer)? Surely that’s always deterministic and has nothing to do with bandwidth/latency.

EDIT:

Also bonus: Technically picking the lower hash is fairer since the lower-hash miner has put in “more PoW” (even if it’s only slightly more) since there are potentially more consecutive 0-bits in the high order bit positions.

Or are you worried that using the lower hash does indeed enable some selfish mining tricks because if they throw more PoW at it than their peers they can pull it off?

What if the lower hash is lower by a significant threshold?

Meh.

In that case a miner who gets a “lucky” hash would know it’s definitely a lucky hash and could withhold it until a block is found and THEN release it, so to make everyone waste work and give himself comparative advantage.

With H(A||B) he can’t know whether his hash will be lucky, because B will be unknown and it will have 50:50 of flipping his block.

5 Likes

Hmm. Yes correct.

I guess if they define some threshold when they feel “lucky enough” (say has 2, 3 or 5 or whatever extra preceding 0-bits)… then they can do the selfish mine, otherwise mine normally. Yeah, good point.

1 Like

OK, I have read the spec 3 times now, I think I can say I understand it at this point.

  • The idea will just work like described, once all/most miners update the software :white_check_mark:
  • It’s easy to code :white_check_mark:
  • I see no significant downsides right now :white_check_mark:
  • It is beneficial to the network :white_check_mark:
  • Makes mining more fair for everybody :white_check_mark:

I think we should implement this ASAP. I wonder how it is we didn’t do it earlier, seems like a total no-brainer to have it.

I guess maybe before people did not care about small percentage of forks caused by worse connectivity?

2 Likes

Based on my telegram message:

The first seen idea combined with headers first means that miners switch mining to a new block in less than 100ms for most. (this is a speed of light thing, as that is the speed of electrons-reactions. If you want help with the math, ask grok: https://x.com/i/grok/share/fOxbygzh92j680tA02N0oyg7Z)
Which effectively means that the problem being “solved” does not exist.

On the other hand, a block that can be mined which will replace an already mined one misaligns the incentives. A miner can suddenly choose to continue mining on a tip-minus-one (in order to hurt another miner or whatever) instead of mining on the tip, with little to no risk.

So, yeah, the downside to this is that it opens up to unknown unknowns while it doesn’t actually solve a real world problem.

Looks very promising. At first and second glance, this looks like an oversight that could’ve been done long ago! Not to say I’m not missing something, but definitely interesting.

I don’t know, it needs more analysis, no rush, we don’t have the problem which this would hypothetically solve.

How I got here is asking myself: “Why are orphan rates a problem?” and “How high orphan rates could we tolerate?” but that’s for another topic, the takeaway from my pondering is this: if everyone had equal orphan rates then they wouldn’t be a problem at all.
That’s how I got here, wondered “If we have to have some orphans then what if there was a way to equalize orphan rates across pools?”

Uncle merging proposals like Tailstorm would address the problem by subsidizing orphans, and
this proposal would address the problem socializing orphan losses.

Header-first requires mining an empty block to get the subsidy. How would header-first work when fees take over?
But still, if bandwidth significantly outpaces our network growth and demand for transactions then it may as well be that we never see orphan rates become big enough to be a problem, so changes to 1st seen would be unnecessary.

The current state of things is that miners are free to implement whatever tie breaker policy they want because any 2 tips are equal as far as consensus is concerned, favoring either is subjective.
That means we can actually have competing policies, there needs not be consensus on this policy.

With the H(A||B) as policy we’d have an objective tie-breaker for the case when chainworks are equal.


Something more to ponder, what if longer tips are competing, e.g.:

N+A+B vs N+C+D

should we evaluate H(B||D) or H(A||C) to pick the tip? or some 3rd thing like H(A||B||C||D)?

what if evaluating N+A+B+C vs N+D+E+F ?

in that case difficulty in C and F could differ so our DAA may resolve the conflict because one of the chains would have higher chainwork?

It would work exactly the same.
The question asks a question that is irrelevant to the reason miners use header first mining.

The miners essentially have a hardware problem.
The moment a block-header comes in, they don’t have anything to mine. So they can just turn off the mining hardware and save power that way. That is the “proper” solution. Don’t spend money on power.

The hardware problem is that this turning off and then 2 or 10 seconds later turning it on again is really bad for your mining hardware. Imagine going from zero ampere usage to 100 ampere in milliseconds. That will just create massive power (voltage) fluctuations that make your hardware reboot or worse.
In other words, they can’t turn off their hardware.

So, what to do?

  1. you keep mining the block you already started mining. This may create an orphan, though. But they are rare, so that’s a risk.
  2. you mine on top of the chain that you have validated as having the most PoW, with an empty block until you have new transactions to put into it.

Most miners pick 2.

Work? Sure, you extend a header with your empty block and get paid 0 for it (or in nearer future: just 0.1 BCH while everyone else is getting 1 BCH for blocks filled with TXs).

The longer you have to wait to get the full block, the longer you delay producing a template with 1 BCH reward and getting to work on it, and the longer you work on a template with just 0.1 BCH reward. Your costs are the same, but for some % of the time you revenue will be 10% of what it could be.

This reduces your average revenue per block (but cost stays the same), and your margins suffer. As you say, the “proper” solution is to avoid it by simply not mining until you verify the tip and fill your template to 1 BCH, then you preserve your margin - and as you say, that’s technically not possible to do with 0 lag, due to hardware limits.

One mining company claims a 15s cycle (5s to drop, 10s to ramp up again):

If tech gets better and gap between subsidy and fees grows, wouldn’t miners start dropping header first mining to optimize their margins?