aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/chain_manager.go33
-rw-r--r--core/state/managed_state.go4
-rw-r--r--miner/worker.go15
3 files changed, 41 insertions, 11 deletions
diff --git a/core/chain_manager.go b/core/chain_manager.go
index 721c008bc..ade922217 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -490,8 +490,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
block.Td = td
self.mu.Lock()
- cblock := self.currentBlock
{
+ cblock := self.currentBlock
// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
// not in the canonical chain.
self.write(block)
@@ -505,6 +505,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
if glog.V(logger.Info) {
glog.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, hash[:4], td, cblock.Header().Number, chash[:4], self.td)
}
+ // during split we merge two different chains and create the new canonical chain
+ self.merge(cblock, block)
queue[i] = ChainSplitEvent{block, logs}
queueEvent.splitCount++
@@ -553,6 +555,35 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
return nil
}
+// merge 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.
+func (self *ChainManager) merge(oldBlock, newBlock *types.Block) {
+ glog.V(logger.Debug).Infof("Applying diff to %x & %x\n", oldBlock.Hash().Bytes()[:4], newBlock.Hash().Bytes()[:4])
+
+ var oldChain, newChain types.Blocks
+ // First find the split (common ancestor) so we can perform an adequate merge
+ for {
+ oldBlock, newBlock = self.GetBlock(oldBlock.ParentHash()), self.GetBlock(newBlock.ParentHash())
+ if oldBlock.Hash() == newBlock.Hash() {
+ break
+ }
+ oldChain = append(oldChain, oldBlock)
+ newChain = append(newChain, newBlock)
+ }
+
+ // insert blocks
+ for _, block := range newChain {
+ self.insert(block)
+ }
+
+ if glog.V(logger.Detail) {
+ for i, oldBlock := range oldChain {
+ glog.Infof("- %.10v = %x\n", oldBlock.Number(), oldBlock.Hash())
+ glog.Infof("+ %.10v = %x\n", newChain[i].Number(), newChain[i].Hash())
+ }
+ }
+}
+
func (self *ChainManager) update() {
events := self.eventMux.Subscribe(queueEvent{})
futureTimer := time.NewTicker(5 * time.Second)
diff --git a/core/state/managed_state.go b/core/state/managed_state.go
index 9d2fc48e7..97d098039 100644
--- a/core/state/managed_state.go
+++ b/core/state/managed_state.go
@@ -52,8 +52,8 @@ func (ms *ManagedState) RemoveNonce(addr common.Address, n uint64) {
// NewNonce returns the new canonical nonce for the managed account
func (ms *ManagedState) NewNonce(addr common.Address) uint64 {
- ms.mu.RLock()
- defer ms.mu.RUnlock()
+ ms.mu.Lock()
+ defer ms.mu.Unlock()
account := ms.getAccount(addr)
for i, nonce := range account.nonces {
diff --git a/miner/worker.go b/miner/worker.go
index b74b67552..141294385 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -172,7 +172,7 @@ out:
case <-self.quit:
break out
case <-timer.C:
- if glog.V(logger.Debug) {
+ if glog.V(logger.Detail) && atomic.LoadInt64(&self.mining) == 1 {
glog.Infoln("Hash rate:", self.HashRate(), "Khash")
}
@@ -264,8 +264,8 @@ func (self *worker) commitNewWork() {
remove = set.New()
tcount = 0
)
-gasLimit:
- for i, tx := range transactions {
+ //gasLimit:
+ for _, tx := range transactions {
self.current.state.StartRecord(tx.Hash(), common.Hash{}, 0)
err := self.commitTransaction(tx)
@@ -276,14 +276,13 @@ gasLimit:
self.chain.TxState().RemoveNonce(from, tx.Nonce())
remove.Add(tx.Hash())
- if glog.V(logger.Debug) {
+ if glog.V(logger.Detail) {
glog.Infof("TX (%x) failed, will be removed: %v\n", tx.Hash().Bytes()[:4], err)
- glog.Infoln(tx)
+ //glog.Infoln(tx)
}
case state.IsGasLimitErr(err):
- glog.V(logger.Debug).Infof("Gas limit reached for block. %d TXs included in this block\n", i)
- // Break on gas limit
- break gasLimit
+ //glog.V(logger.Debug).Infof("Gas limit reached for block. %d TXs included in this block\n", i)
+ //break gasLimit
default:
tcount++
}