aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Wilcke <geffobscura@gmail.com>2015-06-30 17:14:43 +0800
committerJeffrey Wilcke <geffobscura@gmail.com>2015-06-30 17:14:43 +0800
commitd8fe64acaa94fc5a12e53cec110e57cace52ced9 (patch)
tree0ecce1385d1ed0e60ba69e8bc1234109c6c09b28
parent7625b07dd9a2a7b5c5a504c1276eea04596ac871 (diff)
downloadgo-tangerine-d8fe64acaa94fc5a12e53cec110e57cace52ced9.tar.gz
go-tangerine-d8fe64acaa94fc5a12e53cec110e57cace52ced9.tar.zst
go-tangerine-d8fe64acaa94fc5a12e53cec110e57cace52ced9.zip
core, miner: added queued write to WriteBlock
This fixes an issue with the lru cache not being available when calling WriteBlock. WriteBlock previously always assumed to be called from the InsertChain where the lru cache was always created prior to calling WriteBlock. When being called from the worker this could lead in to a nil pointer exception being thrown and causing database corruption.
-rw-r--r--core/chain_manager.go33
-rw-r--r--miner/worker.go2
2 files changed, 19 insertions, 16 deletions
diff --git a/core/chain_manager.go b/core/chain_manager.go
index 7c78b6bb7..808ccd201 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -364,14 +364,12 @@ func (bc *ChainManager) insert(block *types.Block) {
func (bc *ChainManager) write(block *types.Block) {
tstart := time.Now()
- go func() {
- enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block))
- key := append(blockHashPre, block.Hash().Bytes()...)
- err := bc.blockDb.Put(key, enc)
- if err != nil {
- glog.Fatal("db write fail:", err)
- }
- }()
+ enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block))
+ key := append(blockHashPre, block.Hash().Bytes()...)
+ err := bc.blockDb.Put(key, enc)
+ if err != nil {
+ glog.Fatal("db write fail:", err)
+ }
if glog.V(logger.Debug) {
glog.Infof("wrote block #%v %s. Took %v\n", block.Number(), common.PP(block.Hash().Bytes()), time.Since(tstart))
@@ -555,7 +553,8 @@ const (
sideStatTy
)
-func (self *ChainManager) WriteBlock(block *types.Block) (status writeStatus, err error) {
+// WriteBlock writes the block to the chain (or pending queue)
+func (self *ChainManager) WriteBlock(block *types.Block, queued bool) (status writeStatus, err error) {
self.wg.Add(1)
defer self.wg.Done()
@@ -587,11 +586,15 @@ func (self *ChainManager) WriteBlock(block *types.Block) (status writeStatus, er
status = sideStatTy
}
- // Write block to database. Eventually we'll have to improve on this and throw away blocks that are
- // not in the canonical chain.
- self.mu.Lock()
- self.enqueueForWrite(block)
- self.mu.Unlock()
+ if queued {
+ // Write block to database. Eventually we'll have to improve on this and throw away blocks that are
+ // not in the canonical chain.
+ self.mu.Lock()
+ self.enqueueForWrite(block)
+ self.mu.Unlock()
+ } else {
+ self.write(block)
+ }
// Delete from future blocks
self.futureBlocks.Remove(block.Hash())
@@ -693,7 +696,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
txcount += len(block.Transactions())
// write the block to the chain and get the status
- status, err := self.WriteBlock(block)
+ status, err := self.WriteBlock(block, true)
if err != nil {
return i, err
}
diff --git a/miner/worker.go b/miner/worker.go
index 0971bd957..f06b6afa1 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -233,7 +233,7 @@ func (self *worker) wait() {
continue
}
- _, err := self.chain.WriteBlock(block)
+ _, err := self.chain.WriteBlock(block, false)
if err != nil {
glog.V(logger.Error).Infoln("error writing block to chain", err)
continue