7
7
hexToBytes ,
8
8
} from '@ethereumjs/util'
9
9
import { createVerkleTree } from '@ethereumjs/verkle'
10
+ import * as ssz from 'micro-eth-signer/ssz'
10
11
11
12
import { createEVM } from '../constructors.js'
12
13
import { EvmErrorResult , OOGResult } from '../evm.js'
@@ -22,6 +23,56 @@ import type { ExecResult } from '../types.js'
22
23
import type { PrecompileInput } from './types.js'
23
24
import type { VerkleExecutionWitness } from '@ethereumjs/util'
24
25
26
+ const MAX_CALL_DATA_SIZE = 7500000 // Assuming a transaction with all zero bytes fills up an entire block worth of gas
27
+ export const traceContainer = ssz . container ( {
28
+ txs : ssz . list (
29
+ 256 ,
30
+ ssz . container ( {
31
+ to : ssz . bytevector ( 20 ) ,
32
+ from : ssz . bytevector ( 20 ) ,
33
+ gasLimit : ssz . uint64 ,
34
+ gasPrice : ssz . uint64 ,
35
+ value : ssz . uint64 ,
36
+ data : ssz . bytelist ( MAX_CALL_DATA_SIZE ) ,
37
+ } ) ,
38
+ ) ,
39
+ witness : ssz . container ( {
40
+ stateDiff : ssz . list (
41
+ 256 ,
42
+ ssz . container ( {
43
+ stem : ssz . bytevector ( 31 ) ,
44
+ suffixDiffs : ssz . list (
45
+ 256 ,
46
+ ssz . container ( {
47
+ suffix : ssz . uint64 ,
48
+ currentValue : ssz . bytevector ( 32 ) ,
49
+ newValue : ssz . bytevector ( 32 ) ,
50
+ } ) ,
51
+ ) ,
52
+ } ) ,
53
+ ) ,
54
+ parentStateRoot : ssz . bytevector ( 32 ) ,
55
+ } ) ,
56
+ } )
57
+
58
+ export const executionWitnessJSONToSSZ = ( witness : VerkleExecutionWitness ) => {
59
+ return {
60
+ stateDiff : witness . stateDiff . map ( ( diff ) => ( {
61
+ stem : hexToBytes ( diff . stem ) ,
62
+ suffixDiffs : diff . suffixDiffs . map ( ( suffixDiff ) => ( {
63
+ suffix : BigInt ( suffixDiff . suffix ) ,
64
+ currentValue :
65
+ suffixDiff . currentValue !== null
66
+ ? hexToBytes ( suffixDiff . currentValue )
67
+ : new Uint8Array ( 32 ) ,
68
+ newValue :
69
+ suffixDiff . newValue !== null ? hexToBytes ( suffixDiff . newValue ) : new Uint8Array ( 32 ) ,
70
+ } ) ) ,
71
+ } ) ) ,
72
+ parentStateRoot : hexToBytes ( witness . parentStateRoot ) ,
73
+ }
74
+ }
75
+
25
76
export async function precompile12 ( opts : PrecompileInput ) : Promise < ExecResult > {
26
77
const pName = getPrecompileName ( '12' )
27
78
const data = opts . data
@@ -43,15 +94,15 @@ export async function precompile12(opts: PrecompileInput): Promise<ExecResult> {
43
94
return EvmErrorResult ( new EvmError ( ERROR . REVERT ) , opts . gasLimit )
44
95
}
45
96
46
- const decodedTrace = JSON . parse ( new TextDecoder ( ) . decode ( traceBlob ) )
97
+ const decodedTrace = traceContainer . decode ( traceBlob )
47
98
48
99
if ( decodedTrace . txs === undefined || decodedTrace . witness === undefined ) {
49
100
opts . _debug ?.( `${ pName } error - trace is invalid` )
50
101
return EvmErrorResult ( new EvmError ( ERROR . REVERT ) , opts . gasLimit )
51
102
}
52
103
const executeGasUsed = bytesToBigInt ( data . subarray ( 96 ) )
53
104
54
- const witness = decodedTrace . witness as VerkleExecutionWitness
105
+ const witness = decodedTrace . witness
55
106
const tree = await createVerkleTree ( { verkleCrypto : opts . common . customCrypto . verkle } )
56
107
57
108
// Populate the L2 state trie with the prestate
@@ -61,10 +112,10 @@ export async function precompile12(opts: PrecompileInput): Promise<ExecResult> {
61
112
for ( const diff of stateDiff . suffixDiffs ) {
62
113
if ( diff . currentValue !== null ) {
63
114
suffixes . push ( Number ( diff . suffix ) )
64
- values . push ( hexToBytes ( diff . currentValue ) )
115
+ values . push ( diff . currentValue )
65
116
}
66
117
}
67
- const stem = hexToBytes ( stateDiff . stem )
118
+ const stem = stateDiff . stem
68
119
await tree . put ( stem , suffixes , values )
69
120
}
70
121
const executionResult = true
@@ -83,12 +134,12 @@ export async function precompile12(opts: PrecompileInput): Promise<ExecResult> {
83
134
// Run each transaction in the trace
84
135
for ( const tx of decodedTrace . txs ) {
85
136
const res = await l2EVM . runCall ( {
86
- to : createAddressFromString ( tx . to ) ,
87
- caller : createAddressFromString ( tx . from ) ,
137
+ to : createAddressFromString ( bytesToHex ( tx . to ) ) ,
138
+ caller : createAddressFromString ( bytesToHex ( tx . from ) ) ,
88
139
gasLimit : BigInt ( tx . gasLimit ) ,
89
140
gasPrice : BigInt ( tx . gasPrice ) ,
90
141
value : BigInt ( tx . value ) ,
91
- data : tx . data !== undefined ? hexToBytes ( tx . data ) : undefined ,
142
+ data : tx . data !== undefined ? tx . data : undefined ,
92
143
} )
93
144
computedGasUsed += res . execResult . executionGasUsed
94
145
}
0 commit comments