mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
feat: change bytecode hash function from Keccak to Poseidon (#149)
* feat: change bytecode hash function from Keccak to Poseidon * fix TestStateProcessorErrors * rename files * copy iden3's poseidon package to local * update poseidon hash * apply new hash in codehash * extend hash method, use actual code size as cap * prune keccak(nil) for empty code * update empty code hash references to Poseidon * add TestPoseidonCodeHash * use keccak for empty code hash * go mod tidy * goimports * use Poseidon code hash in state and sync tests * run goimports * run goimports * remove unnecessary reallocation from CodeHash * goimports * move codehash API to separate module * add missing package * fix review comments * improve comments Co-authored-by: Ho Vei <noelwei@gmail.com>
This commit is contained in:
parent
346bfc82e8
commit
304af60f50
25 changed files with 25516 additions and 41 deletions
|
|
@ -32,7 +32,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/core/state/pruner"
|
"github.com/scroll-tech/go-ethereum/core/state/pruner"
|
||||||
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/log"
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
"github.com/scroll-tech/go-ethereum/rlp"
|
"github.com/scroll-tech/go-ethereum/rlp"
|
||||||
"github.com/scroll-tech/go-ethereum/trie"
|
"github.com/scroll-tech/go-ethereum/trie"
|
||||||
|
|
@ -43,7 +43,7 @@ var (
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
// emptyCode is the known hash of the empty EVM bytecode.
|
||||||
emptyCode = crypto.Keccak256(nil)
|
emptyCode = codehash.EmptyCodeHash.Bytes()
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus"
|
"github.com/scroll-tech/go-ethereum/consensus"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus/ethash"
|
"github.com/scroll-tech/go-ethereum/consensus/ethash"
|
||||||
|
|
@ -2986,3 +2988,108 @@ func TestEIP1559Transition(t *testing.T) {
|
||||||
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestPoseidonCodeHash makes sure that, after switching
|
||||||
|
// to Poseidon, code hashes change but addresses do not.
|
||||||
|
func TestPoseidonCodeHash(t *testing.T) {
|
||||||
|
// pragma solidity =0.8.7;
|
||||||
|
//
|
||||||
|
// contract Factory {
|
||||||
|
// event Deployed(address addr);
|
||||||
|
//
|
||||||
|
// function create(bytes memory code) public {
|
||||||
|
// address addr;
|
||||||
|
//
|
||||||
|
// assembly {
|
||||||
|
// addr := create(0, add(code, 0x20), mload(code))
|
||||||
|
// if iszero(extcodesize(addr)) {
|
||||||
|
// revert(0, 0)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// emit Deployed(addr);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// function create2(bytes memory code) public {
|
||||||
|
// address addr;
|
||||||
|
//
|
||||||
|
// assembly {
|
||||||
|
// addr := create2(0, add(code, 0x20), mload(code), 0)
|
||||||
|
// if iszero(extcodesize(addr)) {
|
||||||
|
// revert(0, 0)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// emit Deployed(addr);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
var deployCode = common.Hex2Bytes("608060405234801561001057600080fd5b506101d1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063cf5ba53f1461003b578063f4754f6614610050575b600080fd5b61004e6100493660046100d4565b610063565b005b61004e61005e3660046100d4565b6100bb565b60008151602083016000f09050803b61007b57600080fd5b6040516001600160a01b03821681527ff40fcec21964ffb566044d083b4073f29f7f7929110ea19e1b3ebe375d89055e9060200160405180910390a15050565b6000808251602084016000f59050803b61007b57600080fd5b6000602082840312156100e657600080fd5b813567ffffffffffffffff808211156100fe57600080fd5b818401915084601f83011261011257600080fd5b81358181111561012457610124610185565b604051601f8201601f19908116603f0116810190838211818310171561014c5761014c610185565b8160405282815287602084870101111561016557600080fd5b826020860160208301376000928101602001929092525095945050505050565b634e487b7160e01b600052604160045260246000fdfea2646970667358221220c9bd2005b8669d44bf0254309308e422e7bdf086ac7a507990a0690a22b1eccd64736f6c63430008070033")
|
||||||
|
|
||||||
|
var callCreateCode = common.Hex2Bytes("cf5ba53f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005c6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220707985753fcb6578098bb16f3709cf6d012993cba6dd3712661cf8f57bbc0d4d64736f6c6343000807003300000000")
|
||||||
|
var callCreate2Code = common.Hex2Bytes("f4754f660000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005c6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220707985753fcb6578098bb16f3709cf6d012993cba6dd3712661cf8f57bbc0d4d64736f6c6343000807003300000000")
|
||||||
|
|
||||||
|
var (
|
||||||
|
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
|
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
|
db = rawdb.NewMemoryDatabase()
|
||||||
|
gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
|
||||||
|
genesis = gspec.MustCommit(db)
|
||||||
|
signer = types.LatestSigner(gspec.Config)
|
||||||
|
engine = ethash.NewFaker()
|
||||||
|
blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
defer blockchain.Stop()
|
||||||
|
|
||||||
|
// check empty code hash
|
||||||
|
state, _ := blockchain.State()
|
||||||
|
codeHash := state.GetCodeHash(addr1)
|
||||||
|
assert.Equal(t, codeHash, common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), "code hash mismatch")
|
||||||
|
|
||||||
|
// deploy contract through transaction
|
||||||
|
chain, receipts := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, gen *BlockGen) {
|
||||||
|
tx, _ := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, deployCode), signer, key1)
|
||||||
|
gen.AddTx(tx)
|
||||||
|
})
|
||||||
|
|
||||||
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
|
t.Fatalf("failed to insert chain: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure that the address did not change
|
||||||
|
contractAddress := receipts[0][0].ContractAddress
|
||||||
|
assert.Equal(t, common.HexToAddress("0x3A220f351252089D385b29beca14e27F204c296A"), contractAddress, "address mismatch")
|
||||||
|
|
||||||
|
state, _ = blockchain.State()
|
||||||
|
codeHash = state.GetCodeHash(contractAddress)
|
||||||
|
|
||||||
|
// keccak: 0x089bfd332dfa6117cbc20756f31801ce4f5a175eb258e46bf8123317da54cd96
|
||||||
|
assert.Equal(t, codeHash, common.HexToHash("0x28ec09723b285e17caabc4a8d52dbd097feddf408aee115cbb57c3c9c814d2b2"), "code hash mismatch")
|
||||||
|
|
||||||
|
// deploy contract through another contract (CREATE and CREATE2)
|
||||||
|
chain, receipts = GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), engine, db, 1, func(i int, gen *BlockGen) {
|
||||||
|
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), contractAddress, new(big.Int), 1000000, gen.header.BaseFee, callCreateCode), signer, key1)
|
||||||
|
gen.AddTx(tx)
|
||||||
|
|
||||||
|
tx2, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), contractAddress, new(big.Int), 1000000, gen.header.BaseFee, callCreate2Code), signer, key1)
|
||||||
|
gen.AddTx(tx2)
|
||||||
|
})
|
||||||
|
|
||||||
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
|
t.Fatalf("failed to insert chain: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
address1 := common.BytesToAddress(receipts[0][0].Logs[0].Data)
|
||||||
|
address2 := common.BytesToAddress(receipts[0][1].Logs[0].Data)
|
||||||
|
|
||||||
|
assert.Equal(t, common.HexToAddress("0x733f1083Fe476698001FA20D651376b7b3F1CA79"), address1, "address mismatch")
|
||||||
|
assert.Equal(t, common.HexToAddress("0x4099734c88B7D091E744da0E849df0e818e7E208"), address2, "address mismatch")
|
||||||
|
|
||||||
|
state, _ = blockchain.State()
|
||||||
|
codeHash1 := state.GetCodeHash(address1)
|
||||||
|
codeHash2 := state.GetCodeHash(address2)
|
||||||
|
|
||||||
|
// keccak: 0xfb5cd93a70ce47f91d33fac3afdb7b54680a6b0683506646a108ef4dfc047583
|
||||||
|
assert.Equal(t, common.HexToHash("0x2fa5836118b70a257defd2e54064ab63cc9bb2e91823eaacbdef32370050b5b2"), codeHash1, "code hash mismatch")
|
||||||
|
assert.Equal(t, common.HexToHash("0x2fa5836118b70a257defd2e54064ab63cc9bb2e91823eaacbdef32370050b5b2"), codeHash2, "code hash mismatch")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||||
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb"
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
||||||
"github.com/scroll-tech/go-ethereum/log"
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
"github.com/scroll-tech/go-ethereum/rlp"
|
"github.com/scroll-tech/go-ethereum/rlp"
|
||||||
|
|
@ -60,7 +60,7 @@ var (
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
// emptyCode is the known hash of the empty EVM bytecode.
|
||||||
emptyCode = crypto.Keccak256(nil)
|
emptyCode = codehash.EmptyCodeHash.Bytes()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pruner is an offline tool to prune the stale state with the
|
// Pruner is an offline tool to prune the stale state with the
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
||||||
"github.com/scroll-tech/go-ethereum/common/math"
|
"github.com/scroll-tech/go-ethereum/common/math"
|
||||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb"
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb/memorydb"
|
"github.com/scroll-tech/go-ethereum/ethdb/memorydb"
|
||||||
"github.com/scroll-tech/go-ethereum/log"
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
|
|
@ -44,7 +44,7 @@ var (
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
// emptyCode is the known hash of the empty EVM bytecode.
|
||||||
emptyCode = crypto.Keccak256Hash(nil)
|
emptyCode = codehash.EmptyCodeHash
|
||||||
|
|
||||||
// accountCheckRange is the upper limit of the number of accounts involved in
|
// accountCheckRange is the upper limit of the number of accounts involved in
|
||||||
// each range check. This is a value estimated based on experience. If this
|
// each range check. This is a value estimated based on experience. If this
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,12 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/metrics"
|
"github.com/scroll-tech/go-ethereum/metrics"
|
||||||
"github.com/scroll-tech/go-ethereum/rlp"
|
"github.com/scroll-tech/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var emptyCodeHash = crypto.Keccak256(nil)
|
var emptyCodeHash = codehash.EmptyCodeHash.Bytes()
|
||||||
|
|
||||||
type Code []byte
|
type Code []byte
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import (
|
||||||
|
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb"
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -47,7 +47,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(codehash.CodeHash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3})
|
||||||
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))
|
||||||
|
|
||||||
|
|
@ -59,7 +59,7 @@ func TestDump(t *testing.T) {
|
||||||
// check that DumpToCollector contains the state objects that are in trie
|
// check that DumpToCollector contains the state objects that are in trie
|
||||||
got := string(s.state.Dump(nil))
|
got := string(s.state.Dump(nil))
|
||||||
want := `{
|
want := `{
|
||||||
"root": "71edff0130dd2385947095001c73d9e28d862fc286fca2b922ca6f6f3cddfdd2",
|
"root": "bfd17853c56ac63be7327da432ef90a9b04376d71efede2a60765d2c94704cfe",
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"0x0000000000000000000000000000000000000001": {
|
"0x0000000000000000000000000000000000000001": {
|
||||||
"balance": "22",
|
"balance": "22",
|
||||||
|
|
@ -79,7 +79,7 @@ func TestDump(t *testing.T) {
|
||||||
"balance": "0",
|
"balance": "0",
|
||||||
"nonce": 0,
|
"nonce": 0,
|
||||||
"root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
"root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||||
"codeHash": "0x87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3",
|
"codeHash": "0x2263940ad476ca23bf01a9b033d65cd6b8bf9b7224a7ef2a4f10b61a2c039083",
|
||||||
"code": "0x03030303030303",
|
"code": "0x03030303030303",
|
||||||
"key": "0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1"
|
"key": "0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1"
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +165,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(codehash.CodeHash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'})
|
||||||
so0.suicided = false
|
so0.suicided = false
|
||||||
so0.deleted = false
|
so0.deleted = false
|
||||||
state.setStateObject(so0)
|
state.setStateObject(so0)
|
||||||
|
|
@ -177,7 +177,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(codehash.CodeHash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'})
|
||||||
so1.suicided = true
|
so1.suicided = true
|
||||||
so1.deleted = true
|
so1.deleted = true
|
||||||
state.setStateObject(so1)
|
state.setStateObject(so1)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/log"
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
"github.com/scroll-tech/go-ethereum/metrics"
|
"github.com/scroll-tech/go-ethereum/metrics"
|
||||||
"github.com/scroll-tech/go-ethereum/rlp"
|
"github.com/scroll-tech/go-ethereum/rlp"
|
||||||
|
|
@ -459,7 +460,7 @@ func (s *StateDB) SetNonce(addr common.Address, nonce uint64) {
|
||||||
func (s *StateDB) SetCode(addr common.Address, code []byte) {
|
func (s *StateDB) SetCode(addr common.Address, code []byte) {
|
||||||
stateObject := s.GetOrNewStateObject(addr)
|
stateObject := s.GetOrNewStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
stateObject.SetCode(crypto.Keccak256Hash(code), code)
|
stateObject.SetCode(codehash.CodeHash(code), code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb"
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb/memorydb"
|
"github.com/scroll-tech/go-ethereum/ethdb/memorydb"
|
||||||
"github.com/scroll-tech/go-ethereum/rlp"
|
"github.com/scroll-tech/go-ethereum/rlp"
|
||||||
|
|
@ -58,12 +59,12 @@ func makeTestState() (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(codehash.CodeHash([]byte{i, i, i, i, i}), []byte{i, i, i, i, i})
|
||||||
acc.code = []byte{i, i, i, i, i}
|
acc.code = []byte{i, i, i, i, i}
|
||||||
}
|
}
|
||||||
if i%5 == 0 {
|
if i%5 == 0 {
|
||||||
for j := byte(0); j < 5; j++ {
|
for j := byte(0); j < 5; j++ {
|
||||||
hash := crypto.Keccak256Hash([]byte{i, i, i, i, i, j, j})
|
hash := codehash.CodeHash([]byte{i, i, i, i, i, j, j})
|
||||||
obj.SetState(db, hash, hash)
|
obj.SetState(db, hash, hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -407,7 +408,7 @@ func TestIncompleteStateSync(t *testing.T) {
|
||||||
var isCode = make(map[common.Hash]struct{})
|
var isCode = make(map[common.Hash]struct{})
|
||||||
for _, acc := range srcAccounts {
|
for _, acc := range srcAccounts {
|
||||||
if len(acc.code) > 0 {
|
if len(acc.code) > 0 {
|
||||||
isCode[crypto.Keccak256Hash(acc.code)] = struct{}{}
|
isCode[codehash.CodeHash(acc.code)] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isCode[common.BytesToHash(emptyCodeHash)] = struct{}{}
|
isCode[common.BytesToHash(emptyCodeHash)] = struct{}{}
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ func TestStateProcessorErrors(t *testing.T) {
|
||||||
txs: []*types.Transaction{
|
txs: []*types.Transaction{
|
||||||
mkDynamicTx(0, common.Address{}, params.TxGas-1000, big.NewInt(0), big.NewInt(0)),
|
mkDynamicTx(0, common.Address{}, params.TxGas-1000, big.NewInt(0), big.NewInt(0)),
|
||||||
},
|
},
|
||||||
want: "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: sender not an eoa: address 0x71562b71999873DB5b286dF957af199Ec94617F7, codehash: 0x9280914443471259d4570a8661015ae4a5b80186dbc619658fb494bebc3da3d1",
|
want: "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: sender not an eoa: address 0x71562b71999873DB5b286dF957af199Ec94617F7, codehash: 0x14644f8304e8c7052dee61ac235af61e12e25a730d13beccac8b3b72f5705874",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
|
block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@ import (
|
||||||
cmath "github.com/scroll-tech/go-ethereum/common/math"
|
cmath "github.com/scroll-tech/go-ethereum/common/math"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/core/vm"
|
"github.com/scroll-tech/go-ethereum/core/vm"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
var emptyCodeHash = crypto.Keccak256Hash(nil)
|
var emptyCodeHash = codehash.EmptyCodeHash
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The State Transitioning Model
|
The State Transitioning Model
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package zktrie
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/iden3/go-iden3-crypto/poseidon"
|
"github.com/scroll-tech/go-ethereum/crypto/poseidon"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HashElems performs a recursive poseidon hash over the array of ElemBytes, each hash
|
// HashElems performs a recursive poseidon hash over the array of ElemBytes, each hash
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
func HashElems(fst, snd *big.Int, elems ...*big.Int) (*Hash, error) {
|
func HashElems(fst, snd *big.Int, elems ...*big.Int) (*Hash, error) {
|
||||||
|
|
||||||
l := len(elems)
|
l := len(elems)
|
||||||
baseH, err := poseidon.Hash([]*big.Int{fst, snd})
|
baseH, err := poseidon.HashFixed([]*big.Int{fst, snd})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ func HashElems(fst, snd *big.Int, elems ...*big.Int) (*Hash, error) {
|
||||||
if (i+1)*2 > l {
|
if (i+1)*2 > l {
|
||||||
tmp[i] = elems[i*2+1]
|
tmp[i] = elems[i*2+1]
|
||||||
} else {
|
} else {
|
||||||
h, err := poseidon.Hash(elems[i*2 : (i+1)*2])
|
h, err := poseidon.HashFixed(elems[i*2 : (i+1)*2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,13 @@ import (
|
||||||
|
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// emptyCodeHash is used by create to ensure deployment is disallowed to already
|
// emptyCodeHash is used by create to ensure deployment is disallowed to already
|
||||||
// deployed contract addresses (relevant after the account abstraction).
|
// deployed contract addresses (relevant after the account abstraction).
|
||||||
var emptyCodeHash = crypto.Keccak256Hash(nil)
|
var emptyCodeHash = codehash.EmptyCodeHash
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// CanTransferFunc is the signature of a transfer guard function
|
// CanTransferFunc is the signature of a transfer guard function
|
||||||
|
|
@ -410,6 +411,7 @@ type codeAndHash struct {
|
||||||
|
|
||||||
func (c *codeAndHash) Hash() common.Hash {
|
func (c *codeAndHash) Hash() common.Hash {
|
||||||
if c.hash == (common.Hash{}) {
|
if c.hash == (common.Hash{}) {
|
||||||
|
// when calculating CREATE2 address, we use Keccak256 not Poseidon
|
||||||
c.hash = crypto.Keccak256Hash(c.code)
|
c.hash = crypto.Keccak256Hash(c.code)
|
||||||
}
|
}
|
||||||
return c.hash
|
return c.hash
|
||||||
|
|
|
||||||
16
crypto/codehash/codehash.go
Normal file
16
crypto/codehash/codehash.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package codehash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/poseidon"
|
||||||
|
)
|
||||||
|
|
||||||
|
var EmptyCodeHash common.Hash
|
||||||
|
|
||||||
|
func CodeHash(code []byte) (h common.Hash) {
|
||||||
|
return poseidon.CodeHash(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
EmptyCodeHash = poseidon.CodeHash(nil)
|
||||||
|
}
|
||||||
47
crypto/poseidon/codehash.go
Normal file
47
crypto/poseidon/codehash.go
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
package poseidon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultPoseidonChunk = 3
|
||||||
|
|
||||||
|
func CodeHash(code []byte) (h common.Hash) {
|
||||||
|
// special case for nil hash
|
||||||
|
if len(code) == 0 {
|
||||||
|
return crypto.Keccak256Hash(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
cap := int64(len(code))
|
||||||
|
|
||||||
|
// step 1: pad code with 0x0 (STOP) so that len(code) % 16 == 0
|
||||||
|
// step 2: for every 16 bytes, convert to Fr, so that we get a Fr array
|
||||||
|
var length = (len(code) + 15) / 16
|
||||||
|
|
||||||
|
Frs := make([]*big.Int, length)
|
||||||
|
ii := 0
|
||||||
|
|
||||||
|
for ii < length-1 {
|
||||||
|
Frs[ii] = big.NewInt(0)
|
||||||
|
Frs[ii].SetBytes(code[ii*16 : (ii+1)*16])
|
||||||
|
ii++
|
||||||
|
}
|
||||||
|
|
||||||
|
Frs[ii] = big.NewInt(0)
|
||||||
|
bytes := make([]byte, 16)
|
||||||
|
copy(bytes, code[ii*16:])
|
||||||
|
Frs[ii].SetBytes(bytes)
|
||||||
|
|
||||||
|
// step 3: apply the array onto a sponge process with the current poseidon scheme
|
||||||
|
// (3 Frs permutation and 1 Fr for output, so the throughout is 2 Frs)
|
||||||
|
// step 4: convert final root Fr to u256 (big-endian representation)
|
||||||
|
hash, _ := HashWithCap(Frs, defaultPoseidonChunk, cap)
|
||||||
|
|
||||||
|
codeHash := common.Hash{}
|
||||||
|
hash.FillBytes(codeHash[:])
|
||||||
|
|
||||||
|
return codeHash
|
||||||
|
}
|
||||||
24
crypto/poseidon/codehash_test.go
Normal file
24
crypto/poseidon/codehash_test.go
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
package poseidon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPoseidonCodeHash(t *testing.T) {
|
||||||
|
// nil
|
||||||
|
got := fmt.Sprintf("%s", CodeHash(nil))
|
||||||
|
want := "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
||||||
|
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("got %q, wanted %q", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
// single byte
|
||||||
|
got = fmt.Sprintf("%s", CodeHash([]byte{0}))
|
||||||
|
want = "0x0ee069e6aa796ef0e46cbd51d10468393d443a00f5affe72898d9ab62e335e16"
|
||||||
|
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("got %q, wanted %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
24906
crypto/poseidon/constants.go
Normal file
24906
crypto/poseidon/constants.go
Normal file
File diff suppressed because it is too large
Load diff
192
crypto/poseidon/poseidon.go
Normal file
192
crypto/poseidon/poseidon.go
Normal file
|
|
@ -0,0 +1,192 @@
|
||||||
|
// from github.com/iden3/go-iden3-crypto/ff/poseidon
|
||||||
|
|
||||||
|
package poseidon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/iden3/go-iden3-crypto/ff"
|
||||||
|
"github.com/iden3/go-iden3-crypto/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const NROUNDSF = 8 //nolint:golint
|
||||||
|
|
||||||
|
var NROUNDSP = []int{56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68} //nolint:golint
|
||||||
|
|
||||||
|
func zero() *ff.Element {
|
||||||
|
return ff.NewElement()
|
||||||
|
}
|
||||||
|
|
||||||
|
// exp5 performs x^5 mod p
|
||||||
|
// https://eprint.iacr.org/2019/458.pdf page 8
|
||||||
|
func exp5(a *ff.Element) {
|
||||||
|
a.Exp(*a, big.NewInt(5)) //nolint:gomnd
|
||||||
|
}
|
||||||
|
|
||||||
|
// exp5state perform exp5 for whole state
|
||||||
|
func exp5state(state []*ff.Element) {
|
||||||
|
for i := 0; i < len(state); i++ {
|
||||||
|
exp5(state[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ark computes Add-Round Key, from the paper https://eprint.iacr.org/2019/458.pdf
|
||||||
|
func ark(state []*ff.Element, c []*ff.Element, it int) {
|
||||||
|
for i := 0; i < len(state); i++ {
|
||||||
|
state[i].Add(state[i], c[it+i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mix returns [[matrix]] * [vector]
|
||||||
|
func mix(state []*ff.Element, t int, m [][]*ff.Element) []*ff.Element {
|
||||||
|
mul := zero()
|
||||||
|
newState := make([]*ff.Element, t)
|
||||||
|
for i := 0; i < t; i++ {
|
||||||
|
newState[i] = zero()
|
||||||
|
}
|
||||||
|
for i := 0; i < len(state); i++ {
|
||||||
|
newState[i].SetUint64(0)
|
||||||
|
for j := 0; j < len(state); j++ {
|
||||||
|
mul.Mul(m[j][i], state[j])
|
||||||
|
newState[i].Add(newState[i], mul)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newState
|
||||||
|
}
|
||||||
|
|
||||||
|
func permute(state []*ff.Element, t int) []*ff.Element {
|
||||||
|
|
||||||
|
nRoundsF := NROUNDSF
|
||||||
|
nRoundsP := NROUNDSP[t-2]
|
||||||
|
C := c.c[t-2]
|
||||||
|
S := c.s[t-2]
|
||||||
|
M := c.m[t-2]
|
||||||
|
P := c.p[t-2]
|
||||||
|
|
||||||
|
ark(state, C, 0)
|
||||||
|
|
||||||
|
for i := 0; i < nRoundsF/2-1; i++ {
|
||||||
|
exp5state(state)
|
||||||
|
ark(state, C, (i+1)*t)
|
||||||
|
state = mix(state, t, M)
|
||||||
|
}
|
||||||
|
exp5state(state)
|
||||||
|
ark(state, C, (nRoundsF/2)*t)
|
||||||
|
state = mix(state, t, P)
|
||||||
|
|
||||||
|
for i := 0; i < nRoundsP; i++ {
|
||||||
|
exp5(state[0])
|
||||||
|
state[0].Add(state[0], C[(nRoundsF/2+1)*t+i])
|
||||||
|
|
||||||
|
mul := zero()
|
||||||
|
newState0 := zero()
|
||||||
|
for j := 0; j < len(state); j++ {
|
||||||
|
mul.Mul(S[(t*2-1)*i+j], state[j])
|
||||||
|
newState0.Add(newState0, mul)
|
||||||
|
}
|
||||||
|
|
||||||
|
for k := 1; k < t; k++ {
|
||||||
|
mul = zero()
|
||||||
|
state[k] = state[k].Add(state[k], mul.Mul(state[0], S[(t*2-1)*i+t+k-1]))
|
||||||
|
}
|
||||||
|
state[0] = newState0
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < nRoundsF/2-1; i++ {
|
||||||
|
exp5state(state)
|
||||||
|
ark(state, C, (nRoundsF/2+1)*t+nRoundsP+i*t)
|
||||||
|
state = mix(state, t, M)
|
||||||
|
}
|
||||||
|
exp5state(state)
|
||||||
|
return mix(state, t, M)
|
||||||
|
}
|
||||||
|
|
||||||
|
// for short, use size of inpBI as cap
|
||||||
|
func Hash(inpBI []*big.Int, width int) (*big.Int, error) {
|
||||||
|
return HashWithCap(inpBI, width, int64(len(inpBI)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash using possible sponge specs specified by width (rate from 1 to 15), the size of input is applied as capacity
|
||||||
|
// (notice we do not include width in the capacity )
|
||||||
|
func HashWithCap(inpBI []*big.Int, width int, cap int64) (*big.Int, error) {
|
||||||
|
if width < 2 {
|
||||||
|
return nil, fmt.Errorf("width must be ranged from 2 to 16")
|
||||||
|
}
|
||||||
|
if width-2 > len(NROUNDSP) {
|
||||||
|
return nil, fmt.Errorf("invalid inputs width %d, max %d", width, len(NROUNDSP)+1) //nolint:gomnd,lll
|
||||||
|
}
|
||||||
|
|
||||||
|
capflag := ff.NewElement().SetBigInt(big.NewInt(cap))
|
||||||
|
|
||||||
|
state := make([]*ff.Element, width)
|
||||||
|
state[0] = capflag
|
||||||
|
for i := 1; i < width; i++ {
|
||||||
|
state[i] = zero()
|
||||||
|
}
|
||||||
|
|
||||||
|
rate := width - 1
|
||||||
|
var absorb []*ff.Element
|
||||||
|
for len(inpBI) > 0 {
|
||||||
|
// sponge for fully absorb
|
||||||
|
if l := len(absorb); l != 0 {
|
||||||
|
//sanity check
|
||||||
|
if l != rate {
|
||||||
|
panic("unexpected absorption size")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, elm := range absorb {
|
||||||
|
state[i+1].Add(state[i+1], elm)
|
||||||
|
}
|
||||||
|
state = permute(state, width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// absorb
|
||||||
|
if len(inpBI) < rate {
|
||||||
|
// padding zero() equal to no action on state
|
||||||
|
absorb = utils.BigIntArrayToElementArray(inpBI)
|
||||||
|
inpBI = nil
|
||||||
|
} else {
|
||||||
|
absorb = utils.BigIntArrayToElementArray(inpBI[:rate])
|
||||||
|
inpBI = inpBI[rate:]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//last time sponge (padding with unabsorb items)
|
||||||
|
for i, elm := range absorb {
|
||||||
|
state[i+1].Add(state[i+1], elm)
|
||||||
|
}
|
||||||
|
state = permute(state, width)
|
||||||
|
|
||||||
|
//squeeze
|
||||||
|
rE := state[0]
|
||||||
|
r := big.NewInt(0)
|
||||||
|
rE.ToBigIntRegular(r)
|
||||||
|
return r, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash computes the Poseidon hash for the given fixed-size inputs, select specs automatically from the size, no capacity flag is applied
|
||||||
|
func HashFixed(inpBI []*big.Int) (*big.Int, error) {
|
||||||
|
t := len(inpBI) + 1
|
||||||
|
if len(inpBI) == 0 || len(inpBI) > len(NROUNDSP) {
|
||||||
|
return nil, fmt.Errorf("invalid inputs length %d, max %d", len(inpBI), len(NROUNDSP)) //nolint:gomnd,lll
|
||||||
|
}
|
||||||
|
if !utils.CheckBigIntArrayInField(inpBI[:]) {
|
||||||
|
return nil, errors.New("inputs values not inside Finite Field")
|
||||||
|
}
|
||||||
|
inp := utils.BigIntArrayToElementArray(inpBI[:])
|
||||||
|
|
||||||
|
state := make([]*ff.Element, t)
|
||||||
|
state[0] = zero()
|
||||||
|
copy(state[1:], inp[:])
|
||||||
|
|
||||||
|
state = permute(state, t)
|
||||||
|
|
||||||
|
rE := state[0]
|
||||||
|
r := big.NewInt(0)
|
||||||
|
rE.ToBigIntRegular(r)
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
170
crypto/poseidon/poseidon_test.go
Normal file
170
crypto/poseidon/poseidon_test.go
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
// from github.com/iden3/go-iden3-crypto/ff/poseidon
|
||||||
|
package poseidon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/iden3/go-iden3-crypto/utils"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPoseidonHashFixed(t *testing.T) {
|
||||||
|
b0 := big.NewInt(0)
|
||||||
|
b1 := big.NewInt(1)
|
||||||
|
b2 := big.NewInt(2)
|
||||||
|
b3 := big.NewInt(3)
|
||||||
|
b4 := big.NewInt(4)
|
||||||
|
b5 := big.NewInt(5)
|
||||||
|
b6 := big.NewInt(6)
|
||||||
|
b7 := big.NewInt(7)
|
||||||
|
b8 := big.NewInt(8)
|
||||||
|
b9 := big.NewInt(9)
|
||||||
|
b10 := big.NewInt(10)
|
||||||
|
b11 := big.NewInt(11)
|
||||||
|
b12 := big.NewInt(12)
|
||||||
|
b13 := big.NewInt(13)
|
||||||
|
b14 := big.NewInt(14)
|
||||||
|
b15 := big.NewInt(15)
|
||||||
|
b16 := big.NewInt(16)
|
||||||
|
|
||||||
|
h, err := HashFixed([]*big.Int{b1})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"18586133768512220936620570745912940619677854269274689475585506675881198879027",
|
||||||
|
h.String())
|
||||||
|
|
||||||
|
h, err = HashFixed([]*big.Int{b1, b2})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"7853200120776062878684798364095072458815029376092732009249414926327459813530",
|
||||||
|
h.String())
|
||||||
|
|
||||||
|
h, err = HashFixed([]*big.Int{b1, b2, b0, b0, b0})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"1018317224307729531995786483840663576608797660851238720571059489595066344487",
|
||||||
|
h.String())
|
||||||
|
h, err = HashFixed([]*big.Int{b1, b2, b0, b0, b0, b0})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"15336558801450556532856248569924170992202208561737609669134139141992924267169",
|
||||||
|
h.String())
|
||||||
|
|
||||||
|
h, err = HashFixed([]*big.Int{b3, b4, b0, b0, b0})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"5811595552068139067952687508729883632420015185677766880877743348592482390548",
|
||||||
|
h.String())
|
||||||
|
h, err = HashFixed([]*big.Int{b3, b4, b0, b0, b0, b0})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"12263118664590987767234828103155242843640892839966517009184493198782366909018",
|
||||||
|
h.String())
|
||||||
|
|
||||||
|
h, err = HashFixed([]*big.Int{b1, b2, b3, b4, b5, b6})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"20400040500897583745843009878988256314335038853985262692600694741116813247201",
|
||||||
|
h.String())
|
||||||
|
|
||||||
|
h, err = HashFixed([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"8354478399926161176778659061636406690034081872658507739535256090879947077494",
|
||||||
|
h.String())
|
||||||
|
|
||||||
|
h, err = HashFixed([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b0, b0, b0, b0, b0})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"5540388656744764564518487011617040650780060800286365721923524861648744699539",
|
||||||
|
h.String())
|
||||||
|
|
||||||
|
h, err = HashFixed([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b0, b0, b0, b0, b0, b0, b0})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"11882816200654282475720830292386643970958445617880627439994635298904836126497",
|
||||||
|
h.String())
|
||||||
|
|
||||||
|
h, err = HashFixed([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"9989051620750914585850546081941653841776809718687451684622678807385399211877",
|
||||||
|
h.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorInputs(t *testing.T) {
|
||||||
|
b0 := big.NewInt(0)
|
||||||
|
b1 := big.NewInt(1)
|
||||||
|
b2 := big.NewInt(2)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
_, err = HashFixed([]*big.Int{b1, b2, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0})
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
_, err = HashFixed([]*big.Int{b1, b2, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0})
|
||||||
|
require.NotNil(t, err)
|
||||||
|
assert.Equal(t, "invalid inputs length 17, max 16", err.Error())
|
||||||
|
|
||||||
|
_, err = HashFixed([]*big.Int{b1, b2, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0})
|
||||||
|
require.NotNil(t, err)
|
||||||
|
assert.Equal(t, "invalid inputs length 18, max 16", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInputsNotInField(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Very big number, should just return error and not go into endless loop
|
||||||
|
b1 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061999999999999999999999999999999999999999999999999999999999") //nolint:lll
|
||||||
|
_, err = HashFixed([]*big.Int{b1})
|
||||||
|
require.Error(t, err, "inputs values not inside Finite Field")
|
||||||
|
|
||||||
|
// Finite Field const Q, should return error
|
||||||
|
b2 := utils.NewIntFromString("21888242871839275222246405745257275088548364400416034343698204186575808495617") //nolint:lll
|
||||||
|
_, err = HashFixed([]*big.Int{b2})
|
||||||
|
require.Error(t, err, "inputs values not inside Finite Field")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPoseidonHash(t *testing.T) {
|
||||||
|
ret, err := Hash(nil, 3)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash nil for width 3 equal to Hash([0, 0])
|
||||||
|
retRef, err := HashFixed([]*big.Int{big.NewInt(0), big.NewInt(0)})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, ret, retRef)
|
||||||
|
|
||||||
|
// hash is different for the cap flag
|
||||||
|
ret1, err := Hash([]*big.Int{big.NewInt(0)}, 3)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NotEqual(t, ret1, retRef)
|
||||||
|
|
||||||
|
ret2, err := HashWithCap([]*big.Int{big.NewInt(0)}, 3, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, ret2, retRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkPoseidonHash(b *testing.B) {
|
||||||
|
b0 := big.NewInt(0)
|
||||||
|
b1 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061") //nolint:lll
|
||||||
|
b2 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061") //nolint:lll
|
||||||
|
|
||||||
|
bigArray4 := []*big.Int{b1, b2, b0, b0, b0, b0}
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
HashFixed(bigArray4) //nolint:errcheck,gosec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,6 +36,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb"
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
||||||
"github.com/scroll-tech/go-ethereum/event"
|
"github.com/scroll-tech/go-ethereum/event"
|
||||||
"github.com/scroll-tech/go-ethereum/light"
|
"github.com/scroll-tech/go-ethereum/light"
|
||||||
|
|
@ -50,7 +51,7 @@ var (
|
||||||
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
|
|
||||||
// emptyCode is the known hash of the empty EVM bytecode.
|
// emptyCode is the known hash of the empty EVM bytecode.
|
||||||
emptyCode = crypto.Keccak256Hash(nil)
|
emptyCode = codehash.EmptyCodeHash
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
||||||
7
go.mod
7
go.mod
|
|
@ -56,9 +56,10 @@ require (
|
||||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
|
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
|
||||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
|
||||||
golang.org/x/text v0.3.6
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
|
||||||
|
golang.org/x/text v0.3.7
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6
|
||||||
|
|
|
||||||
16
go.sum
16
go.sum
|
|
@ -492,8 +492,9 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||||
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
|
@ -507,8 +508,9 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|
@ -548,19 +550,23 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo=
|
|
||||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/core/vm"
|
"github.com/scroll-tech/go-ethereum/core/vm"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/log"
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
"github.com/scroll-tech/go-ethereum/p2p"
|
"github.com/scroll-tech/go-ethereum/p2p"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/go-ethereum/params"
|
||||||
|
|
@ -672,7 +673,7 @@ func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Addre
|
||||||
storageHash = storageTrie.Hash()
|
storageHash = storageTrie.Hash()
|
||||||
} else {
|
} else {
|
||||||
// no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray.
|
// no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray.
|
||||||
codeHash = crypto.Keccak256Hash(nil)
|
codeHash = codehash.EmptyCodeHash
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the proof for the storageKeys
|
// create the proof for the storageKeys
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,12 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/core/state"
|
"github.com/scroll-tech/go-ethereum/core/state"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb"
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
||||||
"github.com/scroll-tech/go-ethereum/rlp"
|
"github.com/scroll-tech/go-ethereum/rlp"
|
||||||
"github.com/scroll-tech/go-ethereum/trie"
|
"github.com/scroll-tech/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
sha3Nil = crypto.Keccak256Hash(nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewState(ctx context.Context, head *types.Header, odr OdrBackend) *state.StateDB {
|
func NewState(ctx context.Context, head *types.Header, odr OdrBackend) *state.StateDB {
|
||||||
state, _ := state.New(head.Root, NewStateDatabase(ctx, head, odr), nil)
|
state, _ := state.New(head.Root, NewStateDatabase(ctx, head, odr), nil)
|
||||||
return state
|
return state
|
||||||
|
|
@ -73,7 +70,7 @@ func (db *odrDatabase) CopyTrie(t state.Trie) state.Trie {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *odrDatabase) ContractCode(addrHash, codeHash common.Hash) ([]byte, error) {
|
func (db *odrDatabase) ContractCode(addrHash, codeHash common.Hash) ([]byte, error) {
|
||||||
if codeHash == sha3Nil {
|
if codeHash == codehash.EmptyCodeHash {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
code := rawdb.ReadCode(db.backend.Database(), codeHash)
|
code := rawdb.ReadCode(db.backend.Database(), codeHash)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/common/prque"
|
"github.com/scroll-tech/go-ethereum/common/prque"
|
||||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb"
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -189,7 +190,7 @@ func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, cal
|
||||||
// as is.
|
// as is.
|
||||||
func (s *Sync) AddCodeEntry(hash common.Hash, path []byte, parent common.Hash) {
|
func (s *Sync) AddCodeEntry(hash common.Hash, path []byte, parent common.Hash) {
|
||||||
// Short circuit if the entry is empty or already known
|
// Short circuit if the entry is empty or already known
|
||||||
if hash == emptyState {
|
if hash == codehash.EmptyCodeHash {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.membatch.hasCode(hash) {
|
if s.membatch.hasCode(hash) {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto/codehash"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb"
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb/leveldb"
|
"github.com/scroll-tech/go-ethereum/ethdb/leveldb"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb/memorydb"
|
"github.com/scroll-tech/go-ethereum/ethdb/memorydb"
|
||||||
|
|
@ -649,7 +650,7 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
|
||||||
var (
|
var (
|
||||||
nonce = uint64(random.Int63())
|
nonce = uint64(random.Int63())
|
||||||
root = emptyRoot
|
root = emptyRoot
|
||||||
code = crypto.Keccak256(nil)
|
code = codehash.EmptyCodeHash.Bytes()
|
||||||
)
|
)
|
||||||
// The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
|
// 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.
|
// and will consume different amount of data from the rand source.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue