@@ -2,16 +2,19 @@ import { Common, Hardfork, Mainnet } from '@ethereumjs/common'
2
2
import { StatefulVerkleStateManager } from '@ethereumjs/statemanager'
3
3
import {
4
4
bigIntToBytes ,
5
+ bytesToHex ,
5
6
createAccount ,
6
7
createAddressFromString ,
8
+ decodeVerkleLeafBasicData ,
9
+ getVerkleStem ,
7
10
hexToBytes ,
8
11
setLengthLeft ,
9
12
} from '@ethereumjs/util'
10
13
import { createVerkleTree } from '@ethereumjs/verkle'
11
14
import * as verkle from 'micro-eth-signer/verkle'
12
15
import { assert , describe , it } from 'vitest'
13
16
14
- import { VerkleAccessWitness , createEVM } from '../src/index.js'
17
+ import { VerkleAccessWitness , createEVM , generateExecutionWitness } from '../src/index.js'
15
18
16
19
describe ( 'verkle tests' , ( ) => {
17
20
it ( 'should execute bytecode and update the state' , async ( ) => {
@@ -109,3 +112,79 @@ describe('verkle tests', () => {
109
112
assert . equal ( res . execResult . exceptionError ?. error , undefined )
110
113
} )
111
114
} )
115
+ describe ( 'generate an execution witness' , ( ) => {
116
+ it ( 'should generate the correct execution witness from a prestate and changes' , async ( ) => {
117
+ const preStateVKT = {
118
+ '0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d00' :
119
+ '0x00000000000000000000000000000000000000000000003635c9adc5dea00000' ,
120
+ '0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d01' :
121
+ '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' ,
122
+ '0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad700' :
123
+ '0x0000000000000036000000000000000100000000000000000000000000000000' ,
124
+ '0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad701' :
125
+ '0xdf61faef43babbb1ebde8fd82ab9cb4cb74c240d0025138521477e073f72080a' ,
126
+ '0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad780' :
127
+ '0x0060203611603157600143035f35116029575f35612000014311602957612000' ,
128
+ '0x5b5fdfedd6a0e932da408ac7d772a36513d1eee9b9926e52620c43a433aad781' :
129
+ '0x005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd000000000000000000' ,
130
+ }
131
+ const tx = {
132
+ type : '0x0' ,
133
+ chainId : '0x1' ,
134
+ nonce : '0x0' ,
135
+ gasPrice : '0xa' ,
136
+ gas : '0x5f5e100' ,
137
+ to : '0x8a0a19589531694250d570040a0c4b74576919b8' ,
138
+ value : '0x0' ,
139
+ input : '0x' ,
140
+ v : '0x25' ,
141
+ r : '0x50ae258f0b1f7c44e5227b43c338aa7f2d9805115b90a6baeaaee2358796e074' ,
142
+ s : '0xec910ad0244580c17e1d6a512b3574c62e92840184109e3037760d39b20cb94' ,
143
+ sender : '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b' ,
144
+ }
145
+
146
+ const common = new Common ( {
147
+ chain : Mainnet ,
148
+ customCrypto : { verkle } ,
149
+ eips : [ 6800 ] ,
150
+ hardfork : Hardfork . Prague ,
151
+ } )
152
+ const trie = await createVerkleTree ( )
153
+ // Setup prestate
154
+ for ( const [ key , value ] of Object . entries ( preStateVKT ) ) {
155
+ const stem = hexToBytes ( key ) . slice ( 0 , 31 )
156
+ const suffix = parseInt ( key . slice ( 64 ) , 16 )
157
+ await trie . put ( stem , [ suffix ] , [ hexToBytes ( value ) ] )
158
+ }
159
+ const preStateRoot = trie . root ( )
160
+ const sm = new StatefulVerkleStateManager ( { common, trie } )
161
+ const evm = await createEVM ( { common, stateManager : sm } )
162
+ evm . verkleAccessWitness = new VerkleAccessWitness ( {
163
+ verkleCrypto : verkle ,
164
+ } )
165
+ evm . systemVerkleAccessWitness = new VerkleAccessWitness ( {
166
+ verkleCrypto : verkle ,
167
+ } )
168
+ // Run tx
169
+ await evm . runCall ( {
170
+ code : hexToBytes ( tx . input ) ,
171
+ caller : createAddressFromString ( tx . sender ) ,
172
+ to : createAddressFromString ( tx . to ) ,
173
+ gasLimit : BigInt ( tx . gas ) ,
174
+ gasPrice : BigInt ( tx . gasPrice ) ,
175
+ } )
176
+ const executionWitness = await generateExecutionWitness (
177
+ sm ,
178
+ evm . verkleAccessWitness ,
179
+ preStateRoot ,
180
+ )
181
+ const stem = bytesToHex ( getVerkleStem ( verkle , createAddressFromString ( tx . sender ) ) )
182
+ assert . ok ( executionWitness . stateDiff . findIndex ( ( diff ) => diff . stem === stem ) !== - 1 )
183
+ const diff =
184
+ executionWitness . stateDiff [ executionWitness . stateDiff . findIndex ( ( diff ) => diff . stem === stem ) ]
185
+ const suffixDiff = diff . suffixDiffs . find ( ( suffDiff ) => suffDiff . suffix === 0 )
186
+ assert . ok ( suffixDiff ?. newValue !== undefined )
187
+ // Ensure sender account nonce is 1 in execution witness
188
+ assert . equal ( decodeVerkleLeafBasicData ( hexToBytes ( suffixDiff ! . newValue ! ) ) . nonce , 1n )
189
+ } )
190
+ } )
0 commit comments