@feelyourprotocol/common 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.
- package/LICENSE +22 -0
- package/README.md +409 -0
- package/dist/cjs/chains.d.ts +6 -0
- package/dist/cjs/chains.d.ts.map +1 -0
- package/dist/cjs/chains.js +637 -0
- package/dist/cjs/chains.js.map +1 -0
- package/dist/cjs/common.d.ts +318 -0
- package/dist/cjs/common.d.ts.map +1 -0
- package/dist/cjs/common.js +789 -0
- package/dist/cjs/common.js.map +1 -0
- package/dist/cjs/constructors.d.ts +27 -0
- package/dist/cjs/constructors.d.ts.map +1 -0
- package/dist/cjs/constructors.js +53 -0
- package/dist/cjs/constructors.js.map +1 -0
- package/dist/cjs/crc.d.ts +8 -0
- package/dist/cjs/crc.d.ts.map +1 -0
- package/dist/cjs/crc.js +63 -0
- package/dist/cjs/crc.js.map +1 -0
- package/dist/cjs/eips.d.ts +3 -0
- package/dist/cjs/eips.d.ts.map +1 -0
- package/dist/cjs/eips.js +589 -0
- package/dist/cjs/eips.js.map +1 -0
- package/dist/cjs/enums.d.ts +65 -0
- package/dist/cjs/enums.d.ts.map +1 -0
- package/dist/cjs/enums.js +80 -0
- package/dist/cjs/enums.js.map +1 -0
- package/dist/cjs/gethGenesis.d.ts +145 -0
- package/dist/cjs/gethGenesis.d.ts.map +1 -0
- package/dist/cjs/gethGenesis.js +26 -0
- package/dist/cjs/gethGenesis.js.map +1 -0
- package/dist/cjs/hardforks.d.ts +3 -0
- package/dist/cjs/hardforks.d.ts.map +1 -0
- package/dist/cjs/hardforks.js +207 -0
- package/dist/cjs/hardforks.js.map +1 -0
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/interfaces.d.ts +132 -0
- package/dist/cjs/interfaces.d.ts.map +1 -0
- package/dist/cjs/interfaces.js +13 -0
- package/dist/cjs/interfaces.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/types.d.ts +167 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils.d.ts +60 -0
- package/dist/cjs/utils.d.ts.map +1 -0
- package/dist/cjs/utils.js +263 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/esm/chains.d.ts +6 -0
- package/dist/esm/chains.d.ts.map +1 -0
- package/dist/esm/chains.js +634 -0
- package/dist/esm/chains.js.map +1 -0
- package/dist/esm/common.d.ts +318 -0
- package/dist/esm/common.d.ts.map +1 -0
- package/dist/esm/common.js +785 -0
- package/dist/esm/common.js.map +1 -0
- package/dist/esm/constructors.d.ts +27 -0
- package/dist/esm/constructors.d.ts.map +1 -0
- package/dist/esm/constructors.js +49 -0
- package/dist/esm/constructors.js.map +1 -0
- package/dist/esm/crc.d.ts +8 -0
- package/dist/esm/crc.d.ts.map +1 -0
- package/dist/esm/crc.js +59 -0
- package/dist/esm/crc.js.map +1 -0
- package/dist/esm/eips.d.ts +3 -0
- package/dist/esm/eips.d.ts.map +1 -0
- package/dist/esm/eips.js +586 -0
- package/dist/esm/eips.js.map +1 -0
- package/dist/esm/enums.d.ts +65 -0
- package/dist/esm/enums.d.ts.map +1 -0
- package/dist/esm/enums.js +77 -0
- package/dist/esm/enums.js.map +1 -0
- package/dist/esm/gethGenesis.d.ts +145 -0
- package/dist/esm/gethGenesis.d.ts.map +1 -0
- package/dist/esm/gethGenesis.js +23 -0
- package/dist/esm/gethGenesis.js.map +1 -0
- package/dist/esm/hardforks.d.ts +3 -0
- package/dist/esm/hardforks.d.ts.map +1 -0
- package/dist/esm/hardforks.js +204 -0
- package/dist/esm/hardforks.js.map +1 -0
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/interfaces.d.ts +132 -0
- package/dist/esm/interfaces.d.ts.map +1 -0
- package/dist/esm/interfaces.js +10 -0
- package/dist/esm/interfaces.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/types.d.ts +167 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils.d.ts +60 -0
- package/dist/esm/utils.d.ts.map +1 -0
- package/dist/esm/utils.js +258 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.prod.esm.tsbuildinfo +1 -0
- package/package.json +77 -0
- package/src/chains.ts +638 -0
- package/src/common.ts +913 -0
- package/src/constructors.ts +60 -0
- package/src/crc.ts +63 -0
- package/src/eips.ts +588 -0
- package/src/enums.ts +104 -0
- package/src/gethGenesis.ts +175 -0
- package/src/hardforks.ts +205 -0
- package/src/index.ts +8 -0
- package/src/interfaces.ts +191 -0
- package/src/types.ts +193 -0
- package/src/utils.ts +324 -0
|
@@ -0,0 +1,785 @@
|
|
|
1
|
+
import { BIGINT_0, EthereumJSErrorWithoutCode, TypeOutput, bytesToHex, concatBytes, hexToBytes, intToBytes, toType, } from '@feelyourprotocol/util';
|
|
2
|
+
import { EventEmitter } from 'eventemitter3';
|
|
3
|
+
import { crc32 } from "./crc.js";
|
|
4
|
+
import { eipsDict } from "./eips.js";
|
|
5
|
+
import { Hardfork } from "./enums.js";
|
|
6
|
+
import { hardforksDict } from "./hardforks.js";
|
|
7
|
+
/**
|
|
8
|
+
* Common class to access chain and hardfork parameters and to provide
|
|
9
|
+
* a unified and shared view on the network and hardfork state.
|
|
10
|
+
*
|
|
11
|
+
* Use the {@link createCustomCommon} constructor for creating simple
|
|
12
|
+
* custom chain {@link Common} objects (more complete custom chain setups
|
|
13
|
+
* can be created via the main constructor).
|
|
14
|
+
*
|
|
15
|
+
* Use the {@link createCommonFromGethGenesis} constructor for creating
|
|
16
|
+
* a Common object from a Geth genesis file.
|
|
17
|
+
*/
|
|
18
|
+
export class Common {
|
|
19
|
+
constructor(opts) {
|
|
20
|
+
this._eips = [];
|
|
21
|
+
this._paramsCache = {};
|
|
22
|
+
this._activatedEIPsCache = [];
|
|
23
|
+
this.events = new EventEmitter();
|
|
24
|
+
this._chainParams = JSON.parse(JSON.stringify(opts.chain)); // copy
|
|
25
|
+
this.DEFAULT_HARDFORK = this._chainParams.defaultHardfork ?? Hardfork.Prague;
|
|
26
|
+
// Assign hardfork changes in the sequence of the applied hardforks
|
|
27
|
+
this.HARDFORK_CHANGES = this.hardforks().map((hf) => [
|
|
28
|
+
hf.name,
|
|
29
|
+
// Allow to even override an existing hardfork specification
|
|
30
|
+
(this._chainParams.customHardforks && this._chainParams.customHardforks[hf.name]) ??
|
|
31
|
+
hardforksDict[hf.name],
|
|
32
|
+
]);
|
|
33
|
+
this._hardfork = this.DEFAULT_HARDFORK;
|
|
34
|
+
this._params = opts.params ? JSON.parse(JSON.stringify(opts.params)) : {}; // copy
|
|
35
|
+
if (opts.hardfork !== undefined) {
|
|
36
|
+
this.setHardfork(opts.hardfork);
|
|
37
|
+
}
|
|
38
|
+
if (opts.eips) {
|
|
39
|
+
this.setEIPs(opts.eips);
|
|
40
|
+
}
|
|
41
|
+
this.customCrypto = opts.customCrypto ?? {};
|
|
42
|
+
if (Object.keys(this._paramsCache).length === 0) {
|
|
43
|
+
this._buildParamsCache();
|
|
44
|
+
this._buildActivatedEIPsCache();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Update the internal Common EIP params set. Existing values
|
|
49
|
+
* will get preserved unless there is a new value for a parameter
|
|
50
|
+
* provided with params.
|
|
51
|
+
*
|
|
52
|
+
* Example Format:
|
|
53
|
+
*
|
|
54
|
+
* ```ts
|
|
55
|
+
* {
|
|
56
|
+
* 1559: {
|
|
57
|
+
* initialBaseFee: 1000000000,
|
|
58
|
+
* }
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @param params
|
|
63
|
+
*/
|
|
64
|
+
updateParams(params) {
|
|
65
|
+
for (const [eip, paramsConfig] of Object.entries(params)) {
|
|
66
|
+
if (!(eip in this._params)) {
|
|
67
|
+
this._params[eip] = JSON.parse(JSON.stringify(paramsConfig)); // copy
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this._params[eip] = JSON.parse(JSON.stringify({ ...this._params[eip], ...params[eip] })); // copy
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
this._buildParamsCache();
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Fully resets the internal Common EIP params set with the values provided.
|
|
77
|
+
*
|
|
78
|
+
* Example Format:
|
|
79
|
+
*
|
|
80
|
+
* ```ts
|
|
81
|
+
* {
|
|
82
|
+
* 1559: {
|
|
83
|
+
* initialBaseFee: 1000000000,
|
|
84
|
+
* }
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @param params
|
|
89
|
+
*/
|
|
90
|
+
resetParams(params) {
|
|
91
|
+
this._params = JSON.parse(JSON.stringify(params)); // copy
|
|
92
|
+
this._buildParamsCache();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Sets the hardfork to get params for
|
|
96
|
+
* @param hardfork String identifier (e.g. 'byzantium') or {@link Hardfork} enum
|
|
97
|
+
*/
|
|
98
|
+
setHardfork(hardfork) {
|
|
99
|
+
let existing = false;
|
|
100
|
+
for (const hfChanges of this.HARDFORK_CHANGES) {
|
|
101
|
+
if (hfChanges[0] === hardfork) {
|
|
102
|
+
if (this._hardfork !== hardfork) {
|
|
103
|
+
this._hardfork = hardfork;
|
|
104
|
+
this._buildParamsCache();
|
|
105
|
+
this._buildActivatedEIPsCache();
|
|
106
|
+
this.events.emit('hardforkChanged', hardfork);
|
|
107
|
+
}
|
|
108
|
+
existing = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!existing) {
|
|
112
|
+
throw EthereumJSErrorWithoutCode(`Hardfork with name ${hardfork} not supported`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Returns the hardfork either based on block number (older HFs) or
|
|
117
|
+
* timestamp (Shanghai upwards).
|
|
118
|
+
*
|
|
119
|
+
* @param opts Block number or timestamp
|
|
120
|
+
* @returns The name of the HF
|
|
121
|
+
*/
|
|
122
|
+
getHardforkBy(opts) {
|
|
123
|
+
const blockNumber = toType(opts.blockNumber, TypeOutput.BigInt);
|
|
124
|
+
const timestamp = toType(opts.timestamp, TypeOutput.BigInt);
|
|
125
|
+
// Filter out hardforks with no block number, no timestamp (i.e. unapplied hardforks)
|
|
126
|
+
const hfs = this.hardforks().filter((hf) => hf.block !== null || hf.timestamp !== undefined);
|
|
127
|
+
// Find the first hardfork that has a block number greater than `blockNumber`
|
|
128
|
+
// If timestamp is not provided, it also skips timestamps hardforks to continue
|
|
129
|
+
// discovering/checking number hardforks.
|
|
130
|
+
let hfIndex = hfs.findIndex((hf) => (blockNumber !== undefined && hf.block !== null && BigInt(hf.block) > blockNumber) ||
|
|
131
|
+
(timestamp !== undefined && hf.timestamp !== undefined && BigInt(hf.timestamp) > timestamp));
|
|
132
|
+
if (hfIndex === -1) {
|
|
133
|
+
// all hardforks apply, set hfIndex to the last one as that's the candidate
|
|
134
|
+
hfIndex = hfs.length;
|
|
135
|
+
}
|
|
136
|
+
else if (hfIndex === 0) {
|
|
137
|
+
// cannot have a case where a block number is before all applied hardforks
|
|
138
|
+
// since the chain has to start with a hardfork
|
|
139
|
+
throw Error('Must have at least one hardfork at block 0');
|
|
140
|
+
}
|
|
141
|
+
// If timestamp is not provided, we need to rollback to the last hf with block
|
|
142
|
+
if (timestamp === undefined) {
|
|
143
|
+
const stepBack = hfs
|
|
144
|
+
.slice(0, hfIndex)
|
|
145
|
+
.reverse()
|
|
146
|
+
.findIndex((hf) => hf.block !== null);
|
|
147
|
+
hfIndex = hfIndex - stepBack;
|
|
148
|
+
}
|
|
149
|
+
// Move hfIndex one back to arrive at candidate hardfork
|
|
150
|
+
hfIndex = hfIndex - 1;
|
|
151
|
+
const hfStartIndex = hfIndex;
|
|
152
|
+
// Move the hfIndex to the end of the hardforks that might be scheduled on the same block/timestamp
|
|
153
|
+
// This won't anyway be the case with Merge hfs
|
|
154
|
+
for (; hfIndex < hfs.length - 1; hfIndex++) {
|
|
155
|
+
// break out if hfIndex + 1 is not scheduled at hfIndex
|
|
156
|
+
if (hfs[hfIndex].block !== hfs[hfIndex + 1].block ||
|
|
157
|
+
hfs[hfIndex].timestamp !== hfs[hfIndex + 1].timestamp) {
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (timestamp !== undefined) {
|
|
162
|
+
const minTimeStamp = hfs
|
|
163
|
+
.slice(0, hfStartIndex)
|
|
164
|
+
.reduce((acc, hf) => Math.max(Number(hf.timestamp ?? '0'), acc), 0);
|
|
165
|
+
if (minTimeStamp > timestamp) {
|
|
166
|
+
throw Error(`Maximum HF determined by timestamp is lower than the block number HF`);
|
|
167
|
+
}
|
|
168
|
+
const maxTimeStamp = hfs
|
|
169
|
+
.slice(hfIndex + 1)
|
|
170
|
+
.reduce((acc, hf) => Math.min(Number(hf.timestamp ?? timestamp), acc), Number(timestamp));
|
|
171
|
+
if (maxTimeStamp < timestamp) {
|
|
172
|
+
throw Error(`Maximum HF determined by block number is lower than timestamp HF`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const hardfork = hfs[hfIndex];
|
|
176
|
+
return hardfork.name;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Sets a new hardfork either based on block number (older HFs) or
|
|
180
|
+
* timestamp (Shanghai upwards).
|
|
181
|
+
*
|
|
182
|
+
* @param opts Block number or timestamp
|
|
183
|
+
* @returns The name of the HF set
|
|
184
|
+
*/
|
|
185
|
+
setHardforkBy(opts) {
|
|
186
|
+
const hardfork = this.getHardforkBy(opts);
|
|
187
|
+
this.setHardfork(hardfork);
|
|
188
|
+
return hardfork;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Internal helper function, returns the params for the given hardfork for the chain set
|
|
192
|
+
* @param hardfork Hardfork name
|
|
193
|
+
* @returns Dictionary with hardfork params or null if hardfork not on chain
|
|
194
|
+
*/
|
|
195
|
+
_getHardfork(hardfork) {
|
|
196
|
+
const hfs = this.hardforks();
|
|
197
|
+
for (const hf of hfs) {
|
|
198
|
+
if (hf['name'] === hardfork)
|
|
199
|
+
return hf;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Sets the active EIPs
|
|
205
|
+
* @param eips
|
|
206
|
+
*/
|
|
207
|
+
setEIPs(eips = []) {
|
|
208
|
+
for (const eip of eips) {
|
|
209
|
+
if (!(eip in eipsDict)) {
|
|
210
|
+
throw EthereumJSErrorWithoutCode(`${eip} not supported`);
|
|
211
|
+
}
|
|
212
|
+
const minHF = this.gteHardfork(eipsDict[eip]['minimumHardfork']);
|
|
213
|
+
if (!minHF) {
|
|
214
|
+
throw EthereumJSErrorWithoutCode(`${eip} cannot be activated on hardfork ${this.hardfork()}, minimumHardfork: ${minHF}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
this._eips = eips;
|
|
218
|
+
this._buildParamsCache();
|
|
219
|
+
this._buildActivatedEIPsCache();
|
|
220
|
+
for (const eip of eips) {
|
|
221
|
+
if (eipsDict[eip].requiredEIPs !== undefined) {
|
|
222
|
+
for (const elem of eipsDict[eip].requiredEIPs) {
|
|
223
|
+
if (!(eips.includes(elem) || this.isActivatedEIP(elem))) {
|
|
224
|
+
throw EthereumJSErrorWithoutCode(`${eip} requires EIP ${elem}, but is not included in the EIP list`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Internal helper for _buildParamsCache()
|
|
232
|
+
*/
|
|
233
|
+
_mergeWithParamsCache(params) {
|
|
234
|
+
for (const [key, value] of Object.entries(params)) {
|
|
235
|
+
this._paramsCache[key] = value;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Build up a cache for all parameter values for the current HF and all activated EIPs
|
|
240
|
+
*/
|
|
241
|
+
_buildParamsCache() {
|
|
242
|
+
this._paramsCache = {};
|
|
243
|
+
// Iterate through all hardforks up to hardfork set
|
|
244
|
+
const hardfork = this.hardfork();
|
|
245
|
+
for (const hfChanges of this.HARDFORK_CHANGES) {
|
|
246
|
+
// EIP-referencing HF config (e.g. for berlin)
|
|
247
|
+
if ('eips' in hfChanges[1]) {
|
|
248
|
+
const hfEIPs = hfChanges[1].eips ?? [];
|
|
249
|
+
for (const eip of hfEIPs) {
|
|
250
|
+
if (this._params[eip] !== undefined && this._params[eip] !== null) {
|
|
251
|
+
this._mergeWithParamsCache(this._params[eip]);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Hardfork-scoped params (e.g. for bpo1, bpo2)
|
|
256
|
+
// override the baseline EIP values when present
|
|
257
|
+
const hfScopedParams = this._params[hfChanges[0]];
|
|
258
|
+
if (hfScopedParams !== undefined && hfScopedParams !== null) {
|
|
259
|
+
this._mergeWithParamsCache(hfScopedParams);
|
|
260
|
+
}
|
|
261
|
+
// Parameter-inlining HF config (e.g. for istanbul or custom blobSchedule)
|
|
262
|
+
if (hfChanges[1].params !== undefined && hfChanges[1].params !== null) {
|
|
263
|
+
this._mergeWithParamsCache(hfChanges[1].params);
|
|
264
|
+
}
|
|
265
|
+
if (hfChanges[0] === hardfork)
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
// Iterate through all additionally activated EIPs
|
|
269
|
+
for (const eip of this._eips) {
|
|
270
|
+
if (this._params[eip] !== undefined && this._params[eip] !== null) {
|
|
271
|
+
this._mergeWithParamsCache(this._params[eip]);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Builds the cache of EIPs activated either via hardforks or constructor `eips`.
|
|
277
|
+
*/
|
|
278
|
+
_buildActivatedEIPsCache() {
|
|
279
|
+
this._activatedEIPsCache = [];
|
|
280
|
+
for (const [name, hf] of this.HARDFORK_CHANGES) {
|
|
281
|
+
if (this.gteHardfork(name) && 'eips' in hf) {
|
|
282
|
+
this._activatedEIPsCache = this._activatedEIPsCache.concat(hf.eips ?? []);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
this._activatedEIPsCache = this._activatedEIPsCache.concat(this._eips);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Returns a parameter for the current chain setup
|
|
289
|
+
*
|
|
290
|
+
* If the parameter is present in an EIP, the EIP always takes precedence.
|
|
291
|
+
* Otherwise the parameter is taken from the latest applied HF with
|
|
292
|
+
* a change on the respective parameter.
|
|
293
|
+
*
|
|
294
|
+
* @param name Parameter name (e.g. 'minGasLimit')
|
|
295
|
+
* @returns The value requested (throws if not found)
|
|
296
|
+
*/
|
|
297
|
+
param(name) {
|
|
298
|
+
// TODO: consider the case that different active EIPs
|
|
299
|
+
// can change the same parameter
|
|
300
|
+
if (!(name in this._paramsCache)) {
|
|
301
|
+
throw EthereumJSErrorWithoutCode(`Missing parameter value for ${name}`);
|
|
302
|
+
}
|
|
303
|
+
const value = this._paramsCache[name];
|
|
304
|
+
return BigInt(value ?? 0);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Returns the parameter corresponding to a hardfork
|
|
308
|
+
* @param name Parameter name (e.g. 'minGasLimit')
|
|
309
|
+
* @param hardfork Hardfork name
|
|
310
|
+
* @returns The value requested (throws if not found)
|
|
311
|
+
*/
|
|
312
|
+
paramByHardfork(name, hardfork) {
|
|
313
|
+
let value;
|
|
314
|
+
for (const hfChanges of this.HARDFORK_CHANGES) {
|
|
315
|
+
// EIP-referencing HF config (e.g. for berlin)
|
|
316
|
+
if ('eips' in hfChanges[1]) {
|
|
317
|
+
const hfEIPs = hfChanges[1]['eips'];
|
|
318
|
+
for (const eip of hfEIPs) {
|
|
319
|
+
const eipParams = this._params[eip];
|
|
320
|
+
const eipValue = eipParams?.[name];
|
|
321
|
+
if (eipValue !== undefined) {
|
|
322
|
+
value = eipValue;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// Parameter-inlining HF config (e.g. for istanbul)
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
const hfValue = hfChanges[1].params?.[name];
|
|
329
|
+
if (hfValue !== undefined) {
|
|
330
|
+
value = hfValue;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (hfChanges[0] === hardfork)
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
if (value === undefined) {
|
|
337
|
+
throw EthereumJSErrorWithoutCode(`Missing parameter value for ${name}`);
|
|
338
|
+
}
|
|
339
|
+
return BigInt(value ?? 0);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Returns a parameter corresponding to an EIP
|
|
343
|
+
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
|
|
344
|
+
* @param eip Number of the EIP
|
|
345
|
+
* @returns The value requested (throws if not found)
|
|
346
|
+
*/
|
|
347
|
+
paramByEIP(name, eip) {
|
|
348
|
+
if (!(eip in eipsDict)) {
|
|
349
|
+
throw EthereumJSErrorWithoutCode(`${eip} not supported`);
|
|
350
|
+
}
|
|
351
|
+
const eipParams = this._params[eip];
|
|
352
|
+
if (eipParams?.[name] === undefined) {
|
|
353
|
+
throw EthereumJSErrorWithoutCode(`Missing parameter value for ${name}`);
|
|
354
|
+
}
|
|
355
|
+
const value = eipParams[name];
|
|
356
|
+
return BigInt(value ?? 0);
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Returns a parameter for the hardfork active on block number or
|
|
360
|
+
* optional provided total difficulty (Merge HF)
|
|
361
|
+
* @param name Parameter name
|
|
362
|
+
* @param blockNumber Block number
|
|
363
|
+
* @returns The value requested or `BigInt(0)` if not found
|
|
364
|
+
*/
|
|
365
|
+
paramByBlock(name, blockNumber, timestamp) {
|
|
366
|
+
const hardfork = this.getHardforkBy({ blockNumber, timestamp });
|
|
367
|
+
return this.paramByHardfork(name, hardfork);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Returns the blob gas schedule for the current hardfork
|
|
371
|
+
* @returns The blob gas schedule
|
|
372
|
+
*/
|
|
373
|
+
getBlobGasSchedule() {
|
|
374
|
+
if (this.gteHardfork(Hardfork.Bpo1)) {
|
|
375
|
+
return {
|
|
376
|
+
targetBlobGasPerBlock: this.param('target') * this.param('blobGasPerBlob'),
|
|
377
|
+
maxBlobGasPerBlock: this.param('max') * this.param('blobGasPerBlob'),
|
|
378
|
+
blobGasPriceUpdateFraction: this.param('blobGasPriceUpdateFraction'),
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
return {
|
|
382
|
+
targetBlobGasPerBlock: this.param('targetBlobGasPerBlock'),
|
|
383
|
+
maxBlobGasPerBlock: this.param('maxBlobGasPerBlock'),
|
|
384
|
+
blobGasPriceUpdateFraction: this.param('blobGasPriceUpdateFraction'),
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Checks if an EIP is activated by either being included in the EIPs
|
|
389
|
+
* manually passed in with the {@link CommonOpts.eips} or in a
|
|
390
|
+
* hardfork currently being active
|
|
391
|
+
*
|
|
392
|
+
* Note: this method only works for EIPs being supported
|
|
393
|
+
* by the {@link CommonOpts.eips} constructor option
|
|
394
|
+
* @param eip
|
|
395
|
+
*/
|
|
396
|
+
isActivatedEIP(eip) {
|
|
397
|
+
if (this._activatedEIPsCache.includes(eip)) {
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Checks if set or provided hardfork is active on block number
|
|
404
|
+
* @param hardfork Hardfork name or null (for HF set)
|
|
405
|
+
* @param blockNumber
|
|
406
|
+
* @returns True if HF is active on block number
|
|
407
|
+
*/
|
|
408
|
+
hardforkIsActiveOnBlock(hardfork, blockNumber) {
|
|
409
|
+
blockNumber = toType(blockNumber, TypeOutput.BigInt);
|
|
410
|
+
hardfork = hardfork ?? this._hardfork;
|
|
411
|
+
const hfBlock = this.hardforkBlock(hardfork);
|
|
412
|
+
if (typeof hfBlock === 'bigint' && hfBlock !== BIGINT_0 && blockNumber >= hfBlock) {
|
|
413
|
+
return true;
|
|
414
|
+
}
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Alias to hardforkIsActiveOnBlock when hardfork is set
|
|
419
|
+
* @param blockNumber
|
|
420
|
+
* @returns True if HF is active on block number
|
|
421
|
+
*/
|
|
422
|
+
activeOnBlock(blockNumber) {
|
|
423
|
+
return this.hardforkIsActiveOnBlock(null, blockNumber);
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Sequence based check if given or set HF1 is greater than or equal HF2
|
|
427
|
+
* @param hardfork1 Hardfork name or null (if set)
|
|
428
|
+
* @param hardfork2 Hardfork name
|
|
429
|
+
* @returns True if HF1 gte HF2
|
|
430
|
+
*/
|
|
431
|
+
hardforkGteHardfork(hardfork1, hardfork2) {
|
|
432
|
+
hardfork1 = hardfork1 ?? this._hardfork;
|
|
433
|
+
const hardforks = this.hardforks();
|
|
434
|
+
let posHf1 = -1, posHf2 = -1;
|
|
435
|
+
let index = 0;
|
|
436
|
+
for (const hf of hardforks) {
|
|
437
|
+
if (hf['name'] === hardfork1)
|
|
438
|
+
posHf1 = index;
|
|
439
|
+
if (hf['name'] === hardfork2)
|
|
440
|
+
posHf2 = index;
|
|
441
|
+
index += 1;
|
|
442
|
+
}
|
|
443
|
+
return posHf1 >= posHf2 && posHf2 !== -1;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Alias to hardforkGteHardfork when hardfork is set
|
|
447
|
+
* @param hardfork Hardfork name
|
|
448
|
+
* @returns True if hardfork set is greater than hardfork provided
|
|
449
|
+
*/
|
|
450
|
+
gteHardfork(hardfork) {
|
|
451
|
+
return this.hardforkGteHardfork(null, hardfork);
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Returns the hardfork change block for hardfork provided or set
|
|
455
|
+
* @param hardfork Hardfork name, optional if HF set
|
|
456
|
+
* @returns Block number or null if unscheduled
|
|
457
|
+
*/
|
|
458
|
+
hardforkBlock(hardfork) {
|
|
459
|
+
hardfork = hardfork ?? this._hardfork;
|
|
460
|
+
const block = this._getHardfork(hardfork)?.['block'];
|
|
461
|
+
if (block === undefined || block === null) {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
return BigInt(block);
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Returns the timestamp at which a given hardfork is scheduled (if any).
|
|
468
|
+
* @param hardfork Hardfork name, optional if HF set
|
|
469
|
+
* @returns Timestamp or null if the hardfork is not timestamp-based
|
|
470
|
+
*/
|
|
471
|
+
hardforkTimestamp(hardfork) {
|
|
472
|
+
hardfork = hardfork ?? this._hardfork;
|
|
473
|
+
const timestamp = this._getHardfork(hardfork)?.['timestamp'];
|
|
474
|
+
if (timestamp === undefined || timestamp === null) {
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
return BigInt(timestamp);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Returns the hardfork change block for eip
|
|
481
|
+
* @param eip EIP number
|
|
482
|
+
* @returns Block number or null if unscheduled
|
|
483
|
+
*/
|
|
484
|
+
eipBlock(eip) {
|
|
485
|
+
for (const hfChanges of this.HARDFORK_CHANGES) {
|
|
486
|
+
const hf = hfChanges[1];
|
|
487
|
+
if ('eips' in hf) {
|
|
488
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
489
|
+
if (hf['eips'].includes(eip)) {
|
|
490
|
+
return this.hardforkBlock(hfChanges[0]);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return null;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Returns the scheduled timestamp of the EIP (if scheduled and scheduled by timestamp)
|
|
498
|
+
* @param eip EIP number
|
|
499
|
+
* @returns Scheduled timestamp. If this EIP is unscheduled, or the EIP is scheduled by block number, then it returns `null`.
|
|
500
|
+
*/
|
|
501
|
+
eipTimestamp(eip) {
|
|
502
|
+
for (const hfChanges of this.HARDFORK_CHANGES) {
|
|
503
|
+
const hf = hfChanges[1];
|
|
504
|
+
if ('eips' in hf) {
|
|
505
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
506
|
+
if (hf['eips'].includes(eip)) {
|
|
507
|
+
return this.hardforkTimestamp(hfChanges[0]);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return null;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Returns the block number or timestamp at which the next hardfork will occur.
|
|
515
|
+
* For pre-merge hardforks, returns the block number.
|
|
516
|
+
* For post-merge hardforks, returns the timestamp.
|
|
517
|
+
* Returns null if there is no next hardfork.
|
|
518
|
+
* @param hardfork Hardfork name, optional if HF set
|
|
519
|
+
* @returns Block number or timestamp, or null if not available
|
|
520
|
+
*/
|
|
521
|
+
nextHardforkBlockOrTimestamp(hardfork) {
|
|
522
|
+
const targetHardfork = hardfork ?? this._hardfork;
|
|
523
|
+
const hfs = this.hardforks();
|
|
524
|
+
// Find the index of the target hardfork
|
|
525
|
+
let targetHfIndex = hfs.findIndex((hf) => hf.name === targetHardfork);
|
|
526
|
+
// Special handling for The Merge (Paris) hardfork
|
|
527
|
+
if (targetHardfork === Hardfork.Paris) {
|
|
528
|
+
// The Merge is determined by total difficulty, not block number
|
|
529
|
+
// So we look at the previous hardfork's parameters instead
|
|
530
|
+
targetHfIndex -= 1;
|
|
531
|
+
}
|
|
532
|
+
// If we couldn't find a valid hardfork index, return null
|
|
533
|
+
if (targetHfIndex < 0) {
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
// Get the current hardfork's block/timestamp
|
|
537
|
+
const currentHf = hfs[targetHfIndex];
|
|
538
|
+
const currentBlockOrTimestamp = currentHf.timestamp ?? currentHf.block;
|
|
539
|
+
if (currentBlockOrTimestamp === null || currentBlockOrTimestamp === undefined) {
|
|
540
|
+
return null;
|
|
541
|
+
}
|
|
542
|
+
// Find the next hardfork that has a different block/timestamp
|
|
543
|
+
const nextHf = hfs.slice(targetHfIndex + 1).find((hf) => {
|
|
544
|
+
const nextBlockOrTimestamp = hf.timestamp ?? hf.block;
|
|
545
|
+
return (nextBlockOrTimestamp !== null &&
|
|
546
|
+
nextBlockOrTimestamp !== undefined &&
|
|
547
|
+
nextBlockOrTimestamp !== currentBlockOrTimestamp);
|
|
548
|
+
});
|
|
549
|
+
// If no next hf found with valid block or timestamp return null
|
|
550
|
+
if (nextHf === undefined) {
|
|
551
|
+
return null;
|
|
552
|
+
}
|
|
553
|
+
// Get the block/timestamp for the next hardfork
|
|
554
|
+
const nextBlockOrTimestamp = nextHf.timestamp ?? nextHf.block;
|
|
555
|
+
if (nextBlockOrTimestamp === null || nextBlockOrTimestamp === undefined) {
|
|
556
|
+
return null;
|
|
557
|
+
}
|
|
558
|
+
return BigInt(nextBlockOrTimestamp);
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Internal helper function to calculate a fork hash
|
|
562
|
+
* @param hardfork Hardfork name
|
|
563
|
+
* @param genesisHash Genesis block hash of the chain
|
|
564
|
+
* @returns Fork hash as hex string
|
|
565
|
+
*/
|
|
566
|
+
_calcForkHash(hardfork, genesisHash) {
|
|
567
|
+
let hfBytes = new Uint8Array(0);
|
|
568
|
+
let prevBlockOrTime = 0;
|
|
569
|
+
for (const hf of this.hardforks()) {
|
|
570
|
+
const { block, timestamp, name } = hf;
|
|
571
|
+
// Timestamp to be used for timestamp based hfs even if we may bundle
|
|
572
|
+
// block number with them retrospectively
|
|
573
|
+
let blockOrTime = timestamp ?? block;
|
|
574
|
+
blockOrTime = blockOrTime !== null ? Number(blockOrTime) : null;
|
|
575
|
+
// Skip for chainstart (0), not applied HFs (null) and
|
|
576
|
+
// when already applied on same blockOrTime HFs
|
|
577
|
+
// and on the merge since forkhash doesn't change on merge hf
|
|
578
|
+
if (typeof blockOrTime === 'number' &&
|
|
579
|
+
blockOrTime !== 0 &&
|
|
580
|
+
blockOrTime !== prevBlockOrTime &&
|
|
581
|
+
name !== Hardfork.Paris) {
|
|
582
|
+
const hfBlockBytes = hexToBytes(`0x${blockOrTime.toString(16).padStart(16, '0')}`);
|
|
583
|
+
hfBytes = concatBytes(hfBytes, hfBlockBytes);
|
|
584
|
+
prevBlockOrTime = blockOrTime;
|
|
585
|
+
}
|
|
586
|
+
if (hf.name === hardfork)
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
const inputBytes = concatBytes(genesisHash, hfBytes);
|
|
590
|
+
// CRC32 delivers result as signed (negative) 32-bit integer,
|
|
591
|
+
// convert to hex string
|
|
592
|
+
const forkhash = bytesToHex(intToBytes(crc32(inputBytes) >>> 0));
|
|
593
|
+
return forkhash;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Returns an eth/64 compliant fork hash (EIP-2124)
|
|
597
|
+
* @param hardfork Hardfork name, optional if HF set
|
|
598
|
+
* @param genesisHash Genesis block hash of the network, optional if already defined and not needed to be calculated
|
|
599
|
+
* @returns Fork hash as a hex string
|
|
600
|
+
*/
|
|
601
|
+
forkHash(hardfork, genesisHash) {
|
|
602
|
+
hardfork = hardfork ?? this._hardfork;
|
|
603
|
+
const data = this._getHardfork(hardfork);
|
|
604
|
+
if (data === null || (data?.block === null && data?.timestamp === undefined)) {
|
|
605
|
+
const msg = 'No fork hash calculation possible for future hardfork';
|
|
606
|
+
throw EthereumJSErrorWithoutCode(msg);
|
|
607
|
+
}
|
|
608
|
+
if (data?.forkHash !== null && data?.forkHash !== undefined) {
|
|
609
|
+
return data.forkHash;
|
|
610
|
+
}
|
|
611
|
+
if (!genesisHash)
|
|
612
|
+
throw EthereumJSErrorWithoutCode('genesisHash required for forkHash calculation');
|
|
613
|
+
return this._calcForkHash(hardfork, genesisHash);
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
*
|
|
617
|
+
* @param forkHash Fork hash as a hex string
|
|
618
|
+
* @returns Array with hardfork data (name, block, forkHash)
|
|
619
|
+
*/
|
|
620
|
+
hardforkForForkHash(forkHash) {
|
|
621
|
+
const resArray = this.hardforks().filter((hf) => {
|
|
622
|
+
return hf.forkHash === forkHash;
|
|
623
|
+
});
|
|
624
|
+
return resArray.length >= 1 ? resArray[resArray.length - 1] : null;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Sets any missing forkHashes on this {@link Common} instance.
|
|
628
|
+
* @param genesisHash The genesis block hash
|
|
629
|
+
*/
|
|
630
|
+
setForkHashes(genesisHash) {
|
|
631
|
+
for (const hf of this.hardforks()) {
|
|
632
|
+
const blockOrTime = hf.timestamp ?? hf.block;
|
|
633
|
+
if ((hf.forkHash === null || hf.forkHash === undefined) &&
|
|
634
|
+
blockOrTime !== null &&
|
|
635
|
+
blockOrTime !== undefined) {
|
|
636
|
+
hf.forkHash = this.forkHash(hf.name, genesisHash);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Returns the Genesis parameters of the current chain
|
|
642
|
+
* @returns Genesis dictionary
|
|
643
|
+
*/
|
|
644
|
+
genesis() {
|
|
645
|
+
return this._chainParams.genesis;
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Returns the hardfork definitions for the current chain.
|
|
649
|
+
* @returns Array of hardfork transition configs
|
|
650
|
+
*/
|
|
651
|
+
hardforks() {
|
|
652
|
+
const hfs = this._chainParams.hardforks;
|
|
653
|
+
if (this._chainParams.customHardforks !== undefined) {
|
|
654
|
+
// Add transition configs for custom hardforks that aren't already in the hardforks array
|
|
655
|
+
const existingNames = new Set(hfs.map((hf) => hf.name));
|
|
656
|
+
const customHfEntries = Object.keys(this._chainParams.customHardforks)
|
|
657
|
+
.filter((name) => !existingNames.has(name))
|
|
658
|
+
.map((name) => ({
|
|
659
|
+
name,
|
|
660
|
+
block: null, // Custom hardforks without explicit transition config default to null (inactive by block)
|
|
661
|
+
}));
|
|
662
|
+
return [...hfs, ...customHfEntries];
|
|
663
|
+
}
|
|
664
|
+
return hfs;
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Returns bootstrap nodes for the current chain.
|
|
668
|
+
* @returns Array of bootstrap node configs
|
|
669
|
+
*/
|
|
670
|
+
bootstrapNodes() {
|
|
671
|
+
return this._chainParams.bootstrapNodes;
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Returns DNS networks for the current chain
|
|
675
|
+
* @returns {String[]} Array of DNS ENR urls
|
|
676
|
+
*/
|
|
677
|
+
dnsNetworks() {
|
|
678
|
+
return this._chainParams.dnsNetworks;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Returns the hardfork set
|
|
682
|
+
* @returns Hardfork name
|
|
683
|
+
*/
|
|
684
|
+
hardfork() {
|
|
685
|
+
return this._hardfork;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Returns the Id of current chain
|
|
689
|
+
* @returns chain Id
|
|
690
|
+
*/
|
|
691
|
+
chainId() {
|
|
692
|
+
return BigInt(this._chainParams.chainId);
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Returns the name of current chain
|
|
696
|
+
* @returns chain name (lower case)
|
|
697
|
+
*/
|
|
698
|
+
chainName() {
|
|
699
|
+
return this._chainParams.name;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Returns the additionally activated EIPs
|
|
703
|
+
* (by using the `eips` constructor option)
|
|
704
|
+
* @returns List of EIPs
|
|
705
|
+
*/
|
|
706
|
+
eips() {
|
|
707
|
+
return this._eips;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Returns the consensus type of the network
|
|
711
|
+
* Possible values: "pow"|"poa"|"pos"
|
|
712
|
+
*
|
|
713
|
+
* Note: This value can update along a Hardfork.
|
|
714
|
+
*/
|
|
715
|
+
consensusType() {
|
|
716
|
+
const hardfork = this.hardfork();
|
|
717
|
+
let value;
|
|
718
|
+
for (const hfChanges of this.HARDFORK_CHANGES) {
|
|
719
|
+
if ('consensus' in hfChanges[1]) {
|
|
720
|
+
value = hfChanges[1]['consensus']['type'];
|
|
721
|
+
}
|
|
722
|
+
if (hfChanges[0] === hardfork)
|
|
723
|
+
break;
|
|
724
|
+
}
|
|
725
|
+
return value ?? this._chainParams['consensus']['type'];
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Returns the concrete consensus implementation
|
|
729
|
+
* algorithm or protocol for the network
|
|
730
|
+
* e.g. "ethash" for "pow" consensus type,
|
|
731
|
+
* "clique" for "poa" consensus type or
|
|
732
|
+
* "casper" for "pos" consensus type.
|
|
733
|
+
*
|
|
734
|
+
* Note: This value can update along a Hardfork.
|
|
735
|
+
*/
|
|
736
|
+
consensusAlgorithm() {
|
|
737
|
+
const hardfork = this.hardfork();
|
|
738
|
+
let value;
|
|
739
|
+
for (const hfChanges of this.HARDFORK_CHANGES) {
|
|
740
|
+
if ('consensus' in hfChanges[1]) {
|
|
741
|
+
value = hfChanges[1]['consensus']['algorithm'];
|
|
742
|
+
}
|
|
743
|
+
if (hfChanges[0] === hardfork)
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
return value ?? this._chainParams['consensus']['algorithm'];
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Returns a dictionary with consensus configuration
|
|
750
|
+
* parameters based on the consensus algorithm
|
|
751
|
+
*
|
|
752
|
+
* Expected returns (parameters must be present in
|
|
753
|
+
* the respective chain JSON files):
|
|
754
|
+
*
|
|
755
|
+
* ethash: empty object
|
|
756
|
+
* clique: period, epoch
|
|
757
|
+
* casper: empty object
|
|
758
|
+
*
|
|
759
|
+
* Note: This value can update along a Hardfork.
|
|
760
|
+
*/
|
|
761
|
+
consensusConfig() {
|
|
762
|
+
const hardfork = this.hardfork();
|
|
763
|
+
let value;
|
|
764
|
+
for (const hfChanges of this.HARDFORK_CHANGES) {
|
|
765
|
+
if ('consensus' in hfChanges[1]) {
|
|
766
|
+
// The config parameter is named after the respective consensus algorithm
|
|
767
|
+
const config = hfChanges[1];
|
|
768
|
+
const algorithm = config['consensus']['algorithm'];
|
|
769
|
+
value = config['consensus'][algorithm];
|
|
770
|
+
}
|
|
771
|
+
if (hfChanges[0] === hardfork)
|
|
772
|
+
break;
|
|
773
|
+
}
|
|
774
|
+
return (value ?? this._chainParams['consensus'][this.consensusAlgorithm()] ?? {});
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Returns a deep copy of this {@link Common} instance.
|
|
778
|
+
*/
|
|
779
|
+
copy() {
|
|
780
|
+
const copy = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
|
|
781
|
+
copy.events = new EventEmitter();
|
|
782
|
+
return copy;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
//# sourceMappingURL=common.js.map
|