Closed kayabaNerve closed 3 years ago
I generally don't comment with this sort of stuff, yet I feel it may be helpful.
I added this to the bottom of State.processBlock in order to find the first block at which these values diverged from the expectation.
var
tCopy: int = state.total
cCopy: int = state.counted
pCopy: int = state.pending
try:
for h in 0 ..< state.merit.len:
tCopy -= state.merit[h]
if state.statuses[h] == MeritStatus.Unlocked:
cCopy -= state.merit[h]
if state.statuses[h] == MeritStatus.Pending:
cCopy -= state.merit[h]
pCopy -= state.merit[h]
except Exception as e:
panic("Exception when checking Merit status of a holder: " & e.msg)
if tCopy != 0:
panic("Total is wrong.")
if cCopy != 0:
panic("Counted is wrong.")
if pCopy != 0:
panic("Pending is wrong.")
Discovered during the recent testnet thanks to @Vyryn.
Unlocked is produced by
state.counted - state.pending
. Both can turn negative of their own accord thanks to the Dead Merit code, notably an oversight which updated these variables based on the status of who just gained Merit, not whoever just lost Merit.This bug did end the testnet. While nodes were stable, and we never hit a negative Merit threshold thanks to a max statement, this did change Mints and therefore invalidate most of the chain. The net ran for 4.5 days out of its planned 7 days,