eth/protocols: stop serving on unavailable response

This commit is contained in:
healthykim 2026-04-21 21:08:11 +02:00
parent c374e74ee1
commit 10337315a5
2 changed files with 23 additions and 16 deletions

View file

@ -422,18 +422,22 @@ func testGetBlockBodies(t *testing.T, protocol uint) {
{limit + 1, nil, nil, limit}, // No more than the possible block count should be returned {limit + 1, nil, nil, limit}, // No more than the possible block count should be returned
{0, []common.Hash{backend.chain.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable {0, []common.Hash{backend.chain.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable
{0, []common.Hash{backend.chain.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable {0, []common.Hash{backend.chain.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable
{0, []common.Hash{{}}, []bool{false}, 0}, // A non existent block should not be returned {0, []common.Hash{{}}, []bool{false}, 0}, // A non existent block should not be returned
// Existing and non-existing blocks interleaved should not cause problems // Existing blocks followed by a non-existing one should stop at the gap
{0, []common.Hash{
backend.chain.GetBlockByNumber(1).Hash(),
backend.chain.GetBlockByNumber(10).Hash(),
backend.chain.GetBlockByNumber(100).Hash(),
{},
}, []bool{true, true, true, false}, 3},
// A non-existing block at the start should return nothing
{0, []common.Hash{ {0, []common.Hash{
{}, {},
backend.chain.GetBlockByNumber(1).Hash(), backend.chain.GetBlockByNumber(1).Hash(),
{},
backend.chain.GetBlockByNumber(10).Hash(), backend.chain.GetBlockByNumber(10).Hash(),
{}, }, []bool{false, true, true}, 0},
backend.chain.GetBlockByNumber(100).Hash(),
{},
}, []bool{false, true, false, true, false, true, false}, 3},
} }
// Run each of the tests and verify the results against the chain // Run each of the tests and verify the results against the chain
for i, tt := range tests { for i, tt := range tests {

View file

@ -238,10 +238,12 @@ func ServiceGetBlockBodiesQuery(chain *core.BlockChain, query GetBlockBodiesRequ
lookups >= 2*maxBodiesServe { lookups >= 2*maxBodiesServe {
break break
} }
if data := chain.GetBodyRLP(hash); len(data) != 0 { data := chain.GetBodyRLP(hash)
bodies = append(bodies, data) if len(data) == 0 {
bytes += len(data) break // If we don't have this block's body, stop serving.
} }
bodies = append(bodies, data)
bytes += len(data)
} }
return bodies return bodies
} }
@ -281,16 +283,16 @@ func ServiceGetReceiptsQuery69(chain *core.BlockChain, query GetReceiptsRequest)
// Retrieve the requested block's receipts // Retrieve the requested block's receipts
results := chain.GetReceiptsRLP(hash) results := chain.GetReceiptsRLP(hash)
if results == nil { if results == nil {
continue // Can't retrieve the receipts, so we just skip this block. break // Don't have this block's receipts, stop serving.
} }
body := chain.GetBodyRLP(hash) body := chain.GetBodyRLP(hash)
if body == nil { if body == nil {
continue // The block body is missing, we also have to skip. break // The block body is missing, stop serving.
} }
results, _, err := blockReceiptsToNetwork(results, body, receiptQueryParams{}) results, _, err := blockReceiptsToNetwork(results, body, receiptQueryParams{})
if err != nil { if err != nil {
log.Error("Error in block receipts conversion", "hash", hash, "err", err) log.Error("Error in block receipts conversion", "hash", hash, "err", err)
continue break
} }
receipts.AppendRaw(results) receipts.AppendRaw(results)
bytes += len(results) bytes += len(results)
@ -312,12 +314,13 @@ func serviceGetReceiptsQuery70(chain *core.BlockChain, query GetReceiptsRequest,
break break
} }
results := chain.GetReceiptsRLP(hash) results := chain.GetReceiptsRLP(hash)
// If we don't have this block's receipts or body, stop serving.
if results == nil { if results == nil {
continue // Can't retrieve the receipts, so we just skip this block. break
} }
body := chain.GetBodyRLP(hash) body := chain.GetBodyRLP(hash)
if body == nil { if body == nil {
continue // The block body is missing, we also have to skip. break
} }
q := receiptQueryParams{sizeLimit: uint64(maxPacketSize - bytes)} q := receiptQueryParams{sizeLimit: uint64(maxPacketSize - bytes)}
if i == 0 { if i == 0 {
@ -326,7 +329,7 @@ func serviceGetReceiptsQuery70(chain *core.BlockChain, query GetReceiptsRequest,
results, incomplete, err := blockReceiptsToNetwork(results, body, q) results, incomplete, err := blockReceiptsToNetwork(results, body, q)
if err != nil { if err != nil {
log.Error("Error in block receipts conversion", "hash", hash, "err", err) log.Error("Error in block receipts conversion", "hash", hash, "err", err)
continue break
} }
if results == nil { if results == nil {
// This case triggers when the first receipt of the block receipts list doesn't // This case triggers when the first receipt of the block receipts list doesn't