@feelyourprotocol/blockchain 8141.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +269 -0
  2. package/dist/cjs/blockchain.d.ts +372 -0
  3. package/dist/cjs/blockchain.d.ts.map +1 -0
  4. package/dist/cjs/blockchain.js +1105 -0
  5. package/dist/cjs/blockchain.js.map +1 -0
  6. package/dist/cjs/consensus/casper.d.ts +16 -0
  7. package/dist/cjs/consensus/casper.d.ts.map +1 -0
  8. package/dist/cjs/consensus/casper.js +28 -0
  9. package/dist/cjs/consensus/casper.js.map +1 -0
  10. package/dist/cjs/consensus/clique.d.ts +164 -0
  11. package/dist/cjs/consensus/clique.d.ts.map +1 -0
  12. package/dist/cjs/consensus/clique.js +520 -0
  13. package/dist/cjs/consensus/clique.js.map +1 -0
  14. package/dist/cjs/consensus/ethash.d.ts +29 -0
  15. package/dist/cjs/consensus/ethash.d.ts.map +1 -0
  16. package/dist/cjs/consensus/ethash.js +48 -0
  17. package/dist/cjs/consensus/ethash.js.map +1 -0
  18. package/dist/cjs/consensus/index.d.ts +5 -0
  19. package/dist/cjs/consensus/index.d.ts.map +1 -0
  20. package/dist/cjs/consensus/index.js +10 -0
  21. package/dist/cjs/consensus/index.js.map +1 -0
  22. package/dist/cjs/constructors.d.ts +13 -0
  23. package/dist/cjs/constructors.d.ts.map +1 -0
  24. package/dist/cjs/constructors.js +80 -0
  25. package/dist/cjs/constructors.js.map +1 -0
  26. package/dist/cjs/db/cache.d.ts +17 -0
  27. package/dist/cjs/db/cache.d.ts.map +1 -0
  28. package/dist/cjs/db/cache.js +38 -0
  29. package/dist/cjs/db/cache.js.map +1 -0
  30. package/dist/cjs/db/constants.d.ts +23 -0
  31. package/dist/cjs/db/constants.d.ts.map +1 -0
  32. package/dist/cjs/db/constants.js +54 -0
  33. package/dist/cjs/db/constants.js.map +1 -0
  34. package/dist/cjs/db/helpers.d.ts +9 -0
  35. package/dist/cjs/db/helpers.d.ts.map +1 -0
  36. package/dist/cjs/db/helpers.js +68 -0
  37. package/dist/cjs/db/helpers.js.map +1 -0
  38. package/dist/cjs/db/manager.d.ts +78 -0
  39. package/dist/cjs/db/manager.d.ts.map +1 -0
  40. package/dist/cjs/db/manager.js +203 -0
  41. package/dist/cjs/db/manager.js.map +1 -0
  42. package/dist/cjs/db/operation.d.ts +45 -0
  43. package/dist/cjs/db/operation.d.ts.map +1 -0
  44. package/dist/cjs/db/operation.js +110 -0
  45. package/dist/cjs/db/operation.js.map +1 -0
  46. package/dist/cjs/helpers.d.ts +19 -0
  47. package/dist/cjs/helpers.d.ts.map +1 -0
  48. package/dist/cjs/helpers.js +34 -0
  49. package/dist/cjs/helpers.js.map +1 -0
  50. package/dist/cjs/index.d.ts +7 -0
  51. package/dist/cjs/index.d.ts.map +1 -0
  52. package/dist/cjs/index.js +33 -0
  53. package/dist/cjs/index.js.map +1 -0
  54. package/dist/cjs/package.json +3 -0
  55. package/dist/cjs/types.d.ts +219 -0
  56. package/dist/cjs/types.d.ts.map +1 -0
  57. package/dist/cjs/types.js +3 -0
  58. package/dist/cjs/types.js.map +1 -0
  59. package/dist/esm/blockchain.d.ts +372 -0
  60. package/dist/esm/blockchain.d.ts.map +1 -0
  61. package/dist/esm/blockchain.js +1101 -0
  62. package/dist/esm/blockchain.js.map +1 -0
  63. package/dist/esm/consensus/casper.d.ts +16 -0
  64. package/dist/esm/consensus/casper.d.ts.map +1 -0
  65. package/dist/esm/consensus/casper.js +24 -0
  66. package/dist/esm/consensus/casper.js.map +1 -0
  67. package/dist/esm/consensus/clique.d.ts +164 -0
  68. package/dist/esm/consensus/clique.d.ts.map +1 -0
  69. package/dist/esm/consensus/clique.js +516 -0
  70. package/dist/esm/consensus/clique.js.map +1 -0
  71. package/dist/esm/consensus/ethash.d.ts +29 -0
  72. package/dist/esm/consensus/ethash.d.ts.map +1 -0
  73. package/dist/esm/consensus/ethash.js +44 -0
  74. package/dist/esm/consensus/ethash.js.map +1 -0
  75. package/dist/esm/consensus/index.d.ts +5 -0
  76. package/dist/esm/consensus/index.d.ts.map +1 -0
  77. package/dist/esm/consensus/index.js +5 -0
  78. package/dist/esm/consensus/index.js.map +1 -0
  79. package/dist/esm/constructors.d.ts +13 -0
  80. package/dist/esm/constructors.d.ts.map +1 -0
  81. package/dist/esm/constructors.js +76 -0
  82. package/dist/esm/constructors.js.map +1 -0
  83. package/dist/esm/db/cache.d.ts +17 -0
  84. package/dist/esm/db/cache.d.ts.map +1 -0
  85. package/dist/esm/db/cache.js +34 -0
  86. package/dist/esm/db/cache.js.map +1 -0
  87. package/dist/esm/db/constants.d.ts +23 -0
  88. package/dist/esm/db/constants.d.ts.map +1 -0
  89. package/dist/esm/db/constants.js +46 -0
  90. package/dist/esm/db/constants.js.map +1 -0
  91. package/dist/esm/db/helpers.d.ts +9 -0
  92. package/dist/esm/db/helpers.d.ts.map +1 -0
  93. package/dist/esm/db/helpers.js +61 -0
  94. package/dist/esm/db/helpers.js.map +1 -0
  95. package/dist/esm/db/manager.d.ts +78 -0
  96. package/dist/esm/db/manager.d.ts.map +1 -0
  97. package/dist/esm/db/manager.js +199 -0
  98. package/dist/esm/db/manager.js.map +1 -0
  99. package/dist/esm/db/operation.d.ts +45 -0
  100. package/dist/esm/db/operation.d.ts.map +1 -0
  101. package/dist/esm/db/operation.js +106 -0
  102. package/dist/esm/db/operation.js.map +1 -0
  103. package/dist/esm/helpers.d.ts +19 -0
  104. package/dist/esm/helpers.d.ts.map +1 -0
  105. package/dist/esm/helpers.js +30 -0
  106. package/dist/esm/helpers.js.map +1 -0
  107. package/dist/esm/index.d.ts +7 -0
  108. package/dist/esm/index.d.ts.map +1 -0
  109. package/dist/esm/index.js +7 -0
  110. package/dist/esm/index.js.map +1 -0
  111. package/dist/esm/package.json +3 -0
  112. package/dist/esm/types.d.ts +219 -0
  113. package/dist/esm/types.d.ts.map +1 -0
  114. package/dist/esm/types.js +2 -0
  115. package/dist/esm/types.js.map +1 -0
  116. package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
  117. package/dist/tsconfig.prod.esm.tsbuildinfo +1 -0
  118. package/package.json +75 -0
  119. package/src/blockchain.ts +1353 -0
  120. package/src/consensus/casper.ts +33 -0
  121. package/src/consensus/clique.ts +633 -0
  122. package/src/consensus/ethash.ts +69 -0
  123. package/src/consensus/index.ts +5 -0
  124. package/src/constructors.ts +119 -0
  125. package/src/db/cache.ts +39 -0
  126. package/src/db/constants.ts +73 -0
  127. package/src/db/helpers.ts +81 -0
  128. package/src/db/manager.ts +243 -0
  129. package/src/db/operation.ts +152 -0
  130. package/src/helpers.ts +37 -0
  131. package/src/index.ts +12 -0
  132. package/src/types.ts +256 -0
@@ -0,0 +1,516 @@
1
+ import { cliqueEpochTransitionSigners, cliqueIsEpochTransition, cliqueSigner, cliqueVerifySignature, } from '@feelyourprotocol/block';
2
+ import { ConsensusAlgorithm } from '@feelyourprotocol/common';
3
+ import { RLP } from '@feelyourprotocol/rlp';
4
+ import { Address, BIGINT_0, BIGINT_1, BIGINT_2, EthereumJSErrorWithoutCode, TypeOutput, bigIntToBytes, bytesToBigInt, equalsBytes, hexToBytes, isDebugEnabled, toType, } from '@feelyourprotocol/util';
5
+ import debugDefault from 'debug';
6
+ const debug = debugDefault('blockchain:clique');
7
+ // Magic nonce number to vote on adding a new signer
8
+ export const CLIQUE_NONCE_AUTH = new Uint8Array(hexToBytes('0xffffffffffffffff').buffer);
9
+ // Magic nonce number to vote on removing a signer.
10
+ export const CLIQUE_NONCE_DROP = new Uint8Array(8);
11
+ const CLIQUE_SIGNERS_KEY = 'CliqueSigners';
12
+ const CLIQUE_VOTES_KEY = 'CliqueVotes';
13
+ const CLIQUE_BLOCK_SIGNERS_SNAPSHOT_KEY = 'CliqueBlockSignersSnapshot';
14
+ // Block difficulty for in-turn signatures
15
+ export const CLIQUE_DIFF_INTURN = BIGINT_2;
16
+ // Block difficulty for out-of-turn signatures
17
+ export const CLIQUE_DIFF_NOTURN = BIGINT_1;
18
+ /**
19
+ * This class encapsulates Clique-related consensus functionality when used with the Blockchain class.
20
+ * Note: reorgs which happen between epoch transitions, which change the internal voting state over the reorg
21
+ * will result in failure and is currently not supported.
22
+ * The hotfix for this could be: re-load the latest epoch block (this has the clique state in the extraData of the header)
23
+ * Now replay all blocks on top of it. This should validate the chain up to the new/reorged tip which previously threw.
24
+ */
25
+ export class CliqueConsensus {
26
+ constructor() {
27
+ /**
28
+ * Keep signer history data (signer states and votes)
29
+ * for all block numbers >= HEAD_BLOCK - CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT
30
+ *
31
+ * This defines a limit for reorgs on PoA clique chains.
32
+ */
33
+ this.CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT = 200;
34
+ /**
35
+ * List with the latest signer states checkpointed on blocks where
36
+ * a change (added new or removed a signer) occurred.
37
+ *
38
+ * Format:
39
+ * [ [BLOCK_NUMBER_1, [SIGNER1, SIGNER 2,]], [BLOCK_NUMBER2, [SIGNER1, SIGNER3]], ...]
40
+ *
41
+ * The top element from the array represents the list of current signers.
42
+ * On reorgs elements from the array are removed until BLOCK_NUMBER > REORG_BLOCK.
43
+ *
44
+ * Always keep at least one item on the stack.
45
+ */
46
+ this._cliqueLatestSignerStates = [];
47
+ /**
48
+ * List with the latest signer votes.
49
+ *
50
+ * Format:
51
+ * [ [BLOCK_NUMBER_1, [SIGNER, BENEFICIARY, AUTH]], [BLOCK_NUMBER_1, [SIGNER, BENEFICIARY, AUTH]] ]
52
+ * where AUTH = CLIQUE_NONCE_AUTH | CLIQUE_NONCE_DROP
53
+ *
54
+ * For votes all elements here must be taken into account with a
55
+ * block number >= LAST_EPOCH_BLOCK
56
+ * (nevertheless keep entries with blocks before EPOCH_BLOCK in case a reorg happens
57
+ * during an epoch change)
58
+ *
59
+ * On reorgs elements from the array are removed until BLOCK_NUMBER > REORG_BLOCK.
60
+ */
61
+ this._cliqueLatestVotes = [];
62
+ /**
63
+ * List of signers for the last consecutive {@link Blockchain.cliqueSignerLimit} blocks.
64
+ * Kept as a snapshot for quickly checking for "recently signed" error.
65
+ * Format: [ [BLOCK_NUMBER, SIGNER_ADDRESS], ...]
66
+ *
67
+ * On reorgs elements from the array are removed until BLOCK_NUMBER > REORG_BLOCK.
68
+ */
69
+ this._cliqueLatestBlockSigners = [];
70
+ // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables
71
+ this.DEBUG = isDebugEnabled('ethjs');
72
+ this.algorithm = ConsensusAlgorithm.Clique;
73
+ }
74
+ /**
75
+ *
76
+ * @param param dictionary containing a {@link Blockchain} object
77
+ *
78
+ * Note: this method must be called before consensus checks are used or type errors will occur
79
+ */
80
+ async setup({ blockchain }) {
81
+ this.blockchain = blockchain;
82
+ this._cliqueLatestSignerStates = await this.getCliqueLatestSignerStates();
83
+ this._cliqueLatestSignerStates.sort((a, b) => (a[0] > b[0] ? 1 : -1));
84
+ this._cliqueLatestVotes = await this.getCliqueLatestVotes();
85
+ this._cliqueLatestBlockSigners = await this.getCliqueLatestBlockSigners();
86
+ }
87
+ async genesisInit(genesisBlock) {
88
+ await this.cliqueSaveGenesisSigners(genesisBlock);
89
+ }
90
+ async validateConsensus(block) {
91
+ if (!this.blockchain) {
92
+ throw EthereumJSErrorWithoutCode('blockchain not provided');
93
+ }
94
+ const { header } = block;
95
+ const valid = cliqueVerifySignature(header, this.cliqueActiveSigners(header.number));
96
+ if (!valid) {
97
+ throw EthereumJSErrorWithoutCode('invalid PoA block signature (clique)');
98
+ }
99
+ if (this.cliqueCheckRecentlySigned(header)) {
100
+ throw EthereumJSErrorWithoutCode('recently signed');
101
+ }
102
+ // validate checkpoint signers towards active signers on epoch transition blocks
103
+ if (cliqueIsEpochTransition(header)) {
104
+ // note: keep votes on epoch transition blocks in case of reorgs.
105
+ // only active (non-stale) votes will counted (if vote.blockNumber >= lastEpochBlockNumber
106
+ const checkpointSigners = cliqueEpochTransitionSigners(header);
107
+ const activeSigners = this.cliqueActiveSigners(header.number);
108
+ for (const [i, cSigner] of checkpointSigners.entries()) {
109
+ if (activeSigners[i]?.equals(cSigner) !== true) {
110
+ throw EthereumJSErrorWithoutCode(`checkpoint signer not found in active signers list at index ${i}: ${cSigner}`);
111
+ }
112
+ }
113
+ }
114
+ }
115
+ async validateDifficulty(header) {
116
+ if (!this.blockchain) {
117
+ throw EthereumJSErrorWithoutCode('blockchain not provided');
118
+ }
119
+ if (header.difficulty !== CLIQUE_DIFF_INTURN && header.difficulty !== CLIQUE_DIFF_NOTURN) {
120
+ const msg = `difficulty for clique block must be INTURN (2) or NOTURN (1), received: ${header.difficulty}`;
121
+ throw EthereumJSErrorWithoutCode(`${msg} ${header.errorStr()}`);
122
+ }
123
+ const signers = this.cliqueActiveSigners(header.number);
124
+ if (signers.length === 0) {
125
+ // abort if signers are unavailable
126
+ const msg = 'no signers available';
127
+ throw EthereumJSErrorWithoutCode(`${msg} ${header.errorStr()}`);
128
+ }
129
+ const signerIndex = signers.findIndex((address) => address.equals(cliqueSigner(header)));
130
+ const inTurn = header.number % BigInt(signers.length) === BigInt(signerIndex);
131
+ if ((inTurn && header.difficulty === CLIQUE_DIFF_INTURN) ||
132
+ (!inTurn && header.difficulty === CLIQUE_DIFF_NOTURN)) {
133
+ return;
134
+ }
135
+ throw EthereumJSErrorWithoutCode(`'invalid clique difficulty ${header.errorStr()}`);
136
+ }
137
+ async newBlock(block, commonAncestor) {
138
+ // Clique: update signer votes and state
139
+ const { header } = block;
140
+ const commonAncestorNumber = commonAncestor?.number;
141
+ if (commonAncestorNumber !== undefined) {
142
+ await this._cliqueDeleteSnapshots(commonAncestorNumber + BIGINT_1);
143
+ for (let number = commonAncestorNumber + BigInt(1); number <= header.number; number++) {
144
+ const canonicalHeader = await this.blockchain.getCanonicalHeader(number);
145
+ await this._cliqueBuildSnapshots(canonicalHeader);
146
+ }
147
+ }
148
+ }
149
+ /**
150
+ * Save genesis signers to db
151
+ * @param genesisBlock genesis block
152
+ * @hidden
153
+ */
154
+ async cliqueSaveGenesisSigners(genesisBlock) {
155
+ const genesisSignerState = [
156
+ BIGINT_0,
157
+ cliqueEpochTransitionSigners(genesisBlock.header),
158
+ ];
159
+ await this.cliqueUpdateSignerStates(genesisSignerState);
160
+ this.DEBUG && debug(`[Block 0] Genesis block -> update signer states`);
161
+ await this.cliqueUpdateVotes();
162
+ }
163
+ /**
164
+ * Save signer state to db
165
+ * @param signerState
166
+ * @hidden
167
+ */
168
+ async cliqueUpdateSignerStates(signerState) {
169
+ if (signerState) {
170
+ const blockNumber = signerState[0];
171
+ const known = this._cliqueLatestSignerStates.find((value) => {
172
+ if (value[0] === blockNumber) {
173
+ return true;
174
+ }
175
+ });
176
+ if (known !== undefined) {
177
+ return;
178
+ }
179
+ this._cliqueLatestSignerStates.push(signerState);
180
+ this._cliqueLatestSignerStates.sort((a, b) => (a[0] > b[0] ? 1 : -1));
181
+ }
182
+ // trim to CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT
183
+ const limit = this.CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT;
184
+ const blockSigners = this._cliqueLatestBlockSigners;
185
+ const lastBlockNumber = blockSigners[blockSigners.length - 1]?.[0];
186
+ if (lastBlockNumber) {
187
+ const blockLimit = lastBlockNumber - BigInt(limit);
188
+ const states = this._cliqueLatestSignerStates;
189
+ const lastItem = states[states.length - 1];
190
+ this._cliqueLatestSignerStates = states.filter((state) => state[0] >= blockLimit);
191
+ if (this._cliqueLatestSignerStates.length === 0) {
192
+ // always keep at least one item on the stack
193
+ this._cliqueLatestSignerStates.push(lastItem);
194
+ }
195
+ }
196
+ // save to db
197
+ const formatted = this._cliqueLatestSignerStates.map((state) => [
198
+ bigIntToBytes(state[0]),
199
+ state[1].map((a) => a.toBytes()),
200
+ ]);
201
+ await this.blockchain.db.put(CLIQUE_SIGNERS_KEY, RLP.encode(formatted));
202
+ // Output active signers for debugging purposes
203
+ if (signerState !== undefined) {
204
+ let i = 0;
205
+ try {
206
+ for (const signer of this.cliqueActiveSigners(signerState[0])) {
207
+ this.DEBUG && debug(`Clique signer [${i}]: ${signer} (block: ${signerState[0]})`);
208
+ i++;
209
+ }
210
+ // eslint-disable-next-line no-empty
211
+ }
212
+ catch { }
213
+ }
214
+ }
215
+ /**
216
+ * Update clique votes and save to db
217
+ * @param header BlockHeader
218
+ * @hidden
219
+ */
220
+ async cliqueUpdateVotes(header) {
221
+ // Block contains a vote on a new signer
222
+ if (header && !header.coinbase.isZero()) {
223
+ const signer = cliqueSigner(header);
224
+ const beneficiary = header.coinbase;
225
+ const nonce = header.nonce;
226
+ const latestVote = [header.number, [signer, beneficiary, nonce]];
227
+ // Do two rounds here, one to execute on a potential previously reached consensus
228
+ // on the newly touched beneficiary, one with the added new vote
229
+ for (let round = 1; round <= 2; round++) {
230
+ // See if there is a new majority consensus to update the signer list
231
+ const lastEpochBlockNumber = header.number -
232
+ (header.number %
233
+ BigInt(this.blockchain.common.consensusConfig().epoch));
234
+ const limit = this.cliqueSignerLimit(header.number);
235
+ let activeSigners = [...this.cliqueActiveSigners(header.number)];
236
+ let consensus = false;
237
+ // AUTH vote analysis
238
+ let votes = this._cliqueLatestVotes.filter((vote) => {
239
+ return (vote[0] >= BigInt(lastEpochBlockNumber) &&
240
+ !vote[1][0].equals(signer) &&
241
+ vote[1][1].equals(beneficiary) &&
242
+ equalsBytes(vote[1][2], CLIQUE_NONCE_AUTH));
243
+ });
244
+ const beneficiaryVotesAUTH = [];
245
+ for (const vote of votes) {
246
+ const num = beneficiaryVotesAUTH.filter((voteCMP) => {
247
+ return voteCMP.equals(vote[1][0]);
248
+ }).length;
249
+ if (num === 0) {
250
+ beneficiaryVotesAUTH.push(vote[1][0]);
251
+ }
252
+ }
253
+ let numBeneficiaryVotesAUTH = beneficiaryVotesAUTH.length;
254
+ if (round === 2 && equalsBytes(nonce, CLIQUE_NONCE_AUTH)) {
255
+ numBeneficiaryVotesAUTH += 1;
256
+ }
257
+ // Majority consensus
258
+ if (numBeneficiaryVotesAUTH >= limit) {
259
+ consensus = true;
260
+ // Authorize new signer
261
+ activeSigners.push(beneficiary);
262
+ activeSigners.sort((a, b) => {
263
+ // Sort by array size
264
+ const result = toType(a.toString(), TypeOutput.BigInt) < toType(b.toString(), TypeOutput.BigInt);
265
+ if (result) {
266
+ return -1;
267
+ }
268
+ else {
269
+ return 1;
270
+ }
271
+ });
272
+ // Discard votes for added signer
273
+ this._cliqueLatestVotes = this._cliqueLatestVotes.filter((vote) => !vote[1][1].equals(beneficiary));
274
+ this.DEBUG &&
275
+ debug(`[Block ${header.number}] Clique majority consensus (AUTH ${beneficiary})`);
276
+ }
277
+ // DROP vote
278
+ votes = this._cliqueLatestVotes.filter((vote) => {
279
+ return (vote[0] >= BigInt(lastEpochBlockNumber) &&
280
+ !vote[1][0].equals(signer) &&
281
+ vote[1][1].equals(beneficiary) &&
282
+ equalsBytes(vote[1][2], CLIQUE_NONCE_DROP));
283
+ });
284
+ const beneficiaryVotesDROP = [];
285
+ for (const vote of votes) {
286
+ const num = beneficiaryVotesDROP.filter((voteCMP) => {
287
+ return voteCMP.equals(vote[1][0]);
288
+ }).length;
289
+ if (num === 0) {
290
+ beneficiaryVotesDROP.push(vote[1][0]);
291
+ }
292
+ }
293
+ let numBeneficiaryVotesDROP = beneficiaryVotesDROP.length;
294
+ if (round === 2 && equalsBytes(nonce, CLIQUE_NONCE_DROP)) {
295
+ numBeneficiaryVotesDROP += 1;
296
+ }
297
+ // Majority consensus
298
+ if (numBeneficiaryVotesDROP >= limit) {
299
+ consensus = true;
300
+ // Drop signer
301
+ activeSigners = activeSigners.filter((signer) => !signer.equals(beneficiary));
302
+ this._cliqueLatestVotes = this._cliqueLatestVotes.filter(
303
+ // Discard votes from removed signer and for removed signer
304
+ (vote) => !vote[1][0].equals(beneficiary) && !vote[1][1].equals(beneficiary));
305
+ this.DEBUG &&
306
+ debug(`[Block ${header.number}] Clique majority consensus (DROP ${beneficiary})`);
307
+ }
308
+ if (round === 1) {
309
+ // Always add the latest vote to the history no matter if already voted
310
+ // the same vote or not
311
+ this._cliqueLatestVotes.push(latestVote);
312
+ this.DEBUG &&
313
+ debug(`[Block ${header.number}] New clique vote: ${signer} -> ${beneficiary} ${equalsBytes(nonce, CLIQUE_NONCE_AUTH) ? 'AUTH' : 'DROP'}`);
314
+ }
315
+ if (consensus) {
316
+ if (round === 1) {
317
+ this.DEBUG &&
318
+ debug(`[Block ${header.number}] Clique majority consensus on existing votes -> update signer states`);
319
+ }
320
+ else {
321
+ this.DEBUG &&
322
+ debug(`[Block ${header.number}] Clique majority consensus on new vote -> update signer states`);
323
+ }
324
+ const newSignerState = [header.number, activeSigners];
325
+ await this.cliqueUpdateSignerStates(newSignerState);
326
+ return;
327
+ }
328
+ }
329
+ }
330
+ // trim to lastEpochBlockNumber - CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT
331
+ const limit = this.CLIQUE_SIGNER_HISTORY_BLOCK_LIMIT;
332
+ const blockSigners = this._cliqueLatestBlockSigners;
333
+ const lastBlockNumber = blockSigners[blockSigners.length - 1]?.[0];
334
+ if (lastBlockNumber) {
335
+ const lastEpochBlockNumber = lastBlockNumber -
336
+ (lastBlockNumber %
337
+ BigInt(this.blockchain.common.consensusConfig().epoch));
338
+ const blockLimit = lastEpochBlockNumber - BigInt(limit);
339
+ this._cliqueLatestVotes = this._cliqueLatestVotes.filter((state) => state[0] >= blockLimit);
340
+ }
341
+ // save votes to db
342
+ const formatted = this._cliqueLatestVotes.map((v) => [
343
+ bigIntToBytes(v[0]),
344
+ [v[1][0].toBytes(), v[1][1].toBytes(), v[1][2]],
345
+ ]);
346
+ await this.blockchain.db.put(CLIQUE_VOTES_KEY, RLP.encode(formatted));
347
+ }
348
+ /**
349
+ * Returns a list with the current block signers
350
+ */
351
+ cliqueActiveSigners(blockNum) {
352
+ const signers = this._cliqueLatestSignerStates;
353
+ if (signers.length === 0) {
354
+ return [];
355
+ }
356
+ for (let i = signers.length - 1; i >= 0; i--) {
357
+ if (signers[i][0] < blockNum) {
358
+ return signers[i][1];
359
+ }
360
+ }
361
+ throw EthereumJSErrorWithoutCode(`Could not load signers for block ${blockNum}`);
362
+ }
363
+ /**
364
+ * Number of consecutive blocks out of which a signer may only sign one.
365
+ * Defined as `Math.floor(SIGNER_COUNT / 2) + 1` to enforce majority consensus.
366
+ * signer count -> signer limit:
367
+ * 1 -> 1, 2 -> 2, 3 -> 2, 4 -> 2, 5 -> 3, ...
368
+ * @hidden
369
+ */
370
+ cliqueSignerLimit(blockNum) {
371
+ return Math.floor(this.cliqueActiveSigners(blockNum).length / 2) + 1;
372
+ }
373
+ /**
374
+ * Checks if signer was recently signed.
375
+ * Returns true if signed too recently: more than once per {@link CliqueConsensus.cliqueSignerLimit} consecutive blocks.
376
+ * @param header BlockHeader
377
+ * @hidden
378
+ */
379
+ cliqueCheckRecentlySigned(header) {
380
+ if (header.isGenesis() || header.number === BigInt(1)) {
381
+ // skip genesis, first block
382
+ return false;
383
+ }
384
+ const limit = this.cliqueSignerLimit(header.number);
385
+ // construct recent block signers list with this block
386
+ let signers = this._cliqueLatestBlockSigners;
387
+ signers = signers.slice(signers.length < limit ? 0 : 1);
388
+ if (signers.length > 0 && signers[signers.length - 1][0] !== header.number - BigInt(1)) {
389
+ // if the last signed block is not one minus the head we are trying to compare
390
+ // we do not have a complete picture of the state to verify if too recently signed
391
+ return false;
392
+ }
393
+ signers.push([header.number, cliqueSigner(header)]);
394
+ const seen = signers.filter((s) => s[1].equals(cliqueSigner(header))).length;
395
+ return seen > 1;
396
+ }
397
+ /**
398
+ * Remove clique snapshots with blockNumber higher than input.
399
+ * @param blockNumber - the block number from which we start deleting
400
+ * @hidden
401
+ */
402
+ async _cliqueDeleteSnapshots(blockNumber) {
403
+ // remove blockNumber from clique snapshots
404
+ // (latest signer states, latest votes, latest block signers)
405
+ this._cliqueLatestSignerStates = this._cliqueLatestSignerStates.filter((s) => s[0] <= blockNumber);
406
+ await this.cliqueUpdateSignerStates();
407
+ this._cliqueLatestVotes = this._cliqueLatestVotes.filter((v) => v[0] <= blockNumber);
408
+ await this.cliqueUpdateVotes();
409
+ this._cliqueLatestBlockSigners = this._cliqueLatestBlockSigners.filter((s) => s[0] <= blockNumber);
410
+ await this.cliqueUpdateLatestBlockSigners();
411
+ }
412
+ /**
413
+ * Update snapshot of latest clique block signers.
414
+ * Used for checking for 'recently signed' error.
415
+ * Length trimmed to {@link Blockchain.cliqueSignerLimit}.
416
+ * @param header BlockHeader
417
+ * @hidden
418
+ */
419
+ async cliqueUpdateLatestBlockSigners(header) {
420
+ if (header) {
421
+ if (header.isGenesis()) {
422
+ return;
423
+ }
424
+ // add this block's signer
425
+ const signer = [header.number, cliqueSigner(header)];
426
+ this._cliqueLatestBlockSigners.push(signer);
427
+ // trim length to `this.cliqueSignerLimit()`
428
+ const length = this._cliqueLatestBlockSigners.length;
429
+ const limit = this.cliqueSignerLimit(header.number);
430
+ if (length > limit) {
431
+ this._cliqueLatestBlockSigners = this._cliqueLatestBlockSigners.slice(length - limit, length);
432
+ }
433
+ }
434
+ // save to db
435
+ const formatted = this._cliqueLatestBlockSigners.map((b) => [
436
+ bigIntToBytes(b[0]),
437
+ b[1].toBytes(),
438
+ ]);
439
+ await this.blockchain.db.put(CLIQUE_BLOCK_SIGNERS_SNAPSHOT_KEY, RLP.encode(formatted));
440
+ }
441
+ /**
442
+ * Fetches clique signers.
443
+ * @hidden
444
+ */
445
+ async getCliqueLatestSignerStates() {
446
+ const signerStates = await this.blockchain.db.get(CLIQUE_SIGNERS_KEY);
447
+ if (signerStates === undefined)
448
+ return [];
449
+ const states = RLP.decode(signerStates);
450
+ return states.map((state) => {
451
+ const blockNum = bytesToBigInt(state[0]);
452
+ const addresses = state[1].map((bytes) => {
453
+ const address = new Address(bytes);
454
+ return address;
455
+ });
456
+ return [blockNum, addresses];
457
+ });
458
+ }
459
+ /**
460
+ * Fetches clique votes.
461
+ * @hidden
462
+ */
463
+ async getCliqueLatestVotes() {
464
+ const signerVotes = await this.blockchain.db.get(CLIQUE_VOTES_KEY);
465
+ if (signerVotes === undefined)
466
+ return [];
467
+ const votes = RLP.decode(signerVotes);
468
+ return votes.map((vote) => {
469
+ const blockNum = bytesToBigInt(vote[0]);
470
+ const signer = new Address(vote[1][0]);
471
+ const beneficiary = new Address(vote[1][1]);
472
+ const nonce = vote[1][2];
473
+ return [blockNum, [signer, beneficiary, nonce]];
474
+ });
475
+ }
476
+ /**
477
+ * Fetches snapshot of clique signers.
478
+ * @hidden
479
+ */
480
+ async getCliqueLatestBlockSigners() {
481
+ const blockSigners = await this.blockchain.db.get(CLIQUE_BLOCK_SIGNERS_SNAPSHOT_KEY);
482
+ if (blockSigners === undefined)
483
+ return [];
484
+ const signers = RLP.decode(blockSigners);
485
+ return signers.map((s) => {
486
+ const blockNum = bytesToBigInt(s[0]);
487
+ const signer = new Address(s[1]);
488
+ return [blockNum, signer];
489
+ });
490
+ }
491
+ /**
492
+ * Build clique snapshots.
493
+ * @param header - the new block header
494
+ * @hidden
495
+ */
496
+ async _cliqueBuildSnapshots(header) {
497
+ if (!cliqueIsEpochTransition(header)) {
498
+ await this.cliqueUpdateVotes(header);
499
+ }
500
+ await this.cliqueUpdateLatestBlockSigners(header);
501
+ }
502
+ /**
503
+ * Helper to determine if a signer is in or out of turn for the next block.
504
+ * @param signer The signer address
505
+ */
506
+ async cliqueSignerInTurn(signer, blockNum) {
507
+ const signers = this.cliqueActiveSigners(blockNum);
508
+ const signerIndex = signers.findIndex((address) => address.equals(signer));
509
+ if (signerIndex === -1) {
510
+ throw EthereumJSErrorWithoutCode('Signer not found');
511
+ }
512
+ const { number } = await this.blockchain.getCanonicalHeadHeader();
513
+ return (number + BigInt(1)) % BigInt(signers.length) === BigInt(signerIndex);
514
+ }
515
+ }
516
+ //# sourceMappingURL=clique.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clique.js","sourceRoot":"","sources":["../../../src/consensus/clique.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { ConsensusAlgorithm } from '@feelyourprotocol/common';
2
+ import type { Block, BlockHeader } from '@feelyourprotocol/block';
3
+ import type { Blockchain } from '../index.ts';
4
+ import type { Consensus, ConsensusOptions } from '../types.ts';
5
+ export type MinimalEthashInterface = {
6
+ cacheDB?: any;
7
+ verifyPOW(block: Block): Promise<boolean>;
8
+ };
9
+ /**
10
+ * This class encapsulates Ethash-related consensus functionality when used with the Blockchain class.
11
+ */
12
+ export declare class EthashConsensus implements Consensus {
13
+ blockchain: Blockchain | undefined;
14
+ algorithm: ConsensusAlgorithm;
15
+ _ethash: MinimalEthashInterface;
16
+ private DEBUG;
17
+ private _debug;
18
+ constructor(ethash: MinimalEthashInterface);
19
+ validateConsensus(block: Block): Promise<void>;
20
+ /**
21
+ * Checks that the block's `difficulty` matches the canonical difficulty of the parent header.
22
+ * @param header - header of block to be checked
23
+ */
24
+ validateDifficulty(header: BlockHeader): Promise<void>;
25
+ genesisInit(): Promise<void>;
26
+ setup({ blockchain }: ConsensusOptions): Promise<void>;
27
+ newBlock(): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=ethash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ethash.d.ts","sourceRoot":"","sources":["../../../src/consensus/ethash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAIvD,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9D,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,CAAC,EAAE,GAAG,CAAA;IACb,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAC1C,CAAA;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAC/C,UAAU,EAAE,UAAU,GAAG,SAAS,CAAA;IAClC,SAAS,EAAE,kBAAkB,CAAA;IAC7B,OAAO,EAAE,sBAAsB,CAAA;IAE/B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAU;gBAEZ,MAAM,EAAE,sBAAsB;IAQpC,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAWpD;;;OAGG;IACG,kBAAkB,CAAC,MAAM,EAAE,WAAW;IAc/B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CACvC"}
@@ -0,0 +1,44 @@
1
+ import { ConsensusAlgorithm } from '@feelyourprotocol/common';
2
+ import { EthereumJSErrorWithoutCode, bytesToHex, isDebugEnabled } from '@feelyourprotocol/util';
3
+ import debugDefault from 'debug';
4
+ /**
5
+ * This class encapsulates Ethash-related consensus functionality when used with the Blockchain class.
6
+ */
7
+ export class EthashConsensus {
8
+ constructor(ethash) {
9
+ this.DEBUG = isDebugEnabled('ethjs');
10
+ this._debug = debugDefault('blockchain:ethash');
11
+ this.algorithm = ConsensusAlgorithm.Ethash;
12
+ this._ethash = ethash;
13
+ }
14
+ async validateConsensus(block) {
15
+ const valid = await this._ethash.verifyPOW(block);
16
+ if (!valid) {
17
+ throw EthereumJSErrorWithoutCode('invalid POW');
18
+ }
19
+ this.DEBUG &&
20
+ this._debug(`valid PoW consensus block: number ${block.header.number} hash ${bytesToHex(block.hash())}`);
21
+ }
22
+ /**
23
+ * Checks that the block's `difficulty` matches the canonical difficulty of the parent header.
24
+ * @param header - header of block to be checked
25
+ */
26
+ async validateDifficulty(header) {
27
+ if (!this.blockchain) {
28
+ throw EthereumJSErrorWithoutCode('blockchain not provided');
29
+ }
30
+ const parentHeader = await this.blockchain['_getHeader'](header.parentHash);
31
+ if (header.ethashCanonicalDifficulty(parentHeader) !== header.difficulty) {
32
+ throw EthereumJSErrorWithoutCode(`invalid difficulty ${header.errorStr()}`);
33
+ }
34
+ this.DEBUG &&
35
+ this._debug(`valid difficulty header: number ${header.number} difficulty ${header.difficulty} parentHash ${bytesToHex(header.parentHash)}`);
36
+ }
37
+ async genesisInit() { }
38
+ async setup({ blockchain }) {
39
+ this.blockchain = blockchain;
40
+ this._ethash.cacheDB = this.blockchain.db;
41
+ }
42
+ async newBlock() { }
43
+ }
44
+ //# sourceMappingURL=ethash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ethash.js","sourceRoot":"","sources":["../../../src/consensus/ethash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,0BAA0B,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACzF,OAAO,YAAY,MAAM,OAAO,CAAA;AAYhC;;GAEG;AACH,MAAM,OAAO,eAAe;IAQ1B,YAAY,MAA8B;QACxC,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QACpC,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAA;QAE/C,IAAI,CAAC,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAA;QAC1C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,KAAY;QAClC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QACjD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,0BAA0B,CAAC,aAAa,CAAC,CAAA;QACjD,CAAC;QACD,IAAI,CAAC,KAAK;YACR,IAAI,CAAC,MAAM,CACT,qCAAqC,KAAK,CAAC,MAAM,CAAC,MAAM,SAAS,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAC5F,CAAA;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,kBAAkB,CAAC,MAAmB;QAC1C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,0BAA0B,CAAC,yBAAyB,CAAC,CAAA;QAC7D,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAC3E,IAAI,MAAM,CAAC,yBAAyB,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC,UAAU,EAAE,CAAC;YACzE,MAAM,0BAA0B,CAAC,sBAAsB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QAC7E,CAAC;QACD,IAAI,CAAC,KAAK;YACR,IAAI,CAAC,MAAM,CACT,mCAAmC,MAAM,CAAC,MAAM,eAAe,MAAM,CAAC,UAAU,eAAe,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAC/H,CAAA;IACL,CAAC;IAEM,KAAK,CAAC,WAAW,KAAmB,CAAC;IACrC,KAAK,CAAC,KAAK,CAAC,EAAE,UAAU,EAAoB;QACjD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAA;IAC3C,CAAC;IACM,KAAK,CAAC,QAAQ,KAAmB,CAAC;CAC1C"}
@@ -0,0 +1,5 @@
1
+ import { CasperConsensus } from './casper.ts';
2
+ import { CliqueConsensus } from './clique.ts';
3
+ import { EthashConsensus } from './ethash.ts';
4
+ export { CasperConsensus, CliqueConsensus, EthashConsensus };
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/consensus/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { CasperConsensus } from "./casper.js";
2
+ import { CliqueConsensus } from "./clique.js";
3
+ import { EthashConsensus } from "./ethash.js";
4
+ export { CasperConsensus, CliqueConsensus, EthashConsensus };
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/consensus/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,CAAA"}