Add prefix for validator wrapper (#4402)

* add separate prefix for validator wrapper

* update comments

* make read/write backward compatible

* add validator codes to stats

* goimports

* goimports accessor_state
pull/4409/head
Gheis Mohammadi 2 years ago committed by GitHub
parent 7d47d9e8a9
commit 53161ca33c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      core/genesis.go
  2. 54
      core/rawdb/accessors_state.go
  3. 4
      core/rawdb/database.go
  4. 17
      core/rawdb/schema.go
  5. 47
      core/state/database.go
  6. 2
      core/state/dump.go
  7. 6
      core/state/iterator.go
  8. 2
      core/state/iterator_test.go
  9. 2
      core/state/journal.go
  10. 2
      core/state/prefeth.go
  11. 37
      core/state/state_object.go
  12. 8
      core/state/state_test.go
  13. 23
      core/state/statedb.go
  14. 36
      core/state/statedb_test.go
  15. 2
      core/state/trie_prefetcher_test.go
  16. 2
      core/vm/contracts_write.go
  17. 10
      core/vm/evm.go
  18. 2
      core/vm/gas_table_test.go
  19. 4
      core/vm/instructions.go
  20. 6
      core/vm/interface.go
  21. 2
      core/vm/logger_test.go
  22. 2
      core/vm/runtime/runtime.go
  23. 4
      core/vm/runtime/runtime_test.go
  24. 2
      hmy/tracers/block_tracer.go
  25. 2
      hmy/tracers/tracer.go
  26. 4
      rosetta/services/block.go
  27. 2
      rosetta/services/construction_check.go
  28. 2
      rpc/contract.go
  29. 6
      staking/availability/measure_test.go

@ -247,7 +247,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) statedb, _ := state.New(common.Hash{}, state.NewDatabase(db), nil)
for addr, account := range g.Alloc { for addr, account := range g.Alloc {
statedb.AddBalance(addr, account.Balance) statedb.AddBalance(addr, account.Balance)
statedb.SetCode(addr, account.Code) statedb.SetCode(addr, account.Code, false)
statedb.SetNonce(addr, account.Nonce) statedb.SetNonce(addr, account.Nonce)
for key, value := range account.Storage { for key, value := range account.Storage {
statedb.SetState(addr, key, value) statedb.SetState(addr, key, value)

@ -93,3 +93,57 @@ func DeleteCode(db ethdb.KeyValueWriter, hash common.Hash) {
utils.Logger().Error().Err(err).Msg("Failed to delete contract code") utils.Logger().Error().Err(err).Msg("Failed to delete contract code")
} }
} }
// ReadValidatorCode retrieves the validator code of the provided code hash.
func ReadValidatorCode(db ethdb.KeyValueReader, hash common.Hash) []byte {
// Try with the prefixed code scheme first, if not then try with legacy
// scheme.
data := ReadValidatorCodeWithPrefix(db, hash)
if len(data) != 0 {
return data
}
data, _ = db.Get(hash.Bytes())
return data
}
// ReadValidatorCodeWithPrefix retrieves the validator code of the provided code hash.
// The main difference between this function and ReadValidatorCode is this function
// will only check the existence with latest scheme(with prefix).
func ReadValidatorCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) []byte {
data, _ := db.Get(validatorCodeKey(hash))
return data
}
// HasValidatorCode checks if the validator code corresponding to the
// provided code hash is present in the db.
func HasValidatorCode(db ethdb.KeyValueReader, hash common.Hash) bool {
// Try with the prefixed code scheme first, if not then try with legacy
// scheme.
if ok := HasValidatorCodeWithPrefix(db, hash); ok {
return true
}
ok, _ := db.Has(hash.Bytes())
return ok
}
// HasValidatorCodeWithPrefix checks if the validator code corresponding to the
// provided code hash is present in the db. This function will only check
// presence using the prefix-scheme.
func HasValidatorCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) bool {
ok, _ := db.Has(validatorCodeKey(hash))
return ok
}
// WriteValidatorCode writes the provided validator code to database.
func WriteValidatorCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) {
if err := db.Put(validatorCodeKey(hash), code); err != nil {
utils.Logger().Error().Err(err).Msg("Failed to store validator code")
}
}
// DeleteValidatorCode deletes the specified validator code from the database.
func DeleteValidatorCode(db ethdb.KeyValueWriter, hash common.Hash) {
if err := db.Delete(validatorCodeKey(hash)); err != nil {
utils.Logger().Error().Err(err).Msg("Failed to delete validator code")
}
}

@ -316,6 +316,7 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
hashNumPairings stat hashNumPairings stat
tries stat tries stat
codes stat codes stat
validatorCodes stat
txLookups stat txLookups stat
accountSnaps stat accountSnaps stat
storageSnaps stat storageSnaps stat
@ -359,6 +360,8 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
tries.Add(size) tries.Add(size)
case bytes.HasPrefix(key, CodePrefix) && len(key) == len(CodePrefix)+common.HashLength: case bytes.HasPrefix(key, CodePrefix) && len(key) == len(CodePrefix)+common.HashLength:
codes.Add(size) codes.Add(size)
case bytes.HasPrefix(key, ValidatorCodePrefix) && len(key) == len(ValidatorCodePrefix)+common.HashLength:
validatorCodes.Add(size)
case bytes.HasPrefix(key, txLookupPrefix) && len(key) == (len(txLookupPrefix)+common.HashLength): case bytes.HasPrefix(key, txLookupPrefix) && len(key) == (len(txLookupPrefix)+common.HashLength):
txLookups.Add(size) txLookups.Add(size)
case bytes.HasPrefix(key, SnapshotAccountPrefix) && len(key) == (len(SnapshotAccountPrefix)+common.HashLength): case bytes.HasPrefix(key, SnapshotAccountPrefix) && len(key) == (len(SnapshotAccountPrefix)+common.HashLength):
@ -422,6 +425,7 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
{"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()}, {"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()},
{"Key-Value store", "Bloombit index", bloomBits.Size(), bloomBits.Count()}, {"Key-Value store", "Bloombit index", bloomBits.Size(), bloomBits.Count()},
{"Key-Value store", "Contract codes", codes.Size(), codes.Count()}, {"Key-Value store", "Contract codes", codes.Size(), codes.Count()},
{"Key-Value store", "Validator codes", validatorCodes.Size(), validatorCodes.Count()},
{"Key-Value store", "Trie nodes", tries.Size(), tries.Count()}, {"Key-Value store", "Trie nodes", tries.Size(), tries.Count()},
{"Key-Value store", "Trie preimages", preimages.Size(), preimages.Count()}, {"Key-Value store", "Trie preimages", preimages.Size(), preimages.Count()},
{"Key-Value store", "Account snapshot", accountSnaps.Size(), accountSnaps.Count()}, {"Key-Value store", "Account snapshot", accountSnaps.Size(), accountSnaps.Count()},

@ -128,7 +128,8 @@ var (
// Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes). // Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes).
SnapshotAccountPrefix = []byte("a") // SnapshotAccountPrefix + account hash -> account trie value SnapshotAccountPrefix = []byte("a") // SnapshotAccountPrefix + account hash -> account trie value
SnapshotStoragePrefix = []byte("o") // SnapshotStoragePrefix + account hash + storage hash -> storage trie value SnapshotStoragePrefix = []byte("o") // SnapshotStoragePrefix + account hash + storage hash -> storage trie value
CodePrefix = []byte("c") // CodePrefix + code hash -> account code -> We not using this at the moment CodePrefix = []byte("c") // CodePrefix + code hash -> account code
ValidatorCodePrefix = []byte("vc") // ValidatorCodePrefix + code hash -> validator code
skeletonHeaderPrefix = []byte("S") // skeletonHeaderPrefix + num (uint64 big endian) -> header skeletonHeaderPrefix = []byte("S") // skeletonHeaderPrefix + num (uint64 big endian) -> header
// Path-based trie node scheme. // Path-based trie node scheme.
@ -196,6 +197,20 @@ func IsCodeKey(key []byte) (bool, []byte) {
return false, nil return false, nil
} }
// validatorCodeKey = ValidatorCodePrefix + hash
func validatorCodeKey(hash common.Hash) []byte {
return append(ValidatorCodePrefix, hash.Bytes()...)
}
// IsValidatorCodeKey reports whether the given byte slice is the key of validator code,
// if so return the raw code hash as well.
func IsValidatorCodeKey(key []byte) (bool, []byte) {
if bytes.HasPrefix(key, ValidatorCodePrefix) && len(key) == common.HashLength+len(ValidatorCodePrefix) {
return true, key[len(ValidatorCodePrefix):]
}
return false, nil
}
// genesisStateSpecKey = genesisPrefix + hash // genesisStateSpecKey = genesisPrefix + hash
func genesisStateSpecKey(hash common.Hash) []byte { func genesisStateSpecKey(hash common.Hash) []byte {
return append(genesisPrefix, hash.Bytes()...) return append(genesisPrefix, hash.Bytes()...)

@ -53,6 +53,12 @@ type Database interface {
// ContractCodeSize retrieves a particular contracts code's size. // ContractCodeSize retrieves a particular contracts code's size.
ContractCodeSize(addrHash, codeHash common.Hash) (int, error) ContractCodeSize(addrHash, codeHash common.Hash) (int, error)
// ValidatorCode retrieves a particular validator's code.
ValidatorCode(addrHash, codeHash common.Hash) ([]byte, error)
// ValidatorCodeSize retrieves a particular validator code's size.
ValidatorCodeSize(addrHash, codeHash common.Hash) (int, error)
// DiskDB returns the underlying key-value disk database. // DiskDB returns the underlying key-value disk database.
DiskDB() ethdb.KeyValueStore DiskDB() ethdb.KeyValueStore
@ -234,6 +240,47 @@ func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, erro
return len(code), err return len(code), err
} }
// ValidatorCodeSize retrieves a particular validators code's size.
func (db *cachingDB) ValidatorCodeSize(addrHash, codeHash common.Hash) (int, error) {
if cached, ok := db.codeSizeCache.Get(codeHash); ok {
return cached, nil
}
code, err := db.ValidatorCode(addrHash, codeHash)
return len(code), err
}
// ValidatorCode retrieves a particular validator's code.
func (db *cachingDB) ValidatorCode(addrHash, codeHash common.Hash) ([]byte, error) {
code, _ := db.codeCache.Get(codeHash)
if len(code) > 0 {
return code, nil
}
code = rawdb.ReadValidatorCode(db.disk, codeHash)
if len(code) > 0 {
db.codeCache.Add(codeHash, code)
db.codeSizeCache.Add(codeHash, len(code))
return code, nil
}
return nil, errors.New("not found")
}
// ValidatorCodeWithPrefix retrieves a particular validator's code. If the
// code can't be found in the cache, then check the existence with **new**
// db scheme.
func (db *cachingDB) ValidatorCodeWithPrefix(addrHash, codeHash common.Hash) ([]byte, error) {
code, _ := db.codeCache.Get(codeHash)
if len(code) > 0 {
return code, nil
}
code = rawdb.ReadValidatorCodeWithPrefix(db.disk, codeHash)
if len(code) > 0 {
db.codeCache.Add(codeHash, code)
db.codeSizeCache.Add(codeHash, len(code))
return code, nil
}
return nil, errors.New("not found")
}
// DiskDB returns the underlying key-value disk database. // DiskDB returns the underlying key-value disk database.
func (db *cachingDB) DiskDB() ethdb.KeyValueStore { func (db *cachingDB) DiskDB() ethdb.KeyValueStore {
return db.disk return db.disk

@ -165,7 +165,7 @@ func (s *DB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []byte)
addr := common.BytesToAddress(addrBytes) addr := common.BytesToAddress(addrBytes)
obj := newObject(s, addr, data) obj := newObject(s, addr, data)
if !conf.SkipCode { if !conf.SkipCode {
account.Code = obj.Code(s.db) account.Code = obj.Code(s.db, false)
} }
if !conf.SkipStorage { if !conf.SkipStorage {
account.Storage = make(map[common.Hash]string) account.Storage = make(map[common.Hash]string)

@ -124,6 +124,12 @@ func (it *NodeIterator) step() error {
if err != nil { if err != nil {
return fmt.Errorf("code %x: %v", account.CodeHash, err) return fmt.Errorf("code %x: %v", account.CodeHash, err)
} }
if it.code == nil || len(it.code) == 0 {
it.code, err = it.state.db.ValidatorCode(addrHash, common.BytesToHash(account.CodeHash))
if err != nil {
return fmt.Errorf("code %x: %v", account.CodeHash, err)
}
}
} }
it.accountHash = it.stateIt.Parent() it.accountHash = it.stateIt.Parent()
return nil return nil

@ -54,7 +54,7 @@ func makeTestState() (ethdb.Database, Database, common.Hash, []*testAccount) {
acc.nonce = uint64(42 * i) acc.nonce = uint64(42 * i)
if i%3 == 0 { if i%3 == 0 {
obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i}), []byte{i, i, i, i, i}) obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i}), []byte{i, i, i, i, i}, false)
acc.code = []byte{i, i, i, i, i} acc.code = []byte{i, i, i, i, i}
} }
if i%5 == 0 { if i%5 == 0 {

@ -217,7 +217,7 @@ func (ch nonceChange) dirtied() *common.Address {
} }
func (ch codeChange) revert(s *DB) { func (ch codeChange) revert(s *DB) {
s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode) s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode, false)
} }
func (ch codeChange) dirtied() *common.Address { func (ch codeChange) dirtied() *common.Address {

@ -100,7 +100,7 @@ func (s *DB) prefetchWorker(job *prefetchJob, jobs chan *prefetchJob) {
addr := common.BytesToAddress(addrBytes) addr := common.BytesToAddress(addrBytes)
obj := newObject(s, addr, data) obj := newObject(s, addr, data)
if data.CodeHash != nil { if data.CodeHash != nil {
obj.Code(s.db) obj.Code(s.db, false)
} }
// build account trie tree // build account trie tree

@ -93,6 +93,7 @@ type Object struct {
// Cache flags. // Cache flags.
// When an object is marked suicided it will be delete from the trie // When an object is marked suicided it will be delete from the trie
// during the "update" phase of the state transition. // during the "update" phase of the state transition.
validatorWrapper bool // true if the code belongs to validator wrapper
dirtyCode bool // true if the code was updated dirtyCode bool // true if the code was updated
suicided bool suicided bool
deleted bool deleted bool
@ -497,14 +498,24 @@ func (s *Object) Address() common.Address {
return s.address return s.address
} }
// Code returns the contract code associated with this object, if any. // Code returns the contract/validator code associated with this object, if any.
func (s *Object) Code(db Database) []byte { func (s *Object) Code(db Database, isValidatorCode bool) []byte {
if s.code != nil { if s.code != nil {
return s.code return s.code
} }
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
return nil return nil
} }
if s.validatorWrapper || isValidatorCode {
code, err := db.ValidatorCode(s.addrHash, common.BytesToHash(s.CodeHash()))
if err != nil {
s.setError(fmt.Errorf("can't load validator code hash %x: %v", s.CodeHash(), err))
}
if code != nil {
s.code = code
return code
}
}
code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash())) code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash()))
if err != nil { if err != nil {
s.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) s.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err))
@ -513,16 +524,25 @@ func (s *Object) Code(db Database) []byte {
return code return code
} }
// CodeSize returns the size of the contract code associated with this object, // CodeSize returns the size of the contract/validator code associated with this object,
// or zero if none. This method is an almost mirror of Code, but uses a cache // or zero if none. This method is an almost mirror of Code, but uses a cache
// inside the database to avoid loading codes seen recently. // inside the database to avoid loading codes seen recently.
func (s *Object) CodeSize(db Database) int { func (s *Object) CodeSize(db Database, isValidatorCode bool) int {
if s.code != nil { if s.code != nil {
return len(s.code) return len(s.code)
} }
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
return 0 return 0
} }
if s.validatorWrapper || isValidatorCode {
size, err := db.ValidatorCodeSize(s.addrHash, common.BytesToHash(s.CodeHash()))
if err != nil {
s.setError(fmt.Errorf("can't load validator code size %x: %v", s.CodeHash(), err))
}
if size > 0 {
return size
}
}
size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash())) size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash()))
if err != nil { if err != nil {
s.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err)) s.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err))
@ -530,20 +550,21 @@ func (s *Object) CodeSize(db Database) int {
return size return size
} }
func (s *Object) SetCode(codeHash common.Hash, code []byte) { func (s *Object) SetCode(codeHash common.Hash, code []byte, isValidatorCode bool) {
prevcode := s.Code(s.db.db) prevcode := s.Code(s.db.db, isValidatorCode)
s.db.journal.append(codeChange{ s.db.journal.append(codeChange{
account: &s.address, account: &s.address,
prevhash: s.CodeHash(), prevhash: s.CodeHash(),
prevcode: prevcode, prevcode: prevcode,
}) })
s.setCode(codeHash, code) s.setCode(codeHash, code, isValidatorCode)
} }
func (s *Object) setCode(codeHash common.Hash, code []byte) { func (s *Object) setCode(codeHash common.Hash, code []byte, isValidatorCode bool) {
s.code = code s.code = code
s.data.CodeHash = codeHash[:] s.data.CodeHash = codeHash[:]
s.dirtyCode = true s.dirtyCode = true
s.validatorWrapper = isValidatorCode
} }
func (s *Object) SetNonce(nonce uint64) { func (s *Object) SetNonce(nonce uint64) {

@ -48,7 +48,7 @@ func TestDump(t *testing.T) {
obj1 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x01})) obj1 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x01}))
obj1.AddBalance(big.NewInt(22)) obj1.AddBalance(big.NewInt(22))
obj2 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02})) obj2 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02}))
obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}, false)
obj3 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x02})) obj3 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x02}))
obj3.SetBalance(big.NewInt(44)) obj3.SetBalance(big.NewInt(44))
@ -166,7 +166,7 @@ func TestSnapshot2(t *testing.T) {
so0 := state.getStateObject(stateobjaddr0) so0 := state.getStateObject(stateobjaddr0)
so0.SetBalance(big.NewInt(42)) so0.SetBalance(big.NewInt(42))
so0.SetNonce(43) so0.SetNonce(43)
so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}, false)
so0.suicided = false so0.suicided = false
so0.deleted = false so0.deleted = false
state.setStateObject(so0) state.setStateObject(so0)
@ -178,7 +178,7 @@ func TestSnapshot2(t *testing.T) {
so1 := state.getStateObject(stateobjaddr1) so1 := state.getStateObject(stateobjaddr1)
so1.SetBalance(big.NewInt(52)) so1.SetBalance(big.NewInt(52))
so1.SetNonce(53) so1.SetNonce(53)
so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'}) so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'}, false)
so1.suicided = true so1.suicided = true
so1.deleted = true so1.deleted = true
state.setStateObject(so1) state.setStateObject(so1)
@ -194,7 +194,7 @@ func TestSnapshot2(t *testing.T) {
so0Restored := state.getStateObject(stateobjaddr0) so0Restored := state.getStateObject(stateobjaddr0)
// Update lazily-loaded values before comparing. // Update lazily-loaded values before comparing.
so0Restored.GetState(state.db, storageaddr) so0Restored.GetState(state.db, storageaddr)
so0Restored.Code(state.db) so0Restored.Code(state.db, false)
// non-deleted is equal (restored) // non-deleted is equal (restored)
compareStateObjects(so0Restored, so0, t) compareStateObjects(so0Restored, so0, t)

@ -342,18 +342,18 @@ func (db *DB) BlockHash() common.Hash {
return db.bhash return db.bhash
} }
func (db *DB) GetCode(addr common.Address) []byte { func (db *DB) GetCode(addr common.Address, isValidatorCode bool) []byte {
Object := db.getStateObject(addr) Object := db.getStateObject(addr)
if Object != nil { if Object != nil {
return Object.Code(db.db) return Object.Code(db.db, isValidatorCode)
} }
return nil return nil
} }
func (db *DB) GetCodeSize(addr common.Address) int { func (db *DB) GetCodeSize(addr common.Address, isValidatorCode bool) int {
Object := db.getStateObject(addr) Object := db.getStateObject(addr)
if Object != nil { if Object != nil {
return Object.CodeSize(db.db) return Object.CodeSize(db.db, isValidatorCode)
} }
return 0 return 0
} }
@ -475,10 +475,10 @@ func (db *DB) SetNonce(addr common.Address, nonce uint64) {
} }
} }
func (db *DB) SetCode(addr common.Address, code []byte) { func (db *DB) SetCode(addr common.Address, code []byte, isValidatorCode bool) {
Object := db.GetOrNewStateObject(addr) Object := db.GetOrNewStateObject(addr)
if Object != nil { if Object != nil {
Object.SetCode(crypto.Keccak256Hash(code), code) Object.SetCode(crypto.Keccak256Hash(code), code, isValidatorCode)
} }
} }
@ -1053,7 +1053,11 @@ func (db *DB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
if obj := db.stateObjects[addr]; !obj.deleted { if obj := db.stateObjects[addr]; !obj.deleted {
// Write any contract code associated with the state object // Write any contract code associated with the state object
if obj.code != nil && obj.dirtyCode { if obj.code != nil && obj.dirtyCode {
if obj.validatorWrapper {
rawdb.WriteValidatorCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code)
} else {
rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code) rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code)
}
obj.dirtyCode = false obj.dirtyCode = false
} }
// Write any storage changes in the state object to its storage trie // Write any storage changes in the state object to its storage trie
@ -1237,10 +1241,13 @@ func (db *DB) ValidatorWrapper(
return copyValidatorWrapperIfNeeded(cached, sendOriginal, copyDelegations), nil return copyValidatorWrapperIfNeeded(cached, sendOriginal, copyDelegations), nil
} }
by := db.GetCode(addr) by := db.GetCode(addr, true)
if len(by) == 0 {
by = db.GetCode(addr, false)
if len(by) == 0 { if len(by) == 0 {
return nil, ErrAddressNotPresent return nil, ErrAddressNotPresent
} }
}
val := stk.ValidatorWrapper{} val := stk.ValidatorWrapper{}
if err := rlp.DecodeBytes(by, &val); err != nil { if err := rlp.DecodeBytes(by, &val); err != nil {
return nil, errors.Wrapf( return nil, errors.Wrapf(
@ -1285,7 +1292,7 @@ func (db *DB) UpdateValidatorWrapper(
return err return err
} }
// has revert in-built for the code field // has revert in-built for the code field
db.SetCode(addr, by) db.SetCode(addr, by, true)
// update cache // update cache
db.stateValidators[addr] = val db.stateValidators[addr] = val
return nil return nil

@ -50,7 +50,7 @@ func TestUpdateLeaks(t *testing.T) {
state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i})) state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i}))
} }
if i%3 == 0 { if i%3 == 0 {
state.SetCode(addr, []byte{i, i, i, i, i}) state.SetCode(addr, []byte{i, i, i, i, i}, false)
} }
} }
@ -84,7 +84,7 @@ func TestIntermediateLeaks(t *testing.T) {
state.SetState(addr, common.Hash{i, i, i, tweak}, common.Hash{i, i, i, i, tweak}) state.SetState(addr, common.Hash{i, i, i, tweak}, common.Hash{i, i, i, i, tweak})
} }
if i%3 == 0 { if i%3 == 0 {
state.SetCode(addr, []byte{i, i, i, i, i, tweak}) state.SetCode(addr, []byte{i, i, i, i, i, tweak}, false)
} }
} }
@ -286,7 +286,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction {
code := make([]byte, 16) code := make([]byte, 16)
binary.BigEndian.PutUint64(code, uint64(a.args[0])) binary.BigEndian.PutUint64(code, uint64(a.args[0]))
binary.BigEndian.PutUint64(code[8:], uint64(a.args[1])) binary.BigEndian.PutUint64(code[8:], uint64(a.args[1]))
s.SetCode(addr, code) s.SetCode(addr, code, false)
}, },
args: make([]int64, 2), args: make([]int64, 2),
}, },
@ -452,9 +452,9 @@ func (test *snapshotTest) checkEqual(state, checkstate *DB) error {
checkeq("HasSuicided", state.HasSuicided(addr), checkstate.HasSuicided(addr)) checkeq("HasSuicided", state.HasSuicided(addr), checkstate.HasSuicided(addr))
checkeq("GetBalance", state.GetBalance(addr), checkstate.GetBalance(addr)) checkeq("GetBalance", state.GetBalance(addr), checkstate.GetBalance(addr))
checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr)) checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr))
checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr)) checkeq("GetCode", state.GetCode(addr, false), checkstate.GetCode(addr, false))
checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr)) checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr))
checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr)) checkeq("GetCodeSize", state.GetCodeSize(addr, false), checkstate.GetCodeSize(addr, false))
// Check storage. // Check storage.
if obj := state.getStateObject(addr); obj != nil { if obj := state.getStateObject(addr); obj != nil {
state.ForEachStorage(addr, func(key, value common.Hash) bool { state.ForEachStorage(addr, func(key, value common.Hash) bool {
@ -526,13 +526,13 @@ func TestCopyCommitCopy(t *testing.T) {
sval := common.HexToHash("bbb") sval := common.HexToHash("bbb")
state.SetBalance(addr, big.NewInt(42)) // Change the account trie state.SetBalance(addr, big.NewInt(42)) // Change the account trie
state.SetCode(addr, []byte("hello")) // Change an external metadata state.SetCode(addr, []byte("hello"), false) // Change an external metadata
state.SetState(addr, skey, sval) // Change the storage trie state.SetState(addr, skey, sval) // Change the storage trie
if balance := state.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { if balance := state.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42) t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42)
} }
if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) { if code := state.GetCode(addr, false); !bytes.Equal(code, []byte("hello")) {
t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello")) t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello"))
} }
if val := state.GetState(addr, skey); val != sval { if val := state.GetState(addr, skey); val != sval {
@ -546,7 +546,7 @@ func TestCopyCommitCopy(t *testing.T) {
if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("first copy pre-commit balance mismatch: have %v, want %v", balance, 42) t.Fatalf("first copy pre-commit balance mismatch: have %v, want %v", balance, 42)
} }
if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) { if code := copyOne.GetCode(addr, false); !bytes.Equal(code, []byte("hello")) {
t.Fatalf("first copy pre-commit code mismatch: have %x, want %x", code, []byte("hello")) t.Fatalf("first copy pre-commit code mismatch: have %x, want %x", code, []byte("hello"))
} }
if val := copyOne.GetState(addr, skey); val != sval { if val := copyOne.GetState(addr, skey); val != sval {
@ -560,7 +560,7 @@ func TestCopyCommitCopy(t *testing.T) {
if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("first copy post-commit balance mismatch: have %v, want %v", balance, 42) t.Fatalf("first copy post-commit balance mismatch: have %v, want %v", balance, 42)
} }
if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) { if code := copyOne.GetCode(addr, false); !bytes.Equal(code, []byte("hello")) {
t.Fatalf("first copy post-commit code mismatch: have %x, want %x", code, []byte("hello")) t.Fatalf("first copy post-commit code mismatch: have %x, want %x", code, []byte("hello"))
} }
if val := copyOne.GetState(addr, skey); val != sval { if val := copyOne.GetState(addr, skey); val != sval {
@ -574,7 +574,7 @@ func TestCopyCommitCopy(t *testing.T) {
if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("second copy balance mismatch: have %v, want %v", balance, 42) t.Fatalf("second copy balance mismatch: have %v, want %v", balance, 42)
} }
if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) { if code := copyTwo.GetCode(addr, false); !bytes.Equal(code, []byte("hello")) {
t.Fatalf("second copy code mismatch: have %x, want %x", code, []byte("hello")) t.Fatalf("second copy code mismatch: have %x, want %x", code, []byte("hello"))
} }
if val := copyTwo.GetState(addr, skey); val != sval { if val := copyTwo.GetState(addr, skey); val != sval {
@ -598,13 +598,13 @@ func TestCopyCopyCommitCopy(t *testing.T) {
sval := common.HexToHash("bbb") sval := common.HexToHash("bbb")
state.SetBalance(addr, big.NewInt(42)) // Change the account trie state.SetBalance(addr, big.NewInt(42)) // Change the account trie
state.SetCode(addr, []byte("hello")) // Change an external metadata state.SetCode(addr, []byte("hello"), false) // Change an external metadata
state.SetState(addr, skey, sval) // Change the storage trie state.SetState(addr, skey, sval) // Change the storage trie
if balance := state.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { if balance := state.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42) t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42)
} }
if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) { if code := state.GetCode(addr, false); !bytes.Equal(code, []byte("hello")) {
t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello")) t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello"))
} }
if val := state.GetState(addr, skey); val != sval { if val := state.GetState(addr, skey); val != sval {
@ -618,7 +618,7 @@ func TestCopyCopyCommitCopy(t *testing.T) {
if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("first copy balance mismatch: have %v, want %v", balance, 42) t.Fatalf("first copy balance mismatch: have %v, want %v", balance, 42)
} }
if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) { if code := copyOne.GetCode(addr, false); !bytes.Equal(code, []byte("hello")) {
t.Fatalf("first copy code mismatch: have %x, want %x", code, []byte("hello")) t.Fatalf("first copy code mismatch: have %x, want %x", code, []byte("hello"))
} }
if val := copyOne.GetState(addr, skey); val != sval { if val := copyOne.GetState(addr, skey); val != sval {
@ -632,7 +632,7 @@ func TestCopyCopyCommitCopy(t *testing.T) {
if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("second copy pre-commit balance mismatch: have %v, want %v", balance, 42) t.Fatalf("second copy pre-commit balance mismatch: have %v, want %v", balance, 42)
} }
if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) { if code := copyTwo.GetCode(addr, false); !bytes.Equal(code, []byte("hello")) {
t.Fatalf("second copy pre-commit code mismatch: have %x, want %x", code, []byte("hello")) t.Fatalf("second copy pre-commit code mismatch: have %x, want %x", code, []byte("hello"))
} }
if val := copyTwo.GetState(addr, skey); val != sval { if val := copyTwo.GetState(addr, skey); val != sval {
@ -645,7 +645,7 @@ func TestCopyCopyCommitCopy(t *testing.T) {
if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("second copy post-commit balance mismatch: have %v, want %v", balance, 42) t.Fatalf("second copy post-commit balance mismatch: have %v, want %v", balance, 42)
} }
if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) { if code := copyTwo.GetCode(addr, false); !bytes.Equal(code, []byte("hello")) {
t.Fatalf("second copy post-commit code mismatch: have %x, want %x", code, []byte("hello")) t.Fatalf("second copy post-commit code mismatch: have %x, want %x", code, []byte("hello"))
} }
if val := copyTwo.GetState(addr, skey); val != sval { if val := copyTwo.GetState(addr, skey); val != sval {
@ -659,7 +659,7 @@ func TestCopyCopyCommitCopy(t *testing.T) {
if balance := copyThree.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { if balance := copyThree.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("third copy balance mismatch: have %v, want %v", balance, 42) t.Fatalf("third copy balance mismatch: have %v, want %v", balance, 42)
} }
if code := copyThree.GetCode(addr); !bytes.Equal(code, []byte("hello")) { if code := copyThree.GetCode(addr, false); !bytes.Equal(code, []byte("hello")) {
t.Fatalf("third copy code mismatch: have %x, want %x", code, []byte("hello")) t.Fatalf("third copy code mismatch: have %x, want %x", code, []byte("hello"))
} }
if val := copyThree.GetState(addr, skey); val != sval { if val := copyThree.GetState(addr, skey); val != sval {
@ -717,10 +717,10 @@ func TestMissingTrieNodes(t *testing.T) {
addr := common.BytesToAddress([]byte("so")) addr := common.BytesToAddress([]byte("so"))
{ {
state.SetBalance(addr, big.NewInt(1)) state.SetBalance(addr, big.NewInt(1))
state.SetCode(addr, []byte{1, 2, 3}) state.SetCode(addr, []byte{1, 2, 3}, false)
a2 := common.BytesToAddress([]byte("another")) a2 := common.BytesToAddress([]byte("another"))
state.SetBalance(a2, big.NewInt(100)) state.SetBalance(a2, big.NewInt(100))
state.SetCode(a2, []byte{1, 2, 4}) state.SetCode(a2, []byte{1, 2, 4}, false)
root, _ = state.Commit(false) root, _ = state.Commit(false)
t.Logf("root: %x", root) t.Logf("root: %x", root)
// force-flush // force-flush

@ -34,7 +34,7 @@ func filledStateDB() *DB {
sval := common.HexToHash("bbb") sval := common.HexToHash("bbb")
state.SetBalance(addr, big.NewInt(42)) // Change the account trie state.SetBalance(addr, big.NewInt(42)) // Change the account trie
state.SetCode(addr, []byte("hello")) // Change an external metadata state.SetCode(addr, []byte("hello"), false) // Change an external metadata
state.SetState(addr, skey, sval) // Change the storage trie state.SetState(addr, skey, sval) // Change the storage trie
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
sk := common.BigToHash(big.NewInt(int64(i))) sk := common.BigToHash(big.NewInt(int64(i)))

@ -242,7 +242,7 @@ func (c *crossShardXferPrecompile) RunWriteCapable(
return nil, err return nil, err
} }
// validate not a contract (toAddress can still be a contract) // validate not a contract (toAddress can still be a contract)
if len(evm.StateDB.GetCode(fromAddress)) > 0 && !evm.IsValidator(evm.StateDB, fromAddress) { if len(evm.StateDB.GetCode(fromAddress, false)) > 0 && !evm.IsValidator(evm.StateDB, fromAddress) {
return nil, errors.New("cross shard xfer not yet implemented for contracts") return nil, errors.New("cross shard xfer not yet implemented for contracts")
} }
// can't have too many shards // can't have too many shards

@ -336,7 +336,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value, txType) evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value, txType)
codeHash := evm.StateDB.GetCodeHash(addr) codeHash := evm.StateDB.GetCodeHash(addr)
code := evm.StateDB.GetCode(addr) code := evm.StateDB.GetCode(addr, false)
// If address is a validator address, then it's not a smart contract address // If address is a validator address, then it's not a smart contract address
// we don't use its code and codeHash fields // we don't use its code and codeHash fields
if evm.Context.IsValidator(evm.StateDB, addr) { if evm.Context.IsValidator(evm.StateDB, addr) {
@ -402,7 +402,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// EVM. The contract is a scoped environment for this execution context // EVM. The contract is a scoped environment for this execution context
// only. // only.
contract := NewContract(caller, to, value, gas) contract := NewContract(caller, to, value, gas)
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr, false))
ret, err = run(evm, contract, input, false) ret, err = run(evm, contract, input, false)
if err != nil { if err != nil {
@ -435,7 +435,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
// Initialise a new contract and make initialise the delegate values // Initialise a new contract and make initialise the delegate values
contract := NewContract(caller, to, nil, gas).AsDelegate() contract := NewContract(caller, to, nil, gas).AsDelegate()
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr, false))
ret, err = run(evm, contract, input, false) ret, err = run(evm, contract, input, false)
if err != nil { if err != nil {
@ -468,7 +468,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
// EVM. The contract is a scoped environment for this execution context // EVM. The contract is a scoped environment for this execution context
// only. // only.
contract := NewContract(caller, to, new(big.Int), gas) contract := NewContract(caller, to, new(big.Int), gas)
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr, false))
// We do an AddBalance of zero here, just in order to trigger a touch. // We do an AddBalance of zero here, just in order to trigger a touch.
// This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium,
@ -553,7 +553,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
if err == nil && !maxCodeSizeExceeded { if err == nil && !maxCodeSizeExceeded {
createDataGas := uint64(len(ret)) * params.CreateDataGas createDataGas := uint64(len(ret)) * params.CreateDataGas
if contract.UseGas(createDataGas) { if contract.UseGas(createDataGas) {
evm.StateDB.SetCode(address, ret) evm.StateDB.SetCode(address, ret, false)
} else { } else {
err = ErrCodeStoreOutOfGas err = ErrCodeStoreOutOfGas
} }

@ -85,7 +85,7 @@ func TestEIP2200(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb.CreateAccount(address) statedb.CreateAccount(address)
statedb.SetCode(address, hexutil.MustDecode(tt.input)) statedb.SetCode(address, hexutil.MustDecode(tt.input), false)
statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original})) statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
statedb.Finalise(true) // Push the state into the "original" slot statedb.Finalise(true) // Push the state into the "original" slot

@ -488,7 +488,7 @@ func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract,
slot.SetUint64(0) slot.SetUint64(0)
return nil, nil return nil, nil
} }
slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(common.BigToAddress(slot)))) slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(common.BigToAddress(slot), false)))
return nil, nil return nil, nil
} }
@ -528,7 +528,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract,
// for EOAs that are not validators, statedb returns nil // for EOAs that are not validators, statedb returns nil
code = nil code = nil
} else { } else {
code = interpreter.evm.StateDB.GetCode(addr) code = interpreter.evm.StateDB.GetCode(addr, false)
} }
codeCopy := getDataBig(code, codeOffset, length) codeCopy := getDataBig(code, codeOffset, length)
memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)

@ -38,9 +38,9 @@ type StateDB interface {
SetNonce(common.Address, uint64) SetNonce(common.Address, uint64)
GetCodeHash(common.Address) common.Hash GetCodeHash(common.Address) common.Hash
GetCode(common.Address) []byte GetCode(common.Address, bool) []byte
SetCode(common.Address, []byte) SetCode(common.Address, []byte, bool)
GetCodeSize(common.Address) int GetCodeSize(common.Address, bool) int
ValidatorWrapper(common.Address, bool, bool) (*staking.ValidatorWrapper, error) ValidatorWrapper(common.Address, bool, bool) (*staking.ValidatorWrapper, error)
UpdateValidatorWrapper(common.Address, *staking.ValidatorWrapper) error UpdateValidatorWrapper(common.Address, *staking.ValidatorWrapper) error

@ -31,7 +31,7 @@ type dummyContractRef struct {
func (dummyContractRef) ReturnGas(*big.Int) {} func (dummyContractRef) ReturnGas(*big.Int) {}
func (dummyContractRef) Address() common.Address { return common.Address{} } func (dummyContractRef) Address() common.Address { return common.Address{} }
func (dummyContractRef) Value() *big.Int { return new(big.Int) } func (dummyContractRef) Value() *big.Int { return new(big.Int) }
func (dummyContractRef) SetCode(common.Hash, []byte) {} func (dummyContractRef) SetCode(common.Hash, []byte, bool) {}
func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) { func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) {
d.calledForEach = true d.calledForEach = true
} }

@ -112,7 +112,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.DB, error) {
) )
cfg.State.CreateAccount(address) cfg.State.CreateAccount(address)
// set the receiver's (the executing contract) code for execution. // set the receiver's (the executing contract) code for execution.
cfg.State.SetCode(address, code) cfg.State.SetCode(address, code, false)
// Call the code with the given configuration. // Call the code with the given configuration.
ret, _, err := vmenv.Call( ret, _, err := vmenv.Call(
sender, sender,

@ -105,7 +105,7 @@ func TestCall(t *testing.T) {
byte(vm.PUSH1), 32, byte(vm.PUSH1), 32,
byte(vm.PUSH1), 0, byte(vm.PUSH1), 0,
byte(vm.RETURN), byte(vm.RETURN),
}) }, false)
ret, _, err := Call(address, nil, &Config{State: state}) ret, _, err := Call(address, nil, &Config{State: state})
if err != nil { if err != nil {
@ -158,7 +158,7 @@ func benchmarkEVMCreate(bench *testing.B, code string) {
) )
statedb.CreateAccount(sender) statedb.CreateAccount(sender)
statedb.SetCode(receiver, common.FromHex(code)) statedb.SetCode(receiver, common.FromHex(code), false)
runtimeConfig := Config{ runtimeConfig := Config{
Origin: sender, Origin: sender,
State: statedb, State: statedb,

@ -353,7 +353,7 @@ func (jst *ParityBlockTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode,
ret := stackPeek(0) ret := stackPeek(0)
if ret.Sign() != 0 { if ret.Sign() != 0 {
call.to = common.BigToAddress(ret) call.to = common.BigToAddress(ret)
call.output = env.StateDB.GetCode(call.to) call.output = env.StateDB.GetCode(call.to, false)
} else if call.err == nil { } else if call.err == nil {
call.err = errors.New("internal failure") call.err = errors.New("internal failure")
} }

@ -210,7 +210,7 @@ func (dw *dbWrapper) pushObject(vm *duktape.Context) {
// Push the wrapper for statedb.GetCode // Push the wrapper for statedb.GetCode
vm.PushGoFunction(func(ctx *duktape.Context) int { vm.PushGoFunction(func(ctx *duktape.Context) int {
code := dw.db.GetCode(common.BytesToAddress(popSlice(ctx))) code := dw.db.GetCode(common.BytesToAddress(popSlice(ctx)), false)
ptr := ctx.PushFixedBuffer(len(code)) ptr := ctx.PushFixedBuffer(len(code))
copy(makeSlice(ptr, uint(len(code))), code) copy(makeSlice(ptr, uint(len(code))), code)

@ -178,11 +178,11 @@ func (s *BlockAPI) BlockTransaction(
// check for contract related operations, if it is a plain transaction. // check for contract related operations, if it is a plain transaction.
if txInfo.tx.To() != nil { if txInfo.tx.To() != nil {
// possible call to existing contract so fetch relevant data // possible call to existing contract so fetch relevant data
contractInfo.ContractCode = state.GetCode(*txInfo.tx.To()) contractInfo.ContractCode = state.GetCode(*txInfo.tx.To(), false)
contractInfo.ContractAddress = txInfo.tx.To() contractInfo.ContractAddress = txInfo.tx.To()
} else { } else {
// contract creation, so address is in receipt // contract creation, so address is in receipt
contractInfo.ContractCode = state.GetCode(txInfo.receipt.ContractAddress) contractInfo.ContractCode = state.GetCode(txInfo.receipt.ContractAddress, false)
contractInfo.ContractAddress = &txInfo.receipt.ContractAddress contractInfo.ContractAddress = &txInfo.receipt.ContractAddress
} }
contractInfo.ExecutionResult, rosettaError = s.getTransactionTrace(ctx, blk, txInfo) contractInfo.ExecutionResult, rosettaError = s.getTransactionTrace(ctx, blk, txInfo)

@ -289,7 +289,7 @@ func (s *ConstructAPI) ConstructionMetadata(
GasPrice: sugNativePrice, GasPrice: sugNativePrice,
GasLimit: estGasUsed, GasLimit: estGasUsed,
Transaction: options.TransactionMetadata, Transaction: options.TransactionMetadata,
ContractCode: state.GetCode(contractAddress), ContractCode: state.GetCode(contractAddress, false),
EvmErrorMessage: evmErrorMsg, EvmErrorMessage: evmErrorMsg,
EvmReturn: evmReturn, EvmReturn: evmReturn,
}) })

@ -123,7 +123,7 @@ func (s *PublicContractService) GetCode(
DoMetricRPCQueryInfo(GetCode, FailedNumber) DoMetricRPCQueryInfo(GetCode, FailedNumber)
return nil, err return nil, err
} }
code := state.GetCode(address) code := state.GetCode(address, false)
// Response output is the same for all versions // Response output is the same for all versions
return code, state.Error() return code, state.Error()

@ -434,8 +434,8 @@ func (ctx *incStateTestCtx) checkAddrIncStateByType(addr common.Address, typeInc
// checkHmyNodeStateChangeByAddr checks the state change for hmy nodes. Since hmy nodes does not // checkHmyNodeStateChangeByAddr checks the state change for hmy nodes. Since hmy nodes does not
// have wrapper, it is supposed to be unchanged in code field // have wrapper, it is supposed to be unchanged in code field
func (ctx *incStateTestCtx) checkHmyNodeStateChangeByAddr(addr common.Address) error { func (ctx *incStateTestCtx) checkHmyNodeStateChangeByAddr(addr common.Address) error {
snapCode := ctx.snapState.GetCode(addr) snapCode := ctx.snapState.GetCode(addr, false)
curCode := ctx.state.GetCode(addr) curCode := ctx.state.GetCode(addr, false)
if !reflect.DeepEqual(snapCode, curCode) { if !reflect.DeepEqual(snapCode, curCode) {
return errors.New("code not expected") return errors.New("code not expected")
} }
@ -618,7 +618,7 @@ func (state testStateDB) UpdateValidatorWrapper(addr common.Address, wrapper *st
return nil return nil
} }
func (state testStateDB) GetCode(addr common.Address) []byte { func (state testStateDB) GetCode(addr common.Address, isValidatorCode bool) []byte {
wrapper, ok := state[addr] wrapper, ok := state[addr]
if !ok { if !ok {
return nil return nil

Loading…
Cancel
Save