aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ethchain/state.go5
-rw-r--r--ethchain/state_manager.go38
-rw-r--r--ethchain/state_object.go52
-rw-r--r--ethchain/state_transition.go17
-rw-r--r--ethchain/transaction.go8
-rw-r--r--ethchain/vm.go10
-rw-r--r--ethutil/config.go1
-rw-r--r--ethutil/value.go13
-rw-r--r--peer.go2
9 files changed, 77 insertions, 69 deletions
diff --git a/ethchain/state.go b/ethchain/state.go
index 8df79dcef..66c298b3c 100644
--- a/ethchain/state.go
+++ b/ethchain/state.go
@@ -145,7 +145,6 @@ func (self *State) Set(state *State) {
self.trie = state.trie
self.stateObjects = state.stateObjects
- //*self = *state
}
func (s *State) Root() interface{} {
@@ -212,9 +211,9 @@ func (self *State) Update() {
// Debug stuff
func (self *State) CreateOutputForDiff() {
for addr, stateObject := range self.stateObjects {
- fmt.Printf("0x%x 0x%x 0x%x 0x%x\n", addr, stateObject.state.Root(), stateObject.Amount.Bytes(), stateObject.Nonce)
+ fmt.Printf("%x %x %x %x\n", addr, stateObject.state.Root(), stateObject.Amount.Bytes(), stateObject.Nonce)
stateObject.state.EachStorage(func(addr string, value *ethutil.Value) {
- fmt.Printf("0x%x 0x%x\n", addr, value.Bytes())
+ fmt.Printf("%x %x\n", addr, value.Bytes())
})
}
}
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index 62fcda8a5..129b30ba6 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -148,10 +148,15 @@ done:
accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
+ original := block.Receipts()[i]
+ if !original.Cmp(receipt) {
+ return nil, nil, nil, fmt.Errorf("err diff #%d (r) %v ~ %x <=> (c) %v ~ %x (%x)\n", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], receipt.Tx.Hash())
+ }
+
receipts = append(receipts, receipt)
handled = append(handled, tx)
- if ethutil.Config.Diff {
+ if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
state.CreateOutputForDiff()
}
}
@@ -187,36 +192,11 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
// before that.
defer state.Reset()
- if ethutil.Config.Diff {
- fmt.Printf("## 0x%x 0x%x ##\n", block.Hash(), block.Number)
+ if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
+ fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
}
- receipts, err := sm.ApplyDiff(state, parent, block)
- defer func() {
- if err != nil {
- if len(receipts) == len(block.Receipts()) {
- for i, receipt := range block.Receipts() {
- statelogger.Infof("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 {
- statelogger.Warnln("Unable to print receipt diff. Length didn't match", len(receipts), "for", len(block.Receipts()))
- }
- } else {
- /*
- for i, receipt := range receipts {
- gu := new(big.Int)
- if i != 0 {
- gu.Sub(receipt.CumulativeGasUsed, receipts[i-1].CumulativeGasUsed)
- } else {
- gu.Set(receipt.CumulativeGasUsed)
- }
-
- statelogger.Infof("[r] %v ~ %x (%x)\n", gu, receipt.PostState[0:4], receipt.Tx.Hash())
- }
- */
- }
- }()
-
+ _, err = sm.ApplyDiff(state, parent, block)
if err != nil {
return err
}
diff --git a/ethchain/state_object.go b/ethchain/state_object.go
index ebc050863..5791c6ed1 100644
--- a/ethchain/state_object.go
+++ b/ethchain/state_object.go
@@ -15,6 +15,18 @@ func (self Code) String() string {
return strings.Join(Disassemble(self), " ")
}
+type Storage map[string]*ethutil.Value
+
+func (self Storage) Copy() Storage {
+ cpy := make(Storage)
+ for key, value := range self {
+ // XXX Do we need a 'value' copy or is this sufficient?
+ cpy[key] = value
+ }
+
+ return cpy
+}
+
type StateObject struct {
// Address of the object
address []byte
@@ -27,7 +39,7 @@ type StateObject struct {
script Code
initScript Code
- storage map[string]*ethutil.Value
+ storage Storage
// Total gas pool is the total amount of gas currently
// left if this object is the coinbase. Gas is directly
@@ -41,7 +53,8 @@ type StateObject struct {
}
func (self *StateObject) Reset() {
- self.storage = make(map[string]*ethutil.Value)
+ self.storage = make(Storage)
+ self.state.Reset()
}
// Converts an transaction in to a state object
@@ -66,7 +79,7 @@ func NewStateObject(addr []byte) *StateObject {
object := &StateObject{address: address, Amount: new(big.Int), gasPool: new(big.Int)}
object.state = NewState(ethtrie.NewTrie(ethutil.Config.Db, ""))
- object.storage = make(map[string]*ethutil.Value)
+ object.storage = make(Storage)
return object
}
@@ -95,7 +108,7 @@ func NewStateObjectFromBytes(address, data []byte) *StateObject {
func (self *StateObject) MarkForDeletion() {
self.remove = true
- statelogger.Infof("%x: #%d %v (deletion)\n", self.Address(), self.Nonce, self.Amount)
+ statelogger.DebugDetailf("%x: #%d %v (deletion)\n", self.Address(), self.Nonce, self.Amount)
}
func (c *StateObject) GetAddr(addr []byte) *ethutil.Value {
@@ -113,23 +126,24 @@ func (self *StateObject) SetStorage(key *big.Int, value *ethutil.Value) {
self.setStorage(key.Bytes(), value)
}
-func (self *StateObject) getStorage(key []byte) *ethutil.Value {
- k := ethutil.LeftPadBytes(key, 32)
+func (self *StateObject) getStorage(k []byte) *ethutil.Value {
+ key := ethutil.LeftPadBytes(k, 32)
- value := self.storage[string(k)]
+ value := self.storage[string(key)]
if value == nil {
- value = self.GetAddr(k)
+ value = self.GetAddr(key)
- self.storage[string(k)] = value
+ if !value.IsNil() {
+ self.storage[string(key)] = value
+ }
}
return value
}
-func (self *StateObject) setStorage(key []byte, value *ethutil.Value) {
- k := ethutil.LeftPadBytes(key, 32)
-
- self.storage[string(k)] = value
+func (self *StateObject) setStorage(k []byte, value *ethutil.Value) {
+ key := ethutil.LeftPadBytes(k, 32)
+ self.storage[string(key)] = value.Copy()
}
func (self *StateObject) Sync() {
@@ -140,9 +154,16 @@ func (self *StateObject) Sync() {
}
self.SetAddr([]byte(key), value)
+ }
+ valid, t2 := ethtrie.ParanoiaCheck(self.state.trie)
+ if !valid {
+ self.state.trie = t2
+
+ statelogger.Infoln("Warn: PARANOIA: Different state storage root during copy")
}
}
+
func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
if int64(len(c.script)-1) < pc.Int64() {
return ethutil.NewValue(0)
@@ -154,13 +175,13 @@ func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
func (c *StateObject) AddAmount(amount *big.Int) {
c.SetAmount(new(big.Int).Add(c.Amount, amount))
- statelogger.Infof("%x: #%d %v (+ %v)\n", c.Address(), c.Nonce, c.Amount, amount)
+ statelogger.DebugDetailf("%x: #%d %v (+ %v)\n", c.Address(), c.Nonce, c.Amount, amount)
}
func (c *StateObject) SubAmount(amount *big.Int) {
c.SetAmount(new(big.Int).Sub(c.Amount, amount))
- statelogger.Infof("%x: #%d %v (- %v)\n", c.Address(), c.Nonce, c.Amount, amount)
+ statelogger.DebugDetailf("%x: #%d %v (- %v)\n", c.Address(), c.Nonce, c.Amount, amount)
}
func (c *StateObject) SetAmount(amount *big.Int) {
@@ -222,6 +243,7 @@ func (self *StateObject) Copy() *StateObject {
}
stateObject.script = ethutil.CopyBytes(self.script)
stateObject.initScript = ethutil.CopyBytes(self.initScript)
+ stateObject.storage = self.storage.Copy()
return stateObject
}
diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go
index 314d858f2..8cface9e8 100644
--- a/ethchain/state_transition.go
+++ b/ethchain/state_transition.go
@@ -2,8 +2,6 @@ package ethchain
import (
"fmt"
- "github.com/ethereum/eth-go/ethtrie"
- "github.com/ethereum/eth-go/ethutil"
"math/big"
)
@@ -275,20 +273,5 @@ func (self *StateTransition) Eval(script []byte, context *StateObject, typ strin
func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error) {
ret, _, err = closure.Call(vm, data)
- if ethutil.Config.Paranoia {
- var (
- context = closure.object
- trie = context.state.trie
- )
-
- valid, t2 := ethtrie.ParanoiaCheck(trie)
- if !valid {
- // TODO FIXME ASAP
- context.state.trie = t2
-
- statelogger.Infoln("Warn: PARANOIA: Different state object roots during copy")
- }
- }
-
return
}
diff --git a/ethchain/transaction.go b/ethchain/transaction.go
index da3f9bcf2..5686a7edb 100644
--- a/ethchain/transaction.go
+++ b/ethchain/transaction.go
@@ -227,6 +227,14 @@ func (self *Receipt) String() string {
self.CumulativeGasUsed)
}
+func (self *Receipt) Cmp(other *Receipt) bool {
+ if bytes.Compare(self.PostState, other.PostState) != 0 {
+ return false
+ }
+
+ return true
+}
+
// Transaction slice type for basic sorting
type Transactions []*Transaction
diff --git a/ethchain/vm.go b/ethchain/vm.go
index f1794ff77..788bde886 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -184,7 +184,8 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
var mult *big.Int
y, x := stack.Peekn()
val := closure.GetStorage(x)
- if val.IsEmpty() && len(y.Bytes()) > 0 {
+ //if val.IsEmpty() && len(y.Bytes()) > 0 {
+ if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
mult = ethutil.Big2
} else if !val.IsEmpty() && len(y.Bytes()) == 0 {
mult = ethutil.Big0
@@ -482,7 +483,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
case ORIGIN:
stack.Push(ethutil.BigD(vm.vars.Origin))
- vm.Printf(" => %v", vm.vars.Origin)
+ vm.Printf(" => %x", vm.vars.Origin)
case CALLER:
caller := closure.caller.Address()
stack.Push(ethutil.BigD(caller))
@@ -550,10 +551,10 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
}
code := closure.Script[cOff : cOff+l]
- fmt.Println("len:", l, "code off:", cOff, "mem off:", mOff)
+ //fmt.Println("len:", l, "code off:", cOff, "mem off:", mOff)
mem.Set(mOff, l, code)
- fmt.Println(Code(mem.Get(mOff, l)))
+ //fmt.Println(Code(mem.Get(mOff, l)))
case GASPRICE:
stack.Push(closure.Price)
@@ -743,6 +744,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
if closure.object.Amount.Cmp(value) < 0 {
vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount)
+
closure.ReturnGas(gas, nil, nil)
stack.Push(ethutil.BigFalse)
diff --git a/ethutil/config.go b/ethutil/config.go
index 2f3d706fe..41bece21d 100644
--- a/ethutil/config.go
+++ b/ethutil/config.go
@@ -14,6 +14,7 @@ type ConfigManager struct {
ExecPath string
Debug bool
Diff bool
+ DiffType string
Paranoia bool
conf *globalconf.GlobalConf
diff --git a/ethutil/value.go b/ethutil/value.go
index b37b33c28..ecb9d1511 100644
--- a/ethutil/value.go
+++ b/ethutil/value.go
@@ -190,6 +190,19 @@ func (val *Value) Get(idx int) *Value {
return NewValue(nil)
}
+func (self *Value) Copy() *Value {
+ switch val := self.Val.(type) {
+ case *big.Int:
+ return NewValue(new(big.Int).Set(val))
+ case []byte:
+ return NewValue(CopyBytes(val))
+ default:
+ return NewValue(self.Val)
+ }
+
+ return nil
+}
+
func (val *Value) Cmp(o *Value) bool {
return reflect.DeepEqual(val.Val, o.Val)
}
diff --git a/peer.go b/peer.go
index 0a4f08af5..8c622aa5c 100644
--- a/peer.go
+++ b/peer.go
@@ -754,7 +754,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) {
if !p.catchingUp {
// Make sure nobody else is catching up when you want to do this
p.catchingUp = true
- msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(10)})
+ msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(30)})
p.QueueMessage(msg)
peerlogger.DebugDetailf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr())