|
1 | 1 | import { Common, Hardfork, Mainnet } from '@ethereumjs/common'
|
2 | 2 | import { StatefulVerkleStateManager } from '@ethereumjs/statemanager'
|
3 | 3 | import {
|
| 4 | + Address, |
4 | 5 | bigIntToBytes,
|
5 | 6 | bytesToHex,
|
6 | 7 | concatBytes,
|
@@ -107,3 +108,106 @@ describe('Precompiles: EXECUTE', () => {
|
107 | 108 | assert.equal(result.returnValue[0], 1)
|
108 | 109 | })
|
109 | 110 | })
|
| 111 | + |
| 112 | +describe('runCall', () => { |
| 113 | + it.only('should execute runCall', async () => { |
| 114 | + const common = new Common({ |
| 115 | + chain: Mainnet, |
| 116 | + hardfork: Hardfork.Prague, |
| 117 | + eips: [6800, 9999], |
| 118 | + customCrypto: { |
| 119 | + verkle, |
| 120 | + }, |
| 121 | + }) |
| 122 | + // Construct L2 state and transaction |
| 123 | + const account = createAccount({ balance: 0xffffffffffffffffffffffffffffffffffffffffn }) |
| 124 | + const address = createAddressFromString('0x999aebeac9619be18e0369d9cb8d0393cfb99021') |
| 125 | + const receiver = createAddressFromPrivateKey( |
| 126 | + hexToBytes('0xaeb51ceb07e4f6761ea6ad9a772d0e4a70367020fd6175b5e271d0d12e37d24d'), |
| 127 | + ) |
| 128 | + const l2Tx = { |
| 129 | + to: receiver.toBytes(), |
| 130 | + from: address.toBytes(), |
| 131 | + gasLimit: BigInt('0xffffffffff'), |
| 132 | + gasPrice: BigInt('0x1'), |
| 133 | + value: BigInt('0x1'), |
| 134 | + data: new Uint8Array(), |
| 135 | + } |
| 136 | + const l2Tree = await createVerkleTree({ verkleCrypto: verkle }) |
| 137 | + const l2StateManager = new StatefulVerkleStateManager({ common, trie: l2Tree }) |
| 138 | + await l2StateManager.putAccount(address, account) |
| 139 | + |
| 140 | + const preStateRoot = l2Tree.root() |
| 141 | + const l2EVM = await createEVM({ stateManager: l2StateManager, common }) |
| 142 | + |
| 143 | + l2EVM.verkleAccessWitness = new VerkleAccessWitness({ |
| 144 | + verkleCrypto: verkle, |
| 145 | + }) |
| 146 | + l2EVM.systemVerkleAccessWitness = new VerkleAccessWitness({ |
| 147 | + verkleCrypto: verkle, |
| 148 | + }) |
| 149 | + const res = await l2EVM.runCall({ |
| 150 | + to: receiver, |
| 151 | + caller: address, |
| 152 | + gasLimit: l2Tx.gasLimit, |
| 153 | + gasPrice: l2Tx.gasPrice, |
| 154 | + value: l2Tx.value, |
| 155 | + }) |
| 156 | + const executionGasUsed = res.execResult.executionGasUsed |
| 157 | + const postStateRoot = l2Tree.root() |
| 158 | + const execWitness = await generateExecutionWitness( |
| 159 | + l2StateManager, |
| 160 | + l2EVM.verkleAccessWitness, |
| 161 | + preStateRoot, |
| 162 | + ) |
| 163 | + |
| 164 | + // End of L2 state construction |
| 165 | + |
| 166 | + // Create mainnet state and EVM |
| 167 | + const tree = await createVerkleTree({ verkleCrypto: verkle }) |
| 168 | + const stateManager = new StatefulVerkleStateManager({ common, trie: tree }) |
| 169 | + const evm = await createEVM({ stateManager, common }) |
| 170 | + |
| 171 | + evm.verkleAccessWitness = new VerkleAccessWitness({ |
| 172 | + verkleCrypto: verkle, |
| 173 | + }) |
| 174 | + evm.systemVerkleAccessWitness = new VerkleAccessWitness({ |
| 175 | + verkleCrypto: verkle, |
| 176 | + }) |
| 177 | + |
| 178 | + // Create a trace |
| 179 | + const trace = { |
| 180 | + witness: executionWitnessJSONToSSZ(execWitness), |
| 181 | + txs: [l2Tx], |
| 182 | + } |
| 183 | + const traceBytes = traceContainer.encode(trace) |
| 184 | + |
| 185 | + // We use the sha256 hash of the serialized trace as a reference. This is standing in for the versionedHash that we should use |
| 186 | + // once we have the trace properly converted to an Ethereum blob. |
| 187 | + const hash = bytesToHex(sha256(traceBytes)) |
| 188 | + evm['executionBlobs'].set(hash, traceBytes) |
| 189 | + |
| 190 | + const caller = createAddressFromString('0x0000000000000000000000000000000000001234') |
| 191 | + await evm.stateManager.putAccount(caller, createAccount({ balance: 0xffffffffffffffffn })) |
| 192 | + const precompileAddrStr = '0x0000000000000000000000000000000000000012' |
| 193 | + |
| 194 | + const input = concatBytes( |
| 195 | + preStateRoot, |
| 196 | + postStateRoot, |
| 197 | + hexToBytes(hash), |
| 198 | + setLengthLeft(bigIntToBytes(executionGasUsed), 32), |
| 199 | + ) |
| 200 | + |
| 201 | + const mainnetTx = { |
| 202 | + to: createAddressFromString(precompileAddrStr), |
| 203 | + caller, |
| 204 | + gasLimit: BigInt('0xffffffffff'), |
| 205 | + gasPrice: BigInt('0x1'), |
| 206 | + value: BigInt('0x1'), |
| 207 | + data: input, |
| 208 | + } |
| 209 | + |
| 210 | + const res2 = await evm.runCall(mainnetTx) |
| 211 | + assert.equal(res2.execResult.returnValue[0], 1) |
| 212 | + }) |
| 213 | +}) |
0 commit comments