mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
Merge branch 'ethereum:master' into portal
This commit is contained in:
commit
d1ec5b945c
23 changed files with 1290 additions and 317 deletions
|
|
@ -53,6 +53,7 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -226,8 +227,7 @@ func doInstall(cmdline []string) {
|
|||
|
||||
// Do the build!
|
||||
for _, pkg := range packages {
|
||||
args := make([]string, len(gobuild.Args))
|
||||
copy(args, gobuild.Args)
|
||||
args := slices.Clone(gobuild.Args)
|
||||
args = append(args, "-o", executablePath(path.Base(pkg)))
|
||||
args = append(args, pkg)
|
||||
build.MustRun(&exec.Cmd{Path: gobuild.Path, Args: args, Env: gobuild.Env})
|
||||
|
|
|
|||
|
|
@ -398,21 +398,25 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
|
|||
if parent == nil {
|
||||
return nil, fmt.Errorf("nil parent header for block %d", header.Number)
|
||||
}
|
||||
|
||||
preTrie, err := state.Database().OpenTrie(parent.Root)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error opening pre-state tree root: %w", err)
|
||||
}
|
||||
|
||||
vktPreTrie, okpre := preTrie.(*trie.VerkleTrie)
|
||||
vktPostTrie, okpost := state.GetTrie().(*trie.VerkleTrie)
|
||||
|
||||
// The witness is only attached iff both parent and current block are
|
||||
// using verkle tree.
|
||||
if okpre && okpost {
|
||||
if len(keys) > 0 {
|
||||
verkleProof, stateDiff, err := vktPreTrie.Proof(vktPostTrie, keys, vktPreTrie.FlatdbNodeResolver)
|
||||
verkleProof, stateDiff, err := vktPreTrie.Proof(vktPostTrie, keys)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error generating verkle proof for block %d: %w", header.Number, err)
|
||||
}
|
||||
block = block.WithWitness(&types.ExecutionWitness{StateDiff: stateDiff, VerkleProof: verkleProof})
|
||||
block = block.WithWitness(&types.ExecutionWitness{
|
||||
StateDiff: stateDiff,
|
||||
VerkleProof: verkleProof,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,9 +81,15 @@ var (
|
|||
// value-transfer transaction with n bytes of extra data in each
|
||||
// block.
|
||||
func genValueTx(nbytes int) func(int, *BlockGen) {
|
||||
// We can reuse the data for all transactions.
|
||||
// During signing, the method tx.WithSignature(s, sig)
|
||||
// performs:
|
||||
// cpy := tx.inner.copy()
|
||||
// cpy.setSignatureValues(signer.ChainID(), v, r, s)
|
||||
// After this operation, the data can be reused by the caller.
|
||||
data := make([]byte, nbytes)
|
||||
return func(i int, gen *BlockGen) {
|
||||
toaddr := common.Address{}
|
||||
data := make([]byte, nbytes)
|
||||
gas, _ := IntrinsicGas(data, nil, false, false, false, false)
|
||||
signer := gen.Signer()
|
||||
gasPrice := big.NewInt(0)
|
||||
|
|
@ -210,15 +216,27 @@ func BenchmarkChainRead_full_10k(b *testing.B) {
|
|||
benchReadChain(b, true, 10000)
|
||||
}
|
||||
func BenchmarkChainRead_header_100k(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchReadChain(b, false, 100000)
|
||||
}
|
||||
func BenchmarkChainRead_full_100k(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchReadChain(b, true, 100000)
|
||||
}
|
||||
func BenchmarkChainRead_header_500k(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchReadChain(b, false, 500000)
|
||||
}
|
||||
func BenchmarkChainRead_full_500k(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchReadChain(b, true, 500000)
|
||||
}
|
||||
func BenchmarkChainWrite_header_10k(b *testing.B) {
|
||||
|
|
@ -234,9 +252,15 @@ func BenchmarkChainWrite_full_100k(b *testing.B) {
|
|||
benchWriteChain(b, true, 100000)
|
||||
}
|
||||
func BenchmarkChainWrite_header_500k(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchWriteChain(b, false, 500000)
|
||||
}
|
||||
func BenchmarkChainWrite_full_500k(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchWriteChain(b, true, 500000)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -649,11 +649,15 @@ func makeTestBlocks(nblock int, txsPerBlock int) []*types.Block {
|
|||
// makeTestReceipts creates fake receipts for the ancient write benchmark.
|
||||
func makeTestReceipts(n int, nPerBlock int) []types.Receipts {
|
||||
receipts := make([]*types.Receipt, nPerBlock)
|
||||
var logs []*types.Log
|
||||
for i := 0; i < 5; i++ {
|
||||
logs = append(logs, new(types.Log))
|
||||
}
|
||||
for i := 0; i < len(receipts); i++ {
|
||||
receipts[i] = &types.Receipt{
|
||||
Status: types.ReceiptStatusSuccessful,
|
||||
CumulativeGasUsed: 0x888888888,
|
||||
Logs: make([]*types.Log, 5),
|
||||
Logs: logs,
|
||||
}
|
||||
}
|
||||
allReceipts := make([]types.Receipts, n)
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ func (ae *AccessEvents) ValueTransferGas(callerAddr, targetAddr common.Address)
|
|||
return gas
|
||||
}
|
||||
|
||||
// ContractCreateCPreheck charges access costs before
|
||||
// ContractCreatePreCheckGas charges access costs before
|
||||
// a contract creation is initiated. It is just reads, because the
|
||||
// address collision is done before the transfer, and so no write
|
||||
// are guaranteed to happen at this point.
|
||||
|
|
|
|||
|
|
@ -1068,7 +1068,8 @@ func (s *StateDB) handleDestruction() (map[common.Hash]*accountDelete, []*trieno
|
|||
deletes[addrHash] = op
|
||||
|
||||
// Short circuit if the origin storage was empty.
|
||||
if prev.Root == types.EmptyRootHash {
|
||||
|
||||
if prev.Root == types.EmptyRootHash || s.db.TrieDB().IsVerkle() {
|
||||
continue
|
||||
}
|
||||
// Remove storage slots belonging to the account.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package core
|
|||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
|
@ -30,14 +29,11 @@ import (
|
|||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/ethereum/go-ethereum/triedb"
|
||||
"github.com/ethereum/go-verkle"
|
||||
"github.com/holiman/uint256"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
|
@ -426,193 +422,3 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
|
|||
}
|
||||
return types.NewBlock(header, body, receipts, trie.NewStackTrie(nil))
|
||||
}
|
||||
|
||||
var (
|
||||
code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`)
|
||||
intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, true, true, true, true)
|
||||
// A contract creation that calls EXTCODECOPY in the constructor. Used to ensure that the witness
|
||||
// will not contain that copied data.
|
||||
// Source: https://gist.github.com/gballet/a23db1e1cb4ed105616b5920feb75985
|
||||
codeWithExtCodeCopy = common.FromHex(`0x60806040526040516100109061017b565b604051809103906000f08015801561002c573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561007857600080fd5b5060008067ffffffffffffffff8111156100955761009461024a565b5b6040519080825280601f01601f1916602001820160405280156100c75781602001600182028036833780820191505090505b50905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506020600083833c81610101906101e3565b60405161010d90610187565b61011791906101a3565b604051809103906000f080158015610133573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061029b565b60d58061046783390190565b6102068061053c83390190565b61019d816101d9565b82525050565b60006020820190506101b86000830184610194565b92915050565b6000819050602082019050919050565b600081519050919050565b6000819050919050565b60006101ee826101ce565b826101f8846101be565b905061020381610279565b925060208210156102435761023e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261028e565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600061028582516101d9565b80915050919050565b600082821b905092915050565b6101bd806102aa6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f566852414610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381ca91d36040518163ffffffff1660e01b815260040160206040518083038186803b1580156100b857600080fd5b505afa1580156100cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f0919061010a565b905090565b60008151905061010481610170565b92915050565b6000602082840312156101205761011f61016b565b5b600061012e848285016100f5565b91505092915050565b61014081610161565b82525050565b600060208201905061015b6000830184610137565b92915050565b6000819050919050565b600080fd5b61017981610161565b811461018457600080fd5b5056fea2646970667358221220a6a0e11af79f176f9c421b7b12f441356b25f6489b83d38cc828a701720b41f164736f6c63430008070033608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ab5ed15014602d575b600080fd5b60336047565b604051603e9190605d565b60405180910390f35b60006001905090565b6057816076565b82525050565b6000602082019050607060008301846050565b92915050565b600081905091905056fea26469706673582212203a14eb0d5cd07c277d3e24912f110ddda3e553245a99afc4eeefb2fbae5327aa64736f6c63430008070033608060405234801561001057600080fd5b5060405161020638038061020683398181016040528101906100329190610063565b60018160001c6100429190610090565b60008190555050610145565b60008151905061005d8161012e565b92915050565b60006020828403121561007957610078610129565b5b60006100878482850161004e565b91505092915050565b600061009b826100f0565b91506100a6836100f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156100db576100da6100fa565b5b828201905092915050565b6000819050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610137816100e6565b811461014257600080fd5b50565b60b3806101536000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806381ca91d314602d575b600080fd5b60336047565b604051603e9190605a565b60405180910390f35b60005481565b6054816073565b82525050565b6000602082019050606d6000830184604d565b92915050565b600081905091905056fea26469706673582212209bff7098a2f526de1ad499866f27d6d0d6f17b74a413036d6063ca6a0998ca4264736f6c63430008070033`)
|
||||
intrinsicCodeWithExtCodeCopyGas, _ = IntrinsicGas(codeWithExtCodeCopy, nil, true, true, true, true)
|
||||
)
|
||||
|
||||
func TestProcessVerkle(t *testing.T) {
|
||||
var (
|
||||
config = ¶ms.ChainConfig{
|
||||
ChainID: big.NewInt(1),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
IstanbulBlock: big.NewInt(0),
|
||||
MuirGlacierBlock: big.NewInt(0),
|
||||
BerlinBlock: big.NewInt(0),
|
||||
LondonBlock: big.NewInt(0),
|
||||
Ethash: new(params.EthashConfig),
|
||||
ShanghaiTime: u64(0),
|
||||
VerkleTime: u64(0),
|
||||
TerminalTotalDifficulty: common.Big0,
|
||||
}
|
||||
signer = types.LatestSigner(config)
|
||||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain
|
||||
coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7")
|
||||
gspec = &Genesis{
|
||||
Config: config,
|
||||
Alloc: GenesisAlloc{
|
||||
coinbase: GenesisAccount{
|
||||
Balance: big.NewInt(1000000000000000000), // 1 ether
|
||||
Nonce: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
// Verkle trees use the snapshot, which must be enabled before the
|
||||
// data is saved into the tree+database.
|
||||
// genesis := gspec.MustCommit(bcdb, triedb)
|
||||
cacheConfig := DefaultCacheConfigWithScheme("path")
|
||||
cacheConfig.SnapshotLimit = 0
|
||||
blockchain, _ := NewBlockChain(bcdb, cacheConfig, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil)
|
||||
defer blockchain.Stop()
|
||||
|
||||
txCost1 := params.TxGas
|
||||
txCost2 := params.TxGas
|
||||
contractCreationCost := intrinsicContractCreationGas +
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* creation with value */
|
||||
739 /* execution costs */
|
||||
codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas +
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (tx) */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at pc=0x20) */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */
|
||||
params.WitnessChunkReadCost + /* SLOAD in constructor */
|
||||
params.WitnessChunkWriteCost + /* SSTORE in constructor */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at PC=0x121) */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */
|
||||
params.WitnessChunkReadCost + /* SLOAD in constructor */
|
||||
params.WitnessChunkWriteCost + /* SSTORE in constructor */
|
||||
params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash for tx creation */
|
||||
15*(params.WitnessChunkReadCost+params.WitnessChunkWriteCost) + /* code chunks #0..#14 */
|
||||
4844 /* execution costs */
|
||||
blockGasUsagesExpected := []uint64{
|
||||
txCost1*2 + txCost2,
|
||||
txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas,
|
||||
}
|
||||
_, chain, _, proofs, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) {
|
||||
gen.SetPoS()
|
||||
|
||||
// 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)
|
||||
tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+1, common.Address{}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey)
|
||||
gen.AddTx(tx)
|
||||
tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+2, common.Address{}, big.NewInt(0), txCost2, big.NewInt(875000000), nil), signer, testKey)
|
||||
gen.AddTx(tx)
|
||||
|
||||
// Add two contract creations in block #2
|
||||
if i == 1 {
|
||||
tx, _ = types.SignTx(types.NewContractCreation(6, big.NewInt(16), 3000000, big.NewInt(875000000), code), signer, testKey)
|
||||
gen.AddTx(tx)
|
||||
|
||||
tx, _ = types.SignTx(types.NewContractCreation(7, big.NewInt(0), 3000000, big.NewInt(875000000), codeWithExtCodeCopy), signer, testKey)
|
||||
gen.AddTx(tx)
|
||||
}
|
||||
})
|
||||
|
||||
// Check proof for both blocks
|
||||
err := verkle.Verify(proofs[0], gspec.ToBlock().Root().Bytes(), chain[0].Root().Bytes(), statediffs[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = verkle.Verify(proofs[1], chain[0].Root().Bytes(), chain[1].Root().Bytes(), statediffs[1])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Log("verified verkle proof, inserting blocks into the chain")
|
||||
|
||||
endnum, err := blockchain.InsertChain(chain)
|
||||
if err != nil {
|
||||
t.Fatalf("block %d imported with error: %v", endnum, err)
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
b := blockchain.GetBlockByNumber(uint64(i) + 1)
|
||||
if b == nil {
|
||||
t.Fatalf("expected block %d to be present in chain", i+1)
|
||||
}
|
||||
if b.Hash() != chain[i].Hash() {
|
||||
t.Fatalf("block #%d not found at expected height", b.NumberU64())
|
||||
}
|
||||
if b.GasUsed() != blockGasUsagesExpected[i] {
|
||||
t.Fatalf("expected block #%d txs to use %d, got %d\n", b.NumberU64(), blockGasUsagesExpected[i], b.GasUsed())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessParentBlockHash(t *testing.T) {
|
||||
var (
|
||||
chainConfig = params.MergedTestChainConfig
|
||||
hashA = common.Hash{0x01}
|
||||
hashB = common.Hash{0x02}
|
||||
header = &types.Header{ParentHash: hashA, Number: big.NewInt(2), Difficulty: big.NewInt(0)}
|
||||
parent = &types.Header{ParentHash: hashB, Number: big.NewInt(1), Difficulty: big.NewInt(0)}
|
||||
coinbase = common.Address{}
|
||||
)
|
||||
test := func(statedb *state.StateDB) {
|
||||
statedb.SetNonce(params.HistoryStorageAddress, 1)
|
||||
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode)
|
||||
statedb.IntermediateRoot(true)
|
||||
|
||||
vmContext := NewEVMBlockContext(header, nil, &coinbase)
|
||||
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{})
|
||||
ProcessParentBlockHash(header.ParentHash, evm, statedb)
|
||||
|
||||
vmContext = NewEVMBlockContext(parent, nil, &coinbase)
|
||||
evm = vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{})
|
||||
ProcessParentBlockHash(parent.ParentHash, evm, statedb)
|
||||
|
||||
// make sure that the state is correct
|
||||
if have := getParentBlockHash(statedb, 1); have != hashA {
|
||||
t.Errorf("want parent hash %v, have %v", hashA, have)
|
||||
}
|
||||
if have := getParentBlockHash(statedb, 0); have != hashB {
|
||||
t.Errorf("want parent hash %v, have %v", hashB, have)
|
||||
}
|
||||
}
|
||||
t.Run("MPT", func(t *testing.T) {
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
test(statedb)
|
||||
})
|
||||
t.Run("Verkle", func(t *testing.T) {
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme)
|
||||
cacheConfig.SnapshotLimit = 0
|
||||
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true))
|
||||
statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil))
|
||||
test(statedb)
|
||||
})
|
||||
}
|
||||
|
||||
func getParentBlockHash(statedb *state.StateDB, number uint64) common.Hash {
|
||||
ringIndex := number % params.HistoryServeWindow
|
||||
var key common.Hash
|
||||
binary.BigEndian.PutUint64(key[24:], ringIndex)
|
||||
return statedb.GetState(params.HistoryStorageAddress, key)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,6 +318,10 @@ type BlobPool struct {
|
|||
discoverFeed event.Feed // Event feed to send out new tx events on pool discovery (reorg excluded)
|
||||
insertFeed event.Feed // Event feed to send out new tx events on pool inclusion (reorg included)
|
||||
|
||||
// txValidationFn defaults to txpool.ValidateTransaction, but can be
|
||||
// overridden for testing purposes.
|
||||
txValidationFn txpool.ValidationFunction
|
||||
|
||||
lock sync.RWMutex // Mutex protecting the pool during reorg handling
|
||||
}
|
||||
|
||||
|
|
@ -329,12 +333,13 @@ func New(config Config, chain BlockChain) *BlobPool {
|
|||
|
||||
// Create the transaction pool with its initial settings
|
||||
return &BlobPool{
|
||||
config: config,
|
||||
signer: types.LatestSigner(chain.Config()),
|
||||
chain: chain,
|
||||
lookup: newLookup(),
|
||||
index: make(map[common.Address][]*blobTxMeta),
|
||||
spent: make(map[common.Address]*uint256.Int),
|
||||
config: config,
|
||||
signer: types.LatestSigner(chain.Config()),
|
||||
chain: chain,
|
||||
lookup: newLookup(),
|
||||
index: make(map[common.Address][]*blobTxMeta),
|
||||
spent: make(map[common.Address]*uint256.Int),
|
||||
txValidationFn: txpool.ValidateTransaction,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1090,7 +1095,8 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error {
|
|||
MaxSize: txMaxSize,
|
||||
MinTip: p.gasTip.ToBig(),
|
||||
}
|
||||
if err := txpool.ValidateTransaction(tx, p.head, p.signer, baseOpts); err != nil {
|
||||
|
||||
if err := p.txValidationFn(tx, p.head, p.signer, baseOpts); err != nil {
|
||||
return err
|
||||
}
|
||||
// Ensure the transaction adheres to the stateful pool filters (nonce, balance)
|
||||
|
|
|
|||
|
|
@ -1449,11 +1449,29 @@ func TestAdd(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// fakeBilly is a billy.Database implementation which just drops data on the floor.
|
||||
type fakeBilly struct {
|
||||
billy.Database
|
||||
count uint64
|
||||
}
|
||||
|
||||
func (f *fakeBilly) Put(data []byte) (uint64, error) {
|
||||
f.count++
|
||||
return f.count, nil
|
||||
}
|
||||
|
||||
var _ billy.Database = (*fakeBilly)(nil)
|
||||
|
||||
// Benchmarks the time it takes to assemble the lazy pending transaction list
|
||||
// from the pool contents.
|
||||
func BenchmarkPoolPending100Mb(b *testing.B) { benchmarkPoolPending(b, 100_000_000) }
|
||||
func BenchmarkPoolPending1GB(b *testing.B) { benchmarkPoolPending(b, 1_000_000_000) }
|
||||
func BenchmarkPoolPending10GB(b *testing.B) { benchmarkPoolPending(b, 10_000_000_000) }
|
||||
func BenchmarkPoolPending10GB(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchmarkPoolPending(b, 10_000_000_000)
|
||||
}
|
||||
|
||||
func benchmarkPoolPending(b *testing.B, datacap uint64) {
|
||||
// Calculate the maximum number of transaction that would fit into the pool
|
||||
|
|
@ -1477,6 +1495,15 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) {
|
|||
if err := pool.Init(1, chain.CurrentBlock(), makeAddressReserver()); err != nil {
|
||||
b.Fatalf("failed to create blob pool: %v", err)
|
||||
}
|
||||
// Make the pool not use disk (just drop everything). This test never reads
|
||||
// back the data, it just iterates over the pool in-memory items
|
||||
pool.store = &fakeBilly{pool.store, 0}
|
||||
// Avoid validation - verifying all blob proofs take significant time
|
||||
// when the capacity is large. The purpose of this bench is to measure assembling
|
||||
// the lazies, not the kzg verifications.
|
||||
pool.txValidationFn = func(tx *types.Transaction, head *types.Header, signer types.Signer, opts *txpool.ValidationOptions) error {
|
||||
return nil // accept all
|
||||
}
|
||||
// Fill the pool up with one random transaction from each account with the
|
||||
// same price and everything to maximize the worst case scenario
|
||||
for i := 0; i < int(capacity); i++ {
|
||||
|
|
|
|||
|
|
@ -239,9 +239,25 @@ func BenchmarkPriceHeapOverflow10MB(b *testing.B) { benchmarkPriceHeapOverflow(
|
|||
func BenchmarkPriceHeapOverflow100MB(b *testing.B) { benchmarkPriceHeapOverflow(b, 100*1024*1024) }
|
||||
func BenchmarkPriceHeapOverflow1GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 1024*1024*1024) }
|
||||
func BenchmarkPriceHeapOverflow10GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 10*1024*1024*1024) }
|
||||
func BenchmarkPriceHeapOverflow25GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 25*1024*1024*1024) }
|
||||
func BenchmarkPriceHeapOverflow50GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 50*1024*1024*1024) }
|
||||
func BenchmarkPriceHeapOverflow100GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 100*1024*1024*1024) }
|
||||
|
||||
func BenchmarkPriceHeapOverflow25GB(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchmarkPriceHeapOverflow(b, 25*1024*1024*1024)
|
||||
}
|
||||
func BenchmarkPriceHeapOverflow50GB(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchmarkPriceHeapOverflow(b, 50*1024*1024*1024)
|
||||
}
|
||||
func BenchmarkPriceHeapOverflow100GB(b *testing.B) {
|
||||
if testing.Short() {
|
||||
b.Skip("Skipping in short-mode")
|
||||
}
|
||||
benchmarkPriceHeapOverflow(b, 100*1024*1024*1024)
|
||||
}
|
||||
|
||||
func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) {
|
||||
// Calculate how many unique transactions we can fit into the provided disk
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ func (p *TxPool) Add(txs []*types.Transaction, local bool, sync bool) []error {
|
|||
for i, split := range splits {
|
||||
// If the transaction was rejected by all subpools, mark it unsupported
|
||||
if split == -1 {
|
||||
errs[i] = core.ErrTxTypeNotSupported
|
||||
errs[i] = fmt.Errorf("%w: received type %d", core.ErrTxTypeNotSupported, txs[i].Type())
|
||||
continue
|
||||
}
|
||||
// Find which subpool handled it and pull in the corresponding error
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@ type ValidationOptions struct {
|
|||
MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool
|
||||
}
|
||||
|
||||
// ValidationFunction is an method type which the pools use to perform the tx-validations which do not
|
||||
// require state access. Production code typically uses ValidateTransaction, whereas testing-code
|
||||
// might choose to instead use something else, e.g. to always fail or avoid heavy cpu usage.
|
||||
type ValidationFunction func(tx *types.Transaction, head *types.Header, signer types.Signer, opts *ValidationOptions) error
|
||||
|
||||
// ValidateTransaction is a helper method to check whether a transaction is valid
|
||||
// according to the consensus rules, but does not check state-dependent validation
|
||||
// (balance, nonce, etc).
|
||||
|
|
@ -99,7 +104,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
|||
}
|
||||
// Make sure the transaction is signed properly
|
||||
if _, err := types.Sender(signer, tx); err != nil {
|
||||
return ErrInvalidSender
|
||||
return fmt.Errorf("%w: %v", ErrInvalidSender, err)
|
||||
}
|
||||
// Ensure the transaction has more gas than the bare minimum needed to cover
|
||||
// the transaction metadata
|
||||
|
|
|
|||
1087
core/verkle_witness_test.go
Normal file
1087
core/verkle_witness_test.go
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -142,13 +142,16 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
|||
// set the receiver's (the executing contract) code for execution.
|
||||
cfg.State.SetCode(address, code)
|
||||
// Call the code with the given configuration.
|
||||
ret, _, err := vmenv.Call(
|
||||
ret, leftOverGas, err := vmenv.Call(
|
||||
sender,
|
||||
common.BytesToAddress([]byte("contract")),
|
||||
input,
|
||||
cfg.GasLimit,
|
||||
uint256.MustFromBig(cfg.Value),
|
||||
)
|
||||
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
|
||||
cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)
|
||||
}
|
||||
return ret, cfg.State, err
|
||||
}
|
||||
|
||||
|
|
@ -181,6 +184,9 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
|||
cfg.GasLimit,
|
||||
uint256.MustFromBig(cfg.Value),
|
||||
)
|
||||
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
|
||||
cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)
|
||||
}
|
||||
return code, address, leftOverGas, err
|
||||
}
|
||||
|
||||
|
|
@ -214,5 +220,8 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
|
|||
cfg.GasLimit,
|
||||
uint256.MustFromBig(cfg.Value),
|
||||
)
|
||||
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
|
||||
cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)
|
||||
}
|
||||
return ret, leftOverGas, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,6 @@ func TestEth2PrepareAndGetPayload(t *testing.T) {
|
|||
t.Fatalf("error preparing payload, err=%v", err)
|
||||
}
|
||||
// give the payload some time to be built
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
payloadID := (&miner.BuildPayloadArgs{
|
||||
Parent: fcState.HeadBlockHash,
|
||||
Timestamp: blockParams.Timestamp,
|
||||
|
|
@ -217,12 +216,12 @@ func TestEth2PrepareAndGetPayload(t *testing.T) {
|
|||
BeaconRoot: blockParams.BeaconRoot,
|
||||
Version: engine.PayloadV1,
|
||||
}).Id()
|
||||
execData, err := api.GetPayloadV1(payloadID)
|
||||
execData, err := api.getPayload(payloadID, true)
|
||||
if err != nil {
|
||||
t.Fatalf("error getting payload, err=%v", err)
|
||||
}
|
||||
if len(execData.Transactions) != blocks[9].Transactions().Len() {
|
||||
t.Fatalf("invalid number of transactions %d != 1", len(execData.Transactions))
|
||||
if len(execData.ExecutionPayload.Transactions) != blocks[9].Transactions().Len() {
|
||||
t.Fatalf("invalid number of transactions %d != 1", len(execData.ExecutionPayload.Transactions))
|
||||
}
|
||||
// Test invalid payloadID
|
||||
var invPayload engine.PayloadID
|
||||
|
|
@ -453,7 +452,6 @@ func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block)
|
|||
}
|
||||
|
||||
mcfg := miner.DefaultConfig
|
||||
mcfg.PendingFeeRecipient = testAddr
|
||||
ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: mcfg}
|
||||
ethservice, err := eth.New(n, ethcfg)
|
||||
if err != nil {
|
||||
|
|
@ -628,7 +626,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
|
|||
SafeBlockHash: common.Hash{},
|
||||
FinalizedBlockHash: common.Hash{},
|
||||
}
|
||||
payload *engine.ExecutableData
|
||||
payload *engine.ExecutionPayloadEnvelope
|
||||
resp engine.ForkChoiceResponse
|
||||
err error
|
||||
)
|
||||
|
|
@ -640,11 +638,10 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
|
|||
t.Fatalf("error preparing payload, invalid status: %v", resp.PayloadStatus.Status)
|
||||
}
|
||||
// give the payload some time to be built
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
if payload, err = api.GetPayloadV1(*resp.PayloadID); err != nil {
|
||||
if payload, err = api.getPayload(*resp.PayloadID, true); err != nil {
|
||||
t.Fatalf("can't get payload: %v", err)
|
||||
}
|
||||
if len(payload.Transactions) > 0 {
|
||||
if len(payload.ExecutionPayload.Transactions) > 0 {
|
||||
break
|
||||
}
|
||||
// No luck this time we need to update the params and try again.
|
||||
|
|
@ -653,7 +650,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
|
|||
t.Fatalf("payload should not be empty")
|
||||
}
|
||||
}
|
||||
execResp, err := api.NewPayloadV1(*payload)
|
||||
execResp, err := api.NewPayloadV1(*payload.ExecutionPayload)
|
||||
if err != nil {
|
||||
t.Fatalf("can't execute payload: %v", err)
|
||||
}
|
||||
|
|
@ -661,14 +658,14 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
|
|||
t.Fatalf("invalid status: %v", execResp.Status)
|
||||
}
|
||||
fcState = engine.ForkchoiceStateV1{
|
||||
HeadBlockHash: payload.BlockHash,
|
||||
SafeBlockHash: payload.ParentHash,
|
||||
FinalizedBlockHash: payload.ParentHash,
|
||||
HeadBlockHash: payload.ExecutionPayload.BlockHash,
|
||||
SafeBlockHash: payload.ExecutionPayload.ParentHash,
|
||||
FinalizedBlockHash: payload.ExecutionPayload.ParentHash,
|
||||
}
|
||||
if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
|
||||
t.Fatalf("Failed to insert block: %v", err)
|
||||
}
|
||||
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.Number {
|
||||
if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.ExecutionPayload.Number {
|
||||
t.Fatalf("Chain head should be updated")
|
||||
}
|
||||
parent = ethservice.BlockChain().CurrentBlock()
|
||||
|
|
@ -1736,9 +1733,6 @@ func TestWitnessCreationAndConsumption(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("error preparing payload, err=%v", err)
|
||||
}
|
||||
// Give the payload some time to be built
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
payloadID := (&miner.BuildPayloadArgs{
|
||||
Parent: fcState.HeadBlockHash,
|
||||
Timestamp: blockParams.Timestamp,
|
||||
|
|
@ -1748,7 +1742,7 @@ func TestWitnessCreationAndConsumption(t *testing.T) {
|
|||
BeaconRoot: blockParams.BeaconRoot,
|
||||
Version: engine.PayloadV3,
|
||||
}).Id()
|
||||
envelope, err := api.GetPayloadV3(payloadID)
|
||||
envelope, err := api.getPayload(payloadID, true)
|
||||
if err != nil {
|
||||
t.Fatalf("error getting payload, err=%v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/eth/tracers"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/tests"
|
||||
)
|
||||
|
||||
|
|
@ -202,7 +201,7 @@ func BenchmarkTracers(b *testing.B) {
|
|||
func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
|
||||
// Configure a blockchain with the given prestate
|
||||
tx := new(types.Transaction)
|
||||
if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil {
|
||||
if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil {
|
||||
b.Fatalf("failed to parse testcase input: %v", err)
|
||||
}
|
||||
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
|
||||
|
|
@ -211,15 +210,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
|
|||
Origin: origin,
|
||||
GasPrice: tx.GasPrice(),
|
||||
}
|
||||
context := vm.BlockContext{
|
||||
CanTransfer: core.CanTransfer,
|
||||
Transfer: core.Transfer,
|
||||
Coinbase: test.Context.Miner,
|
||||
BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
|
||||
Time: uint64(test.Context.Time),
|
||||
Difficulty: (*big.Int)(test.Context.Difficulty),
|
||||
GasLimit: uint64(test.Context.GasLimit),
|
||||
}
|
||||
context := test.Context.toBlockContext(test.Genesis)
|
||||
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||
|
|
|
|||
|
|
@ -99,11 +99,13 @@ func BenchmarkTransactionTrace(b *testing.B) {
|
|||
|
||||
for i := 0; i < b.N; i++ {
|
||||
snap := state.StateDB.Snapshot()
|
||||
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||
_, err = st.TransitionDb()
|
||||
res, err := st.TransitionDb()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
tracer.OnTxEnd(&types.Receipt{GasUsed: res.UsedGas}, nil)
|
||||
state.StateDB.RevertToSnapshot(snap)
|
||||
if have, want := len(tracer.StructLogs()), 244752; have != want {
|
||||
b.Fatalf("trace wrong, want %d steps, have %d", want, have)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import (
|
|||
"io"
|
||||
"log/slog"
|
||||
"math/big"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -70,7 +69,7 @@ func TestJSONHandler(t *testing.T) {
|
|||
}
|
||||
|
||||
func BenchmarkTraceLogging(b *testing.B) {
|
||||
SetDefault(NewLogger(NewTerminalHandler(os.Stderr, true)))
|
||||
SetDefault(NewLogger(NewTerminalHandler(io.Discard, true)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Trace("a message", "v", i)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package metrics
|
|||
import (
|
||||
"math"
|
||||
"math/rand"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -27,6 +26,7 @@ func BenchmarkCompute1000(b *testing.B) {
|
|||
SampleVariance(mean, s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCompute1000000(b *testing.B) {
|
||||
s := make([]int64, 1000000)
|
||||
var sum int64
|
||||
|
|
@ -40,28 +40,6 @@ func BenchmarkCompute1000000(b *testing.B) {
|
|||
SampleVariance(mean, s)
|
||||
}
|
||||
}
|
||||
func BenchmarkCopy1000(b *testing.B) {
|
||||
s := make([]int64, 1000)
|
||||
for i := 0; i < len(s); i++ {
|
||||
s[i] = int64(i)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sCopy := make([]int64, len(s))
|
||||
copy(sCopy, s)
|
||||
}
|
||||
}
|
||||
func BenchmarkCopy1000000(b *testing.B) {
|
||||
s := make([]int64, 1000000)
|
||||
for i := 0; i < len(s); i++ {
|
||||
s[i] = int64(i)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sCopy := make([]int64, len(s))
|
||||
copy(sCopy, s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkExpDecaySample257(b *testing.B) {
|
||||
benchmarkSample(b, NewExpDecaySample(257, 0.015))
|
||||
|
|
@ -237,17 +215,9 @@ func TestUniformSampleStatistics(t *testing.T) {
|
|||
}
|
||||
|
||||
func benchmarkSample(b *testing.B, s Sample) {
|
||||
var memStats runtime.MemStats
|
||||
runtime.ReadMemStats(&memStats)
|
||||
pauseTotalNs := memStats.PauseTotalNs
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Update(1)
|
||||
}
|
||||
b.StopTimer()
|
||||
runtime.GC()
|
||||
runtime.ReadMemStats(&memStats)
|
||||
b.Logf("GC cost: %d ns/op", int(memStats.PauseTotalNs-pauseTotalNs)/b.N)
|
||||
}
|
||||
|
||||
func testExpDecaySampleStatistics(t *testing.T, s SampleSnapshot) {
|
||||
|
|
|
|||
|
|
@ -257,8 +257,12 @@ func fuzzCrossG1MultiExp(data []byte) int {
|
|||
cp.MultiExp(gnarkPoints, gnarkScalars, ecc.MultiExpConfig{})
|
||||
|
||||
// compare result
|
||||
if !(bytes.Equal(cp.Marshal(), g1.ToBytes(&kp))) {
|
||||
panic("G1 multi exponentiation mismatch gnark / geth ")
|
||||
gnarkRes := cp.Marshal()
|
||||
gethRes := g1.ToBytes(&kp)
|
||||
if !bytes.Equal(gnarkRes, gethRes) {
|
||||
msg := fmt.Sprintf("G1 multi exponentiation mismatch gnark/geth.\ngnark: %x\ngeth: %x\ninput: %x\n ",
|
||||
gnarkRes, gethRes, data)
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
return 1
|
||||
|
|
@ -283,15 +287,18 @@ func getG1Points(input io.Reader) (*bls12381.PointG1, *gnark.G1Affine, *blst.P1A
|
|||
if err != nil {
|
||||
panic(fmt.Sprintf("Could not marshal gnark.G1 -> geth.G1: %v", err))
|
||||
}
|
||||
if !bytes.Equal(g1.ToBytes(kp), cpBytes) {
|
||||
panic("bytes(gnark.G1) != bytes(geth.G1)")
|
||||
|
||||
gnarkRes := g1.ToBytes(kp)
|
||||
if !bytes.Equal(gnarkRes, cpBytes) {
|
||||
panic(fmt.Sprintf("bytes(gnark.G1) != bytes(geth.G1)\ngnark.G1: %x\ngeth.G1: %x\n", gnarkRes, cpBytes))
|
||||
}
|
||||
|
||||
// marshal gnark point -> blst point
|
||||
scalar := new(blst.Scalar).FromBEndian(common.LeftPadBytes(s.Bytes(), 32))
|
||||
p1 := new(blst.P1Affine).From(scalar)
|
||||
if !bytes.Equal(p1.Serialize(), cpBytes) {
|
||||
panic("bytes(blst.G1) != bytes(geth.G1)")
|
||||
blstRes := p1.Serialize()
|
||||
if !bytes.Equal(blstRes, cpBytes) {
|
||||
panic(fmt.Sprintf("bytes(blst.G1) != bytes(geth.G1)\nblst.G1: %x\ngeth.G1: %x\n", blstRes, cpBytes))
|
||||
}
|
||||
|
||||
return kp, cp, p1, nil
|
||||
|
|
@ -316,8 +323,10 @@ func getG2Points(input io.Reader) (*bls12381.PointG2, *gnark.G2Affine, *blst.P2A
|
|||
if err != nil {
|
||||
panic(fmt.Sprintf("Could not marshal gnark.G2 -> geth.G2: %v", err))
|
||||
}
|
||||
if !bytes.Equal(g2.ToBytes(kp), cpBytes) {
|
||||
panic("bytes(gnark.G2) != bytes(geth.G2)")
|
||||
|
||||
gnarkRes := g2.ToBytes(kp)
|
||||
if !bytes.Equal(gnarkRes, cpBytes) {
|
||||
panic(fmt.Sprintf("bytes(gnark.G2) != bytes(geth.G2)\ngnark.G2: %x\ngeth.G2: %x\n", gnarkRes, cpBytes))
|
||||
}
|
||||
|
||||
// marshal gnark point -> blst point
|
||||
|
|
|
|||
|
|
@ -204,10 +204,10 @@ func CodeChunkKey(address []byte, chunk *uint256.Int) []byte {
|
|||
return GetTreeKey(address, treeIndex, subIndex)
|
||||
}
|
||||
|
||||
func StorageIndex(bytes []byte) (*uint256.Int, byte) {
|
||||
func StorageIndex(storageKey []byte) (*uint256.Int, byte) {
|
||||
// If the storage slot is in the header, we need to add the header offset.
|
||||
var key uint256.Int
|
||||
key.SetBytes(bytes)
|
||||
key.SetBytes(storageKey)
|
||||
if key.Cmp(codeStorageDelta) < 0 {
|
||||
// This addition is always safe; it can't ever overflow since pos<codeStorageDelta.
|
||||
key.Add(headerStorageOffset, &key)
|
||||
|
|
@ -216,6 +216,18 @@ func StorageIndex(bytes []byte) (*uint256.Int, byte) {
|
|||
// and the sub-index is the LSB of the modified storage key.
|
||||
return zero, byte(key[0] & 0xFF)
|
||||
}
|
||||
// If the storage slot is in the main storage, we need to add the main storage offset.
|
||||
|
||||
// The first MAIN_STORAGE_OFFSET group will see its
|
||||
// first 64 slots unreachable. This is either a typo in the
|
||||
// spec or intended to conserve the 256-u256
|
||||
// aligment. If we decide to ever access these 64
|
||||
// slots, uncomment this.
|
||||
// // Get the new offset since we now know that we are above 64.
|
||||
// pos.Sub(&pos, codeStorageDelta)
|
||||
// suffix := byte(pos[0] & 0xFF)
|
||||
suffix := storageKey[len(storageKey)-1]
|
||||
|
||||
// We first divide by VerkleNodeWidth to create room to avoid an overflow next.
|
||||
key.Rsh(&key, uint(verkleNodeWidthLog2))
|
||||
|
||||
|
|
@ -224,7 +236,7 @@ func StorageIndex(bytes []byte) (*uint256.Int, byte) {
|
|||
|
||||
// The sub-index is the LSB of the original storage key, since mainStorageOffset
|
||||
// doesn't affect this byte, so we can avoid masks or shifts.
|
||||
return &key, byte(key[0] & 0xFF)
|
||||
return &key, suffix
|
||||
}
|
||||
|
||||
// StorageSlotKey returns the verkle tree key of the storage slot for the
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package trie
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -32,7 +33,6 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
zero [32]byte
|
||||
errInvalidRootType = errors.New("invalid node type for root")
|
||||
)
|
||||
|
||||
|
|
@ -170,25 +170,35 @@ func (t *VerkleTrie) UpdateStorage(address common.Address, key, value []byte) er
|
|||
return t.root.Insert(k, v[:], t.nodeResolver)
|
||||
}
|
||||
|
||||
// DeleteAccount implements state.Trie, deleting the specified account from the
|
||||
// trie. If the account was not existent in the trie, no error will be returned.
|
||||
// If the trie is corrupted, an error will be returned.
|
||||
// DeleteAccount leaves the account untouched, as no account deletion can happen
|
||||
// in verkle.
|
||||
// There is a special corner case, in which an account that is prefunded, CREATE2-d
|
||||
// and then SELFDESTRUCT-d should see its funds drained. EIP161 says that account
|
||||
// should be removed, but this is verboten by the verkle spec. This contains a
|
||||
// workaround in which the method checks for this corner case, and if so, overwrites
|
||||
// the balance with 0. This will be removed once the spec has been clarified.
|
||||
func (t *VerkleTrie) DeleteAccount(addr common.Address) error {
|
||||
var (
|
||||
err error
|
||||
values = make([][]byte, verkle.NodeWidth)
|
||||
)
|
||||
for i := 0; i < verkle.NodeWidth; i++ {
|
||||
values[i] = zero[:]
|
||||
k := utils.BasicDataKeyWithEvaluatedAddress(t.cache.Get(addr.Bytes()))
|
||||
values, err := t.root.(*verkle.InternalNode).GetValuesAtStem(k, t.nodeResolver)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting data at %x in delete: %w", k, err)
|
||||
}
|
||||
switch n := t.root.(type) {
|
||||
case *verkle.InternalNode:
|
||||
err = n.InsertValuesAtStem(t.cache.GetStem(addr.Bytes()), values, t.nodeResolver)
|
||||
if err != nil {
|
||||
return fmt.Errorf("DeleteAccount (%x) error: %v", addr, err)
|
||||
var prefunded bool
|
||||
for i, v := range values {
|
||||
switch i {
|
||||
case 0:
|
||||
prefunded = len(v) == 32
|
||||
case 1:
|
||||
prefunded = len(v) == 32 && bytes.Equal(v, types.EmptyCodeHash[:])
|
||||
default:
|
||||
prefunded = v == nil
|
||||
}
|
||||
default:
|
||||
return errInvalidRootType
|
||||
if !prefunded {
|
||||
break
|
||||
}
|
||||
}
|
||||
if prefunded {
|
||||
t.root.Insert(k, common.Hash{}.Bytes(), t.nodeResolver)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -302,21 +312,19 @@ func (t *VerkleTrie) IsVerkle() bool {
|
|||
// Proof builds and returns the verkle multiproof for keys, built against
|
||||
// the pre tree. The post tree is passed in order to add the post values
|
||||
// to that proof.
|
||||
func (t *VerkleTrie) Proof(posttrie *VerkleTrie, keys [][]byte, resolver verkle.NodeResolverFn) (*verkle.VerkleProof, verkle.StateDiff, error) {
|
||||
func (t *VerkleTrie) Proof(posttrie *VerkleTrie, keys [][]byte) (*verkle.VerkleProof, verkle.StateDiff, error) {
|
||||
var postroot verkle.VerkleNode
|
||||
if posttrie != nil {
|
||||
postroot = posttrie.root
|
||||
}
|
||||
proof, _, _, _, err := verkle.MakeVerkleMultiProof(t.root, postroot, keys, resolver)
|
||||
proof, _, _, _, err := verkle.MakeVerkleMultiProof(t.root, postroot, keys, t.FlatdbNodeResolver)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p, kvps, err := verkle.SerializeProof(proof)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return p, kvps, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ func benchmarkSearch(b *testing.B, depth int, total int) {
|
|||
nblob = common.CopyBytes(blob)
|
||||
}
|
||||
}
|
||||
return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), nil)
|
||||
return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil))
|
||||
}
|
||||
var layer layer
|
||||
layer = emptyLayer()
|
||||
|
|
@ -118,7 +118,7 @@ func BenchmarkPersist(b *testing.B) {
|
|||
)
|
||||
nodes[common.Hash{}][string(path)] = node
|
||||
}
|
||||
return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), nil)
|
||||
return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil))
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
b.StopTimer()
|
||||
|
|
@ -156,8 +156,7 @@ func BenchmarkJournal(b *testing.B) {
|
|||
)
|
||||
nodes[common.Hash{}][string(path)] = node
|
||||
}
|
||||
// TODO(rjl493456442) a non-nil state set is expected.
|
||||
return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), nil)
|
||||
return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), new(StateSetWithOrigin))
|
||||
}
|
||||
var layer layer
|
||||
layer = emptyLayer()
|
||||
|
|
|
|||
Loading…
Reference in a new issue