Unverified Commit 17f0b119 authored by changhong's avatar changhong Committed by Péter Szilágyi

core: typos and comments improve

1. fix typos
2. methods recevier of struct should be same
3. comments improve

(cherry picked from commit 1ba979539582a00b7fd1a7c8a37a6852e59eac0d)
parent 07aae19e
...@@ -56,7 +56,7 @@ const ( ...@@ -56,7 +56,7 @@ const (
blockCacheLimit = 256 blockCacheLimit = 256
maxFutureBlocks = 256 maxFutureBlocks = 256
maxTimeFutureBlocks = 30 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) // command to be run (forces the blocks to be imported again using the new algorithm)
BlockChainVersion = 3 BlockChainVersion = 3
badBlockLimit = 10 badBlockLimit = 10
...@@ -168,67 +168,67 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, engine co ...@@ -168,67 +168,67 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, engine co
return bc, nil return bc, nil
} }
func (self *BlockChain) getProcInterrupt() bool { func (bc *BlockChain) getProcInterrupt() bool {
return atomic.LoadInt32(&self.procInterrupt) == 1 return atomic.LoadInt32(&bc.procInterrupt) == 1
} }
// loadLastState loads the last known chain state from the database. This method // loadLastState loads the last known chain state from the database. This method
// assumes that the chain manager mutex is held. // assumes that the chain manager mutex is held.
func (self *BlockChain) loadLastState() error { func (bc *BlockChain) loadLastState() error {
// Restore the last known head block // Restore the last known head block
head := GetHeadBlockHash(self.chainDb) head := GetHeadBlockHash(bc.chainDb)
if head == (common.Hash{}) { if head == (common.Hash{}) {
// Corrupt or empty database, init from scratch // Corrupt or empty database, init from scratch
log.Warn("Empty database, resetting chain") log.Warn("Empty database, resetting chain")
return self.Reset() return bc.Reset()
} }
// Make sure the entire head block is available // Make sure the entire head block is available
currentBlock := self.GetBlockByHash(head) currentBlock := bc.GetBlockByHash(head)
if currentBlock == nil { if currentBlock == nil {
// Corrupt or empty database, init from scratch // Corrupt or empty database, init from scratch
log.Warn("Head block missing, resetting chain", "hash", head) 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 // 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 // Dangling block without a state associated, init from scratch
log.Warn("Head state missing, resetting chain", "number", currentBlock.Number(), "hash", currentBlock.Hash()) 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 // Everything seems to be fine, set as the head block
self.currentBlock = currentBlock bc.currentBlock = currentBlock
// Restore the last known head header // Restore the last known head header
currentHeader := self.currentBlock.Header() currentHeader := bc.currentBlock.Header()
if head := GetHeadHeaderHash(self.chainDb); head != (common.Hash{}) { if head := GetHeadHeaderHash(bc.chainDb); head != (common.Hash{}) {
if header := self.GetHeaderByHash(head); header != nil { if header := bc.GetHeaderByHash(head); header != nil {
currentHeader = header currentHeader = header
} }
} }
self.hc.SetCurrentHeader(currentHeader) bc.hc.SetCurrentHeader(currentHeader)
// Restore the last known head fast block // Restore the last known head fast block
self.currentFastBlock = self.currentBlock bc.currentFastBlock = bc.currentBlock
if head := GetHeadFastBlockHash(self.chainDb); head != (common.Hash{}) { if head := GetHeadFastBlockHash(bc.chainDb); head != (common.Hash{}) {
if block := self.GetBlockByHash(head); block != nil { if block := bc.GetBlockByHash(head); block != nil {
self.currentFastBlock = block bc.currentFastBlock = block
} }
} }
// Initialize a statedb cache to ensure singleton account bloom filter generation // 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 { if err != nil {
return err return err
} }
self.stateCache = statedb bc.stateCache = statedb
// Issue a status log for the user // Issue a status log for the user
headerTd := self.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()) headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64())
blockTd := self.GetTd(self.currentBlock.Hash(), self.currentBlock.NumberU64()) blockTd := bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64())
fastTd := self.GetTd(self.currentFastBlock.Hash(), self.currentFastBlock.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 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 full block", "number", bc.currentBlock.Number(), "hash", bc.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 fast block", "number", bc.currentFastBlock.Number(), "hash", bc.currentFastBlock.Hash(), "td", fastTd)
return nil return nil
} }
...@@ -288,103 +288,103 @@ func (bc *BlockChain) SetHead(head uint64) error { ...@@ -288,103 +288,103 @@ func (bc *BlockChain) SetHead(head uint64) error {
// FastSyncCommitHead sets the current head block to the one defined by the hash // FastSyncCommitHead sets the current head block to the one defined by the hash
// irrelevant what the chain contents were prior. // 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 // Make sure that both the block as well at its state trie exists
block := self.GetBlockByHash(hash) block := bc.GetBlockByHash(hash)
if block == nil { if block == nil {
return fmt.Errorf("non existent block [%x…]", hash[:4]) 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 return err
} }
// If all checks out, manually set the head block // If all checks out, manually set the head block
self.mu.Lock() bc.mu.Lock()
self.currentBlock = block bc.currentBlock = block
self.mu.Unlock() bc.mu.Unlock()
log.Info("Committed new head block", "number", block.Number(), "hash", hash) log.Info("Committed new head block", "number", block.Number(), "hash", hash)
return nil return nil
} }
// GasLimit returns the gas limit of the current HEAD block. // GasLimit returns the gas limit of the current HEAD block.
func (self *BlockChain) GasLimit() *big.Int { func (bc *BlockChain) GasLimit() *big.Int {
self.mu.RLock() bc.mu.RLock()
defer self.mu.RUnlock() defer bc.mu.RUnlock()
return self.currentBlock.GasLimit() return bc.currentBlock.GasLimit()
} }
// LastBlockHash return the hash of the HEAD block. // LastBlockHash return the hash of the HEAD block.
func (self *BlockChain) LastBlockHash() common.Hash { func (bc *BlockChain) LastBlockHash() common.Hash {
self.mu.RLock() bc.mu.RLock()
defer self.mu.RUnlock() defer bc.mu.RUnlock()
return self.currentBlock.Hash() return bc.currentBlock.Hash()
} }
// CurrentBlock retrieves the current head block of the canonical chain. The // CurrentBlock retrieves the current head block of the canonical chain. The
// block is retrieved from the blockchain's internal cache. // block is retrieved from the blockchain's internal cache.
func (self *BlockChain) CurrentBlock() *types.Block { func (bc *BlockChain) CurrentBlock() *types.Block {
self.mu.RLock() bc.mu.RLock()
defer self.mu.RUnlock() defer bc.mu.RUnlock()
return self.currentBlock return bc.currentBlock
} }
// CurrentFastBlock retrieves the current fast-sync head block of the canonical // CurrentFastBlock retrieves the current fast-sync head block of the canonical
// chain. The block is retrieved from the blockchain's internal cache. // chain. The block is retrieved from the blockchain's internal cache.
func (self *BlockChain) CurrentFastBlock() *types.Block { func (bc *BlockChain) CurrentFastBlock() *types.Block {
self.mu.RLock() bc.mu.RLock()
defer self.mu.RUnlock() defer bc.mu.RUnlock()
return self.currentFastBlock return bc.currentFastBlock
} }
// Status returns status information about the current chain such as the HEAD Td, // Status returns status information about the current chain such as the HEAD Td,
// the HEAD hash and the hash of the genesis block. // the HEAD hash and the hash of the genesis block.
func (self *BlockChain) Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash) { func (bc *BlockChain) Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash) {
self.mu.RLock() bc.mu.RLock()
defer self.mu.RUnlock() 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. // SetProcessor sets the processor required for making state modifications.
func (self *BlockChain) SetProcessor(processor Processor) { func (bc *BlockChain) SetProcessor(processor Processor) {
self.procmu.Lock() bc.procmu.Lock()
defer self.procmu.Unlock() defer bc.procmu.Unlock()
self.processor = processor bc.processor = processor
} }
// SetValidator sets the validator which is used to validate incoming blocks. // SetValidator sets the validator which is used to validate incoming blocks.
func (self *BlockChain) SetValidator(validator Validator) { func (bc *BlockChain) SetValidator(validator Validator) {
self.procmu.Lock() bc.procmu.Lock()
defer self.procmu.Unlock() defer bc.procmu.Unlock()
self.validator = validator bc.validator = validator
} }
// Validator returns the current validator. // Validator returns the current validator.
func (self *BlockChain) Validator() Validator { func (bc *BlockChain) Validator() Validator {
self.procmu.RLock() bc.procmu.RLock()
defer self.procmu.RUnlock() defer bc.procmu.RUnlock()
return self.validator return bc.validator
} }
// Processor returns the current processor. // Processor returns the current processor.
func (self *BlockChain) Processor() Processor { func (bc *BlockChain) Processor() Processor {
self.procmu.RLock() bc.procmu.RLock()
defer self.procmu.RUnlock() defer bc.procmu.RUnlock()
return self.processor return bc.processor
} }
// State returns a new mutable state based on the current HEAD block. // State returns a new mutable state based on the current HEAD block.
func (self *BlockChain) State() (*state.StateDB, error) { func (bc *BlockChain) State() (*state.StateDB, error) {
return self.StateAt(self.CurrentBlock().Root()) return bc.StateAt(bc.CurrentBlock().Root())
} }
// StateAt returns a new mutable state based on a particular point in time. // StateAt returns a new mutable state based on a particular point in time.
func (self *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
return self.stateCache.New(root) return bc.stateCache.New(root)
} }
// Reset purges the entire blockchain, restoring it to its genesis state. // Reset purges the entire blockchain, restoring it to its genesis state.
...@@ -420,14 +420,14 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { ...@@ -420,14 +420,14 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
} }
// Export writes the active chain to the given writer. // Export writes the active chain to the given writer.
func (self *BlockChain) Export(w io.Writer) error { func (bc *BlockChain) Export(w io.Writer) error {
return self.ExportN(w, uint64(0), self.currentBlock.NumberU64()) return bc.ExportN(w, uint64(0), bc.currentBlock.NumberU64())
} }
// ExportN writes a subset of the active chain to the given writer. // ExportN writes a subset of the active chain to the given writer.
func (self *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
self.mu.RLock() bc.mu.RLock()
defer self.mu.RUnlock() defer bc.mu.RUnlock()
if first > last { if first > last {
return fmt.Errorf("export failed: first (%d) is greater than last (%d)", 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 { ...@@ -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) log.Info("Exporting batch of blocks", "count", last-first+1)
for nr := first; nr <= last; nr++ { for nr := first; nr <= last; nr++ {
block := self.GetBlockByNumber(nr) block := bc.GetBlockByNumber(nr)
if block == nil { if block == nil {
return fmt.Errorf("export failed on #%d: not found", nr) return fmt.Errorf("export failed on #%d: not found", nr)
} }
...@@ -478,41 +478,41 @@ func (bc *BlockChain) insert(block *types.Block) { ...@@ -478,41 +478,41 @@ func (bc *BlockChain) insert(block *types.Block) {
} }
} }
// Accessors // Genesis Accessors
func (bc *BlockChain) Genesis() *types.Block { func (bc *BlockChain) Genesis() *types.Block {
return bc.genesisBlock return bc.genesisBlock
} }
// GetBody retrieves a block body (transactions and uncles) from the database by // GetBody retrieves a block body (transactions and uncles) from the database by
// hash, caching it if found. // 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 // 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) body := cached.(*types.Body)
return body return body
} }
body := GetBody(self.chainDb, hash, self.hc.GetBlockNumber(hash)) body := GetBody(bc.chainDb, hash, bc.hc.GetBlockNumber(hash))
if body == nil { if body == nil {
return nil return nil
} }
// Cache the found body for next time and return // Cache the found body for next time and return
self.bodyCache.Add(hash, body) bc.bodyCache.Add(hash, body)
return body return body
} }
// GetBodyRLP retrieves a block body in RLP encoding from the database by hash, // GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
// caching it if found. // 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 // 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) 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 { if len(body) == 0 {
return nil return nil
} }
// Cache the found body for next time and return // Cache the found body for next time and return
self.bodyRLPCache.Add(hash, body) bc.bodyRLPCache.Add(hash, body)
return body return body
} }
...@@ -537,41 +537,41 @@ func (bc *BlockChain) HasBlockAndState(hash common.Hash) bool { ...@@ -537,41 +537,41 @@ func (bc *BlockChain) HasBlockAndState(hash common.Hash) bool {
// GetBlock retrieves a block from the database by hash and number, // GetBlock retrieves a block from the database by hash and number,
// caching it if found. // 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 // 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) return block.(*types.Block)
} }
block := GetBlock(self.chainDb, hash, number) block := GetBlock(bc.chainDb, hash, number)
if block == nil { if block == nil {
return nil return nil
} }
// Cache the found block for next time and return // Cache the found block for next time and return
self.blockCache.Add(block.Hash(), block) bc.blockCache.Add(block.Hash(), block)
return block return block
} }
// GetBlockByHash retrieves a block from the database by hash, caching it if found. // GetBlockByHash retrieves a block from the database by hash, caching it if found.
func (self *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
return self.GetBlock(hash, self.hc.GetBlockNumber(hash)) return bc.GetBlock(hash, bc.hc.GetBlockNumber(hash))
} }
// GetBlockByNumber retrieves a block from the database by number, caching it // GetBlockByNumber retrieves a block from the database by number, caching it
// (associated with its hash) if found. // (associated with its hash) if found.
func (self *BlockChain) GetBlockByNumber(number uint64) *types.Block { func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
hash := GetCanonicalHash(self.chainDb, number) hash := GetCanonicalHash(bc.chainDb, number)
if hash == (common.Hash{}) { if hash == (common.Hash{}) {
return nil 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. // 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) { // [deprecated by eth/62]
number := self.hc.GetBlockNumber(hash) func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
number := bc.hc.GetBlockNumber(hash)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
block := self.GetBlock(hash, number) block := bc.GetBlock(hash, number)
if block == nil { if block == nil {
break break
} }
...@@ -584,11 +584,11 @@ func (self *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*ty ...@@ -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 // GetUnclesInChain retrieves all the uncles from a given block backwards until
// a specific distance is reached. // 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{} uncles := []*types.Header{}
for i := 0; block != nil && i < length; i++ { for i := 0; block != nil && i < length; i++ {
uncles = append(uncles, block.Uncles()...) uncles = append(uncles, block.Uncles()...)
block = self.GetBlock(block.ParentHash(), block.NumberU64()-1) block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
} }
return uncles return uncles
} }
...@@ -606,10 +606,10 @@ func (bc *BlockChain) Stop() { ...@@ -606,10 +606,10 @@ func (bc *BlockChain) Stop() {
log.Info("Blockchain manager stopped") log.Info("Blockchain manager stopped")
} }
func (self *BlockChain) procFutureBlocks() { func (bc *BlockChain) procFutureBlocks() {
blocks := make([]*types.Block, 0, self.futureBlocks.Len()) blocks := make([]*types.Block, 0, bc.futureBlocks.Len())
for _, hash := range self.futureBlocks.Keys() { for _, hash := range bc.futureBlocks.Keys() {
if block, exist := self.futureBlocks.Peek(hash); exist { if block, exist := bc.futureBlocks.Peek(hash); exist {
blocks = append(blocks, block.(*types.Block)) blocks = append(blocks, block.(*types.Block))
} }
} }
...@@ -618,11 +618,12 @@ func (self *BlockChain) procFutureBlocks() { ...@@ -618,11 +618,12 @@ func (self *BlockChain) procFutureBlocks() {
// Insert one by one as chain insertion needs contiguous ancestry between blocks // Insert one by one as chain insertion needs contiguous ancestry between blocks
for i := range blocks { for i := range blocks {
self.InsertChain(blocks[i : i+1]) bc.InsertChain(blocks[i : i+1])
} }
} }
} }
// WriteStatus status of write
type WriteStatus byte type WriteStatus byte
const ( const (
...@@ -633,24 +634,24 @@ const ( ...@@ -633,24 +634,24 @@ const (
// Rollback is designed to remove a chain of links from the database that aren't // Rollback is designed to remove a chain of links from the database that aren't
// certain enough to be valid. // certain enough to be valid.
func (self *BlockChain) Rollback(chain []common.Hash) { func (bc *BlockChain) Rollback(chain []common.Hash) {
self.mu.Lock() bc.mu.Lock()
defer self.mu.Unlock() defer bc.mu.Unlock()
for i := len(chain) - 1; i >= 0; i-- { for i := len(chain) - 1; i >= 0; i-- {
hash := chain[i] hash := chain[i]
currentHeader := self.hc.CurrentHeader() currentHeader := bc.hc.CurrentHeader()
if currentHeader.Hash() == hash { 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 { if bc.currentFastBlock.Hash() == hash {
self.currentFastBlock = self.GetBlock(self.currentFastBlock.ParentHash(), self.currentFastBlock.NumberU64()-1) bc.currentFastBlock = bc.GetBlock(bc.currentFastBlock.ParentHash(), bc.currentFastBlock.NumberU64()-1)
WriteHeadFastBlockHash(self.chainDb, self.currentFastBlock.Hash()) WriteHeadFastBlockHash(bc.chainDb, bc.currentFastBlock.Hash())
} }
if self.currentBlock.Hash() == hash { if bc.currentBlock.Hash() == hash {
self.currentBlock = self.GetBlock(self.currentBlock.ParentHash(), self.currentBlock.NumberU64()-1) bc.currentBlock = bc.GetBlock(bc.currentBlock.ParentHash(), bc.currentBlock.NumberU64()-1)
WriteHeadBlockHash(self.chainDb, self.currentBlock.Hash()) WriteHeadBlockHash(bc.chainDb, bc.currentBlock.Hash())
} }
} }
} }
...@@ -692,7 +693,7 @@ func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts ty ...@@ -692,7 +693,7 @@ func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts ty
// InsertReceiptChain attempts to complete an already existing header chain with // InsertReceiptChain attempts to complete an already existing header chain with
// transaction and receipt data. // transaction and receipt data.
// XXX should this be moved to the test? // 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 // Do a sanity check that the provided chain is actually ordered and linked
for i := 1; i < len(blockChain); i++ { for i := 1; i < len(blockChain); i++ {
if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() { 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 ...@@ -705,8 +706,8 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain
} }
} }
// Pre-checks passed, start the block body and receipt imports // Pre-checks passed, start the block body and receipt imports
self.wg.Add(1) bc.wg.Add(1)
defer self.wg.Done() defer bc.wg.Done()
// Collect some import statistics to report on // Collect some import statistics to report on
stats := struct{ processed, ignored int32 }{} stats := struct{ processed, ignored int32 }{}
...@@ -725,51 +726,51 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain ...@@ -725,51 +726,51 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain
block, receipts := blockChain[index], receiptChain[index] block, receipts := blockChain[index], receiptChain[index]
// Short circuit insertion if shutting down or processing failed // Short circuit insertion if shutting down or processing failed
if atomic.LoadInt32(&self.procInterrupt) == 1 { if atomic.LoadInt32(&bc.procInterrupt) == 1 {
return return
} }
if atomic.LoadInt32(&failed) > 0 { if atomic.LoadInt32(&failed) > 0 {
return return
} }
// Short circuit if the owner header is unknown // 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]) errs[index] = fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4])
atomic.AddInt32(&failed, 1) atomic.AddInt32(&failed, 1)
return return
} }
// Skip if the entire data is already known // Skip if the entire data is already known
if self.HasBlock(block.Hash()) { if bc.HasBlock(block.Hash()) {
atomic.AddInt32(&stats.ignored, 1) atomic.AddInt32(&stats.ignored, 1)
continue continue
} }
// Compute all the non-consensus fields of the receipts // 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 // 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) errs[index] = fmt.Errorf("failed to write block body: %v", err)
atomic.AddInt32(&failed, 1) atomic.AddInt32(&failed, 1)
log.Crit("Failed to write block body", "err", err) log.Crit("Failed to write block body", "err", err)
return 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) errs[index] = fmt.Errorf("failed to write block receipts: %v", err)
atomic.AddInt32(&failed, 1) atomic.AddInt32(&failed, 1)
log.Crit("Failed to write block receipts", "err", err) log.Crit("Failed to write block receipts", "err", err)
return 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) errs[index] = fmt.Errorf("failed to write log blooms: %v", err)
atomic.AddInt32(&failed, 1) atomic.AddInt32(&failed, 1)
log.Crit("Failed to write log blooms", "err", err) log.Crit("Failed to write log blooms", "err", err)
return 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) errs[index] = fmt.Errorf("failed to write individual transactions: %v", err)
atomic.AddInt32(&failed, 1) atomic.AddInt32(&failed, 1)
log.Crit("Failed to write individual transactions", "err", err) log.Crit("Failed to write individual transactions", "err", err)
return 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) errs[index] = fmt.Errorf("failed to write individual receipts: %v", err)
atomic.AddInt32(&failed, 1) atomic.AddInt32(&failed, 1)
log.Crit("Failed to write individual receipts", "err", err) log.Crit("Failed to write individual receipts", "err", err)
...@@ -797,23 +798,23 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain ...@@ -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") log.Debug("Premature abort during receipts processing")
return 0, nil return 0, nil
} }
// Update the head fast sync block if better // Update the head fast sync block if better
self.mu.Lock() bc.mu.Lock()
head := blockChain[len(errs)-1] head := blockChain[len(errs)-1]
if td := self.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case if td := bc.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 bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64()).Cmp(td) < 0 {
if err := WriteHeadFastBlockHash(self.chainDb, head.Hash()); err != nil { if err := WriteHeadFastBlockHash(bc.chainDb, head.Hash()); err != nil {
log.Crit("Failed to update head fast block hash", "err", err) 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 // Report some public statistics so the user has a clue what's going on
last := blockChain[len(blockChain)-1] last := blockChain[len(blockChain)-1]
...@@ -824,27 +825,27 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain ...@@ -824,27 +825,27 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain
} }
// WriteBlock writes the block to the chain. // WriteBlock writes the block to the chain.
func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err error) { func (bc *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err error) {
self.wg.Add(1) bc.wg.Add(1)
defer self.wg.Done() defer bc.wg.Done()
// Calculate the total difficulty of the block // 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 { if ptd == nil {
return NonStatTy, consensus.ErrUnknownAncestor return NonStatTy, consensus.ErrUnknownAncestor
} }
// Make sure no inconsistent state is leaked during insertion // Make sure no inconsistent state is leaked during insertion
self.mu.Lock() bc.mu.Lock()
defer self.mu.Unlock() 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) externTd := new(big.Int).Add(block.Difficulty(), ptd)
// Irrelevant of the canonical status, write the block itself to the database // 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) 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) log.Crit("Failed to write block contents", "err", err)
} }
...@@ -853,25 +854,25 @@ func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, 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 // 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) { if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) {
// Reorganise the chain if the parent is not the head block // Reorganise the chain if the parent is not the head block
if block.ParentHash() != self.currentBlock.Hash() { if block.ParentHash() != bc.currentBlock.Hash() {
if err := self.reorg(self.currentBlock, block); err != nil { if err := bc.reorg(bc.currentBlock, block); err != nil {
return NonStatTy, err 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 status = CanonStatTy
} else { } else {
status = SideStatTy status = SideStatTy
} }
self.futureBlocks.Remove(block.Hash()) bc.futureBlocks.Remove(block.Hash())
return return
} }
// InsertChain will attempt to insert the given chain in to the canonical chain or, otherwise, create a fork. If an error is returned // 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). // 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 // Do a sanity check that the provided chain is actually ordered and linked
for i := 1; i < len(chain); i++ { for i := 1; i < len(chain); i++ {
if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() { 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) { ...@@ -884,11 +885,11 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
} }
} }
// Pre-checks passed, start the full block imports // Pre-checks passed, start the full block imports
self.wg.Add(1) bc.wg.Add(1)
defer self.wg.Done() defer bc.wg.Done()
self.chainmu.Lock() bc.chainmu.Lock()
defer self.chainmu.Unlock() defer bc.chainmu.Unlock()
// A queued approach to delivering events. This is generally // A queued approach to delivering events. This is generally
// faster than direct delivery and requires much less mutex // faster than direct delivery and requires much less mutex
...@@ -906,19 +907,19 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { ...@@ -906,19 +907,19 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
headers[i] = block.Header() headers[i] = block.Header()
seals[i] = true seals[i] = true
} }
abort, results := self.engine.VerifyHeaders(self, headers, seals) abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
defer close(abort) defer close(abort)
// Iterate over the blocks and insert when the verifier permits // Iterate over the blocks and insert when the verifier permits
for i, block := range chain { for i, block := range chain {
// If the chain is terminating, stop processing blocks // 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") log.Debug("Premature abort during blocks processing")
break break
} }
// If the header is a banned one, straight out abort // If the header is a banned one, straight out abort
if BadHashes[block.Hash()] { if BadHashes[block.Hash()] {
self.reportBlock(block, nil, ErrBlacklistedHash) bc.reportBlock(block, nil, ErrBlacklistedHash)
return i, ErrBlacklistedHash return i, ErrBlacklistedHash
} }
// Wait for the block's verification to complete // Wait for the block's verification to complete
...@@ -926,7 +927,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { ...@@ -926,7 +927,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
err := <-results err := <-results
if err == nil { if err == nil {
err = self.Validator().ValidateBody(block) err = bc.Validator().ValidateBody(block)
} }
if err != nil { if err != nil {
if err == ErrKnownBlock { if err == ErrKnownBlock {
...@@ -942,46 +943,46 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { ...@@ -942,46 +943,46 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
if block.Time().Cmp(max) > 0 { if block.Time().Cmp(max) > 0 {
return i, fmt.Errorf("future block: %v > %v", block.Time(), max) 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++ stats.queued++
continue continue
} }
if err == consensus.ErrUnknownAncestor && self.futureBlocks.Contains(block.ParentHash()) { if err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(block.ParentHash()) {
self.futureBlocks.Add(block.Hash(), block) bc.futureBlocks.Add(block.Hash(), block)
stats.queued++ stats.queued++
continue continue
} }
self.reportBlock(block, nil, err) bc.reportBlock(block, nil, err)
return i, err return i, err
} }
// Create a new statedb using the parent block and report an // Create a new statedb using the parent block and report an
// error if it fails. // error if it fails.
switch { switch {
case i == 0: 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: default:
err = self.stateCache.Reset(chain[i-1].Root()) err = bc.stateCache.Reset(chain[i-1].Root())
} }
if err != nil { if err != nil {
self.reportBlock(block, nil, err) bc.reportBlock(block, nil, err)
return i, err return i, err
} }
// Process block using the parent state as reference point. // 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 { if err != nil {
self.reportBlock(block, receipts, err) bc.reportBlock(block, receipts, err)
return i, err return i, err
} }
// Validate the state using the default validator // 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 { if err != nil {
self.reportBlock(block, receipts, err) bc.reportBlock(block, receipts, err)
return i, err return i, err
} }
// Write state changes to database // 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 { if err != nil {
return i, err return i, err
} }
...@@ -989,12 +990,12 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { ...@@ -989,12 +990,12 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
// coalesce logs for later processing // coalesce logs for later processing
coalescedLogs = append(coalescedLogs, logs...) 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 return i, err
} }
// write the block to the chain and get the status // write the block to the chain and get the status
status, err := self.WriteBlock(block) status, err := bc.WriteBlock(block)
if err != nil { if err != nil {
return i, err return i, err
} }
...@@ -1008,19 +1009,19 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { ...@@ -1008,19 +1009,19 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
events = append(events, ChainEvent{block, block.Hash(), logs}) events = append(events, ChainEvent{block, block.Hash(), logs})
// This puts transactions in a extra db for rpc // 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 return i, err
} }
// store the receipts // store the receipts
if err := WriteReceipts(self.chainDb, receipts); err != nil { if err := WriteReceipts(bc.chainDb, receipts); err != nil {
return i, err return i, err
} }
// Write map map bloom filters // 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 return i, err
} }
// Write hash preimages // 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 return i, err
} }
case SideStatTy: case SideStatTy:
...@@ -1034,7 +1035,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { ...@@ -1034,7 +1035,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
stats.usedGas += usedGas.Uint64() stats.usedGas += usedGas.Uint64()
stats.report(chain, i) stats.report(chain, i)
} }
go self.postChainEvents(events, coalescedLogs) go bc.postChainEvents(events, coalescedLogs)
return 0, nil return 0, nil
} }
...@@ -1092,7 +1093,7 @@ func countTransactions(chain []*types.Block) (c int) { ...@@ -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 // 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 // to be part of the new canonical chain and accumulates potential missing transactions and post an
// event about them // event about them
func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
var ( var (
newChain types.Blocks newChain types.Blocks
oldChain types.Blocks oldChain types.Blocks
...@@ -1104,7 +1105,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { ...@@ -1104,7 +1105,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
// These logs are later announced as deleted. // These logs are later announced as deleted.
collectLogs = func(h common.Hash) { collectLogs = func(h common.Hash) {
// Coalesce logs and set 'Removed'. // 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 _, receipt := range receipts {
for _, log := range receipt.Logs { for _, log := range receipt.Logs {
del := *log del := *log
...@@ -1118,7 +1119,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { ...@@ -1118,7 +1119,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
// first reduce whoever is higher bound // first reduce whoever is higher bound
if oldBlock.NumberU64() > newBlock.NumberU64() { if oldBlock.NumberU64() > newBlock.NumberU64() {
// reduce old chain // 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) oldChain = append(oldChain, oldBlock)
deletedTxs = append(deletedTxs, oldBlock.Transactions()...) deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
...@@ -1126,7 +1127,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { ...@@ -1126,7 +1127,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
} }
} else { } else {
// reduce new chain and append new chain blocks for inserting later on // 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) newChain = append(newChain, newBlock)
} }
} }
...@@ -1148,7 +1149,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { ...@@ -1148,7 +1149,7 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
deletedTxs = append(deletedTxs, oldBlock.Transactions()...) deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
collectLogs(oldBlock.Hash()) 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 { if oldBlock == nil {
return fmt.Errorf("Invalid old chain") return fmt.Errorf("Invalid old chain")
} }
...@@ -1168,21 +1169,21 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { ...@@ -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()) log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash())
} }
var addedTxs types.Transactions 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 { for _, block := range newChain {
// insert the block in the canonical way, re-writing history // insert the block in the canonical way, re-writing history
self.insert(block) bc.insert(block)
// write canonical receipts and transactions // write canonical receipts and transactions
if err := WriteTransactions(self.chainDb, block); err != nil { if err := WriteTransactions(bc.chainDb, block); err != nil {
return err return err
} }
receipts := GetBlockReceipts(self.chainDb, block.Hash(), block.NumberU64()) receipts := GetBlockReceipts(bc.chainDb, block.Hash(), block.NumberU64())
// write receipts // write receipts
if err := WriteReceipts(self.chainDb, receipts); err != nil { if err := WriteReceipts(bc.chainDb, receipts); err != nil {
return err return err
} }
// Write map map bloom filters // 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 return err
} }
addedTxs = append(addedTxs, block.Transactions()...) addedTxs = append(addedTxs, block.Transactions()...)
...@@ -1193,22 +1194,22 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { ...@@ -1193,22 +1194,22 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
// When transactions get deleted from the database that means the // When transactions get deleted from the database that means the
// receipts that were created in the fork must also be deleted // receipts that were created in the fork must also be deleted
for _, tx := range diff { for _, tx := range diff {
DeleteReceipt(self.chainDb, tx.Hash()) DeleteReceipt(bc.chainDb, tx.Hash())
DeleteTransaction(self.chainDb, tx.Hash()) DeleteTransaction(bc.chainDb, tx.Hash())
} }
// Must be posted in a goroutine because of the transaction pool trying // Must be posted in a goroutine because of the transaction pool trying
// to acquire the chain manager lock // to acquire the chain manager lock
if len(diff) > 0 { if len(diff) > 0 {
go self.eventMux.Post(RemovedTransactionEvent{diff}) go bc.eventMux.Post(RemovedTransactionEvent{diff})
} }
if len(deletedLogs) > 0 { if len(deletedLogs) > 0 {
go self.eventMux.Post(RemovedLogsEvent{deletedLogs}) go bc.eventMux.Post(RemovedLogsEvent{deletedLogs})
} }
if len(oldChain) > 0 { if len(oldChain) > 0 {
go func() { go func() {
for _, block := range oldChain { 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 { ...@@ -1218,30 +1219,30 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
// postChainEvents iterates over the events generated by a chain insertion and // postChainEvents iterates over the events generated by a chain insertion and
// posts them into the event mux. // 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 // post event logs for further processing
self.eventMux.Post(logs) bc.eventMux.Post(logs)
for _, event := range events { for _, event := range events {
if event, ok := event.(ChainEvent); ok { if event, ok := event.(ChainEvent); ok {
// We need some control over the mining operation. Acquiring locks and waiting // 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 // for the miner to create new block takes too long and in most cases isn't
// even necessary. // even necessary.
if self.LastBlockHash() == event.Hash { if bc.LastBlockHash() == event.Hash {
self.eventMux.Post(ChainHeadEvent{event.Block}) bc.eventMux.Post(ChainHeadEvent{event.Block})
} }
} }
// Fire the insertion events individually too // 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) futureTimer := time.Tick(5 * time.Second)
for { for {
select { select {
case <-futureTimer: case <-futureTimer:
self.procFutureBlocks() bc.procFutureBlocks()
case <-self.quit: case <-bc.quit:
return return
} }
} }
...@@ -1299,28 +1300,28 @@ Error: %v ...@@ -1299,28 +1300,28 @@ Error: %v
// should be done or not. The reason behind the optional check is because some // 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 // of the header retrieval mechanisms already need to verify nonces, as well as
// because nonces can be verified sparsely, not needing to check each. // 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() 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 return i, err
} }
// Make sure only one thread manipulates the chain at once // Make sure only one thread manipulates the chain at once
self.chainmu.Lock() bc.chainmu.Lock()
defer self.chainmu.Unlock() defer bc.chainmu.Unlock()
self.wg.Add(1) bc.wg.Add(1)
defer self.wg.Done() defer bc.wg.Done()
whFunc := func(header *types.Header) error { whFunc := func(header *types.Header) error {
self.mu.Lock() bc.mu.Lock()
defer self.mu.Unlock() defer bc.mu.Unlock()
_, err := self.hc.WriteHeader(header) _, err := bc.hc.WriteHeader(header)
return err 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 // 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) ...@@ -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 // without the real blocks. Hence, writing headers directly should only be done
// in two scenarios: pure-header mode of operation (light clients), or properly // in two scenarios: pure-header mode of operation (light clients), or properly
// separated header/block phases (non-archive clients). // separated header/block phases (non-archive clients).
func (self *BlockChain) writeHeader(header *types.Header) error { func (bc *BlockChain) writeHeader(header *types.Header) error {
self.wg.Add(1) bc.wg.Add(1)
defer self.wg.Done() defer bc.wg.Done()
self.mu.Lock() bc.mu.Lock()
defer self.mu.Unlock() defer bc.mu.Unlock()
_, err := self.hc.WriteHeader(header) _, err := bc.hc.WriteHeader(header)
return err return err
} }
// CurrentHeader retrieves the current head header of the canonical chain. The // CurrentHeader retrieves the current head header of the canonical chain. The
// header is retrieved from the HeaderChain's internal cache. // header is retrieved from the HeaderChain's internal cache.
func (self *BlockChain) CurrentHeader() *types.Header { func (bc *BlockChain) CurrentHeader() *types.Header {
self.mu.RLock() bc.mu.RLock()
defer self.mu.RUnlock() 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 // GetTd retrieves a block's total difficulty in the canonical chain from the
// database by hash and number, caching it if found. // database by hash and number, caching it if found.
func (self *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int {
return self.hc.GetTd(hash, number) return bc.hc.GetTd(hash, number)
} }
// GetTdByHash retrieves a block's total difficulty in the canonical chain from the // GetTdByHash retrieves a block's total difficulty in the canonical chain from the
// database by hash, caching it if found. // database by hash, caching it if found.
func (self *BlockChain) GetTdByHash(hash common.Hash) *big.Int { func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int {
return self.hc.GetTdByHash(hash) return bc.hc.GetTdByHash(hash)
} }
// 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 (self *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header {
return self.hc.GetHeader(hash, number) return bc.hc.GetHeader(hash, number)
} }
// GetHeaderByHash retrieves a block header from the database by hash, caching it if // GetHeaderByHash retrieves a block header from the database by hash, caching it if
// found. // found.
func (self *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
return self.hc.GetHeaderByHash(hash) return bc.hc.GetHeaderByHash(hash)
} }
// HasHeader checks if a block header is present in the database or not, caching // 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 { ...@@ -1384,18 +1385,18 @@ func (bc *BlockChain) HasHeader(hash common.Hash) bool {
// GetBlockHashesFromHash retrieves a number of block hashes starting at a given // GetBlockHashesFromHash retrieves a number of block hashes starting at a given
// hash, fetching towards the genesis block. // hash, fetching towards the genesis block.
func (self *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash {
return self.hc.GetBlockHashesFromHash(hash, max) return bc.hc.GetBlockHashesFromHash(hash, max)
} }
// GetHeaderByNumber retrieves a block header from the database by number, // GetHeaderByNumber retrieves a block header from the database by number,
// caching it (associated with its hash) if found. // caching it (associated with its hash) if found.
func (self *BlockChain) GetHeaderByNumber(number uint64) *types.Header { func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
return self.hc.GetHeaderByNumber(number) return bc.hc.GetHeaderByNumber(number)
} }
// Config retrieves the blockchain's chain configuration. // 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. // 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 }
...@@ -18,7 +18,7 @@ package core ...@@ -18,7 +18,7 @@ package core
import "github.com/ethereum/go-ethereum/common" import "github.com/ethereum/go-ethereum/common"
// Set of manually tracked bad hashes (usually hard forks) // BadHashes represent a set of manually tracked bad hashes (usually hard forks)
var BadHashes = map[common.Hash]bool{ var BadHashes = map[common.Hash]bool{
common.HexToHash("05bef30ef572270f654746da22639a7a0c97dd97a7050b9e252391996aaeb689"): true, common.HexToHash("05bef30ef572270f654746da22639a7a0c97dd97a7050b9e252391996aaeb689"): true,
common.HexToHash("7d05d08cbc596a2e5e4f13b80a743e53e09221b5323c3a61946b20873e58583f"): true, common.HexToHash("7d05d08cbc596a2e5e4f13b80a743e53e09221b5323c3a61946b20873e58583f"): true,
......
...@@ -98,10 +98,10 @@ func (b *BlockGen) Number() *big.Int { ...@@ -98,10 +98,10 @@ func (b *BlockGen) Number() *big.Int {
return new(big.Int).Set(b.header.Number) return new(big.Int).Set(b.header.Number)
} }
// AddUncheckedReceipts forcefully adds a receipts to the block without a // AddUncheckedReceipt forcefully adds a receipts to the block without a
// backing transaction. // backing transaction.
// //
// AddUncheckedReceipts will cause consensus failures when used during real // AddUncheckedReceipt will cause consensus failures when used during real
// chain processing. This is best used in conjunction with raw block insertion. // chain processing. This is best used in conjunction with raw block insertion.
func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt) { func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt) {
b.receipts = append(b.receipts, receipt) b.receipts = append(b.receipts, receipt)
......
...@@ -64,7 +64,7 @@ var ( ...@@ -64,7 +64,7 @@ var (
oldBlockReceiptsPrefix = []byte("receipts-block-") oldBlockReceiptsPrefix = []byte("receipts-block-")
oldBlockHashPrefix = []byte("block-hash-") // [deprecated by the header/block split, remove eventually] oldBlockHashPrefix = []byte("block-hash-") // [deprecated by the header/block split, remove eventually]
ChainConfigNotFoundErr = errors.New("ChainConfig not found") // general config not found error ErrChainConfigNotFound = errors.New("ChainConfig not found") // general config not found error
mipmapBloomMu sync.Mutex // protect against race condition when updating mipmap blooms mipmapBloomMu sync.Mutex // protect against race condition when updating mipmap blooms
...@@ -546,7 +546,7 @@ func mipmapKey(num, level uint64) []byte { ...@@ -546,7 +546,7 @@ func mipmapKey(num, level uint64) []byte {
return append(mipmapPre, append(lkey, key.Bytes()...)...) return append(mipmapPre, append(lkey, key.Bytes()...)...)
} }
// WriteMapmapBloom writes each address included in the receipts' logs to the // WriteMipmapBloom writes each address included in the receipts' logs to the
// MIP bloom bin. // MIP bloom bin.
func WriteMipmapBloom(db ethdb.Database, number uint64, receipts types.Receipts) error { func WriteMipmapBloom(db ethdb.Database, number uint64, receipts types.Receipts) error {
mipmapBloomMu.Lock() mipmapBloomMu.Lock()
...@@ -638,7 +638,7 @@ func WriteChainConfig(db ethdb.Database, hash common.Hash, cfg *params.ChainConf ...@@ -638,7 +638,7 @@ func WriteChainConfig(db ethdb.Database, hash common.Hash, cfg *params.ChainConf
func GetChainConfig(db ethdb.Database, hash common.Hash) (*params.ChainConfig, error) { func GetChainConfig(db ethdb.Database, hash common.Hash) (*params.ChainConfig, error) {
jsonChainConfig, _ := db.Get(append(configPrefix, hash[:]...)) jsonChainConfig, _ := db.Get(append(configPrefix, hash[:]...))
if len(jsonChainConfig) == 0 { if len(jsonChainConfig) == 0 {
return nil, ChainConfigNotFoundErr return nil, ErrChainConfigNotFound
} }
var config params.ChainConfig var config params.ChainConfig
......
...@@ -41,7 +41,7 @@ type NewMinedBlockEvent struct{ Block *types.Block } ...@@ -41,7 +41,7 @@ type NewMinedBlockEvent struct{ Block *types.Block }
// RemovedTransactionEvent is posted when a reorg happens // RemovedTransactionEvent is posted when a reorg happens
type RemovedTransactionEvent struct{ Txs types.Transactions } type RemovedTransactionEvent struct{ Txs types.Transactions }
// RemovedLogEvent is posted when a reorg happens // RemovedLogsEvent is posted when a reorg happens
type RemovedLogsEvent struct{ Logs []*types.Log } type RemovedLogsEvent struct{ Logs []*types.Log }
type ChainEvent struct { type ChainEvent struct {
......
...@@ -20,4 +20,4 @@ import ( ...@@ -20,4 +20,4 @@ import (
"math/big" "math/big"
) )
var BlockReward *big.Int = big.NewInt(5e+18) var BlockReward = big.NewInt(5e+18)
...@@ -133,7 +133,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig ...@@ -133,7 +133,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
newcfg := genesis.configOrDefault(stored) newcfg := genesis.configOrDefault(stored)
storedcfg, err := GetChainConfig(db, stored) storedcfg, err := GetChainConfig(db, stored)
if err != nil { if err != nil {
if err == ChainConfigNotFoundErr { if err == ErrChainConfigNotFound {
// This case happens if a genesis write was interrupted. // This case happens if a genesis write was interrupted.
log.Warn("Found genesis block without chain config") log.Warn("Found genesis block without chain config")
err = WriteChainConfig(db, stored, newcfg) err = WriteChainConfig(db, stored, newcfg)
......
...@@ -201,15 +201,6 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er ...@@ -201,15 +201,6 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
// header writes should be protected by the parent chain mutex individually. // header writes should be protected by the parent chain mutex individually.
type WhCallback func(*types.Header) error type WhCallback func(*types.Header) error
// InsertHeaderChain attempts to insert the given header chain in to the local
// chain, possibly creating a reorg. If an error is returned, it will return the
// index number of the failing header as well an error describing what went wrong.
//
// The verify parameter can be used to fine tune whether nonce verification
// should be done or not. The reason behind the optional check is because some
// of the header retrieval mechanisms already need to verfy nonces, as well as
// because nonces can be verified sparsely, not needing to check each.
func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) { func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) {
// Do a sanity check that the provided chain is actually ordered and linked // Do a sanity check that the provided chain is actually ordered and linked
for i := 1; i < len(chain); i++ { for i := 1; i < len(chain); i++ {
...@@ -257,6 +248,14 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) ...@@ -257,6 +248,14 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int)
return 0, nil return 0, nil
} }
// InsertHeaderChain attempts to insert the given header chain in to the local
// chain, possibly creating a reorg. If an error is returned, it will return the
// index number of the failing header as well an error describing what went wrong.
//
// The verify parameter can be used to fine tune whether nonce verification
// should be done or not. The reason behind the optional check is because some
// of the header retrieval mechanisms already need to verfy nonces, as well as
// because nonces can be verified sparsely, not needing to check each.
func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, writeHeader WhCallback, start time.Time) (int, error) { func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, writeHeader WhCallback, start time.Time) (int, error) {
// Collect some import statistics to report on // Collect some import statistics to report on
stats := struct{ processed, ignored int }{} stats := struct{ processed, ignored int }{}
......
...@@ -21,8 +21,6 @@ import ( ...@@ -21,8 +21,6 @@ import (
"fmt" "fmt"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
// "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
) )
...@@ -38,24 +36,24 @@ type TestManager struct { ...@@ -38,24 +36,24 @@ type TestManager struct {
Blocks []*types.Block Blocks []*types.Block
} }
func (s *TestManager) IsListening() bool { func (tm *TestManager) IsListening() bool {
return false return false
} }
func (s *TestManager) IsMining() bool { func (tm *TestManager) IsMining() bool {
return false return false
} }
func (s *TestManager) PeerCount() int { func (tm *TestManager) PeerCount() int {
return 0 return 0
} }
func (s *TestManager) Peers() *list.List { func (tm *TestManager) Peers() *list.List {
return list.New() return list.New()
} }
func (s *TestManager) BlockChain() *BlockChain { func (tm *TestManager) BlockChain() *BlockChain {
return s.blockChain return tm.blockChain
} }
func (tm *TestManager) TxPool() *TxPool { func (tm *TestManager) TxPool() *TxPool {
......
...@@ -134,112 +134,113 @@ func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, erro ...@@ -134,112 +134,113 @@ func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, erro
return ret, gasUsed, err return ret, gasUsed, err
} }
func (self *StateTransition) from() vm.AccountRef { func (st *StateTransition) from() vm.AccountRef {
f := self.msg.From() f := st.msg.From()
if !self.state.Exist(f) { if !st.state.Exist(f) {
self.state.CreateAccount(f) st.state.CreateAccount(f)
} }
return vm.AccountRef(f) return vm.AccountRef(f)
} }
func (self *StateTransition) to() vm.AccountRef { func (st *StateTransition) to() vm.AccountRef {
if self.msg == nil { if st.msg == nil {
return vm.AccountRef{} return vm.AccountRef{}
} }
to := self.msg.To() to := st.msg.To()
if to == nil { if to == nil {
return vm.AccountRef{} // contract creation return vm.AccountRef{} // contract creation
} }
reference := vm.AccountRef(*to) reference := vm.AccountRef(*to)
if !self.state.Exist(*to) { if !st.state.Exist(*to) {
self.state.CreateAccount(*to) st.state.CreateAccount(*to)
} }
return reference return reference
} }
func (self *StateTransition) useGas(amount uint64) error { func (st *StateTransition) useGas(amount uint64) error {
if self.gas < amount { if st.gas < amount {
return vm.ErrOutOfGas return vm.ErrOutOfGas
} }
self.gas -= amount st.gas -= amount
return nil return nil
} }
func (self *StateTransition) buyGas() error { func (st *StateTransition) buyGas() error {
mgas := self.msg.Gas() mgas := st.msg.Gas()
if mgas.BitLen() > 64 { if mgas.BitLen() > 64 {
return vm.ErrOutOfGas return vm.ErrOutOfGas
} }
mgval := new(big.Int).Mul(mgas, self.gasPrice) mgval := new(big.Int).Mul(mgas, st.gasPrice)
var ( var (
state = self.state state = st.state
sender = self.from() sender = st.from()
) )
if state.GetBalance(sender.Address()).Cmp(mgval) < 0 { if state.GetBalance(sender.Address()).Cmp(mgval) < 0 {
return errInsufficientBalanceForGas return errInsufficientBalanceForGas
} }
if err := self.gp.SubGas(mgas); err != nil { if err := st.gp.SubGas(mgas); err != nil {
return err return err
} }
self.gas += mgas.Uint64() st.gas += mgas.Uint64()
self.initialGas.Set(mgas) st.initialGas.Set(mgas)
state.SubBalance(sender.Address(), mgval) state.SubBalance(sender.Address(), mgval)
return nil return nil
} }
func (self *StateTransition) preCheck() error { func (st *StateTransition) preCheck() error {
msg := self.msg msg := st.msg
sender := self.from() sender := st.from()
// Make sure this transaction's nonce is correct // Make sure this transaction's nonce is correct
if msg.CheckNonce() { if msg.CheckNonce() {
if n := self.state.GetNonce(sender.Address()); n != msg.Nonce() { if n := st.state.GetNonce(sender.Address()); n != msg.Nonce() {
return fmt.Errorf("invalid nonce: have %d, expected %d", msg.Nonce(), n) return fmt.Errorf("invalid nonce: have %d, expected %d", msg.Nonce(), n)
} }
} }
return self.buyGas() return st.buyGas()
} }
// TransitionDb will transition the state by applying the current message and returning the result // TransitionDb will transition the state by applying the current message and returning the result
// including the required gas for the operation as well as the used gas. It returns an error if it // including the required gas for the operation as well as the used gas. It returns an error if it
// failed. An error indicates a consensus issue. // failed. An error indicates a consensus issue.
func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, err error) { func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, err error) {
if err = self.preCheck(); err != nil { if err = st.preCheck(); err != nil {
return return
} }
msg := self.msg msg := st.msg
sender := self.from() // err checked in preCheck sender := st.from() // err checked in preCheck
homestead := self.evm.ChainConfig().IsHomestead(self.evm.BlockNumber) homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber)
contractCreation := msg.To() == nil contractCreation := msg.To() == nil
// Pay intrinsic gas // Pay intrinsic gas
// TODO convert to uint64 // TODO convert to uint64
intrinsicGas := IntrinsicGas(self.data, contractCreation, homestead) intrinsicGas := IntrinsicGas(st.data, contractCreation, homestead)
if intrinsicGas.BitLen() > 64 { if intrinsicGas.BitLen() > 64 {
return nil, nil, nil, vm.ErrOutOfGas return nil, nil, nil, vm.ErrOutOfGas
} }
if err = self.useGas(intrinsicGas.Uint64()); err != nil { if err = st.useGas(intrinsicGas.Uint64()); err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
var ( var (
evm = self.evm evm = st.evm
// vm errors do not effect consensus and are therefor // vm errors do not effect consensus and are therefor
// not assigned to err, except for insufficient balance // not assigned to err, except for insufficient balance
// error. // error.
vmerr error vmerr error
) )
if contractCreation { if contractCreation {
ret, _, self.gas, vmerr = evm.Create(sender, self.data, self.gas, self.value) ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value)
} else { } else {
// Increment the nonce for the next transaction // Increment the nonce for the next transaction
self.state.SetNonce(sender.Address(), self.state.GetNonce(sender.Address())+1) st.state.SetNonce(sender.Address(), st.state.GetNonce(sender.Address())+1)
ret, self.gas, vmerr = evm.Call(sender, self.to().Address(), self.data, self.gas, self.value) ret, st.gas, vmerr = evm.Call(sender, st.to().Address(), st.data, st.gas, st.value)
} }
if vmerr != nil { if vmerr != nil {
log.Debug("VM returned with error", "err", err) log.Debug("VM returned with error", "err", err)
...@@ -250,33 +251,33 @@ func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *b ...@@ -250,33 +251,33 @@ func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *b
return nil, nil, nil, vmerr return nil, nil, nil, vmerr
} }
} }
requiredGas = new(big.Int).Set(self.gasUsed()) requiredGas = new(big.Int).Set(st.gasUsed())
self.refundGas() st.refundGas()
self.state.AddBalance(self.evm.Coinbase, new(big.Int).Mul(self.gasUsed(), self.gasPrice)) st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(st.gasUsed(), st.gasPrice))
return ret, requiredGas, self.gasUsed(), err return ret, requiredGas, st.gasUsed(), err
} }
func (self *StateTransition) refundGas() { func (st *StateTransition) refundGas() {
// Return eth for remaining gas to the sender account, // Return eth for remaining gas to the sender account,
// exchanged at the original rate. // exchanged at the original rate.
sender := self.from() // err already checked sender := st.from() // err already checked
remaining := new(big.Int).Mul(new(big.Int).SetUint64(self.gas), self.gasPrice) remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice)
self.state.AddBalance(sender.Address(), remaining) st.state.AddBalance(sender.Address(), remaining)
// Apply refund counter, capped to half of the used gas. // Apply refund counter, capped to half of the used gas.
uhalf := remaining.Div(self.gasUsed(), common.Big2) uhalf := remaining.Div(st.gasUsed(), common.Big2)
refund := math.BigMin(uhalf, self.state.GetRefund()) refund := math.BigMin(uhalf, st.state.GetRefund())
self.gas += refund.Uint64() st.gas += refund.Uint64()
self.state.AddBalance(sender.Address(), refund.Mul(refund, self.gasPrice)) st.state.AddBalance(sender.Address(), refund.Mul(refund, st.gasPrice))
// Also return remaining gas to the block gas counter so it is // Also return remaining gas to the block gas counter so it is
// available for the next transaction. // available for the next transaction.
self.gp.AddGas(new(big.Int).SetUint64(self.gas)) st.gp.AddGas(new(big.Int).SetUint64(st.gas))
} }
func (self *StateTransition) gasUsed() *big.Int { func (st *StateTransition) gasUsed() *big.Int {
return new(big.Int).Sub(self.initialGas, new(big.Int).SetUint64(self.gas)) return new(big.Int).Sub(st.initialGas, new(big.Int).SetUint64(st.gas))
} }
...@@ -209,6 +209,7 @@ func (pool *TxPool) resetState() { ...@@ -209,6 +209,7 @@ func (pool *TxPool) resetState() {
pool.promoteExecutables(currentState) pool.promoteExecutables(currentState)
} }
// Stop stops a TxPool
func (pool *TxPool) Stop() { func (pool *TxPool) Stop() {
pool.events.Unsubscribe() pool.events.Unsubscribe()
close(pool.quit) close(pool.quit)
...@@ -238,6 +239,7 @@ func (pool *TxPool) SetGasPrice(price *big.Int) { ...@@ -238,6 +239,7 @@ func (pool *TxPool) SetGasPrice(price *big.Int) {
log.Info("Transaction pool price threshold updated", "price", price) log.Info("Transaction pool price threshold updated", "price", price)
} }
// State returns the state of TxPool
func (pool *TxPool) State() *state.ManagedState { func (pool *TxPool) State() *state.ManagedState {
pool.mu.RLock() pool.mu.RLock()
defer pool.mu.RUnlock() defer pool.mu.RUnlock()
...@@ -850,22 +852,22 @@ func newTxSet() *txSet { ...@@ -850,22 +852,22 @@ func newTxSet() *txSet {
// contains returns true if the set contains the given transaction hash // contains returns true if the set contains the given transaction hash
// (not thread safe, should be called from a locked environment) // (not thread safe, should be called from a locked environment)
func (self *txSet) contains(hash common.Hash) bool { func (ts *txSet) contains(hash common.Hash) bool {
_, ok := self.txMap[hash] _, ok := ts.txMap[hash]
return ok return ok
} }
// add adds a transaction hash to the set, then removes entries older than txSetDuration // add adds a transaction hash to the set, then removes entries older than txSetDuration
// (not thread safe, should be called from a locked environment) // (not thread safe, should be called from a locked environment)
func (self *txSet) add(hash common.Hash) { func (ts *txSet) add(hash common.Hash) {
self.txMap[hash] = struct{}{} ts.txMap[hash] = struct{}{}
now := time.Now() now := time.Now()
self.txOrd[self.addPtr] = txOrdType{hash: hash, time: now} ts.txOrd[ts.addPtr] = txOrdType{hash: hash, time: now}
self.addPtr++ ts.addPtr++
delBefore := now.Add(-txSetDuration) delBefore := now.Add(-txSetDuration)
for self.delPtr < self.addPtr && self.txOrd[self.delPtr].time.Before(delBefore) { for ts.delPtr < ts.addPtr && ts.txOrd[ts.delPtr].time.Before(delBefore) {
delete(self.txMap, self.txOrd[self.delPtr].hash) delete(ts.txMap, ts.txOrd[ts.delPtr].hash)
delete(self.txOrd, self.delPtr) delete(ts.txOrd, ts.delPtr)
self.delPtr++ ts.delPtr++
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment