diff --git a/nimbus/p2p/clique/clique_defs.nim b/nimbus/p2p/clique/clique_defs.nim index 64d803bef..f8da244db 100644 --- a/nimbus/p2p/clique/clique_defs.nim +++ b/nimbus/p2p/clique/clique_defs.nim @@ -250,7 +250,7 @@ type errCliqueGasRepriceFork errCliqueSealSigFn - errCliqueStopped = "Process was interrupted" + errCliqueStopped = "process was interrupted" errCliqueExpectedBaseFee = "header is missing baseFee" errCliqueGasLimitTooLow = "gas limit is too low" errCliqueGasLimitTooHigh = "gas limit is too high" diff --git a/nimbus/p2p/clique/clique_poll.nim b/nimbus/p2p/clique/clique_poll.nim index 3c3212f19..8f8028849 100644 --- a/nimbus/p2p/clique/clique_poll.nim +++ b/nimbus/p2p/clique/clique_poll.nim @@ -110,6 +110,11 @@ proc delVote*(t: var CliquePoll; signer, address: EthAddress) {. t.votes[address].signers.del(signer) +proc flushVotes*(t: var CliquePoll) = + ## Reset/flush pending votes, authorised signers remain the same. + t.votes.clear + + # clique/snapshot.go(141): func (s *Snapshot) validVote(address [..] proc validVote*(t: var CliquePoll; address: EthAddress; authorize: bool): bool = ## Check whether voting would have an effect in `addVote()` diff --git a/nimbus/p2p/clique/snapshot.nim b/nimbus/p2p/clique/snapshot.nim index c1424e856..55ce82309 100644 --- a/nimbus/p2p/clique/snapshot.nim +++ b/nimbus/p2p/clique/snapshot.nim @@ -30,7 +30,6 @@ import ./clique_cfg, ./clique_defs, ./clique_poll, - ./clique_utils, ./ec_recover, chronicles, eth/[common, rlp, trie/db] @@ -82,7 +81,7 @@ proc pp(s: var Snapshot; h: var AddressHistory): string = proc pp(s: var Snapshot; v: Vote): string = proc authorized(b: bool): string = - if b: "auhorize" else: "de-authorize" + if b: "authorise" else: "de-authorise" ppExceptionWrap: "(" & &"address={s.pp(v.address)}" & &",signer={s.pp(v.signer)}" & @@ -239,24 +238,15 @@ proc applySnapshot*(s: var Snapshot; # Remove any votes on checkpoint blocks if (number mod s.cfg.epoch) == 0: - # clique/snapshot.go(210): snap.Votes = nil - s.say "applySnapshot epoch => reset, state=", s.pp(41) - - # This part differs from the go implementation in that the `signer` - # list is re-assigned. The original implementation silently assumes - # that the `signer` list is the same as the previous one but this is - # not enforced. + # Note that the correctness of the authorised accounts list is verified in + # clique/clique.verifyCascadingFields(), + # see clique/clique.go(355): if number%c.config.Epoch == 0 { + # This means, the account list passed with the epoch header is verified + # to be the same as the one we already have. # - # The eip225 discussion has it as: [..] where every epoch transition - # flushes all pending votes. Furthermore, these epoch transitions can - # also act as stateless checkpoints containing the list of current - # authorized signers within the header extra-data. This permits clients - # to sync up based only on a checkpoint hash without having to replay - # all the voting that was done on the chain up to that point. It also - # allows the genesis header to fully define the chain, containing the - # list of initial signers. - s.data.ballot.initCliquePoll(header.extraData.extraDataAddresses) - s.data.ballot.setDebug(s.data.debug) + # clique/snapshot.go(210): snap.Votes = nil + s.data.ballot.flushVotes + s.say "applySnapshot epoch => reset, state=", s.pp(41) # Delete the oldest signer from the recent list to allow it signing again block: diff --git a/tests/test_clique.nim b/tests/test_clique.nim index e507a9f9e..390334b42 100644 --- a/tests/test_clique.nim +++ b/tests/test_clique.nim @@ -36,7 +36,7 @@ proc cliqueMain*(noisy = defined(debug)) = # clique/snapshot_test.go(379): for i, tt := range tests { for tt in voterSamples.filterIt(it.id in testSet): - test &"Snapshots {tt.id: 2}: {tt.info.substr(0,50)}...": + test &"Snapshots {tt.id:2}: {tt.info.substr(0,50)}...": pool.say "\n" if tt.id in skipSet: