mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
core: restore test
This commit is contained in:
parent
9aa4df467c
commit
93bb4057fb
1 changed files with 133 additions and 111 deletions
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/beacon"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core/history"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
|
@ -4256,115 +4257,136 @@ func testChainReorgSnapSync(t *testing.T, ancientLimit uint64) {
|
|||
// chain cutoff point. In this case the chain segment before the cutoff should
|
||||
// be persisted without the receipts and bodies; chain after should be persisted
|
||||
// normally.
|
||||
// func TestInsertChainWithCutoff(t *testing.T) {
|
||||
// testInsertChainWithCutoff(t, 32, 32) // cutoff = 32, ancientLimit = 32
|
||||
// testInsertChainWithCutoff(t, 32, 64) // cutoff = 32, ancientLimit = 64 (entire chain in ancient)
|
||||
// testInsertChainWithCutoff(t, 32, 65) // cutoff = 32, ancientLimit = 65 (64 blocks in ancient, 1 block in live)
|
||||
// }
|
||||
func TestInsertChainWithCutoff(t *testing.T) {
|
||||
const chainLength = 64
|
||||
|
||||
// func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64) {
|
||||
// // log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true)))
|
||||
//
|
||||
// // Configure and generate a sample block chain
|
||||
// var (
|
||||
// key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
// address = crypto.PubkeyToAddress(key.PublicKey)
|
||||
// funds = big.NewInt(1000000000000000)
|
||||
// gspec = &Genesis{
|
||||
// Config: params.TestChainConfig,
|
||||
// Alloc: types.GenesisAlloc{address: {Balance: funds}},
|
||||
// BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
// }
|
||||
// signer = types.LatestSigner(gspec.Config)
|
||||
// engine = beacon.New(ethash.NewFaker())
|
||||
// )
|
||||
// _, blocks, receipts := GenerateChainWithGenesis(gspec, engine, int(2*cutoff), func(i int, block *BlockGen) {
|
||||
// block.SetCoinbase(common.Address{0x00})
|
||||
//
|
||||
// tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// block.AddTx(tx)
|
||||
// })
|
||||
// db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
|
||||
// defer db.Close()
|
||||
//
|
||||
// cutoffBlock := blocks[cutoff-1]
|
||||
// config := DefaultCacheConfigWithScheme(rawdb.PathScheme)
|
||||
// config.HistoryPruningCutoffNumber = cutoffBlock.NumberU64()
|
||||
// config.HistoryPruningCutoffHash = cutoffBlock.Hash()
|
||||
//
|
||||
// chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil)
|
||||
// defer chain.Stop()
|
||||
//
|
||||
// var (
|
||||
// headersBefore []*types.Header
|
||||
// blocksAfter []*types.Block
|
||||
// receiptsAfter []types.Receipts
|
||||
// )
|
||||
// for i, b := range blocks {
|
||||
// if b.NumberU64() < cutoffBlock.NumberU64() {
|
||||
// headersBefore = append(headersBefore, b.Header())
|
||||
// } else {
|
||||
// blocksAfter = append(blocksAfter, b)
|
||||
// receiptsAfter = append(receiptsAfter, receipts[i])
|
||||
// }
|
||||
// }
|
||||
// if n, err := chain.InsertHeadersBeforeCutoff(headersBefore); err != nil {
|
||||
// t.Fatalf("failed to insert headers before cutoff %d: %v", n, err)
|
||||
// }
|
||||
// if n, err := chain.InsertReceiptChain(blocksAfter, receiptsAfter, ancientLimit); err != nil {
|
||||
// t.Fatalf("failed to insert receipt %d: %v", n, err)
|
||||
// }
|
||||
// headSnap := chain.CurrentSnapBlock()
|
||||
// if headSnap.Hash() != blocks[len(blocks)-1].Hash() {
|
||||
// t.Errorf("head snap block #%d: header mismatch: want: %v, got: %v", headSnap.Number, blocks[len(blocks)-1].Hash(), headSnap.Hash())
|
||||
// }
|
||||
// headHeader := chain.CurrentHeader()
|
||||
// if headHeader.Hash() != blocks[len(blocks)-1].Hash() {
|
||||
// t.Errorf("head header #%d: header mismatch: want: %v, got: %v", headHeader.Number, blocks[len(blocks)-1].Hash(), headHeader.Hash())
|
||||
// }
|
||||
// headBlock := chain.CurrentBlock()
|
||||
// if headBlock.Hash() != gspec.ToBlock().Hash() {
|
||||
// t.Errorf("head block #%d: header mismatch: want: %v, got: %v", headBlock.Number, gspec.ToBlock().Hash(), headBlock.Hash())
|
||||
// }
|
||||
//
|
||||
// // Iterate over all chain data components, and cross reference
|
||||
// for i := 0; i < len(blocks); i++ {
|
||||
// num, hash := blocks[i].NumberU64(), blocks[i].Hash()
|
||||
//
|
||||
// // Canonical headers should be visible regardless of cutoff
|
||||
// header := chain.GetHeaderByNumber(num)
|
||||
// if header.Hash() != hash {
|
||||
// t.Errorf("block #%d: header mismatch: want: %v, got: %v", num, hash, header.Hash())
|
||||
// }
|
||||
// tail, err := db.Tail()
|
||||
// if err != nil {
|
||||
// t.Fatalf("Failed to get chain tail, %v", err)
|
||||
// }
|
||||
// if tail != cutoffBlock.NumberU64() {
|
||||
// t.Fatalf("Unexpected chain tail, want: %d, got: %d", cutoffBlock.NumberU64(), tail)
|
||||
// }
|
||||
// // Block bodies and receipts before the cutoff should be non-existent
|
||||
// if num < cutoffBlock.NumberU64() {
|
||||
// body := chain.GetBody(hash)
|
||||
// if body != nil {
|
||||
// t.Fatalf("Unexpected block body: %d, cutoff: %d", num, cutoffBlock.NumberU64())
|
||||
// }
|
||||
// receipts := chain.GetReceiptsByHash(hash)
|
||||
// if receipts != nil {
|
||||
// t.Fatalf("Unexpected block receipts: %d, cutoff: %d", num, cutoffBlock.NumberU64())
|
||||
// }
|
||||
// } else {
|
||||
// body := chain.GetBody(hash)
|
||||
// if body == nil || len(body.Transactions) != 1 {
|
||||
// t.Fatalf("Missed block body: %d, cutoff: %d", num, cutoffBlock.NumberU64())
|
||||
// }
|
||||
// receipts := chain.GetReceiptsByHash(hash)
|
||||
// if receipts == nil || len(receipts) != 1 {
|
||||
// t.Fatalf("Missed block receipts: %d, cutoff: %d", num, cutoffBlock.NumberU64())
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Configure and generate a sample block chain
|
||||
var (
|
||||
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||
funds = big.NewInt(1000000000000000)
|
||||
gspec = &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{address: {Balance: funds}},
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
}
|
||||
signer = types.LatestSigner(gspec.Config)
|
||||
engine = beacon.New(ethash.NewFaker())
|
||||
)
|
||||
_, blocks, receipts := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, block *BlockGen) {
|
||||
block.SetCoinbase(common.Address{0x00})
|
||||
tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
block.AddTx(tx)
|
||||
})
|
||||
|
||||
// Run the actual tests.
|
||||
t.Run("cutoff-32/ancientLimit-32", func(t *testing.T) {
|
||||
// cutoff = 32, ancientLimit = 32
|
||||
testInsertChainWithCutoff(t, 32, 32, gspec, blocks, receipts)
|
||||
})
|
||||
t.Run("cutoff-32/ancientLimit-64", func(t *testing.T) {
|
||||
// cutoff = 32, ancientLimit = 64 (entire chain in ancient)
|
||||
testInsertChainWithCutoff(t, 32, 64, gspec, blocks, receipts)
|
||||
})
|
||||
t.Run("cutoff-32/ancientLimit-64", func(t *testing.T) {
|
||||
// cutoff = 32, ancientLimit = 65 (64 blocks in ancient, 1 block in live)
|
||||
testInsertChainWithCutoff(t, 32, 65, gspec, blocks, receipts)
|
||||
})
|
||||
}
|
||||
|
||||
func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64, genesis *Genesis, blocks []*types.Block, receipts []types.Receipts) {
|
||||
// log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true)))
|
||||
|
||||
// Add a known pruning point for the duration of the test.
|
||||
ghash := genesis.ToBlock().Hash()
|
||||
cutoffBlock := blocks[cutoff-1]
|
||||
history.PrunePoints[ghash] = &history.PrunePoint{
|
||||
BlockNumber: cutoffBlock.NumberU64(),
|
||||
BlockHash: cutoffBlock.Hash(),
|
||||
}
|
||||
defer func() {
|
||||
delete(history.PrunePoints, ghash)
|
||||
}()
|
||||
|
||||
// Enable pruning in cache config.
|
||||
config := DefaultCacheConfigWithScheme(rawdb.PathScheme)
|
||||
config.ChainHistoryMode = history.KeepPostMerge
|
||||
|
||||
db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
|
||||
defer db.Close()
|
||||
chain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(rawdb.PathScheme), genesis, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil)
|
||||
defer chain.Stop()
|
||||
|
||||
var (
|
||||
headersBefore []*types.Header
|
||||
blocksAfter []*types.Block
|
||||
receiptsAfter []types.Receipts
|
||||
)
|
||||
for i, b := range blocks {
|
||||
if b.NumberU64() < cutoffBlock.NumberU64() {
|
||||
headersBefore = append(headersBefore, b.Header())
|
||||
} else {
|
||||
blocksAfter = append(blocksAfter, b)
|
||||
receiptsAfter = append(receiptsAfter, receipts[i])
|
||||
}
|
||||
}
|
||||
if n, err := chain.InsertHeadersBeforeCutoff(headersBefore); err != nil {
|
||||
t.Fatalf("failed to insert headers before cutoff %d: %v", n, err)
|
||||
}
|
||||
if n, err := chain.InsertReceiptChain(blocksAfter, receiptsAfter, ancientLimit); err != nil {
|
||||
t.Fatalf("failed to insert receipt %d: %v", n, err)
|
||||
}
|
||||
headSnap := chain.CurrentSnapBlock()
|
||||
if headSnap.Hash() != blocks[len(blocks)-1].Hash() {
|
||||
t.Errorf("head snap block #%d: header mismatch: want: %v, got: %v", headSnap.Number, blocks[len(blocks)-1].Hash(), headSnap.Hash())
|
||||
}
|
||||
headHeader := chain.CurrentHeader()
|
||||
if headHeader.Hash() != blocks[len(blocks)-1].Hash() {
|
||||
t.Errorf("head header #%d: header mismatch: want: %v, got: %v", headHeader.Number, blocks[len(blocks)-1].Hash(), headHeader.Hash())
|
||||
}
|
||||
headBlock := chain.CurrentBlock()
|
||||
if headBlock.Hash() != ghash {
|
||||
t.Errorf("head block #%d: header mismatch: want: %v, got: %v", headBlock.Number, ghash, headBlock.Hash())
|
||||
}
|
||||
|
||||
// Iterate over all chain data components, and cross reference
|
||||
for i := 0; i < len(blocks); i++ {
|
||||
num, hash := blocks[i].NumberU64(), blocks[i].Hash()
|
||||
|
||||
// Canonical headers should be visible regardless of cutoff
|
||||
header := chain.GetHeaderByNumber(num)
|
||||
if header.Hash() != hash {
|
||||
t.Errorf("block #%d: header mismatch: want: %v, got: %v", num, hash, header.Hash())
|
||||
}
|
||||
tail, err := db.Tail()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get chain tail, %v", err)
|
||||
}
|
||||
if tail != cutoffBlock.NumberU64() {
|
||||
t.Fatalf("Unexpected chain tail, want: %d, got: %d", cutoffBlock.NumberU64(), tail)
|
||||
}
|
||||
// Block bodies and receipts before the cutoff should be non-existent
|
||||
if num < cutoffBlock.NumberU64() {
|
||||
body := chain.GetBody(hash)
|
||||
if body != nil {
|
||||
t.Fatalf("Unexpected block body: %d, cutoff: %d", num, cutoffBlock.NumberU64())
|
||||
}
|
||||
receipts := chain.GetReceiptsByHash(hash)
|
||||
if receipts != nil {
|
||||
t.Fatalf("Unexpected block receipts: %d, cutoff: %d", num, cutoffBlock.NumberU64())
|
||||
}
|
||||
} else {
|
||||
body := chain.GetBody(hash)
|
||||
if body == nil || len(body.Transactions) != 1 {
|
||||
t.Fatalf("Missed block body: %d, cutoff: %d", num, cutoffBlock.NumberU64())
|
||||
}
|
||||
receipts := chain.GetReceiptsByHash(hash)
|
||||
if receipts == nil || len(receipts) != 1 {
|
||||
t.Fatalf("Missed block receipts: %d, cutoff: %d", num, cutoffBlock.NumberU64())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue