Skip to content

Commit cac4765

Browse files
holimankielbarry
authored andcommitted
core: improve getBadBlocks to return full block rlp (ethereum#16902)
* core: improve getBadBlocks to return full block rlp * core, eth, ethapi: changes to getBadBlocks formatting * ethapi: address review concerns
1 parent d9a5f91 commit cac4765

File tree

3 files changed

+48
-21
lines changed

3 files changed

+48
-21
lines changed

core/blockchain.go

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,27 +1392,21 @@ func (bc *BlockChain) update() {
13921392
}
13931393
}
13941394

1395-
// BadBlockArgs represents the entries in the list returned when bad blocks are queried.
1396-
type BadBlockArgs struct {
1397-
Hash common.Hash `json:"hash"`
1398-
Header *types.Header `json:"header"`
1399-
}
1400-
14011395
// BadBlocks returns a list of the last 'bad blocks' that the client has seen on the network
1402-
func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) {
1403-
headers := make([]BadBlockArgs, 0, bc.badBlocks.Len())
1396+
func (bc *BlockChain) BadBlocks() []*types.Block {
1397+
blocks := make([]*types.Block, 0, bc.badBlocks.Len())
14041398
for _, hash := range bc.badBlocks.Keys() {
1405-
if hdr, exist := bc.badBlocks.Peek(hash); exist {
1406-
header := hdr.(*types.Header)
1407-
headers = append(headers, BadBlockArgs{header.Hash(), header})
1399+
if blk, exist := bc.badBlocks.Peek(hash); exist {
1400+
block := blk.(*types.Block)
1401+
blocks = append(blocks, block)
14081402
}
14091403
}
1410-
return headers, nil
1404+
return blocks
14111405
}
14121406

14131407
// addBadBlock adds a bad block to the bad-block LRU cache
14141408
func (bc *BlockChain) addBadBlock(block *types.Block) {
1415-
bc.badBlocks.Add(block.Header().Hash(), block.Header())
1409+
bc.badBlocks.Add(block.Hash(), block)
14161410
}
14171411

14181412
// reportBlock logs a bad block error.

eth/api.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/ethereum/go-ethereum/core/rawdb"
3333
"github.com/ethereum/go-ethereum/core/state"
3434
"github.com/ethereum/go-ethereum/core/types"
35+
"github.com/ethereum/go-ethereum/internal/ethapi"
3536
"github.com/ethereum/go-ethereum/log"
3637
"github.com/ethereum/go-ethereum/miner"
3738
"github.com/ethereum/go-ethereum/params"
@@ -351,10 +352,34 @@ func (api *PrivateDebugAPI) Preimage(ctx context.Context, hash common.Hash) (hex
351352
return nil, errors.New("unknown preimage")
352353
}
353354

355+
// BadBlockArgs represents the entries in the list returned when bad blocks are queried.
356+
type BadBlockArgs struct {
357+
Hash common.Hash `json:"hash"`
358+
Block map[string]interface{} `json:"block"`
359+
RLP string `json:"rlp"`
360+
}
361+
354362
// GetBadBLocks returns a list of the last 'bad blocks' that the client has seen on the network
355363
// and returns them as a JSON list of block-hashes
356-
func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]core.BadBlockArgs, error) {
357-
return api.eth.BlockChain().BadBlocks()
364+
func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, error) {
365+
blocks := api.eth.BlockChain().BadBlocks()
366+
results := make([]*BadBlockArgs, len(blocks))
367+
368+
var err error
369+
for i, block := range blocks {
370+
results[i] = &BadBlockArgs{
371+
Hash: block.Hash(),
372+
}
373+
if rlpBytes, err := rlp.EncodeToBytes(block); err != nil {
374+
results[i].RLP = err.Error() // Hacky, but hey, it works
375+
} else {
376+
results[i].RLP = fmt.Sprintf("0x%x", rlpBytes)
377+
}
378+
if results[i].Block, err = ethapi.RPCMarshalBlock(block, true, true); err != nil {
379+
results[i].Block = map[string]interface{}{"error": err.Error()}
380+
}
381+
}
382+
return results, nil
358383
}
359384

360385
// StorageRangeResult is the result of a debug_storageRangeAt API call.

internal/ethapi/api.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -792,10 +792,10 @@ func FormatLogs(logs []vm.StructLog) []StructLogRes {
792792
return formatted
793793
}
794794

795-
// rpcOutputBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
795+
// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
796796
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
797797
// transaction hashes.
798-
func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
798+
func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
799799
head := b.Header() // copies the header once
800800
fields := map[string]interface{}{
801801
"number": (*hexutil.Big)(head.Number),
@@ -808,7 +808,6 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
808808
"stateRoot": head.Root,
809809
"miner": head.Coinbase,
810810
"difficulty": (*hexutil.Big)(head.Difficulty),
811-
"totalDifficulty": (*hexutil.Big)(s.b.GetTd(b.Hash())),
812811
"extraData": hexutil.Bytes(head.Extra),
813812
"size": hexutil.Uint64(b.Size()),
814813
"gasLimit": hexutil.Uint64(head.GasLimit),
@@ -822,17 +821,15 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
822821
formatTx := func(tx *types.Transaction) (interface{}, error) {
823822
return tx.Hash(), nil
824823
}
825-
826824
if fullTx {
827825
formatTx = func(tx *types.Transaction) (interface{}, error) {
828826
return newRPCTransactionFromBlockHash(b, tx.Hash()), nil
829827
}
830828
}
831-
832829
txs := b.Transactions()
833830
transactions := make([]interface{}, len(txs))
834831
var err error
835-
for i, tx := range b.Transactions() {
832+
for i, tx := range txs {
836833
if transactions[i], err = formatTx(tx); err != nil {
837834
return nil, err
838835
}
@@ -850,6 +847,17 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
850847
return fields, nil
851848
}
852849

850+
// rpcOutputBlock uses the generalized output filler, then adds the total difficulty field, which requires
851+
// a `PublicBlockchainAPI`.
852+
func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
853+
fields, err := RPCMarshalBlock(b, inclTx, fullTx)
854+
if err != nil {
855+
return nil, err
856+
}
857+
fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(b.Hash()))
858+
return fields, err
859+
}
860+
853861
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
854862
type RPCTransaction struct {
855863
BlockHash common.Hash `json:"blockHash"`

0 commit comments

Comments
 (0)