From 75ee3b3f089e703b728bb301cc6b2abe4c111c41 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 11 Nov 2014 12:16:36 +0100 Subject: debugging code --- state/log.go | 19 ++++++++++++++++++- state/state.go | 6 +++--- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'state') diff --git a/state/log.go b/state/log.go index 73039d7ce..e61a4186e 100644 --- a/state/log.go +++ b/state/log.go @@ -1,6 +1,11 @@ package state -import "github.com/ethereum/go-ethereum/ethutil" +import ( + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/ethutil" +) type Log struct { Address []byte @@ -26,6 +31,10 @@ func (self Log) RlpData() interface{} { return []interface{}{self.Address, ethutil.ByteSliceToInterface(self.Topics), self.Data} } +func (self Log) String() string { + return fmt.Sprintf(`log: %x %x %x`, self.Address, self.Topics, self.Data) +} + type Logs []Log func (self Logs) RlpData() interface{} { @@ -36,3 +45,11 @@ func (self Logs) RlpData() interface{} { return data } + +func (self Logs) String() string { + var logs []string + for _, log := range self { + logs = append(logs, log.String()) + } + return "[ " + strings.Join(logs, ", ") + " ]" +} diff --git a/state/state.go b/state/state.go index e1b73a6ab..8eb348dda 100644 --- a/state/state.go +++ b/state/state.go @@ -62,7 +62,7 @@ func (self *State) Refund(addr []byte, gas, price *big.Int) { self.refund[string(addr)] = new(big.Int) } - self.refund[string(addr)] = new(big.Int).Add(self.refund[string(addr)], amount) + self.refund[string(addr)].Add(self.refund[string(addr)], amount) } func (self *State) AddBalance(addr []byte, amount *big.Int) { @@ -237,8 +237,8 @@ func (self *State) Set(state *State) { self.logs = state.logs } -func (s *State) Root() interface{} { - return s.Trie.Root +func (s *State) Root() []byte { + return s.Trie.GetRoot() } // Resets the trie and all siblings -- cgit v1.2.3 From 6c9e503eb8d41d331d6a74e69539a06590072190 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 11 Nov 2014 22:51:26 +0100 Subject: Removed all implicit logging. Fixed gas issues and jump errors --- state/log.go | 10 +++++----- state/state.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'state') diff --git a/state/log.go b/state/log.go index e61a4186e..49da30535 100644 --- a/state/log.go +++ b/state/log.go @@ -13,8 +13,8 @@ type Log struct { Data []byte } -func NewLogFromValue(decoder *ethutil.Value) Log { - log := Log{ +func NewLogFromValue(decoder *ethutil.Value) *Log { + log := &Log{ Address: decoder.Get(0).Bytes(), Data: decoder.Get(2).Bytes(), } @@ -27,15 +27,15 @@ func NewLogFromValue(decoder *ethutil.Value) Log { return log } -func (self Log) RlpData() interface{} { +func (self *Log) RlpData() interface{} { return []interface{}{self.Address, ethutil.ByteSliceToInterface(self.Topics), self.Data} } -func (self Log) String() string { +func (self *Log) String() string { return fmt.Sprintf(`log: %x %x %x`, self.Address, self.Topics, self.Data) } -type Logs []Log +type Logs []*Log func (self Logs) RlpData() interface{} { data := make([]interface{}, len(self)) diff --git a/state/state.go b/state/state.go index 8eb348dda..e3012f019 100644 --- a/state/state.go +++ b/state/state.go @@ -37,7 +37,7 @@ func (self *State) EmptyLogs() { self.logs = nil } -func (self *State) AddLog(log Log) { +func (self *State) AddLog(log *Log) { self.logs = append(self.logs, log) } -- cgit v1.2.3 From 60cdb1148c404218846fd39331690658168f4e04 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 12 Nov 2014 01:36:36 +0100 Subject: Transaction execution fixes --- state/dump.go | 2 +- state/state.go | 2 +- state/state_object.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'state') diff --git a/state/dump.go b/state/dump.go index a7057b445..be3b362c4 100644 --- a/state/dump.go +++ b/state/dump.go @@ -22,7 +22,7 @@ type World struct { func (self *State) Dump() []byte { world := World{ - Root: ethutil.Bytes2Hex(self.Trie.Root.([]byte)), + Root: ethutil.Bytes2Hex(self.Trie.GetRoot()), Accounts: make(map[string]Account), } diff --git a/state/state.go b/state/state.go index e3012f019..3abf1545b 100644 --- a/state/state.go +++ b/state/state.go @@ -302,7 +302,7 @@ func (self *State) Update() { if deleted { valid, t2 := trie.ParanoiaCheck(self.Trie) if !valid { - statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.Trie.Root, t2.Root) + statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.Trie.GetRoot(), t2.GetRoot()) self.Trie = t2 } diff --git a/state/state_object.go b/state/state_object.go index dde058e12..5ce74c434 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -160,7 +160,7 @@ func (self *StateObject) Sync() { valid, t2 := trie.ParanoiaCheck(self.State.Trie) if !valid { - statelogger.Infof("Warn: PARANOIA: Different state storage root during copy %x vs %x\n", self.State.Trie.Root, t2.Root) + statelogger.Infof("Warn: PARANOIA: Different state storage root during copy %x vs %x\n", self.State.Root(), t2.GetRoot()) self.State.Trie = t2 } @@ -301,7 +301,7 @@ func (self *StateObject) CreateOutputForDiff() { // State object encoding methods func (c *StateObject) RlpEncode() []byte { - return ethutil.Encode([]interface{}{c.Nonce, c.balance, c.State.Trie.Root, c.CodeHash()}) + return ethutil.Encode([]interface{}{c.Nonce, c.balance, c.Root(), c.CodeHash()}) } func (c *StateObject) CodeHash() ethutil.Bytes { -- cgit v1.2.3 From 2a9fc7baa908d64ff1ddae44641024114d3ec88d Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 14 Nov 2014 15:01:52 -0600 Subject: Merge branch 'develop' of https://github.com/tgerring/go-ethereum --- state/main_test.go | 8 +++++++ state/state_test.go | 67 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 21 deletions(-) create mode 100644 state/main_test.go (limited to 'state') diff --git a/state/main_test.go b/state/main_test.go new file mode 100644 index 000000000..973a7c373 --- /dev/null +++ b/state/main_test.go @@ -0,0 +1,8 @@ +package state + +import ( + checker "gopkg.in/check.v1" + "testing" +) + +func Test(t *testing.T) { checker.TestingT(t) } diff --git a/state/state_test.go b/state/state_test.go index 737815e90..825d21fcc 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -1,36 +1,61 @@ package state import ( - "testing" + checker "gopkg.in/check.v1" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/trie" ) -var ZeroHash256 = make([]byte, 32) - -func TestSnapshot(t *testing.T) { - db, _ := ethdb.NewMemDatabase() - ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "") - ethutil.Config.Db = db - - state := New(trie.New(db, "")) - - stateObject := state.GetOrNewStateObject([]byte("aa")) +type StateSuite struct { + state *State +} - stateObject.SetStorage(ethutil.Big("0"), ethutil.NewValue(42)) +var _ = checker.Suite(&StateSuite{}) - snapshot := state.Copy() +// var ZeroHash256 = make([]byte, 32) - stateObject = state.GetStateObject([]byte("aa")) - stateObject.SetStorage(ethutil.Big("0"), ethutil.NewValue(43)) +func (s *StateSuite) TestDump(c *checker.C) { + key := []byte{0x01} + value := "foo" + node := []interface{}{key, value} + s.state.Trie.Put(node) + dump := s.state.Dump() + c.Assert(dump, checker.NotNil) +} - state.Set(snapshot) +func (s *StateSuite) SetUpTest(c *checker.C) { + db, _ := ethdb.NewMemDatabase() + ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "") + ethutil.Config.Db = db + s.state = New(trie.New(db, "")) +} - stateObject = state.GetStateObject([]byte("aa")) - res := stateObject.GetStorage(ethutil.Big("0")) - if !res.Cmp(ethutil.NewValue(42)) { - t.Error("Expected storage 0 to be 42", res) - } +func (s *StateSuite) TestSnapshot(c *checker.C) { + stateobjaddr := []byte("aa") + storageaddr := ethutil.Big("0") + data1 := ethutil.NewValue(42) + data2 := ethutil.NewValue(43) + + // get state object + stateObject := s.state.GetOrNewStateObject(stateobjaddr) + // set inital state object value + stateObject.SetStorage(storageaddr, data1) + // get snapshot of current state + snapshot := s.state.Copy() + + // get state object. is this strictly necessary? + stateObject = s.state.GetStateObject(stateobjaddr) + // set new state object value + stateObject.SetStorage(storageaddr, data2) + // restore snapshot + s.state.Set(snapshot) + + // get state object + stateObject = s.state.GetStateObject(stateobjaddr) + // get state storage value + res := stateObject.GetStorage(storageaddr) + + c.Assert(data1, checker.DeepEquals, res) } -- cgit v1.2.3 From ddca18638f1a81e730001ff7fda4581379094aa4 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 15 Nov 2014 20:21:55 -0600 Subject: update imports order per goimports --- state/main_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'state') diff --git a/state/main_test.go b/state/main_test.go index 973a7c373..f3d3f7e23 100644 --- a/state/main_test.go +++ b/state/main_test.go @@ -1,8 +1,9 @@ package state import ( - checker "gopkg.in/check.v1" "testing" + + checker "gopkg.in/check.v1" ) func Test(t *testing.T) { checker.TestingT(t) } -- cgit v1.2.3 From 14e2e488fdf0f4d6ed1a5a48ffbbe883faa7edb6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 19 Nov 2014 12:25:52 +0100 Subject: Added `chain` tests & minor fixes * Fork tests (equal and larger chains) * `chain.link` fields are now exported * moved debug function from state to dump.go --- state/dump.go | 8 ++++++++ state/state_object.go | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'state') diff --git a/state/dump.go b/state/dump.go index be3b362c4..186c6dd73 100644 --- a/state/dump.go +++ b/state/dump.go @@ -46,3 +46,11 @@ func (self *State) Dump() []byte { return json } + +// Debug stuff +func (self *StateObject) CreateOutputForDiff() { + fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.Nonce) + self.EachStorage(func(addr string, value *ethutil.Value) { + fmt.Printf("%x %x\n", addr, value.Bytes()) + }) +} diff --git a/state/state_object.go b/state/state_object.go index 5ce74c434..729e32ae4 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -287,14 +287,6 @@ func (self *StateObject) Root() []byte { return self.State.Trie.GetRoot() } -// Debug stuff -func (self *StateObject) CreateOutputForDiff() { - fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.Nonce) - self.EachStorage(func(addr string, value *ethutil.Value) { - fmt.Printf("%x %x\n", addr, value.Bytes()) - }) -} - // // Encoding // -- cgit v1.2.3 From e70529a97785012368e7e0d5b272cccab705e551 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 19 Nov 2014 15:05:08 +0100 Subject: Added new iterator and tests --- state/state_object.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'state') diff --git a/state/state_object.go b/state/state_object.go index 729e32ae4..f02d1b5ab 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -148,9 +148,7 @@ func (self *StateObject) EachStorage(cb trie.EachCallback) { func (self *StateObject) Sync() { for key, value := range self.storage { - if value.Len() == 0 { // value.BigInt().Cmp(ethutil.Big0) == 0 { - //data := self.getStorage([]byte(key)) - //fmt.Printf("deleting %x %x 0x%x\n", self.Address(), []byte(key), data) + if value.Len() == 0 { self.State.Trie.Delete(string(key)) continue } -- cgit v1.2.3 From c8d0f8adc5145f650ced3ad5c8c008eb4b4094e2 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 28 Nov 2014 21:20:32 +0100 Subject: Changed refund --- state/state.go | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'state') diff --git a/state/state.go b/state/state.go index 3abf1545b..0a7f717fe 100644 --- a/state/state.go +++ b/state/state.go @@ -23,14 +23,14 @@ type State struct { manifest *Manifest - refund map[string]*big.Int + refund map[string][]refund logs Logs } // Create a new state from a given trie func New(trie *trie.Trie) *State { - return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} + return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string][]refund)} } func (self *State) EmptyLogs() { @@ -55,14 +55,12 @@ func (self *State) GetBalance(addr []byte) *big.Int { return ethutil.Big0 } -func (self *State) Refund(addr []byte, gas, price *big.Int) { - amount := new(big.Int).Mul(gas, price) - - if self.refund[string(addr)] == nil { - self.refund[string(addr)] = new(big.Int) - } +type refund struct { + gas, price *big.Int +} - self.refund[string(addr)].Add(self.refund[string(addr)], amount) +func (self *State) Refund(addr []byte, gas, price *big.Int) { + self.refund[string(addr)] = append(self.refund[string(addr)], refund{gas, price}) } func (self *State) AddBalance(addr []byte, amount *big.Int) { @@ -276,15 +274,20 @@ func (s *State) Sync() { func (self *State) Empty() { self.stateObjects = make(map[string]*StateObject) - self.refund = make(map[string]*big.Int) + self.refund = make(map[string][]refund) } -func (self *State) Update() { +func (self *State) Update(gasUsed *big.Int) { var deleted bool // Refund any gas that's left - for addr, amount := range self.refund { - self.GetStateObject([]byte(addr)).AddBalance(amount) + uhalf := new(big.Int).Div(gasUsed, ethutil.Big2) + for addr, refs := range self.refund { + for _, ref := range refs { + refund := ethutil.BigMin(uhalf, ref.gas) + + self.GetStateObject([]byte(addr)).AddBalance(refund.Mul(refund, ref.price)) + } } for _, stateObject := range self.stateObjects { -- cgit v1.2.3 From 6dc46d3341dc5fa25bd005f9606de258874139be Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 1 Dec 2014 20:18:09 +0100 Subject: Changed the way transactions are being added to the transaction pool --- state/state.go | 3 ++- state/state_object.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'state') diff --git a/state/state.go b/state/state.go index 0a7f717fe..732a1192b 100644 --- a/state/state.go +++ b/state/state.go @@ -249,7 +249,6 @@ func (s *State) Reset() { continue } - //stateObject.state.Reset() stateObject.Reset() } @@ -281,6 +280,7 @@ func (self *State) Update(gasUsed *big.Int) { var deleted bool // Refund any gas that's left + // XXX THIS WILL CHANGE IN POC8 uhalf := new(big.Int).Div(gasUsed, ethutil.Big2) for addr, refs := range self.refund { for _, ref := range refs { @@ -289,6 +289,7 @@ func (self *State) Update(gasUsed *big.Int) { self.GetStateObject([]byte(addr)).AddBalance(refund.Mul(refund, ref.price)) } } + self.refund = make(map[string][]refund) for _, stateObject := range self.stateObjects { if stateObject.remove { diff --git a/state/state_object.go b/state/state_object.go index 5ce74c434..8aa126785 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -214,7 +214,7 @@ func (c *StateObject) ConvertGas(gas, price *big.Int) error { func (self *StateObject) SetGasPool(gasLimit *big.Int) { self.gasPool = new(big.Int).Set(gasLimit) - statelogger.DebugDetailf("%x: fuel (+ %v)", self.Address(), self.gasPool) + statelogger.Debugf("%x: gas (+ %v)", self.Address(), self.gasPool) } func (self *StateObject) BuyGas(gas, price *big.Int) error { -- cgit v1.2.3 From 99853ac3ce57807deb4822dd324186e1d2ee0821 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 3 Dec 2014 17:06:54 +0100 Subject: Moved execution from vm to chain. This moves call and create to the specified environments. Vms are no longer re-used. Vm uses environment's Call(Code) and Create in order to execute new contracts or transfer value between accounts. State transition now uses the same mechanism described above. --- state/state_object.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'state') diff --git a/state/state_object.go b/state/state_object.go index 47c882463..a56e91bc5 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -276,15 +276,14 @@ func (c *StateObject) Init() Code { return c.InitCode } -// To satisfy ClosureRef -func (self *StateObject) Object() *StateObject { - return self -} - func (self *StateObject) Root() []byte { return self.State.Trie.GetRoot() } +func (self *StateObject) SetCode(code []byte) { + self.Code = code +} + // // Encoding // -- cgit v1.2.3 From f298ffdbb8ec2b14f254e880a65f22f4d7c66305 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 4 Dec 2014 11:40:20 +0100 Subject: Renamed State => StateDB --- state/dump.go | 2 +- state/state.go | 68 +++++++++++++++++++++++++-------------------------- state/state_object.go | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) (limited to 'state') diff --git a/state/dump.go b/state/dump.go index 186c6dd73..c1f5ecf3a 100644 --- a/state/dump.go +++ b/state/dump.go @@ -20,7 +20,7 @@ type World struct { Accounts map[string]Account `json:"accounts"` } -func (self *State) Dump() []byte { +func (self *StateDB) Dump() []byte { world := World{ Root: ethutil.Bytes2Hex(self.Trie.GetRoot()), Accounts: make(map[string]Account), diff --git a/state/state.go b/state/state.go index 732a1192b..39c5f33cc 100644 --- a/state/state.go +++ b/state/state.go @@ -10,12 +10,12 @@ import ( var statelogger = logger.NewLogger("STATE") -// States within the ethereum protocol are used to store anything -// within the merkle trie. States take care of caching and storing +// StateDBs within the ethereum protocol are used to store anything +// within the merkle trie. StateDBs take care of caching and storing // nested states. It's the general query interface to retrieve: // * Contracts // * Accounts -type State struct { +type StateDB struct { // The trie for this structure Trie *trie.Trie @@ -29,24 +29,24 @@ type State struct { } // Create a new state from a given trie -func New(trie *trie.Trie) *State { - return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string][]refund)} +func New(trie *trie.Trie) *StateDB { + return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string][]refund)} } -func (self *State) EmptyLogs() { +func (self *StateDB) EmptyLogs() { self.logs = nil } -func (self *State) AddLog(log *Log) { +func (self *StateDB) AddLog(log *Log) { self.logs = append(self.logs, log) } -func (self *State) Logs() Logs { +func (self *StateDB) Logs() Logs { return self.logs } // Retrieve the balance from the given address or 0 if object not found -func (self *State) GetBalance(addr []byte) *big.Int { +func (self *StateDB) GetBalance(addr []byte) *big.Int { stateObject := self.GetStateObject(addr) if stateObject != nil { return stateObject.balance @@ -59,18 +59,18 @@ type refund struct { gas, price *big.Int } -func (self *State) Refund(addr []byte, gas, price *big.Int) { +func (self *StateDB) Refund(addr []byte, gas, price *big.Int) { self.refund[string(addr)] = append(self.refund[string(addr)], refund{gas, price}) } -func (self *State) AddBalance(addr []byte, amount *big.Int) { +func (self *StateDB) AddBalance(addr []byte, amount *big.Int) { stateObject := self.GetStateObject(addr) if stateObject != nil { stateObject.AddBalance(amount) } } -func (self *State) GetNonce(addr []byte) uint64 { +func (self *StateDB) GetNonce(addr []byte) uint64 { stateObject := self.GetStateObject(addr) if stateObject != nil { return stateObject.Nonce @@ -79,14 +79,14 @@ func (self *State) GetNonce(addr []byte) uint64 { return 0 } -func (self *State) SetNonce(addr []byte, nonce uint64) { +func (self *StateDB) SetNonce(addr []byte, nonce uint64) { stateObject := self.GetStateObject(addr) if stateObject != nil { stateObject.Nonce = nonce } } -func (self *State) GetCode(addr []byte) []byte { +func (self *StateDB) GetCode(addr []byte) []byte { stateObject := self.GetStateObject(addr) if stateObject != nil { return stateObject.Code @@ -95,7 +95,7 @@ func (self *State) GetCode(addr []byte) []byte { return nil } -func (self *State) GetState(a, b []byte) []byte { +func (self *StateDB) GetState(a, b []byte) []byte { stateObject := self.GetStateObject(a) if stateObject != nil { return stateObject.GetState(b).Bytes() @@ -104,14 +104,14 @@ func (self *State) GetState(a, b []byte) []byte { return nil } -func (self *State) SetState(addr, key []byte, value interface{}) { +func (self *StateDB) SetState(addr, key []byte, value interface{}) { stateObject := self.GetStateObject(addr) if stateObject != nil { stateObject.SetState(key, ethutil.NewValue(value)) } } -func (self *State) Delete(addr []byte) bool { +func (self *StateDB) Delete(addr []byte) bool { stateObject := self.GetStateObject(addr) if stateObject != nil { stateObject.MarkForDeletion() @@ -127,7 +127,7 @@ func (self *State) Delete(addr []byte) bool { // // Update the given state object and apply it to state trie -func (self *State) UpdateStateObject(stateObject *StateObject) { +func (self *StateDB) UpdateStateObject(stateObject *StateObject) { addr := stateObject.Address() if len(stateObject.CodeHash()) > 0 { @@ -138,14 +138,14 @@ func (self *State) UpdateStateObject(stateObject *StateObject) { } // Delete the given state object and delete it from the state trie -func (self *State) DeleteStateObject(stateObject *StateObject) { +func (self *StateDB) DeleteStateObject(stateObject *StateObject) { self.Trie.Delete(string(stateObject.Address())) delete(self.stateObjects, string(stateObject.Address())) } // Retrieve a state object given my the address. Nil if not found -func (self *State) GetStateObject(addr []byte) *StateObject { +func (self *StateDB) GetStateObject(addr []byte) *StateObject { addr = ethutil.Address(addr) stateObject := self.stateObjects[string(addr)] @@ -164,12 +164,12 @@ func (self *State) GetStateObject(addr []byte) *StateObject { return stateObject } -func (self *State) SetStateObject(object *StateObject) { +func (self *StateDB) SetStateObject(object *StateObject) { self.stateObjects[string(object.address)] = object } // Retrieve a state object or create a new state object if nil -func (self *State) GetOrNewStateObject(addr []byte) *StateObject { +func (self *StateDB) GetOrNewStateObject(addr []byte) *StateObject { stateObject := self.GetStateObject(addr) if stateObject == nil { stateObject = self.NewStateObject(addr) @@ -179,7 +179,7 @@ func (self *State) GetOrNewStateObject(addr []byte) *StateObject { } // Create a state object whether it exist in the trie or not -func (self *State) NewStateObject(addr []byte) *StateObject { +func (self *StateDB) NewStateObject(addr []byte) *StateObject { addr = ethutil.Address(addr) statelogger.Debugf("(+) %x\n", addr) @@ -191,7 +191,7 @@ func (self *State) NewStateObject(addr []byte) *StateObject { } // Deprecated -func (self *State) GetAccount(addr []byte) *StateObject { +func (self *StateDB) GetAccount(addr []byte) *StateObject { return self.GetOrNewStateObject(addr) } @@ -199,11 +199,11 @@ func (self *State) GetAccount(addr []byte) *StateObject { // Setting, copying of the state methods // -func (s *State) Cmp(other *State) bool { +func (s *StateDB) Cmp(other *StateDB) bool { return s.Trie.Cmp(other.Trie) } -func (self *State) Copy() *State { +func (self *StateDB) Copy() *StateDB { if self.Trie != nil { state := New(self.Trie.Copy()) for k, stateObject := range self.stateObjects { @@ -224,7 +224,7 @@ func (self *State) Copy() *State { return nil } -func (self *State) Set(state *State) { +func (self *StateDB) Set(state *StateDB) { if state == nil { panic("Tried setting 'state' to nil through 'Set'") } @@ -235,12 +235,12 @@ func (self *State) Set(state *State) { self.logs = state.logs } -func (s *State) Root() []byte { +func (s *StateDB) Root() []byte { return s.Trie.GetRoot() } // Resets the trie and all siblings -func (s *State) Reset() { +func (s *StateDB) Reset() { s.Trie.Undo() // Reset all nested states @@ -256,7 +256,7 @@ func (s *State) Reset() { } // Syncs the trie and all siblings -func (s *State) Sync() { +func (s *StateDB) Sync() { // Sync all nested states for _, stateObject := range s.stateObjects { if stateObject.State == nil { @@ -271,12 +271,12 @@ func (s *State) Sync() { s.Empty() } -func (self *State) Empty() { +func (self *StateDB) Empty() { self.stateObjects = make(map[string]*StateObject) self.refund = make(map[string][]refund) } -func (self *State) Update(gasUsed *big.Int) { +func (self *StateDB) Update(gasUsed *big.Int) { var deleted bool // Refund any gas that's left @@ -313,12 +313,12 @@ func (self *State) Update(gasUsed *big.Int) { } } -func (self *State) Manifest() *Manifest { +func (self *StateDB) Manifest() *Manifest { return self.manifest } // Debug stuff -func (self *State) CreateOutputForDiff() { +func (self *StateDB) CreateOutputForDiff() { for _, stateObject := range self.stateObjects { stateObject.CreateOutputForDiff() } diff --git a/state/state_object.go b/state/state_object.go index a56e91bc5..b8af4e702 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -35,7 +35,7 @@ type StateObject struct { codeHash []byte Nonce uint64 // Contract related attributes - State *State + State *StateDB Code Code InitCode Code -- cgit v1.2.3 From 3043b233ea4df9b630638d75f3589b94653ccfa9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 4 Dec 2014 12:35:23 +0100 Subject: Log is now interface --- state/log.go | 61 ++++++++++++++++++++++++++++++++++++++++------------------ state/state.go | 2 +- 2 files changed, 43 insertions(+), 20 deletions(-) (limited to 'state') diff --git a/state/log.go b/state/log.go index 49da30535..46360f4aa 100644 --- a/state/log.go +++ b/state/log.go @@ -2,40 +2,63 @@ package state import ( "fmt" - "strings" "github.com/ethereum/go-ethereum/ethutil" ) -type Log struct { - Address []byte - Topics [][]byte - Data []byte +type Log interface { + ethutil.RlpEncodable + + Address() []byte + Topics() [][]byte + Data() []byte +} + +type StateLog struct { + address []byte + topics [][]byte + data []byte +} + +func NewLog(address []byte, topics [][]byte, data []byte) *StateLog { + return &StateLog{address, topics, data} +} + +func (self *StateLog) Address() []byte { + return self.address +} + +func (self *StateLog) Topics() [][]byte { + return self.topics } -func NewLogFromValue(decoder *ethutil.Value) *Log { - log := &Log{ - Address: decoder.Get(0).Bytes(), - Data: decoder.Get(2).Bytes(), +func (self *StateLog) Data() []byte { + return self.data +} + +func NewLogFromValue(decoder *ethutil.Value) *StateLog { + log := &StateLog{ + address: decoder.Get(0).Bytes(), + data: decoder.Get(2).Bytes(), } it := decoder.Get(1).NewIterator() for it.Next() { - log.Topics = append(log.Topics, it.Value().Bytes()) + log.topics = append(log.topics, it.Value().Bytes()) } return log } -func (self *Log) RlpData() interface{} { - return []interface{}{self.Address, ethutil.ByteSliceToInterface(self.Topics), self.Data} +func (self *StateLog) RlpData() interface{} { + return []interface{}{self.address, ethutil.ByteSliceToInterface(self.topics), self.data} } -func (self *Log) String() string { - return fmt.Sprintf(`log: %x %x %x`, self.Address, self.Topics, self.Data) +func (self *StateLog) String() string { + return fmt.Sprintf(`log: %x %x %x`, self.address, self.topics, self.data) } -type Logs []*Log +type Logs []Log func (self Logs) RlpData() interface{} { data := make([]interface{}, len(self)) @@ -46,10 +69,10 @@ func (self Logs) RlpData() interface{} { return data } -func (self Logs) String() string { - var logs []string +func (self Logs) String() (ret string) { for _, log := range self { - logs = append(logs, log.String()) + ret += fmt.Sprintf("%v", log) } - return "[ " + strings.Join(logs, ", ") + " ]" + + return "[" + ret + "]" } diff --git a/state/state.go b/state/state.go index 39c5f33cc..ca3f2af9c 100644 --- a/state/state.go +++ b/state/state.go @@ -37,7 +37,7 @@ func (self *StateDB) EmptyLogs() { self.logs = nil } -func (self *StateDB) AddLog(log *Log) { +func (self *StateDB) AddLog(log Log) { self.logs = append(self.logs, log) } -- cgit v1.2.3 From 1fb84d3c5f486ef0d42a21f3cd8416d6ef211604 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 10 Dec 2014 10:57:19 +0100 Subject: Fixed tests --- state/state_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'state') diff --git a/state/state_test.go b/state/state_test.go index 825d21fcc..28e4fc5da 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -9,7 +9,7 @@ import ( ) type StateSuite struct { - state *State + state *StateDB } var _ = checker.Suite(&StateSuite{}) -- cgit v1.2.3 From 198cc69357a0f25ae486a041786e1239c6f5ab0f Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 21:58:26 +0100 Subject: Gas corrections and vm fixes --- state/state.go | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'state') diff --git a/state/state.go b/state/state.go index ca3f2af9c..682e233c1 100644 --- a/state/state.go +++ b/state/state.go @@ -23,14 +23,14 @@ type StateDB struct { manifest *Manifest - refund map[string][]refund + refund map[string][]*big.Int logs Logs } // Create a new state from a given trie func New(trie *trie.Trie) *StateDB { - return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string][]refund)} + return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string][]*big.Int)} } func (self *StateDB) EmptyLogs() { @@ -55,12 +55,8 @@ func (self *StateDB) GetBalance(addr []byte) *big.Int { return ethutil.Big0 } -type refund struct { - gas, price *big.Int -} - -func (self *StateDB) Refund(addr []byte, gas, price *big.Int) { - self.refund[string(addr)] = append(self.refund[string(addr)], refund{gas, price}) +func (self *StateDB) Refund(addr []byte, gas *big.Int) { + self.refund[string(addr)] = append(self.refund[string(addr)], gas) } func (self *StateDB) AddBalance(addr []byte, amount *big.Int) { @@ -273,23 +269,17 @@ func (s *StateDB) Sync() { func (self *StateDB) Empty() { self.stateObjects = make(map[string]*StateObject) - self.refund = make(map[string][]refund) + self.refund = make(map[string][]*big.Int) +} + +func (self *StateDB) Refunds() map[string][]*big.Int { + return self.refund } func (self *StateDB) Update(gasUsed *big.Int) { var deleted bool - // Refund any gas that's left - // XXX THIS WILL CHANGE IN POC8 - uhalf := new(big.Int).Div(gasUsed, ethutil.Big2) - for addr, refs := range self.refund { - for _, ref := range refs { - refund := ethutil.BigMin(uhalf, ref.gas) - - self.GetStateObject([]byte(addr)).AddBalance(refund.Mul(refund, ref.price)) - } - } - self.refund = make(map[string][]refund) + self.refund = make(map[string][]*big.Int) for _, stateObject := range self.stateObjects { if stateObject.remove { -- cgit v1.2.3 From 332568379454dce6b1fb3c3e023a53d0c52cded0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 22:38:51 +0100 Subject: Fixed refund model --- state/state.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'state') diff --git a/state/state.go b/state/state.go index 682e233c1..a8d611668 100644 --- a/state/state.go +++ b/state/state.go @@ -23,14 +23,14 @@ type StateDB struct { manifest *Manifest - refund map[string][]*big.Int + refund map[string]*big.Int logs Logs } // Create a new state from a given trie func New(trie *trie.Trie) *StateDB { - return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string][]*big.Int)} + return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} } func (self *StateDB) EmptyLogs() { @@ -56,7 +56,10 @@ func (self *StateDB) GetBalance(addr []byte) *big.Int { } func (self *StateDB) Refund(addr []byte, gas *big.Int) { - self.refund[string(addr)] = append(self.refund[string(addr)], gas) + if self.refund[string(addr)] == nil { + self.refund[string(addr)] = new(big.Int) + } + self.refund[string(addr)].Add(self.refund[string(addr)], gas) } func (self *StateDB) AddBalance(addr []byte, amount *big.Int) { @@ -207,7 +210,7 @@ func (self *StateDB) Copy() *StateDB { } for addr, refund := range self.refund { - state.refund[addr] = refund + state.refund[addr] = new(big.Int).Set(refund) } logs := make(Logs, len(self.logs)) @@ -269,17 +272,17 @@ func (s *StateDB) Sync() { func (self *StateDB) Empty() { self.stateObjects = make(map[string]*StateObject) - self.refund = make(map[string][]*big.Int) + self.refund = make(map[string]*big.Int) } -func (self *StateDB) Refunds() map[string][]*big.Int { +func (self *StateDB) Refunds() map[string]*big.Int { return self.refund } func (self *StateDB) Update(gasUsed *big.Int) { var deleted bool - self.refund = make(map[string][]*big.Int) + self.refund = make(map[string]*big.Int) for _, stateObject := range self.stateObjects { if stateObject.remove { -- cgit v1.2.3 From 1508a23a6fe3cc50f718bfd6c62caae056534c09 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 20 Dec 2014 02:21:13 +0100 Subject: Minor updates on gas and removed/refactored old code. --- state/state.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'state') diff --git a/state/state.go b/state/state.go index a8d611668..f77da72f0 100644 --- a/state/state.go +++ b/state/state.go @@ -94,6 +94,13 @@ func (self *StateDB) GetCode(addr []byte) []byte { return nil } +func (self *StateDB) SetCode(addr, code []byte) { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + stateObject.SetCode(code) + } +} + func (self *StateDB) GetState(a, b []byte) []byte { stateObject := self.GetStateObject(a) if stateObject != nil { -- cgit v1.2.3 From 780abaec988df302e0c98f1a35e9af35b5623746 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 23 Dec 2014 18:35:36 +0100 Subject: Switched to new trie --- state/dump.go | 26 ++-- state/state.go | 325 ------------------------------------------------- state/state_object.go | 42 ++++--- state/statedb.go | 326 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 365 insertions(+), 354 deletions(-) delete mode 100644 state/state.go create mode 100644 state/statedb.go (limited to 'state') diff --git a/state/dump.go b/state/dump.go index c1f5ecf3a..40ecff50c 100644 --- a/state/dump.go +++ b/state/dump.go @@ -22,22 +22,23 @@ type World struct { func (self *StateDB) Dump() []byte { world := World{ - Root: ethutil.Bytes2Hex(self.Trie.GetRoot()), + Root: ethutil.Bytes2Hex(self.trie.Root()), Accounts: make(map[string]Account), } - self.Trie.NewIterator().Each(func(key string, value *ethutil.Value) { - stateObject := NewStateObjectFromBytes([]byte(key), value.Bytes()) + it := self.trie.Iterator() + for it.Next() { + stateObject := NewStateObjectFromBytes(it.Key, it.Value) account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.Nonce, Root: ethutil.Bytes2Hex(stateObject.Root()), CodeHash: ethutil.Bytes2Hex(stateObject.codeHash)} account.Storage = make(map[string]string) - stateObject.EachStorage(func(key string, value *ethutil.Value) { - value.Decode() - account.Storage[ethutil.Bytes2Hex([]byte(key))] = ethutil.Bytes2Hex(value.Bytes()) - }) - world.Accounts[ethutil.Bytes2Hex([]byte(key))] = account - }) + storageIt := stateObject.State.trie.Iterator() + for storageIt.Next() { + account.Storage[ethutil.Bytes2Hex(it.Key)] = ethutil.Bytes2Hex(it.Value) + } + world.Accounts[ethutil.Bytes2Hex(it.Key)] = account + } json, err := json.MarshalIndent(world, "", " ") if err != nil { @@ -50,7 +51,8 @@ func (self *StateDB) Dump() []byte { // Debug stuff func (self *StateObject) CreateOutputForDiff() { fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.Nonce) - self.EachStorage(func(addr string, value *ethutil.Value) { - fmt.Printf("%x %x\n", addr, value.Bytes()) - }) + it := self.State.trie.Iterator() + for it.Next() { + fmt.Printf("%x %x\n", it.Key, it.Value) + } } diff --git a/state/state.go b/state/state.go deleted file mode 100644 index f77da72f0..000000000 --- a/state/state.go +++ /dev/null @@ -1,325 +0,0 @@ -package state - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/trie" -) - -var statelogger = logger.NewLogger("STATE") - -// StateDBs within the ethereum protocol are used to store anything -// within the merkle trie. StateDBs take care of caching and storing -// nested states. It's the general query interface to retrieve: -// * Contracts -// * Accounts -type StateDB struct { - // The trie for this structure - Trie *trie.Trie - - stateObjects map[string]*StateObject - - manifest *Manifest - - refund map[string]*big.Int - - logs Logs -} - -// Create a new state from a given trie -func New(trie *trie.Trie) *StateDB { - return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} -} - -func (self *StateDB) EmptyLogs() { - self.logs = nil -} - -func (self *StateDB) AddLog(log Log) { - self.logs = append(self.logs, log) -} - -func (self *StateDB) Logs() Logs { - return self.logs -} - -// Retrieve the balance from the given address or 0 if object not found -func (self *StateDB) GetBalance(addr []byte) *big.Int { - stateObject := self.GetStateObject(addr) - if stateObject != nil { - return stateObject.balance - } - - return ethutil.Big0 -} - -func (self *StateDB) Refund(addr []byte, gas *big.Int) { - if self.refund[string(addr)] == nil { - self.refund[string(addr)] = new(big.Int) - } - self.refund[string(addr)].Add(self.refund[string(addr)], gas) -} - -func (self *StateDB) AddBalance(addr []byte, amount *big.Int) { - stateObject := self.GetStateObject(addr) - if stateObject != nil { - stateObject.AddBalance(amount) - } -} - -func (self *StateDB) GetNonce(addr []byte) uint64 { - stateObject := self.GetStateObject(addr) - if stateObject != nil { - return stateObject.Nonce - } - - return 0 -} - -func (self *StateDB) SetNonce(addr []byte, nonce uint64) { - stateObject := self.GetStateObject(addr) - if stateObject != nil { - stateObject.Nonce = nonce - } -} - -func (self *StateDB) GetCode(addr []byte) []byte { - stateObject := self.GetStateObject(addr) - if stateObject != nil { - return stateObject.Code - } - - return nil -} - -func (self *StateDB) SetCode(addr, code []byte) { - stateObject := self.GetStateObject(addr) - if stateObject != nil { - stateObject.SetCode(code) - } -} - -func (self *StateDB) GetState(a, b []byte) []byte { - stateObject := self.GetStateObject(a) - if stateObject != nil { - return stateObject.GetState(b).Bytes() - } - - return nil -} - -func (self *StateDB) SetState(addr, key []byte, value interface{}) { - stateObject := self.GetStateObject(addr) - if stateObject != nil { - stateObject.SetState(key, ethutil.NewValue(value)) - } -} - -func (self *StateDB) Delete(addr []byte) bool { - stateObject := self.GetStateObject(addr) - if stateObject != nil { - stateObject.MarkForDeletion() - - return true - } - - return false -} - -// -// Setting, updating & deleting state object methods -// - -// Update the given state object and apply it to state trie -func (self *StateDB) UpdateStateObject(stateObject *StateObject) { - addr := stateObject.Address() - - if len(stateObject.CodeHash()) > 0 { - ethutil.Config.Db.Put(stateObject.CodeHash(), stateObject.Code) - } - - self.Trie.Update(string(addr), string(stateObject.RlpEncode())) -} - -// Delete the given state object and delete it from the state trie -func (self *StateDB) DeleteStateObject(stateObject *StateObject) { - self.Trie.Delete(string(stateObject.Address())) - - delete(self.stateObjects, string(stateObject.Address())) -} - -// Retrieve a state object given my the address. Nil if not found -func (self *StateDB) GetStateObject(addr []byte) *StateObject { - addr = ethutil.Address(addr) - - stateObject := self.stateObjects[string(addr)] - if stateObject != nil { - return stateObject - } - - data := self.Trie.Get(string(addr)) - if len(data) == 0 { - return nil - } - - stateObject = NewStateObjectFromBytes(addr, []byte(data)) - self.SetStateObject(stateObject) - - return stateObject -} - -func (self *StateDB) SetStateObject(object *StateObject) { - self.stateObjects[string(object.address)] = object -} - -// Retrieve a state object or create a new state object if nil -func (self *StateDB) GetOrNewStateObject(addr []byte) *StateObject { - stateObject := self.GetStateObject(addr) - if stateObject == nil { - stateObject = self.NewStateObject(addr) - } - - return stateObject -} - -// Create a state object whether it exist in the trie or not -func (self *StateDB) NewStateObject(addr []byte) *StateObject { - addr = ethutil.Address(addr) - - statelogger.Debugf("(+) %x\n", addr) - - stateObject := NewStateObject(addr) - self.stateObjects[string(addr)] = stateObject - - return stateObject -} - -// Deprecated -func (self *StateDB) GetAccount(addr []byte) *StateObject { - return self.GetOrNewStateObject(addr) -} - -// -// Setting, copying of the state methods -// - -func (s *StateDB) Cmp(other *StateDB) bool { - return s.Trie.Cmp(other.Trie) -} - -func (self *StateDB) Copy() *StateDB { - if self.Trie != nil { - state := New(self.Trie.Copy()) - for k, stateObject := range self.stateObjects { - state.stateObjects[k] = stateObject.Copy() - } - - for addr, refund := range self.refund { - state.refund[addr] = new(big.Int).Set(refund) - } - - logs := make(Logs, len(self.logs)) - copy(logs, self.logs) - state.logs = logs - - return state - } - - return nil -} - -func (self *StateDB) Set(state *StateDB) { - if state == nil { - panic("Tried setting 'state' to nil through 'Set'") - } - - self.Trie = state.Trie - self.stateObjects = state.stateObjects - self.refund = state.refund - self.logs = state.logs -} - -func (s *StateDB) Root() []byte { - return s.Trie.GetRoot() -} - -// Resets the trie and all siblings -func (s *StateDB) Reset() { - s.Trie.Undo() - - // Reset all nested states - for _, stateObject := range s.stateObjects { - if stateObject.State == nil { - continue - } - - stateObject.Reset() - } - - s.Empty() -} - -// Syncs the trie and all siblings -func (s *StateDB) Sync() { - // Sync all nested states - for _, stateObject := range s.stateObjects { - if stateObject.State == nil { - continue - } - - stateObject.State.Sync() - } - - s.Trie.Sync() - - s.Empty() -} - -func (self *StateDB) Empty() { - self.stateObjects = make(map[string]*StateObject) - self.refund = make(map[string]*big.Int) -} - -func (self *StateDB) Refunds() map[string]*big.Int { - return self.refund -} - -func (self *StateDB) Update(gasUsed *big.Int) { - var deleted bool - - self.refund = make(map[string]*big.Int) - - for _, stateObject := range self.stateObjects { - if stateObject.remove { - self.DeleteStateObject(stateObject) - deleted = true - } else { - stateObject.Sync() - - self.UpdateStateObject(stateObject) - } - } - - // FIXME trie delete is broken - if deleted { - valid, t2 := trie.ParanoiaCheck(self.Trie) - if !valid { - statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.Trie.GetRoot(), t2.GetRoot()) - - self.Trie = t2 - } - } -} - -func (self *StateDB) Manifest() *Manifest { - return self.manifest -} - -// Debug stuff -func (self *StateDB) CreateOutputForDiff() { - for _, stateObject := range self.stateObjects { - stateObject.CreateOutputForDiff() - } -} diff --git a/state/state_object.go b/state/state_object.go index b8af4e702..420ad9757 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/ptrie" ) type Code []byte @@ -62,7 +62,7 @@ func NewStateObject(addr []byte) *StateObject { address := ethutil.Address(addr) object := &StateObject{address: address, balance: new(big.Int), gasPool: new(big.Int)} - object.State = New(trie.New(ethutil.Config.Db, "")) + object.State = New(ptrie.New(nil, ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, "")) object.storage = make(Storage) object.gasPool = new(big.Int) @@ -72,7 +72,7 @@ func NewStateObject(addr []byte) *StateObject { func NewContract(address []byte, balance *big.Int, root []byte) *StateObject { contract := NewStateObject(address) contract.balance = balance - contract.State = New(trie.New(ethutil.Config.Db, string(root))) + contract.State = New(ptrie.New(nil, ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, string(root))) return contract } @@ -89,12 +89,12 @@ func (self *StateObject) MarkForDeletion() { statelogger.DebugDetailf("%x: #%d %v (deletion)\n", self.Address(), self.Nonce, self.balance) } -func (c *StateObject) GetAddr(addr []byte) *ethutil.Value { - return ethutil.NewValueFromBytes([]byte(c.State.Trie.Get(string(addr)))) +func (c *StateObject) getAddr(addr []byte) *ethutil.Value { + return ethutil.NewValueFromBytes([]byte(c.State.trie.Get(addr))) } -func (c *StateObject) SetAddr(addr []byte, value interface{}) { - c.State.Trie.Update(string(addr), string(ethutil.NewValue(value).Encode())) +func (c *StateObject) setAddr(addr []byte, value interface{}) { + c.State.trie.Update(addr, ethutil.Encode(value)) } func (self *StateObject) GetStorage(key *big.Int) *ethutil.Value { @@ -113,7 +113,7 @@ func (self *StateObject) GetState(k []byte) *ethutil.Value { value := self.storage[string(key)] if value == nil { - value = self.GetAddr(key) + value = self.getAddr(key) if !value.IsNil() { self.storage[string(key)] = value @@ -128,6 +128,7 @@ func (self *StateObject) SetState(k []byte, value *ethutil.Value) { self.storage[string(key)] = value.Copy() } +/* // Iterate over each storage address and yield callback func (self *StateObject) EachStorage(cb trie.EachCallback) { // First loop over the uncommit/cached values in storage @@ -145,23 +146,26 @@ func (self *StateObject) EachStorage(cb trie.EachCallback) { } }) } +*/ func (self *StateObject) Sync() { for key, value := range self.storage { if value.Len() == 0 { - self.State.Trie.Delete(string(key)) + self.State.trie.Delete([]byte(key)) continue } - self.SetAddr([]byte(key), value) + self.setAddr([]byte(key), value) } - valid, t2 := trie.ParanoiaCheck(self.State.Trie) - if !valid { - statelogger.Infof("Warn: PARANOIA: Different state storage root during copy %x vs %x\n", self.State.Root(), t2.GetRoot()) + /* + valid, t2 := ptrie.ParanoiaCheck(self.State.trie, ethutil.Config.Db) + if !valid { + statelogger.Infof("Warn: PARANOIA: Different state storage root during copy %x vs %x\n", self.State.Root(), t2.Root()) - self.State.Trie = t2 - } + self.State.trie = t2 + } + */ } func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value { @@ -276,8 +280,12 @@ func (c *StateObject) Init() Code { return c.InitCode } +func (self *StateObject) Trie() *ptrie.Trie { + return self.State.trie +} + func (self *StateObject) Root() []byte { - return self.State.Trie.GetRoot() + return self.Trie().Root() } func (self *StateObject) SetCode(code []byte) { @@ -302,7 +310,7 @@ func (c *StateObject) RlpDecode(data []byte) { c.Nonce = decoder.Get(0).Uint() c.balance = decoder.Get(1).BigInt() - c.State = New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface())) + c.State = New(ptrie.New(decoder.Get(2).Bytes(), ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface())) c.storage = make(map[string]*ethutil.Value) c.gasPool = new(big.Int) diff --git a/state/statedb.go b/state/statedb.go new file mode 100644 index 000000000..6a11fc328 --- /dev/null +++ b/state/statedb.go @@ -0,0 +1,326 @@ +package state + +import ( + "bytes" + "math/big" + + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/ptrie" +) + +var statelogger = logger.NewLogger("STATE") + +// StateDBs within the ethereum protocol are used to store anything +// within the merkle trie. StateDBs take care of caching and storing +// nested states. It's the general query interface to retrieve: +// * Contracts +// * Accounts +type StateDB struct { + //Trie *trie.Trie + trie *ptrie.Trie + + stateObjects map[string]*StateObject + + manifest *Manifest + + refund map[string]*big.Int + + logs Logs +} + +// Create a new state from a given trie +func New(trie *ptrie.Trie) *StateDB { + return &StateDB{trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} +} + +func (self *StateDB) EmptyLogs() { + self.logs = nil +} + +func (self *StateDB) AddLog(log Log) { + self.logs = append(self.logs, log) +} + +func (self *StateDB) Logs() Logs { + return self.logs +} + +// Retrieve the balance from the given address or 0 if object not found +func (self *StateDB) GetBalance(addr []byte) *big.Int { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + return stateObject.balance + } + + return ethutil.Big0 +} + +func (self *StateDB) Refund(addr []byte, gas *big.Int) { + if self.refund[string(addr)] == nil { + self.refund[string(addr)] = new(big.Int) + } + self.refund[string(addr)].Add(self.refund[string(addr)], gas) +} + +func (self *StateDB) AddBalance(addr []byte, amount *big.Int) { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + stateObject.AddBalance(amount) + } +} + +func (self *StateDB) GetNonce(addr []byte) uint64 { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + return stateObject.Nonce + } + + return 0 +} + +func (self *StateDB) SetNonce(addr []byte, nonce uint64) { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + stateObject.Nonce = nonce + } +} + +func (self *StateDB) GetCode(addr []byte) []byte { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + return stateObject.Code + } + + return nil +} + +func (self *StateDB) SetCode(addr, code []byte) { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + stateObject.SetCode(code) + } +} + +func (self *StateDB) GetState(a, b []byte) []byte { + stateObject := self.GetStateObject(a) + if stateObject != nil { + return stateObject.GetState(b).Bytes() + } + + return nil +} + +func (self *StateDB) SetState(addr, key []byte, value interface{}) { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + stateObject.SetState(key, ethutil.NewValue(value)) + } +} + +func (self *StateDB) Delete(addr []byte) bool { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + stateObject.MarkForDeletion() + + return true + } + + return false +} + +// +// Setting, updating & deleting state object methods +// + +// Update the given state object and apply it to state trie +func (self *StateDB) UpdateStateObject(stateObject *StateObject) { + addr := stateObject.Address() + + if len(stateObject.CodeHash()) > 0 { + ethutil.Config.Db.Put(stateObject.CodeHash(), stateObject.Code) + } + + self.trie.Update(addr, stateObject.RlpEncode()) +} + +// Delete the given state object and delete it from the state trie +func (self *StateDB) DeleteStateObject(stateObject *StateObject) { + self.trie.Delete(stateObject.Address()) + + delete(self.stateObjects, string(stateObject.Address())) +} + +// Retrieve a state object given my the address. Nil if not found +func (self *StateDB) GetStateObject(addr []byte) *StateObject { + addr = ethutil.Address(addr) + + stateObject := self.stateObjects[string(addr)] + if stateObject != nil { + return stateObject + } + + data := self.trie.Get(addr) + if len(data) == 0 { + return nil + } + + stateObject = NewStateObjectFromBytes(addr, []byte(data)) + self.SetStateObject(stateObject) + + return stateObject +} + +func (self *StateDB) SetStateObject(object *StateObject) { + self.stateObjects[string(object.address)] = object +} + +// Retrieve a state object or create a new state object if nil +func (self *StateDB) GetOrNewStateObject(addr []byte) *StateObject { + stateObject := self.GetStateObject(addr) + if stateObject == nil { + stateObject = self.NewStateObject(addr) + } + + return stateObject +} + +// Create a state object whether it exist in the trie or not +func (self *StateDB) NewStateObject(addr []byte) *StateObject { + addr = ethutil.Address(addr) + + statelogger.Debugf("(+) %x\n", addr) + + stateObject := NewStateObject(addr) + self.stateObjects[string(addr)] = stateObject + + return stateObject +} + +// Deprecated +func (self *StateDB) GetAccount(addr []byte) *StateObject { + return self.GetOrNewStateObject(addr) +} + +// +// Setting, copying of the state methods +// + +func (s *StateDB) Cmp(other *StateDB) bool { + return bytes.Equal(s.trie.Root(), other.trie.Root()) +} + +func (self *StateDB) Copy() *StateDB { + if self.trie != nil { + state := New(self.trie.Copy()) + for k, stateObject := range self.stateObjects { + state.stateObjects[k] = stateObject.Copy() + } + + for addr, refund := range self.refund { + state.refund[addr] = new(big.Int).Set(refund) + } + + logs := make(Logs, len(self.logs)) + copy(logs, self.logs) + state.logs = logs + + return state + } + + return nil +} + +func (self *StateDB) Set(state *StateDB) { + if state == nil { + panic("Tried setting 'state' to nil through 'Set'") + } + + self.trie = state.trie + self.stateObjects = state.stateObjects + self.refund = state.refund + self.logs = state.logs +} + +func (s *StateDB) Root() []byte { + return s.trie.Root() +} + +// Resets the trie and all siblings +func (s *StateDB) Reset() { + s.trie.Reset() + + // Reset all nested states + for _, stateObject := range s.stateObjects { + if stateObject.State == nil { + continue + } + + stateObject.Reset() + } + + s.Empty() +} + +// Syncs the trie and all siblings +func (s *StateDB) Sync() { + // Sync all nested states + for _, stateObject := range s.stateObjects { + if stateObject.State == nil { + continue + } + + stateObject.State.Sync() + } + + s.trie.Commit() + + s.Empty() +} + +func (self *StateDB) Empty() { + self.stateObjects = make(map[string]*StateObject) + self.refund = make(map[string]*big.Int) +} + +func (self *StateDB) Refunds() map[string]*big.Int { + return self.refund +} + +func (self *StateDB) Update(gasUsed *big.Int) { + var deleted bool + + self.refund = make(map[string]*big.Int) + + for _, stateObject := range self.stateObjects { + if stateObject.remove { + self.DeleteStateObject(stateObject) + deleted = true + } else { + stateObject.Sync() + + self.UpdateStateObject(stateObject) + } + } + + // FIXME trie delete is broken + if deleted { + valid, t2 := ptrie.ParanoiaCheck(self.trie, ethutil.Config.Db) + if !valid { + statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root(), t2.Root()) + + self.trie = t2 + } + } +} + +func (self *StateDB) Manifest() *Manifest { + return self.manifest +} + +// Debug stuff +func (self *StateDB) CreateOutputForDiff() { + for _, stateObject := range self.stateObjects { + stateObject.CreateOutputForDiff() + } +} -- cgit v1.2.3 From e2d1d832efe0623539c9d37ca8aee17d44e47067 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 2 Jan 2015 13:00:25 +0100 Subject: added nil check --- state/state_test.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'state') diff --git a/state/state_test.go b/state/state_test.go index 28e4fc5da..1f76eff0f 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -5,7 +5,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/ptrie" ) type StateSuite struct { @@ -18,9 +18,8 @@ var _ = checker.Suite(&StateSuite{}) func (s *StateSuite) TestDump(c *checker.C) { key := []byte{0x01} - value := "foo" - node := []interface{}{key, value} - s.state.Trie.Put(node) + value := []byte("foo") + s.state.trie.Update(key, value) dump := s.state.Dump() c.Assert(dump, checker.NotNil) } @@ -29,7 +28,7 @@ func (s *StateSuite) SetUpTest(c *checker.C) { db, _ := ethdb.NewMemDatabase() ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "") ethutil.Config.Db = db - s.state = New(trie.New(db, "")) + s.state = New(ptrie.New(nil, db)) } func (s *StateSuite) TestSnapshot(c *checker.C) { -- cgit v1.2.3 From ca1b2a1a91401255ab4e26cec7eb575b99ecb8da Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 3 Jan 2015 17:18:43 +0100 Subject: Changed prev_hash to block_hash, state transition now uses vm env * PREVHASH => BLOCKHASH( N ) * State transition object uses VMEnv as it's query interface * Updated vm.Enviroment has GetHash( n ) for BLOCKHASH instruction * Added GetHash to xeth, core, utils & test environments --- state/manifest.go | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'state') diff --git a/state/manifest.go b/state/manifest.go index 21cd04a1a..994019a08 100644 --- a/state/manifest.go +++ b/state/manifest.go @@ -30,6 +30,12 @@ func (self *Manifest) AddMessage(msg *Message) *Message { return msg } +func (self *Manifest) SetHash(hash []byte) { + for _, message := range self.Messages { + message.Block = hash + } +} + type Messages []*Message type Message struct { To, From []byte -- cgit v1.2.3 From fed3e6a808921fb8274b50043c5c39a24a1bbccf Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 7 Jan 2015 13:17:48 +0100 Subject: Refactored ethutil.Config.Db out --- state/dump.go | 2 +- state/state_object.go | 25 +++++++++---------------- state/state_test.go | 6 ++---- state/statedb.go | 19 +++++++++++-------- 4 files changed, 23 insertions(+), 29 deletions(-) (limited to 'state') diff --git a/state/dump.go b/state/dump.go index 40ecff50c..ac646480c 100644 --- a/state/dump.go +++ b/state/dump.go @@ -28,7 +28,7 @@ func (self *StateDB) Dump() []byte { it := self.trie.Iterator() for it.Next() { - stateObject := NewStateObjectFromBytes(it.Key, it.Value) + stateObject := NewStateObjectFromBytes(it.Key, it.Value, self.db) account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.Nonce, Root: ethutil.Bytes2Hex(stateObject.Root()), CodeHash: ethutil.Bytes2Hex(stateObject.codeHash)} account.Storage = make(map[string]string) diff --git a/state/state_object.go b/state/state_object.go index 420ad9757..c1c78bee0 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -28,6 +28,7 @@ func (self Storage) Copy() Storage { } type StateObject struct { + db ethutil.Database // Address of the object address []byte // Shared attributes @@ -57,28 +58,20 @@ func (self *StateObject) Reset() { self.State.Reset() } -func NewStateObject(addr []byte) *StateObject { +func NewStateObject(addr []byte, db ethutil.Database) *StateObject { // This to ensure that it has 20 bytes (and not 0 bytes), thus left or right pad doesn't matter. address := ethutil.Address(addr) - object := &StateObject{address: address, balance: new(big.Int), gasPool: new(big.Int)} - object.State = New(ptrie.New(nil, ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, "")) + object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int)} + object.State = New(nil, db) //New(trie.New(ethutil.Config.Db, "")) object.storage = make(Storage) object.gasPool = new(big.Int) return object } -func NewContract(address []byte, balance *big.Int, root []byte) *StateObject { - contract := NewStateObject(address) - contract.balance = balance - contract.State = New(ptrie.New(nil, ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, string(root))) - - return contract -} - -func NewStateObjectFromBytes(address, data []byte) *StateObject { - object := &StateObject{address: address} +func NewStateObjectFromBytes(address, data []byte, db ethutil.Database) *StateObject { + object := &StateObject{address: address, db: db} object.RlpDecode(data) return object @@ -242,7 +235,7 @@ func (self *StateObject) RefundGas(gas, price *big.Int) { } func (self *StateObject) Copy() *StateObject { - stateObject := NewStateObject(self.Address()) + stateObject := NewStateObject(self.Address(), self.db) stateObject.balance.Set(self.balance) stateObject.codeHash = ethutil.CopyBytes(self.codeHash) stateObject.Nonce = self.Nonce @@ -310,13 +303,13 @@ func (c *StateObject) RlpDecode(data []byte) { c.Nonce = decoder.Get(0).Uint() c.balance = decoder.Get(1).BigInt() - c.State = New(ptrie.New(decoder.Get(2).Bytes(), ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface())) + c.State = New(decoder.Get(2).Bytes(), c.db) //New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface())) c.storage = make(map[string]*ethutil.Value) c.gasPool = new(big.Int) c.codeHash = decoder.Get(3).Bytes() - c.Code, _ = ethutil.Config.Db.Get(c.codeHash) + c.Code, _ = c.db.Get(c.codeHash) } // Storage change object. Used by the manifest for notifying changes to diff --git a/state/state_test.go b/state/state_test.go index 1f76eff0f..7c54cedc0 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -5,7 +5,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/ptrie" ) type StateSuite struct { @@ -25,10 +24,9 @@ func (s *StateSuite) TestDump(c *checker.C) { } func (s *StateSuite) SetUpTest(c *checker.C) { - db, _ := ethdb.NewMemDatabase() ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "") - ethutil.Config.Db = db - s.state = New(ptrie.New(nil, db)) + db, _ := ethdb.NewMemDatabase() + s.state = New(nil, db) } func (s *StateSuite) TestSnapshot(c *checker.C) { diff --git a/state/statedb.go b/state/statedb.go index 6a11fc328..de7314790 100644 --- a/state/statedb.go +++ b/state/statedb.go @@ -17,7 +17,7 @@ var statelogger = logger.NewLogger("STATE") // * Contracts // * Accounts type StateDB struct { - //Trie *trie.Trie + db ethutil.Database trie *ptrie.Trie stateObjects map[string]*StateObject @@ -30,8 +30,10 @@ type StateDB struct { } // Create a new state from a given trie -func New(trie *ptrie.Trie) *StateDB { - return &StateDB{trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} +//func New(trie *ptrie.Trie) *StateDB { +func New(root []byte, db ethutil.Database) *StateDB { + trie := ptrie.New(root, db) + return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} } func (self *StateDB) EmptyLogs() { @@ -138,7 +140,7 @@ func (self *StateDB) UpdateStateObject(stateObject *StateObject) { addr := stateObject.Address() if len(stateObject.CodeHash()) > 0 { - ethutil.Config.Db.Put(stateObject.CodeHash(), stateObject.Code) + self.db.Put(stateObject.CodeHash(), stateObject.Code) } self.trie.Update(addr, stateObject.RlpEncode()) @@ -165,7 +167,7 @@ func (self *StateDB) GetStateObject(addr []byte) *StateObject { return nil } - stateObject = NewStateObjectFromBytes(addr, []byte(data)) + stateObject = NewStateObjectFromBytes(addr, []byte(data), self.db) self.SetStateObject(stateObject) return stateObject @@ -191,7 +193,7 @@ func (self *StateDB) NewStateObject(addr []byte) *StateObject { statelogger.Debugf("(+) %x\n", addr) - stateObject := NewStateObject(addr) + stateObject := NewStateObject(addr, self.db) self.stateObjects[string(addr)] = stateObject return stateObject @@ -212,7 +214,8 @@ func (s *StateDB) Cmp(other *StateDB) bool { func (self *StateDB) Copy() *StateDB { if self.trie != nil { - state := New(self.trie.Copy()) + state := New(nil, self.db) + state.trie = self.trie.Copy() for k, stateObject := range self.stateObjects { state.stateObjects[k] = stateObject.Copy() } @@ -305,7 +308,7 @@ func (self *StateDB) Update(gasUsed *big.Int) { // FIXME trie delete is broken if deleted { - valid, t2 := ptrie.ParanoiaCheck(self.trie, ethutil.Config.Db) + valid, t2 := ptrie.ParanoiaCheck(self.trie, self.db) if !valid { statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root(), t2.Root()) -- cgit v1.2.3 From db4aaedcbdb409e17ea3de161e7b24a80ba0a58c Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 8 Jan 2015 11:47:04 +0100 Subject: Moved ptrie => trie. Removed old trie --- state/state_object.go | 6 +++--- state/statedb.go | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'state') diff --git a/state/state_object.go b/state/state_object.go index c1c78bee0..913c57a31 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/ptrie" + "github.com/ethereum/go-ethereum/trie" ) type Code []byte @@ -152,7 +152,7 @@ func (self *StateObject) Sync() { } /* - valid, t2 := ptrie.ParanoiaCheck(self.State.trie, ethutil.Config.Db) + valid, t2 := trie.ParanoiaCheck(self.State.trie, ethutil.Config.Db) if !valid { statelogger.Infof("Warn: PARANOIA: Different state storage root during copy %x vs %x\n", self.State.Root(), t2.Root()) @@ -273,7 +273,7 @@ func (c *StateObject) Init() Code { return c.InitCode } -func (self *StateObject) Trie() *ptrie.Trie { +func (self *StateObject) Trie() *trie.Trie { return self.State.trie } diff --git a/state/statedb.go b/state/statedb.go index de7314790..3176ab755 100644 --- a/state/statedb.go +++ b/state/statedb.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/ptrie" + "github.com/ethereum/go-ethereum/trie" ) var statelogger = logger.NewLogger("STATE") @@ -18,7 +18,7 @@ var statelogger = logger.NewLogger("STATE") // * Accounts type StateDB struct { db ethutil.Database - trie *ptrie.Trie + trie *trie.Trie stateObjects map[string]*StateObject @@ -30,9 +30,8 @@ type StateDB struct { } // Create a new state from a given trie -//func New(trie *ptrie.Trie) *StateDB { func New(root []byte, db ethutil.Database) *StateDB { - trie := ptrie.New(root, db) + trie := trie.New(root, db) return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} } @@ -308,7 +307,7 @@ func (self *StateDB) Update(gasUsed *big.Int) { // FIXME trie delete is broken if deleted { - valid, t2 := ptrie.ParanoiaCheck(self.trie, self.db) + valid, t2 := trie.ParanoiaCheck(self.trie, self.db) if !valid { statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root(), t2.Root()) -- cgit v1.2.3 From 54927dc0e0b99009f92fbb7b28d71ae20179ce1e Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 29 Jan 2015 23:58:43 +0100 Subject: Fixed issue with Storage() * Storage() returned encoded values. They are now decode prior to hexing * Removed old code from state object * Updated coin --- state/state_object.go | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'state') diff --git a/state/state_object.go b/state/state_object.go index 913c57a31..340939a5d 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -121,26 +121,6 @@ func (self *StateObject) SetState(k []byte, value *ethutil.Value) { self.storage[string(key)] = value.Copy() } -/* -// Iterate over each storage address and yield callback -func (self *StateObject) EachStorage(cb trie.EachCallback) { - // First loop over the uncommit/cached values in storage - for key, value := range self.storage { - // XXX Most iterators Fns as it stands require encoded values - encoded := ethutil.NewValue(value.Encode()) - cb(key, encoded) - } - - it := self.State.Trie.NewIterator() - it.Each(func(key string, value *ethutil.Value) { - // If it's cached don't call the callback. - if self.storage[key] == nil { - cb(key, value) - } - }) -} -*/ - func (self *StateObject) Sync() { for key, value := range self.storage { if value.Len() == 0 { @@ -150,15 +130,6 @@ func (self *StateObject) Sync() { self.setAddr([]byte(key), value) } - - /* - valid, t2 := trie.ParanoiaCheck(self.State.trie, ethutil.Config.Db) - if !valid { - statelogger.Infof("Warn: PARANOIA: Different state storage root during copy %x vs %x\n", self.State.Root(), t2.Root()) - - self.State.trie = t2 - } - */ } func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value { -- cgit v1.2.3 From 79cd58bdf32c8e4e725480f9d6dc58f7325e07a0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 31 Jan 2015 17:23:46 +0100 Subject: removed old code --- state/statedb.go | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'state') diff --git a/state/statedb.go b/state/statedb.go index 3176ab755..1b6e274de 100644 --- a/state/statedb.go +++ b/state/statedb.go @@ -290,30 +290,18 @@ func (self *StateDB) Refunds() map[string]*big.Int { } func (self *StateDB) Update(gasUsed *big.Int) { - var deleted bool self.refund = make(map[string]*big.Int) for _, stateObject := range self.stateObjects { if stateObject.remove { self.DeleteStateObject(stateObject) - deleted = true } else { stateObject.Sync() self.UpdateStateObject(stateObject) } } - - // FIXME trie delete is broken - if deleted { - valid, t2 := trie.ParanoiaCheck(self.trie, self.db) - if !valid { - statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root(), t2.Root()) - - self.trie = t2 - } - } } func (self *StateDB) Manifest() *Manifest { -- cgit v1.2.3