Description
Follow-up of #2147 (comment):
I think the light client being capable of reorging is reasonable. Definitely an okay response especially in cases of high network latency.
This is making me realize that it would take some cleverness to make light clients capable of reorging. Here is one rough proposal. The LightClientStore keeps track of a series of heads, which must always satisfy the following invariants:
store.heads[0]
must be finalized (if we want, if a block has been part ofstore.heads
for >= 24 hours we can "finalize" it locally)store.heads[n+1]
must be a descendant ofstore.heads[n]
vote_count(store.heads[n+1]) < vote_count(store.heads[n])
Essentially, it is the client's best guess of the current chain, with confidence naturally decreasing as you get closer to the tip.
When a client receives a light client update, the update must reference an ancestor that is in store.heads
. The update must satisfy the properties:
votes(update.block) < votes(update.ancestor)
update.ancestor == store.heads[-1] or votes(update.block) > votes(store.heads[store.heads.index(update.ancestor) + 1])
In other words, it must be a better alternative than whatever block it is replacing. If the update is accepted, then all elements from store.heads
after update.ancestor
are removed, and update.block
is added to the end.