mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
cmd/evm/internal/t8ntool: support for verkle-at-genesis testnets
Co-authored-by: Ignacio Hagopian <jsign.uy@gmail.com>
This commit is contained in:
parent
bb038c64a5
commit
2196aa1158
11 changed files with 349 additions and 35 deletions
77
.github/workflows/stable-spec-tests.yml
vendored
Normal file
77
.github/workflows/stable-spec-tests.yml
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
name: Execution Spec Tests - Consume (stable)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
branches: [master, kaustinen-with-shapella]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FIXTURES_TAG: "verkle@v0.0.9-alpha-1"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
setup:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout go-ethereum
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12.4"
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: 1.22.4
|
||||||
|
|
||||||
|
- name: Build geth evm
|
||||||
|
run: |
|
||||||
|
go build -v ./cmd/evm
|
||||||
|
mkdir -p ${{ github.workspace }}/bin
|
||||||
|
mv evm ${{ github.workspace }}/bin/evm
|
||||||
|
chmod +x ${{ github.workspace }}/bin/evm
|
||||||
|
|
||||||
|
- name: Archive built evm
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: evm
|
||||||
|
path: ${{ github.workspace }}/bin/evm
|
||||||
|
|
||||||
|
consume:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: setup
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
filename:
|
||||||
|
[
|
||||||
|
fixtures_verkle-genesis.tar.gz,
|
||||||
|
]
|
||||||
|
steps:
|
||||||
|
- name: Download geth evm
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: evm
|
||||||
|
path: ./bin
|
||||||
|
|
||||||
|
- name: Make evm binary executable and add to PATH
|
||||||
|
run: |
|
||||||
|
chmod +x ./bin/evm
|
||||||
|
echo "${{ github.workspace }}/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
- name: Download fixtures
|
||||||
|
uses: robinraju/release-downloader@v1
|
||||||
|
with:
|
||||||
|
repository: "ethereum/execution-spec-tests"
|
||||||
|
tag: "${{ env.FIXTURES_TAG }}"
|
||||||
|
fileName: "${{ matrix.filename }}"
|
||||||
|
extract: true
|
||||||
|
- name: Clone execution-spec-tests and consume tests
|
||||||
|
run: |
|
||||||
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||||
|
git clone https://github.com/ethereum/execution-spec-tests -b ${{ env.FIXTURES_TAG }} --depth 1
|
||||||
|
cd execution-spec-tests
|
||||||
|
uv run consume direct --evm-bin="${{ github.workspace }}/bin/evm" --input=../fixtures -n auto
|
||||||
|
shell: bash
|
||||||
|
|
@ -89,7 +89,7 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result := &testResult{Name: name, Pass: true}
|
result := &testResult{Name: name, Pass: true}
|
||||||
if err := tests[name].Run(false, rawdb.HashScheme, ctx.Bool(WitnessCrossCheckFlag.Name), tracer, func(res error, chain *core.BlockChain) {
|
if err := tests[name].Run(false, rawdb.PathScheme, ctx.Bool(WitnessCrossCheckFlag.Name), tracer, func(res error, chain *core.BlockChain) {
|
||||||
if ctx.Bool(DumpFlag.Name) {
|
if ctx.Bool(DumpFlag.Name) {
|
||||||
if s, _ := chain.State(); s != nil {
|
if s, _ := chain.State(); s != nil {
|
||||||
result.State = dump(s)
|
result.State = dump(s)
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/ethereum/go-ethereum/triedb"
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
|
"github.com/ethereum/go-verkle"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
@ -46,6 +47,7 @@ import (
|
||||||
type Prestate struct {
|
type Prestate struct {
|
||||||
Env stEnv `json:"env"`
|
Env stEnv `json:"env"`
|
||||||
Pre types.GenesisAlloc `json:"pre"`
|
Pre types.GenesisAlloc `json:"pre"`
|
||||||
|
VKT map[common.Hash]hexutil.Bytes `json:"vkt,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate go run github.com/fjl/gencodec -type ExecutionResult -field-override executionResultMarshaling -out gen_execresult.go
|
//go:generate go run github.com/fjl/gencodec -type ExecutionResult -field-override executionResultMarshaling -out gen_execresult.go
|
||||||
|
|
@ -68,6 +70,11 @@ type ExecutionResult struct {
|
||||||
CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"`
|
CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"`
|
||||||
RequestsHash *common.Hash `json:"requestsHash,omitempty"`
|
RequestsHash *common.Hash `json:"requestsHash,omitempty"`
|
||||||
Requests [][]byte `json:"requests"`
|
Requests [][]byte `json:"requests"`
|
||||||
|
|
||||||
|
// Verkle witness
|
||||||
|
VerkleProof *verkle.VerkleProof `json:"verkleProof,omitempty"`
|
||||||
|
StateDiff verkle.StateDiff `json:"stateDiff,omitempty"`
|
||||||
|
ParentRoot common.Hash `json:"parentStateRoot,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type executionResultMarshaling struct {
|
type executionResultMarshaling struct {
|
||||||
|
|
@ -101,6 +108,7 @@ type stEnv struct {
|
||||||
ParentExcessBlobGas *uint64 `json:"parentExcessBlobGas,omitempty"`
|
ParentExcessBlobGas *uint64 `json:"parentExcessBlobGas,omitempty"`
|
||||||
ParentBlobGasUsed *uint64 `json:"parentBlobGasUsed,omitempty"`
|
ParentBlobGasUsed *uint64 `json:"parentBlobGasUsed,omitempty"`
|
||||||
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||||
|
ParentHash *common.Hash `json:"parentHash,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type stEnvMarshaling struct {
|
type stEnvMarshaling struct {
|
||||||
|
|
@ -143,7 +151,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre)
|
parentStateRoot, statedb = MakePreState(rawdb.NewMemoryDatabase(), chainConfig, pre, chainConfig.IsVerkle(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp))
|
||||||
signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp)
|
signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp)
|
||||||
gaspool = new(core.GasPool)
|
gaspool = new(core.GasPool)
|
||||||
blockHash = common.Hash{0x13, 0x37}
|
blockHash = common.Hash{0x13, 0x37}
|
||||||
|
|
@ -153,6 +161,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
blobGasUsed = uint64(0)
|
blobGasUsed = uint64(0)
|
||||||
receipts = make(types.Receipts, 0)
|
receipts = make(types.Receipts, 0)
|
||||||
txIndex = 0
|
txIndex = 0
|
||||||
|
vtrpre *trie.VerkleTrie
|
||||||
)
|
)
|
||||||
gaspool.AddGas(pre.Env.GasLimit)
|
gaspool.AddGas(pre.Env.GasLimit)
|
||||||
vmContext := vm.BlockContext{
|
vmContext := vm.BlockContext{
|
||||||
|
|
@ -165,6 +174,14 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
GasLimit: pre.Env.GasLimit,
|
GasLimit: pre.Env.GasLimit,
|
||||||
GetHash: getHash,
|
GetHash: getHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We save the current state of the Verkle Tree before applying the transactions.
|
||||||
|
// Note that if the Verkle fork isn't active, this will be a noop.
|
||||||
|
switch tr := statedb.GetTrie().(type) {
|
||||||
|
case *trie.VerkleTrie:
|
||||||
|
vtrpre = tr.Copy()
|
||||||
|
}
|
||||||
|
|
||||||
// If currentBaseFee is defined, add it to the vmContext.
|
// If currentBaseFee is defined, add it to the vmContext.
|
||||||
if pre.Env.BaseFee != nil {
|
if pre.Env.BaseFee != nil {
|
||||||
vmContext.BaseFee = new(big.Int).Set(pre.Env.BaseFee)
|
vmContext.BaseFee = new(big.Int).Set(pre.Env.BaseFee)
|
||||||
|
|
@ -251,6 +268,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statedb.SetTxContext(tx.Hash(), txIndex)
|
statedb.SetTxContext(tx.Hash(), txIndex)
|
||||||
|
evm.AccessEvents = state.NewAccessEvents(evm.StateDB.PointCache())
|
||||||
var (
|
var (
|
||||||
snapshot = statedb.Snapshot()
|
snapshot = statedb.Snapshot()
|
||||||
prevGas = gaspool.Gas()
|
prevGas = gaspool.Gas()
|
||||||
|
|
@ -315,7 +333,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
evm.Config.Tracer.OnTxEnd(receipt, nil)
|
evm.Config.Tracer.OnTxEnd(receipt, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
statedb.AccessEvents().Merge(evm.AccessEvents)
|
||||||
txIndex++
|
txIndex++
|
||||||
}
|
}
|
||||||
statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber))
|
statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber))
|
||||||
|
|
@ -348,6 +366,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
// Amount is in gwei, turn into wei
|
// Amount is in gwei, turn into wei
|
||||||
amount := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), big.NewInt(params.GWei))
|
amount := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), big.NewInt(params.GWei))
|
||||||
statedb.AddBalance(w.Address, uint256.MustFromBig(amount), tracing.BalanceIncreaseWithdrawal)
|
statedb.AddBalance(w.Address, uint256.MustFromBig(amount), tracing.BalanceIncreaseWithdrawal)
|
||||||
|
|
||||||
|
statedb.AccessEvents().AddAccount(w.Address, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather the execution-layer triggered requests.
|
// Gather the execution-layer triggered requests.
|
||||||
|
|
@ -373,6 +393,25 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err))
|
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err))
|
||||||
}
|
}
|
||||||
|
// Add the witness to the execution result
|
||||||
|
var vktProof *verkle.VerkleProof
|
||||||
|
var vktStateDiff verkle.StateDiff
|
||||||
|
if chainConfig.IsVerkle(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp) {
|
||||||
|
keys := statedb.AccessEvents().Keys()
|
||||||
|
if len(keys) > 0 && vtrpre != nil {
|
||||||
|
var proofTrie *trie.VerkleTrie
|
||||||
|
switch tr := statedb.GetTrie().(type) {
|
||||||
|
case *trie.VerkleTrie:
|
||||||
|
proofTrie = tr
|
||||||
|
default:
|
||||||
|
return nil, nil, nil, fmt.Errorf("invalid tree type in proof generation: %v", tr)
|
||||||
|
}
|
||||||
|
vktProof, vktStateDiff, err = vtrpre.Proof(proofTrie, keys)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, fmt.Errorf("error generating verkle proof for block %d: %w", pre.Env.Number, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
execRs := &ExecutionResult{
|
execRs := &ExecutionResult{
|
||||||
StateRoot: root,
|
StateRoot: root,
|
||||||
TxRoot: types.DeriveSha(includedTxs, trie.NewStackTrie(nil)),
|
TxRoot: types.DeriveSha(includedTxs, trie.NewStackTrie(nil)),
|
||||||
|
|
@ -384,6 +423,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
Difficulty: (*math.HexOrDecimal256)(vmContext.Difficulty),
|
Difficulty: (*math.HexOrDecimal256)(vmContext.Difficulty),
|
||||||
GasUsed: (math.HexOrDecimal64)(gasUsed),
|
GasUsed: (math.HexOrDecimal64)(gasUsed),
|
||||||
BaseFee: (*math.HexOrDecimal256)(vmContext.BaseFee),
|
BaseFee: (*math.HexOrDecimal256)(vmContext.BaseFee),
|
||||||
|
VerkleProof: vktProof,
|
||||||
|
StateDiff: vktStateDiff,
|
||||||
|
ParentRoot: parentStateRoot,
|
||||||
}
|
}
|
||||||
if pre.Env.Withdrawals != nil {
|
if pre.Env.Withdrawals != nil {
|
||||||
h := types.DeriveSha(types.Withdrawals(pre.Env.Withdrawals), trie.NewStackTrie(nil))
|
h := types.DeriveSha(types.Withdrawals(pre.Env.Withdrawals), trie.NewStackTrie(nil))
|
||||||
|
|
@ -414,11 +456,13 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
return statedb, execRs, body, nil
|
return statedb, execRs, body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
|
// XXX peut-etre pas besoin de changer les parametres tant qu'on n'a pas la conversion
|
||||||
|
func MakePreState(db ethdb.Database, chainConfig *params.ChainConfig, pre *Prestate, verkle bool) (common.Hash, *state.StateDB) {
|
||||||
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
||||||
sdb := state.NewDatabase(tdb, nil)
|
sdb := state.NewDatabase(tdb, nil)
|
||||||
|
|
||||||
statedb, _ := state.New(types.EmptyRootHash, sdb)
|
statedb, _ := state.New(types.EmptyRootHash, sdb)
|
||||||
for addr, a := range accounts {
|
for addr, a := range pre.Pre {
|
||||||
statedb.SetCode(addr, a.Code)
|
statedb.SetCode(addr, a.Code)
|
||||||
statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeGenesis)
|
statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeGenesis)
|
||||||
statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceIncreaseGenesisBalance)
|
statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceIncreaseGenesisBalance)
|
||||||
|
|
@ -427,9 +471,19 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Commit and re-open to start with a clean state.
|
// Commit and re-open to start with a clean state.
|
||||||
root, _ := statedb.Commit(0, false, false)
|
mptRoot, err := statedb.Commit(0, false, false)
|
||||||
statedb, _ = state.New(root, sdb)
|
if err != nil {
|
||||||
return statedb
|
panic(err)
|
||||||
|
}
|
||||||
|
parentRoot := mptRoot
|
||||||
|
// If verkle mode started, establish the conversion
|
||||||
|
if verkle {
|
||||||
|
if _, ok := statedb.GetTrie().(*trie.VerkleTrie); ok {
|
||||||
|
return parentRoot, statedb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statedb, _ = state.New(mptRoot, sdb)
|
||||||
|
return parentRoot, statedb
|
||||||
}
|
}
|
||||||
|
|
||||||
func rlpHash(x interface{}) (h common.Hash) {
|
func rlpHash(x interface{}) (h common.Hash) {
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,22 @@ var (
|
||||||
"\t<file> - into the file <file> ",
|
"\t<file> - into the file <file> ",
|
||||||
Value: "block.json",
|
Value: "block.json",
|
||||||
}
|
}
|
||||||
|
OutputVKTFlag = &cli.StringFlag{
|
||||||
|
Name: "output.vkt",
|
||||||
|
Usage: "Determines where to put the `VKT` of the post-state.\n" +
|
||||||
|
"\t`stdout` - into the stdout output\n" +
|
||||||
|
"\t`stderr` - into the stderr output\n" +
|
||||||
|
"\t<file> - into the file <file> ",
|
||||||
|
Value: "vkt.json",
|
||||||
|
}
|
||||||
|
OutputWitnessFlag = &cli.StringFlag{
|
||||||
|
Name: "output.witness",
|
||||||
|
Usage: "Determines where to put the `witness` of the post-state.\n" +
|
||||||
|
"\t`stdout` - into the stdout output\n" +
|
||||||
|
"\t`stderr` - into the stderr output\n" +
|
||||||
|
"\t<file> - into the file <file> ",
|
||||||
|
Value: "witness.json",
|
||||||
|
}
|
||||||
InputAllocFlag = &cli.StringFlag{
|
InputAllocFlag = &cli.StringFlag{
|
||||||
Name: "input.alloc",
|
Name: "input.alloc",
|
||||||
Usage: "`stdin` or file name of where to find the prestate alloc to use.",
|
Usage: "`stdin` or file name of where to find the prestate alloc to use.",
|
||||||
|
|
@ -123,6 +139,10 @@ var (
|
||||||
Usage: "`stdin` or file name of where to find the transactions list in RLP form.",
|
Usage: "`stdin` or file name of where to find the transactions list in RLP form.",
|
||||||
Value: "txs.rlp",
|
Value: "txs.rlp",
|
||||||
}
|
}
|
||||||
|
InputVKTFlag = &cli.StringFlag{
|
||||||
|
Name: "input.vkt",
|
||||||
|
Usage: "`stdin` or file name of where to find the prestate VKT.",
|
||||||
|
}
|
||||||
SealCliqueFlag = &cli.StringFlag{
|
SealCliqueFlag = &cli.StringFlag{
|
||||||
Name: "seal.clique",
|
Name: "seal.clique",
|
||||||
Usage: "Seal block with Clique. `stdin` or file name of where to find the Clique sealing data.",
|
Usage: "Seal block with Clique. `stdin` or file name of where to find the Clique sealing data.",
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
|
||||||
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
|
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
|
||||||
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
|
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
|
||||||
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||||
|
ParentHash *common.Hash `json:"parentHash,omitempty"`
|
||||||
}
|
}
|
||||||
var enc stEnv
|
var enc stEnv
|
||||||
enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
|
enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
|
||||||
|
|
@ -59,6 +60,7 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
|
||||||
enc.ParentExcessBlobGas = (*math.HexOrDecimal64)(s.ParentExcessBlobGas)
|
enc.ParentExcessBlobGas = (*math.HexOrDecimal64)(s.ParentExcessBlobGas)
|
||||||
enc.ParentBlobGasUsed = (*math.HexOrDecimal64)(s.ParentBlobGasUsed)
|
enc.ParentBlobGasUsed = (*math.HexOrDecimal64)(s.ParentBlobGasUsed)
|
||||||
enc.ParentBeaconBlockRoot = s.ParentBeaconBlockRoot
|
enc.ParentBeaconBlockRoot = s.ParentBeaconBlockRoot
|
||||||
|
enc.ParentHash = s.ParentHash
|
||||||
return json.Marshal(&enc)
|
return json.Marshal(&enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,6 +87,7 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
|
||||||
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
|
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
|
||||||
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
|
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
|
||||||
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||||
|
ParentHash *common.Hash `json:"parentHash,omitempty"`
|
||||||
}
|
}
|
||||||
var dec stEnv
|
var dec stEnv
|
||||||
if err := json.Unmarshal(input, &dec); err != nil {
|
if err := json.Unmarshal(input, &dec); err != nil {
|
||||||
|
|
@ -154,5 +157,8 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
|
||||||
if dec.ParentBeaconBlockRoot != nil {
|
if dec.ParentBeaconBlockRoot != nil {
|
||||||
s.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot
|
s.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot
|
||||||
}
|
}
|
||||||
|
if dec.ParentHash != nil {
|
||||||
|
s.ParentHash = dec.ParentHash
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ var (
|
||||||
type input struct {
|
type input struct {
|
||||||
Alloc types.GenesisAlloc `json:"alloc,omitempty"`
|
Alloc types.GenesisAlloc `json:"alloc,omitempty"`
|
||||||
Env *stEnv `json:"env,omitempty"`
|
Env *stEnv `json:"env,omitempty"`
|
||||||
|
VKT map[common.Hash]hexutil.Bytes `json:"vkt,omitempty"`
|
||||||
Txs []*txWithKey `json:"txs,omitempty"`
|
Txs []*txWithKey `json:"txs,omitempty"`
|
||||||
TxRlp string `json:"txsRlp,omitempty"`
|
TxRlp string `json:"txsRlp,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
@ -93,13 +94,13 @@ func Transition(ctx *cli.Context) error {
|
||||||
prestate Prestate
|
prestate Prestate
|
||||||
txIt txIterator // txs to apply
|
txIt txIterator // txs to apply
|
||||||
allocStr = ctx.String(InputAllocFlag.Name)
|
allocStr = ctx.String(InputAllocFlag.Name)
|
||||||
|
vktStr = ctx.String(InputVKTFlag.Name)
|
||||||
envStr = ctx.String(InputEnvFlag.Name)
|
envStr = ctx.String(InputEnvFlag.Name)
|
||||||
txStr = ctx.String(InputTxsFlag.Name)
|
txStr = ctx.String(InputTxsFlag.Name)
|
||||||
inputData = &input{}
|
inputData = &input{}
|
||||||
)
|
)
|
||||||
// Figure out the prestate alloc
|
// Figure out the prestate alloc
|
||||||
if allocStr == stdinSelector || envStr == stdinSelector || txStr == stdinSelector {
|
if allocStr == stdinSelector || vktStr == stdinSelector || envStr == stdinSelector || txStr == stdinSelector {
|
||||||
decoder := json.NewDecoder(os.Stdin)
|
decoder := json.NewDecoder(os.Stdin)
|
||||||
if err := decoder.Decode(inputData); err != nil {
|
if err := decoder.Decode(inputData); err != nil {
|
||||||
return NewError(ErrorJson, fmt.Errorf("failed unmarshalling stdin: %v", err))
|
return NewError(ErrorJson, fmt.Errorf("failed unmarshalling stdin: %v", err))
|
||||||
|
|
@ -110,8 +111,18 @@ func Transition(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if vktStr != stdinSelector {
|
||||||
|
if err := readFile(vktStr, "VKT", &inputData.Alloc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
prestate.Pre = inputData.Alloc
|
prestate.Pre = inputData.Alloc
|
||||||
|
if vktStr != stdinSelector && vktStr != "" {
|
||||||
|
if err := readFile(vktStr, "VKT", &inputData.VKT); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prestate.VKT = inputData.VKT
|
||||||
// Set the block environment
|
// Set the block environment
|
||||||
if envStr != stdinSelector {
|
if envStr != stdinSelector {
|
||||||
var env stEnv
|
var env stEnv
|
||||||
|
|
@ -183,8 +194,14 @@ func Transition(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
// Dump the execution result
|
// Dump the execution result
|
||||||
collector := make(Alloc)
|
collector := make(Alloc)
|
||||||
|
var vktleaves map[common.Hash]hexutil.Bytes
|
||||||
|
if !chainConfig.IsVerkle(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp) {
|
||||||
s.DumpToCollector(collector, nil)
|
s.DumpToCollector(collector, nil)
|
||||||
return dispatchOutput(ctx, baseDir, result, collector, body)
|
} else {
|
||||||
|
vktleaves = make(map[common.Hash]hexutil.Bytes)
|
||||||
|
s.DumpVKTLeaves(vktleaves)
|
||||||
|
}
|
||||||
|
return dispatchOutput(ctx, baseDir, result, collector, body, vktleaves)
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
||||||
|
|
@ -306,7 +323,7 @@ func saveFile(baseDir, filename string, data interface{}) error {
|
||||||
|
|
||||||
// dispatchOutput writes the output data to either stderr or stdout, or to the specified
|
// dispatchOutput writes the output data to either stderr or stdout, or to the specified
|
||||||
// files
|
// files
|
||||||
func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, alloc Alloc, body hexutil.Bytes) error {
|
func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, alloc Alloc, body hexutil.Bytes, vkt map[common.Hash]hexutil.Bytes) error {
|
||||||
stdOutObject := make(map[string]interface{})
|
stdOutObject := make(map[string]interface{})
|
||||||
stdErrObject := make(map[string]interface{})
|
stdErrObject := make(map[string]interface{})
|
||||||
dispatch := func(baseDir, fName, name string, obj interface{}) error {
|
dispatch := func(baseDir, fName, name string, obj interface{}) error {
|
||||||
|
|
@ -333,6 +350,11 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, a
|
||||||
if err := dispatch(baseDir, ctx.String(OutputBodyFlag.Name), "body", body); err != nil {
|
if err := dispatch(baseDir, ctx.String(OutputBodyFlag.Name), "body", body); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if vkt != nil {
|
||||||
|
if err := dispatch(baseDir, ctx.String(OutputVKTFlag.Name), "vkt", vkt); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
if len(stdOutObject) > 0 {
|
if len(stdOutObject) > 0 {
|
||||||
b, err := json.MarshalIndent(stdOutObject, "", " ")
|
b, err := json.MarshalIndent(stdOutObject, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -146,10 +146,13 @@ var (
|
||||||
t8ntool.TraceEnableCallFramesFlag,
|
t8ntool.TraceEnableCallFramesFlag,
|
||||||
t8ntool.OutputBasedir,
|
t8ntool.OutputBasedir,
|
||||||
t8ntool.OutputAllocFlag,
|
t8ntool.OutputAllocFlag,
|
||||||
|
t8ntool.OutputVKTFlag,
|
||||||
|
t8ntool.OutputWitnessFlag,
|
||||||
t8ntool.OutputResultFlag,
|
t8ntool.OutputResultFlag,
|
||||||
t8ntool.OutputBodyFlag,
|
t8ntool.OutputBodyFlag,
|
||||||
t8ntool.InputAllocFlag,
|
t8ntool.InputAllocFlag,
|
||||||
t8ntool.InputEnvFlag,
|
t8ntool.InputEnvFlag,
|
||||||
|
t8ntool.InputVKTFlag,
|
||||||
t8ntool.InputTxsFlag,
|
t8ntool.InputTxsFlag,
|
||||||
t8ntool.ForknameFlag,
|
t8ntool.ForknameFlag,
|
||||||
t8ntool.ChainIDFlag,
|
t8ntool.ChainIDFlag,
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,17 @@ data, and verifies that all snapshot storage data has a corresponding account.
|
||||||
Description: `
|
Description: `
|
||||||
geth snapshot inspect-account <address | hash> checks all snapshot layers and prints out
|
geth snapshot inspect-account <address | hash> checks all snapshot layers and prints out
|
||||||
information about the specified address.
|
information about the specified address.
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "inspect-garys-account",
|
||||||
|
Usage: "Check all snapshot layers for the specific account",
|
||||||
|
ArgsUsage: "<address | hash>",
|
||||||
|
Action: checkGarysAccounts,
|
||||||
|
Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
|
Description: `
|
||||||
|
geth snapshot inspect-account <address | hash> checks all snapshot layers and prints out
|
||||||
|
information about the specified address.
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -692,3 +703,72 @@ func checkAccount(ctx *cli.Context) error {
|
||||||
log.Info("Checked the snapshot journalled storage", "time", common.PrettyDuration(time.Since(start)))
|
log.Info("Checked the snapshot journalled storage", "time", common.PrettyDuration(time.Since(start)))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkGarysAccounts(ctx *cli.Context) error {
|
||||||
|
stack, _ := makeConfigNode(ctx)
|
||||||
|
defer stack.Close()
|
||||||
|
|
||||||
|
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
|
defer chaindb.Close()
|
||||||
|
|
||||||
|
triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false)
|
||||||
|
defer triedb.Close()
|
||||||
|
|
||||||
|
var root common.Hash
|
||||||
|
if ctx.NArg() == 1 {
|
||||||
|
rootBytes := common.FromHex(ctx.Args().Get(1))
|
||||||
|
if len(rootBytes) != common.HashLength {
|
||||||
|
return fmt.Errorf("invalid hash: %s", ctx.Args().Get(1))
|
||||||
|
}
|
||||||
|
root = common.BytesToHash(rootBytes)
|
||||||
|
} else {
|
||||||
|
headBlock := rawdb.ReadHeadBlock(chaindb)
|
||||||
|
if headBlock == nil {
|
||||||
|
log.Error("Failed to load head block")
|
||||||
|
return errors.New("no head block")
|
||||||
|
}
|
||||||
|
root = headBlock.Root()
|
||||||
|
}
|
||||||
|
snapConfig := snapshot.Config{
|
||||||
|
CacheSize: 256,
|
||||||
|
Recovery: false,
|
||||||
|
NoBuild: true,
|
||||||
|
AsyncBuild: false,
|
||||||
|
}
|
||||||
|
snaptree, err := snapshot.New(snapConfig, chaindb, triedb, root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
accIt, err := snaptree.AccountIterator(root, common.Hash{})
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to create account iterator", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer accIt.Release()
|
||||||
|
|
||||||
|
// Open the file in append mode, create it if it doesn't exist
|
||||||
|
file, err := os.OpenFile("weird_contracts.csv", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
file.WriteString("account hash,nonce,code hash,root hash,balance\n")
|
||||||
|
|
||||||
|
var weird int
|
||||||
|
for accIt.Next() {
|
||||||
|
acc, err := types.FullAccount(accIt.Account())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to get full account", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if acc.Nonce == 0 && bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) && acc.Root != types.EmptyRootHash {
|
||||||
|
weird++
|
||||||
|
if _, err = file.WriteString(fmt.Sprintf("%x,%d,%x,%x,%s\n", accIt.Hash(), acc.Nonce, acc.CodeHash, acc.Root, acc.Balance.String())); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Info("sweep completed", "count", weird)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,18 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
|
||||||
return nextKey
|
return nextKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StateDB) DumpVKTLeaves(collector map[common.Hash]hexutil.Bytes) {
|
||||||
|
it, err := s.trie.(*trie.VerkleTrie).NodeIterator(nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for it.Next(true) {
|
||||||
|
if it.Leaf() {
|
||||||
|
collector[common.BytesToHash(it.LeafKey())] = it.LeafBlob()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RawDump returns the state. If the processing is aborted e.g. due to options
|
// RawDump returns the state. If the processing is aborted e.g. due to options
|
||||||
// reaching Max, the `Next` key is set on the returned Dump.
|
// reaching Max, the `Next` key is set on the returned Dump.
|
||||||
func (s *StateDB) RawDump(opts *DumpConfig) Dump {
|
func (s *StateDB) RawDump(opts *DumpConfig) Dump {
|
||||||
|
|
|
||||||
|
|
@ -117,19 +117,20 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *t
|
||||||
return UnsupportedForkError{t.json.Network}
|
return UnsupportedForkError{t.json.Network}
|
||||||
}
|
}
|
||||||
// import pre accounts & construct test genesis block & state root
|
// import pre accounts & construct test genesis block & state root
|
||||||
|
// Commit genesis state
|
||||||
|
gspec := t.genesis(config)
|
||||||
var (
|
var (
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
tconf = &triedb.Config{
|
tconf = &triedb.Config{
|
||||||
Preimages: true,
|
Preimages: true,
|
||||||
|
IsVerkle: gspec.Config.VerkleTime != nil && *gspec.Config.VerkleTime <= gspec.Timestamp,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if scheme == rawdb.PathScheme {
|
if scheme == rawdb.PathScheme || tconf.IsVerkle {
|
||||||
tconf.PathDB = pathdb.Defaults
|
tconf.PathDB = pathdb.Defaults
|
||||||
} else {
|
} else {
|
||||||
tconf.HashDB = hashdb.Defaults
|
tconf.HashDB = hashdb.Defaults
|
||||||
}
|
}
|
||||||
// Commit genesis state
|
|
||||||
gspec := t.genesis(config)
|
|
||||||
|
|
||||||
// if ttd is not specified, set an arbitrary huge value
|
// if ttd is not specified, set an arbitrary huge value
|
||||||
if gspec.Config.TerminalTotalDifficulty == nil {
|
if gspec.Config.TerminalTotalDifficulty == nil {
|
||||||
|
|
|
||||||
|
|
@ -464,6 +464,45 @@ var Forks = map[string]*params.ChainConfig{
|
||||||
Osaka: params.DefaultOsakaBlobConfig,
|
Osaka: params.DefaultOsakaBlobConfig,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"Verkle": {
|
||||||
|
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),
|
||||||
|
ArrowGlacierBlock: big.NewInt(0),
|
||||||
|
MergeNetsplitBlock: big.NewInt(0),
|
||||||
|
TerminalTotalDifficulty: big.NewInt(0),
|
||||||
|
ShanghaiTime: u64(0),
|
||||||
|
VerkleTime: u64(0),
|
||||||
|
},
|
||||||
|
"ShanghaiToVerkleAtTime32": {
|
||||||
|
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),
|
||||||
|
ArrowGlacierBlock: big.NewInt(0),
|
||||||
|
MergeNetsplitBlock: big.NewInt(0),
|
||||||
|
TerminalTotalDifficulty: big.NewInt(0),
|
||||||
|
ShanghaiTime: u64(0),
|
||||||
|
VerkleTime: u64(32),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// AvailableForks returns the set of defined fork names
|
// AvailableForks returns the set of defined fork names
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue