diff options
Diffstat (limited to 'core/blockchain.go')
-rw-r--r-- | core/blockchain.go | 473 |
1 files changed, 237 insertions, 236 deletions
diff --git a/core/blockchain.go b/core/blockchain.go index 794e1915f..865077132 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -56,7 +56,7 @@ const ( blockCacheLimit = 256 maxFutureBlocks = 256 maxTimeFutureBlocks = 30 - // must be bumped when consensus algorithm is changed, this forces the upgradedb + // BlockChainVersion must be bumped when consensus algorithm is changed, this forces the upgradedb // command to be run (forces the blocks to be imported again using the new algorithm) BlockChainVersion = 3 badBlockLimit = 10 @@ -168,67 +168,67 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, engine co return bc, nil } -func (self *BlockChain) getProcInterrupt() bool { - return atomic.LoadInt32(&self.procInterrupt) == 1 +func (bc *BlockChain) getProcInterrupt() bool { + return atomic.LoadInt32(&bc.procInterrupt) == 1 } // loadLastState loads the last known chain state from the database. This method // assumes that the chain manager mutex is held. -func (self *BlockChain) loadLastState() error { +func (bc *BlockChain) loadLastState() error { // Restore the last known head block - head := GetHeadBlockHash(self.chainDb) + head := GetHeadBlockHash(bc.chainDb) if head == (common.Hash{}) { // Corrupt or empty database, init from scratch log.Warn("Empty database, resetting chain") - return self.Reset() + return bc.Reset() } // Make sure the entire head block is available - currentBlock := self.GetBlockByHash(head) + currentBlock := bc.GetBlockByHash(head) if currentBlock == nil { // Corrupt or empty database, init from scratch log.Warn("Head block missing, resetting chain", "hash", head) - return self.Reset() + return bc.Reset() } // Make sure the state associated with the block is available - if _, err := state.New(currentBlock.Root(), self.chainDb); err != nil { + if _, err := state.New(currentBlock.Root(), bc.chainDb); err != nil { // Dangling block without a state associated, init from scratch log.Warn("Head state missing, resetting chain", "number", currentBlock.Number(), "hash", currentBlock.Hash()) - return self.Reset() + return bc.Reset() } // Everything seems to be fine, set as the head block - self.currentBlock = currentBlock + bc.currentBlock = currentBlock // Restore the last known head header - currentHeader := self.currentBlock.Header() - if head := GetHeadHeaderHash(self.chainDb); head != (common.Hash{}) { - if header := self.GetHeaderByHash(head); header != nil { + currentHeader := bc.currentBlock.Header() + if head := GetHeadHeaderHash(bc.chainDb); head != (common.Hash{}) { + if header := bc.GetHeaderByHash(head); header != nil { currentHeader = header } } - self.hc.SetCurrentHeader(currentHeader) + bc.hc.SetCurrentHeader(currentHeader) // Restore the last known head fast block - self.currentFastBlock = self.currentBlock - if head := GetHeadFastBlockHash(self.chainDb); head != (common.Hash{}) { - if block := self.GetBlockByHash(head); block != nil { - self.currentFastBlock = block + bc.currentFastBlock = bc.currentBlock + if head := GetHeadFastBlockHash(bc.chainDb); head != (common.Hash{}) { + if block := bc.GetBlockByHash(head); block != nil { + bc.currentFastBlock = block } } // Initialize a statedb cache to ensure singleton account bloom filter generation - statedb, err := state.New(self.currentBlock.Root(), self.chainDb) + statedb, err := state.New(bc.currentBlock.Root(), bc.chainDb) if err != nil { return err } - self.stateCache = statedb + bc.stateCache = statedb // Issue a status log for the user - headerTd := self.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()) - blockTd := self.GetTd(self.currentBlock.Hash(), self.currentBlock.NumberU64()) - fastTd := self.GetTd(self.currentFastBlock.Hash(), self.currentFastBlock.NumberU64()) + headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()) + blockTd := bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()) + fastTd := bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64()) log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd) - log.Info("Loaded most recent local full block", "number", self.currentBlock.Number(), "hash", self.currentBlock.Hash(), "td", blockTd) - log.Info("Loaded most recent local fast block", "number", self.currentFastBlock.Number(), "hash", self.currentFastBlock.Hash(), "td", fastTd) + log.Info("Loaded most recent local full block", "number", bc.currentBlock.Number(), "hash", bc.currentBlock.Hash(), "td", blockTd) + log.Info("Loaded most recent local fast block", "number", bc.currentFastBlock.Number(), "hash", bc.currentFastBlock.Hash(), "td", fastTd) return nil } @@ -288,103 +288,103 @@ func (bc *BlockChain) SetHead(head uint64) error { // FastSyncCommitHead sets the current head block to the one defined by the hash // irrelevant what the chain contents were prior. -func (self *BlockChain) FastSyncCommitHead(hash common.Hash) error { +func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { // Make sure that both the block as well at its state trie exists - block := self.GetBlockByHash(hash) + block := bc.GetBlockByHash(hash) if block == nil { return fmt.Errorf("non existent block [%x…]", hash[:4]) } - if _, err := trie.NewSecure(block.Root(), self.chainDb, 0); err != nil { + if _, err := trie.NewSecure(block.Root(), bc.chainDb, 0); err != nil { return err } // If all checks out, manually set the head block - self.mu.Lock() - self.currentBlock = block - self.mu.Unlock() + bc.mu.Lock() + bc.currentBlock = block + bc.mu.Unlock() log.Info("Committed new head block", "number", block.Number(), "hash", hash) return nil } // GasLimit returns the gas limit of the current HEAD block. -func (self *BlockChain) GasLimit() *big.Int { - self.mu.RLock() - defer self.mu.RUnlock() +func (bc *BlockChain) GasLimit() *big.Int { + bc.mu.RLock() + defer bc.mu.RUnlock() - return self.currentBlock.GasLimit() + return bc.currentBlock.GasLimit() } // LastBlockHash return the hash of the HEAD block. -func (self *BlockChain) LastBlockHash() common.Hash { - self.mu.RLock() - defer self.mu.RUnlock() +func (bc *BlockChain) LastBlockHash() common.Hash { + bc.mu.RLock() + defer bc.mu.RUnlock() - return self.currentBlock.Hash() + return bc.currentBlock.Hash() } // CurrentBlock retrieves the current head block of the canonical chain. The // block is retrieved from the blockchain's internal cache. -func (self *BlockChain) CurrentBlock() *types.Block { - self.mu.RLock() - defer self.mu.RUnlock() +func (bc *BlockChain) CurrentBlock() *types.Block { + bc.mu.RLock() + defer bc.mu.RUnlock() - return self.currentBlock + return bc.currentBlock } // CurrentFastBlock retrieves the current fast-sync head block of the canonical // chain. The block is retrieved from the blockchain's internal cache. -func (self *BlockChain) CurrentFastBlock() *types.Block { - self.mu.RLock() - defer self.mu.RUnlock() +func (bc *BlockChain) CurrentFastBlock() *types.Block { + bc.mu.RLock() + defer bc.mu.RUnlock() - return self.currentFastBlock + return bc.currentFastBlock } // Status returns status information about the current chain such as the HEAD Td, // the HEAD hash and the hash of the genesis block. -func (self *BlockChain) Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash) { - self.mu.RLock() - defer self.mu.RUnlock() +func (bc *BlockChain) Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash) { + bc.mu.RLock() + defer bc.mu.RUnlock() - return self.GetTd(self.currentBlock.Hash(), self.currentBlock.NumberU64()), self.currentBlock.Hash(), self.genesisBlock.Hash() + return bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()), bc.currentBlock.Hash(), bc.genesisBlock.Hash() } // SetProcessor sets the processor required for making state modifications. -func (self *BlockChain) SetProcessor(processor Processor) { - self.procmu.Lock() - defer self.procmu.Unlock() - self.processor = processor +func (bc *BlockChain) SetProcessor(processor Processor) { + bc.procmu.Lock() + defer bc.procmu.Unlock() + bc.processor = processor } // SetValidator sets the validator which is used to validate incoming blocks. -func (self *BlockChain) SetValidator(validator Validator) { - self.procmu.Lock() - defer self.procmu.Unlock() - self.validator = validator +func (bc *BlockChain) SetValidator(validator Validator) { + bc.procmu.Lock() + defer bc.procmu.Unlock() + bc.validator = validator } // Validator returns the current validator. -func (self *BlockChain) Validator() Validator { - self.procmu.RLock() - defer self.procmu.RUnlock() - return self.validator +func (bc *BlockChain) Validator() Validator { + bc.procmu.RLock() + defer bc.procmu.RUnlock() + return bc.validator } // Processor returns the current processor. -func (self *BlockChain) Processor() Processor { - self.procmu.RLock() - defer self.procmu.RUnlock() - return self.processor +func (bc *BlockChain) Processor() Processor { + bc.procmu.RLock() + defer bc.procmu.RUnlock() + return bc.processor } // State returns a new mutable state based on the current HEAD block. -func (self *BlockChain) State() (*state.StateDB, error) { - return self.StateAt(self.CurrentBlock().Root()) +func (bc *BlockChain) State() (*state.StateDB, error) { + return bc.StateAt(bc.CurrentBlock().Root()) } // StateAt returns a new mutable state based on a particular point in time. -func (self *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { - return self.stateCache.New(root) +func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { + return bc.stateCache.New(root) } // Reset purges the entire blockchain, restoring it to its genesis state. @@ -420,14 +420,14 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { } // Export writes the active chain to the given writer. -func (self *BlockChain) Export(w io.Writer) error { - return self.ExportN(w, uint64(0), self.currentBlock.NumberU64()) +func (bc *BlockChain) Export(w io.Writer) error { + return bc.ExportN(w, uint64(0), bc.currentBlock.NumberU64()) } // ExportN writes a subset of the active chain to the given writer. -func (self *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { - self.mu.RLock() - defer self.mu.RUnlock() +func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { + bc.mu.RLock() + defer bc.mu.RUnlock() if first > last { return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) @@ -435,7 +435,7 @@ func (self *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { log.Info("Exporting batch of blocks", "count", last-first+1) for nr := first; nr <= last; nr++ { - block := self.GetBlockByNumber(nr) + block := bc.GetBlockByNumber(nr) if block == nil { return fmt.Errorf("export failed on #%d: not found", nr) } @@ -478,41 +478,41 @@ func (bc *BlockChain) insert(block *types.Block) { } } -// Accessors +// Genesis Accessors func (bc *BlockChain) Genesis() *types.Block { return bc.genesisBlock } // GetBody retrieves a block body (transactions and uncles) from the database by // hash, caching it if found. -func (self *BlockChain) GetBody(hash common.Hash) *types.Body { +func (bc *BlockChain) GetBody(hash common.Hash) *types.Body { // Short circuit if the body's already in the cache, retrieve otherwise - if cached, ok := self.bodyCache.Get(hash); ok { + if cached, ok := bc.bodyCache.Get(hash); ok { body := cached.(*types.Body) return body } - body := GetBody(self.chainDb, hash, self.hc.GetBlockNumber(hash)) + body := GetBody(bc.chainDb, hash, bc.hc.GetBlockNumber(hash)) if body == nil { return nil } // Cache the found body for next time and return - self.bodyCache.Add(hash, body) + bc.bodyCache.Add(hash, body) return body } // GetBodyRLP retrieves a block body in RLP encoding from the database by hash, // caching it if found. -func (self *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { +func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { // Short circuit if the body's already in the cache, retrieve otherwise - if cached, ok := self.bodyRLPCache.Get(hash); ok { + if cached, ok := bc.bodyRLPCache.Get(hash); ok { return cached.(rlp.RawValue) } - body := GetBodyRLP(self.chainDb, hash, self.hc.GetBlockNumber(hash)) + body := GetBodyRLP(bc.chainDb, hash, bc.hc.GetBlockNumber(hash)) if len(body) == 0 { return nil } // Cache the found body for next time and return - self.bodyRLPCache.Add(hash, body) + bc.bodyRLPCache.Add(hash, body) return body } @@ -537,41 +537,41 @@ func (bc *BlockChain) HasBlockAndState(hash common.Hash) bool { // GetBlock retrieves a block from the database by hash and number, // caching it if found. -func (self *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { +func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { // Short circuit if the block's already in the cache, retrieve otherwise - if block, ok := self.blockCache.Get(hash); ok { + if block, ok := bc.blockCache.Get(hash); ok { return block.(*types.Block) } - block := GetBlock(self.chainDb, hash, number) + block := GetBlock(bc.chainDb, hash, number) if block == nil { return nil } // Cache the found block for next time and return - self.blockCache.Add(block.Hash(), block) + bc.blockCache.Add(block.Hash(), block) return block } // GetBlockByHash retrieves a block from the database by hash, caching it if found. -func (self *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { - return self.GetBlock(hash, self.hc.GetBlockNumber(hash)) +func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { + return bc.GetBlock(hash, bc.hc.GetBlockNumber(hash)) } // GetBlockByNumber retrieves a block from the database by number, caching it // (associated with its hash) if found. -func (self *BlockChain) GetBlockByNumber(number uint64) *types.Block { - hash := GetCanonicalHash(self.chainDb, number) +func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { + hash := GetCanonicalHash(bc.chainDb, number) if hash == (common.Hash{}) { return nil } - return self.GetBlock(hash, number) + return bc.GetBlock(hash, number) } -// [deprecated by eth/62] // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors. -func (self *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { - number := self.hc.GetBlockNumber(hash) +// [deprecated by eth/62] +func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { + number := bc.hc.GetBlockNumber(hash) for i := 0; i < n; i++ { - block := self.GetBlock(hash, number) + block := bc.GetBlock(hash, number) if block == nil { break } @@ -584,11 +584,11 @@ func (self *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*ty // GetUnclesInChain retrieves all the uncles from a given block backwards until // a specific distance is reached. -func (self *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { +func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { uncles := []*types.Header{} for i := 0; block != nil && i < length; i++ { uncles = append(uncles, block.Uncles()...) - block = self.GetBlock(block.ParentHash(), block.NumberU64()-1) + block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) } return uncles } @@ -606,10 +606,10 @@ func (bc *BlockChain) Stop() { log.Info("Blockchain manager stopped") } -func (self *BlockChain) procFutureBlocks() { - blocks := make([]*types.Block, 0, self.futureBlocks.Len()) - for _, hash := range self.futureBlocks.Keys() { - if block, exist := self.futureBlocks.Peek(hash); exist { +func (bc *BlockChain) procFutureBlocks() { + blocks := make([]*types.Block, 0, bc.futureBlocks.Len()) + for _, hash := range bc.futureBlocks.Keys() { + if block, exist := bc.futureBlocks.Peek(hash); exist { blocks = append(blocks, block.(*types.Block)) } } @@ -618,11 +618,12 @@ func (self *BlockChain) procFutureBlocks() { // Insert one by one as chain insertion needs contiguous ancestry between blocks for i := range blocks { - self.InsertChain(blocks[i : i+1]) + bc.InsertChain(blocks[i : i+1]) } } } +// WriteStatus status of write type WriteStatus byte const ( @@ -633,24 +634,24 @@ const ( // Rollback is designed to remove a chain of links from the database that aren't // certain enough to be valid. -func (self *BlockChain) Rollback(chain []common.Hash) { - self.mu.Lock() - defer self.mu.Unlock() +func (bc *BlockChain) Rollback(chain []common.Hash) { + bc.mu.Lock() + defer bc.mu.Unlock() for i := len(chain) - 1; i >= 0; i-- { hash := chain[i] - currentHeader := self.hc.CurrentHeader() + currentHeader := bc.hc.CurrentHeader() if currentHeader.Hash() == hash { - self.hc.SetCurrentHeader(self.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1)) + bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1)) } - if self.currentFastBlock.Hash() == hash { - self.currentFastBlock = self.GetBlock(self.currentFastBlock.ParentHash(), self.currentFastBlock.NumberU64()-1) - WriteHeadFastBlockHash(self.chainDb, self.currentFastBlock.Hash()) + if bc.currentFastBlock.Hash() == hash { + bc.currentFastBlock = bc.GetBlock(bc.currentFastBlock.ParentHash(), bc.currentFastBlock.NumberU64()-1) + WriteHeadFastBlockHash(bc.chainDb, bc.currentFastBlock.Hash()) } - if self.currentBlock.Hash() == hash { - self.currentBlock = self.GetBlock(self.currentBlock.ParentHash(), self.currentBlock.NumberU64()-1) - WriteHeadBlockHash(self.chainDb, self.currentBlock.Hash()) + if bc.currentBlock.Hash() == hash { + bc.currentBlock = bc.GetBlock(bc.currentBlock.ParentHash(), bc.currentBlock.NumberU64()-1) + WriteHeadBlockHash(bc.chainDb, bc.currentBlock.Hash()) } } } @@ -692,7 +693,7 @@ func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts ty // InsertReceiptChain attempts to complete an already existing header chain with // transaction and receipt data. // XXX should this be moved to the test? -func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { +func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(blockChain); i++ { if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() { @@ -705,8 +706,8 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain } } // Pre-checks passed, start the block body and receipt imports - self.wg.Add(1) - defer self.wg.Done() + bc.wg.Add(1) + defer bc.wg.Done() // Collect some import statistics to report on stats := struct{ processed, ignored int32 }{} @@ -725,51 +726,51 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain block, receipts := blockChain[index], receiptChain[index] // Short circuit insertion if shutting down or processing failed - if atomic.LoadInt32(&self.procInterrupt) == 1 { + if atomic.LoadInt32(&bc.procInterrupt) == 1 { return } if atomic.LoadInt32(&failed) > 0 { return } // Short circuit if the owner header is unknown - if !self.HasHeader(block.Hash()) { + if !bc.HasHeader(block.Hash()) { errs[index] = fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4]) atomic.AddInt32(&failed, 1) return } // Skip if the entire data is already known - if self.HasBlock(block.Hash()) { + if bc.HasBlock(block.Hash()) { atomic.AddInt32(&stats.ignored, 1) continue } // Compute all the non-consensus fields of the receipts - SetReceiptsData(self.config, block, receipts) + SetReceiptsData(bc.config, block, receipts) // Write all the data out into the database - if err := WriteBody(self.chainDb, block.Hash(), block.NumberU64(), block.Body()); err != nil { + if err := WriteBody(bc.chainDb, block.Hash(), block.NumberU64(), block.Body()); err != nil { errs[index] = fmt.Errorf("failed to write block body: %v", err) atomic.AddInt32(&failed, 1) log.Crit("Failed to write block body", "err", err) return } - if err := WriteBlockReceipts(self.chainDb, block.Hash(), block.NumberU64(), receipts); err != nil { + if err := WriteBlockReceipts(bc.chainDb, block.Hash(), block.NumberU64(), receipts); err != nil { errs[index] = fmt.Errorf("failed to write block receipts: %v", err) atomic.AddInt32(&failed, 1) log.Crit("Failed to write block receipts", "err", err) return } - if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil { + if err := WriteMipmapBloom(bc.chainDb, block.NumberU64(), receipts); err != nil { errs[index] = fmt.Errorf("failed to write log blooms: %v", err) atomic.AddInt32(&failed, 1) log.Crit("Failed to write log blooms", "err", err) return } - if err := WriteTransactions(self.chainDb, block); err != nil { + if err := WriteTransactions(bc.chainDb, block); err != nil { errs[index] = fmt.Errorf("failed to write individual transactions: %v", err) atomic.AddInt32(&failed, 1) log.Crit("Failed to write individual transactions", "err", err) return } - if err := WriteReceipts(self.chainDb, receipts); err != nil { + if err := WriteReceipts(bc.chainDb, receipts); err != nil { errs[index] = fmt.Errorf("failed to write individual receipts: %v", err) atomic.AddInt32(&failed, 1) log.Crit("Failed to write individual receipts", "err", err) @@ -797,23 +798,23 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain } } } - if atomic.LoadInt32(&self.procInterrupt) == 1 { + if atomic.LoadInt32(&bc.procInterrupt) == 1 { log.Debug("Premature abort during receipts processing") return 0, nil } // Update the head fast sync block if better - self.mu.Lock() + bc.mu.Lock() head := blockChain[len(errs)-1] - if td := self.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case - if self.GetTd(self.currentFastBlock.Hash(), self.currentFastBlock.NumberU64()).Cmp(td) < 0 { - if err := WriteHeadFastBlockHash(self.chainDb, head.Hash()); err != nil { + if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case + if bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64()).Cmp(td) < 0 { + if err := WriteHeadFastBlockHash(bc.chainDb, head.Hash()); err != nil { log.Crit("Failed to update head fast block hash", "err", err) } - self.currentFastBlock = head + bc.currentFastBlock = head } } - self.mu.Unlock() + bc.mu.Unlock() // Report some public statistics so the user has a clue what's going on last := blockChain[len(blockChain)-1] @@ -824,27 +825,27 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain } // WriteBlock writes the block to the chain. -func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err error) { - self.wg.Add(1) - defer self.wg.Done() +func (bc *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err error) { + bc.wg.Add(1) + defer bc.wg.Done() // Calculate the total difficulty of the block - ptd := self.GetTd(block.ParentHash(), block.NumberU64()-1) + ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) if ptd == nil { return NonStatTy, consensus.ErrUnknownAncestor } // Make sure no inconsistent state is leaked during insertion - self.mu.Lock() - defer self.mu.Unlock() + bc.mu.Lock() + defer bc.mu.Unlock() - localTd := self.GetTd(self.currentBlock.Hash(), self.currentBlock.NumberU64()) + localTd := bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()) externTd := new(big.Int).Add(block.Difficulty(), ptd) // Irrelevant of the canonical status, write the block itself to the database - if err := self.hc.WriteTd(block.Hash(), block.NumberU64(), externTd); err != nil { + if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd); err != nil { log.Crit("Failed to write block total difficulty", "err", err) } - if err := WriteBlock(self.chainDb, block); err != nil { + if err := WriteBlock(bc.chainDb, block); err != nil { log.Crit("Failed to write block contents", "err", err) } @@ -853,25 +854,25 @@ func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) { // Reorganise the chain if the parent is not the head block - if block.ParentHash() != self.currentBlock.Hash() { - if err := self.reorg(self.currentBlock, block); err != nil { + if block.ParentHash() != bc.currentBlock.Hash() { + if err := bc.reorg(bc.currentBlock, block); err != nil { return NonStatTy, err } } - self.insert(block) // Insert the block as the new head of the chain + bc.insert(block) // Insert the block as the new head of the chain status = CanonStatTy } else { status = SideStatTy } - self.futureBlocks.Remove(block.Hash()) + bc.futureBlocks.Remove(block.Hash()) return } // InsertChain will attempt to insert the given chain in to the canonical chain or, otherwise, create a fork. If an error is returned // it will return the index number of the failing block as well an error describing what went wrong (for possible errors see core/errors.go). -func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { +func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(chain); i++ { if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() { @@ -884,11 +885,11 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { } } // Pre-checks passed, start the full block imports - self.wg.Add(1) - defer self.wg.Done() + bc.wg.Add(1) + defer bc.wg.Done() - self.chainmu.Lock() - defer self.chainmu.Unlock() + bc.chainmu.Lock() + defer bc.chainmu.Unlock() // A queued approach to delivering events. This is generally // faster than direct delivery and requires much less mutex @@ -906,19 +907,19 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { headers[i] = block.Header() seals[i] = true } - abort, results := self.engine.VerifyHeaders(self, headers, seals) + abort, results := bc.engine.VerifyHeaders(bc, headers, seals) defer close(abort) // Iterate over the blocks and insert when the verifier permits for i, block := range chain { // If the chain is terminating, stop processing blocks - if atomic.LoadInt32(&self.procInterrupt) == 1 { + if atomic.LoadInt32(&bc.procInterrupt) == 1 { log.Debug("Premature abort during blocks processing") break } // If the header is a banned one, straight out abort if BadHashes[block.Hash()] { - self.reportBlock(block, nil, ErrBlacklistedHash) + bc.reportBlock(block, nil, ErrBlacklistedHash) return i, ErrBlacklistedHash } // Wait for the block's verification to complete @@ -926,7 +927,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { err := <-results if err == nil { - err = self.Validator().ValidateBody(block) + err = bc.Validator().ValidateBody(block) } if err != nil { if err == ErrKnownBlock { @@ -942,46 +943,46 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { if block.Time().Cmp(max) > 0 { return i, fmt.Errorf("future block: %v > %v", block.Time(), max) } - self.futureBlocks.Add(block.Hash(), block) + bc.futureBlocks.Add(block.Hash(), block) stats.queued++ continue } - if err == consensus.ErrUnknownAncestor && self.futureBlocks.Contains(block.ParentHash()) { - self.futureBlocks.Add(block.Hash(), block) + if err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(block.ParentHash()) { + bc.futureBlocks.Add(block.Hash(), block) stats.queued++ continue } - self.reportBlock(block, nil, err) + bc.reportBlock(block, nil, err) return i, err } // Create a new statedb using the parent block and report an // error if it fails. switch { case i == 0: - err = self.stateCache.Reset(self.GetBlock(block.ParentHash(), block.NumberU64()-1).Root()) + err = bc.stateCache.Reset(bc.GetBlock(block.ParentHash(), block.NumberU64()-1).Root()) default: - err = self.stateCache.Reset(chain[i-1].Root()) + err = bc.stateCache.Reset(chain[i-1].Root()) } if err != nil { - self.reportBlock(block, nil, err) + bc.reportBlock(block, nil, err) return i, err } // Process block using the parent state as reference point. - receipts, logs, usedGas, err := self.processor.Process(block, self.stateCache, self.vmConfig) + receipts, logs, usedGas, err := bc.processor.Process(block, bc.stateCache, bc.vmConfig) if err != nil { - self.reportBlock(block, receipts, err) + bc.reportBlock(block, receipts, err) return i, err } // Validate the state using the default validator - err = self.Validator().ValidateState(block, self.GetBlock(block.ParentHash(), block.NumberU64()-1), self.stateCache, receipts, usedGas) + err = bc.Validator().ValidateState(block, bc.GetBlock(block.ParentHash(), block.NumberU64()-1), bc.stateCache, receipts, usedGas) if err != nil { - self.reportBlock(block, receipts, err) + bc.reportBlock(block, receipts, err) return i, err } // Write state changes to database - _, err = self.stateCache.Commit(self.config.IsEIP158(block.Number())) + _, err = bc.stateCache.Commit(bc.config.IsEIP158(block.Number())) if err != nil { return i, err } @@ -989,12 +990,12 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { // coalesce logs for later processing coalescedLogs = append(coalescedLogs, logs...) - if err = WriteBlockReceipts(self.chainDb, block.Hash(), block.NumberU64(), receipts); err != nil { + if err = WriteBlockReceipts(bc.chainDb, block.Hash(), block.NumberU64(), receipts); err != nil { return i, err } // write the block to the chain and get the status - status, err := self.WriteBlock(block) + status, err := bc.WriteBlock(block) if err != nil { return i, err } @@ -1008,19 +1009,19 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { events = append(events, ChainEvent{block, block.Hash(), logs}) // This puts transactions in a extra db for rpc - if err := WriteTransactions(self.chainDb, block); err != nil { + if err := WriteTransactions(bc.chainDb, block); err != nil { return i, err } // store the receipts - if err := WriteReceipts(self.chainDb, receipts); err != nil { + if err := WriteReceipts(bc.chainDb, receipts); err != nil { return i, err } // Write map map bloom filters - if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil { + if err := WriteMipmapBloom(bc.chainDb, block.NumberU64(), receipts); err != nil { return i, err } // Write hash preimages - if err := WritePreimages(self.chainDb, block.NumberU64(), self.stateCache.Preimages()); err != nil { + if err := WritePreimages(bc.chainDb, block.NumberU64(), bc.stateCache.Preimages()); err != nil { return i, err } case SideStatTy: @@ -1034,7 +1035,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { stats.usedGas += usedGas.Uint64() stats.report(chain, i) } - go self.postChainEvents(events, coalescedLogs) + go bc.postChainEvents(events, coalescedLogs) return 0, nil } @@ -1092,7 +1093,7 @@ func countTransactions(chain []*types.Block) (c int) { // reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them // to be part of the new canonical chain and accumulates potential missing transactions and post an // event about them -func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { +func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { var ( newChain types.Blocks oldChain types.Blocks @@ -1104,7 +1105,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { // These logs are later announced as deleted. collectLogs = func(h common.Hash) { // Coalesce logs and set 'Removed'. - receipts := GetBlockReceipts(self.chainDb, h, self.hc.GetBlockNumber(h)) + receipts := GetBlockReceipts(bc.chainDb, h, bc.hc.GetBlockNumber(h)) for _, receipt := range receipts { for _, log := range receipt.Logs { del := *log @@ -1118,7 +1119,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { // first reduce whoever is higher bound if oldBlock.NumberU64() > newBlock.NumberU64() { // reduce old chain - for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = self.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) { + for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) { oldChain = append(oldChain, oldBlock) deletedTxs = append(deletedTxs, oldBlock.Transactions()...) @@ -1126,7 +1127,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { } } else { // reduce new chain and append new chain blocks for inserting later on - for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = self.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) { + for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) { newChain = append(newChain, newBlock) } } @@ -1148,7 +1149,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { deletedTxs = append(deletedTxs, oldBlock.Transactions()...) collectLogs(oldBlock.Hash()) - oldBlock, newBlock = self.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), self.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) + oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) if oldBlock == nil { return fmt.Errorf("Invalid old chain") } @@ -1168,21 +1169,21 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash()) } var addedTxs types.Transactions - // insert blocks. Order does not matter. Last block will be written in ImportChain itself which creates the new head properly + // insert blocks. Order does not matter. Last block will be written in ImportChain itbc which creates the new head properly for _, block := range newChain { // insert the block in the canonical way, re-writing history - self.insert(block) + bc.insert(block) // write canonical receipts and transactions - if err := WriteTransactions(self.chainDb, block); err != nil { + if err := WriteTransactions(bc.chainDb, block); err != nil { return err } - receipts := GetBlockReceipts(self.chainDb, block.Hash(), block.NumberU64()) + receipts := GetBlockReceipts(bc.chainDb, block.Hash(), block.NumberU64()) // write receipts - if err := WriteReceipts(self.chainDb, receipts); err != nil { + if err := WriteReceipts(bc.chainDb, receipts); err != nil { return err } // Write map map bloom filters - if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil { + if err := WriteMipmapBloom(bc.chainDb, block.NumberU64(), receipts); err != nil { return err } addedTxs = append(addedTxs, block.Transactions()...) @@ -1193,22 +1194,22 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { // When transactions get deleted from the database that means the // receipts that were created in the fork must also be deleted for _, tx := range diff { - DeleteReceipt(self.chainDb, tx.Hash()) - DeleteTransaction(self.chainDb, tx.Hash()) + DeleteReceipt(bc.chainDb, tx.Hash()) + DeleteTransaction(bc.chainDb, tx.Hash()) } // Must be posted in a goroutine because of the transaction pool trying // to acquire the chain manager lock if len(diff) > 0 { - go self.eventMux.Post(RemovedTransactionEvent{diff}) + go bc.eventMux.Post(RemovedTransactionEvent{diff}) } if len(deletedLogs) > 0 { - go self.eventMux.Post(RemovedLogsEvent{deletedLogs}) + go bc.eventMux.Post(RemovedLogsEvent{deletedLogs}) } if len(oldChain) > 0 { go func() { for _, block := range oldChain { - self.eventMux.Post(ChainSideEvent{Block: block}) + bc.eventMux.Post(ChainSideEvent{Block: block}) } }() } @@ -1218,30 +1219,30 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { // postChainEvents iterates over the events generated by a chain insertion and // posts them into the event mux. -func (self *BlockChain) postChainEvents(events []interface{}, logs []*types.Log) { +func (bc *BlockChain) postChainEvents(events []interface{}, logs []*types.Log) { // post event logs for further processing - self.eventMux.Post(logs) + bc.eventMux.Post(logs) for _, event := range events { if event, ok := event.(ChainEvent); ok { // We need some control over the mining operation. Acquiring locks and waiting // for the miner to create new block takes too long and in most cases isn't // even necessary. - if self.LastBlockHash() == event.Hash { - self.eventMux.Post(ChainHeadEvent{event.Block}) + if bc.LastBlockHash() == event.Hash { + bc.eventMux.Post(ChainHeadEvent{event.Block}) } } // Fire the insertion events individually too - self.eventMux.Post(event) + bc.eventMux.Post(event) } } -func (self *BlockChain) update() { +func (bc *BlockChain) update() { futureTimer := time.Tick(5 * time.Second) for { select { case <-futureTimer: - self.procFutureBlocks() - case <-self.quit: + bc.procFutureBlocks() + case <-bc.quit: return } } @@ -1299,28 +1300,28 @@ Error: %v // should be done or not. The reason behind the optional check is because some // of the header retrieval mechanisms already need to verify nonces, as well as // because nonces can be verified sparsely, not needing to check each. -func (self *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { +func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { start := time.Now() - if i, err := self.hc.ValidateHeaderChain(chain, checkFreq); err != nil { + if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { return i, err } // Make sure only one thread manipulates the chain at once - self.chainmu.Lock() - defer self.chainmu.Unlock() + bc.chainmu.Lock() + defer bc.chainmu.Unlock() - self.wg.Add(1) - defer self.wg.Done() + bc.wg.Add(1) + defer bc.wg.Done() whFunc := func(header *types.Header) error { - self.mu.Lock() - defer self.mu.Unlock() + bc.mu.Lock() + defer bc.mu.Unlock() - _, err := self.hc.WriteHeader(header) + _, err := bc.hc.WriteHeader(header) return err } - return self.hc.InsertHeaderChain(chain, whFunc, start) + return bc.hc.InsertHeaderChain(chain, whFunc, start) } // writeHeader writes a header into the local chain, given that its parent is @@ -1332,48 +1333,48 @@ func (self *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) // without the real blocks. Hence, writing headers directly should only be done // in two scenarios: pure-header mode of operation (light clients), or properly // separated header/block phases (non-archive clients). -func (self *BlockChain) writeHeader(header *types.Header) error { - self.wg.Add(1) - defer self.wg.Done() +func (bc *BlockChain) writeHeader(header *types.Header) error { + bc.wg.Add(1) + defer bc.wg.Done() - self.mu.Lock() - defer self.mu.Unlock() + bc.mu.Lock() + defer bc.mu.Unlock() - _, err := self.hc.WriteHeader(header) + _, err := bc.hc.WriteHeader(header) return err } // CurrentHeader retrieves the current head header of the canonical chain. The // header is retrieved from the HeaderChain's internal cache. -func (self *BlockChain) CurrentHeader() *types.Header { - self.mu.RLock() - defer self.mu.RUnlock() +func (bc *BlockChain) CurrentHeader() *types.Header { + bc.mu.RLock() + defer bc.mu.RUnlock() - return self.hc.CurrentHeader() + return bc.hc.CurrentHeader() } // GetTd retrieves a block's total difficulty in the canonical chain from the // database by hash and number, caching it if found. -func (self *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { - return self.hc.GetTd(hash, number) +func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { + return bc.hc.GetTd(hash, number) } // GetTdByHash retrieves a block's total difficulty in the canonical chain from the // database by hash, caching it if found. -func (self *BlockChain) GetTdByHash(hash common.Hash) *big.Int { - return self.hc.GetTdByHash(hash) +func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int { + return bc.hc.GetTdByHash(hash) } // GetHeader retrieves a block header from the database by hash and number, // caching it if found. -func (self *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { - return self.hc.GetHeader(hash, number) +func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { + return bc.hc.GetHeader(hash, number) } // GetHeaderByHash retrieves a block header from the database by hash, caching it if // found. -func (self *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { - return self.hc.GetHeaderByHash(hash) +func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { + return bc.hc.GetHeaderByHash(hash) } // HasHeader checks if a block header is present in the database or not, caching @@ -1384,18 +1385,18 @@ func (bc *BlockChain) HasHeader(hash common.Hash) bool { // GetBlockHashesFromHash retrieves a number of block hashes starting at a given // hash, fetching towards the genesis block. -func (self *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { - return self.hc.GetBlockHashesFromHash(hash, max) +func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { + return bc.hc.GetBlockHashesFromHash(hash, max) } // GetHeaderByNumber retrieves a block header from the database by number, // caching it (associated with its hash) if found. -func (self *BlockChain) GetHeaderByNumber(number uint64) *types.Header { - return self.hc.GetHeaderByNumber(number) +func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { + return bc.hc.GetHeaderByNumber(number) } // Config retrieves the blockchain's chain configuration. -func (self *BlockChain) Config() *params.ChainConfig { return self.config } +func (bc *BlockChain) Config() *params.ChainConfig { return bc.config } // Engine retrieves the blockchain's consensus engine. -func (self *BlockChain) Engine() consensus.Engine { return self.engine } +func (bc *BlockChain) Engine() consensus.Engine { return bc.engine } |