Skip to content

Commit 30835b8

Browse files
eth/catalyst: make compliant with spec
1 parent 9ff81fa commit 30835b8

File tree

2 files changed

+82
-23
lines changed

2 files changed

+82
-23
lines changed

eth/catalyst/api.go

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -765,43 +765,58 @@ func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*beaco
765765
var bodies = make([]*beacon.ExecutionPayloadBodyV1, len(hashes))
766766
for i, hash := range hashes {
767767
block := api.eth.BlockChain().GetBlockByHash(hash)
768-
bodies[i] = getBody(block)
768+
bodies[i] = api.getBody(block)
769769
}
770770
return bodies
771771
}
772772

773773
// GetPayloadBodiesByRangeV1 implements engine_getPayloadBodiesByRangeV1 which allows for retrieval of a range
774774
// of block bodies by the engine api.
775-
func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count uint64) []*beacon.ExecutionPayloadBodyV1 {
776-
if api.eth.BlockChain().CurrentBlock().NumberU64() < start {
777-
// Return [] if the requested range is past our latest block
778-
return []*beacon.ExecutionPayloadBodyV1{}
779-
}
780-
bodies := make([]*beacon.ExecutionPayloadBodyV1, count)
781-
for i := uint64(0); i < count; i++ {
782-
block := api.eth.BlockChain().GetBlockByNumber(start + i)
783-
bodies[i] = getBody(block)
784-
}
785-
return bodies
775+
func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count uint64) ([]*beacon.ExecutionPayloadBodyV1, error) {
776+
if start == 0 || count == 0 || count > 1024 {
777+
return nil, beacon.InvalidParams.With(fmt.Errorf("invalid start or count, start: %v count: %v", start, count))
778+
}
779+
current := api.eth.BlockChain().CurrentBlock().NumberU64()
780+
// Return [] if the requested range is past our latest block
781+
if current < start {
782+
return []*beacon.ExecutionPayloadBodyV1{}, nil
783+
}
784+
// limit count up until current
785+
end := start + count
786+
if end > current {
787+
end = current
788+
}
789+
var bodies []*beacon.ExecutionPayloadBodyV1
790+
for i := uint64(start); i < end; i++ {
791+
block := api.eth.BlockChain().GetBlockByNumber(i)
792+
bodies = append(bodies, api.getBody(block))
793+
}
794+
return bodies, nil
786795
}
787796

788-
func getBody(block *types.Block) *beacon.ExecutionPayloadBodyV1 {
797+
func (api *ConsensusAPI) getBody(block *types.Block) *beacon.ExecutionPayloadBodyV1 {
789798
if block == nil {
790799
return nil
791800
}
792801

793802
var (
794-
body = block.Body()
795-
txs = make([]hexutil.Bytes, len(body.Transactions))
803+
body = block.Body()
804+
txs = make([]hexutil.Bytes, len(body.Transactions))
805+
withdrawals = body.Withdrawals
796806
)
797807

798808
for j, tx := range body.Transactions {
799809
data, _ := tx.MarshalBinary()
800810
txs[j] = hexutil.Bytes(data)
801811
}
802812

813+
// Post-shanghai withdrawals MUST be set to empty slice instead of nil
814+
if withdrawals == nil && api.eth.APIBackend.ChainConfig().IsShanghai(block.Time()) {
815+
withdrawals = make([]*types.Withdrawal, 0)
816+
}
817+
803818
return &beacon.ExecutionPayloadBodyV1{
804819
TransactionData: txs,
805-
Withdrawals: body.Withdrawals,
820+
Withdrawals: withdrawals,
806821
}
807822
}

eth/catalyst/api_test.go

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,8 +1314,8 @@ func TestGetBlockBodiesByRange(t *testing.T) {
13141314
}{
13151315
// Genesis
13161316
{
1317-
results: []*types.Body{eth.BlockChain().GetBlockByNumber(0).Body()},
1318-
start: 0,
1317+
results: []*types.Body{blocks[0].Body()},
1318+
start: 1,
13191319
count: 1,
13201320
},
13211321
// First post-merge block
@@ -1332,26 +1332,70 @@ func TestGetBlockBodiesByRange(t *testing.T) {
13321332
},
13331333
// unavailable block
13341334
{
1335-
results: []*types.Body{blocks[19].Body(), nil, nil},
1336-
start: 20,
1335+
results: []*types.Body{blocks[18].Body()},
1336+
start: 19,
13371337
count: 3,
13381338
},
13391339
// after range
13401340
{
13411341
results: make([]*types.Body, 0),
1342-
start: 21,
1342+
start: 20,
13431343
count: 2,
13441344
},
13451345
}
13461346

13471347
for k, test := range tests {
1348-
result := api.GetPayloadBodiesByRangeV1(test.start, test.count)
1349-
if len(result) != len(test.results) {
1348+
result, err := api.GetPayloadBodiesByRangeV1(test.start, test.count)
1349+
if err != nil {
1350+
t.Fatal(err)
1351+
}
1352+
if len(result) == len(test.results) {
13501353
for i, r := range result {
13511354
if !equalBody(test.results[i], r) {
13521355
t.Fatalf("test %v: invalid response: expected %+v got %+v", k, test.results[i], r)
13531356
}
13541357
}
1358+
} else {
1359+
t.Fatalf("invalid length want %v got %v", len(test.results), len(result))
1360+
}
1361+
}
1362+
}
1363+
1364+
func TestGetBlockBodiesByRangeInvalidParams(t *testing.T) {
1365+
node, eth, _ := setupBodies(t)
1366+
api := NewConsensusAPI(eth)
1367+
defer node.Close()
1368+
1369+
tests := []struct {
1370+
start uint64
1371+
count uint64
1372+
}{
1373+
// Genesis
1374+
{
1375+
start: 0,
1376+
count: 1,
1377+
},
1378+
// No block requested
1379+
{
1380+
start: 1,
1381+
count: 0,
1382+
},
1383+
// Genesis & no block
1384+
{
1385+
start: 0,
1386+
count: 0,
1387+
},
1388+
// More than 1024 blocks
1389+
{
1390+
start: 1,
1391+
count: 1025,
1392+
},
1393+
}
1394+
1395+
for _, test := range tests {
1396+
result, err := api.GetPayloadBodiesByRangeV1(test.start, test.count)
1397+
if err == nil {
1398+
t.Fatalf("expected error, got %v", result)
13551399
}
13561400
}
13571401
}

0 commit comments

Comments
 (0)