aboutsummaryrefslogtreecommitdiffstats
path: root/core/blockchain.go
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2016-03-08 22:55:27 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2016-03-11 16:52:36 +0800
commit558d18d2b036e4598babf65e12a4907da0946086 (patch)
treef5480b2c18eff98cc54e40371c65bcaa06ab6bf5 /core/blockchain.go
parent8b58cd01907ff4dffdca4e7fe250b7371a574b61 (diff)
downloadgo-tangerine-558d18d2b036e4598babf65e12a4907da0946086.tar
go-tangerine-558d18d2b036e4598babf65e12a4907da0946086.tar.gz
go-tangerine-558d18d2b036e4598babf65e12a4907da0946086.tar.bz2
go-tangerine-558d18d2b036e4598babf65e12a4907da0946086.tar.lz
go-tangerine-558d18d2b036e4598babf65e12a4907da0946086.tar.xz
go-tangerine-558d18d2b036e4598babf65e12a4907da0946086.tar.zst
go-tangerine-558d18d2b036e4598babf65e12a4907da0946086.zip
core: added future proc mutex lock
Added a future lock which prevents the anything being added or removed from or to the set when looping over the set of blocks. This fixes a nil pointer in the range loop when trying to retrieve a block from the set which was previously available but removed due to regular chain processing. Fixes #2305
Diffstat (limited to 'core/blockchain.go')
-rw-r--r--core/blockchain.go29
1 files changed, 15 insertions, 14 deletions
diff --git a/core/blockchain.go b/core/blockchain.go
index 83299ceec..1d161dbf1 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -85,10 +85,9 @@ type BlockChain struct {
eventMux *event.TypeMux
genesisBlock *types.Block
- mu sync.RWMutex
- chainmu sync.RWMutex
- tsmu sync.RWMutex
- procmu sync.RWMutex
+ mu sync.RWMutex // global mutex for locking chain operations
+ chainmu sync.RWMutex // blockchain insertion lock
+ procmu sync.RWMutex // block processor lock
checkpoint int // checkpoint counts towards the new checkpoint
currentBlock *types.Block // Current head of the block chain
@@ -99,15 +98,15 @@ type BlockChain struct {
blockCache *lru.Cache // Cache for the most recent entire blocks
futureBlocks *lru.Cache // future blocks are blocks added for later processing
- quit chan struct{}
- running int32 // running must be called automically
+ quit chan struct{} // blockchain quit channel
+ running int32 // running must be called automically
// procInterrupt must be atomically called
- procInterrupt int32 // interrupt signaler for block processing
- wg sync.WaitGroup
+ procInterrupt int32 // interrupt signaler for block processing
+ wg sync.WaitGroup // chain processing wait group for shutting down
pow pow.PoW
- processor Processor
- validator Validator
+ processor Processor // block processor interface
+ validator Validator // block and state validator interface
}
// NewBlockChain returns a fully initialised block chain using information
@@ -567,10 +566,11 @@ func (bc *BlockChain) Stop() {
}
func (self *BlockChain) procFutureBlocks() {
- blocks := make([]*types.Block, self.futureBlocks.Len())
- for i, hash := range self.futureBlocks.Keys() {
- block, _ := self.futureBlocks.Get(hash)
- blocks[i] = block.(*types.Block)
+ blocks := make([]*types.Block, 0, self.futureBlocks.Len())
+ for _, hash := range self.futureBlocks.Keys() {
+ if block, exist := self.futureBlocks.Get(hash); exist {
+ blocks = append(blocks, block.(*types.Block))
+ }
}
if len(blocks) > 0 {
types.BlockBy(types.Number).Sort(blocks)
@@ -794,6 +794,7 @@ func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err
if err := WriteBlock(self.chainDb, block); err != nil {
glog.Fatalf("filed to write block contents: %v", err)
}
+
self.futureBlocks.Remove(block.Hash())
return