aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain/state_manager.go
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-06-27 01:55:14 +0800
committerobscuren <geffobscura@gmail.com>2014-06-27 01:55:14 +0800
commit9d5a3f013121c319f9cf679d9afc4e40661a0284 (patch)
treef57ecbea40ca0354bb050d70a10851669412a581 /ethchain/state_manager.go
parent3f1f8438ed8bf7b63ea5172090a5c7025cb093f0 (diff)
parenta98e6a262a21ff08c28495bab5180a1c15826d40 (diff)
downloadgo-tangerine-9d5a3f013121c319f9cf679d9afc4e40661a0284.tar
go-tangerine-9d5a3f013121c319f9cf679d9afc4e40661a0284.tar.gz
go-tangerine-9d5a3f013121c319f9cf679d9afc4e40661a0284.tar.bz2
go-tangerine-9d5a3f013121c319f9cf679d9afc4e40661a0284.tar.lz
go-tangerine-9d5a3f013121c319f9cf679d9afc4e40661a0284.tar.xz
go-tangerine-9d5a3f013121c319f9cf679d9afc4e40661a0284.tar.zst
go-tangerine-9d5a3f013121c319f9cf679d9afc4e40661a0284.zip
Merge branch 'release/0.5.15'
Diffstat (limited to 'ethchain/state_manager.go')
-rw-r--r--ethchain/state_manager.go73
1 files changed, 38 insertions, 35 deletions
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index 36ba1731c..312ba3084 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -3,7 +3,7 @@ package ethchain
import (
"bytes"
"container/list"
- "fmt"
+ "github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethwire"
"math/big"
@@ -11,6 +11,8 @@ import (
"time"
)
+var statelogger = ethlog.NewLogger("STATE")
+
type BlockProcessor interface {
ProcessBlock(block *Block)
}
@@ -120,7 +122,7 @@ done:
break done
default:
- ethutil.Config.Log.Infoln(err)
+ statelogger.Infoln(err)
}
}
@@ -143,72 +145,62 @@ done:
return receipts, handled, unhandled, err
}
-func (sm *StateManager) Process(block *Block, dontReact bool) error {
- if !sm.bc.HasBlock(block.PrevHash) {
- return ParentError(block.PrevHash)
- }
-
- parent := sm.bc.GetBlock(block.PrevHash)
-
- return sm.ProcessBlock(parent.State(), parent, block, dontReact)
-
-}
-
-// Block processing and validating with a given (temporarily) state
-func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontReact bool) (err error) {
+func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
// Processing a blocks may never happen simultaneously
sm.mutex.Lock()
defer sm.mutex.Unlock()
- hash := block.Hash()
- if sm.bc.HasBlock(hash) {
+ if sm.bc.HasBlock(block.Hash()) {
return nil
}
+ if !sm.bc.HasBlock(block.PrevHash) {
+ return ParentError(block.PrevHash)
+ }
+
+ var (
+ parent = sm.bc.GetBlock(block.PrevHash)
+ state = parent.State()
+ )
+
// Defer the Undo on the Trie. If the block processing happened
// we don't want to undo but since undo only happens on dirty
// nodes this won't happen because Commit would have been called
// before that.
defer state.Reset()
- // Check if we have the parent hash, if it isn't known we discard it
- // Reasons might be catching up or simply an invalid block
- if !sm.bc.HasBlock(block.PrevHash) && sm.bc.CurrentBlock != nil {
- return ParentError(block.PrevHash)
- }
-
- coinbase := state.GetOrNewStateObject(block.Coinbase)
- coinbase.SetGasPool(block.CalcGasLimit(parent))
-
- // Process the transactions on to current block
- receipts, _, _, _ := sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
+ receipts, err := sm.ApplyDiff(state, parent, block)
defer func() {
if err != nil {
if len(receipts) == len(block.Receipts()) {
for i, receipt := range block.Receipts() {
- ethutil.Config.Log.Debugf("diff (r) %v ~ %x <=> (c) %v ~ %x (%x)\n", receipt.CumulativeGasUsed, receipt.PostState[0:4], receipts[i].CumulativeGasUsed, receipts[i].PostState[0:4], receipt.Tx.Hash())
+ statelogger.Debugf("diff (r) %v ~ %x <=> (c) %v ~ %x (%x)\n", receipt.CumulativeGasUsed, receipt.PostState[0:4], receipts[i].CumulativeGasUsed, receipts[i].PostState[0:4], receipt.Tx.Hash())
}
} else {
- ethutil.Config.Log.Debugln("Unable to print receipt diff. Length didn't match", len(receipts), "for", len(block.Receipts()))
+ statelogger.Warnln("Unable to print receipt diff. Length didn't match", len(receipts), "for", len(block.Receipts()))
}
}
}()
+ if err != nil {
+ return err
+ }
+
// Block validation
if err = sm.ValidateBlock(block); err != nil {
- fmt.Println("[SM] Error validating block:", err)
+ statelogger.Errorln("Error validating block:", err)
return err
}
// I'm not sure, but I don't know if there should be thrown
// any errors at this time.
if err = sm.AccumelateRewards(state, block); err != nil {
- fmt.Println("[SM] Error accumulating reward", err)
+ statelogger.Errorln("Error accumulating reward", err)
return err
}
if !block.State().Cmp(state) {
- err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().trie.Root, state.trie.Root)
+ statelogger.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().trie.Root, state.trie.Root)
return
}
@@ -221,7 +213,7 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
sm.bc.Add(block)
sm.notifyChanges(state)
- ethutil.Config.Log.Infof("[STATE] Added block #%d (%x)\n", block.Number, block.Hash())
+ statelogger.Infof("Added block #%d (%x)\n", block.Number, block.Hash())
if dontReact == false {
sm.Ethereum.Reactor().Post("newBlock", block)
@@ -232,11 +224,22 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
sm.Ethereum.TxPool().RemoveInvalid(state)
} else {
- fmt.Println("total diff failed")
+ statelogger.Errorln("total diff failed")
}
return nil
}
+
+func (sm *StateManager) ApplyDiff(state *State, parent, block *Block) (receipts Receipts, err error) {
+ coinbase := state.GetOrNewStateObject(block.Coinbase)
+ coinbase.SetGasPool(block.CalcGasLimit(parent))
+
+ // Process the transactions on to current block
+ receipts, _, _, _ = sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
+
+ return receipts, nil
+}
+
func (sm *StateManager) CalculateTD(block *Block) bool {
uncleDiff := new(big.Int)
for _, uncle := range block.Uncles {