mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core: doesn't process head block in reorg function
This commit is contained in:
parent
03df23355e
commit
d348ed2976
2 changed files with 87 additions and 88 deletions
|
|
@ -1164,14 +1164,13 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []
|
|||
localTd = bc.GetTd(current.Hash(), current.NumberU64())
|
||||
externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1) // The first block can't be nil
|
||||
)
|
||||
externTd = new(big.Int).Add(externTd, block.Difficulty())
|
||||
for block != nil && err == ErrKnownBlock && localTd.Cmp(externTd) >= 0 {
|
||||
for block != nil && err == ErrKnownBlock {
|
||||
externTd = new(big.Int).Add(externTd, block.Difficulty())
|
||||
if localTd.Cmp(externTd) < 0 {
|
||||
break
|
||||
}
|
||||
stats.ignored++
|
||||
block, err = it.next()
|
||||
|
||||
if block != nil {
|
||||
externTd = new(big.Int).Add(externTd, block.Difficulty())
|
||||
}
|
||||
}
|
||||
// The remaining blocks are still known blocks, the only scenario here is:
|
||||
// During the fast sync, the pivot point is already submitted but rollback
|
||||
|
|
@ -1181,15 +1180,13 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []
|
|||
// When node runs a fast sync again, it can re-import a batch of known blocks via
|
||||
// `insertChain` while a part of them have higher total difficulty than current
|
||||
// head full block(new pivot point).
|
||||
if err == ErrKnownBlock {
|
||||
for block != nil && err == ErrKnownBlock {
|
||||
if err := bc.writeKnownBlock(block); err != nil {
|
||||
return it.index, nil, nil, err
|
||||
}
|
||||
lastCanon = block
|
||||
|
||||
block, err = it.next()
|
||||
for block != nil && err == ErrKnownBlock {
|
||||
if err := bc.writeKnownBlock(block); err != nil {
|
||||
return it.index, nil, nil, err
|
||||
}
|
||||
lastCanon = block
|
||||
|
||||
block, err = it.next()
|
||||
}
|
||||
// Falls through to the block import
|
||||
}
|
||||
|
|
@ -1571,15 +1568,15 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
|
|||
} else {
|
||||
log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash())
|
||||
}
|
||||
// Insert the new chain, taking care of the proper incremental order
|
||||
for i := len(newChain) - 1; i >= 0; i-- {
|
||||
// Insert the new chain(except the head block(reverse order)),
|
||||
// taking care of the proper incremental order.
|
||||
for i := len(newChain) - 1; i >= 1; i-- {
|
||||
// Insert the block in the canonical way, re-writing history
|
||||
bc.insert(newChain[i])
|
||||
|
||||
// Collect reborn logs due to chain reorg (except head block (reverse order))
|
||||
if i != 0 {
|
||||
collectLogs(newChain[i].Hash(), false)
|
||||
}
|
||||
// Collect reborn logs due to chain reorg
|
||||
collectLogs(newChain[i].Hash(), false)
|
||||
|
||||
// Write lookup entries for hash based transaction/receipt searches
|
||||
rawdb.WriteTxLookupEntries(bc.db, newChain[i])
|
||||
addedTxs = append(addedTxs, newChain[i].Transactions()...)
|
||||
|
|
|
|||
|
|
@ -1819,76 +1819,17 @@ func testInsertKnownChainData(t *testing.T, typ string) {
|
|||
// The head shouldn't change.
|
||||
asserter(t, blocks3[len(blocks3)-1])
|
||||
|
||||
// Rollback the heavier chain and re-insert the longer chain again
|
||||
for i := 0; i < len(blocks3); i++ {
|
||||
rollback = append(rollback, blocks3[i].Hash())
|
||||
}
|
||||
chain.Rollback(rollback)
|
||||
|
||||
if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
|
||||
t.Fatalf("failed to insert chain data: %v", err)
|
||||
}
|
||||
asserter(t, blocks2[len(blocks2)-1])
|
||||
}
|
||||
|
||||
// Benchmarks large blocks with value transfers to non-existing accounts
|
||||
func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
|
||||
var (
|
||||
signer = types.HomesteadSigner{}
|
||||
testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
|
||||
bankFunds = big.NewInt(100000000000000000)
|
||||
gspec = Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: GenesisAlloc{
|
||||
testBankAddress: {Balance: bankFunds},
|
||||
common.HexToAddress("0xc0de"): {
|
||||
Code: []byte{0x60, 0x01, 0x50},
|
||||
Balance: big.NewInt(0),
|
||||
}, // push 1, pop
|
||||
},
|
||||
GasLimit: 100e6, // 100 M
|
||||
if typ != "headers" {
|
||||
// Rollback the heavier chain and re-insert the longer chain again
|
||||
for i := 0; i < len(blocks3); i++ {
|
||||
rollback = append(rollback, blocks3[i].Hash())
|
||||
}
|
||||
)
|
||||
// Generate the original common chain segment and the two competing forks
|
||||
engine := ethash.NewFaker()
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
genesis := gspec.MustCommit(db)
|
||||
|
||||
blockGenerator := func(i int, block *BlockGen) {
|
||||
block.SetCoinbase(common.Address{1})
|
||||
for txi := 0; txi < numTxs; txi++ {
|
||||
uniq := uint64(i*numTxs + txi)
|
||||
recipient := recipientFn(uniq)
|
||||
tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
block.AddTx(tx)
|
||||
}
|
||||
}
|
||||
|
||||
shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
|
||||
b.StopTimer()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
// Import the shared chain and the original canonical one
|
||||
diskdb := rawdb.NewMemoryDatabase()
|
||||
gspec.MustCommit(diskdb)
|
||||
|
||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create tester chain: %v", err)
|
||||
}
|
||||
b.StartTimer()
|
||||
if _, err := chain.InsertChain(shared); err != nil {
|
||||
b.Fatalf("failed to insert shared chain: %v", err)
|
||||
}
|
||||
b.StopTimer()
|
||||
if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
|
||||
b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
|
||||
chain.Rollback(rollback)
|
||||
|
||||
if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
|
||||
t.Fatalf("failed to insert chain data: %v", err)
|
||||
}
|
||||
asserter(t, blocks2[len(blocks2)-1])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2012,6 +1953,67 @@ func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Benchmarks large blocks with value transfers to non-existing accounts
|
||||
func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
|
||||
var (
|
||||
signer = types.HomesteadSigner{}
|
||||
testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
|
||||
bankFunds = big.NewInt(100000000000000000)
|
||||
gspec = Genesis{
|
||||
Config: params.TestChainConfig,
|
||||
Alloc: GenesisAlloc{
|
||||
testBankAddress: {Balance: bankFunds},
|
||||
common.HexToAddress("0xc0de"): {
|
||||
Code: []byte{0x60, 0x01, 0x50},
|
||||
Balance: big.NewInt(0),
|
||||
}, // push 1, pop
|
||||
},
|
||||
GasLimit: 100e6, // 100 M
|
||||
}
|
||||
)
|
||||
// Generate the original common chain segment and the two competing forks
|
||||
engine := ethash.NewFaker()
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
genesis := gspec.MustCommit(db)
|
||||
|
||||
blockGenerator := func(i int, block *BlockGen) {
|
||||
block.SetCoinbase(common.Address{1})
|
||||
for txi := 0; txi < numTxs; txi++ {
|
||||
uniq := uint64(i*numTxs + txi)
|
||||
recipient := recipientFn(uniq)
|
||||
tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
block.AddTx(tx)
|
||||
}
|
||||
}
|
||||
|
||||
shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
|
||||
b.StopTimer()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
// Import the shared chain and the original canonical one
|
||||
diskdb := rawdb.NewMemoryDatabase()
|
||||
gspec.MustCommit(diskdb)
|
||||
|
||||
chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to create tester chain: %v", err)
|
||||
}
|
||||
b.StartTimer()
|
||||
if _, err := chain.InsertChain(shared); err != nil {
|
||||
b.Fatalf("failed to insert shared chain: %v", err)
|
||||
}
|
||||
b.StopTimer()
|
||||
if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
|
||||
b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
|
||||
var (
|
||||
numTxs = 1000
|
||||
|
|
@ -2062,4 +2064,4 @@ func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
|
|||
}
|
||||
|
||||
benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue