mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
feat: dual code hash (#583)
* add crypto/codehash/codehash.go fix * init EmptyCodeHash * fix * WIP * fix * ??? * minor * update light/trie.go * update cmd/geth/snapshot.go * update core/state/dump.go * update core/state/snapshot/conversion.go * update core/state/snapshot/generate.go * update core/state/pruner/pruner.go * update core/state/iterator.go * update core/state/sync.go * update core/state/state_object.go * update core/state/statedb.go * update core/vm/interface.go * update core/vm/evm.go * update core/vm/instructions.go * update core/vm/contract.go * update core/state_transition.go * update les/server_requests.go * update eth/protocols/snap/sync.go * update internal/ethapi/api.go * update cmd/geth/snapshot.go * update ethclient/gethclient/gethclient.go * gofmt * fix `(s *stateObject) SetCode` * fix tests * minor * minor minor
This commit is contained in:
parent
b639349788
commit
8c5bae2e69
41 changed files with 366 additions and 290 deletions
|
|
@ -261,11 +261,11 @@ func (s *Suite) TestSnapGetByteCodes(t *utesting.T) {
|
|||
expHashes: 0,
|
||||
},
|
||||
{
|
||||
nBytes: 10000, hashes: []common.Hash{types.EmptyCodeHash},
|
||||
nBytes: 10000, hashes: []common.Hash{types.EmptyKeccakCodeHash},
|
||||
expHashes: 1,
|
||||
},
|
||||
{
|
||||
nBytes: 10000, hashes: []common.Hash{types.EmptyCodeHash, types.EmptyCodeHash, types.EmptyCodeHash},
|
||||
nBytes: 10000, hashes: []common.Hash{types.EmptyKeccakCodeHash, types.EmptyKeccakCodeHash, types.EmptyKeccakCodeHash},
|
||||
expHashes: 3,
|
||||
},
|
||||
// The existing bytecodes
|
||||
|
|
@ -357,7 +357,7 @@ func (s *Suite) TestSnapTrieNodes(t *utesting.T) {
|
|||
for i := 1; i <= 65; i++ {
|
||||
accPaths = append(accPaths, pathTo(i))
|
||||
}
|
||||
empty := types.EmptyCodeHash
|
||||
empty := types.EmptyKeccakCodeHash
|
||||
for i, tc := range []trieNodesTest{
|
||||
{
|
||||
root: s.chain.RootAt(999),
|
||||
|
|
|
|||
|
|
@ -338,9 +338,9 @@ func traverseState(ctx *cli.Context) error {
|
|||
return storageIter.Err
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
||||
log.Error("Code is missing", "hash", common.BytesToHash(acc.CodeHash))
|
||||
if !bytes.Equal(acc.KeccakCodeHash, types.EmptyKeccakCodeHash.Bytes()) {
|
||||
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.KeccakCodeHash)) {
|
||||
log.Error("Code is missing", "hash", common.BytesToHash(acc.KeccakCodeHash))
|
||||
return errors.New("missing code")
|
||||
}
|
||||
codes += 1
|
||||
|
|
@ -496,8 +496,8 @@ func traverseRawState(ctx *cli.Context) error {
|
|||
return storageIter.Error()
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) {
|
||||
if !bytes.Equal(acc.KeccakCodeHash, types.EmptyKeccakCodeHash.Bytes()) {
|
||||
if !rawdb.HasCode(chaindb, common.BytesToHash(acc.KeccakCodeHash)) {
|
||||
log.Error("Code is missing", "account", common.BytesToHash(accIter.LeafKey()))
|
||||
return errors.New("missing code")
|
||||
}
|
||||
|
|
@ -568,14 +568,15 @@ func dumpState(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
da := &state.DumpAccount{
|
||||
Balance: account.Balance.String(),
|
||||
Nonce: account.Nonce,
|
||||
Root: account.Root.Bytes(),
|
||||
CodeHash: account.CodeHash,
|
||||
SecureKey: accIt.Hash().Bytes(),
|
||||
Balance: account.Balance.String(),
|
||||
Nonce: account.Nonce,
|
||||
Root: account.Root.Bytes(),
|
||||
KeccakCodeHash: account.KeccakCodeHash,
|
||||
PoseidonCodeHash: account.PoseidonCodeHash,
|
||||
SecureKey: accIt.Hash().Bytes(),
|
||||
}
|
||||
if !conf.SkipCode && !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||
da.Code = rawdb.ReadCode(db, common.BytesToHash(account.CodeHash))
|
||||
if !conf.SkipCode && !bytes.Equal(account.KeccakCodeHash, types.EmptyKeccakCodeHash.Bytes()) {
|
||||
da.Code = rawdb.ReadCode(db, common.BytesToHash(account.KeccakCodeHash))
|
||||
}
|
||||
if !conf.SkipStorage {
|
||||
da.Storage = make(map[common.Hash]string)
|
||||
|
|
|
|||
|
|
@ -49,14 +49,15 @@ type DumpCollector interface {
|
|||
|
||||
// DumpAccount represents an account in the state.
|
||||
type DumpAccount struct {
|
||||
Balance string `json:"balance"`
|
||||
Nonce uint64 `json:"nonce"`
|
||||
Root hexutil.Bytes `json:"root"`
|
||||
CodeHash hexutil.Bytes `json:"codeHash"`
|
||||
Code hexutil.Bytes `json:"code,omitempty"`
|
||||
Storage map[common.Hash]string `json:"storage,omitempty"`
|
||||
Address *common.Address `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode
|
||||
SecureKey hexutil.Bytes `json:"key,omitempty"` // If we don't have address, we can output the key
|
||||
Balance string `json:"balance"`
|
||||
Nonce uint64 `json:"nonce"`
|
||||
Root hexutil.Bytes `json:"root"`
|
||||
KeccakCodeHash hexutil.Bytes `json:"keccakCodeHash"`
|
||||
PoseidonCodeHash hexutil.Bytes `json:"poseidonCodeHash"`
|
||||
Code hexutil.Bytes `json:"code,omitempty"`
|
||||
Storage map[common.Hash]string `json:"storage,omitempty"`
|
||||
Address *common.Address `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode
|
||||
SecureKey hexutil.Bytes `json:"key,omitempty"` // If we don't have address, we can output the key
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -105,14 +106,15 @@ type iterativeDump struct {
|
|||
// OnAccount implements DumpCollector interface
|
||||
func (d iterativeDump) OnAccount(addr *common.Address, account DumpAccount) {
|
||||
dumpAccount := &DumpAccount{
|
||||
Balance: account.Balance,
|
||||
Nonce: account.Nonce,
|
||||
Root: account.Root,
|
||||
CodeHash: account.CodeHash,
|
||||
Code: account.Code,
|
||||
Storage: account.Storage,
|
||||
SecureKey: account.SecureKey,
|
||||
Address: addr,
|
||||
Balance: account.Balance,
|
||||
Nonce: account.Nonce,
|
||||
Root: account.Root,
|
||||
KeccakCodeHash: account.KeccakCodeHash,
|
||||
PoseidonCodeHash: account.PoseidonCodeHash,
|
||||
Code: account.Code,
|
||||
Storage: account.Storage,
|
||||
SecureKey: account.SecureKey,
|
||||
Address: addr,
|
||||
}
|
||||
d.Encode(dumpAccount)
|
||||
}
|
||||
|
|
@ -151,11 +153,12 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
|
|||
panic(err)
|
||||
}
|
||||
account := DumpAccount{
|
||||
Balance: data.Balance.String(),
|
||||
Nonce: data.Nonce,
|
||||
Root: data.Root[:],
|
||||
CodeHash: data.CodeHash,
|
||||
SecureKey: it.Key,
|
||||
Balance: data.Balance.String(),
|
||||
Nonce: data.Nonce,
|
||||
Root: data.Root[:],
|
||||
KeccakCodeHash: data.KeccakCodeHash,
|
||||
PoseidonCodeHash: data.PoseidonCodeHash,
|
||||
SecureKey: it.Key,
|
||||
}
|
||||
var (
|
||||
addrBytes = s.trie.GetKey(it.Key)
|
||||
|
|
|
|||
|
|
@ -134,11 +134,11 @@ func (it *nodeIterator) step() error {
|
|||
if !it.dataIt.Next(true) {
|
||||
it.dataIt = nil
|
||||
}
|
||||
if !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||
it.codeHash = common.BytesToHash(account.CodeHash)
|
||||
it.code, err = it.state.db.ContractCode(address, common.BytesToHash(account.CodeHash))
|
||||
if !bytes.Equal(account.KeccakCodeHash, types.EmptyKeccakCodeHash.Bytes()) {
|
||||
it.codeHash = common.BytesToHash(account.KeccakCodeHash)
|
||||
it.code, err = it.state.db.ContractCode(address, common.BytesToHash(account.KeccakCodeHash))
|
||||
if err != nil {
|
||||
return fmt.Errorf("code %x: %v", account.CodeHash, err)
|
||||
return fmt.Errorf("code %x: %v", account.KeccakCodeHash, err)
|
||||
}
|
||||
}
|
||||
it.accountHash = it.stateIt.Parent()
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ func (ch nonceChange) dirtied() *common.Address {
|
|||
}
|
||||
|
||||
func (ch codeChange) revert(s *StateDB) {
|
||||
s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode)
|
||||
s.getStateObject(*ch.account).setCode(ch.prevcode)
|
||||
}
|
||||
|
||||
func (ch codeChange) dirtied() *common.Address {
|
||||
|
|
|
|||
|
|
@ -451,8 +451,8 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
|
|||
return storageIter.Error()
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(acc.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||
stateBloom.Put(acc.CodeHash, nil)
|
||||
if !bytes.Equal(acc.KeccakCodeHash, types.EmptyKeccakCodeHash.Bytes()) {
|
||||
stateBloom.Put(acc.KeccakCodeHash, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func GenerateTrie(snaptree *Tree, root common.Hash, src ethdb.Database, dst ethd
|
|||
scheme := snaptree.triedb.Scheme()
|
||||
got, err := generateTrieRoot(dst, scheme, acctIt, common.Hash{}, stackTrieGenerate, func(dst ethdb.KeyValueWriter, accountHash, codeHash common.Hash, stat *generateStats) (common.Hash, error) {
|
||||
// Migrate the code first, commit the contract code into the tmp db.
|
||||
if codeHash != types.EmptyCodeHash {
|
||||
if codeHash != types.EmptyKeccakCodeHash {
|
||||
code := rawdb.ReadCode(src, codeHash)
|
||||
if len(code) == 0 {
|
||||
return common.Hash{}, errors.New("failed to read contract code")
|
||||
|
|
@ -317,7 +317,7 @@ func generateTrieRoot(db ethdb.KeyValueWriter, scheme string, it Iterator, accou
|
|||
return stop(err)
|
||||
}
|
||||
go func(hash common.Hash) {
|
||||
subroot, err := leafCallback(db, hash, common.BytesToHash(account.CodeHash), stats)
|
||||
subroot, err := leafCallback(db, hash, common.BytesToHash(account.KeccakCodeHash), stats)
|
||||
if err != nil {
|
||||
results <- err
|
||||
return
|
||||
|
|
|
|||
|
|
@ -586,8 +586,11 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
|||
if accMarker == nil || !bytes.Equal(account[:], accMarker) {
|
||||
dataLen := len(val) // Approximate size, saves us a round of RLP-encoding
|
||||
if !write {
|
||||
if bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) {
|
||||
dataLen -= 32
|
||||
if bytes.Equal(acc.KeccakCodeHash, types.EmptyKeccakCodeHash[:]) {
|
||||
// TODO: codesize
|
||||
// dataLen = dataLen - 32 - 32 - 8
|
||||
// account for keccakCodeHash, poseidonCodeHash
|
||||
dataLen = dataLen - 32 - 32
|
||||
}
|
||||
if acc.Root == types.EmptyRootHash {
|
||||
dataLen -= 32
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ func testGeneration(t *testing.T, scheme string) {
|
|||
var helper = newHelper(scheme)
|
||||
stRoot := helper.makeStorageTrie(common.Hash{}, []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, false)
|
||||
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
|
||||
helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
|
|
@ -97,16 +97,16 @@ func testGenerateExistentState(t *testing.T, scheme string) {
|
|||
var helper = newHelper(scheme)
|
||||
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
|
||||
stRoot = helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||
|
||||
root, snap := helper.CommitAndGenerate()
|
||||
|
|
@ -259,28 +259,28 @@ func testGenerateExistentStateWithWrongStorage(t *testing.T, scheme string) {
|
|||
helper := newHelper(scheme)
|
||||
|
||||
// Account one, empty root but non-empty database
|
||||
helper.addAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||
|
||||
// Account two, non empty root but empty database
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-2")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
|
||||
// Miss slots
|
||||
{
|
||||
// Account three, non empty root but misses slots in the beginning
|
||||
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-3", []string{"key-2", "key-3"}, []string{"val-2", "val-3"})
|
||||
|
||||
// Account four, non empty root but misses slots in the middle
|
||||
helper.makeStorageTrie(hashData([]byte("acc-4")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-4", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-4", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-4", []string{"key-1", "key-3"}, []string{"val-1", "val-3"})
|
||||
|
||||
// Account five, non empty root but misses slots in the end
|
||||
helper.makeStorageTrie(hashData([]byte("acc-5")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-5", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-5", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-5", []string{"key-1", "key-2"}, []string{"val-1", "val-2"})
|
||||
}
|
||||
|
||||
|
|
@ -288,22 +288,22 @@ func testGenerateExistentStateWithWrongStorage(t *testing.T, scheme string) {
|
|||
{
|
||||
// Account six, non empty root but wrong slots in the beginning
|
||||
helper.makeStorageTrie(hashData([]byte("acc-6")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-6", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-6", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-6", []string{"key-1", "key-2", "key-3"}, []string{"badval-1", "val-2", "val-3"})
|
||||
|
||||
// Account seven, non empty root but wrong slots in the middle
|
||||
helper.makeStorageTrie(hashData([]byte("acc-7")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-7", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-7", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-7", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "badval-2", "val-3"})
|
||||
|
||||
// Account eight, non empty root but wrong slots in the end
|
||||
helper.makeStorageTrie(hashData([]byte("acc-8")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-8", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-8", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-8", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "badval-3"})
|
||||
|
||||
// Account 9, non empty root but rotated slots
|
||||
helper.makeStorageTrie(hashData([]byte("acc-9")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-9", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-9", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-9", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-3", "val-2"})
|
||||
}
|
||||
|
||||
|
|
@ -311,17 +311,17 @@ func testGenerateExistentStateWithWrongStorage(t *testing.T, scheme string) {
|
|||
{
|
||||
// Account 10, non empty root but extra slots in the beginning
|
||||
helper.makeStorageTrie(hashData([]byte("acc-10")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-10", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-10", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-10", []string{"key-0", "key-1", "key-2", "key-3"}, []string{"val-0", "val-1", "val-2", "val-3"})
|
||||
|
||||
// Account 11, non empty root but extra slots in the middle
|
||||
helper.makeStorageTrie(hashData([]byte("acc-11")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-11", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-11", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-11", []string{"key-1", "key-2", "key-2-1", "key-3"}, []string{"val-1", "val-2", "val-2-1", "val-3"})
|
||||
|
||||
// Account 12, non empty root but extra slots in the end
|
||||
helper.makeStorageTrie(hashData([]byte("acc-12")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-12", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-12", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapStorage("acc-12", []string{"key-1", "key-2", "key-3", "key-4"}, []string{"val-1", "val-2", "val-3", "val-4"})
|
||||
}
|
||||
|
||||
|
|
@ -366,25 +366,25 @@ func testGenerateExistentStateWithWrongAccounts(t *testing.T, scheme string) {
|
|||
|
||||
// Missing accounts, only in the trie
|
||||
{
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Beginning
|
||||
helper.addTrieAccount("acc-4", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // Middle
|
||||
helper.addTrieAccount("acc-6", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // End
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // Beginning
|
||||
helper.addTrieAccount("acc-4", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // Middle
|
||||
helper.addTrieAccount("acc-6", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // End
|
||||
}
|
||||
|
||||
// Wrong accounts
|
||||
{
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: common.Hex2Bytes("0x1234")})
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: common.Hex2Bytes("0x1234"), PoseidonCodeHash: common.Hex2Bytes("0x1234")})
|
||||
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addSnapAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
}
|
||||
|
||||
// Extra accounts, only in the snap
|
||||
{
|
||||
helper.addSnapAccount("acc-0", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // before the beginning
|
||||
helper.addSnapAccount("acc-5", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: common.Hex2Bytes("0x1234")}) // Middle
|
||||
helper.addSnapAccount("acc-7", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // after the end
|
||||
helper.addSnapAccount("acc-0", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // before the beginning
|
||||
helper.addSnapAccount("acc-5", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, KeccakCodeHash: common.Hex2Bytes("0x1234"), PoseidonCodeHash: common.Hex2Bytes("0x1234")}) // Middle
|
||||
helper.addSnapAccount("acc-7", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // after the end
|
||||
}
|
||||
|
||||
root, snap := helper.CommitAndGenerate()
|
||||
|
|
@ -418,9 +418,9 @@ func testGenerateCorruptAccountTrie(t *testing.T, scheme string) {
|
|||
// without any storage slots to keep the test smaller.
|
||||
helper := newHelper(scheme)
|
||||
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
|
||||
|
||||
root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978
|
||||
|
||||
|
|
@ -462,11 +462,11 @@ func testGenerateMissingStorageTrie(t *testing.T, scheme string) {
|
|||
acc3 = hashData([]byte("acc-3"))
|
||||
helper = newHelper(scheme)
|
||||
)
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||
stRoot = helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||
|
||||
root := helper.Commit()
|
||||
|
||||
|
|
@ -502,11 +502,11 @@ func testGenerateCorruptStorageTrie(t *testing.T, scheme string) {
|
|||
// two of which also has the same 3-slot storage trie attached.
|
||||
helper := newHelper(scheme)
|
||||
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||
stRoot = helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||
|
||||
root := helper.Commit()
|
||||
|
||||
|
|
@ -546,7 +546,7 @@ func testGenerateWithExtraAccounts(t *testing.T, scheme string) {
|
|||
[]string{"val-1", "val-2", "val-3", "val-4", "val-5"},
|
||||
true,
|
||||
)
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}
|
||||
val, _ := rlp.EncodeToBytes(acc)
|
||||
helper.accTrie.MustUpdate([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||
|
||||
|
|
@ -566,7 +566,7 @@ func testGenerateWithExtraAccounts(t *testing.T, scheme string) {
|
|||
[]string{"val-1", "val-2", "val-3", "val-4", "val-5"},
|
||||
true,
|
||||
)
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}
|
||||
val, _ := rlp.EncodeToBytes(acc)
|
||||
key := hashData([]byte("acc-2"))
|
||||
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
|
||||
|
|
@ -622,7 +622,7 @@ func testGenerateWithManyExtraAccounts(t *testing.T, scheme string) {
|
|||
[]string{"val-1", "val-2", "val-3"},
|
||||
true,
|
||||
)
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}
|
||||
val, _ := rlp.EncodeToBytes(acc)
|
||||
helper.accTrie.MustUpdate([]byte("acc-1"), val) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||
|
||||
|
|
@ -636,7 +636,7 @@ func testGenerateWithManyExtraAccounts(t *testing.T, scheme string) {
|
|||
{
|
||||
// 100 accounts exist only in snapshot
|
||||
for i := 0; i < 1000; i++ {
|
||||
acc := &types.StateAccount{Balance: big.NewInt(int64(i)), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||
acc := &types.StateAccount{Balance: big.NewInt(int64(i)), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}
|
||||
val, _ := rlp.EncodeToBytes(acc)
|
||||
key := hashData([]byte(fmt.Sprintf("acc-%d", i)))
|
||||
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
|
||||
|
|
@ -678,7 +678,7 @@ func testGenerateWithExtraBeforeAndAfter(t *testing.T, scheme string) {
|
|||
}
|
||||
helper := newHelper(scheme)
|
||||
{
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}
|
||||
val, _ := rlp.EncodeToBytes(acc)
|
||||
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
||||
helper.accTrie.MustUpdate(common.HexToHash("0x07").Bytes(), val)
|
||||
|
|
@ -720,7 +720,7 @@ func testGenerateWithMalformedSnapdata(t *testing.T, scheme string) {
|
|||
}
|
||||
helper := newHelper(scheme)
|
||||
{
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||
acc := &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()}
|
||||
val, _ := rlp.EncodeToBytes(acc)
|
||||
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
||||
|
||||
|
|
@ -764,7 +764,7 @@ func testGenerateFromEmptySnap(t *testing.T, scheme string) {
|
|||
for i := 0; i < 400; i++ {
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte(fmt.Sprintf("acc-%d", i))), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addTrieAccount(fmt.Sprintf("acc-%d", i),
|
||||
&types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
&types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
}
|
||||
root, snap := helper.CommitAndGenerate()
|
||||
t.Logf("Root: %#x\n", root) // Root: 0x6f7af6d2e1a1bf2b84a3beb3f8b64388465fbc1e274ca5d5d3fc787ca78f59e4
|
||||
|
|
@ -806,7 +806,7 @@ func testGenerateWithIncompleteStorage(t *testing.T, scheme string) {
|
|||
for i := 0; i < 8; i++ {
|
||||
accKey := fmt.Sprintf("acc-%d", i)
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte(accKey)), stKeys, stVals, true)
|
||||
helper.addAccount(accKey, &types.StateAccount{Balance: big.NewInt(int64(i)), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount(accKey, &types.StateAccount{Balance: big.NewInt(int64(i)), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
var moddedKeys []string
|
||||
var moddedVals []string
|
||||
for ii := 0; ii < 8; ii++ {
|
||||
|
|
@ -903,11 +903,11 @@ func testGenerateCompleteSnapshotWithDanglingStorage(t *testing.T, scheme string
|
|||
var helper = newHelper(scheme)
|
||||
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addAccount("acc-2", &types.StateAccount{Balance: big.NewInt(1), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
|
||||
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addAccount("acc-3", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
|
||||
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||
helper.addSnapStorage("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||
|
|
@ -943,11 +943,11 @@ func testGenerateBrokenSnapshotWithDanglingStorage(t *testing.T, scheme string)
|
|||
var helper = newHelper(scheme)
|
||||
|
||||
stRoot := helper.makeStorageTrie(hashData([]byte("acc-1")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: big.NewInt(1), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: big.NewInt(2), Root: types.EmptyRootHash, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
|
||||
helper.makeStorageTrie(hashData([]byte("acc-3")), []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: big.NewInt(3), Root: stRoot, KeccakCodeHash: types.EmptyKeccakCodeHash.Bytes(), PoseidonCodeHash: types.EmptyPoseidonCodeHash.Bytes()})
|
||||
|
||||
populateDangling(helper.diskdb)
|
||||
|
||||
|
|
|
|||
|
|
@ -44,10 +44,11 @@ func randomHash() common.Hash {
|
|||
// randomAccount generates a random account and returns it RLP encoded.
|
||||
func randomAccount() []byte {
|
||||
a := &types.StateAccount{
|
||||
Balance: big.NewInt(rand.Int63()),
|
||||
Nonce: rand.Uint64(),
|
||||
Root: randomHash(),
|
||||
CodeHash: types.EmptyCodeHash[:],
|
||||
Balance: big.NewInt(rand.Int63()),
|
||||
Nonce: rand.Uint64(),
|
||||
Root: randomHash(),
|
||||
KeccakCodeHash: types.EmptyKeccakCodeHash[:],
|
||||
PoseidonCodeHash: types.EmptyPoseidonCodeHash[:],
|
||||
}
|
||||
data, _ := rlp.EncodeToBytes(a)
|
||||
return data
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ func CheckJournalAccount(db ethdb.KeyValueStore, hash common.Hash) error {
|
|||
fmt.Printf("\taccount.nonce: %d\n", account.Nonce)
|
||||
fmt.Printf("\taccount.balance: %x\n", account.Balance)
|
||||
fmt.Printf("\taccount.root: %x\n", account.Root)
|
||||
fmt.Printf("\taccount.codehash: %x\n", account.CodeHash)
|
||||
fmt.Printf("\taccount.keccak_codehash: %x\n", account.KeccakCodeHash)
|
||||
fmt.Printf("\taccount.poseidon_codehash: %x\n", account.PoseidonCodeHash)
|
||||
}
|
||||
// Check storage
|
||||
{
|
||||
|
|
@ -136,7 +137,8 @@ func CheckJournalAccount(db ethdb.KeyValueStore, hash common.Hash) error {
|
|||
fmt.Printf("\taccount.nonce: %d\n", account.Nonce)
|
||||
fmt.Printf("\taccount.balance: %x\n", account.Balance)
|
||||
fmt.Printf("\taccount.root: %x\n", account.Root)
|
||||
fmt.Printf("\taccount.codehash: %x\n", account.CodeHash)
|
||||
fmt.Printf("\taccount.keccakcodehash: %x\n", account.KeccakCodeHash)
|
||||
fmt.Printf("\taccount.poseidoncodehash: %x\n", account.PoseidonCodeHash)
|
||||
}
|
||||
if _, ok := destructs[hash]; ok {
|
||||
fmt.Printf("\t Destructed!")
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/codehash"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
|
|
@ -93,7 +94,8 @@ type stateObject struct {
|
|||
|
||||
// empty returns whether the account is considered empty.
|
||||
func (s *stateObject) empty() bool {
|
||||
return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, types.EmptyCodeHash.Bytes())
|
||||
// note: if KeccakCodeHash is empty then PoseidonCodeHash and CodeSize will also be empty
|
||||
return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.KeccakCodeHash, types.EmptyKeccakCodeHash.Bytes())
|
||||
}
|
||||
|
||||
// newObject creates a state object.
|
||||
|
|
@ -469,12 +471,12 @@ func (s *stateObject) Code() []byte {
|
|||
if s.code != nil {
|
||||
return s.code
|
||||
}
|
||||
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
|
||||
if bytes.Equal(s.KeccakCodeHash(), types.EmptyKeccakCodeHash.Bytes()) {
|
||||
return nil
|
||||
}
|
||||
code, err := s.db.db.ContractCode(s.address, common.BytesToHash(s.CodeHash()))
|
||||
code, err := s.db.db.ContractCode(s.address, common.BytesToHash(s.KeccakCodeHash()))
|
||||
if err != nil {
|
||||
s.db.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.KeccakCodeHash(), err))
|
||||
}
|
||||
s.code = code
|
||||
return code
|
||||
|
|
@ -487,29 +489,29 @@ func (s *stateObject) CodeSize() int {
|
|||
if s.code != nil {
|
||||
return len(s.code)
|
||||
}
|
||||
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
|
||||
if bytes.Equal(s.KeccakCodeHash(), types.EmptyKeccakCodeHash.Bytes()) {
|
||||
return 0
|
||||
}
|
||||
size, err := s.db.db.ContractCodeSize(s.address, common.BytesToHash(s.CodeHash()))
|
||||
size, err := s.db.db.ContractCodeSize(s.address, common.BytesToHash(s.KeccakCodeHash()))
|
||||
if err != nil {
|
||||
s.db.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.KeccakCodeHash(), err))
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
func (s *stateObject) SetCode(codeHash common.Hash, code []byte) {
|
||||
func (s *stateObject) SetCode(code []byte) {
|
||||
prevcode := s.Code()
|
||||
s.db.journal.append(codeChange{
|
||||
account: &s.address,
|
||||
prevhash: s.CodeHash(),
|
||||
prevcode: prevcode,
|
||||
})
|
||||
s.setCode(codeHash, code)
|
||||
s.setCode(code)
|
||||
}
|
||||
|
||||
func (s *stateObject) setCode(codeHash common.Hash, code []byte) {
|
||||
func (s *stateObject) setCode(code []byte) {
|
||||
s.code = code
|
||||
s.data.CodeHash = codeHash[:]
|
||||
s.data.KeccakCodeHash = codehash.KeccakCodeHash(code).Bytes()
|
||||
s.data.PoseidonCodeHash = codehash.PoseidonCodeHash(code).Bytes()
|
||||
s.dirtyCode = true
|
||||
}
|
||||
|
||||
|
|
@ -525,8 +527,12 @@ func (s *stateObject) setNonce(nonce uint64) {
|
|||
s.data.Nonce = nonce
|
||||
}
|
||||
|
||||
func (s *stateObject) CodeHash() []byte {
|
||||
return s.data.CodeHash
|
||||
func (s *stateObject) PoseidonCodeHash() []byte {
|
||||
return s.data.PoseidonCodeHash
|
||||
}
|
||||
|
||||
func (s *stateObject) KeccakCodeHash() []byte {
|
||||
return s.data.KeccakCodeHash
|
||||
}
|
||||
|
||||
func (s *stateObject) Balance() *big.Int {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
)
|
||||
|
|
@ -51,7 +50,7 @@ func TestDump(t *testing.T) {
|
|||
obj1 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x01}))
|
||||
obj1.AddBalance(big.NewInt(22))
|
||||
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([]byte{3, 3, 3, 3, 3, 3, 3})
|
||||
obj3 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x02}))
|
||||
obj3.SetBalance(big.NewInt(44))
|
||||
|
||||
|
|
@ -105,7 +104,7 @@ func TestIterativeDump(t *testing.T) {
|
|||
obj1 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x01}))
|
||||
obj1.AddBalance(big.NewInt(22))
|
||||
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([]byte{3, 3, 3, 3, 3, 3, 3})
|
||||
obj3 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x02}))
|
||||
obj3.SetBalance(big.NewInt(44))
|
||||
obj4 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x00}))
|
||||
|
|
@ -207,7 +206,7 @@ func TestSnapshot2(t *testing.T) {
|
|||
so0 := state.getStateObject(stateobjaddr0)
|
||||
so0.SetBalance(big.NewInt(42))
|
||||
so0.SetNonce(43)
|
||||
so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'})
|
||||
so0.SetCode([]byte{'c', 'a', 'f', 'e'})
|
||||
so0.selfDestructed = false
|
||||
so0.deleted = false
|
||||
state.setStateObject(so0)
|
||||
|
|
@ -219,7 +218,7 @@ func TestSnapshot2(t *testing.T) {
|
|||
so1 := state.getStateObject(stateobjaddr1)
|
||||
so1.SetBalance(big.NewInt(52))
|
||||
so1.SetNonce(53)
|
||||
so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'})
|
||||
so1.SetCode([]byte{'c', 'a', 'f', 'e', '2'})
|
||||
so1.selfDestructed = true
|
||||
so1.deleted = true
|
||||
state.setStateObject(so1)
|
||||
|
|
@ -259,8 +258,8 @@ func compareStateObjects(so0, so1 *stateObject, t *testing.T) {
|
|||
if so0.data.Root != so1.data.Root {
|
||||
t.Errorf("Root mismatch: have %x, want %x", so0.data.Root[:], so1.data.Root[:])
|
||||
}
|
||||
if !bytes.Equal(so0.CodeHash(), so1.CodeHash()) {
|
||||
t.Fatalf("CodeHash mismatch: have %v, want %v", so0.CodeHash(), so1.CodeHash())
|
||||
if !bytes.Equal(so0.KeccakCodeHash(), so1.KeccakCodeHash()) {
|
||||
t.Fatalf("CodeHash mismatch: have %v, want %v", so0.KeccakCodeHash(), so1.KeccakCodeHash())
|
||||
}
|
||||
if !bytes.Equal(so0.code, so1.code) {
|
||||
t.Fatalf("Code mismatch: have %v, want %v", so0.code, so1.code)
|
||||
|
|
|
|||
|
|
@ -329,12 +329,20 @@ func (s *StateDB) GetCodeSize(addr common.Address) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (s *StateDB) GetCodeHash(addr common.Address) common.Hash {
|
||||
func (s *StateDB) GetPoseidonCodeHash(addr common.Address) common.Hash {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
return common.Hash{}
|
||||
}
|
||||
return common.BytesToHash(stateObject.CodeHash())
|
||||
return common.BytesToHash(stateObject.PoseidonCodeHash())
|
||||
}
|
||||
|
||||
func (s *StateDB) GetKeccakCodeHash(addr common.Address) common.Hash {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
return common.Hash{}
|
||||
}
|
||||
return common.BytesToHash(stateObject.KeccakCodeHash())
|
||||
}
|
||||
|
||||
// GetState retrieves a value from the given account's storage trie.
|
||||
|
|
@ -405,7 +413,7 @@ func (s *StateDB) SetNonce(addr common.Address, nonce uint64) {
|
|||
func (s *StateDB) SetCode(addr common.Address, code []byte) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetCode(crypto.Keccak256Hash(code), code)
|
||||
stateObject.SetCode(code)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -510,7 +518,7 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
|
|||
s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err))
|
||||
}
|
||||
if obj.dirtyCode {
|
||||
s.trie.UpdateContractCode(obj.Address(), common.BytesToHash(obj.CodeHash()), obj.code)
|
||||
s.trie.UpdateContractCode(obj.Address(), common.BytesToHash(obj.KeccakCodeHash()), obj.code)
|
||||
}
|
||||
// Cache the data until commit. Note, this update mechanism is not symmetric
|
||||
// to the deletion, because whereas it is enough to track account updates
|
||||
|
|
@ -575,13 +583,15 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
|||
return nil
|
||||
}
|
||||
data = &types.StateAccount{
|
||||
Nonce: acc.Nonce,
|
||||
Balance: acc.Balance,
|
||||
CodeHash: acc.CodeHash,
|
||||
Root: common.BytesToHash(acc.Root),
|
||||
Nonce: acc.Nonce,
|
||||
Balance: acc.Balance,
|
||||
KeccakCodeHash: acc.KeccakCodeHash,
|
||||
PoseidonCodeHash: acc.PoseidonCodeHash,
|
||||
Root: common.BytesToHash(acc.Root),
|
||||
}
|
||||
if len(data.CodeHash) == 0 {
|
||||
data.CodeHash = types.EmptyCodeHash.Bytes()
|
||||
if len(data.KeccakCodeHash) == 0 {
|
||||
data.KeccakCodeHash = types.EmptyKeccakCodeHash.Bytes()
|
||||
data.PoseidonCodeHash = types.EmptyPoseidonCodeHash.Bytes()
|
||||
}
|
||||
if data.Root == (common.Hash{}) {
|
||||
data.Root = types.EmptyRootHash
|
||||
|
|
@ -1194,7 +1204,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
|
|||
}
|
||||
// Write any contract code associated with the state object
|
||||
if obj.code != nil && obj.dirtyCode {
|
||||
rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code)
|
||||
rawdb.WriteCode(codeWriter, common.BytesToHash(obj.KeccakCodeHash()), obj.code)
|
||||
obj.dirtyCode = false
|
||||
}
|
||||
// Write any storage changes in the state object to its storage trie
|
||||
|
|
|
|||
|
|
@ -504,7 +504,8 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
|
|||
checkeq("GetBalance", state.GetBalance(addr), checkstate.GetBalance(addr))
|
||||
checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr))
|
||||
checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr))
|
||||
checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr))
|
||||
checkeq("GetKeccakCodeHash", state.GetKeccakCodeHash(addr), checkstate.GetKeccakCodeHash(addr))
|
||||
checkeq("GetPoseidonCodeHash", state.GetPoseidonCodeHash(addr), checkstate.GetPoseidonCodeHash(addr))
|
||||
checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr))
|
||||
// Check storage.
|
||||
if obj := state.getStateObject(addr); obj != nil {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func NewStateSync(root common.Hash, database ethdb.KeyValueReader, onLeaf func(k
|
|||
return err
|
||||
}
|
||||
syncer.AddSubTrie(obj.Root, path, parent, parentPath, onSlot)
|
||||
syncer.AddCodeEntry(common.BytesToHash(obj.CodeHash), path, parent, parentPath)
|
||||
syncer.AddCodeEntry(common.BytesToHash(obj.KeccakCodeHash), path, parent, parentPath)
|
||||
return nil
|
||||
}
|
||||
syncer = trie.NewSync(root, database, onAccount, scheme)
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ func makeTestState(scheme string) (ethdb.Database, Database, *trie.Database, com
|
|||
acc.nonce = uint64(42 * i)
|
||||
|
||||
if i%3 == 0 {
|
||||
obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i}), []byte{i, i, i, i, i})
|
||||
obj.SetCode([]byte{i, i, i, i, i})
|
||||
acc.code = []byte{i, i, i, i, i}
|
||||
}
|
||||
if i%5 == 0 {
|
||||
|
|
@ -615,7 +615,7 @@ func testIncompleteStateSync(t *testing.T, scheme string) {
|
|||
isCode[crypto.Keccak256Hash(acc.code)] = struct{}{}
|
||||
}
|
||||
}
|
||||
isCode[types.EmptyCodeHash] = struct{}{}
|
||||
isCode[types.EmptyKeccakCodeHash] = struct{}{}
|
||||
|
||||
// Create a destination state and sync with the scheduler
|
||||
dstDb := rawdb.NewMemoryDatabase()
|
||||
|
|
|
|||
|
|
@ -281,8 +281,8 @@ func (st *StateTransition) preCheck() error {
|
|||
msg.From.Hex(), stNonce)
|
||||
}
|
||||
// Make sure the sender is an EOA
|
||||
codeHash := st.state.GetCodeHash(msg.From)
|
||||
if codeHash != (common.Hash{}) && codeHash != types.EmptyCodeHash {
|
||||
codeHash := st.state.GetKeccakCodeHash(msg.From)
|
||||
if codeHash != (common.Hash{}) && codeHash != types.EmptyKeccakCodeHash {
|
||||
return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
|
||||
msg.From.Hex(), codeHash)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,25 @@
|
|||
// TODO: fix me
|
||||
// Code generated by rlpgen. DO NOT EDIT.
|
||||
|
||||
package types
|
||||
|
||||
import "github.com/ethereum/go-ethereum/rlp"
|
||||
import "io"
|
||||
// import "github.com/ethereum/go-ethereum/rlp"
|
||||
// import "io"
|
||||
|
||||
func (obj *StateAccount) EncodeRLP(_w io.Writer) error {
|
||||
w := rlp.NewEncoderBuffer(_w)
|
||||
_tmp0 := w.List()
|
||||
w.WriteUint64(obj.Nonce)
|
||||
if obj.Balance == nil {
|
||||
w.Write(rlp.EmptyString)
|
||||
} else {
|
||||
if obj.Balance.Sign() == -1 {
|
||||
return rlp.ErrNegativeBigInt
|
||||
}
|
||||
w.WriteBigInt(obj.Balance)
|
||||
}
|
||||
w.WriteBytes(obj.Root[:])
|
||||
w.WriteBytes(obj.CodeHash)
|
||||
w.ListEnd(_tmp0)
|
||||
return w.Flush()
|
||||
}
|
||||
// func (obj *StateAccount) EncodeRLP(_w io.Writer) error {
|
||||
// w := rlp.NewEncoderBuffer(_w)
|
||||
// _tmp0 := w.List()
|
||||
// w.WriteUint64(obj.Nonce)
|
||||
// if obj.Balance == nil {
|
||||
// w.Write(rlp.EmptyString)
|
||||
// } else {
|
||||
// if obj.Balance.Sign() == -1 {
|
||||
// return rlp.ErrNegativeBigInt
|
||||
// }
|
||||
// w.WriteBigInt(obj.Balance)
|
||||
// }
|
||||
// w.WriteBytes(obj.Root[:])
|
||||
// w.WriteBytes(obj.CodeHash)
|
||||
// w.ListEnd(_tmp0)
|
||||
// return w.Flush()
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package types
|
|||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/codehash"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
|
|
@ -29,8 +29,14 @@ var (
|
|||
// EmptyUncleHash is the known hash of the empty uncle set.
|
||||
EmptyUncleHash = rlpHash([]*Header(nil)) // 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
|
||||
|
||||
// EmptyCodeHash is the known hash of the empty EVM bytecode.
|
||||
EmptyCodeHash = crypto.Keccak256Hash(nil) // c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
|
||||
// // EmptyCodeHash is the known hash of the empty EVM bytecode.
|
||||
// EmptyCodeHash = crypto.Keccak256Hash(nil) // c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
|
||||
|
||||
// EmptyKeccakCodeHash is the known Keccak hash of the empty EVM bytecode.
|
||||
EmptyKeccakCodeHash = codehash.EmptyKeccakCodeHash
|
||||
|
||||
// EmptyKeccakCodeHash is the known Poseidon hash of the empty EVM bytecode.
|
||||
EmptyPoseidonCodeHash = codehash.EmptyPoseidonCodeHash
|
||||
|
||||
// EmptyTxsHash is the known hash of the empty transaction set.
|
||||
EmptyTxsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||
|
|
|
|||
|
|
@ -29,18 +29,20 @@ import (
|
|||
// StateAccount is the Ethereum consensus representation of accounts.
|
||||
// These objects are stored in the main account trie.
|
||||
type StateAccount struct {
|
||||
Nonce uint64
|
||||
Balance *big.Int
|
||||
Root common.Hash // merkle root of the storage trie
|
||||
CodeHash []byte
|
||||
Nonce uint64
|
||||
Balance *big.Int
|
||||
Root common.Hash // merkle root of the storage trie
|
||||
KeccakCodeHash []byte
|
||||
PoseidonCodeHash []byte
|
||||
}
|
||||
|
||||
// NewEmptyStateAccount constructs an empty state account.
|
||||
func NewEmptyStateAccount() *StateAccount {
|
||||
return &StateAccount{
|
||||
Balance: new(big.Int),
|
||||
Root: EmptyRootHash,
|
||||
CodeHash: EmptyCodeHash.Bytes(),
|
||||
Balance: new(big.Int),
|
||||
Root: EmptyRootHash,
|
||||
KeccakCodeHash: EmptyKeccakCodeHash.Bytes(),
|
||||
PoseidonCodeHash: EmptyPoseidonCodeHash.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51,10 +53,11 @@ func (acct *StateAccount) Copy() *StateAccount {
|
|||
balance = new(big.Int).Set(acct.Balance)
|
||||
}
|
||||
return &StateAccount{
|
||||
Nonce: acct.Nonce,
|
||||
Balance: balance,
|
||||
Root: acct.Root,
|
||||
CodeHash: common.CopyBytes(acct.CodeHash),
|
||||
Nonce: acct.Nonce,
|
||||
Balance: balance,
|
||||
Root: acct.Root,
|
||||
KeccakCodeHash: common.CopyBytes(acct.KeccakCodeHash),
|
||||
PoseidonCodeHash: common.CopyBytes(acct.PoseidonCodeHash),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,10 +65,11 @@ func (acct *StateAccount) Copy() *StateAccount {
|
|||
// with a byte slice. This format can be used to represent full-consensus format
|
||||
// or slim format which replaces the empty root and code hash as nil byte slice.
|
||||
type SlimAccount struct {
|
||||
Nonce uint64
|
||||
Balance *big.Int
|
||||
Root []byte // Nil if root equals to types.EmptyRootHash
|
||||
CodeHash []byte // Nil if hash equals to types.EmptyCodeHash
|
||||
Nonce uint64
|
||||
Balance *big.Int
|
||||
Root []byte // Nil if root equals to types.EmptyRootHash
|
||||
KeccakCodeHash []byte // Nil if hash equals to types.EmptyKeccakCodeHash
|
||||
PoseidonCodeHash []byte // Nil if hash equals to types.EmptyPoseidonCodeHash
|
||||
}
|
||||
|
||||
// SlimAccountRLP encodes the state account in 'slim RLP' format.
|
||||
|
|
@ -77,8 +81,9 @@ func SlimAccountRLP(account StateAccount) []byte {
|
|||
if account.Root != EmptyRootHash {
|
||||
slim.Root = account.Root[:]
|
||||
}
|
||||
if !bytes.Equal(account.CodeHash, EmptyCodeHash[:]) {
|
||||
slim.CodeHash = account.CodeHash
|
||||
if !bytes.Equal(account.KeccakCodeHash, EmptyKeccakCodeHash[:]) {
|
||||
slim.KeccakCodeHash = account.KeccakCodeHash
|
||||
slim.PoseidonCodeHash = account.PoseidonCodeHash
|
||||
}
|
||||
data, err := rlp.EncodeToBytes(slim)
|
||||
if err != nil {
|
||||
|
|
@ -103,10 +108,12 @@ func FullAccount(data []byte) (*StateAccount, error) {
|
|||
} else {
|
||||
account.Root = common.BytesToHash(slim.Root)
|
||||
}
|
||||
if len(slim.CodeHash) == 0 {
|
||||
account.CodeHash = EmptyCodeHash[:]
|
||||
if len(slim.KeccakCodeHash) == 0 {
|
||||
account.KeccakCodeHash = EmptyKeccakCodeHash[:]
|
||||
account.PoseidonCodeHash = EmptyPoseidonCodeHash[:]
|
||||
} else {
|
||||
account.CodeHash = slim.CodeHash
|
||||
account.KeccakCodeHash = slim.KeccakCodeHash
|
||||
account.PoseidonCodeHash = slim.PoseidonCodeHash
|
||||
}
|
||||
return &account, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ type Contract struct {
|
|||
analysis bitvec // Locally cached result of JUMPDEST analysis
|
||||
|
||||
Code []byte
|
||||
CodeHash common.Hash
|
||||
CodeHash common.Hash // Keccak code hash
|
||||
CodeAddr *common.Address
|
||||
Input []byte
|
||||
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
// If the account has no code, we can abort here
|
||||
// The depth-check is already done, and precompiles handled above
|
||||
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code)
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetKeccakCodeHash(addrCopy), code)
|
||||
ret, err = evm.interpreter.Run(contract, input, false)
|
||||
gas = contract.Gas
|
||||
}
|
||||
|
|
@ -291,7 +291,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
|||
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||
// The contract is a scoped environment for this execution context only.
|
||||
contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetKeccakCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
|
||||
ret, err = evm.interpreter.Run(contract, input, false)
|
||||
gas = contract.Gas
|
||||
}
|
||||
|
|
@ -335,7 +335,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
|||
addrCopy := addr
|
||||
// Initialise a new contract and make initialise the delegate values
|
||||
contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetKeccakCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
|
||||
ret, err = evm.interpreter.Run(contract, input, false)
|
||||
gas = contract.Gas
|
||||
}
|
||||
|
|
@ -388,7 +388,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
|
|||
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||
// The contract is a scoped environment for this execution context only.
|
||||
contract := NewContract(caller, AccountRef(addrCopy), new(big.Int), gas)
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetKeccakCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
|
||||
// When an error was returned by the EVM or when setting the creation code
|
||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||
// when we're in Homestead this also counts for code storage gas errors.
|
||||
|
|
@ -411,6 +411,7 @@ type codeAndHash struct {
|
|||
|
||||
func (c *codeAndHash) Hash() common.Hash {
|
||||
if c.hash == (common.Hash{}) {
|
||||
// when calculating CREATE2 address, we use Keccak256 not Poseidon
|
||||
c.hash = crypto.Keccak256Hash(c.code)
|
||||
}
|
||||
return c.hash
|
||||
|
|
@ -437,8 +438,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
evm.StateDB.AddAddressToAccessList(address)
|
||||
}
|
||||
// Ensure there's no existing contract already at the designated address
|
||||
contractHash := evm.StateDB.GetCodeHash(address)
|
||||
if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) {
|
||||
contractHash := evm.StateDB.GetKeccakCodeHash(address)
|
||||
if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != types.EmptyKeccakCodeHash) {
|
||||
return nil, common.Address{}, 0, ErrContractAddressCollision
|
||||
}
|
||||
// Create a new account on the state
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
|
|||
|
||||
// opExtCodeHash returns the code hash of a specified account.
|
||||
// There are several cases when the function is called, while we can relay everything
|
||||
// to `state.GetCodeHash` function to ensure the correctness.
|
||||
// to `state.GetKeccakCodeHash` function to ensure the correctness.
|
||||
//
|
||||
// 1. Caller tries to get the code hash of a normal contract account, state
|
||||
// should return the relative code hash and set it as the result.
|
||||
|
|
@ -421,7 +421,7 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
|
|||
if interpreter.evm.StateDB.Empty(address) {
|
||||
slot.Clear()
|
||||
} else {
|
||||
slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes())
|
||||
slot.SetBytes(interpreter.evm.StateDB.GetKeccakCodeHash(address).Bytes())
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -725,7 +725,7 @@ func TestRandom(t *testing.T) {
|
|||
for _, tt := range []testcase{
|
||||
{name: "empty hash", random: common.Hash{}},
|
||||
{name: "1", random: common.Hash{0}},
|
||||
{name: "emptyCodeHash", random: types.EmptyCodeHash},
|
||||
{name: "emptyCodeHash", random: types.EmptyKeccakCodeHash},
|
||||
{name: "hash(0x010203)", random: crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})},
|
||||
} {
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ type StateDB interface {
|
|||
GetNonce(common.Address) uint64
|
||||
SetNonce(common.Address, uint64)
|
||||
|
||||
GetCodeHash(common.Address) common.Hash
|
||||
GetKeccakCodeHash(common.Address) common.Hash
|
||||
GetPoseidonCodeHash(common.Address) common.Hash
|
||||
GetCode(common.Address) []byte
|
||||
SetCode(common.Address, []byte)
|
||||
GetCodeSize(common.Address) int
|
||||
|
|
|
|||
23
crypto/codehash/codehash.go
Normal file
23
crypto/codehash/codehash.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package codehash
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/poseidon"
|
||||
)
|
||||
|
||||
var EmptyPoseidonCodeHash common.Hash
|
||||
var EmptyKeccakCodeHash common.Hash
|
||||
|
||||
func PoseidonCodeHash(code []byte) (h common.Hash) {
|
||||
return poseidon.CodeHash(code)
|
||||
}
|
||||
|
||||
func KeccakCodeHash(code []byte) (h common.Hash) {
|
||||
return crypto.Keccak256Hash(code)
|
||||
}
|
||||
|
||||
func init() {
|
||||
EmptyPoseidonCodeHash = poseidon.CodeHash(nil)
|
||||
EmptyKeccakCodeHash = crypto.Keccak256Hash(nil)
|
||||
}
|
||||
|
|
@ -465,7 +465,7 @@ func ServiceGetByteCodesQuery(chain *core.BlockChain, req *GetByteCodesPacket) [
|
|||
bytes uint64
|
||||
)
|
||||
for _, hash := range req.Hashes {
|
||||
if hash == types.EmptyCodeHash {
|
||||
if hash == types.EmptyKeccakCodeHash {
|
||||
// Peers should not request the empty code, but if they do, at
|
||||
// least sent them back a correct response without db lookups
|
||||
codes = append(codes, []byte{})
|
||||
|
|
|
|||
|
|
@ -1881,9 +1881,9 @@ func (s *Syncer) processAccountResponse(res *accountResponse) {
|
|||
res.task.pend = 0
|
||||
for i, account := range res.accounts {
|
||||
// Check if the account is a contract with an unknown code
|
||||
if !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||
if !rawdb.HasCodeWithPrefix(s.db, common.BytesToHash(account.CodeHash)) {
|
||||
res.task.codeTasks[common.BytesToHash(account.CodeHash)] = struct{}{}
|
||||
if !bytes.Equal(account.KeccakCodeHash, types.EmptyKeccakCodeHash.Bytes()) {
|
||||
if !rawdb.HasCodeWithPrefix(s.db, common.BytesToHash(account.KeccakCodeHash)) {
|
||||
res.task.codeTasks[common.BytesToHash(account.KeccakCodeHash)] = struct{}{}
|
||||
res.task.needCode[i] = true
|
||||
res.task.pend++
|
||||
}
|
||||
|
|
@ -1947,7 +1947,7 @@ func (s *Syncer) processBytecodeResponse(res *bytecodeResponse) {
|
|||
}
|
||||
// Code was delivered, mark it not needed any more
|
||||
for j, account := range res.task.res.accounts {
|
||||
if res.task.needCode[j] && hash == common.BytesToHash(account.CodeHash) {
|
||||
if res.task.needCode[j] && hash == common.BytesToHash(account.KeccakCodeHash) {
|
||||
res.task.needCode[j] = false
|
||||
res.task.pend--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1489,7 +1489,7 @@ func getCodeHash(i uint64) []byte {
|
|||
|
||||
// getCodeByHash convenience function to lookup the code from the code hash
|
||||
func getCodeByHash(hash common.Hash) []byte {
|
||||
if hash == types.EmptyCodeHash {
|
||||
if hash == types.EmptyKeccakCodeHash {
|
||||
return nil
|
||||
}
|
||||
for i, h := range codehashes {
|
||||
|
|
@ -1509,10 +1509,11 @@ func makeAccountTrieNoStorage(n int, scheme string) (string, *trie.Trie, []*kv)
|
|||
)
|
||||
for i := uint64(1); i <= uint64(n); i++ {
|
||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||
Nonce: i,
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: types.EmptyRootHash,
|
||||
CodeHash: getCodeHash(i),
|
||||
Nonce: i,
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: types.EmptyRootHash,
|
||||
KeccakCodeHash: getCodeHash(i),
|
||||
// TODO: PoseidonCodeHash
|
||||
})
|
||||
key := key32(i)
|
||||
elem := &kv{key, value}
|
||||
|
|
@ -1560,10 +1561,11 @@ func makeBoundaryAccountTrie(scheme string, n int) (string, *trie.Trie, []*kv) {
|
|||
// Fill boundary accounts
|
||||
for i := 0; i < len(boundaries); i++ {
|
||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||
Nonce: uint64(0),
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: types.EmptyRootHash,
|
||||
CodeHash: getCodeHash(uint64(i)),
|
||||
Nonce: uint64(0),
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: types.EmptyRootHash,
|
||||
KeccakCodeHash: getCodeHash(uint64(i)),
|
||||
// TODO: PoseidonCodeHash
|
||||
})
|
||||
elem := &kv{boundaries[i].Bytes(), value}
|
||||
accTrie.MustUpdate(elem.k, elem.v)
|
||||
|
|
@ -1572,10 +1574,11 @@ func makeBoundaryAccountTrie(scheme string, n int) (string, *trie.Trie, []*kv) {
|
|||
// Fill other accounts if required
|
||||
for i := uint64(1); i <= uint64(n); i++ {
|
||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||
Nonce: i,
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: types.EmptyRootHash,
|
||||
CodeHash: getCodeHash(i),
|
||||
Nonce: i,
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: types.EmptyRootHash,
|
||||
KeccakCodeHash: getCodeHash(i),
|
||||
// TODO: PoseidonCodeHash
|
||||
})
|
||||
elem := &kv{key32(i), value}
|
||||
accTrie.MustUpdate(elem.k, elem.v)
|
||||
|
|
@ -1607,7 +1610,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(scheme string, accounts, slots
|
|||
// Create n accounts in the trie
|
||||
for i := uint64(1); i <= uint64(accounts); i++ {
|
||||
key := key32(i)
|
||||
codehash := types.EmptyCodeHash.Bytes()
|
||||
codehash := types.EmptyKeccakCodeHash.Bytes()
|
||||
if code {
|
||||
codehash = getCodeHash(i)
|
||||
}
|
||||
|
|
@ -1616,10 +1619,11 @@ func makeAccountTrieWithStorageWithUniqueStorage(scheme string, accounts, slots
|
|||
nodes.Merge(stNodes)
|
||||
|
||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||
Nonce: i,
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: stRoot,
|
||||
CodeHash: codehash,
|
||||
Nonce: i,
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: stRoot,
|
||||
KeccakCodeHash: codehash,
|
||||
// TODO: PoseidonCodeHash
|
||||
})
|
||||
elem := &kv{key, value}
|
||||
accTrie.MustUpdate(elem.k, elem.v)
|
||||
|
|
@ -1662,7 +1666,7 @@ func makeAccountTrieWithStorage(scheme string, accounts, slots int, code, bounda
|
|||
// Create n accounts in the trie
|
||||
for i := uint64(1); i <= uint64(accounts); i++ {
|
||||
key := key32(i)
|
||||
codehash := types.EmptyCodeHash.Bytes()
|
||||
codehash := types.EmptyKeccakCodeHash.Bytes()
|
||||
if code {
|
||||
codehash = getCodeHash(i)
|
||||
}
|
||||
|
|
@ -1682,10 +1686,11 @@ func makeAccountTrieWithStorage(scheme string, accounts, slots int, code, bounda
|
|||
nodes.Merge(stNodes)
|
||||
|
||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||
Nonce: i,
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: stRoot,
|
||||
CodeHash: codehash,
|
||||
Nonce: i,
|
||||
Balance: big.NewInt(int64(i)),
|
||||
Root: stRoot,
|
||||
KeccakCodeHash: codehash,
|
||||
// TODO: PoseidonCodeHash
|
||||
})
|
||||
elem := &kv{key, value}
|
||||
accTrie.MustUpdate(elem.k, elem.v)
|
||||
|
|
@ -1838,10 +1843,11 @@ func verifyTrie(scheme string, db ethdb.KeyValueStore, root common.Hash, t *test
|
|||
accIt := trie.NewIterator(accTrie.MustNodeIterator(nil))
|
||||
for accIt.Next() {
|
||||
var acc struct {
|
||||
Nonce uint64
|
||||
Balance *big.Int
|
||||
Root common.Hash
|
||||
CodeHash []byte
|
||||
Nonce uint64
|
||||
Balance *big.Int
|
||||
Root common.Hash
|
||||
KeccakCodeHash []byte
|
||||
PoseidonCodeHash []byte
|
||||
}
|
||||
if err := rlp.DecodeBytes(accIt.Value, &acc); err != nil {
|
||||
log.Crit("Invalid account encountered during snapshot creation", "err", err)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ func (account) SetBalance(*big.Int) {}
|
|||
func (account) SetNonce(uint64) {}
|
||||
func (account) Balance() *big.Int { return nil }
|
||||
func (account) Address() common.Address { return common.Address{} }
|
||||
func (account) SetCode(common.Hash, []byte) {}
|
||||
func (account) SetCode([]byte) {}
|
||||
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
|
||||
|
||||
type dummyStatedb struct {
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ type dummyContractRef struct {
|
|||
calledForEach bool
|
||||
}
|
||||
|
||||
func (dummyContractRef) Address() common.Address { return common.Address{} }
|
||||
func (dummyContractRef) Value() *big.Int { return new(big.Int) }
|
||||
func (dummyContractRef) SetCode(common.Hash, []byte) {}
|
||||
func (dummyContractRef) Address() common.Address { return common.Address{} }
|
||||
func (dummyContractRef) Value() *big.Int { return new(big.Int) }
|
||||
func (dummyContractRef) SetCode([]byte) {}
|
||||
func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) {
|
||||
d.calledForEach = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,13 +62,14 @@ func (ec *Client) CreateAccessList(ctx context.Context, msg ethereum.CallMsg) (*
|
|||
|
||||
// AccountResult is the result of a GetProof operation.
|
||||
type AccountResult struct {
|
||||
Address common.Address `json:"address"`
|
||||
AccountProof []string `json:"accountProof"`
|
||||
Balance *big.Int `json:"balance"`
|
||||
CodeHash common.Hash `json:"codeHash"`
|
||||
Nonce uint64 `json:"nonce"`
|
||||
StorageHash common.Hash `json:"storageHash"`
|
||||
StorageProof []StorageResult `json:"storageProof"`
|
||||
Address common.Address `json:"address"`
|
||||
AccountProof []string `json:"accountProof"`
|
||||
Balance *big.Int `json:"balance"`
|
||||
KeccakCodeHash common.Hash `json:"keccakCodeHash"`
|
||||
PoseidonCodeHash common.Hash `json:"poseidonCodeHash"`
|
||||
Nonce uint64 `json:"nonce"`
|
||||
StorageHash common.Hash `json:"storageHash"`
|
||||
StorageProof []StorageResult `json:"storageProof"`
|
||||
}
|
||||
|
||||
// StorageResult provides a proof for a key-value pair.
|
||||
|
|
@ -88,13 +89,14 @@ func (ec *Client) GetProof(ctx context.Context, account common.Address, keys []s
|
|||
}
|
||||
|
||||
type accountResult struct {
|
||||
Address common.Address `json:"address"`
|
||||
AccountProof []string `json:"accountProof"`
|
||||
Balance *hexutil.Big `json:"balance"`
|
||||
CodeHash common.Hash `json:"codeHash"`
|
||||
Nonce hexutil.Uint64 `json:"nonce"`
|
||||
StorageHash common.Hash `json:"storageHash"`
|
||||
StorageProof []storageResult `json:"storageProof"`
|
||||
Address common.Address `json:"address"`
|
||||
AccountProof []string `json:"accountProof"`
|
||||
Balance *hexutil.Big `json:"balance"`
|
||||
KeccakCodeHash common.Hash `json:"keccakCodeHash"`
|
||||
PoseidonCodeHash common.Hash `json:"poseidonCodeHash"`
|
||||
Nonce hexutil.Uint64 `json:"nonce"`
|
||||
StorageHash common.Hash `json:"storageHash"`
|
||||
StorageProof []storageResult `json:"storageProof"`
|
||||
}
|
||||
|
||||
// Avoid keys being 'null'.
|
||||
|
|
@ -114,13 +116,14 @@ func (ec *Client) GetProof(ctx context.Context, account common.Address, keys []s
|
|||
})
|
||||
}
|
||||
result := AccountResult{
|
||||
Address: res.Address,
|
||||
AccountProof: res.AccountProof,
|
||||
Balance: res.Balance.ToInt(),
|
||||
Nonce: uint64(res.Nonce),
|
||||
CodeHash: res.CodeHash,
|
||||
StorageHash: res.StorageHash,
|
||||
StorageProof: storageResults,
|
||||
Address: res.Address,
|
||||
AccountProof: res.AccountProof,
|
||||
Balance: res.Balance.ToInt(),
|
||||
Nonce: uint64(res.Nonce),
|
||||
KeccakCodeHash: res.KeccakCodeHash,
|
||||
PoseidonCodeHash: res.PoseidonCodeHash,
|
||||
StorageHash: res.StorageHash,
|
||||
StorageProof: storageResults,
|
||||
}
|
||||
return &result, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ func testGetProof(t *testing.T, client *rpc.Client, addr common.Address) {
|
|||
}
|
||||
// test code
|
||||
code, _ := ethcl.CodeAt(context.Background(), addr, nil)
|
||||
if have, want := result.CodeHash, crypto.Keccak256Hash(code); have != want {
|
||||
if have, want := result.KeccakCodeHash, crypto.Keccak256Hash(code); have != want {
|
||||
t.Fatalf("codehash wrong, have %v want %v ", have, want)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -641,13 +641,14 @@ func (s *BlockChainAPI) GetBalance(ctx context.Context, address common.Address,
|
|||
|
||||
// Result structs for GetProof
|
||||
type AccountResult struct {
|
||||
Address common.Address `json:"address"`
|
||||
AccountProof []string `json:"accountProof"`
|
||||
Balance *hexutil.Big `json:"balance"`
|
||||
CodeHash common.Hash `json:"codeHash"`
|
||||
Nonce hexutil.Uint64 `json:"nonce"`
|
||||
StorageHash common.Hash `json:"storageHash"`
|
||||
StorageProof []StorageResult `json:"storageProof"`
|
||||
Address common.Address `json:"address"`
|
||||
AccountProof []string `json:"accountProof"`
|
||||
Balance *hexutil.Big `json:"balance"`
|
||||
KeccakCodeHash common.Hash `json:"keccakCodeHash"`
|
||||
PoseidonCodeHash common.Hash `json:"poseidonCodeHash"`
|
||||
Nonce hexutil.Uint64 `json:"nonce"`
|
||||
StorageHash common.Hash `json:"storageHash"`
|
||||
StorageProof []StorageResult `json:"storageProof"`
|
||||
}
|
||||
|
||||
type StorageResult struct {
|
||||
|
|
@ -688,7 +689,8 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
|
|||
if statedb == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
codeHash := statedb.GetCodeHash(address)
|
||||
keccakCodeHash := statedb.GetKeccakCodeHash(address)
|
||||
poseidonCodeHash := statedb.GetPoseidonCodeHash(address)
|
||||
storageRoot := statedb.GetStorageRoot(address)
|
||||
|
||||
if len(keys) > 0 {
|
||||
|
|
@ -735,13 +737,14 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
|
|||
return nil, err
|
||||
}
|
||||
return &AccountResult{
|
||||
Address: address,
|
||||
AccountProof: accountProof,
|
||||
Balance: (*hexutil.Big)(statedb.GetBalance(address)),
|
||||
CodeHash: codeHash,
|
||||
Nonce: hexutil.Uint64(statedb.GetNonce(address)),
|
||||
StorageHash: storageRoot,
|
||||
StorageProof: storageProof,
|
||||
Address: address,
|
||||
AccountProof: accountProof,
|
||||
Balance: (*hexutil.Big)(statedb.GetBalance(address)),
|
||||
KeccakCodeHash: keccakCodeHash,
|
||||
PoseidonCodeHash: poseidonCodeHash,
|
||||
Nonce: hexutil.Uint64(statedb.GetNonce(address)),
|
||||
StorageHash: storageRoot,
|
||||
StorageProof: storageProof,
|
||||
}, statedb.Error()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -311,9 +311,9 @@ func handleGetCode(msg Decoder) (serveRequestFn, uint64, uint64, error) {
|
|||
p.bumpInvalid()
|
||||
continue
|
||||
}
|
||||
code, err := bc.StateCache().ContractCode(address, common.BytesToHash(account.CodeHash))
|
||||
code, err := bc.StateCache().ContractCode(address, common.BytesToHash(account.KeccakCodeHash))
|
||||
if err != nil {
|
||||
p.Log().Warn("Failed to retrieve account code", "block", header.Number, "hash", header.Hash(), "account", address, "codehash", common.BytesToHash(account.CodeHash), "err", err)
|
||||
p.Log().Warn("Failed to retrieve account code", "block", header.Number, "hash", header.Hash(), "account", address, "codehash", common.BytesToHash(account.KeccakCodeHash), "err", err)
|
||||
continue
|
||||
}
|
||||
// Accumulate the code and abort if enough data was retrieved
|
||||
|
|
|
|||
|
|
@ -32,10 +32,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
)
|
||||
|
||||
var (
|
||||
sha3Nil = crypto.Keccak256Hash(nil)
|
||||
)
|
||||
|
||||
func NewState(ctx context.Context, head *types.Header, odr OdrBackend) *state.StateDB {
|
||||
state, _ := state.New(head.Root, NewStateDatabase(ctx, head, odr), nil)
|
||||
return state
|
||||
|
|
@ -73,7 +69,7 @@ func (db *odrDatabase) CopyTrie(t state.Trie) state.Trie {
|
|||
}
|
||||
|
||||
func (db *odrDatabase) ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error) {
|
||||
if codeHash == sha3Nil {
|
||||
if codeHash == types.EmptyKeccakCodeHash {
|
||||
return nil, nil
|
||||
}
|
||||
code := rawdb.ReadCode(db.backend.Database(), codeHash)
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, par
|
|||
// as is.
|
||||
func (s *Sync) AddCodeEntry(hash common.Hash, path []byte, parent common.Hash, parentPath []byte) {
|
||||
// Short circuit if the entry is empty or already known
|
||||
if hash == types.EmptyCodeHash {
|
||||
if hash == types.EmptyKeccakCodeHash {
|
||||
return
|
||||
}
|
||||
if s.membatch.hasCode(hash) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/codehash"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
|
|
@ -762,9 +763,10 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
|
|||
accounts = make([][]byte, len(addresses))
|
||||
for i := 0; i < len(accounts); i++ {
|
||||
var (
|
||||
nonce = uint64(random.Int63())
|
||||
root = types.EmptyRootHash
|
||||
code = crypto.Keccak256(nil)
|
||||
nonce = uint64(random.Int63())
|
||||
root = types.EmptyRootHash
|
||||
codekeccak = codehash.EmptyKeccakCodeHash
|
||||
codeposeidon = codehash.EmptyPoseidonCodeHash
|
||||
)
|
||||
// The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
|
||||
// and will consume different amount of data from the rand source.
|
||||
|
|
@ -774,7 +776,7 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
|
|||
balanceBytes := make([]byte, numBytes)
|
||||
random.Read(balanceBytes)
|
||||
balance := new(big.Int).SetBytes(balanceBytes)
|
||||
data, _ := rlp.EncodeToBytes(&types.StateAccount{Nonce: nonce, Balance: balance, Root: root, CodeHash: code})
|
||||
data, _ := rlp.EncodeToBytes(&types.StateAccount{Nonce: nonce, Balance: balance, Root: root, KeccakCodeHash: codekeccak.Bytes(), PoseidonCodeHash: codeposeidon.Bytes()})
|
||||
accounts[i] = data
|
||||
}
|
||||
return addresses, accounts
|
||||
|
|
|
|||
|
|
@ -52,10 +52,11 @@ func updateTrie(addrHash common.Hash, root common.Hash, dirties, cleans map[comm
|
|||
|
||||
func generateAccount(storageRoot common.Hash) types.StateAccount {
|
||||
return types.StateAccount{
|
||||
Nonce: uint64(rand.Intn(100)),
|
||||
Balance: big.NewInt(rand.Int63()),
|
||||
CodeHash: testutil.RandBytes(32),
|
||||
Root: storageRoot,
|
||||
Nonce: uint64(rand.Intn(100)),
|
||||
Balance: big.NewInt(rand.Int63()),
|
||||
KeccakCodeHash: testutil.RandBytes(32),
|
||||
PoseidonCodeHash: testutil.RandBytes(32),
|
||||
Root: storageRoot,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue