Skip to content

Commit 2fea7ae

Browse files
committed
update request to just store bytes and expose getters for data and type and fix the 6110 and 7685 spec
1 parent 965eb86 commit 2fea7ae

File tree

4 files changed

+57
-101
lines changed

4 files changed

+57
-101
lines changed

packages/util/src/request.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,16 @@ export class CLRequest<T extends CLRequestType> {
7070
// for easy use
7171
public readonly bytes: Uint8Array
7272

73-
constructor(
74-
public readonly type: T,
75-
public readonly data: Uint8Array,
76-
) {
77-
this.bytes = concatBytes(new Uint8Array([this.type]), data)
73+
get type() {
74+
return this.bytes[0] as T
75+
}
76+
77+
get data() {
78+
return this.bytes.subarray(1)
79+
}
80+
81+
constructor(requestType: T, requestData: Uint8Array) {
82+
this.bytes = concatBytes(new Uint8Array([requestType]), requestData)
7883
}
7984
}
8085

packages/vm/src/requests.ts

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -133,45 +133,7 @@ const accumulateDepositsRequest = (
133133
for (let i = 0; i < tx.receipt.logs.length; i++) {
134134
const log = tx.receipt.logs[i]
135135
if (bytesToHex(log[0]).toLowerCase() === depositContractAddressLowerCase) {
136-
// Extracts validator pubkey, withdrawal credential, deposit amount, signature,
137-
// and validator index from Deposit Event log.
138-
// The event fields are non-indexed so contained in one byte array (log[2]) so parsing is as follows:
139-
// 1. Read the first 32 bytes to get the starting position of the first field.
140-
// 2. Continue reading the byte array in 32 byte increments to get all the field starting positions
141-
// 3. Read 32 bytes starting with the first field position to get the size of the first field
142-
// 4. Read the bytes from first field position + 32 + the size of the first field to get the first field value
143-
// 5. Repeat steps 3-4 for each field
144-
// This is equivalent to ABI-decoding the event:
145-
// event DepositEvent(
146-
// bytes pubkey,
147-
// bytes withdrawal_credentials,
148-
// bytes amount,
149-
// bytes signature,
150-
// bytes index
151-
//);
152-
153-
const pubKeyIdx = bytesToInt(log[2].slice(0, 32))
154-
const pubKeySize = bytesToInt(log[2].slice(pubKeyIdx, pubKeyIdx + 32))
155-
const withdrawalCreditsIdx = bytesToInt(log[2].slice(32, 64))
156-
const withdrawalCreditsSize = bytesToInt(
157-
log[2].slice(withdrawalCreditsIdx, withdrawalCreditsIdx + 32),
158-
)
159-
const amountIdx = bytesToInt(log[2].slice(64, 96))
160-
const amountSize = bytesToInt(log[2].slice(amountIdx, amountIdx + 32))
161-
const sigIdx = bytesToInt(log[2].slice(96, 128))
162-
const sigSize = bytesToInt(log[2].slice(sigIdx, sigIdx + 32))
163-
const indexIdx = bytesToInt(log[2].slice(128, 160))
164-
const indexSize = bytesToInt(log[2].slice(indexIdx, indexIdx + 32))
165-
166-
const pubkey = log[2].slice(pubKeyIdx + 32, pubKeyIdx + 32 + pubKeySize)
167-
const withdrawalCredentials = log[2].slice(
168-
withdrawalCreditsIdx + 32,
169-
withdrawalCreditsIdx + 32 + withdrawalCreditsSize,
170-
)
171-
const amount = log[2].slice(amountIdx + 32, amountIdx + 32 + amountSize)
172-
const signature = log[2].slice(sigIdx + 32, sigIdx + 32 + sigSize)
173-
const index = log[2].slice(indexIdx + 32, indexIdx + 32 + indexSize)
174-
136+
const { pubkey, withdrawalCredentials, amount, signature, index } = parseDepositLog(log[2])
175137
const depositRequestBytes = concatBytes(
176138
pubkey,
177139
withdrawalCredentials,
@@ -187,3 +149,43 @@ const accumulateDepositsRequest = (
187149

188150
return new DepositRequest(resultsBytes)
189151
}
152+
153+
function parseDepositLog(requestData: Uint8Array) {
154+
// Extracts validator pubkey, withdrawal credential, deposit amount, signature,
155+
// and validator index from Deposit Event log.
156+
// The event fields are non-indexed so contained in one byte array (log[2]) so parsing is as follows:
157+
// 1. Read the first 32 bytes to get the starting position of the first field.
158+
// 2. Continue reading the byte array in 32 byte increments to get all the field starting positions
159+
// 3. Read 32 bytes starting with the first field position to get the size of the first field
160+
// 4. Read the bytes from first field position + 32 + the size of the first field to get the first field value
161+
// 5. Repeat steps 3-4 for each field
162+
const pubKeyIdx = bytesToInt(requestData.slice(0, 32))
163+
const pubKeySize = bytesToInt(requestData.slice(pubKeyIdx, pubKeyIdx + 32))
164+
const withdrawalCreditsIdx = bytesToInt(requestData.slice(32, 64))
165+
const withdrawalCreditsSize = bytesToInt(
166+
requestData.slice(withdrawalCreditsIdx, withdrawalCreditsIdx + 32),
167+
)
168+
const amountIdx = bytesToInt(requestData.slice(64, 96))
169+
const amountSize = bytesToInt(requestData.slice(amountIdx, amountIdx + 32))
170+
const sigIdx = bytesToInt(requestData.slice(96, 128))
171+
const sigSize = bytesToInt(requestData.slice(sigIdx, sigIdx + 32))
172+
const indexIdx = bytesToInt(requestData.slice(128, 160))
173+
const indexSize = bytesToInt(requestData.slice(indexIdx, indexIdx + 32))
174+
175+
const pubkey = requestData.slice(pubKeyIdx + 32, pubKeyIdx + 32 + pubKeySize)
176+
const withdrawalCredentials = requestData.slice(
177+
withdrawalCreditsIdx + 32,
178+
withdrawalCreditsIdx + 32 + withdrawalCreditsSize,
179+
)
180+
const amount = requestData.slice(amountIdx + 32, amountIdx + 32 + amountSize)
181+
const signature = requestData.slice(sigIdx + 32, sigIdx + 32 + sigSize)
182+
const index = requestData.slice(indexIdx + 32, indexIdx + 32 + indexSize)
183+
184+
return {
185+
pubkey,
186+
withdrawalCredentials,
187+
amount,
188+
signature,
189+
index,
190+
}
191+
}

packages/vm/test/api/EIPs/eip-6110.spec.ts

Lines changed: 5 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ import { createBlock } from '@ethereumjs/block'
22
import { Common, Hardfork, Mainnet, getPresetChainConfig } from '@ethereumjs/common'
33
import { createTx } from '@ethereumjs/tx'
44
import {
5-
bytesToBigInt,
65
bytesToHex,
7-
bytesToInt,
86
createAccount,
97
createAddressFromPrivateKey,
108
createAddressFromString,
@@ -108,60 +106,11 @@ describe('EIP-7685 buildBlock tests', () => {
108106
})
109107

110108
function parseDepositRequest(requestData: Uint8Array) {
111-
// Extracts validator pubkey, withdrawal credential, deposit amount, signature,
112-
// and validator index from Deposit Event log.
113-
// The event fields are non-indexed so contained in one byte array (log[2]) so parsing is as follows:
114-
// 1. Read the first 32 bytes to get the starting position of the first field.
115-
// 2. Continue reading the byte array in 32 byte increments to get all the field starting positions
116-
// 3. Read 32 bytes starting with the first field position to get the size of the first field
117-
// 4. Read the bytes from first field position + 32 + the size of the first field to get the first field value
118-
// 5. Repeat steps 3-4 for each field
119-
const pubKeyIdx = bytesToInt(requestData.slice(0, 32))
120-
const pubKeySize = bytesToInt(requestData.slice(pubKeyIdx, pubKeyIdx + 32))
121-
const withdrawalCreditsIdx = bytesToInt(requestData.slice(32, 64))
122-
const withdrawalCreditsSize = bytesToInt(
123-
requestData.slice(withdrawalCreditsIdx, withdrawalCreditsIdx + 32),
124-
)
125-
const amountIdx = bytesToInt(requestData.slice(64, 96))
126-
const amountSize = bytesToInt(requestData.slice(amountIdx, amountIdx + 32))
127-
const sigIdx = bytesToInt(requestData.slice(96, 128))
128-
const sigSize = bytesToInt(requestData.slice(sigIdx, sigIdx + 32))
129-
const indexIdx = bytesToInt(requestData.slice(128, 160))
130-
const indexSize = bytesToInt(requestData.slice(indexIdx, indexIdx + 32))
131-
const pubkey = requestData.slice(pubKeyIdx + 32, pubKeyIdx + 32 + pubKeySize)
132-
const withdrawalCredentials = requestData.slice(
133-
withdrawalCreditsIdx + 32,
134-
withdrawalCreditsIdx + 32 + withdrawalCreditsSize,
135-
)
136-
const amountBytes = requestData.slice(amountIdx + 32, amountIdx + 32 + amountSize)
137-
const amountBytesBigEndian = new Uint8Array([
138-
amountBytes[7],
139-
amountBytes[6],
140-
amountBytes[5],
141-
amountBytes[4],
142-
amountBytes[3],
143-
amountBytes[2],
144-
amountBytes[1],
145-
amountBytes[0],
146-
])
147-
const amount = bytesToBigInt(amountBytesBigEndian)
148-
149-
const signature = requestData.slice(sigIdx + 32, sigIdx + 32 + sigSize)
150-
151-
const indexBytes = requestData.slice(indexIdx + 32, indexIdx + 32 + indexSize)
152-
153-
// Convert the little-endian array to big-endian array
154-
const indexBytesBigEndian = new Uint8Array([
155-
indexBytes[7],
156-
indexBytes[6],
157-
indexBytes[5],
158-
indexBytes[4],
159-
indexBytes[3],
160-
indexBytes[2],
161-
indexBytes[1],
162-
indexBytes[0],
163-
])
164-
const index = bytesToBigInt(indexBytesBigEndian)
109+
const pubkey = requestData.subarray(0, 48)
110+
const withdrawalCredentials = requestData.subarray(48, 48 + 32)
111+
const amount = requestData.subarray(48 + 32, 48 + 32 + 8)
112+
const signature = requestData.subarray(48 + 32 + 8, 48 + 32 + 8 + 96)
113+
const index = requestData.subarray(48 + 32 + 8 + 96, 48 + 32 + 8 + 96 + 8)
165114

166115
return {
167116
pubkey,

packages/vm/test/api/EIPs/eip-7685.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const invalidRequestsRoot = hexToBytes(
1515
)
1616
function getRandomDepositRequest(): CLRequest<CLRequestType> {
1717
const sampleDepositRequest = hexToBytes(
18-
'0x0000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030ac842878bb70009552a4cfcad801d6e659c50bd50d7d03306790cb455ce7363c5b6972f0159d170f625a99b2064dbefc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020010000000000000000000000818ccb1c4eda80270b04d6df822b1e72dd83c303000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060a747f75c72d0cf0d2b52504c7385b516f0523e2f0842416399f42b4aee5c6384a5674f6426b1cc3d0827886fa9b909e616f5c9f61f986013ed2b9bf37071cbae951136265b549f44e3c8e26233c0433e9124b7fd0dc86e82f9fedfc0a179d76900000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000',
18+
'0x00ac842878bb70009552a4cfcad801d6e659c50bd50d7d03306790cb455ce7363c5b6972f0159d170f625a99b2064dbefc010000000000000000000000818ccb1c4eda80270b04d6df822b1e72dd83c3030040597307000000a747f75c72d0cf0d2b52504c7385b516f0523e2f0842416399f42b4aee5c6384a5674f6426b1cc3d0827886fa9b909e616f5c9f61f986013ed2b9bf37071cbae951136265b549f44e3c8e26233c0433e9124b7fd0dc86e82f9fedfc0a179d7690000000000000000',
1919
)
2020
return createCLRequest(sampleDepositRequest)
2121
}

0 commit comments

Comments
 (0)