mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
core: try to reduce peak memory usage during reorg
This commit is contained in:
parent
368e16f39d
commit
56011b6d87
2 changed files with 42 additions and 5 deletions
|
|
@ -2186,7 +2186,7 @@ func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log {
|
|||
func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
||||
var (
|
||||
newChain types.Blocks
|
||||
oldChain types.Blocks
|
||||
oldChain []*types.Header
|
||||
commonBlock *types.Block
|
||||
|
||||
deletedTxs []common.Hash
|
||||
|
|
@ -2202,7 +2202,7 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
|||
if oldBlock.NumberU64() > newBlock.NumberU64() {
|
||||
// Old chain is longer, gather all transactions and logs as deleted ones
|
||||
for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) {
|
||||
oldChain = append(oldChain, oldBlock)
|
||||
oldChain = append(oldChain, oldBlock.Header())
|
||||
for _, tx := range oldBlock.Transactions() {
|
||||
deletedTxs = append(deletedTxs, tx.Hash())
|
||||
}
|
||||
|
|
@ -2228,7 +2228,7 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
|||
break
|
||||
}
|
||||
// Remove an old block as well as stash away a new block
|
||||
oldChain = append(oldChain, oldBlock)
|
||||
oldChain = append(oldChain, oldBlock.Header())
|
||||
for _, tx := range oldBlock.Transactions() {
|
||||
deletedTxs = append(deletedTxs, tx.Hash())
|
||||
}
|
||||
|
|
@ -2261,7 +2261,7 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
|||
} else if len(newChain) > 0 {
|
||||
// Special case happens in the post merge stage that current head is
|
||||
// the ancestor of new head while these two blocks are not consecutive
|
||||
log.Info("Extend chain", "add", len(newChain), "number", newChain[0].Number(), "hash", newChain[0].Hash())
|
||||
log.Info("Extend chain", "add", len(newChain), "number", newChain[0].Number, "hash", newChain[0].Hash())
|
||||
blockReorgAddMeter.Mark(int64(len(newChain)))
|
||||
} else {
|
||||
// len(newChain) == 0 && len(oldChain) > 0
|
||||
|
|
@ -2273,6 +2273,10 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
|||
// reads should be blocked until the mutation is complete.
|
||||
bc.txLookupLock.Lock()
|
||||
|
||||
var stats runtime.MemStats
|
||||
runtime.ReadMemStats(&stats)
|
||||
panic(stats.HeapInuse)
|
||||
|
||||
// Insert the new chain segment in incremental order, from the old
|
||||
// to the new. The new chain head (newChain[0]) is not inserted here,
|
||||
// as it will be handled separately outside of this function
|
||||
|
|
@ -2325,8 +2329,9 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
|
|||
// Deleted logs + blocks:
|
||||
var deletedLogs []*types.Log
|
||||
for i := len(oldChain) - 1; i >= 0; i-- {
|
||||
oldBlock = bc.GetBlock(oldChain[i].Hash(), oldChain[i].Number.Uint64())
|
||||
// Collect deleted logs for notification
|
||||
if logs := bc.collectLogs(oldChain[i], true); len(logs) > 0 {
|
||||
if logs := bc.collectLogs(oldBlock, true); len(logs) > 0 {
|
||||
deletedLogs = append(deletedLogs, logs...)
|
||||
}
|
||||
if len(deletedLogs) > 512 {
|
||||
|
|
|
|||
|
|
@ -4231,3 +4231,35 @@ func TestPragueRequests(t *testing.T) {
|
|||
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReorg(b *testing.B) {
|
||||
chainLength := b.N
|
||||
|
||||
dir := b.TempDir()
|
||||
db, err := rawdb.NewLevelDBDatabase(dir, 128, 128, "", false)
|
||||
if err != nil {
|
||||
b.Fatalf("cannot create temporary database: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
gspec := &Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: types.GenesisAlloc{benchRootAddr: {Balance: math.BigPow(2, 254)}},
|
||||
}
|
||||
blockchain, _ := NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil)
|
||||
defer blockchain.Stop()
|
||||
|
||||
// Insert an easy and a difficult chain afterwards
|
||||
easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), db, chainLength, genValueTx(500))
|
||||
diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), db, chainLength, genValueTx(500))
|
||||
|
||||
if _, err := blockchain.InsertChain(easyBlocks); err != nil {
|
||||
b.Fatalf("failed to insert easy chain: %v", err)
|
||||
}
|
||||
b.ResetTimer()
|
||||
if _, err := blockchain.InsertChain(diffBlocks); err != nil {
|
||||
b.Fatalf("failed to insert difficult chain: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkReorg-8 10000 362204 ns/op 271290 B/op 1256 allocs/op 151412736 bytes of heap used
|
||||
// BenchmarkReorg-8 10000 381835 ns/op 276959 B/op 1324 allocs/op 152895488 bytes of heap used
|
||||
|
|
|
|||
Loading…
Reference in a new issue