@feelyourprotocol/vm 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 +373 -0
- package/README.md +583 -0
- package/dist/cjs/bloom/index.d.ts +29 -0
- package/dist/cjs/bloom/index.d.ts.map +1 -0
- package/dist/cjs/bloom/index.js +76 -0
- package/dist/cjs/bloom/index.js.map +1 -0
- package/dist/cjs/buildBlock.d.ts +118 -0
- package/dist/cjs/buildBlock.d.ts.map +1 -0
- package/dist/cjs/buildBlock.js +363 -0
- package/dist/cjs/buildBlock.js.map +1 -0
- package/dist/cjs/constructors.d.ts +9 -0
- package/dist/cjs/constructors.d.ts.map +1 -0
- package/dist/cjs/constructors.js +75 -0
- package/dist/cjs/constructors.js.map +1 -0
- package/dist/cjs/emitEVMProfile.d.ts +9 -0
- package/dist/cjs/emitEVMProfile.d.ts.map +1 -0
- package/dist/cjs/emitEVMProfile.js +130 -0
- package/dist/cjs/emitEVMProfile.js.map +1 -0
- package/dist/cjs/index.d.ts +11 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +36 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/params.d.ts +3 -0
- package/dist/cjs/params.d.ts.map +1 -0
- package/dist/cjs/params.js +105 -0
- package/dist/cjs/params.js.map +1 -0
- package/dist/cjs/requests.d.ts +11 -0
- package/dist/cjs/requests.d.ts.map +1 -0
- package/dist/cjs/requests.js +208 -0
- package/dist/cjs/requests.js.map +1 -0
- package/dist/cjs/runBlock.d.ts +35 -0
- package/dist/cjs/runBlock.d.ts.map +1 -0
- package/dist/cjs/runBlock.js +797 -0
- package/dist/cjs/runBlock.js.map +1 -0
- package/dist/cjs/runFrameTx.d.ts +18 -0
- package/dist/cjs/runFrameTx.d.ts.map +1 -0
- package/dist/cjs/runFrameTx.js +313 -0
- package/dist/cjs/runFrameTx.js.map +1 -0
- package/dist/cjs/runTx.d.ts +18 -0
- package/dist/cjs/runTx.d.ts.map +1 -0
- package/dist/cjs/runTx.js +900 -0
- package/dist/cjs/runTx.js.map +1 -0
- package/dist/cjs/types.d.ts +452 -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/vm.d.ts +75 -0
- package/dist/cjs/vm.d.ts.map +1 -0
- package/dist/cjs/vm.js +111 -0
- package/dist/cjs/vm.js.map +1 -0
- package/dist/esm/bloom/index.d.ts +29 -0
- package/dist/esm/bloom/index.d.ts.map +1 -0
- package/dist/esm/bloom/index.js +72 -0
- package/dist/esm/bloom/index.js.map +1 -0
- package/dist/esm/buildBlock.d.ts +118 -0
- package/dist/esm/buildBlock.d.ts.map +1 -0
- package/dist/esm/buildBlock.js +358 -0
- package/dist/esm/buildBlock.js.map +1 -0
- package/dist/esm/constructors.d.ts +9 -0
- package/dist/esm/constructors.d.ts.map +1 -0
- package/dist/esm/constructors.js +72 -0
- package/dist/esm/constructors.js.map +1 -0
- package/dist/esm/emitEVMProfile.d.ts +9 -0
- package/dist/esm/emitEVMProfile.d.ts.map +1 -0
- package/dist/esm/emitEVMProfile.js +127 -0
- package/dist/esm/emitEVMProfile.js.map +1 -0
- package/dist/esm/index.d.ts +11 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/params.d.ts +3 -0
- package/dist/esm/params.d.ts.map +1 -0
- package/dist/esm/params.js +102 -0
- package/dist/esm/params.js.map +1 -0
- package/dist/esm/requests.d.ts +11 -0
- package/dist/esm/requests.d.ts.map +1 -0
- package/dist/esm/requests.js +204 -0
- package/dist/esm/requests.js.map +1 -0
- package/dist/esm/runBlock.d.ts +35 -0
- package/dist/esm/runBlock.d.ts.map +1 -0
- package/dist/esm/runBlock.js +790 -0
- package/dist/esm/runBlock.js.map +1 -0
- package/dist/esm/runFrameTx.d.ts +18 -0
- package/dist/esm/runFrameTx.d.ts.map +1 -0
- package/dist/esm/runFrameTx.js +310 -0
- package/dist/esm/runFrameTx.js.map +1 -0
- package/dist/esm/runTx.d.ts +18 -0
- package/dist/esm/runTx.d.ts.map +1 -0
- package/dist/esm/runTx.js +896 -0
- package/dist/esm/runTx.js.map +1 -0
- package/dist/esm/types.d.ts +452 -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/vm.d.ts +75 -0
- package/dist/esm/vm.d.ts.map +1 -0
- package/dist/esm/vm.js +107 -0
- package/dist/esm/vm.js.map +1 -0
- package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.prod.esm.tsbuildinfo +1 -0
- package/package.json +117 -0
- package/src/bloom/index.ts +83 -0
- package/src/buildBlock.ts +470 -0
- package/src/constructors.ts +91 -0
- package/src/emitEVMProfile.ts +151 -0
- package/src/index.ts +10 -0
- package/src/params.ts +104 -0
- package/src/requests.ts +293 -0
- package/src/runBlock.ts +1022 -0
- package/src/runFrameTx.ts +411 -0
- package/src/runTx.ts +1203 -0
- package/src/types.ts +511 -0
- package/src/vm.ts +147 -0
|
@@ -0,0 +1,797 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runBlock = runBlock;
|
|
4
|
+
exports.accumulateParentBlockHash = accumulateParentBlockHash;
|
|
5
|
+
exports.accumulateParentBeaconBlockRoot = accumulateParentBeaconBlockRoot;
|
|
6
|
+
exports.calculateMinerReward = calculateMinerReward;
|
|
7
|
+
exports.rewardAccount = rewardAccount;
|
|
8
|
+
exports.encodeReceipt = encodeReceipt;
|
|
9
|
+
const block_1 = require("@feelyourprotocol/block");
|
|
10
|
+
const common_1 = require("@feelyourprotocol/common");
|
|
11
|
+
const mpt_1 = require("@feelyourprotocol/mpt");
|
|
12
|
+
const rlp_1 = require("@feelyourprotocol/rlp");
|
|
13
|
+
const tx_1 = require("@feelyourprotocol/tx");
|
|
14
|
+
const util_1 = require("@feelyourprotocol/util");
|
|
15
|
+
const sha2_js_1 = require("@noble/hashes/sha2.js");
|
|
16
|
+
const debug_1 = require("debug");
|
|
17
|
+
const index_ts_1 = require("./bloom/index.js");
|
|
18
|
+
const emitEVMProfile_ts_1 = require("./emitEVMProfile.js");
|
|
19
|
+
const index_ts_2 = require("./index.js");
|
|
20
|
+
const requests_ts_1 = require("./requests.js");
|
|
21
|
+
const debug = (0, debug_1.default)('vm:block');
|
|
22
|
+
const parentBeaconBlockRootAddress = (0, util_1.createAddressFromString)('0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02');
|
|
23
|
+
let enableProfiler = false;
|
|
24
|
+
const stateRootCPLabel = 'New state root, DAO HF, checkpoints, block validation';
|
|
25
|
+
const processTxsLabel = 'Tx processing [ use per-tx profiler for more details ]';
|
|
26
|
+
const withdrawalsRewardsCommitLabel = 'Withdrawals, Rewards, EVM journal commit';
|
|
27
|
+
const entireBlockLabel = 'Entire block';
|
|
28
|
+
/**
|
|
29
|
+
* Processes the `block` running all of the transactions it contains and updating the miner's account
|
|
30
|
+
*
|
|
31
|
+
* vm method modifies the state if successfully executed and header fields are valid.
|
|
32
|
+
* state modifications will be reverted if an exception is raised during execution or validation.
|
|
33
|
+
*
|
|
34
|
+
* @param {VM} vm
|
|
35
|
+
* @param {RunBlockOpts} opts - Default values for options:
|
|
36
|
+
* - `generate`: false
|
|
37
|
+
*/
|
|
38
|
+
async function runBlock(vm, opts) {
|
|
39
|
+
if (vm['_opts'].profilerOpts?.reportAfterBlock === true) {
|
|
40
|
+
enableProfiler = true;
|
|
41
|
+
// eslint-disable-next-line no-console
|
|
42
|
+
console.time(entireBlockLabel);
|
|
43
|
+
}
|
|
44
|
+
const stateManager = vm.stateManager;
|
|
45
|
+
const { root } = opts;
|
|
46
|
+
const clearCache = opts.clearCache ?? true;
|
|
47
|
+
let { block } = opts;
|
|
48
|
+
const generateFields = opts.generate === true;
|
|
49
|
+
if (enableProfiler) {
|
|
50
|
+
const title = `Profiler run - Block ${block.header.number} (${(0, util_1.bytesToHex)(block.hash())} with ${block.transactions.length} txs`;
|
|
51
|
+
// eslint-disable-next-line no-console
|
|
52
|
+
console.log(title);
|
|
53
|
+
// eslint-disable-next-line no-console
|
|
54
|
+
console.time(stateRootCPLabel);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The `beforeBlock` event.
|
|
58
|
+
*
|
|
59
|
+
* @event Event: beforeBlock
|
|
60
|
+
* @type {Object}
|
|
61
|
+
* @property {Block} block emits the block that is about to be processed
|
|
62
|
+
*/
|
|
63
|
+
await vm._emit('beforeBlock', block);
|
|
64
|
+
const setHardforkUsed = opts.setHardfork ?? vm['_setHardfork'];
|
|
65
|
+
if (setHardforkUsed === true) {
|
|
66
|
+
vm.common.setHardforkBy({
|
|
67
|
+
blockNumber: block.header.number,
|
|
68
|
+
timestamp: block.header.timestamp,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (vm.common.isActivatedEIP(7928)) {
|
|
72
|
+
vm.evm.blockLevelAccessList = (0, util_1.createBlockLevelAccessList)();
|
|
73
|
+
}
|
|
74
|
+
if (vm.DEBUG) {
|
|
75
|
+
debug('-'.repeat(100));
|
|
76
|
+
debug(`Running block hash=${(0, util_1.bytesToHex)(block.hash())} number=${block.header.number} hardfork=${vm.common.hardfork()}`);
|
|
77
|
+
}
|
|
78
|
+
// Set state root if provided
|
|
79
|
+
if (root) {
|
|
80
|
+
if (vm.DEBUG) {
|
|
81
|
+
debug(`Set provided state root ${(0, util_1.bytesToHex)(root)} clearCache=${clearCache}`);
|
|
82
|
+
}
|
|
83
|
+
await stateManager.setStateRoot(root, clearCache);
|
|
84
|
+
}
|
|
85
|
+
if (vm.common.isActivatedEIP(7864)) {
|
|
86
|
+
// Initialize the access witness
|
|
87
|
+
if (vm.DEBUG) {
|
|
88
|
+
debug(`Initializing executionWitness`);
|
|
89
|
+
}
|
|
90
|
+
if (clearCache) {
|
|
91
|
+
stateManager.clearCaches();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// check for DAO support and if we should apply the DAO fork
|
|
95
|
+
if (vm.common.hardforkIsActiveOnBlock(common_1.Hardfork.Dao, block.header.number) &&
|
|
96
|
+
block.header.number === vm.common.hardforkBlock(common_1.Hardfork.Dao)) {
|
|
97
|
+
if (vm.DEBUG) {
|
|
98
|
+
debug(`Apply DAO hardfork`);
|
|
99
|
+
}
|
|
100
|
+
await vm.evm.journal.checkpoint();
|
|
101
|
+
await _applyDAOHardfork(vm.evm);
|
|
102
|
+
await vm.evm.journal.commit();
|
|
103
|
+
}
|
|
104
|
+
// Checkpoint state
|
|
105
|
+
await vm.evm.journal.checkpoint();
|
|
106
|
+
if (vm.DEBUG) {
|
|
107
|
+
debug(`block checkpoint`);
|
|
108
|
+
}
|
|
109
|
+
let result;
|
|
110
|
+
try {
|
|
111
|
+
result = await applyBlock(vm, block, opts);
|
|
112
|
+
if (vm.DEBUG) {
|
|
113
|
+
debug(`Received block results gasUsed=${result.gasUsed} bloom=${(0, util_1.short)(result.bloom.bitvector)} (${result.bloom.bitvector.length} bytes) receiptsRoot=${(0, util_1.bytesToHex)(result.receiptsRoot)} receipts=${result.receipts.length} txResults=${result.results.length}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
await vm.evm.journal.revert();
|
|
118
|
+
if (vm.DEBUG) {
|
|
119
|
+
debug(`block checkpoint reverted`);
|
|
120
|
+
}
|
|
121
|
+
if (enableProfiler) {
|
|
122
|
+
// eslint-disable-next-line no-console
|
|
123
|
+
console.timeEnd(withdrawalsRewardsCommitLabel);
|
|
124
|
+
}
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
let requestsHash;
|
|
128
|
+
let requests;
|
|
129
|
+
if (block.common.isActivatedEIP(7685)) {
|
|
130
|
+
const sha256Function = vm.common.customCrypto.sha256 ?? sha2_js_1.sha256;
|
|
131
|
+
requests = await (0, requests_ts_1.accumulateRequests)(vm, result.results);
|
|
132
|
+
requestsHash = (0, block_1.genRequestsRoot)(requests, sha256Function);
|
|
133
|
+
}
|
|
134
|
+
const stateRoot = await stateManager.getStateRoot();
|
|
135
|
+
// Given the generate option, either set resulting header
|
|
136
|
+
// values to the current block, or validate the resulting
|
|
137
|
+
// header values against the current block.
|
|
138
|
+
if (generateFields) {
|
|
139
|
+
const logsBloom = result.bloom.bitvector;
|
|
140
|
+
const gasUsed = result.gasUsed;
|
|
141
|
+
const receiptTrie = result.receiptsRoot;
|
|
142
|
+
const transactionsTrie = await _genTxTrie(block);
|
|
143
|
+
const generatedFields = {
|
|
144
|
+
stateRoot,
|
|
145
|
+
logsBloom,
|
|
146
|
+
gasUsed,
|
|
147
|
+
receiptTrie,
|
|
148
|
+
transactionsTrie,
|
|
149
|
+
requestsHash,
|
|
150
|
+
};
|
|
151
|
+
const blockData = {
|
|
152
|
+
...block,
|
|
153
|
+
header: { ...block.header, ...generatedFields },
|
|
154
|
+
};
|
|
155
|
+
block = (0, block_1.createBlock)(blockData, { common: vm.common });
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
try {
|
|
159
|
+
if (vm.common.isActivatedEIP(7685)) {
|
|
160
|
+
if (!(0, util_1.equalsBytes)(block.header.requestsHash, requestsHash)) {
|
|
161
|
+
if (vm.DEBUG)
|
|
162
|
+
debug(`Invalid requestsHash received=${(0, util_1.bytesToHex)(block.header.requestsHash)} expected=${(0, util_1.bytesToHex)(requestsHash)}`);
|
|
163
|
+
const msg = _errorMsg('invalid requestsHash', vm, block);
|
|
164
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Only validate the following headers if Stateless isn't activated
|
|
168
|
+
if ((0, util_1.equalsBytes)(result.receiptsRoot, block.header.receiptTrie) === false) {
|
|
169
|
+
if (vm.DEBUG) {
|
|
170
|
+
debug(`Invalid receiptTrie received=${(0, util_1.bytesToHex)(result.receiptsRoot)} expected=${(0, util_1.bytesToHex)(block.header.receiptTrie)}`);
|
|
171
|
+
}
|
|
172
|
+
const msg = _errorMsg('invalid receiptTrie', vm, block);
|
|
173
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
|
|
174
|
+
}
|
|
175
|
+
if (!((0, util_1.equalsBytes)(result.bloom.bitvector, block.header.logsBloom) === true)) {
|
|
176
|
+
if (vm.DEBUG) {
|
|
177
|
+
debug(`Invalid bloom received=${(0, util_1.bytesToHex)(result.bloom.bitvector)} expected=${(0, util_1.bytesToHex)(block.header.logsBloom)}`);
|
|
178
|
+
}
|
|
179
|
+
const msg = _errorMsg('invalid bloom', vm, block);
|
|
180
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
|
|
181
|
+
}
|
|
182
|
+
if (result.gasUsed !== block.header.gasUsed) {
|
|
183
|
+
if (vm.DEBUG) {
|
|
184
|
+
debug(`Invalid gasUsed received=${result.gasUsed} expected=${block.header.gasUsed}`);
|
|
185
|
+
}
|
|
186
|
+
const msg = _errorMsg('invalid gasUsed', vm, block);
|
|
187
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
|
|
188
|
+
}
|
|
189
|
+
if (!((0, util_1.equalsBytes)(stateRoot, block.header.stateRoot) === true)) {
|
|
190
|
+
if (vm.DEBUG) {
|
|
191
|
+
debug(`Invalid stateRoot received=${(0, util_1.bytesToHex)(stateRoot)} expected=${(0, util_1.bytesToHex)(block.header.stateRoot)}`);
|
|
192
|
+
}
|
|
193
|
+
const msg = _errorMsg(`invalid block stateRoot, got: ${(0, util_1.bytesToHex)(stateRoot)}, want: ${(0, util_1.bytesToHex)(block.header.stateRoot)}`, vm, block);
|
|
194
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
|
|
195
|
+
}
|
|
196
|
+
if (vm.common.isActivatedEIP(7864)) {
|
|
197
|
+
if (vm.evm.binaryTreeAccessWitness === undefined) {
|
|
198
|
+
throw Error(`binaryTreeAccessWitness required if binary tree (EIP-7864) is activated`);
|
|
199
|
+
}
|
|
200
|
+
// If binary tree is activated and executing statelessly, only validate the post-state
|
|
201
|
+
if ((await vm['_opts'].stateManager.verifyBinaryTreePostState(vm.evm.binaryTreeAccessWitness)) === false) {
|
|
202
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)(`Binary tree post state verification failed on block ${block.header.number}`);
|
|
203
|
+
}
|
|
204
|
+
debug(`Binary tree post state verification succeeded`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
await vm.evm.journal.revert();
|
|
209
|
+
if (vm.DEBUG) {
|
|
210
|
+
debug(`block checkpoint reverted`);
|
|
211
|
+
}
|
|
212
|
+
throw err;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Persist state
|
|
216
|
+
await vm.evm.journal.commit();
|
|
217
|
+
if (vm.DEBUG) {
|
|
218
|
+
debug(`block checkpoint committed`);
|
|
219
|
+
}
|
|
220
|
+
if (enableProfiler) {
|
|
221
|
+
// eslint-disable-next-line no-console
|
|
222
|
+
console.timeEnd(withdrawalsRewardsCommitLabel);
|
|
223
|
+
}
|
|
224
|
+
const results = {
|
|
225
|
+
receipts: result.receipts,
|
|
226
|
+
logsBloom: result.bloom.bitvector,
|
|
227
|
+
results: result.results,
|
|
228
|
+
stateRoot,
|
|
229
|
+
gasUsed: result.gasUsed,
|
|
230
|
+
receiptsRoot: result.receiptsRoot,
|
|
231
|
+
preimages: result.preimages,
|
|
232
|
+
requestsHash,
|
|
233
|
+
requests,
|
|
234
|
+
blockLevelAccessList: vm.evm.blockLevelAccessList,
|
|
235
|
+
};
|
|
236
|
+
const afterBlockEvent = { ...results, block };
|
|
237
|
+
/**
|
|
238
|
+
* The `afterBlock` event
|
|
239
|
+
*
|
|
240
|
+
* @event Event: afterBlock
|
|
241
|
+
* @type {AfterBlockEvent}
|
|
242
|
+
* @property {AfterBlockEvent} result emits the results of processing a block
|
|
243
|
+
*/
|
|
244
|
+
await vm._emit('afterBlock', afterBlockEvent);
|
|
245
|
+
if (vm.DEBUG) {
|
|
246
|
+
debug(`Running block finished hash=${(0, util_1.bytesToHex)(block.hash())} number=${block.header.number} hardfork=${vm.common.hardfork()}`);
|
|
247
|
+
}
|
|
248
|
+
if (enableProfiler) {
|
|
249
|
+
// eslint-disable-next-line no-console
|
|
250
|
+
console.timeEnd(entireBlockLabel);
|
|
251
|
+
const logs = vm.evm.getPerformanceLogs();
|
|
252
|
+
if (logs.precompiles.length === 0 && logs.opcodes.length === 0) {
|
|
253
|
+
// eslint-disable-next-line no-console
|
|
254
|
+
console.log('No block txs with precompile or opcode execution.');
|
|
255
|
+
}
|
|
256
|
+
(0, emitEVMProfile_ts_1.emitEVMProfile)(logs.precompiles, 'Precompile performance');
|
|
257
|
+
(0, emitEVMProfile_ts_1.emitEVMProfile)(logs.opcodes, 'Opcodes performance');
|
|
258
|
+
vm.evm.clearPerformanceLogs();
|
|
259
|
+
}
|
|
260
|
+
return results;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Validates and applies a block, computing the results of
|
|
264
|
+
* applying its transactions. vm method doesn't modify the
|
|
265
|
+
* block itself. It computes the block rewards and puts
|
|
266
|
+
* them on state (but doesn't persist the changes).
|
|
267
|
+
* @param {Block} block
|
|
268
|
+
* @param {RunBlockOpts} opts
|
|
269
|
+
*/
|
|
270
|
+
async function applyBlock(vm, block, opts) {
|
|
271
|
+
// Validate block
|
|
272
|
+
if (opts.skipBlockValidation !== true) {
|
|
273
|
+
if (block.header.gasLimit >= BigInt('0x8000000000000000')) {
|
|
274
|
+
const msg = _errorMsg('Invalid block with gas limit greater than (2^63 - 1)', vm, block);
|
|
275
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
if (vm.DEBUG) {
|
|
279
|
+
debug(`Validate block`);
|
|
280
|
+
}
|
|
281
|
+
// TODO: decide what block validation method is appropriate here
|
|
282
|
+
if (opts.skipHeaderValidation !== true) {
|
|
283
|
+
if (typeof vm.blockchain.validateHeader === 'function') {
|
|
284
|
+
await vm.blockchain.validateHeader(block.header);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)('cannot validate header: blockchain has no `validateHeader` method');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
await block.validateData(false, true, opts.validateBlockSize ?? false);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (vm.common.isActivatedEIP(4788)) {
|
|
294
|
+
if (vm.DEBUG) {
|
|
295
|
+
debug(`accumulate parentBeaconBlockRoot`);
|
|
296
|
+
}
|
|
297
|
+
await accumulateParentBeaconBlockRoot(vm, block.header.parentBeaconBlockRoot, block.header.timestamp);
|
|
298
|
+
}
|
|
299
|
+
if (vm.common.isActivatedEIP(2935)) {
|
|
300
|
+
if (vm.DEBUG) {
|
|
301
|
+
debug(`accumulate parentBlockHash `);
|
|
302
|
+
}
|
|
303
|
+
await accumulateParentBlockHash(vm, block.header.number, block.header.parentHash);
|
|
304
|
+
}
|
|
305
|
+
if (enableProfiler) {
|
|
306
|
+
// eslint-disable-next-line no-console
|
|
307
|
+
console.timeEnd(stateRootCPLabel);
|
|
308
|
+
}
|
|
309
|
+
// Apply transactions
|
|
310
|
+
if (vm.DEBUG) {
|
|
311
|
+
debug(`Apply transactions`);
|
|
312
|
+
}
|
|
313
|
+
const blockResults = await applyTransactions(vm, block, opts);
|
|
314
|
+
if (enableProfiler) {
|
|
315
|
+
// eslint-disable-next-line no-console
|
|
316
|
+
console.time(withdrawalsRewardsCommitLabel);
|
|
317
|
+
}
|
|
318
|
+
// Add txResult preimages to the blockResults preimages
|
|
319
|
+
// Also add the coinbase preimage
|
|
320
|
+
if (opts.reportPreimages === true) {
|
|
321
|
+
if (vm.evm.stateManager.getAppliedKey === undefined) {
|
|
322
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)('applyBlock: evm.stateManager.getAppliedKey can not be undefined if reportPreimages is true');
|
|
323
|
+
}
|
|
324
|
+
blockResults.preimages.set((0, util_1.bytesToHex)(vm.evm.stateManager.getAppliedKey(block.header.coinbase.toBytes())), block.header.coinbase.toBytes());
|
|
325
|
+
for (const txResult of blockResults.results) {
|
|
326
|
+
if (txResult.preimages !== undefined) {
|
|
327
|
+
for (const [key, preimage] of txResult.preimages) {
|
|
328
|
+
blockResults.preimages.set(key, preimage);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (vm.common.isActivatedEIP(4895)) {
|
|
334
|
+
if (opts.reportPreimages === true)
|
|
335
|
+
vm.evm.journal.startReportingPreimages();
|
|
336
|
+
await assignWithdrawals(vm, block);
|
|
337
|
+
if (opts.reportPreimages === true && vm.evm.journal.preimages !== undefined) {
|
|
338
|
+
for (const [key, preimage] of vm.evm.journal.preimages) {
|
|
339
|
+
blockResults.preimages.set(key, preimage);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
await vm.evm.journal.cleanup();
|
|
343
|
+
}
|
|
344
|
+
// Pay ommers and miners
|
|
345
|
+
if (block.common.consensusType() === common_1.ConsensusType.ProofOfWork) {
|
|
346
|
+
await assignBlockRewards(vm, block);
|
|
347
|
+
}
|
|
348
|
+
if (vm.common.isActivatedEIP(7864) && vm.evm.systemBinaryTreeAccessWitness !== undefined) {
|
|
349
|
+
vm.evm.systemBinaryTreeAccessWitness?.commit();
|
|
350
|
+
if (vm.DEBUG) {
|
|
351
|
+
debug('Binary tree access witness aggregate costs:');
|
|
352
|
+
vm.evm.binaryTreeAccessWitness?.debugWitnessCost();
|
|
353
|
+
debug('System binary tree access witness aggregate costs:');
|
|
354
|
+
vm.evm.systemBinaryTreeAccessWitness?.debugWitnessCost();
|
|
355
|
+
}
|
|
356
|
+
vm.evm.binaryTreeAccessWitness?.merge(vm.evm.systemBinaryTreeAccessWitness);
|
|
357
|
+
}
|
|
358
|
+
return blockResults;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* vm method runs the logic of EIP 2935 (save blockhashes to state)
|
|
362
|
+
* It will put the `parentHash` of the block to the storage slot of `block.number - 1` of the history storage contract.
|
|
363
|
+
* vm contract is used to retrieve BLOCKHASHes in EVM if EIP 2935 is activated.
|
|
364
|
+
* In case that the previous block of `block` is pre-EIP-2935 (so we are on the EIP 2935 fork block), additionally
|
|
365
|
+
* also add the currently available past blockhashes which are available by BLOCKHASH (so, the past 256 block hashes)
|
|
366
|
+
* @param vm The VM to run on
|
|
367
|
+
* @param block The current block to save the parent block hash of
|
|
368
|
+
*/
|
|
369
|
+
async function accumulateParentBlockHash(vm, currentBlockNumber, parentHash) {
|
|
370
|
+
if (!vm.common.isActivatedEIP(2935)) {
|
|
371
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)('Cannot call `accumulateParentBlockHash`: EIP 2935 is not active');
|
|
372
|
+
}
|
|
373
|
+
const historyAddress = new util_1.Address((0, util_1.bigIntToAddressBytes)(vm.common.param('historyStorageAddress')));
|
|
374
|
+
const historyServeWindow = vm.common.param('historyServeWindow');
|
|
375
|
+
// getAccount with historyAddress will throw error as witnesses are not bundled
|
|
376
|
+
// but we need to put account so as to query later for slot
|
|
377
|
+
const code = await vm.stateManager.getCode(historyAddress);
|
|
378
|
+
if (code.length === 0) {
|
|
379
|
+
// Exit early, system contract has no code so no storage is written
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
async function putBlockHash(vm, hash, number) {
|
|
383
|
+
// ringKey is the key the hash is actually put in (it is a ring buffer)
|
|
384
|
+
const ringKey = number % historyServeWindow;
|
|
385
|
+
if (vm.common.isActivatedEIP(7864)) {
|
|
386
|
+
if (vm.evm.systemBinaryTreeAccessWitness === undefined) {
|
|
387
|
+
throw Error(`systemBinaryTreeAccessWitness required if binary tree (EIP-7864) is activated`);
|
|
388
|
+
}
|
|
389
|
+
// Add to system binary tree access witness so that it doesn't warm up tx accesses
|
|
390
|
+
vm.evm.systemBinaryTreeAccessWitness.writeAccountStorage(historyAddress, ringKey);
|
|
391
|
+
}
|
|
392
|
+
const key = (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(ringKey), 32);
|
|
393
|
+
if (vm.common.isActivatedEIP(7928)) {
|
|
394
|
+
vm.evm.blockLevelAccessList.addStorageWrite(historyAddress.toString(), key, hash, vm.evm.blockLevelAccessList.blockAccessIndex);
|
|
395
|
+
}
|
|
396
|
+
await vm.stateManager.putStorage(historyAddress, key, hash);
|
|
397
|
+
}
|
|
398
|
+
await putBlockHash(vm, parentHash, currentBlockNumber - util_1.BIGINT_1);
|
|
399
|
+
// do cleanup if the code was not deployed
|
|
400
|
+
await vm.evm.journal.cleanup();
|
|
401
|
+
}
|
|
402
|
+
async function accumulateParentBeaconBlockRoot(vm, root, timestamp) {
|
|
403
|
+
if (!vm.common.isActivatedEIP(4788)) {
|
|
404
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)('Cannot call `accumulateParentBeaconBlockRoot`: EIP 4788 is not active');
|
|
405
|
+
}
|
|
406
|
+
// Save the parentBeaconBlockRoot to the beaconroot stateful precompile ring buffers
|
|
407
|
+
const historicalRootsLength = BigInt(vm.common.param('historicalRootsLength'));
|
|
408
|
+
const timestampIndex = timestamp % historicalRootsLength;
|
|
409
|
+
const timestampExtended = timestampIndex + historicalRootsLength;
|
|
410
|
+
/**
|
|
411
|
+
* Note: (by Gabriel)
|
|
412
|
+
* Get account will throw an error in stateless execution b/c witnesses are not bundled
|
|
413
|
+
* But we do need an account so we are able to put the storage
|
|
414
|
+
*/
|
|
415
|
+
const code = await vm.stateManager.getCode(parentBeaconBlockRootAddress);
|
|
416
|
+
if (code.length === 0) {
|
|
417
|
+
// Exit early, system contract has no code so no storage is written
|
|
418
|
+
// TODO: verify with Gabriel that this is fine regarding binary trees (should we put an empty account?)
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
if (vm.common.isActivatedEIP(7928)) {
|
|
422
|
+
vm.evm.blockLevelAccessList.addStorageWrite(parentBeaconBlockRootAddress.toString(), (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(timestampIndex), 32), (0, util_1.bigIntToBytes)(timestamp), vm.evm.blockLevelAccessList.blockAccessIndex);
|
|
423
|
+
}
|
|
424
|
+
await vm.stateManager.putStorage(parentBeaconBlockRootAddress, (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(timestampIndex), 32), (0, util_1.bigIntToBytes)(timestamp));
|
|
425
|
+
if (vm.common.isActivatedEIP(7928)) {
|
|
426
|
+
vm.evm.blockLevelAccessList.addStorageWrite(parentBeaconBlockRootAddress.toString(), (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(timestampExtended), 32), root, vm.evm.blockLevelAccessList.blockAccessIndex);
|
|
427
|
+
}
|
|
428
|
+
await vm.stateManager.putStorage(parentBeaconBlockRootAddress, (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(timestampExtended), 32), root);
|
|
429
|
+
// do cleanup if the code was not deployed
|
|
430
|
+
await vm.evm.journal.cleanup();
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Applies the transactions in a block, computing the receipts
|
|
434
|
+
* as well as gas usage and some relevant data. vm method is
|
|
435
|
+
* side-effect free (it doesn't modify the block nor the state).
|
|
436
|
+
* @param {Block} block
|
|
437
|
+
* @param {RunBlockOpts} opts
|
|
438
|
+
*/
|
|
439
|
+
async function applyTransactions(vm, block, opts) {
|
|
440
|
+
if (enableProfiler) {
|
|
441
|
+
// eslint-disable-next-line no-console
|
|
442
|
+
console.time(processTxsLabel);
|
|
443
|
+
}
|
|
444
|
+
const bloom = new index_ts_1.Bloom(undefined, vm.common);
|
|
445
|
+
// Block header gas accounting (EIP-7778: no refund subtraction)
|
|
446
|
+
let gasUsed = util_1.BIGINT_0;
|
|
447
|
+
// Receipt cumulative gas accounting (keeps tx refund subtraction semantics)
|
|
448
|
+
let receiptGasUsed = util_1.BIGINT_0;
|
|
449
|
+
let receiptTrie = undefined;
|
|
450
|
+
if (block.transactions.length !== 0) {
|
|
451
|
+
receiptTrie = new mpt_1.MerklePatriciaTrie({ common: vm.common });
|
|
452
|
+
}
|
|
453
|
+
const receipts = [];
|
|
454
|
+
const txResults = [];
|
|
455
|
+
/*
|
|
456
|
+
* Process transactions
|
|
457
|
+
*/
|
|
458
|
+
for (let txIdx = 0; txIdx < block.transactions.length; txIdx++) {
|
|
459
|
+
if (vm.common.isActivatedEIP(7928)) {
|
|
460
|
+
vm.evm.blockLevelAccessList.blockAccessIndex = txIdx + 1;
|
|
461
|
+
}
|
|
462
|
+
const tx = block.transactions[txIdx];
|
|
463
|
+
if (vm.DEBUG) {
|
|
464
|
+
debug(`Run tx ${txIdx + 1}/${block.transactions.length} gasLimit=${tx.gasLimit} type=${tx.type} (block gas used so far: ${gasUsed}/${block.header.gasLimit})`);
|
|
465
|
+
}
|
|
466
|
+
const gasLimitIsHigherThanBlock = block.header.gasLimit < tx.gasLimit + gasUsed;
|
|
467
|
+
if (gasLimitIsHigherThanBlock) {
|
|
468
|
+
const msg = _errorMsg('tx has a higher gas limit than the block', vm, block);
|
|
469
|
+
throw (0, util_1.EthereumJSErrorWithoutCode)(msg);
|
|
470
|
+
}
|
|
471
|
+
// Run the tx through the VM
|
|
472
|
+
const { skipBalance, skipNonce, skipHardForkValidation, reportPreimages } = opts;
|
|
473
|
+
const txRes = await (0, index_ts_2.runTx)(vm, {
|
|
474
|
+
tx,
|
|
475
|
+
block,
|
|
476
|
+
skipBalance,
|
|
477
|
+
skipNonce,
|
|
478
|
+
skipHardForkValidation,
|
|
479
|
+
blockGasUsed: receiptGasUsed,
|
|
480
|
+
reportPreimages,
|
|
481
|
+
});
|
|
482
|
+
txResults.push(txRes);
|
|
483
|
+
if (vm.DEBUG) {
|
|
484
|
+
debug('-'.repeat(100));
|
|
485
|
+
}
|
|
486
|
+
// Add to total block gas usage
|
|
487
|
+
gasUsed += txRes.blockGasSpent;
|
|
488
|
+
receiptGasUsed += txRes.totalGasSpent;
|
|
489
|
+
if (vm.DEBUG) {
|
|
490
|
+
debug(`Add tx gas used (${txRes.blockGasSpent}) to total block gas usage (-> ${gasUsed})`);
|
|
491
|
+
}
|
|
492
|
+
// Combine blooms via bitwise OR
|
|
493
|
+
bloom.or(txRes.bloom);
|
|
494
|
+
// Add receipt to trie to later calculate receipt root
|
|
495
|
+
receipts.push(txRes.receipt);
|
|
496
|
+
const encodedReceipt = encodeReceipt(txRes.receipt, tx.type);
|
|
497
|
+
await receiptTrie.put(rlp_1.RLP.encode(txIdx), encodedReceipt);
|
|
498
|
+
}
|
|
499
|
+
if (enableProfiler) {
|
|
500
|
+
// eslint-disable-next-line no-console
|
|
501
|
+
console.timeEnd(processTxsLabel);
|
|
502
|
+
}
|
|
503
|
+
const receiptsRoot = receiptTrie !== undefined ? receiptTrie.root() : util_1.KECCAK256_RLP;
|
|
504
|
+
return {
|
|
505
|
+
bloom,
|
|
506
|
+
gasUsed,
|
|
507
|
+
preimages: new Map(),
|
|
508
|
+
receiptsRoot,
|
|
509
|
+
receipts,
|
|
510
|
+
results: txResults,
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
async function assignWithdrawals(vm, block) {
|
|
514
|
+
if (vm.common.isActivatedEIP(7928)) {
|
|
515
|
+
vm.evm.blockLevelAccessList.blockAccessIndex = block.transactions.length + 1;
|
|
516
|
+
}
|
|
517
|
+
const withdrawals = block.withdrawals;
|
|
518
|
+
for (const withdrawal of withdrawals) {
|
|
519
|
+
const { address, amount } = withdrawal;
|
|
520
|
+
// Withdrawal amount is represented in Gwei so needs to be
|
|
521
|
+
// converted to wei
|
|
522
|
+
// Note: event if amount is 0, still reward the account
|
|
523
|
+
// such that the account is touched and marked for cleanup if it is empty
|
|
524
|
+
await rewardAccount(vm.evm, address, amount * util_1.GWEI_TO_WEI, vm.common);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Calculates block rewards for miner and ommers and puts
|
|
529
|
+
* the updated balances of their accounts to state.
|
|
530
|
+
*/
|
|
531
|
+
async function assignBlockRewards(vm, block) {
|
|
532
|
+
if (vm.DEBUG) {
|
|
533
|
+
debug(`Assign block rewards`);
|
|
534
|
+
}
|
|
535
|
+
const minerReward = vm.common.param('minerReward');
|
|
536
|
+
const ommers = block.uncleHeaders;
|
|
537
|
+
// Reward ommers
|
|
538
|
+
for (const ommer of ommers) {
|
|
539
|
+
const reward = calculateOmmerReward(ommer.number, block.header.number, minerReward);
|
|
540
|
+
const account = await rewardAccount(vm.evm, ommer.coinbase, reward, vm.common);
|
|
541
|
+
if (vm.DEBUG) {
|
|
542
|
+
debug(`Add uncle reward ${reward} to account ${ommer.coinbase} (-> ${account.balance})`);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
// Reward miner
|
|
546
|
+
const reward = calculateMinerReward(minerReward, ommers.length);
|
|
547
|
+
const account = await rewardAccount(vm.evm, block.header.coinbase, reward, vm.common);
|
|
548
|
+
if (vm.DEBUG) {
|
|
549
|
+
debug(`Add miner reward ${reward} to account ${block.header.coinbase} (-> ${account.balance})`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
function calculateOmmerReward(ommerBlockNumber, blockNumber, minerReward) {
|
|
553
|
+
const heightDiff = blockNumber - ommerBlockNumber;
|
|
554
|
+
let reward = ((util_1.BIGINT_8 - heightDiff) * minerReward) / util_1.BIGINT_8;
|
|
555
|
+
if (reward < util_1.BIGINT_0) {
|
|
556
|
+
reward = util_1.BIGINT_0;
|
|
557
|
+
}
|
|
558
|
+
return reward;
|
|
559
|
+
}
|
|
560
|
+
function calculateMinerReward(minerReward, ommersNum) {
|
|
561
|
+
// calculate nibling reward
|
|
562
|
+
const niblingReward = minerReward / BigInt(32);
|
|
563
|
+
const totalNiblingReward = niblingReward * BigInt(ommersNum);
|
|
564
|
+
const reward = minerReward + totalNiblingReward;
|
|
565
|
+
return reward;
|
|
566
|
+
}
|
|
567
|
+
async function rewardAccount(evm, address, reward, common) {
|
|
568
|
+
let account = await evm.stateManager.getAccount(address);
|
|
569
|
+
if (account === undefined) {
|
|
570
|
+
if (common.isActivatedEIP(7864) === true && reward !== util_1.BIGINT_0) {
|
|
571
|
+
if (evm.systemBinaryTreeAccessWitness === undefined) {
|
|
572
|
+
throw Error(`systemBinaryTreeAccessWitness required if binary tree (EIP-7864) is activated`);
|
|
573
|
+
}
|
|
574
|
+
evm.systemBinaryTreeAccessWitness.writeAccountHeader(address);
|
|
575
|
+
}
|
|
576
|
+
account = new util_1.Account();
|
|
577
|
+
}
|
|
578
|
+
const originalBalance = account.balance;
|
|
579
|
+
account.balance += reward;
|
|
580
|
+
if (common.isActivatedEIP(7928)) {
|
|
581
|
+
if (reward === util_1.BIGINT_0) {
|
|
582
|
+
evm.blockLevelAccessList?.addAddress(address.toString());
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
evm.blockLevelAccessList.addBalanceChange(address.toString(), account.balance, evm.blockLevelAccessList.blockAccessIndex, originalBalance);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
await evm.journal.putAccount(address, account);
|
|
589
|
+
if (common.isActivatedEIP(7864) === true && reward !== util_1.BIGINT_0) {
|
|
590
|
+
if (evm.systemBinaryTreeAccessWitness === undefined) {
|
|
591
|
+
throw Error(`systemBinaryTreeAccessWitness required if binary tree (EIP-7864) is activated`);
|
|
592
|
+
}
|
|
593
|
+
evm.systemBinaryTreeAccessWitness.writeAccountBasicData(address);
|
|
594
|
+
evm.systemBinaryTreeAccessWitness.readAccountCodeHash(address);
|
|
595
|
+
}
|
|
596
|
+
return account;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Returns the encoded tx receipt.
|
|
600
|
+
*/
|
|
601
|
+
function encodeReceipt(receipt, txType) {
|
|
602
|
+
const encoded = rlp_1.RLP.encode([
|
|
603
|
+
receipt.stateRoot ??
|
|
604
|
+
(receipt.status === 0 ? Uint8Array.from([]) : (0, util_1.hexToBytes)('0x01')),
|
|
605
|
+
(0, util_1.bigIntToBytes)(receipt.cumulativeBlockGasUsed),
|
|
606
|
+
receipt.bitvector,
|
|
607
|
+
receipt.logs,
|
|
608
|
+
]);
|
|
609
|
+
if (txType === tx_1.TransactionType.Legacy) {
|
|
610
|
+
return encoded;
|
|
611
|
+
}
|
|
612
|
+
// Serialize receipt according to EIP-2718:
|
|
613
|
+
// `typed-receipt = tx-type || receipt-data`
|
|
614
|
+
return (0, util_1.concatBytes)((0, util_1.intToBytes)(txType), encoded);
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Apply the DAO fork changes to the VM
|
|
618
|
+
*/
|
|
619
|
+
async function _applyDAOHardfork(evm) {
|
|
620
|
+
const state = evm.stateManager;
|
|
621
|
+
/* DAO account list */
|
|
622
|
+
const DAOAccountList = DAOConfig.DAOAccounts;
|
|
623
|
+
const DAORefundContract = DAOConfig.DAORefundContract;
|
|
624
|
+
const DAORefundContractAddress = new util_1.Address((0, util_1.unprefixedHexToBytes)(DAORefundContract));
|
|
625
|
+
if ((await state.getAccount(DAORefundContractAddress)) === undefined) {
|
|
626
|
+
await evm.journal.putAccount(DAORefundContractAddress, new util_1.Account());
|
|
627
|
+
}
|
|
628
|
+
let DAORefundAccount = await state.getAccount(DAORefundContractAddress);
|
|
629
|
+
if (DAORefundAccount === undefined) {
|
|
630
|
+
DAORefundAccount = new util_1.Account();
|
|
631
|
+
}
|
|
632
|
+
const originalDAORefundAccountBalance = DAORefundAccount.balance;
|
|
633
|
+
for (const addr of DAOAccountList) {
|
|
634
|
+
// retrieve the account and add it to the DAO's Refund accounts' balance.
|
|
635
|
+
const address = new util_1.Address((0, util_1.unprefixedHexToBytes)(addr));
|
|
636
|
+
let account = await state.getAccount(address);
|
|
637
|
+
if (account === undefined) {
|
|
638
|
+
account = new util_1.Account();
|
|
639
|
+
}
|
|
640
|
+
DAORefundAccount.balance += account.balance;
|
|
641
|
+
// clear the accounts' balance
|
|
642
|
+
const originalBalance = account.balance;
|
|
643
|
+
account.balance = util_1.BIGINT_0;
|
|
644
|
+
await evm.journal.putAccount(address, account);
|
|
645
|
+
if (evm.common.isActivatedEIP(7928)) {
|
|
646
|
+
evm.blockLevelAccessList.addBalanceChange(address.toString(), account.balance, evm.blockLevelAccessList.blockAccessIndex, originalBalance);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
// finally, put the Refund Account
|
|
650
|
+
await evm.journal.putAccount(DAORefundContractAddress, DAORefundAccount);
|
|
651
|
+
if (evm.common.isActivatedEIP(7928)) {
|
|
652
|
+
evm.blockLevelAccessList.addBalanceChange(DAORefundContractAddress.toString(), DAORefundAccount.balance, evm.blockLevelAccessList.blockAccessIndex, originalDAORefundAccountBalance);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
async function _genTxTrie(block) {
|
|
656
|
+
if (block.transactions.length === 0) {
|
|
657
|
+
return util_1.KECCAK256_RLP;
|
|
658
|
+
}
|
|
659
|
+
const trie = new mpt_1.MerklePatriciaTrie({ common: block.common });
|
|
660
|
+
for (const [i, tx] of block.transactions.entries()) {
|
|
661
|
+
await trie.put(rlp_1.RLP.encode(i), tx.serialize());
|
|
662
|
+
}
|
|
663
|
+
return trie.root();
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Internal helper function to create an annotated error message
|
|
667
|
+
*
|
|
668
|
+
* @param msg Base error message
|
|
669
|
+
* @hidden
|
|
670
|
+
*/
|
|
671
|
+
function _errorMsg(msg, vm, block) {
|
|
672
|
+
const blockErrorStr = 'errorStr' in block ? block.errorStr() : 'block';
|
|
673
|
+
const errorMsg = `${msg} (${vm.errorStr()} -> ${blockErrorStr})`;
|
|
674
|
+
return errorMsg;
|
|
675
|
+
}
|
|
676
|
+
const DAOConfig = {
|
|
677
|
+
DAOAccounts: [
|
|
678
|
+
'd4fe7bc31cedb7bfb8a345f31e668033056b2728',
|
|
679
|
+
'b3fb0e5aba0e20e5c49d252dfd30e102b171a425',
|
|
680
|
+
'2c19c7f9ae8b751e37aeb2d93a699722395ae18f',
|
|
681
|
+
'ecd135fa4f61a655311e86238c92adcd779555d2',
|
|
682
|
+
'1975bd06d486162d5dc297798dfc41edd5d160a7',
|
|
683
|
+
'a3acf3a1e16b1d7c315e23510fdd7847b48234f6',
|
|
684
|
+
'319f70bab6845585f412ec7724b744fec6095c85',
|
|
685
|
+
'06706dd3f2c9abf0a21ddcc6941d9b86f0596936',
|
|
686
|
+
'5c8536898fbb74fc7445814902fd08422eac56d0',
|
|
687
|
+
'6966ab0d485353095148a2155858910e0965b6f9',
|
|
688
|
+
'779543a0491a837ca36ce8c635d6154e3c4911a6',
|
|
689
|
+
'2a5ed960395e2a49b1c758cef4aa15213cfd874c',
|
|
690
|
+
'5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5',
|
|
691
|
+
'9c50426be05db97f5d64fc54bf89eff947f0a321',
|
|
692
|
+
'200450f06520bdd6c527622a273333384d870efb',
|
|
693
|
+
'be8539bfe837b67d1282b2b1d61c3f723966f049',
|
|
694
|
+
'6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb',
|
|
695
|
+
'f1385fb24aad0cd7432824085e42aff90886fef5',
|
|
696
|
+
'd1ac8b1ef1b69ff51d1d401a476e7e612414f091',
|
|
697
|
+
'8163e7fb499e90f8544ea62bbf80d21cd26d9efd',
|
|
698
|
+
'51e0ddd9998364a2eb38588679f0d2c42653e4a6',
|
|
699
|
+
'627a0a960c079c21c34f7612d5d230e01b4ad4c7',
|
|
700
|
+
'f0b1aa0eb660754448a7937c022e30aa692fe0c5',
|
|
701
|
+
'24c4d950dfd4dd1902bbed3508144a54542bba94',
|
|
702
|
+
'9f27daea7aca0aa0446220b98d028715e3bc803d',
|
|
703
|
+
'a5dc5acd6a7968a4554d89d65e59b7fd3bff0f90',
|
|
704
|
+
'd9aef3a1e38a39c16b31d1ace71bca8ef58d315b',
|
|
705
|
+
'63ed5a272de2f6d968408b4acb9024f4cc208ebf',
|
|
706
|
+
'6f6704e5a10332af6672e50b3d9754dc460dfa4d',
|
|
707
|
+
'77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6',
|
|
708
|
+
'492ea3bb0f3315521c31f273e565b868fc090f17',
|
|
709
|
+
'0ff30d6de14a8224aa97b78aea5388d1c51c1f00',
|
|
710
|
+
'9ea779f907f0b315b364b0cfc39a0fde5b02a416',
|
|
711
|
+
'ceaeb481747ca6c540a000c1f3641f8cef161fa7',
|
|
712
|
+
'cc34673c6c40e791051898567a1222daf90be287',
|
|
713
|
+
'579a80d909f346fbfb1189493f521d7f48d52238',
|
|
714
|
+
'e308bd1ac5fda103967359b2712dd89deffb7973',
|
|
715
|
+
'4cb31628079fb14e4bc3cd5e30c2f7489b00960c',
|
|
716
|
+
'ac1ecab32727358dba8962a0f3b261731aad9723',
|
|
717
|
+
'4fd6ace747f06ece9c49699c7cabc62d02211f75',
|
|
718
|
+
'440c59b325d2997a134c2c7c60a8c61611212bad',
|
|
719
|
+
'4486a3d68fac6967006d7a517b889fd3f98c102b',
|
|
720
|
+
'9c15b54878ba618f494b38f0ae7443db6af648ba',
|
|
721
|
+
'27b137a85656544b1ccb5a0f2e561a5703c6a68f',
|
|
722
|
+
'21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241',
|
|
723
|
+
'23b75c2f6791eef49c69684db4c6c1f93bf49a50',
|
|
724
|
+
'1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b',
|
|
725
|
+
'b9637156d330c0d605a791f1c31ba5890582fe1c',
|
|
726
|
+
'6131c42fa982e56929107413a9d526fd99405560',
|
|
727
|
+
'1591fc0f688c81fbeb17f5426a162a7024d430c2',
|
|
728
|
+
'542a9515200d14b68e934e9830d91645a980dd7a',
|
|
729
|
+
'c4bbd073882dd2add2424cf47d35213405b01324',
|
|
730
|
+
'782495b7b3355efb2833d56ecb34dc22ad7dfcc4',
|
|
731
|
+
'58b95c9a9d5d26825e70a82b6adb139d3fd829eb',
|
|
732
|
+
'3ba4d81db016dc2890c81f3acec2454bff5aada5',
|
|
733
|
+
'b52042c8ca3f8aa246fa79c3feaa3d959347c0ab',
|
|
734
|
+
'e4ae1efdfc53b73893af49113d8694a057b9c0d1',
|
|
735
|
+
'3c02a7bc0391e86d91b7d144e61c2c01a25a79c5',
|
|
736
|
+
'0737a6b837f97f46ebade41b9bc3e1c509c85c53',
|
|
737
|
+
'97f43a37f595ab5dd318fb46e7a155eae057317a',
|
|
738
|
+
'52c5317c848ba20c7504cb2c8052abd1fde29d03',
|
|
739
|
+
'4863226780fe7c0356454236d3b1c8792785748d',
|
|
740
|
+
'5d2b2e6fcbe3b11d26b525e085ff818dae332479',
|
|
741
|
+
'5f9f3392e9f62f63b8eac0beb55541fc8627f42c',
|
|
742
|
+
'057b56736d32b86616a10f619859c6cd6f59092a',
|
|
743
|
+
'9aa008f65de0b923a2a4f02012ad034a5e2e2192',
|
|
744
|
+
'304a554a310c7e546dfe434669c62820b7d83490',
|
|
745
|
+
'914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79',
|
|
746
|
+
'4deb0033bb26bc534b197e61d19e0733e5679784',
|
|
747
|
+
'07f5c1e1bc2c93e0402f23341973a0e043f7bf8a',
|
|
748
|
+
'35a051a0010aba705c9008d7a7eff6fb88f6ea7b',
|
|
749
|
+
'4fa802324e929786dbda3b8820dc7834e9134a2a',
|
|
750
|
+
'9da397b9e80755301a3b32173283a91c0ef6c87e',
|
|
751
|
+
'8d9edb3054ce5c5774a420ac37ebae0ac02343c6',
|
|
752
|
+
'0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9',
|
|
753
|
+
'5dc28b15dffed94048d73806ce4b7a4612a1d48f',
|
|
754
|
+
'bcf899e6c7d9d5a215ab1e3444c86806fa854c76',
|
|
755
|
+
'12e626b0eebfe86a56d633b9864e389b45dcb260',
|
|
756
|
+
'a2f1ccba9395d7fcb155bba8bc92db9bafaeade7',
|
|
757
|
+
'ec8e57756626fdc07c63ad2eafbd28d08e7b0ca5',
|
|
758
|
+
'd164b088bd9108b60d0ca3751da4bceb207b0782',
|
|
759
|
+
'6231b6d0d5e77fe001c2a460bd9584fee60d409b',
|
|
760
|
+
'1cba23d343a983e9b5cfd19496b9a9701ada385f',
|
|
761
|
+
'a82f360a8d3455c5c41366975bde739c37bfeb8a',
|
|
762
|
+
'9fcd2deaff372a39cc679d5c5e4de7bafb0b1339',
|
|
763
|
+
'005f5cee7a43331d5a3d3eec71305925a62f34b6',
|
|
764
|
+
'0e0da70933f4c7849fc0d203f5d1d43b9ae4532d',
|
|
765
|
+
'd131637d5275fd1a68a3200f4ad25c71a2a9522e',
|
|
766
|
+
'bc07118b9ac290e4622f5e77a0853539789effbe',
|
|
767
|
+
'47e7aa56d6bdf3f36be34619660de61275420af8',
|
|
768
|
+
'acd87e28b0c9d1254e868b81cba4cc20d9a32225',
|
|
769
|
+
'adf80daec7ba8dcf15392f1ac611fff65d94f880',
|
|
770
|
+
'5524c55fb03cf21f549444ccbecb664d0acad706',
|
|
771
|
+
'40b803a9abce16f50f36a77ba41180eb90023925',
|
|
772
|
+
'fe24cdd8648121a43a7c86d289be4dd2951ed49f',
|
|
773
|
+
'17802f43a0137c506ba92291391a8a8f207f487d',
|
|
774
|
+
'253488078a4edf4d6f42f113d1e62836a942cf1a',
|
|
775
|
+
'86af3e9626fce1957c82e88cbf04ddf3a2ed7915',
|
|
776
|
+
'b136707642a4ea12fb4bae820f03d2562ebff487',
|
|
777
|
+
'dbe9b615a3ae8709af8b93336ce9b477e4ac0940',
|
|
778
|
+
'f14c14075d6c4ed84b86798af0956deef67365b5',
|
|
779
|
+
'ca544e5c4687d109611d0f8f928b53a25af72448',
|
|
780
|
+
'aeeb8ff27288bdabc0fa5ebb731b6f409507516c',
|
|
781
|
+
'cbb9d3703e651b0d496cdefb8b92c25aeb2171f7',
|
|
782
|
+
'6d87578288b6cb5549d5076a207456a1f6a63dc0',
|
|
783
|
+
'b2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e',
|
|
784
|
+
'accc230e8a6e5be9160b8cdf2864dd2a001c28b6',
|
|
785
|
+
'2b3455ec7fedf16e646268bf88846bd7a2319bb2',
|
|
786
|
+
'4613f3bca5c44ea06337a9e439fbc6d42e501d0a',
|
|
787
|
+
'd343b217de44030afaa275f54d31a9317c7f441e',
|
|
788
|
+
'84ef4b2357079cd7a7c69fd7a37cd0609a679106',
|
|
789
|
+
'da2fef9e4a3230988ff17df2165440f37e8b1708',
|
|
790
|
+
'f4c64518ea10f995918a454158c6b61407ea345c',
|
|
791
|
+
'7602b46df5390e432ef1c307d4f2c9ff6d65cc97',
|
|
792
|
+
'bb9bc244d798123fde783fcc1c72d3bb8c189413',
|
|
793
|
+
'807640a13483f8ac783c557fcdf27be11ea4ac7a',
|
|
794
|
+
],
|
|
795
|
+
DAORefundContract: 'bf4ed7b27f1d666546e30d74d50d173d20bca754',
|
|
796
|
+
};
|
|
797
|
+
//# sourceMappingURL=runBlock.js.map
|