Skip to content

Commit

Permalink
fix and test empty withdrawals
Browse files Browse the repository at this point in the history
  • Loading branch information
g11tech committed Nov 8, 2022
1 parent a9c0fc2 commit 199c5c5
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 55 deletions.
6 changes: 5 additions & 1 deletion packages/blockchain/src/db/manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Block, BlockHeader } from '@ethereumjs/block'
import { RLP } from '@ethereumjs/rlp'
import { arrToBufArr, bufferToBigInt } from '@ethereumjs/util'
import { KECCAK256_RLP, arrToBufArr, bufferToBigInt } from '@ethereumjs/util'

import { Cache } from './cache'
import { DBOp, DBTarget } from './operation'
Expand Down Expand Up @@ -113,6 +113,10 @@ export class DBManager {
if (error.code !== 'LEVEL_NOT_FOUND') {
throw error
}
// If this block had empty withdrawals push an empty array in body
if (header.withdrawalsRoot !== undefined && header.withdrawalsRoot.equals(KECCAK256_RLP)) {
body.push([])
}
}
const blockData = [header.raw(), ...body] as BlockBuffer
const opts: BlockOptions = { common: this._common }
Expand Down
116 changes: 62 additions & 54 deletions packages/client/test/rpc/engine/withdrawals.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,11 @@ import { checkError } from '../util'

import type { ExecutionPayload } from '../../../lib/rpc/modules/engine'

tape(`withdrawals spec tests`, async (t) => {
const { server } = await setupChain(genesisJSON, 'post-merge', { engine: true })
let req = params('engine_forkchoiceUpdatedV2', [validForkChoiceState, validPayloadAttributes])
let expectRes = checkError(
t,
INVALID_PARAMS,
"invalid argument 1 for key 'withdrawals': argument is not array"
)
await baseRequest(t, server, req, 200, expectRes, false)

req = params('engine_forkchoiceUpdatedV2', [
validForkChoiceState,
validPayloadAttributesWithWithdrawals,
])
let payloadId
expectRes = (res: any) => {
payloadId = res.body.result.payloadId
}
await baseRequest(t, server, req, 200, expectRes, false)

let payload: ExecutionPayload | undefined = undefined
req = params('engine_getPayloadV2', [payloadId])
expectRes = (res: any) => {
payload = res.body.result
t.equal(res.body.result.blockNumber, '0x1')
}
await baseRequest(t, server, req, 200, expectRes, false)
expectRes = (res: any) => {
t.equal(res.body.result.payloadStatus.status, 'VALID')
}

req = params('engine_newPayloadV2', [payload])
expectRes = (res: any) => {
t.equal(res.body.result.status, 'VALID')
}
await baseRequest(t, server, req, 200, expectRes, false)

req = params('engine_forkchoiceUpdatedV2', [
{
...validForkChoiceState,
headBlockHash: payload!.blockHash,
},
])
expectRes = (res: any) => {
t.equal(res.body.result.payloadStatus.status, 'VALID')
}
await baseRequest(t, server, req, 200, expectRes)
})
const validPayloadAttributes = {
timestamp: '0x2f',
prevRandao: '0xff00000000000000000000000000000000000000000000000000000000000000',
suggestedFeeRecipient: '0xaa00000000000000000000000000000000000000',
}

const withdrawalsVector = [
{
Expand Down Expand Up @@ -108,7 +65,7 @@ const withdrawalsVector = [
},
]

const withdrawals = withdrawalsVector.map((testVec) => ({
const withdrawalsGethVector = withdrawalsVector.map((testVec) => ({
index: intToHex(testVec.Index),
validatorIndex: intToHex(testVec.Validator),
address: testVec.Recipient,
Expand All @@ -121,9 +78,60 @@ const validForkChoiceState = {
finalizedBlockHash: '0xfe950635b1bd2a416ff6283b0bbd30176e1b1125ad06fa729da9f3f4c1c61710',
}

const validPayloadAttributes = {
timestamp: '0x2f',
prevRandao: '0xff00000000000000000000000000000000000000000000000000000000000000',
suggestedFeeRecipient: '0xaa00000000000000000000000000000000000000',
const testCases = [
{ name: 'empty withdrawals', withdrawals: [] },
{ name: '8 withdrawals', withdrawals: withdrawalsGethVector },
]

for (const { name, withdrawals } of testCases) {
const validPayloadAttributesWithWithdrawals = { ...validPayloadAttributes, withdrawals }

tape(name, async (t) => {
const { server } = await setupChain(genesisJSON, 'post-merge', { engine: true })

let req = params('engine_forkchoiceUpdatedV2', [validForkChoiceState, validPayloadAttributes])
let expectRes = checkError(
t,
INVALID_PARAMS,
"invalid argument 1 for key 'withdrawals': argument is not array"
)
await baseRequest(t, server, req, 200, expectRes, false)

req = params('engine_forkchoiceUpdatedV2', [
validForkChoiceState,
validPayloadAttributesWithWithdrawals,
])
let payloadId
expectRes = (res: any) => {
t.equal(res.body.result.payloadId !== undefined, true)
payloadId = res.body.result.payloadId
}
await baseRequest(t, server, req, 200, expectRes, false)

let payload: ExecutionPayload | undefined = undefined
req = params('engine_getPayloadV2', [payloadId])
expectRes = (res: any) => {
payload = res.body.result
t.equal(payload!.blockNumber, '0x1')
t.equal(payload!.withdrawals!.length, withdrawals.length, 'withdrawals should match')
}
await baseRequest(t, server, req, 200, expectRes, false)

req = params('engine_newPayloadV2', [payload])
expectRes = (res: any) => {
t.equal(res.body.result.status, 'VALID')
}
await baseRequest(t, server, req, 200, expectRes, false)

req = params('engine_forkchoiceUpdatedV2', [
{
...validForkChoiceState,
headBlockHash: payload!.blockHash,
},
])
expectRes = async (res: any) => {
t.equal(res.body.result.payloadStatus.status, 'VALID')
}
await baseRequest(t, server, req, 200, expectRes)
})
}
const validPayloadAttributesWithWithdrawals = { ...validPayloadAttributes, withdrawals }

0 comments on commit 199c5c5

Please sign in to comment.