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