Skip to content

Commit 0e63a70

Browse files
committed
core: minor code polishes + rebase fixes
1 parent f1b00cf commit 0e63a70

File tree

2 files changed

+54
-41
lines changed

2 files changed

+54
-41
lines changed

core/blockchain.go

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,17 +1391,21 @@ func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (i
13911391
return 0, nil, nil, nil
13921392
}
13931393

1394-
// reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them
1395-
// to be part of the new canonical chain and accumulates potential missing transactions and post an
1396-
// event about them
1394+
// reorg takes two blocks, an old chain and a new chain and will reconstruct the
1395+
// blocks and inserts them to be part of the new canonical chain and accumulates
1396+
// potential missing transactions and post an event about them.
13971397
func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
13981398
var (
13991399
newChain types.Blocks
14001400
oldChain types.Blocks
14011401
commonBlock *types.Block
1402-
deletedTxs types.Transactions
1402+
1403+
deletedTxs types.Transactions
1404+
addedTxs types.Transactions
1405+
14031406
deletedLogs []*types.Log
14041407
rebirthLogs []*types.Log
1408+
14051409
// collectLogs collects the logs that were generated during the
14061410
// processing of the block that corresponds with the given hash.
14071411
// These logs are later announced as deleted or reborn
@@ -1424,46 +1428,49 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
14241428
}
14251429
}
14261430
)
1427-
1428-
// first reduce whoever is higher bound
1431+
// Reduce the longer chain to the same number as the shorter one
14291432
if oldBlock.NumberU64() > newBlock.NumberU64() {
1430-
// reduce old chain
1433+
// Old chain is longer, gather all transactions and logs as deleted ones
14311434
for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) {
14321435
oldChain = append(oldChain, oldBlock)
14331436
deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
1434-
14351437
collectLogs(oldBlock.Hash(), true)
14361438
}
14371439
} else {
1438-
// reduce new chain and append new chain blocks for inserting later on
1440+
// New chain is longer, stash all blocks away for subsequent insertion
14391441
for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) {
14401442
newChain = append(newChain, newBlock)
14411443
}
14421444
}
14431445
if oldBlock == nil {
1444-
return fmt.Errorf("Invalid old chain")
1446+
return fmt.Errorf("invalid old chain")
14451447
}
14461448
if newBlock == nil {
1447-
return fmt.Errorf("Invalid new chain")
1449+
return fmt.Errorf("invalid new chain")
14481450
}
1449-
1451+
// Both sides of the reorg are at the same number, reduce both until the common
1452+
// ancestor is found
14501453
for {
1454+
// If the common ancestor was found, bail out
14511455
if oldBlock.Hash() == newBlock.Hash() {
14521456
commonBlock = oldBlock
14531457
break
14541458
}
1455-
1459+
// Remove an old block as well as stash away a new block
14561460
oldChain = append(oldChain, oldBlock)
1457-
newChain = append(newChain, newBlock)
14581461
deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
14591462
collectLogs(oldBlock.Hash(), true)
14601463

1461-
oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1)
1464+
newChain = append(newChain, newBlock)
1465+
1466+
// Step back with both chains
1467+
oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1)
14621468
if oldBlock == nil {
1463-
return fmt.Errorf("Invalid old chain")
1469+
return fmt.Errorf("invalid old chain")
14641470
}
1471+
newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1)
14651472
if newBlock == nil {
1466-
return fmt.Errorf("Invalid new chain")
1473+
return fmt.Errorf("invalid new chain")
14671474
}
14681475
}
14691476
// Ensure the user sees large reorgs
@@ -1478,42 +1485,46 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
14781485
log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash())
14791486
}
14801487
// Insert the new chain, taking care of the proper incremental order
1481-
var addedTxs types.Transactions
14821488
for i := len(newChain) - 1; i >= 0; i-- {
1483-
// insert the block in the canonical way, re-writing history
1489+
// Insert the block in the canonical way, re-writing history
14841490
bc.insert(newChain[i])
1485-
// collect reborn logs due to chain reorg(except head block)
1491+
1492+
// Collect reborn logs due to chain reorg (except head block (reverse order))
14861493
if i != 0 {
14871494
collectLogs(newChain[i].Hash(), false)
14881495
}
1489-
// write lookup entries for hash based transaction/receipt searches
1496+
// Write lookup entries for hash based transaction/receipt searches
14901497
rawdb.WriteTxLookupEntries(bc.db, newChain[i])
14911498
addedTxs = append(addedTxs, newChain[i].Transactions()...)
14921499
}
1493-
// calculate the difference between deleted and added transactions
1494-
diff := types.TxDifference(deletedTxs, addedTxs)
1495-
// When transactions get deleted from the database that means the
1496-
// receipts that were created in the fork must also be deleted
1500+
// When transactions get deleted from the database, the receipts that were
1501+
// created in the fork must also be deleted
14971502
batch := bc.db.NewBatch()
1498-
for _, tx := range diff {
1503+
for _, tx := range types.TxDifference(deletedTxs, addedTxs) {
14991504
rawdb.DeleteTxLookupEntry(batch, tx.Hash())
15001505
}
15011506
batch.Write()
15021507

1503-
if len(deletedLogs) > 0 {
1504-
go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
1505-
}
1506-
if len(rebirthLogs) > 0 {
1507-
go bc.logsFeed.Send(rebirthLogs)
1508-
}
1509-
if len(oldChain) > 0 {
1510-
go func() {
1508+
// If any logs need to be fired, do it now. In theory we could avoid creating
1509+
// this goroutine if there are no events to fire, but realistcally that only
1510+
// ever happens if we're reorging empty blocks, which will only happen on idle
1511+
// networks where performance is not an issue either way.
1512+
//
1513+
// TODO(karalabe): Can we get rid of the goroutine somehow to guarantee correct
1514+
// event ordering?
1515+
go func() {
1516+
if len(deletedLogs) > 0 {
1517+
bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
1518+
}
1519+
if len(rebirthLogs) > 0 {
1520+
bc.logsFeed.Send(rebirthLogs)
1521+
}
1522+
if len(oldChain) > 0 {
15111523
for _, block := range oldChain {
15121524
bc.chainSideFeed.Send(ChainSideEvent{Block: block})
15131525
}
1514-
}()
1515-
}
1516-
1526+
}
1527+
}()
15171528
return nil
15181529
}
15191530

core/blockchain_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,7 @@ func TestLogRebirth(t *testing.T) {
934934
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
935935
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
936936
db = ethdb.NewMemDatabase()
937+
937938
// this code generates a log
938939
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
939940
gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
@@ -1035,10 +1036,6 @@ func TestLogRebirth(t *testing.T) {
10351036
if _, err := blockchain.InsertChain(newBlocks); err != nil {
10361037
t.Fatalf("failed to insert forked chain: %v", err)
10371038
}
1038-
// Rebirth logs should omit a newLogEvent
1039-
if !<-newLogCh {
1040-
t.Fatalf("failed to receive new log event")
1041-
}
10421039
// Ensure removedLog events received
10431040
select {
10441041
case ev := <-rmLogsCh:
@@ -1048,13 +1045,18 @@ func TestLogRebirth(t *testing.T) {
10481045
case <-time.NewTimer(1 * time.Second).C:
10491046
t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
10501047
}
1048+
// Rebirth logs should omit a newLogEvent
1049+
if !<-newLogCh {
1050+
t.Fatalf("failed to receive new log event")
1051+
}
10511052
}
10521053

10531054
func TestSideLogRebirth(t *testing.T) {
10541055
var (
10551056
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
10561057
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
10571058
db = ethdb.NewMemDatabase()
1059+
10581060
// this code generates a log
10591061
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
10601062
gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}

0 commit comments

Comments
 (0)