@feelyourprotocol/block 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 (133) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +466 -0
  3. package/dist/cjs/block/block.d.ts +147 -0
  4. package/dist/cjs/block/block.d.ts.map +1 -0
  5. package/dist/cjs/block/block.js +415 -0
  6. package/dist/cjs/block/block.js.map +1 -0
  7. package/dist/cjs/block/constructors.d.ts +77 -0
  8. package/dist/cjs/block/constructors.d.ts.map +1 -0
  9. package/dist/cjs/block/constructors.js +298 -0
  10. package/dist/cjs/block/constructors.js.map +1 -0
  11. package/dist/cjs/block/index.d.ts +3 -0
  12. package/dist/cjs/block/index.d.ts.map +1 -0
  13. package/dist/cjs/block/index.js +19 -0
  14. package/dist/cjs/block/index.js.map +1 -0
  15. package/dist/cjs/consensus/clique.d.ts +52 -0
  16. package/dist/cjs/consensus/clique.d.ts.map +1 -0
  17. package/dist/cjs/consensus/clique.js +144 -0
  18. package/dist/cjs/consensus/clique.js.map +1 -0
  19. package/dist/cjs/consensus/ethash.d.ts +9 -0
  20. package/dist/cjs/consensus/ethash.d.ts.map +1 -0
  21. package/dist/cjs/consensus/ethash.js +13 -0
  22. package/dist/cjs/consensus/ethash.js.map +1 -0
  23. package/dist/cjs/consensus/index.d.ts +3 -0
  24. package/dist/cjs/consensus/index.d.ts.map +1 -0
  25. package/dist/cjs/consensus/index.js +29 -0
  26. package/dist/cjs/consensus/index.js.map +1 -0
  27. package/dist/cjs/from-beacon-payload.d.ts +36 -0
  28. package/dist/cjs/from-beacon-payload.d.ts.map +1 -0
  29. package/dist/cjs/from-beacon-payload.js +48 -0
  30. package/dist/cjs/from-beacon-payload.js.map +1 -0
  31. package/dist/cjs/header/constructors.d.ts +39 -0
  32. package/dist/cjs/header/constructors.d.ts.map +1 -0
  33. package/dist/cjs/header/constructors.js +127 -0
  34. package/dist/cjs/header/constructors.js.map +1 -0
  35. package/dist/cjs/header/header.d.ts +134 -0
  36. package/dist/cjs/header/header.d.ts.map +1 -0
  37. package/dist/cjs/header/header.js +699 -0
  38. package/dist/cjs/header/header.js.map +1 -0
  39. package/dist/cjs/header/index.d.ts +3 -0
  40. package/dist/cjs/header/index.d.ts.map +1 -0
  41. package/dist/cjs/header/index.js +19 -0
  42. package/dist/cjs/header/index.js.map +1 -0
  43. package/dist/cjs/helpers.d.ts +59 -0
  44. package/dist/cjs/helpers.d.ts.map +1 -0
  45. package/dist/cjs/helpers.js +172 -0
  46. package/dist/cjs/helpers.js.map +1 -0
  47. package/dist/cjs/index.d.ts +8 -0
  48. package/dist/cjs/index.d.ts.map +1 -0
  49. package/dist/cjs/index.js +31 -0
  50. package/dist/cjs/index.js.map +1 -0
  51. package/dist/cjs/package.json +3 -0
  52. package/dist/cjs/params.d.ts +3 -0
  53. package/dist/cjs/params.d.ts.map +1 -0
  54. package/dist/cjs/params.js +97 -0
  55. package/dist/cjs/params.js.map +1 -0
  56. package/dist/cjs/types.d.ts +228 -0
  57. package/dist/cjs/types.d.ts.map +1 -0
  58. package/dist/cjs/types.js +3 -0
  59. package/dist/cjs/types.js.map +1 -0
  60. package/dist/esm/block/block.d.ts +147 -0
  61. package/dist/esm/block/block.d.ts.map +1 -0
  62. package/dist/esm/block/block.js +411 -0
  63. package/dist/esm/block/block.js.map +1 -0
  64. package/dist/esm/block/constructors.d.ts +77 -0
  65. package/dist/esm/block/constructors.d.ts.map +1 -0
  66. package/dist/esm/block/constructors.js +286 -0
  67. package/dist/esm/block/constructors.js.map +1 -0
  68. package/dist/esm/block/index.d.ts +3 -0
  69. package/dist/esm/block/index.d.ts.map +1 -0
  70. package/dist/esm/block/index.js +3 -0
  71. package/dist/esm/block/index.js.map +1 -0
  72. package/dist/esm/consensus/clique.d.ts +52 -0
  73. package/dist/esm/consensus/clique.d.ts.map +1 -0
  74. package/dist/esm/consensus/clique.js +132 -0
  75. package/dist/esm/consensus/clique.js.map +1 -0
  76. package/dist/esm/consensus/ethash.d.ts +9 -0
  77. package/dist/esm/consensus/ethash.d.ts.map +1 -0
  78. package/dist/esm/consensus/ethash.js +10 -0
  79. package/dist/esm/consensus/ethash.js.map +1 -0
  80. package/dist/esm/consensus/index.d.ts +3 -0
  81. package/dist/esm/consensus/index.d.ts.map +1 -0
  82. package/dist/esm/consensus/index.js +3 -0
  83. package/dist/esm/consensus/index.js.map +1 -0
  84. package/dist/esm/from-beacon-payload.d.ts +36 -0
  85. package/dist/esm/from-beacon-payload.d.ts.map +1 -0
  86. package/dist/esm/from-beacon-payload.js +45 -0
  87. package/dist/esm/from-beacon-payload.js.map +1 -0
  88. package/dist/esm/header/constructors.d.ts +39 -0
  89. package/dist/esm/header/constructors.d.ts.map +1 -0
  90. package/dist/esm/header/constructors.js +120 -0
  91. package/dist/esm/header/constructors.js.map +1 -0
  92. package/dist/esm/header/header.d.ts +134 -0
  93. package/dist/esm/header/header.d.ts.map +1 -0
  94. package/dist/esm/header/header.js +695 -0
  95. package/dist/esm/header/header.js.map +1 -0
  96. package/dist/esm/header/index.d.ts +3 -0
  97. package/dist/esm/header/index.d.ts.map +1 -0
  98. package/dist/esm/header/index.js +3 -0
  99. package/dist/esm/header/index.js.map +1 -0
  100. package/dist/esm/helpers.d.ts +59 -0
  101. package/dist/esm/helpers.d.ts.map +1 -0
  102. package/dist/esm/helpers.js +161 -0
  103. package/dist/esm/helpers.js.map +1 -0
  104. package/dist/esm/index.d.ts +8 -0
  105. package/dist/esm/index.d.ts.map +1 -0
  106. package/dist/esm/index.js +8 -0
  107. package/dist/esm/index.js.map +1 -0
  108. package/dist/esm/package.json +3 -0
  109. package/dist/esm/params.d.ts +3 -0
  110. package/dist/esm/params.d.ts.map +1 -0
  111. package/dist/esm/params.js +94 -0
  112. package/dist/esm/params.js.map +1 -0
  113. package/dist/esm/types.d.ts +228 -0
  114. package/dist/esm/types.d.ts.map +1 -0
  115. package/dist/esm/types.js +2 -0
  116. package/dist/esm/types.js.map +1 -0
  117. package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
  118. package/dist/tsconfig.prod.esm.tsbuildinfo +1 -0
  119. package/package.json +75 -0
  120. package/src/block/block.ts +526 -0
  121. package/src/block/constructors.ts +407 -0
  122. package/src/block/index.ts +2 -0
  123. package/src/consensus/clique.ts +171 -0
  124. package/src/consensus/ethash.ts +11 -0
  125. package/src/consensus/index.ts +12 -0
  126. package/src/from-beacon-payload.ts +82 -0
  127. package/src/header/constructors.ts +169 -0
  128. package/src/header/header.ts +890 -0
  129. package/src/header/index.ts +2 -0
  130. package/src/helpers.ts +223 -0
  131. package/src/index.ts +13 -0
  132. package/src/params.ts +95 -0
  133. package/src/types.ts +254 -0
@@ -0,0 +1,699 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BlockHeader = void 0;
4
+ const common_1 = require("@feelyourprotocol/common");
5
+ const rlp_1 = require("@feelyourprotocol/rlp");
6
+ const util_1 = require("@feelyourprotocol/util");
7
+ const sha3_js_1 = require("@noble/hashes/sha3.js");
8
+ const clique_ts_1 = require("../consensus/clique.js");
9
+ const helpers_ts_1 = require("../helpers.js");
10
+ const params_ts_1 = require("../params.js");
11
+ const DEFAULT_GAS_LIMIT = BigInt('0xffffffffffffff');
12
+ /**
13
+ * An object that represents the block header.
14
+ */
15
+ class BlockHeader {
16
+ /**
17
+ * EIP-4399: After merge to PoS, `mixHash` supplanted as `prevRandao`
18
+ */
19
+ get prevRandao() {
20
+ if (!this.common.isActivatedEIP(4399)) {
21
+ const msg = this._errorMsg('The prevRandao parameter can only be accessed when EIP-4399 is activated');
22
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
23
+ }
24
+ return this.mixHash;
25
+ }
26
+ /**
27
+ * This constructor takes the values, validates them, assigns them and freezes the object.
28
+ *
29
+ * @deprecated Use the public static factory methods to assist in creating a Header object from
30
+ * varying data types. For a default empty header, use {@link createBlockHeader}.
31
+ *
32
+ */
33
+ constructor(headerData, opts = {}) {
34
+ this.cache = {
35
+ hash: undefined,
36
+ };
37
+ if (opts.common) {
38
+ this.common = opts.common.copy();
39
+ }
40
+ else {
41
+ this.common = new common_1.Common({
42
+ chain: common_1.Mainnet, // default
43
+ });
44
+ }
45
+ this.common.updateParams(opts.params ?? params_ts_1.paramsBlock);
46
+ this.keccakFunction = this.common.customCrypto.keccak256 ?? sha3_js_1.keccak_256;
47
+ const skipValidateConsensusFormat = opts.skipConsensusFormatValidation ?? false;
48
+ const defaults = {
49
+ parentHash: new Uint8Array(32),
50
+ uncleHash: util_1.KECCAK256_RLP_ARRAY,
51
+ coinbase: (0, util_1.createZeroAddress)(),
52
+ stateRoot: new Uint8Array(32),
53
+ transactionsTrie: util_1.KECCAK256_RLP,
54
+ receiptTrie: util_1.KECCAK256_RLP,
55
+ logsBloom: new Uint8Array(256),
56
+ difficulty: util_1.BIGINT_0,
57
+ number: util_1.BIGINT_0,
58
+ gasLimit: DEFAULT_GAS_LIMIT,
59
+ gasUsed: util_1.BIGINT_0,
60
+ timestamp: util_1.BIGINT_0,
61
+ extraData: new Uint8Array(0),
62
+ mixHash: new Uint8Array(32),
63
+ nonce: new Uint8Array(8),
64
+ };
65
+ const parentHash = (0, util_1.toType)(headerData.parentHash, util_1.TypeOutput.Uint8Array) ?? defaults.parentHash;
66
+ const uncleHash = (0, util_1.toType)(headerData.uncleHash, util_1.TypeOutput.Uint8Array) ?? defaults.uncleHash;
67
+ const coinbase = new util_1.Address((0, util_1.toType)(headerData.coinbase ?? defaults.coinbase, util_1.TypeOutput.Uint8Array));
68
+ const stateRoot = (0, util_1.toType)(headerData.stateRoot, util_1.TypeOutput.Uint8Array) ?? defaults.stateRoot;
69
+ const transactionsTrie = (0, util_1.toType)(headerData.transactionsTrie, util_1.TypeOutput.Uint8Array) ?? defaults.transactionsTrie;
70
+ const receiptTrie = (0, util_1.toType)(headerData.receiptTrie, util_1.TypeOutput.Uint8Array) ?? defaults.receiptTrie;
71
+ const logsBloom = (0, util_1.toType)(headerData.logsBloom, util_1.TypeOutput.Uint8Array) ?? defaults.logsBloom;
72
+ const difficulty = (0, util_1.toType)(headerData.difficulty, util_1.TypeOutput.BigInt) ?? defaults.difficulty;
73
+ const number = (0, util_1.toType)(headerData.number, util_1.TypeOutput.BigInt) ?? defaults.number;
74
+ const gasLimit = (0, util_1.toType)(headerData.gasLimit, util_1.TypeOutput.BigInt) ?? defaults.gasLimit;
75
+ const gasUsed = (0, util_1.toType)(headerData.gasUsed, util_1.TypeOutput.BigInt) ?? defaults.gasUsed;
76
+ const timestamp = (0, util_1.toType)(headerData.timestamp, util_1.TypeOutput.BigInt) ?? defaults.timestamp;
77
+ const extraData = (0, util_1.toType)(headerData.extraData, util_1.TypeOutput.Uint8Array) ?? defaults.extraData;
78
+ const mixHash = (0, util_1.toType)(headerData.mixHash, util_1.TypeOutput.Uint8Array) ?? defaults.mixHash;
79
+ const nonce = (0, util_1.toType)(headerData.nonce, util_1.TypeOutput.Uint8Array) ?? defaults.nonce;
80
+ const setHardfork = opts.setHardfork ?? false;
81
+ if (setHardfork === true) {
82
+ this.common.setHardforkBy({
83
+ blockNumber: number,
84
+ timestamp,
85
+ });
86
+ }
87
+ // Hardfork defaults which couldn't be paired with earlier defaults
88
+ const hardforkDefaults = {
89
+ baseFeePerGas: this.common.isActivatedEIP(1559)
90
+ ? number === this.common.hardforkBlock(common_1.Hardfork.London)
91
+ ? this.common.param('initialBaseFee')
92
+ : util_1.BIGINT_7
93
+ : undefined,
94
+ withdrawalsRoot: this.common.isActivatedEIP(4895) ? util_1.KECCAK256_RLP : undefined,
95
+ blobGasUsed: this.common.isActivatedEIP(4844) ? util_1.BIGINT_0 : undefined,
96
+ excessBlobGas: this.common.isActivatedEIP(4844) ? util_1.BIGINT_0 : undefined,
97
+ parentBeaconBlockRoot: this.common.isActivatedEIP(4788) ? new Uint8Array(32) : undefined,
98
+ // Note: as of devnet-4 we stub the null SHA256 hash, but for devnet5 this will actually
99
+ // be the correct hash for empty requests.
100
+ requestsHash: this.common.isActivatedEIP(7685) ? util_1.SHA256_NULL : undefined,
101
+ blockAccessListHash: this.common.isActivatedEIP(7928) ? new Uint8Array(32) : undefined,
102
+ slotNumber: this.common.isActivatedEIP(7843) ? util_1.BIGINT_0 : undefined,
103
+ };
104
+ const baseFeePerGas = (0, util_1.toType)(headerData.baseFeePerGas, util_1.TypeOutput.BigInt) ?? hardforkDefaults.baseFeePerGas;
105
+ const withdrawalsRoot = (0, util_1.toType)(headerData.withdrawalsRoot, util_1.TypeOutput.Uint8Array) ?? hardforkDefaults.withdrawalsRoot;
106
+ const blobGasUsed = (0, util_1.toType)(headerData.blobGasUsed, util_1.TypeOutput.BigInt) ?? hardforkDefaults.blobGasUsed;
107
+ const excessBlobGas = (0, util_1.toType)(headerData.excessBlobGas, util_1.TypeOutput.BigInt) ?? hardforkDefaults.excessBlobGas;
108
+ const parentBeaconBlockRoot = (0, util_1.toType)(headerData.parentBeaconBlockRoot, util_1.TypeOutput.Uint8Array) ??
109
+ hardforkDefaults.parentBeaconBlockRoot;
110
+ const requestsHash = (0, util_1.toType)(headerData.requestsHash, util_1.TypeOutput.Uint8Array) ?? hardforkDefaults.requestsHash;
111
+ const blockAccessListHash = (0, util_1.toType)(headerData.blockAccessListHash, util_1.TypeOutput.Uint8Array) ??
112
+ hardforkDefaults.blockAccessListHash;
113
+ const slotNumber = (0, util_1.toType)(headerData.slotNumber, util_1.TypeOutput.BigInt) ?? hardforkDefaults.slotNumber;
114
+ if (!this.common.isActivatedEIP(1559) && baseFeePerGas !== undefined) {
115
+ throw (0, util_1.EthereumJSErrorWithoutCode)('A base fee for a block can only be set with EIP1559 being activated');
116
+ }
117
+ if (!this.common.isActivatedEIP(4895) && withdrawalsRoot !== undefined) {
118
+ throw (0, util_1.EthereumJSErrorWithoutCode)('A withdrawalsRoot for a header can only be provided with EIP4895 being activated');
119
+ }
120
+ if (!this.common.isActivatedEIP(4844)) {
121
+ if (blobGasUsed !== undefined) {
122
+ throw (0, util_1.EthereumJSErrorWithoutCode)('blob gas used can only be provided with EIP4844 activated');
123
+ }
124
+ if (excessBlobGas !== undefined) {
125
+ throw (0, util_1.EthereumJSErrorWithoutCode)('excess blob gas can only be provided with EIP4844 activated');
126
+ }
127
+ }
128
+ if (!this.common.isActivatedEIP(4788) && parentBeaconBlockRoot !== undefined) {
129
+ throw (0, util_1.EthereumJSErrorWithoutCode)('A parentBeaconBlockRoot for a header can only be provided with EIP4788 being activated');
130
+ }
131
+ if (!this.common.isActivatedEIP(7685) && requestsHash !== undefined) {
132
+ throw (0, util_1.EthereumJSErrorWithoutCode)('requestsHash can only be provided with EIP 7685 activated');
133
+ }
134
+ if (!this.common.isActivatedEIP(7928) && blockAccessListHash !== undefined) {
135
+ throw (0, util_1.EthereumJSErrorWithoutCode)('blockAccessListHash can only be provided with EIP 7928 activated');
136
+ }
137
+ if (!this.common.isActivatedEIP(7843) && slotNumber !== undefined) {
138
+ throw (0, util_1.EthereumJSErrorWithoutCode)('slotNumber can only be provided with EIP 7843 activated');
139
+ }
140
+ this.parentHash = parentHash;
141
+ this.uncleHash = uncleHash;
142
+ this.coinbase = coinbase;
143
+ this.stateRoot = stateRoot;
144
+ this.transactionsTrie = transactionsTrie;
145
+ this.receiptTrie = receiptTrie;
146
+ this.logsBloom = logsBloom;
147
+ this.difficulty = difficulty;
148
+ this.number = number;
149
+ this.gasLimit = gasLimit;
150
+ this.gasUsed = gasUsed;
151
+ this.timestamp = timestamp;
152
+ this.extraData = extraData;
153
+ this.mixHash = mixHash;
154
+ this.nonce = nonce;
155
+ this.baseFeePerGas = baseFeePerGas;
156
+ this.withdrawalsRoot = withdrawalsRoot;
157
+ this.blobGasUsed = blobGasUsed;
158
+ this.excessBlobGas = excessBlobGas;
159
+ this.parentBeaconBlockRoot = parentBeaconBlockRoot;
160
+ this.requestsHash = requestsHash;
161
+ this.blockAccessListHash = blockAccessListHash;
162
+ this.slotNumber = slotNumber;
163
+ this._genericFormatValidation();
164
+ this._validateDAOExtraData();
165
+ // Now we have set all the values of this Header, we possibly have set a dummy
166
+ // `difficulty` value (defaults to 0). If we have a `calcDifficultyFromHeader`
167
+ // block option parameter, we instead set difficulty to this value.
168
+ if (opts.calcDifficultyFromHeader &&
169
+ this.common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Ethash) {
170
+ this.difficulty = this.ethashCanonicalDifficulty(opts.calcDifficultyFromHeader);
171
+ }
172
+ // Validate consensus format after block is sealed (if applicable) so extraData checks will pass
173
+ if (skipValidateConsensusFormat === false)
174
+ this._consensusFormatValidation();
175
+ const freeze = opts?.freeze ?? true;
176
+ if (freeze) {
177
+ Object.freeze(this);
178
+ }
179
+ }
180
+ /**
181
+ * Validates correct buffer lengths, throws if invalid.
182
+ */
183
+ _genericFormatValidation() {
184
+ const { parentHash, stateRoot, transactionsTrie, receiptTrie, mixHash, nonce } = this;
185
+ if (parentHash.length !== 32) {
186
+ const msg = this._errorMsg(`parentHash must be 32 bytes, received ${parentHash.length} bytes`);
187
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
188
+ }
189
+ if (stateRoot.length !== 32) {
190
+ const msg = this._errorMsg(`stateRoot must be 32 bytes, received ${stateRoot.length} bytes`);
191
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
192
+ }
193
+ if (transactionsTrie.length !== 32) {
194
+ const msg = this._errorMsg(`transactionsTrie must be 32 bytes, received ${transactionsTrie.length} bytes`);
195
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
196
+ }
197
+ if (receiptTrie.length !== 32) {
198
+ const msg = this._errorMsg(`receiptTrie must be 32 bytes, received ${receiptTrie.length} bytes`);
199
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
200
+ }
201
+ if (mixHash.length !== 32) {
202
+ const msg = this._errorMsg(`mixHash must be 32 bytes, received ${mixHash.length} bytes`);
203
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
204
+ }
205
+ if (nonce.length !== 8) {
206
+ const msg = this._errorMsg(`nonce must be 8 bytes, received ${nonce.length} bytes`);
207
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
208
+ }
209
+ // check if the block used too much gas
210
+ if (this.gasUsed > this.gasLimit) {
211
+ const msg = this._errorMsg(`Invalid block: too much gas used. Used: ${this.gasUsed}, gas limit: ${this.gasLimit}`);
212
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
213
+ }
214
+ // Validation for EIP-1559 blocks
215
+ if (this.common.isActivatedEIP(1559)) {
216
+ if (typeof this.baseFeePerGas !== 'bigint') {
217
+ const msg = this._errorMsg('EIP1559 block has no base fee field');
218
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
219
+ }
220
+ const londonHfBlock = this.common.hardforkBlock(common_1.Hardfork.London);
221
+ if (typeof londonHfBlock === 'bigint' &&
222
+ londonHfBlock !== util_1.BIGINT_0 &&
223
+ this.number === londonHfBlock) {
224
+ const initialBaseFee = this.common.param('initialBaseFee');
225
+ if (this.baseFeePerGas !== initialBaseFee) {
226
+ const msg = this._errorMsg('Initial EIP1559 block does not have initial base fee');
227
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
228
+ }
229
+ }
230
+ }
231
+ if (this.common.isActivatedEIP(4895)) {
232
+ if (this.withdrawalsRoot === undefined) {
233
+ const msg = this._errorMsg('EIP4895 block has no withdrawalsRoot field');
234
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
235
+ }
236
+ if (this.withdrawalsRoot?.length !== 32) {
237
+ const msg = this._errorMsg(`withdrawalsRoot must be 32 bytes, received ${this.withdrawalsRoot.length} bytes`);
238
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
239
+ }
240
+ }
241
+ if (this.common.isActivatedEIP(4788)) {
242
+ if (this.parentBeaconBlockRoot === undefined) {
243
+ const msg = this._errorMsg('EIP4788 block has no parentBeaconBlockRoot field');
244
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
245
+ }
246
+ if (this.parentBeaconBlockRoot?.length !== 32) {
247
+ const msg = this._errorMsg(`parentBeaconBlockRoot must be 32 bytes, received ${this.parentBeaconBlockRoot.length} bytes`);
248
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
249
+ }
250
+ }
251
+ if (this.common.isActivatedEIP(7685)) {
252
+ if (this.requestsHash === undefined) {
253
+ const msg = this._errorMsg('EIP7685 block has no requestsHash field');
254
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
255
+ }
256
+ }
257
+ if (this.common.isActivatedEIP(7928)) {
258
+ if (this.blockAccessListHash === undefined) {
259
+ const msg = this._errorMsg('EIP7928 block has no blockAccessListHash field');
260
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
261
+ }
262
+ if (this.blockAccessListHash?.length !== 32) {
263
+ const msg = this._errorMsg(`blockAccessListHash must be 32 bytes, received ${this.blockAccessListHash.length} bytes`);
264
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
265
+ }
266
+ }
267
+ if (this.common.isActivatedEIP(7843)) {
268
+ if (this.slotNumber === undefined) {
269
+ const msg = this._errorMsg('EIP7843 block has no slotNumber field');
270
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
271
+ }
272
+ }
273
+ }
274
+ /**
275
+ * Checks static parameters related to consensus algorithm
276
+ * @throws if any check fails
277
+ */
278
+ _consensusFormatValidation() {
279
+ const { nonce, uncleHash, difficulty, extraData, number } = this;
280
+ // Consensus type dependent checks
281
+ if (this.common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Ethash) {
282
+ // PoW/Ethash
283
+ if (number > util_1.BIGINT_0 && this.extraData.length > this.common.param('maxExtraDataSize')) {
284
+ // Check length of data on all post-genesis blocks
285
+ const msg = this._errorMsg('invalid amount of extra data');
286
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
287
+ }
288
+ }
289
+ if (this.common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Clique) {
290
+ // PoA/Clique
291
+ const minLength = clique_ts_1.CLIQUE_EXTRA_VANITY + clique_ts_1.CLIQUE_EXTRA_SEAL;
292
+ if (!(0, clique_ts_1.cliqueIsEpochTransition)(this)) {
293
+ // ExtraData length on epoch transition
294
+ if (this.extraData.length !== minLength) {
295
+ const msg = this._errorMsg(`extraData must be ${minLength} bytes on non-epoch transition blocks, received ${this.extraData.length} bytes`);
296
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
297
+ }
298
+ }
299
+ else {
300
+ const signerLength = this.extraData.length - minLength;
301
+ if (signerLength % 20 !== 0) {
302
+ const msg = this._errorMsg(`invalid signer list length in extraData, received signer length of ${signerLength} (not divisible by 20)`);
303
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
304
+ }
305
+ // coinbase (beneficiary) on epoch transition
306
+ if (!this.coinbase.isZero()) {
307
+ const msg = this._errorMsg(`coinbase must be filled with zeros on epoch transition blocks, received ${this.coinbase}`);
308
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
309
+ }
310
+ }
311
+ // MixHash format
312
+ if (!(0, util_1.equalsBytes)(this.mixHash, new Uint8Array(32))) {
313
+ const msg = this._errorMsg(`mixHash must be filled with zeros, received ${this.mixHash}`);
314
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
315
+ }
316
+ }
317
+ // Validation for PoS blocks (EIP-3675)
318
+ if (this.common.consensusType() === common_1.ConsensusType.ProofOfStake) {
319
+ let error = false;
320
+ let errorMsg = '';
321
+ if (!(0, util_1.equalsBytes)(uncleHash, util_1.KECCAK256_RLP_ARRAY)) {
322
+ errorMsg += `, uncleHash: ${(0, util_1.bytesToHex)(uncleHash)} (expected: ${(0, util_1.bytesToHex)(util_1.KECCAK256_RLP_ARRAY)})`;
323
+ error = true;
324
+ }
325
+ if (number !== util_1.BIGINT_0) {
326
+ // Skip difficulty, nonce, and extraData check for PoS genesis block as genesis block may have non-zero difficulty (if TD is > 0)
327
+ if (difficulty !== util_1.BIGINT_0) {
328
+ errorMsg += `, difficulty: ${difficulty} (expected: 0)`;
329
+ error = true;
330
+ }
331
+ if (extraData.length > 32) {
332
+ errorMsg += `, extraData: ${(0, util_1.bytesToHex)(extraData)} (cannot exceed 32 bytes length, received ${extraData.length} bytes)`;
333
+ error = true;
334
+ }
335
+ if (!(0, util_1.equalsBytes)(nonce, new Uint8Array(8))) {
336
+ errorMsg += `, nonce: ${(0, util_1.bytesToHex)(nonce)} (expected: ${(0, util_1.bytesToHex)(new Uint8Array(8))})`;
337
+ error = true;
338
+ }
339
+ }
340
+ if (error) {
341
+ const msg = this._errorMsg(`Invalid PoS block: ${errorMsg}`);
342
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
343
+ }
344
+ }
345
+ }
346
+ /**
347
+ * Validates if the block gasLimit remains in the boundaries set by the protocol.
348
+ * Throws if out of bounds.
349
+ *
350
+ * @param parentBlockHeader - the header from the parent `Block` of this header
351
+ */
352
+ validateGasLimit(parentBlockHeader) {
353
+ let parentGasLimit = parentBlockHeader.gasLimit;
354
+ // EIP-1559: assume double the parent gas limit on fork block
355
+ // to adopt to the new gas target centered logic
356
+ const londonHardforkBlock = this.common.hardforkBlock(common_1.Hardfork.London);
357
+ if (typeof londonHardforkBlock === 'bigint' &&
358
+ londonHardforkBlock !== util_1.BIGINT_0 &&
359
+ this.number === londonHardforkBlock) {
360
+ const elasticity = this.common.param('elasticityMultiplier');
361
+ parentGasLimit = parentGasLimit * elasticity;
362
+ }
363
+ const gasLimit = this.gasLimit;
364
+ const a = parentGasLimit / this.common.param('gasLimitBoundDivisor');
365
+ const maxGasLimit = parentGasLimit + a;
366
+ const minGasLimit = parentGasLimit - a;
367
+ if (gasLimit >= maxGasLimit) {
368
+ const msg = this._errorMsg(`gas limit increased too much. Gas limit: ${gasLimit}, max gas limit: ${maxGasLimit}`);
369
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
370
+ }
371
+ if (gasLimit <= minGasLimit) {
372
+ const msg = this._errorMsg(`gas limit decreased too much. Gas limit: ${gasLimit}, min gas limit: ${minGasLimit}`);
373
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
374
+ }
375
+ if (gasLimit < this.common.param('minGasLimit')) {
376
+ const msg = this._errorMsg(`gas limit decreased below minimum gas limit. Gas limit: ${gasLimit}, minimum gas limit: ${this.common.param('minGasLimit')}`);
377
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
378
+ }
379
+ }
380
+ /**
381
+ * Calculates the base fee for a potential next block
382
+ */
383
+ calcNextBaseFee() {
384
+ if (!this.common.isActivatedEIP(1559)) {
385
+ const msg = this._errorMsg('calcNextBaseFee() can only be called with EIP1559 being activated');
386
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
387
+ }
388
+ let nextBaseFee;
389
+ const elasticity = this.common.param('elasticityMultiplier');
390
+ const parentGasTarget = this.gasLimit / elasticity;
391
+ if (parentGasTarget === this.gasUsed) {
392
+ nextBaseFee = this.baseFeePerGas;
393
+ }
394
+ else if (this.gasUsed > parentGasTarget) {
395
+ const gasUsedDelta = this.gasUsed - parentGasTarget;
396
+ const baseFeeMaxChangeDenominator = this.common.param('baseFeeMaxChangeDenominator');
397
+ const calculatedDelta = (this.baseFeePerGas * gasUsedDelta) / parentGasTarget / baseFeeMaxChangeDenominator;
398
+ nextBaseFee = (calculatedDelta > util_1.BIGINT_1 ? calculatedDelta : util_1.BIGINT_1) + this.baseFeePerGas;
399
+ }
400
+ else {
401
+ const gasUsedDelta = parentGasTarget - this.gasUsed;
402
+ const baseFeeMaxChangeDenominator = this.common.param('baseFeeMaxChangeDenominator');
403
+ const calculatedDelta = (this.baseFeePerGas * gasUsedDelta) / parentGasTarget / baseFeeMaxChangeDenominator;
404
+ nextBaseFee =
405
+ this.baseFeePerGas - calculatedDelta > util_1.BIGINT_0
406
+ ? this.baseFeePerGas - calculatedDelta
407
+ : util_1.BIGINT_0;
408
+ }
409
+ return nextBaseFee;
410
+ }
411
+ /**
412
+ * Returns the price per unit of blob gas for a blob transaction in the current/pending block
413
+ * @returns the price in gwei per unit of blob gas spent
414
+ */
415
+ getBlobGasPrice() {
416
+ if (this.excessBlobGas === undefined) {
417
+ throw (0, util_1.EthereumJSErrorWithoutCode)('header must have excessBlobGas field populated');
418
+ }
419
+ return (0, helpers_ts_1.computeBlobGasPrice)(this.excessBlobGas, this.common);
420
+ }
421
+ /**
422
+ * Returns the total fee for blob gas spent for including blobs in block.
423
+ *
424
+ * @param numBlobs number of blobs in the transaction/block
425
+ * @returns the total blob gas fee for numBlobs blobs
426
+ */
427
+ calcDataFee(numBlobs) {
428
+ const blobGasPerBlob = this.common.param('blobGasPerBlob');
429
+ const blobGasUsed = blobGasPerBlob * BigInt(numBlobs);
430
+ const blobGasPrice = this.getBlobGasPrice();
431
+ return blobGasUsed * blobGasPrice;
432
+ }
433
+ /**
434
+ * Calculates the excess blob gas for next (hopefully) post EIP 4844 block.
435
+ */
436
+ calcNextExcessBlobGas(childCommon) {
437
+ const excessBlobGas = this.excessBlobGas ?? util_1.BIGINT_0;
438
+ const blobGasUsed = this.blobGasUsed ?? util_1.BIGINT_0;
439
+ const { targetBlobGasPerBlock: targetPerBlock, maxBlobGasPerBlock: maxPerBlock } = childCommon.getBlobGasSchedule();
440
+ // Early exit (strictly < per spec)
441
+ if (excessBlobGas + blobGasUsed < targetPerBlock) {
442
+ return util_1.BIGINT_0;
443
+ }
444
+ // EIP-7918 reserve price check
445
+ if (childCommon.isActivatedEIP(7918)) {
446
+ const blobBaseCost = childCommon.param('blobBaseCost');
447
+ const gasPerBlob = childCommon.param('blobGasPerBlob');
448
+ const baseFee = this.baseFeePerGas ?? util_1.BIGINT_0;
449
+ const blobFee = (0, helpers_ts_1.computeBlobGasPrice)(excessBlobGas, childCommon);
450
+ if (blobBaseCost * baseFee > gasPerBlob * blobFee) {
451
+ const increase = (blobGasUsed * (maxPerBlock - targetPerBlock)) / maxPerBlock;
452
+ return excessBlobGas + increase;
453
+ }
454
+ }
455
+ // Original 4844 path
456
+ return excessBlobGas + blobGasUsed - targetPerBlock;
457
+ }
458
+ /**
459
+ * Calculate the blob gas price of the block built on top of this one
460
+ * @returns The blob gas price
461
+ */
462
+ calcNextBlobGasPrice(childCommon) {
463
+ return (0, helpers_ts_1.computeBlobGasPrice)(this.calcNextExcessBlobGas(childCommon), childCommon);
464
+ }
465
+ /**
466
+ * Returns a Uint8Array Array of the raw Bytes in this header, in order.
467
+ */
468
+ raw() {
469
+ const rawItems = [
470
+ this.parentHash,
471
+ this.uncleHash,
472
+ this.coinbase.bytes,
473
+ this.stateRoot,
474
+ this.transactionsTrie,
475
+ this.receiptTrie,
476
+ this.logsBloom,
477
+ (0, util_1.bigIntToUnpaddedBytes)(this.difficulty),
478
+ (0, util_1.bigIntToUnpaddedBytes)(this.number),
479
+ (0, util_1.bigIntToUnpaddedBytes)(this.gasLimit),
480
+ (0, util_1.bigIntToUnpaddedBytes)(this.gasUsed),
481
+ (0, util_1.bigIntToUnpaddedBytes)(this.timestamp ?? util_1.BIGINT_0),
482
+ this.extraData,
483
+ this.mixHash,
484
+ this.nonce,
485
+ ];
486
+ if (this.common.isActivatedEIP(1559)) {
487
+ rawItems.push((0, util_1.bigIntToUnpaddedBytes)(this.baseFeePerGas));
488
+ }
489
+ if (this.common.isActivatedEIP(4895)) {
490
+ rawItems.push(this.withdrawalsRoot);
491
+ }
492
+ if (this.common.isActivatedEIP(4844)) {
493
+ rawItems.push((0, util_1.bigIntToUnpaddedBytes)(this.blobGasUsed));
494
+ rawItems.push((0, util_1.bigIntToUnpaddedBytes)(this.excessBlobGas));
495
+ }
496
+ if (this.common.isActivatedEIP(4788)) {
497
+ rawItems.push(this.parentBeaconBlockRoot);
498
+ }
499
+ if (this.common.isActivatedEIP(7685)) {
500
+ rawItems.push(this.requestsHash);
501
+ }
502
+ if (this.common.isActivatedEIP(7928)) {
503
+ rawItems.push(this.blockAccessListHash);
504
+ }
505
+ if (this.common.isActivatedEIP(7843)) {
506
+ rawItems.push((0, util_1.bigIntToUnpaddedBytes)(this.slotNumber));
507
+ }
508
+ return rawItems;
509
+ }
510
+ /**
511
+ * Returns the hash of the block header.
512
+ */
513
+ hash() {
514
+ var _a;
515
+ if (Object.isFrozen(this)) {
516
+ (_a = this.cache).hash ?? (_a.hash = this.keccakFunction(rlp_1.RLP.encode(this.raw())));
517
+ return this.cache.hash;
518
+ }
519
+ return this.keccakFunction(rlp_1.RLP.encode(this.raw()));
520
+ }
521
+ /**
522
+ * Checks if the block header is a genesis header.
523
+ */
524
+ isGenesis() {
525
+ return this.number === util_1.BIGINT_0;
526
+ }
527
+ /**
528
+ * Returns the canonical difficulty for this block.
529
+ *
530
+ * @param parentBlockHeader - the header from the parent `Block` of this header
531
+ */
532
+ ethashCanonicalDifficulty(parentBlockHeader) {
533
+ if (this.common.consensusType() !== common_1.ConsensusType.ProofOfWork) {
534
+ const msg = this._errorMsg('difficulty calculation is only supported on PoW chains');
535
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
536
+ }
537
+ if (this.common.consensusAlgorithm() !== common_1.ConsensusAlgorithm.Ethash) {
538
+ const msg = this._errorMsg('difficulty calculation currently only supports the ethash algorithm');
539
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
540
+ }
541
+ const blockTs = this.timestamp;
542
+ const { timestamp: parentTs, difficulty: parentDif } = parentBlockHeader;
543
+ const minimumDifficulty = this.common.param('minimumDifficulty');
544
+ const offset = parentDif / this.common.param('difficultyBoundDivisor');
545
+ let num = this.number;
546
+ // We use a ! here as TS cannot follow this hardfork-dependent logic, but it always gets assigned
547
+ let dif;
548
+ if (this.common.gteHardfork(common_1.Hardfork.Byzantium)) {
549
+ // max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99) (EIP100)
550
+ const uncleAddend = (0, util_1.equalsBytes)(parentBlockHeader.uncleHash, util_1.KECCAK256_RLP_ARRAY) ? 1 : 2;
551
+ let a = BigInt(uncleAddend) - (blockTs - parentTs) / BigInt(9);
552
+ const cutoff = BigInt(-99);
553
+ // MAX(cutoff, a)
554
+ if (cutoff > a) {
555
+ a = cutoff;
556
+ }
557
+ dif = parentDif + offset * a;
558
+ }
559
+ if (this.common.gteHardfork(common_1.Hardfork.Byzantium)) {
560
+ // Get delay as parameter from common
561
+ num = num - this.common.param('difficultyBombDelay');
562
+ if (num < util_1.BIGINT_0) {
563
+ num = util_1.BIGINT_0;
564
+ }
565
+ }
566
+ else if (this.common.gteHardfork(common_1.Hardfork.Homestead)) {
567
+ // 1 - (block_timestamp - parent_timestamp) // 10
568
+ let a = util_1.BIGINT_1 - (blockTs - parentTs) / BigInt(10);
569
+ const cutoff = BigInt(-99);
570
+ // MAX(cutoff, a)
571
+ if (cutoff > a) {
572
+ a = cutoff;
573
+ }
574
+ dif = parentDif + offset * a;
575
+ }
576
+ else {
577
+ // pre-homestead
578
+ if (parentTs + this.common.param('durationLimit') > blockTs) {
579
+ dif = offset + parentDif;
580
+ }
581
+ else {
582
+ dif = parentDif - offset;
583
+ }
584
+ }
585
+ const exp = num / BigInt(100000) - util_1.BIGINT_2;
586
+ if (exp >= 0) {
587
+ dif = dif + util_1.BIGINT_2 ** exp;
588
+ }
589
+ if (dif < minimumDifficulty) {
590
+ dif = minimumDifficulty;
591
+ }
592
+ return dif;
593
+ }
594
+ /**
595
+ * Returns the rlp encoding of the block header.
596
+ */
597
+ serialize() {
598
+ return rlp_1.RLP.encode(this.raw());
599
+ }
600
+ /**
601
+ * Returns the block header in JSON format.
602
+ */
603
+ toJSON() {
604
+ const withdrawalAttr = this.withdrawalsRoot
605
+ ? { withdrawalsRoot: (0, util_1.bytesToHex)(this.withdrawalsRoot) }
606
+ : {};
607
+ const JSONDict = {
608
+ parentHash: (0, util_1.bytesToHex)(this.parentHash),
609
+ uncleHash: (0, util_1.bytesToHex)(this.uncleHash),
610
+ coinbase: this.coinbase.toString(),
611
+ stateRoot: (0, util_1.bytesToHex)(this.stateRoot),
612
+ transactionsTrie: (0, util_1.bytesToHex)(this.transactionsTrie),
613
+ ...withdrawalAttr,
614
+ receiptTrie: (0, util_1.bytesToHex)(this.receiptTrie),
615
+ logsBloom: (0, util_1.bytesToHex)(this.logsBloom),
616
+ difficulty: (0, util_1.bigIntToHex)(this.difficulty),
617
+ number: (0, util_1.bigIntToHex)(this.number),
618
+ gasLimit: (0, util_1.bigIntToHex)(this.gasLimit),
619
+ gasUsed: (0, util_1.bigIntToHex)(this.gasUsed),
620
+ timestamp: (0, util_1.bigIntToHex)(this.timestamp),
621
+ extraData: (0, util_1.bytesToHex)(this.extraData),
622
+ mixHash: (0, util_1.bytesToHex)(this.mixHash),
623
+ nonce: (0, util_1.bytesToHex)(this.nonce),
624
+ };
625
+ if (this.common.isActivatedEIP(1559)) {
626
+ JSONDict.baseFeePerGas = (0, util_1.bigIntToHex)(this.baseFeePerGas);
627
+ }
628
+ if (this.common.isActivatedEIP(4844)) {
629
+ JSONDict.blobGasUsed = (0, util_1.bigIntToHex)(this.blobGasUsed);
630
+ JSONDict.excessBlobGas = (0, util_1.bigIntToHex)(this.excessBlobGas);
631
+ }
632
+ if (this.common.isActivatedEIP(4788)) {
633
+ JSONDict.parentBeaconBlockRoot = (0, util_1.bytesToHex)(this.parentBeaconBlockRoot);
634
+ }
635
+ if (this.common.isActivatedEIP(7685)) {
636
+ JSONDict.requestsHash = (0, util_1.bytesToHex)(this.requestsHash);
637
+ }
638
+ if (this.common.isActivatedEIP(7928)) {
639
+ JSONDict.blockAccessListHash = (0, util_1.bytesToHex)(this.blockAccessListHash);
640
+ }
641
+ if (this.common.isActivatedEIP(7843)) {
642
+ JSONDict.slotNumber = (0, util_1.bigIntToHex)(this.slotNumber);
643
+ }
644
+ return JSONDict;
645
+ }
646
+ /**
647
+ * Validates extra data is DAO_ExtraData for DAO_ForceExtraDataRange blocks after DAO
648
+ * activation block (see: https://blog.slock.it/hard-fork-specification-24b889e70703)
649
+ */
650
+ _validateDAOExtraData() {
651
+ if (!this.common.hardforkIsActiveOnBlock(common_1.Hardfork.Dao, this.number)) {
652
+ return;
653
+ }
654
+ const DAOActivationBlock = this.common.hardforkBlock(common_1.Hardfork.Dao);
655
+ if (DAOActivationBlock === null || this.number < DAOActivationBlock) {
656
+ return;
657
+ }
658
+ const DAO_ExtraData = (0, util_1.hexToBytes)('0x64616f2d686172642d666f726b');
659
+ const DAO_ForceExtraDataRange = BigInt(9);
660
+ const drift = this.number - DAOActivationBlock;
661
+ if (drift <= DAO_ForceExtraDataRange && !(0, util_1.equalsBytes)(this.extraData, DAO_ExtraData)) {
662
+ const msg = this._errorMsg(`extraData should be 'dao-hard-fork', got ${(0, util_1.bytesToUtf8)(this.extraData)} (hex: ${(0, util_1.bytesToHex)(this.extraData)})`);
663
+ throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
664
+ }
665
+ }
666
+ /**
667
+ * Return a compact error string representation of the object
668
+ */
669
+ errorStr() {
670
+ let hash = '';
671
+ try {
672
+ hash = (0, util_1.bytesToHex)(this.hash());
673
+ }
674
+ catch {
675
+ hash = 'error';
676
+ }
677
+ let hf = '';
678
+ try {
679
+ hf = this.common.hardfork();
680
+ }
681
+ catch {
682
+ hf = 'error';
683
+ }
684
+ let errorStr = `block header number=${this.number} hash=${hash} `;
685
+ errorStr += `hf=${hf} baseFeePerGas=${this.baseFeePerGas ?? 'none'}`;
686
+ return errorStr;
687
+ }
688
+ /**
689
+ * Helper function to create an annotated error message
690
+ *
691
+ * @param msg Base error message
692
+ * @hidden
693
+ */
694
+ _errorMsg(msg) {
695
+ return `${msg} (${this.errorStr()})`;
696
+ }
697
+ }
698
+ exports.BlockHeader = BlockHeader;
699
+ //# sourceMappingURL=header.js.map