-
Notifications
You must be signed in to change notification settings - Fork 772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Clique Support #1032
Add Clique Support #1032
Changes from 1 commit
05b0efa
9572564
d6d7c30
1712049
63c2362
a017648
7cd888d
0873bb7
2df16e0
a28851b
0aa3f29
29c11e6
1557f5c
396c896
b1bf363
8b82e3a
31160ac
222fbfb
b6b8bed
f9c6157
4828d1d
ee6902c
8bfafd5
cac505b
014e22d
7c8f722
0641bb8
726102b
f57febd
a6f8ea7
33d5894
4aea0d5
0411971
74618be
00dc55a
6d723ce
edab558
fee1381
def4177
ba4bb83
48da84e
d69444f
2ad875f
9ec8583
3f983e4
d9e5558
6cbebb3
8c81c69
141159c
6721321
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -393,16 +393,23 @@ export default class Blockchain implements BlockchainInterface { | |||||||||||
await this.cliqueUpdateVotes() | ||||||||||||
} | ||||||||||||
|
||||||||||||
private async cliqueUpdateSignerStates(signerState?: CliqueSignerState) { | ||||||||||||
private async cliqueUpdateSignerStates(signerState: CliqueSignerState) { | ||||||||||||
const dbOps: DBOp[] = [] | ||||||||||||
if (signerState) { | ||||||||||||
this._cliqueLatestSignerStates.push(signerState) | ||||||||||||
const formatted = this._cliqueLatestSignerStates.map((state) => [ | ||||||||||||
state[0].toBuffer(), | ||||||||||||
state[1].map((a) => a.toBuffer()), | ||||||||||||
]) | ||||||||||||
dbOps.push(DBOp.set(DBTarget.CliqueSignerStates, rlp.encode(formatted))) | ||||||||||||
this._cliqueLatestSignerStates.push(signerState) | ||||||||||||
|
||||||||||||
// trim length to CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT | ||||||||||||
const length = this._cliqueLatestSignerStates.length | ||||||||||||
const limit = this.CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT | ||||||||||||
if (length > limit) { | ||||||||||||
this._cliqueLatestSignerStates = this._cliqueLatestSignerStates.slice(length - limit, length) | ||||||||||||
} | ||||||||||||
|
||||||||||||
const formatted = this._cliqueLatestSignerStates.map((state) => [ | ||||||||||||
state[0].toBuffer(), | ||||||||||||
state[1].map((a) => a.toBuffer()), | ||||||||||||
]) | ||||||||||||
dbOps.push(DBOp.set(DBTarget.CliqueSignerStates, rlp.encode(formatted))) | ||||||||||||
|
||||||||||||
await this.dbManager.batch(dbOps) | ||||||||||||
} | ||||||||||||
|
||||||||||||
|
@@ -460,12 +467,21 @@ export default class Blockchain implements BlockchainInterface { | |||||||||||
} | ||||||||||||
} | ||||||||||||
} | ||||||||||||
|
||||||||||||
// trim length to CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT | ||||||||||||
const length = this._cliqueLatestVotes.length | ||||||||||||
const limit = this.CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT | ||||||||||||
if (length > limit) { | ||||||||||||
this._cliqueLatestVotes = this._cliqueLatestVotes.slice(length - limit, length) | ||||||||||||
} | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was my initial thought as well to trim both the signer states AND the votes (sorry, just looked it up, also still had this as a comment in along There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I guess for the votes we might want to define a safe-number-of-blocks waiting periods (longest anticipated reorg block counts) and then discard the votes from before the epoch transition. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right now all votes are being cleared on epoch transitions: ethereumjs-monorepo/packages/blockchain/src/index.ts Lines 822 to 826 in 6721321
which is correct as per this part of the spec:
Keeping in mind reorgs would be important though as you mention, but I have to think more about how we would manage that. Perhaps we could keep some history of stale votes, but the vote counting logic in (edit: I added this to the new follow up PR) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't actually think it's too tricky: if there is a reorg, then all vote and signer state entries with block numbers higher than the reorg block number will be deleted, the signers from the last singer state stack item will be become the new active signers. Everything else from that moment on then continues (restarts) as before. If I don't get this wrong, votes need to be kept relatively long in this scenario, so i think "EPOCH_LENGTH + REORG_SAFE_PERIOD" block numbers - so something like 30050, since if a reorg is happening from let's say 30020 -> 29950 and there is voting taking place in these last 50 blocks before the epoch transition, theoretically all existing votes from this 0-29999 epoch might be relevant for the pre-epoch voting. Does this make sense? For Signer States I would think - all states from the last REORG_SAFE_PERIOD blocks + minimally one state - should be enough if I am not forgetting something. But I think we can also generally be a bit more generous here - e.g. take a somewhat longer REORG_SAFE_PERIOD of 100 or something or keep more signer states, nothing lost here, this doesn't take that much space and eventually the date might be interesting for analytical purposes. |
||||||||||||
|
||||||||||||
const dbOps: DBOp[] = [] | ||||||||||||
const formatted = this._cliqueLatestVotes.map((v) => [ | ||||||||||||
v[0].toBuffer(), | ||||||||||||
[v[1][0].toBuffer(), v[1][0].toBuffer(), v[1][2]], | ||||||||||||
]) | ||||||||||||
dbOps.push(DBOp.set(DBTarget.CliqueVotes, rlp.encode(formatted))) | ||||||||||||
|
||||||||||||
await this.dbManager.batch(dbOps) | ||||||||||||
} | ||||||||||||
|
||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My idea for
CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT
was to have a defined period of blocks (therefore the name) and delete the old signer states once these number of blocks have passed. Not sure, this version of just keeping some number of signer states should work as well - I guess - but then I would rename the constant.Also maybe 100 might be a bit too much then? But not sure, maybe that's ok, shouldn't be too much extra data.