mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
parent
de9ed732e2
commit
e34bbe10c6
5 changed files with 34 additions and 23 deletions
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"slices"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
|
|
@ -608,23 +608,13 @@ type badBlock struct {
|
||||||
Body *types.Body
|
Body *types.Body
|
||||||
}
|
}
|
||||||
|
|
||||||
// badBlockList implements the sort interface to allow sorting a list of
|
|
||||||
// bad blocks by their number in the reverse order.
|
|
||||||
type badBlockList []*badBlock
|
|
||||||
|
|
||||||
func (s badBlockList) Len() int { return len(s) }
|
|
||||||
func (s badBlockList) Less(i, j int) bool {
|
|
||||||
return s[i].Header.Number.Uint64() < s[j].Header.Number.Uint64()
|
|
||||||
}
|
|
||||||
func (s badBlockList) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
||||||
|
|
||||||
// ReadBadBlock retrieves the bad block with the corresponding block hash.
|
// ReadBadBlock retrieves the bad block with the corresponding block hash.
|
||||||
func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block {
|
func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block {
|
||||||
blob, err := db.Get(badBlockKey)
|
blob, err := db.Get(badBlockKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var badBlocks badBlockList
|
var badBlocks []*badBlock
|
||||||
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -647,7 +637,7 @@ func ReadAllBadBlocks(db ethdb.Reader) []*types.Block {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var badBlocks badBlockList
|
var badBlocks []*badBlock
|
||||||
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -669,7 +659,7 @@ func WriteBadBlock(db ethdb.KeyValueStore, block *types.Block) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Failed to load old bad blocks", "error", err)
|
log.Warn("Failed to load old bad blocks", "error", err)
|
||||||
}
|
}
|
||||||
var badBlocks badBlockList
|
var badBlocks []*badBlock
|
||||||
if len(blob) > 0 {
|
if len(blob) > 0 {
|
||||||
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
|
||||||
log.Crit("Failed to decode old bad blocks", "error", err)
|
log.Crit("Failed to decode old bad blocks", "error", err)
|
||||||
|
|
@ -685,7 +675,10 @@ func WriteBadBlock(db ethdb.KeyValueStore, block *types.Block) {
|
||||||
Header: block.Header(),
|
Header: block.Header(),
|
||||||
Body: block.Body(),
|
Body: block.Body(),
|
||||||
})
|
})
|
||||||
sort.Sort(sort.Reverse(badBlocks))
|
slices.SortFunc(badBlocks, func(a, b *badBlock) int {
|
||||||
|
// Note: sorting in descending number order.
|
||||||
|
return -a.Header.Number.Cmp(b.Header.Number)
|
||||||
|
})
|
||||||
if len(badBlocks) > badBlockToKeep {
|
if len(badBlocks) > badBlockToKeep {
|
||||||
badBlocks = badBlocks[:badBlockToKeep]
|
badBlocks = badBlocks[:badBlockToKeep]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -221,8 +221,8 @@ func TestBadBlockStorage(t *testing.T) {
|
||||||
Number: big.NewInt(1),
|
Number: big.NewInt(1),
|
||||||
Extra: []byte("bad block"),
|
Extra: []byte("bad block"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
})
|
})
|
||||||
if entry := ReadBadBlock(db, block.Hash()); entry != nil {
|
if entry := ReadBadBlock(db, block.Hash()); entry != nil {
|
||||||
t.Fatalf("Non existent block returned: %v", entry)
|
t.Fatalf("Non existent block returned: %v", entry)
|
||||||
|
|
@ -239,8 +239,8 @@ func TestBadBlockStorage(t *testing.T) {
|
||||||
Number: big.NewInt(2),
|
Number: big.NewInt(2),
|
||||||
Extra: []byte("bad block two"),
|
Extra: []byte("bad block two"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
})
|
})
|
||||||
WriteBadBlock(db, blockTwo)
|
WriteBadBlock(db, blockTwo)
|
||||||
|
|
||||||
|
|
@ -258,8 +258,8 @@ func TestBadBlockStorage(t *testing.T) {
|
||||||
Number: big.NewInt(int64(n)),
|
Number: big.NewInt(int64(n)),
|
||||||
Extra: []byte("bad block"),
|
Extra: []byte("bad block"),
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
TxHash: types.EmptyRootHash,
|
TxHash: types.EmptyTxsHash,
|
||||||
ReceiptHash: types.EmptyRootHash,
|
ReceiptHash: types.EmptyReceiptsHash,
|
||||||
})
|
})
|
||||||
WriteBadBlock(db, block)
|
WriteBadBlock(db, block)
|
||||||
}
|
}
|
||||||
|
|
@ -269,7 +269,7 @@ func TestBadBlockStorage(t *testing.T) {
|
||||||
}
|
}
|
||||||
for i := 0; i < len(badBlocks)-1; i++ {
|
for i := 0; i < len(badBlocks)-1; i++ {
|
||||||
if badBlocks[i].NumberU64() < badBlocks[i+1].NumberU64() {
|
if badBlocks[i].NumberU64() < badBlocks[i+1].NumberU64() {
|
||||||
t.Fatalf("The bad blocks are not sorted #[%d](%d) < #[%d](%d)", i, i+1, badBlocks[i].NumberU64(), badBlocks[i+1].NumberU64())
|
t.Fatalf("The bad blocks are not sorted #[%d](%d) < #[%d](%d)", i, badBlocks[i].NumberU64(), i+1, badBlocks[i+1].NumberU64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ type BadBlockArgs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBadBlocks returns a list of the last 'bad blocks' that the client has seen on the network
|
// GetBadBlocks returns a list of the last 'bad blocks' that the client has seen on the network
|
||||||
// and returns them as a JSON list of block-hashes
|
// and returns them as a JSON list of block hashes.
|
||||||
func (api *DebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, error) {
|
func (api *DebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, error) {
|
||||||
var (
|
var (
|
||||||
blocks = rawdb.ReadAllBadBlocks(api.eth.chainDb)
|
blocks = rawdb.ReadAllBadBlocks(api.eth.chainDb)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core"
|
"github.com/XinFinOrg/XDPoSChain/core"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
||||||
|
|
@ -460,6 +461,17 @@ func (api *API) TraceBlock(ctx context.Context, blob hexutil.Bytes, config *Trac
|
||||||
return api.traceBlock(ctx, block, config)
|
return api.traceBlock(ctx, block, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TraceBadBlock returns the structured logs created during the execution of
|
||||||
|
// EVM against a block pulled from the pool of bad ones and returns them as a JSON
|
||||||
|
// object.
|
||||||
|
func (api *API) TraceBadBlock(ctx context.Context, hash common.Hash, config *TraceConfig) ([]*txTraceResult, error) {
|
||||||
|
block := rawdb.ReadBadBlock(api.backend.ChainDb(), hash)
|
||||||
|
if block == nil {
|
||||||
|
return nil, fmt.Errorf("bad block %#x not found", hash)
|
||||||
|
}
|
||||||
|
return api.traceBlock(ctx, block, config)
|
||||||
|
}
|
||||||
|
|
||||||
// TraceBlockFromFile returns the structured logs created during the execution of
|
// TraceBlockFromFile returns the structured logs created during the execution of
|
||||||
// EVM and returns them as a JSON object.
|
// EVM and returns them as a JSON object.
|
||||||
func (api *API) TraceBlockFromFile(ctx context.Context, file string, config *TraceConfig) ([]*txTraceResult, error) {
|
func (api *API) TraceBlockFromFile(ctx context.Context, file string, config *TraceConfig) ([]*txTraceResult, error) {
|
||||||
|
|
|
||||||
|
|
@ -418,6 +418,12 @@ web3._extend({
|
||||||
params: 2,
|
params: 2,
|
||||||
inputFormatter: [null, null]
|
inputFormatter: [null, null]
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'traceBadBlock',
|
||||||
|
call: 'debug_traceBadBlock',
|
||||||
|
params: 1,
|
||||||
|
inputFormatter: [null]
|
||||||
|
}),
|
||||||
new web3._extend.Method({
|
new web3._extend.Method({
|
||||||
name: 'intermediateRoots',
|
name: 'intermediateRoots',
|
||||||
call: 'debug_intermediateRoots',
|
call: 'debug_intermediateRoots',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue