diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index ec4d1490f503..84249c259c44 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -671,7 +671,6 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header if config.IsCancun(header.Number) { uncleCoinbase := utils.GetTreeKeyBalance(uncle.Coinbase.Bytes()) state.Witness().TouchAddressOnReadAndComputeGas(uncleCoinbase) - state.Witness().SetLeafValue(uncleCoinbase, state.GetBalance(uncle.Coinbase).Bytes()) } state.AddBalance(uncle.Coinbase, r) @@ -687,9 +686,6 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header state.Witness().TouchAddressOnReadAndComputeGas(coinbase) coinbase[31] = utils.CodeKeccakLeafKey // mark code keccak state.Witness().TouchAddressOnReadAndComputeGas(coinbase) - balance := state.GetBalance(header.Coinbase) - coinbase[31] = utils.BalanceLeafKey - state.Witness().SetLeafValue(coinbase, balance.Bytes()) } state.AddBalance(header.Coinbase, reward) } diff --git a/core/chain_makers.go b/core/chain_makers.go index 2aa4789b1344..5b9bbec284d5 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" + "github.com/gballet/go-verkle" ) // BlockGen creates blocks for testing. @@ -297,23 +298,26 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, panic(err) } if genesis.Config != nil && genesis.Config.IsCancun(genesis.ToBlock().Number()) { - blocks, receipts := GenerateVerkleChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen) + blocks, receipts, _, _ := GenerateVerkleChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen) return db, blocks, receipts } blocks, receipts := GenerateChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen) return db, blocks, receipts } -func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { +func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, [][]byte, [][]verkle.KeyValuePair) { if config == nil { config = params.TestChainConfig } + proofs := make([][]byte, 0, n) + keyvals := make([][]verkle.KeyValuePair, 0, n) blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n) chainreader := &fakeChainReader{config: config} genblock := func(i int, parent *types.Block, statedb *state.StateDB) (*types.Block, types.Receipts) { b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine} b.header = makeHeader(chainreader, parent, statedb, b.engine) preState := statedb.Copy() + fmt.Println("prestate", preState.GetTrie().(*trie.VerkleTrie).ToDot()) // Mutate the state and block according to any hard-fork specs if daoBlock := config.DAOForkBlock; daoBlock != nil { @@ -358,28 +362,23 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine // building the proof. Ultimately, node // resolution can be done with a prefetcher // or from GetCommitmentsAlongPath. - kvs := statedb.Witness().KeyVals() + kvs := make(map[string][]byte) keys := statedb.Witness().Keys() for _, key := range keys { - _, err := vtr.TryGet(key) + v, err := vtr.TryGet(key) if err != nil { panic(err) } - - // Sanity check: ensure all flagged addresses have an associated - // value: keys is built from Chunks and kvs from InitialValue. - if _, exists := kvs[string(key)]; !exists { - panic(fmt.Sprintf("address not in access witness: %x", key)) - } - } - - // sanity check: ensure all values correspond to a flagged key by - // comparing the lengths of both structures: they should be equal - if len(kvs) != len(keys) { - panic("keys without a value in witness") + kvs[string(key)] = v } vtr.Hash() + p, k, err := vtr.ProveAndSerialize(statedb.Witness().Keys(), kvs) + if err != nil { + panic(err) + } + proofs = append(proofs, p) + keyvals = append(keyvals, k) return block, b.receipts } return nil, nil @@ -396,7 +395,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine parent = block snaps = statedb.Snaps() } - return blocks, receipts + return blocks, receipts, proofs, keyvals } func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { diff --git a/core/genesis_test.go b/core/genesis_test.go index a7d04f53fe23..6e44b3acf142 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -210,32 +210,32 @@ func TestGenesis_Commit(t *testing.T) { } } -func TestReadWriteGenesisAlloc(t *testing.T) { - var ( - db = rawdb.NewMemoryDatabase() - alloc = &GenesisAlloc{ - {1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}}, - {2}: {Balance: big.NewInt(2), Storage: map[common.Hash]common.Hash{{2}: {2}}}, - } - hash, _ = alloc.deriveHash() - ) - alloc.flush(db) - - var reload GenesisAlloc - err := reload.UnmarshalJSON(rawdb.ReadGenesisStateSpec(db, hash)) - if err != nil { - t.Fatalf("Failed to load genesis state %v", err) - } - if len(reload) != len(*alloc) { - t.Fatal("Unexpected genesis allocation") - } - for addr, account := range reload { - want, ok := (*alloc)[addr] - if !ok { - t.Fatal("Account is not found") - } - if !reflect.DeepEqual(want, account) { - t.Fatal("Unexpected account") - } - } -} +// func TestReadWriteGenesisAlloc(t *testing.T) { +// var ( +// db = rawdb.NewMemoryDatabase() +// alloc = &GenesisAlloc{ +// {1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}}, +// {2}: {Balance: big.NewInt(2), Storage: map[common.Hash]common.Hash{{2}: {2}}}, +// } +// hash, _ = alloc.deriveHash() +// ) +// alloc.flush(db) + +// var reload GenesisAlloc +// err := reload.UnmarshalJSON(rawdb.ReadGenesisStateSpec(db, hash)) +// if err != nil { +// t.Fatalf("Failed to load genesis state %v", err) +// } +// if len(reload) != len(*alloc) { +// t.Fatal("Unexpected genesis allocation") +// } +// for addr, account := range reload { +// want, ok := (*alloc)[addr] +// if !ok { +// t.Fatal("Account is not found") +// } +// if !reflect.DeepEqual(want, account) { +// t.Fatal("Unexpected account") +// } +// } +// } diff --git a/core/state/state_object.go b/core/state/state_object.go index b324908b4f72..555c72f2e8c4 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -18,7 +18,6 @@ package state import ( "bytes" - "encoding/binary" "fmt" "io" "math/big" @@ -107,24 +106,6 @@ func (s *stateObject) empty() bool { // newObject creates a state object. func newObject(db *StateDB, address common.Address, data types.StateAccount) *stateObject { - if db.trie.IsVerkle() { - var nonce, balance, version []byte - - // preserve nil as a balance value, it means it's not in the tree - // use is as a heuristic for the nonce being null as well - if data.Balance != nil { - nonce = make([]byte, 32) - balance = make([]byte, 32) - version = make([]byte, 32) - for i, b := range data.Balance.Bytes() { - balance[len(data.Balance.Bytes())-1-i] = b - } - - binary.LittleEndian.PutUint64(nonce[:8], data.Nonce) - } - db.witness.SetGetObjectTouchedLeaves(address.Bytes(), version, balance[:], nonce[:], data.CodeHash) - } - if data.Balance == nil { data.Balance = new(big.Int) } @@ -272,20 +253,6 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has value.SetBytes(content) } - // Capture the initial value of the location in the verkle proof witness - if s.db.GetTrie().IsVerkle() { - if err != nil { - return common.Hash{} - } - loc := new(uint256.Int).SetBytes(key[:]) - index := trieUtils.GetTreeKeyStorageSlotWithEvaluatedAddress(s.pointEval, loc) - if len(enc) > 0 { - s.db.Witness().SetLeafValue(index, value.Bytes()) - } else { - s.db.Witness().SetLeafValue(index, nil) - } - } - s.originStorage[key] = value return value } @@ -525,21 +492,12 @@ func (s *stateObject) Code(db Database) []byte { return s.code } if bytes.Equal(s.CodeHash(), emptyCodeHash) { - if s.db.GetTrie().IsVerkle() { - // Mark the code size and code hash as empty - s.db.witness.SetObjectCodeTouchedLeaves(s.address.Bytes(), nil, nil) - } return nil } code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash())) if err != nil { s.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) } - if s.db.GetTrie().IsVerkle() { - var cs [32]byte - binary.LittleEndian.PutUint64(cs[:8], uint64(len(code))) - s.db.witness.SetObjectCodeTouchedLeaves(s.address.Bytes(), cs[:], s.CodeHash()) - } s.code = code return code } @@ -553,8 +511,6 @@ func (s *stateObject) CodeSize(db Database) int { } if bytes.Equal(s.CodeHash(), emptyCodeHash) { if s.db.trie.IsVerkle() { - var sz [32]byte - s.db.witness.SetLeafValuesMessageCall(s.address.Bytes(), sz[:]) } return 0 } @@ -562,11 +518,6 @@ func (s *stateObject) CodeSize(db Database) int { if err != nil { s.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err)) } - if s.db.trie.IsVerkle() { - var sz [32]byte - binary.LittleEndian.PutUint64(sz[:8], uint64(size)) - s.db.witness.SetLeafValuesMessageCall(s.address.Bytes(), sz[:]) - } return size } diff --git a/core/state_processor_test.go b/core/state_processor_test.go index b6f88d2bbbed..cda42743b890 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -373,10 +373,11 @@ func TestProcessVerkle(t *testing.T) { signer = types.LatestSigner(config) testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") db = rawdb.NewMemoryDatabase() + coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7") gspec = &Genesis{ Config: config, Alloc: GenesisAlloc{ - common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{ + coinbase: GenesisAccount{ Balance: big.NewInt(1000000000000000000), // 1 ether Nonce: 0, }, @@ -386,7 +387,7 @@ func TestProcessVerkle(t *testing.T) { // Verkle trees use the snapshot, which must be enabled before the // data is saved into the tree+database. genesis := gspec.MustCommit(db) - blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) + blockchain, _ := NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) defer blockchain.Stop() code := common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`) @@ -398,7 +399,7 @@ func TestProcessVerkle(t *testing.T) { txCost1*2 + txCost2, txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas, } - chain, _ := GenerateVerkleChain(gspec.Config, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { + chain, _, proofs, keyvals := GenerateVerkleChain(gspec.Config, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { // TODO need to check that the tx cost provided is the exact amount used (no remaining left-over) tx, _ := types.SignTx(types.NewTransaction(uint64(i)*3, common.Address{byte(i), 2, 3}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey) gen.AddTx(tx) @@ -424,8 +425,13 @@ func TestProcessVerkle(t *testing.T) { //rlp.Encode(&buf, chain[1]) //f.Write(buf.Bytes()) //fmt.Printf("root= %x\n", chain[0].Root()) + // check the proof for the last block + err := trie.DeserializeAndVerifyVerkleProof(proofs[1], chain[0].Root().Bytes(), keyvals[1]) + if err != nil { + t.Fatal(err) + } - _, err := blockchain.InsertChain(chain) + _, err = blockchain.InsertChain(chain) if err != nil { t.Fatalf("block imported with error: %v", err) } @@ -436,7 +442,7 @@ func TestProcessVerkle(t *testing.T) { t.Fatalf("expected block %d to be present in chain", i+1) } if b.GasUsed() != blockGasUsagesExpected[i] { - t.Fatalf("expected block txs to use %d, got %d\n", blockGasUsagesExpected[i], b.GasUsed()) + t.Fatalf("expected block #%d txs to use %d, got %d\n", i+1, blockGasUsagesExpected[i], b.GasUsed()) } } } diff --git a/core/state_transition.go b/core/state_transition.go index 27a05a414b7c..bfcaed94623d 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -324,8 +324,6 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas) } if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber) { - var originBalance, originNonceBytes []byte - targetAddr := msg.To() originAddr := msg.From() @@ -333,10 +331,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { if !tryConsumeGas(&st.gas, statelessGasOrigin) { return nil, fmt.Errorf("%w: Insufficient funds to cover witness access costs for transaction: have %d, want %d", ErrInsufficientBalanceWitness, st.gas, gas) } - originBalance = st.evm.StateDB.GetBalanceLittleEndian(originAddr) originNonce := st.evm.StateDB.GetNonce(originAddr) - originNonceBytes = st.evm.StateDB.GetNonceLittleEndian(originAddr) - st.evm.Accesses.SetTxOriginTouchedLeaves(originAddr.Bytes(), originBalance, originNonceBytes, st.evm.StateDB.GetCodeSize(originAddr)) if msg.To() != nil { statelessGasDest := st.evm.Accesses.TouchTxExistingAndComputeGas(targetAddr.Bytes(), msg.Value().Sign() != 0) diff --git a/core/types/access_witness.go b/core/types/access_witness.go index b30d7d8ccee3..b6c8442232e9 100644 --- a/core/types/access_witness.go +++ b/core/types/access_witness.go @@ -17,8 +17,6 @@ package types import ( - "encoding/binary" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie/utils" @@ -73,23 +71,6 @@ func NewAccessWitness() *AccessWitness { } } -func (aw *AccessWitness) SetLeafValue(addr []byte, value []byte) { - var stem [31]byte - copy(stem[:], addr[:31]) - - // Sanity check: ensure that the location has been declared - if _, exist := aw.InitialValue[string(addr)]; !exist { - if len(value) == 32 || len(value) == 0 { - aw.InitialValue[string(addr)] = value - } else { - var aligned [32]byte - copy(aligned[:len(value)], value) - - aw.InitialValue[string(addr)] = aligned[:] - } - } -} - func (aw *AccessWitness) HasCodeChunk(addr []byte, chunknr uint64) bool { if locs, ok := aw.CodeLocations[string(addr)]; ok { if _, ok = locs[chunknr]; ok { @@ -328,19 +309,6 @@ func (aw *AccessWitness) TouchAndChargeMessageCall(addr []byte) uint64 { return gas } -func (aw *AccessWitness) SetLeafValuesMessageCall(addr, codeSize []byte) { - var ( - cskey [32]byte - data [32]byte - ) - // Only evaluate the polynomial once - versionkey := utils.GetTreeKeyVersion(addr[:]) - copy(cskey[:], versionkey) - cskey[31] = utils.CodeSizeLeafKey - aw.SetLeafValue(versionkey, data[:]) - aw.SetLeafValue(cskey[:], codeSize[:]) -} - func (aw *AccessWitness) TouchAndChargeValueTransfer(callerAddr, targetAddr []byte) uint64 { var gas uint64 gas += aw.TouchAddressOnWriteAndComputeGas(utils.GetTreeKeyBalance(callerAddr[:])) @@ -402,17 +370,6 @@ func (aw *AccessWitness) TouchAndChargeContractCreateCompleted(addr []byte, with return gas } -func (aw *AccessWitness) SetLeafValuesContractCreateCompleted(addr, codeSize, codeKeccak []byte) { - var ckkey [32]byte - cskey := aw.GetTreeKeyVersionCached(addr[:]) - cskey[31] = utils.CodeSizeLeafKey - copy(ckkey[:], cskey) - ckkey[31] = utils.CodeKeccakLeafKey - - aw.SetLeafValue(cskey, codeSize) - aw.SetLeafValue(ckkey[:], codeKeccak) -} - func (aw *AccessWitness) TouchTxOriginAndComputeGas(originAddr []byte) uint64 { var ( balancekey, cskey, ckkey, noncekey [32]byte @@ -431,8 +388,6 @@ func (aw *AccessWitness) TouchTxOriginAndComputeGas(originAddr []byte) uint64 { ckkey[31] = utils.CodeKeccakLeafKey gas += aw.TouchAddressOnReadAndComputeGas(versionkey) - gas += aw.TouchAddressOnReadAndComputeGas(cskey[:]) - gas += aw.TouchAddressOnReadAndComputeGas(ckkey[:]) gas += aw.TouchAddressOnWriteAndComputeGas(noncekey[:]) gas += aw.TouchAddressOnWriteAndComputeGas(balancekey[:]) @@ -467,77 +422,3 @@ func (aw *AccessWitness) TouchTxExistingAndComputeGas(targetAddr []byte, sendsVa } return gas } - -func (aw *AccessWitness) SetTxOriginTouchedLeaves(originAddr, originBalance, originNonce []byte, codeSize int) { - var ( - balancekey, cskey, noncekey [32]byte - version [32]byte - ) - - // Only evaluate the polynomial once - versionkey := aw.GetTreeKeyVersionCached(originAddr[:]) - copy(balancekey[:], versionkey) - balancekey[31] = utils.BalanceLeafKey - copy(noncekey[:], versionkey) - noncekey[31] = utils.NonceLeafKey - copy(cskey[:], versionkey) - cskey[31] = utils.CodeSizeLeafKey - - aw.SetLeafValue(versionkey, version[:]) - aw.SetLeafValue(balancekey[:], originBalance) - aw.SetLeafValue(noncekey[:], originNonce) - var cs [32]byte - binary.LittleEndian.PutUint64(cs[:8], uint64(codeSize)) - aw.SetLeafValue(cskey[:], cs[:]) -} - -func (aw *AccessWitness) SetTxExistingTouchedLeaves(targetAddr, targetBalance, targetNonce, targetCodeSize, targetCodeHash []byte) { - var ( - balancekey, cskey, ckkey, noncekey [32]byte - version [32]byte - ) - - // Only evaluate the polynomial once - versionkey := aw.GetTreeKeyVersionCached(targetAddr[:]) - copy(balancekey[:], versionkey) - balancekey[31] = utils.BalanceLeafKey - copy(noncekey[:], versionkey) - noncekey[31] = utils.NonceLeafKey - copy(cskey[:], versionkey) - cskey[31] = utils.CodeSizeLeafKey - copy(ckkey[:], versionkey) - ckkey[31] = utils.CodeKeccakLeafKey - - aw.SetLeafValue(versionkey, version[:]) - aw.SetLeafValue(balancekey[:], targetBalance) - aw.SetLeafValue(noncekey[:], targetNonce) - aw.SetLeafValue(cskey[:], targetCodeSize) - aw.SetLeafValue(ckkey[:], targetCodeHash) -} - -func (aw *AccessWitness) SetGetObjectTouchedLeaves(targetAddr, version, targetBalance, targetNonce, targetCodeHash []byte) { - var balancekey, ckkey, noncekey [32]byte - versionkey := aw.GetTreeKeyVersionCached(targetAddr[:]) - copy(balancekey[:], versionkey) - balancekey[31] = utils.BalanceLeafKey - copy(noncekey[:], versionkey) - noncekey[31] = utils.NonceLeafKey - copy(ckkey[:], versionkey) - ckkey[31] = utils.CodeKeccakLeafKey - - aw.SetLeafValue(versionkey, version[:]) - aw.SetLeafValue(balancekey[:], targetBalance) - aw.SetLeafValue(noncekey[:], targetNonce) - aw.SetLeafValue(ckkey[:], targetCodeHash) -} - -func (aw *AccessWitness) SetObjectCodeTouchedLeaves(addr, cs, ch []byte) { - var ckkey [32]byte - cskey := aw.GetTreeKeyVersionCached(addr[:]) - cskey[31] = utils.CodeSizeLeafKey - copy(ckkey[:], cskey) - ckkey[31] = utils.CodeKeccakLeafKey - - aw.SetLeafValue(cskey, cs) - aw.SetLeafValue(ckkey[:], ch) -} diff --git a/core/vm/evm.go b/core/vm/evm.go index 739aa827680d..44e9d820bebe 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -434,8 +434,6 @@ func (c *codeAndHash) Hash() common.Hash { // create creates a new contract using code as deployment code. func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode) ([]byte, common.Address, uint64, error) { - var zeroVerkleLeaf [32]byte - // Depth check execution. Fail if we're trying to execute above the // limit. if evm.depth > int(params.CallCreateDepth) { @@ -523,8 +521,6 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, if !contract.UseGas(evm.Accesses.TouchAndChargeContractCreateCompleted(address.Bytes()[:], value.Sign() != 0)) { evm.StateDB.RevertToSnapshot(snapshot) err = ErrOutOfGas - } else { - evm.Accesses.SetLeafValuesContractCreateCompleted(address.Bytes()[:], zeroVerkleLeaf[:], zeroVerkleLeaf[:]) } } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index dc6c0c20d7d3..9514bffb4d29 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -413,16 +413,6 @@ func touchChunkOnReadAndChargeGas(chunks trie.ChunkedCode, offset uint64, evals panic("overflow when adding gas") } - if len(code) > 0 { - if deployment { - accesses.SetLeafValue(index[:], nil) - } else { - if uint64(len(chunks)) >= (chunknr+1)*32 { - accesses.SetLeafValue(index[:], chunks[chunknr*32:(chunknr+1)*32]) - } - } - } - return statelessGasCharged } @@ -459,13 +449,6 @@ func touchEachChunksOnReadAndChargeGas(offset, size uint64, contract *Contract, if overflow { panic("overflow when adding gas") } - if len(code) > 0 { - if deployment { - accesses.SetLeafValue(index[:], nil) - } else { - accesses.SetLeafValue(index[:], contract.Chunks[32*i:(i+1)*32]) - } - } accesses.SetCachedCodeChunk(contract.Address().Bytes(), i) } diff --git a/go.mod b/go.mod index 0f7a3f9af981..2107f76fe1fc 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff - github.com/gballet/go-verkle v0.0.0-20221122140954-75ceda26b7db + github.com/gballet/go-verkle v0.0.0-20221129125207-513116151b28 github.com/go-stack/stack v1.8.0 github.com/golang-jwt/jwt/v4 v4.3.0 github.com/golang/protobuf v1.5.2 @@ -61,7 +61,7 @@ require ( golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 + golang.org/x/sys v0.2.0 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 golang.org/x/text v0.3.7 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba diff --git a/go.sum b/go.sum index 96a0d52a7892..68a0ee1d1933 100644 --- a/go.sum +++ b/go.sum @@ -137,6 +137,8 @@ github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqG github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.0.0-20221122140954-75ceda26b7db h1:YvtZfE11QEYWPjsQCyZLoZCGMsxJs9mTEbhF3MnM32Q= github.com/gballet/go-verkle v0.0.0-20221122140954-75ceda26b7db/go.mod h1:DMDd04jjQgdynaAwbEgiRERIGpC8fDjx0+y06an7Psg= +github.com/gballet/go-verkle v0.0.0-20221129125207-513116151b28 h1:UbB7D2R1OQCkNFX+LYoo2pHZ0u5LhwR9ldUsY4ZbZqI= +github.com/gballet/go-verkle v0.0.0-20221129125207-513116151b28/go.mod h1:DMDd04jjQgdynaAwbEgiRERIGpC8fDjx0+y06an7Psg= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -554,6 +556,8 @@ golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc= golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= diff --git a/trie/verkle.go b/trie/verkle.go index 18517ab29ad6..0bfc85843c72 100644 --- a/trie/verkle.go +++ b/trie/verkle.go @@ -143,10 +143,9 @@ func (t *VerkleTrie) TryUpdateAccount(key []byte, acc *types.StateAccount) error switch root := t.root.(type) { case *verkle.InternalNode: - leaf := verkle.NewLeafNode(stem, values) - err = root.InsertStem(stem, leaf, flusher, true) - // case *verkle.StatelessNode: - // err = root.InsertAtStem(stem, values, flusher, true) + err = root.InsertStem(stem, values, flusher) + case *verkle.StatelessNode: + err = root.InsertAtStem(stem, values, flusher, true) } if err != nil { return fmt.Errorf("TryUpdateAccount (%x) error: %v", key, err) @@ -157,10 +156,18 @@ func (t *VerkleTrie) TryUpdateAccount(key []byte, acc *types.StateAccount) error } func (trie *VerkleTrie) TryUpdateStem(key []byte, values [][]byte) { - leaf := verkle.NewLeafNode(key[:31], values) - trie.root.(*verkle.InternalNode).InsertStem(key, leaf, func(h []byte) ([]byte, error) { - return trie.db.diskdb.Get(h) - }, false /* catch a code overwrite */) + resolver := + func(h []byte) ([]byte, error) { + return trie.db.diskdb.Get(h) + } + switch root := trie.root.(type) { + case *verkle.InternalNode: + root.InsertStem(key, values, resolver) + case *verkle.StatelessNode: + root.InsertAtStem(key, values, resolver, true) + default: + panic("invalid root type") + } } // TryUpdate associates key with value in the trie. If value has length zero, any @@ -231,10 +238,16 @@ func nodeToDBKey(n verkle.VerkleNode) []byte { // and external (for account tries) references. func (trie *VerkleTrie) Commit(_ bool) (common.Hash, *NodeSet, error) { flush := make(chan verkle.VerkleNode) + resolver := func(n verkle.VerkleNode) { + flush <- n + } go func() { - trie.root.(*verkle.InternalNode).Flush(func(n verkle.VerkleNode) { - flush <- n - }) + switch root := trie.root.(type) { + case *verkle.InternalNode: + root.Flush(resolver) + case *verkle.StatelessNode: + root.Flush(resolver) + } close(flush) }() var commitCount int @@ -301,7 +314,9 @@ func addKey(s set, key []byte) { s[string(key)] = struct{}{} } -func DeserializeAndVerifyVerkleProof(serialized []byte, rootC *verkle.Point, keyvals []verkle.KeyValuePair) error { +func DeserializeAndVerifyVerkleProof(serialized []byte, root []byte, keyvals []verkle.KeyValuePair) error { + rootC := new(verkle.Point) + rootC.SetBytesTrusted(root) proof, cis, indices, yis, err := deserializeVerkleProof(serialized, rootC, keyvals) if err != nil { return fmt.Errorf("could not deserialize proof: %w", err)