@@ -3,14 +3,13 @@ import {
33 bigIntToAddressBytes ,
44 bigIntToBytes ,
55 bytesToHex ,
6- bytesToInt ,
76 createAddressFromString ,
8- createConsolidationRequest ,
9- createDepositRequest ,
10- createWithdrawalRequest ,
117 setLengthLeft ,
128} from '@ethereumjs/util'
139
10+ import { concatBytes } from '../../util/src/bytes.js'
11+ import { ConsolidationRequest , DepositRequest , WithdrawalRequest } from '../../util/src/request.js'
12+
1413import type { RunTxResult } from './types.js'
1514import type { VM } from './vm.js'
1615import type { CLRequest , CLRequestType } from '@ethereumjs/util'
@@ -33,30 +32,27 @@ export const accumulateRequests = async (
3332 vm . common [ '_chainParams' ] . depositContractAddress ?? Mainnet . depositContractAddress
3433 if ( depositContractAddress === undefined )
3534 throw new Error ( 'deposit contract address required with EIP 6110' )
36- await accumulateDeposits ( depositContractAddress , txResults , requests )
35+ const depositsRequest = accumulateDepositsRequest ( depositContractAddress , txResults )
36+ requests . push ( depositsRequest )
3737 }
3838
3939 if ( common . isActivatedEIP ( 7002 ) ) {
40- await accumulateEIP7002Requests ( vm , requests )
40+ const withdrawalsRequest = await accumulateWithdrawalsRequest ( vm )
41+ requests . push ( withdrawalsRequest )
4142 }
4243
4344 if ( common . isActivatedEIP ( 7251 ) ) {
44- await accumulateEIP7251Requests ( vm , requests )
45+ const consolidationsRequest = await accumulateConsolidationsRequest ( vm )
46+ requests . push ( consolidationsRequest )
4547 }
4648
47- if ( requests . length > 1 ) {
48- for ( let x = 1 ; x < requests . length ; x ++ ) {
49- if ( requests [ x ] . type < requests [ x - 1 ] . type )
50- throw new Error ( 'requests are not in ascending order' )
51- }
52- }
49+ // requests are already type byte ordered by construction
5350 return requests
5451}
5552
56- const accumulateEIP7002Requests = async (
53+ const accumulateWithdrawalsRequest = async (
5754 vm : VM ,
58- requests : CLRequest < CLRequestType > [ ] ,
59- ) : Promise < void > => {
55+ ) : Promise < CLRequest < CLRequestType . Withdrawal > > => {
6056 // Partial withdrawals logic
6157 const addressBytes = setLengthLeft (
6258 bigIntToBytes ( vm . common . param ( 'withdrawalRequestPredeployAddress' ) ) ,
@@ -71,7 +67,7 @@ const accumulateEIP7002Requests = async (
7167 const originalAccount = await vm . stateManager . getAccount ( withdrawalsAddress )
7268
7369 if ( originalAccount === undefined ) {
74- return
70+ return new WithdrawalRequest ( new Uint8Array ( ) )
7571 }
7672
7773 const results = await vm . evm . runCall ( {
@@ -87,22 +83,12 @@ const accumulateEIP7002Requests = async (
8783 }
8884
8985 const resultsBytes = results . execResult . returnValue
90- if ( resultsBytes . length > 0 ) {
91- // Each request is 76 bytes
92- for ( let startByte = 0 ; startByte < resultsBytes . length ; startByte += 76 ) {
93- const slicedBytes = resultsBytes . slice ( startByte , startByte + 76 )
94- const sourceAddress = slicedBytes . slice ( 0 , 20 ) // 20 Bytes
95- const validatorPubkey = slicedBytes . slice ( 20 , 68 ) // 48 Bytes
96- const amount = slicedBytes . slice ( 68 , 76 ) // 8 Bytes / Uint64 LE
97- requests . push ( createWithdrawalRequest ( { sourceAddress, validatorPubkey, amount } ) )
98- }
99- }
86+ return new WithdrawalRequest ( resultsBytes )
10087}
10188
102- const accumulateEIP7251Requests = async (
89+ const accumulateConsolidationsRequest = async (
10390 vm : VM ,
104- requests : CLRequest < CLRequestType > [ ] ,
105- ) : Promise < void > => {
91+ ) : Promise < CLRequest < CLRequestType . Consolidation > > => {
10692 // Partial withdrawals logic
10793 const addressBytes = setLengthLeft (
10894 bigIntToBytes ( vm . common . param ( 'consolidationRequestPredeployAddress' ) ) ,
@@ -117,7 +103,7 @@ const accumulateEIP7251Requests = async (
117103 const originalAccount = await vm . stateManager . getAccount ( consolidationsAddress )
118104
119105 if ( originalAccount === undefined ) {
120- return
106+ return new ConsolidationRequest ( new Uint8Array ( 0 ) )
121107 }
122108
123109 const results = await vm . evm . runCall ( {
@@ -133,67 +119,22 @@ const accumulateEIP7251Requests = async (
133119 }
134120
135121 const resultsBytes = results . execResult . returnValue
136- if ( resultsBytes . length > 0 ) {
137- // Each request is 116 bytes
138- for ( let startByte = 0 ; startByte < resultsBytes . length ; startByte += 116 ) {
139- const slicedBytes = resultsBytes . slice ( startByte , startByte + 116 )
140- const sourceAddress = slicedBytes . slice ( 0 , 20 ) // 20 Bytes
141- const sourcePubkey = slicedBytes . slice ( 20 , 68 ) // 48 Bytes
142- const targetPubkey = slicedBytes . slice ( 68 , 116 ) // 48 bytes
143- requests . push ( createConsolidationRequest ( { sourceAddress, sourcePubkey, targetPubkey } ) )
144- }
145- }
122+ return new ConsolidationRequest ( resultsBytes )
146123}
147124
148- const accumulateDeposits = async (
125+ const accumulateDepositsRequest = (
149126 depositContractAddress : string ,
150127 txResults : RunTxResult [ ] ,
151- requests : CLRequest < CLRequestType > [ ] ,
152- ) => {
128+ ) : CLRequest < CLRequestType . Deposit > => {
129+ let resultsBytes = new Uint8Array ( 0 )
153130 for ( const [ _ , tx ] of txResults . entries ( ) ) {
154131 for ( let i = 0 ; i < tx . receipt . logs . length ; i ++ ) {
155132 const log = tx . receipt . logs [ i ]
156133 if ( bytesToHex ( log [ 0 ] ) . toLowerCase ( ) === depositContractAddress . toLowerCase ( ) ) {
157- // Extracts validator pubkey, withdrawal credential, deposit amount, signature,
158- // and validator index from Deposit Event log.
159- // The event fields are non-indexed so contained in one byte array (log[2]) so parsing is as follows:
160- // 1. Read the first 32 bytes to get the starting position of the first field.
161- // 2. Continue reading the byte array in 32 byte increments to get all the field starting positions
162- // 3. Read 32 bytes starting with the first field position to get the size of the first field
163- // 4. Read the bytes from first field position + 32 + the size of the first field to get the first field value
164- // 5. Repeat steps 3-4 for each field
165- const pubKeyIdx = bytesToInt ( log [ 2 ] . slice ( 0 , 32 ) )
166- const pubKeySize = bytesToInt ( log [ 2 ] . slice ( pubKeyIdx , pubKeyIdx + 32 ) )
167- const withdrawalCreditsIdx = bytesToInt ( log [ 2 ] . slice ( 32 , 64 ) )
168- const withdrawalCreditsSize = bytesToInt (
169- log [ 2 ] . slice ( withdrawalCreditsIdx , withdrawalCreditsIdx + 32 ) ,
170- )
171- const amountIdx = bytesToInt ( log [ 2 ] . slice ( 64 , 96 ) )
172- const amountSize = bytesToInt ( log [ 2 ] . slice ( amountIdx , amountIdx + 32 ) )
173- const sigIdx = bytesToInt ( log [ 2 ] . slice ( 96 , 128 ) )
174- const sigSize = bytesToInt ( log [ 2 ] . slice ( sigIdx , sigIdx + 32 ) )
175- const indexIdx = bytesToInt ( log [ 2 ] . slice ( 128 , 160 ) )
176- const indexSize = bytesToInt ( log [ 2 ] . slice ( indexIdx , indexIdx + 32 ) )
177-
178- const pubkey = log [ 2 ] . slice ( pubKeyIdx + 32 , pubKeyIdx + 32 + pubKeySize )
179- const withdrawalCredentials = log [ 2 ] . slice (
180- withdrawalCreditsIdx + 32 ,
181- withdrawalCreditsIdx + 32 + withdrawalCreditsSize ,
182- )
183- const amount = log [ 2 ] . slice ( amountIdx + 32 , amountIdx + 32 + amountSize )
184- const signature = log [ 2 ] . slice ( sigIdx + 32 , sigIdx + 32 + sigSize )
185- const index = log [ 2 ] . slice ( indexIdx + 32 , indexIdx + 32 + indexSize )
186-
187- requests . push (
188- createDepositRequest ( {
189- pubkey,
190- withdrawalCredentials,
191- amount,
192- signature,
193- index,
194- } ) ,
195- )
134+ resultsBytes = concatBytes ( resultsBytes , log [ 2 ] )
196135 }
197136 }
198137 }
138+
139+ return new DepositRequest ( resultsBytes )
199140}
0 commit comments