mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core, light: address comments
This commit is contained in:
parent
3c57935687
commit
51390a57ba
3 changed files with 47 additions and 50 deletions
|
|
@ -538,21 +538,21 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
|
||||||
|
|
||||||
// Prepare the genesis block and reinitialise the chain
|
// Prepare the genesis block and reinitialise the chain
|
||||||
batch := bc.db.NewBatch()
|
batch := bc.db.NewBatch()
|
||||||
bc.hc.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty())
|
rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty())
|
||||||
rawdb.WriteBlock(batch, genesis)
|
rawdb.WriteBlock(batch, genesis)
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
log.Crit("Failed to write genesis block", "err", err)
|
log.Crit("Failed to write genesis block", "err", err)
|
||||||
}
|
}
|
||||||
bc.genesisBlock = genesis
|
bc.writeHeadBlock(genesis)
|
||||||
bc.writeHeadBlock(bc.genesisBlock)
|
|
||||||
|
|
||||||
|
// Last update all in-memory chain markers
|
||||||
|
bc.genesisBlock = genesis
|
||||||
bc.currentBlock.Store(bc.genesisBlock)
|
bc.currentBlock.Store(bc.genesisBlock)
|
||||||
headBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
|
headBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
|
||||||
bc.hc.SetGenesis(bc.genesisBlock.Header())
|
bc.hc.SetGenesis(bc.genesisBlock.Header())
|
||||||
bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
|
bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
|
||||||
bc.currentFastBlock.Store(bc.genesisBlock)
|
bc.currentFastBlock.Store(bc.genesisBlock)
|
||||||
headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
|
headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -621,28 +621,28 @@ func (bc *BlockChain) writeHeadBlock(block *types.Block) {
|
||||||
updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash()
|
updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash()
|
||||||
|
|
||||||
// Add the block to the canonical chain number scheme and mark as the head
|
// Add the block to the canonical chain number scheme and mark as the head
|
||||||
// First write all header chain relative indexes
|
|
||||||
batch := bc.db.NewBatch()
|
batch := bc.db.NewBatch()
|
||||||
rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64())
|
rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64())
|
||||||
if updateHeads {
|
|
||||||
bc.hc.WriteHeadHeader(batch, block.Header())
|
|
||||||
}
|
|
||||||
// Then write all block chain relative indexes
|
|
||||||
rawdb.WriteTxLookupEntries(batch, block)
|
rawdb.WriteTxLookupEntries(batch, block)
|
||||||
rawdb.WriteHeadBlockHash(batch, block.Hash())
|
rawdb.WriteHeadBlockHash(batch, block.Hash())
|
||||||
|
|
||||||
bc.currentBlock.Store(block)
|
|
||||||
headBlockGauge.Update(int64(block.NumberU64()))
|
|
||||||
|
|
||||||
// If the block is better than our head or is on a different chain, force update heads
|
// If the block is better than our head or is on a different chain, force update heads
|
||||||
if updateHeads {
|
if updateHeads {
|
||||||
|
rawdb.WriteHeadHeaderHash(batch, block.Hash())
|
||||||
rawdb.WriteHeadFastBlockHash(batch, block.Hash())
|
rawdb.WriteHeadFastBlockHash(batch, block.Hash())
|
||||||
bc.currentFastBlock.Store(block)
|
|
||||||
headFastBlockGauge.Update(int64(block.NumberU64()))
|
|
||||||
}
|
}
|
||||||
|
// Flush the whole batch into the disk, exit the node if failed
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
log.Crit("Failed to update chain indexes and markers", "err", err)
|
log.Crit("Failed to update chain indexes and markers", "err", err)
|
||||||
}
|
}
|
||||||
|
// Update all in-memory chain markers in the last step
|
||||||
|
if updateHeads {
|
||||||
|
bc.hc.SetCurrentHeader(block.Header())
|
||||||
|
bc.currentFastBlock.Store(block)
|
||||||
|
headFastBlockGauge.Update(int64(block.NumberU64()))
|
||||||
|
}
|
||||||
|
bc.currentBlock.Store(block)
|
||||||
|
headBlockGauge.Update(int64(block.NumberU64()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Genesis retrieves the chain's genesis block.
|
// Genesis retrieves the chain's genesis block.
|
||||||
|
|
@ -892,9 +892,15 @@ func (bc *BlockChain) Rollback(chain []common.Hash) {
|
||||||
for i := len(chain) - 1; i >= 0; i-- {
|
for i := len(chain) - 1; i >= 0; i-- {
|
||||||
hash := chain[i]
|
hash := chain[i]
|
||||||
|
|
||||||
|
// Degrade the chain markers if they are explictly reverted.
|
||||||
|
// In thoery we should update all in-memory markers in the
|
||||||
|
// last step, however the direction of rollback is from high
|
||||||
|
// to low, so it's safe the update in-memory markers directly.
|
||||||
currentHeader := bc.hc.CurrentHeader()
|
currentHeader := bc.hc.CurrentHeader()
|
||||||
if currentHeader.Hash() == hash {
|
if currentHeader.Hash() == hash {
|
||||||
bc.hc.WriteHeadHeader(batch, bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1))
|
newHeadHeader := bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1)
|
||||||
|
rawdb.WriteHeadHeaderHash(batch, currentHeader.ParentHash)
|
||||||
|
bc.hc.SetCurrentHeader(newHeadHeader)
|
||||||
}
|
}
|
||||||
if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash {
|
if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash {
|
||||||
newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1)
|
newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1)
|
||||||
|
|
@ -1240,15 +1246,15 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
|
||||||
|
|
||||||
var lastWrite uint64
|
var lastWrite uint64
|
||||||
|
|
||||||
// writeSideBlock writes only the block and its metadata to the database,
|
// writeBlockWithState writes only the block and its metadata to the database,
|
||||||
// but does not write any state. This is used to construct competing side forks
|
// but does not write any state. This is used to construct competing side forks
|
||||||
// up to the point where they exceed the canonical total difficulty.
|
// up to the point where they exceed the canonical total difficulty.
|
||||||
func (bc *BlockChain) writeSideBlock(block *types.Block, td *big.Int) (err error) {
|
func (bc *BlockChain) writeBlockWithoutState(block *types.Block, td *big.Int) (err error) {
|
||||||
bc.wg.Add(1)
|
bc.wg.Add(1)
|
||||||
defer bc.wg.Done()
|
defer bc.wg.Done()
|
||||||
|
|
||||||
batch := bc.db.NewBatch()
|
batch := bc.db.NewBatch()
|
||||||
bc.hc.WriteTd(batch, block.Hash(), block.NumberU64(), td)
|
rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), td)
|
||||||
rawdb.WriteBlock(batch, block)
|
rawdb.WriteBlock(batch, block)
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
log.Crit("Failed to write block into disk", "err", err)
|
log.Crit("Failed to write block into disk", "err", err)
|
||||||
|
|
@ -1301,11 +1307,10 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||||
// Note all the components of block(td, hash->number map, header, body, receipts)
|
// Note all the components of block(td, hash->number map, header, body, receipts)
|
||||||
// should be written atomically. BlockBatch is used for containing all components.
|
// should be written atomically. BlockBatch is used for containing all components.
|
||||||
blockBatch := bc.db.NewBatch()
|
blockBatch := bc.db.NewBatch()
|
||||||
if err := bc.hc.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd); err != nil {
|
rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd)
|
||||||
return NonStatTy, err
|
|
||||||
}
|
|
||||||
rawdb.WriteBlock(blockBatch, block)
|
rawdb.WriteBlock(blockBatch, block)
|
||||||
rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
|
rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
|
||||||
|
rawdb.WritePreimages(blockBatch, state.Preimages())
|
||||||
if err := blockBatch.Write(); err != nil {
|
if err := blockBatch.Write(); err != nil {
|
||||||
log.Crit("Failed to write block into disk", "err", err)
|
log.Crit("Failed to write block into disk", "err", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1393,10 +1398,6 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||||
return NonStatTy, err
|
return NonStatTy, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Preimages is a specical helper data, we don't need to
|
|
||||||
// consider the atomicity.
|
|
||||||
rawdb.WritePreimages(bc.db, state.Preimages())
|
|
||||||
|
|
||||||
status = CanonStatTy
|
status = CanonStatTy
|
||||||
} else {
|
} else {
|
||||||
status = SideStatTy
|
status = SideStatTy
|
||||||
|
|
@ -1801,7 +1802,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i
|
||||||
|
|
||||||
if !bc.HasBlock(block.Hash(), block.NumberU64()) {
|
if !bc.HasBlock(block.Hash(), block.NumberU64()) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if err := bc.writeSideBlock(block, externTd); err != nil {
|
if err := bc.writeBlockWithoutState(block, externTd); err != nil {
|
||||||
return it.index, nil, nil, err
|
return it.index, nil, nil, err
|
||||||
}
|
}
|
||||||
log.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(),
|
log.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(),
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
|
||||||
// Note all the components of header(td, hash->number index and header) should
|
// Note all the components of header(td, hash->number index and header) should
|
||||||
// be written atomically.
|
// be written atomically.
|
||||||
headerBatch := hc.chainDb.NewBatch()
|
headerBatch := hc.chainDb.NewBatch()
|
||||||
hc.WriteTd(headerBatch, hash, number, externTd)
|
rawdb.WriteTd(headerBatch, hash, number, externTd)
|
||||||
rawdb.WriteHeader(headerBatch, header)
|
rawdb.WriteHeader(headerBatch, header)
|
||||||
if err := headerBatch.Write(); err != nil {
|
if err := headerBatch.Write(); err != nil {
|
||||||
log.Crit("Failed to write header into disk", "err", err)
|
log.Crit("Failed to write header into disk", "err", err)
|
||||||
|
|
@ -200,6 +200,7 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
|
||||||
if err := markerBatch.Write(); err != nil {
|
if err := markerBatch.Write(); err != nil {
|
||||||
log.Crit("Failed to write header markers into disk", "err", err)
|
log.Crit("Failed to write header markers into disk", "err", err)
|
||||||
}
|
}
|
||||||
|
// Last step update all in-memory head header markers
|
||||||
hc.currentHeaderHash = hash
|
hc.currentHeaderHash = hash
|
||||||
hc.currentHeader.Store(types.CopyHeader(header))
|
hc.currentHeader.Store(types.CopyHeader(header))
|
||||||
headHeaderGauge.Update(header.Number.Int64())
|
headHeaderGauge.Update(header.Number.Int64())
|
||||||
|
|
@ -208,6 +209,7 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
|
||||||
} else {
|
} else {
|
||||||
status = SideStatTy
|
status = SideStatTy
|
||||||
}
|
}
|
||||||
|
hc.tdCache.Add(hash, externTd)
|
||||||
hc.headerCache.Add(hash, header)
|
hc.headerCache.Add(hash, header)
|
||||||
hc.numberCache.Add(hash, number)
|
hc.numberCache.Add(hash, number)
|
||||||
return
|
return
|
||||||
|
|
@ -411,14 +413,6 @@ func (hc *HeaderChain) GetTdByHash(hash common.Hash) *big.Int {
|
||||||
return hc.GetTd(hash, *number)
|
return hc.GetTd(hash, *number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteTd stores a block's total difficulty into the database, also caching it
|
|
||||||
// along the way.
|
|
||||||
func (hc *HeaderChain) WriteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64, td *big.Int) error {
|
|
||||||
rawdb.WriteTd(db, hash, number, td)
|
|
||||||
hc.tdCache.Add(hash, new(big.Int).Set(td))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHeader retrieves a block header from the database by hash and number,
|
// GetHeader retrieves a block header from the database by hash and number,
|
||||||
// caching it if found.
|
// caching it if found.
|
||||||
func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header {
|
func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header {
|
||||||
|
|
@ -475,20 +469,14 @@ func (hc *HeaderChain) CurrentHeader() *types.Header {
|
||||||
return hc.currentHeader.Load().(*types.Header)
|
return hc.currentHeader.Load().(*types.Header)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCurrentHeader sets the current head header of the canonical chain.
|
// SetCurrentHeader sets the in-memory head header marker of the canonical chan
|
||||||
|
// as the given header.
|
||||||
func (hc *HeaderChain) SetCurrentHeader(head *types.Header) {
|
func (hc *HeaderChain) SetCurrentHeader(head *types.Header) {
|
||||||
hc.currentHeader.Store(head)
|
hc.currentHeader.Store(head)
|
||||||
hc.currentHeaderHash = head.Hash()
|
hc.currentHeaderHash = head.Hash()
|
||||||
headHeaderGauge.Update(head.Number.Int64())
|
headHeaderGauge.Update(head.Number.Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeadHeader sets the current head header of the canonical chain
|
|
||||||
// and write the marker into database.
|
|
||||||
func (hc *HeaderChain) WriteHeadHeader(db ethdb.KeyValueWriter, head *types.Header) {
|
|
||||||
rawdb.WriteHeadHeaderHash(db, head.Hash())
|
|
||||||
hc.SetCurrentHeader(head)
|
|
||||||
}
|
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// UpdateHeadBlocksCallback is a callback function that is called by SetHead
|
// UpdateHeadBlocksCallback is a callback function that is called by SetHead
|
||||||
// before head header is updated.
|
// before head header is updated.
|
||||||
|
|
|
||||||
|
|
@ -200,14 +200,12 @@ func (lc *LightChain) ResetWithGenesisBlock(genesis *types.Block) {
|
||||||
batch := lc.chainDb.NewBatch()
|
batch := lc.chainDb.NewBatch()
|
||||||
rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty())
|
rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty())
|
||||||
rawdb.WriteBlock(batch, genesis)
|
rawdb.WriteBlock(batch, genesis)
|
||||||
|
rawdb.WriteHeadHeaderHash(batch, genesis.Hash())
|
||||||
lc.genesisBlock = genesis
|
|
||||||
lc.hc.SetGenesis(lc.genesisBlock.Header())
|
|
||||||
lc.hc.WriteHeadHeader(batch, lc.genesisBlock.Header())
|
|
||||||
|
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
log.Crit("Failed to reset genesis block", "err", err)
|
log.Crit("Failed to reset genesis block", "err", err)
|
||||||
}
|
}
|
||||||
|
lc.genesisBlock = genesis
|
||||||
|
lc.hc.SetGenesis(lc.genesisBlock.Header())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
|
|
@ -327,13 +325,22 @@ func (lc *LightChain) Rollback(chain []common.Hash) {
|
||||||
lc.chainmu.Lock()
|
lc.chainmu.Lock()
|
||||||
defer lc.chainmu.Unlock()
|
defer lc.chainmu.Unlock()
|
||||||
|
|
||||||
|
batch := lc.chainDb.NewBatch()
|
||||||
for i := len(chain) - 1; i >= 0; i-- {
|
for i := len(chain) - 1; i >= 0; i-- {
|
||||||
hash := chain[i]
|
hash := chain[i]
|
||||||
|
|
||||||
|
// Degrade the chain markers if they are explictly reverted.
|
||||||
|
// In thoery we should update all in-memory markers in the
|
||||||
|
// last step, however the direction of rollback is from high
|
||||||
|
// to low, so it's safe the update in-memory markers directly.
|
||||||
if head := lc.hc.CurrentHeader(); head.Hash() == hash {
|
if head := lc.hc.CurrentHeader(); head.Hash() == hash {
|
||||||
lc.hc.WriteHeadHeader(lc.chainDb, lc.GetHeader(head.ParentHash, head.Number.Uint64()-1))
|
rawdb.WriteHeadHeaderHash(batch, head.ParentHash)
|
||||||
|
lc.hc.SetCurrentHeader(lc.GetHeader(head.ParentHash, head.Number.Uint64()-1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := batch.Write(); err != nil {
|
||||||
|
log.Crit("Failed to rollback light chain", "error", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// postChainEvents iterates over the events generated by a chain insertion and
|
// postChainEvents iterates over the events generated by a chain insertion and
|
||||||
|
|
@ -497,7 +504,8 @@ func (lc *LightChain) SyncCheckpoint(ctx context.Context, checkpoint *params.Tru
|
||||||
// Ensure the chain didn't move past the latest block while retrieving it
|
// Ensure the chain didn't move past the latest block while retrieving it
|
||||||
if lc.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() {
|
if lc.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() {
|
||||||
log.Info("Updated latest header based on CHT", "number", header.Number, "hash", header.Hash(), "age", common.PrettyAge(time.Unix(int64(header.Time), 0)))
|
log.Info("Updated latest header based on CHT", "number", header.Number, "hash", header.Hash(), "age", common.PrettyAge(time.Unix(int64(header.Time), 0)))
|
||||||
lc.hc.WriteHeadHeader(lc.chainDb, header)
|
rawdb.WriteHeadHeaderHash(lc.chainDb, header.Hash())
|
||||||
|
lc.hc.SetCurrentHeader(header)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue