@@ -12,6 +12,7 @@ import {
12
12
getVerkleStem ,
13
13
getVerkleTreeIndicesForCodeChunk ,
14
14
getVerkleTreeIndicesForStorageSlot ,
15
+ hexToBytes ,
15
16
intToBytes ,
16
17
} from '@ethereumjs/util'
17
18
import debugDefault from 'debug'
@@ -26,7 +27,17 @@ import type {
26
27
VerkleAccessedState ,
27
28
VerkleAccessedStateWithAddress ,
28
29
} from '@ethereumjs/common'
29
- import type { Address , PrefixedHexString , VerkleCrypto } from '@ethereumjs/util'
30
+ import type {
31
+ StatefulVerkleStateManager ,
32
+ StatelessVerkleStateManager ,
33
+ } from '@ethereumjs/statemanager'
34
+ import type {
35
+ Address ,
36
+ PrefixedHexString ,
37
+ VerkleCrypto ,
38
+ VerkleExecutionWitness ,
39
+ } from '@ethereumjs/util'
40
+ import type { VerkleTree } from '@ethereumjs/verkle'
30
41
31
42
const debug = debugDefault ( 'evm:verkle:aw' )
32
43
@@ -377,3 +388,46 @@ export class VerkleAccessWitness implements VerkleAccessWitnessInterface {
377
388
}
378
389
}
379
390
}
391
+
392
+ export const generateExecutionWitness = async (
393
+ stateManager : StatefulVerkleStateManager | StatelessVerkleStateManager ,
394
+ accessWitness : VerkleAccessWitness ,
395
+ parentStateRoot : Uint8Array ,
396
+ ) => {
397
+ const trie = ( stateManager as StatefulVerkleStateManager ) [ '_trie' ] as VerkleTree
398
+ const postStateRoot = await stateManager . getStateRoot ( )
399
+ const ew : VerkleExecutionWitness = {
400
+ stateDiff : [ ] ,
401
+ parentStateRoot : bytesToHex ( parentStateRoot ) ,
402
+ verkleProof : undefined as any ,
403
+ }
404
+ const accessedSuffixes = new Map < PrefixedHexString , number [ ] > ( )
405
+ for ( const chunkKey of accessWitness [ 'chunks' ] . keys ( ) ) {
406
+ const stem = chunkKey . slice ( 0 , 34 ) as PrefixedHexString
407
+ if ( accessedSuffixes . has ( stem ) ) {
408
+ const suffixes = accessedSuffixes . get ( stem )
409
+ suffixes ! . push ( parseInt ( chunkKey . slice ( 34 ) , 16 ) )
410
+ accessedSuffixes . set ( stem , suffixes ! )
411
+ } else {
412
+ accessedSuffixes . set ( stem , [ parseInt ( chunkKey . slice ( 34 ) , 16 ) ] )
413
+ }
414
+ }
415
+ // Get values
416
+ for ( const stem of accessedSuffixes . keys ( ) ) {
417
+ trie . root ( parentStateRoot )
418
+ const currentValues = await trie . get ( hexToBytes ( stem ) , accessedSuffixes . get ( stem ) ! )
419
+ trie . root ( postStateRoot )
420
+ const newValues = await trie . get ( hexToBytes ( stem ) , accessedSuffixes . get ( stem ) ! )
421
+ const stemStateDiff = [ ]
422
+ for ( const suffix of accessedSuffixes . get ( stem ) ! ) {
423
+ if ( currentValues [ suffix ] === newValues [ suffix ] ) continue
424
+ stemStateDiff . push ( {
425
+ suffix,
426
+ currentValue : currentValues [ suffix ] ? bytesToHex ( currentValues [ suffix ] ) : null ,
427
+ newValue : newValues [ suffix ] ? bytesToHex ( newValues [ suffix ] ) : null ,
428
+ } )
429
+ }
430
+ ew . stateDiff . push ( { stem, suffixDiffs : stemStateDiff } )
431
+ }
432
+ return ew
433
+ }
0 commit comments