|
|
|
@ -43,7 +43,6 @@ func (s Storage) String() (str string) { |
|
|
|
|
for key, value := range s { |
|
|
|
|
str += fmt.Sprintf("%X : %X\n", key, value) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -52,7 +51,6 @@ func (s Storage) Copy() Storage { |
|
|
|
|
for key, value := range s { |
|
|
|
|
cpy[key] = value |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return cpy |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -68,13 +66,6 @@ type stateObject struct { |
|
|
|
|
data types.StateAccount |
|
|
|
|
db *StateDB |
|
|
|
|
|
|
|
|
|
// DB error.
|
|
|
|
|
// State objects are used by the consensus core and VM which are
|
|
|
|
|
// unable to deal with database-level errors. Any error that occurs
|
|
|
|
|
// during a database read is memoized here and will eventually be returned
|
|
|
|
|
// by StateDB.Commit.
|
|
|
|
|
dbErr error |
|
|
|
|
|
|
|
|
|
// Write caches.
|
|
|
|
|
trie Trie // storage trie, which becomes non-nil on first access
|
|
|
|
|
code Code // contract bytecode, which gets set when code is loaded
|
|
|
|
@ -84,7 +75,7 @@ type stateObject struct { |
|
|
|
|
dirtyStorage Storage // Storage entries that have been modified in the current transaction execution
|
|
|
|
|
|
|
|
|
|
// Cache flags.
|
|
|
|
|
// When an object is marked suicided it will be delete from the trie
|
|
|
|
|
// When an object is marked suicided it will be deleted from the trie
|
|
|
|
|
// during the "update" phase of the state transition.
|
|
|
|
|
dirtyCode bool // true if the code was updated
|
|
|
|
|
suicided bool |
|
|
|
@ -123,13 +114,6 @@ func (s *stateObject) EncodeRLP(w io.Writer) error { |
|
|
|
|
return rlp.Encode(w, &s.data) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// setError remembers the first non-nil error it is called with.
|
|
|
|
|
func (s *stateObject) setError(err error) { |
|
|
|
|
if s.dbErr == nil { |
|
|
|
|
s.dbErr = err |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (s *stateObject) markSuicided() { |
|
|
|
|
s.suicided = true |
|
|
|
|
} |
|
|
|
@ -214,7 +198,7 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has |
|
|
|
|
start := time.Now() |
|
|
|
|
tr, err := s.getTrie(db) |
|
|
|
|
if err != nil { |
|
|
|
|
s.setError(err) |
|
|
|
|
s.db.setError(err) |
|
|
|
|
return common.Hash{} |
|
|
|
|
} |
|
|
|
|
enc, err = tr.TryGet(key.Bytes()) |
|
|
|
@ -222,7 +206,7 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has |
|
|
|
|
s.db.StorageReads += time.Since(start) |
|
|
|
|
} |
|
|
|
|
if err != nil { |
|
|
|
|
s.setError(err) |
|
|
|
|
s.db.setError(err) |
|
|
|
|
return common.Hash{} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -230,7 +214,7 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has |
|
|
|
|
if len(enc) > 0 { |
|
|
|
|
_, content, _, err := rlp.Split(enc) |
|
|
|
|
if err != nil { |
|
|
|
|
s.setError(err) |
|
|
|
|
s.db.setError(err) |
|
|
|
|
} |
|
|
|
|
value.SetBytes(content) |
|
|
|
|
} |
|
|
|
@ -296,7 +280,7 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) { |
|
|
|
|
) |
|
|
|
|
tr, err := s.getTrie(db) |
|
|
|
|
if err != nil { |
|
|
|
|
s.setError(err) |
|
|
|
|
s.db.setError(err) |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
// Insert all the pending updates into the trie
|
|
|
|
@ -311,7 +295,7 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) { |
|
|
|
|
var v []byte |
|
|
|
|
if (value == common.Hash{}) { |
|
|
|
|
if err := tr.TryDelete(key[:]); err != nil { |
|
|
|
|
s.setError(err) |
|
|
|
|
s.db.setError(err) |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
s.db.StorageDeleted += 1 |
|
|
|
@ -319,7 +303,7 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) { |
|
|
|
|
// Encoding []byte cannot fail, ok to ignore the error.
|
|
|
|
|
v, _ = rlp.EncodeToBytes(common.TrimLeftZeroes(value[:])) |
|
|
|
|
if err := tr.TryUpdate(key[:], v); err != nil { |
|
|
|
|
s.setError(err) |
|
|
|
|
s.db.setError(err) |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
s.db.StorageUpdated += 1 |
|
|
|
@ -351,7 +335,6 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) { |
|
|
|
|
func (s *stateObject) updateRoot(db Database) { |
|
|
|
|
tr, err := s.updateTrie(db) |
|
|
|
|
if err != nil { |
|
|
|
|
s.setError(fmt.Errorf("updateRoot (%x) error: %w", s.address, err)) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
// If nothing changed, don't bother with hashing anything
|
|
|
|
@ -372,9 +355,6 @@ func (s *stateObject) commitTrie(db Database) (*trie.NodeSet, error) { |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
if s.dbErr != nil { |
|
|
|
|
return nil, s.dbErr |
|
|
|
|
} |
|
|
|
|
// If nothing changed, don't bother with committing anything
|
|
|
|
|
if tr == nil { |
|
|
|
|
return nil, nil |
|
|
|
@ -385,7 +365,7 @@ func (s *stateObject) commitTrie(db Database) (*trie.NodeSet, error) { |
|
|
|
|
} |
|
|
|
|
root, nodes := tr.Commit(false) |
|
|
|
|
s.data.Root = root |
|
|
|
|
return nodes, err |
|
|
|
|
return nodes, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// AddBalance adds amount to s's balance.
|
|
|
|
@ -457,7 +437,7 @@ func (s *stateObject) Code(db Database) []byte { |
|
|
|
|
} |
|
|
|
|
code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash())) |
|
|
|
|
if err != nil { |
|
|
|
|
s.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) |
|
|
|
|
s.db.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) |
|
|
|
|
} |
|
|
|
|
s.code = code |
|
|
|
|
return code |
|
|
|
@ -475,7 +455,7 @@ func (s *stateObject) CodeSize(db Database) int { |
|
|
|
|
} |
|
|
|
|
size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash())) |
|
|
|
|
if err != nil { |
|
|
|
|
s.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err)) |
|
|
|
|
s.db.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err)) |
|
|
|
|
} |
|
|
|
|
return size |
|
|
|
|
} |
|
|
|
@ -519,10 +499,3 @@ func (s *stateObject) Balance() *big.Int { |
|
|
|
|
func (s *stateObject) Nonce() uint64 { |
|
|
|
|
return s.data.Nonce |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Value is never called, but must be present to allow stateObject to be used
|
|
|
|
|
// as a vm.Account interface that also satisfies the vm.ContractRef
|
|
|
|
|
// interface. Interfaces are awesome.
|
|
|
|
|
func (s *stateObject) Value() *big.Int { |
|
|
|
|
panic("Value on stateObject should never be called") |
|
|
|
|
} |
|
|
|
|