diff options
author | Jeffrey Wilcke <geffobscura@gmail.com> | 2015-06-24 01:19:33 +0800 |
---|---|---|
committer | Jeffrey Wilcke <geffobscura@gmail.com> | 2015-06-24 01:19:33 +0800 |
commit | 72e2613a9fe3205fa5a67b72b832e03b2357ee88 (patch) | |
tree | bbc987510d279d9e174ff8f684158d668131661e /core/state/state_object.go | |
parent | 5daf8729be88eca87b302ebf7a46fc69cad0f6d0 (diff) | |
parent | 67e6f74e9af00ff011a6a02f18644804eb18cdaa (diff) | |
download | go-tangerine-0.9.32.tar go-tangerine-0.9.32.tar.gz go-tangerine-0.9.32.tar.bz2 go-tangerine-0.9.32.tar.lz go-tangerine-0.9.32.tar.xz go-tangerine-0.9.32.tar.zst go-tangerine-0.9.32.zip |
Merge branch 'release/0.9.32'v0.9.32
Diffstat (limited to 'core/state/state_object.go')
-rw-r--r-- | core/state/state_object.go | 97 |
1 files changed, 38 insertions, 59 deletions
diff --git a/core/state/state_object.go b/core/state/state_object.go index 6d2455d79..a31c182d2 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -19,11 +19,11 @@ func (self Code) String() string { return string(self) //strings.Join(Disassemble(self), " ") } -type Storage map[string]*common.Value +type Storage map[string]common.Hash func (self Storage) String() (str string) { for key, value := range self { - str += fmt.Sprintf("%X : %X\n", key, value.Bytes()) + str += fmt.Sprintf("%X : %X\n", key, value) } return @@ -32,7 +32,6 @@ func (self Storage) String() (str string) { 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 } @@ -41,9 +40,8 @@ func (self Storage) Copy() Storage { type StateObject struct { // State database for storing state changes - db common.Database - // The state object - State *StateDB + db common.Database + trie *trie.SecureTrie // Address belonging to this account address common.Address @@ -76,7 +74,6 @@ type StateObject struct { func (self *StateObject) Reset() { self.storage = make(Storage) - self.State.Reset() } func NewStateObject(address common.Address, db common.Database) *StateObject { @@ -84,7 +81,7 @@ func NewStateObject(address common.Address, db common.Database) *StateObject { //address := common.ToAddress(addr) object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int), dirty: true} - object.State = New(common.Hash{}, db) //New(trie.New(common.Config.Db, "")) + object.trie = trie.NewSecure((common.Hash{}).Bytes(), db) object.storage = make(Storage) object.gasPool = new(big.Int) object.prepaid = new(big.Int) @@ -107,12 +104,11 @@ func NewStateObjectFromBytes(address common.Address, data []byte, db common.Data } object := &StateObject{address: address, db: db} - //object.RlpDecode(data) object.nonce = extobject.Nonce object.balance = extobject.Balance object.codeHash = extobject.CodeHash - object.State = New(extobject.Root, db) - object.storage = make(map[string]*common.Value) + object.trie = trie.NewSecure(extobject.Root[:], db) + object.storage = make(map[string]common.Hash) object.gasPool = new(big.Int) object.prepaid = new(big.Int) object.code, _ = db.Get(extobject.CodeHash) @@ -129,35 +125,31 @@ func (self *StateObject) MarkForDeletion() { } } -func (c *StateObject) getAddr(addr common.Hash) *common.Value { - return common.NewValueFromBytes([]byte(c.State.trie.Get(addr[:]))) +func (c *StateObject) getAddr(addr common.Hash) common.Hash { + var ret []byte + rlp.DecodeBytes(c.trie.Get(addr[:]), &ret) + return common.BytesToHash(ret) } -func (c *StateObject) setAddr(addr []byte, value interface{}) { - c.State.trie.Update(addr, common.Encode(value)) -} - -func (self *StateObject) GetStorage(key *big.Int) *common.Value { - fmt.Printf("%v: get %v %v", self.address.Hex(), key) - return self.GetState(common.BytesToHash(key.Bytes())) -} - -func (self *StateObject) SetStorage(key *big.Int, value *common.Value) { - fmt.Printf("%v: set %v -> %v", self.address.Hex(), key, value) - self.SetState(common.BytesToHash(key.Bytes()), value) +func (c *StateObject) setAddr(addr []byte, value common.Hash) { + v, err := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) + if err != nil { + // if RLPing failed we better panic and not fail silently. This would be considered a consensus issue + panic(err) + } + c.trie.Update(addr, v) } func (self *StateObject) Storage() Storage { return self.storage } -func (self *StateObject) GetState(key common.Hash) *common.Value { +func (self *StateObject) GetState(key common.Hash) common.Hash { strkey := key.Str() - value := self.storage[strkey] - if value == nil { + value, exists := self.storage[strkey] + if !exists { value = self.getAddr(key) - - if !value.IsNil() { + if (value != common.Hash{}) { self.storage[strkey] = value } } @@ -165,15 +157,16 @@ func (self *StateObject) GetState(key common.Hash) *common.Value { return value } -func (self *StateObject) SetState(k common.Hash, value *common.Value) { - self.storage[k.Str()] = value.Copy() +func (self *StateObject) SetState(k, value common.Hash) { + self.storage[k.Str()] = value self.dirty = true } -func (self *StateObject) Sync() { +// Update updates the current cached storage to the trie +func (self *StateObject) Update() { for key, value := range self.storage { - if value.Len() == 0 { - self.State.trie.Delete([]byte(key)) + if (value == common.Hash{}) { + self.trie.Delete([]byte(key)) continue } @@ -221,20 +214,8 @@ func (c *StateObject) St() Storage { // Return the gas back to the origin. Used by the Virtual machine or Closures func (c *StateObject) ReturnGas(gas, price *big.Int) {} -func (c *StateObject) ConvertGas(gas, price *big.Int) error { - total := new(big.Int).Mul(gas, price) - if total.Cmp(c.balance) > 0 { - return fmt.Errorf("insufficient amount: %v, %v", c.balance, total) - } - c.SubBalance(total) - - c.dirty = true - - return nil -} - -func (self *StateObject) SetGasPool(gasLimit *big.Int) { +func (self *StateObject) SetGasLimit(gasLimit *big.Int) { self.gasPool = new(big.Int).Set(gasLimit) if glog.V(logger.Core) { @@ -242,7 +223,7 @@ func (self *StateObject) SetGasPool(gasLimit *big.Int) { } } -func (self *StateObject) BuyGas(gas, price *big.Int) error { +func (self *StateObject) SubGas(gas, price *big.Int) error { if self.gasPool.Cmp(gas) < 0 { return GasLimitError(self.gasPool, gas) } @@ -257,7 +238,7 @@ func (self *StateObject) BuyGas(gas, price *big.Int) error { return nil } -func (self *StateObject) RefundGas(gas, price *big.Int) { +func (self *StateObject) AddGas(gas, price *big.Int) { self.gasPool.Add(self.gasPool, gas) } @@ -266,9 +247,7 @@ func (self *StateObject) Copy() *StateObject { stateObject.balance.Set(self.balance) stateObject.codeHash = common.CopyBytes(self.codeHash) stateObject.nonce = self.nonce - if self.State != nil { - stateObject.State = self.State.Copy() - } + stateObject.trie = self.trie stateObject.code = common.CopyBytes(self.code) stateObject.initCode = common.CopyBytes(self.initCode) stateObject.storage = self.storage.Copy() @@ -306,11 +285,11 @@ func (c *StateObject) Init() Code { } func (self *StateObject) Trie() *trie.SecureTrie { - return self.State.trie + return self.trie } func (self *StateObject) Root() []byte { - return self.Trie().Root() + return self.trie.Root() } func (self *StateObject) Code() []byte { @@ -342,10 +321,10 @@ func (self *StateObject) EachStorage(cb func(key, value []byte)) { cb([]byte(h), v.Bytes()) } - it := self.State.trie.Iterator() + it := self.trie.Iterator() for it.Next() { // ignore cached values - key := self.State.trie.GetKey(it.Key) + key := self.trie.GetKey(it.Key) if _, ok := self.storage[string(key)]; !ok { cb(key, it.Value) } @@ -369,8 +348,8 @@ func (c *StateObject) RlpDecode(data []byte) { decoder := common.NewValueFromBytes(data) c.nonce = decoder.Get(0).Uint() c.balance = decoder.Get(1).BigInt() - c.State = New(common.BytesToHash(decoder.Get(2).Bytes()), c.db) //New(trie.New(common.Config.Db, decoder.Get(2).Interface())) - c.storage = make(map[string]*common.Value) + c.trie = trie.NewSecure(decoder.Get(2).Bytes(), c.db) + c.storage = make(map[string]common.Hash) c.gasPool = new(big.Int) c.codeHash = decoder.Get(3).Bytes() |