mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
core/{.,state,vm},miner,ethr/tracers: implement 7709
Co-authored-by: Ignacio Hagopian <jsign.uy@gmail.com> Signed-off-by: Guillaume Ballet <3272758+gballet@users.noreply.github.com>
This commit is contained in:
parent
033de2a05b
commit
dd5ff823bd
8 changed files with 39 additions and 18 deletions
|
|
@ -384,7 +384,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||
blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase)
|
||||
blockContext.Random = &common.Hash{} // enable post-merge instruction set
|
||||
evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{})
|
||||
ProcessParentBlockHash(b.header.ParentHash, evm)
|
||||
ProcessParentBlockHash(b.header.ParentHash, evm, false)
|
||||
}
|
||||
|
||||
// Execute any user modifications to the block
|
||||
|
|
@ -492,7 +492,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
|
|||
// EIP-2935
|
||||
blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase)
|
||||
evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{})
|
||||
ProcessParentBlockHash(b.header.ParentHash, evm)
|
||||
ProcessParentBlockHash(b.header.ParentHash, evm, false)
|
||||
}
|
||||
|
||||
// Execute any user modifications to the block.
|
||||
|
|
|
|||
|
|
@ -157,6 +157,10 @@ func (s *hookedStateDB) Witness() *stateless.Witness {
|
|||
return s.inner.Witness()
|
||||
}
|
||||
|
||||
func (s *hookedStateDB) AccessEvents() *AccessEvents {
|
||||
return s.inner.AccessEvents()
|
||||
}
|
||||
|
||||
func (s *hookedStateDB) SubBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) uint256.Int {
|
||||
prev := s.inner.SubBalance(addr, amount, reason)
|
||||
if s.hooks.OnBalanceChange != nil && !amount.IsZero() {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
|
|
@ -86,7 +87,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||
}
|
||||
if p.config.IsPrague(block.Number(), block.Time()) {
|
||||
ProcessParentBlockHash(block.ParentHash(), evm)
|
||||
ProcessParentBlockHash(block.ParentHash(), evm, p.config.IsVerkle(block.Number(), block.Time()))
|
||||
}
|
||||
|
||||
// Iterate over and process the individual transactions
|
||||
|
|
@ -234,14 +235,24 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, evm *vm.EVM) {
|
|||
}
|
||||
|
||||
// ProcessParentBlockHash stores the parent block hash in the history storage contract
|
||||
// as per EIP-2935.
|
||||
func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) {
|
||||
// as per EIP-2935/7709.
|
||||
func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM, is7709 bool) {
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
onSystemCallStart(tracer, evm.GetVMContext())
|
||||
if tracer.OnSystemCallEnd != nil {
|
||||
defer tracer.OnSystemCallEnd()
|
||||
}
|
||||
}
|
||||
if is7709 {
|
||||
// currently 8192 for kautinen7, to be changed to 8 (and made a constant) for kaustinen8
|
||||
ringIndex := (evm.Context.BlockNumber.Uint64() - 1) % params.HistoryServeWindow
|
||||
var key common.Hash
|
||||
binary.BigEndian.PutUint64(key[24:], ringIndex)
|
||||
evm.StateDB.SetState(params.SystemAddress, key, prevHash)
|
||||
evm.StateDB.AccessEvents().SlotGas(params.SystemAddress, key, true)
|
||||
evm.StateDB.Finalise(false)
|
||||
return
|
||||
}
|
||||
msg := &Message{
|
||||
From: params.SystemAddress,
|
||||
GasLimit: 30_000_000,
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ func TestProcessParentBlockHash(t *testing.T) {
|
|||
// block 1 parent hash is 0x0100....
|
||||
// block 2 parent hash is 0x0200....
|
||||
// etc
|
||||
checkBlockHashes := func(statedb *state.StateDB) {
|
||||
checkBlockHashes := func(statedb *state.StateDB, isVerkle bool) {
|
||||
statedb.SetNonce(params.HistoryStorageAddress, 1)
|
||||
statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode)
|
||||
// Process n blocks, from 1 .. num
|
||||
|
|
@ -226,19 +226,19 @@ func TestProcessParentBlockHash(t *testing.T) {
|
|||
header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)}
|
||||
vmContext := NewEVMBlockContext(header, nil, new(common.Address))
|
||||
evm := vm.NewEVM(vmContext, statedb, params.MergedTestChainConfig, vm.Config{})
|
||||
ProcessParentBlockHash(header.ParentHash, evm)
|
||||
ProcessParentBlockHash(header.ParentHash, evm, isVerkle)
|
||||
}
|
||||
// Read block hashes for block 0 .. num-1
|
||||
for i := 0; i < num; i++ {
|
||||
have, want := getContractStoredBlockHash(statedb, uint64(i)), common.Hash{byte(i + 1)}
|
||||
have, want := getContractStoredBlockHash(statedb, uint64(i), isVerkle), common.Hash{byte(i + 1)}
|
||||
if have != want {
|
||||
t.Errorf("block %d, have parent hash %v, want %v", i, have, want)
|
||||
t.Errorf("block %d, verkle=%v, have parent hash %v, want %v", i, isVerkle, have, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
t.Run("MPT", func(t *testing.T) {
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
checkBlockHashes(statedb)
|
||||
checkBlockHashes(statedb, false)
|
||||
})
|
||||
t.Run("Verkle", func(t *testing.T) {
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
|
|
@ -246,15 +246,18 @@ func TestProcessParentBlockHash(t *testing.T) {
|
|||
cacheConfig.SnapshotLimit = 0
|
||||
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true))
|
||||
statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil))
|
||||
checkBlockHashes(statedb)
|
||||
checkBlockHashes(statedb, true)
|
||||
})
|
||||
}
|
||||
|
||||
// getContractStoredBlockHash is a utility method which reads the stored parent blockhash for block 'number'
|
||||
func getContractStoredBlockHash(statedb *state.StateDB, number uint64) common.Hash {
|
||||
func getContractStoredBlockHash(statedb *state.StateDB, number uint64, isVerkle bool) common.Hash {
|
||||
ringIndex := number % params.HistoryServeWindow
|
||||
var key common.Hash
|
||||
binary.BigEndian.PutUint64(key[24:], ringIndex)
|
||||
if isVerkle {
|
||||
return statedb.GetState(params.SystemAddress, key)
|
||||
}
|
||||
return statedb.GetState(params.HistoryStorageAddress, key)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/stateless"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
|
@ -98,6 +99,8 @@ type StateDB interface {
|
|||
|
||||
Witness() *stateless.Witness
|
||||
|
||||
AccessEvents() *state.AccessEvents
|
||||
|
||||
// Finalise must be invoked at the end of a transaction
|
||||
Finalise(bool)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
|||
}
|
||||
// If prague hardfork, insert parent block hash in the state as per EIP-2935.
|
||||
if eth.blockchain.Config().IsPrague(block.Number(), block.Time()) {
|
||||
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
||||
core.ProcessParentBlockHash(block.ParentHash(), evm, eth.blockchain.Config().IsVerkle(block.Number(), block.Time()))
|
||||
}
|
||||
if txIndex == 0 && len(block.Transactions()) == 0 {
|
||||
return nil, vm.BlockContext{}, statedb, release, nil
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
|||
}
|
||||
// Insert parent hash in history contract.
|
||||
if api.backend.ChainConfig().IsPrague(next.Number(), next.Time()) {
|
||||
core.ProcessParentBlockHash(next.ParentHash(), evm)
|
||||
core.ProcessParentBlockHash(next.ParentHash(), evm, api.backend.ChainConfig().IsVerkle(next.Number(), next.Time()))
|
||||
}
|
||||
// Clean out any pending release functions of trace state. Note this
|
||||
// step must be done after constructing tracing state, because the
|
||||
|
|
@ -541,7 +541,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
|||
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||
}
|
||||
if chainConfig.IsPrague(block.Number(), block.Time()) {
|
||||
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
||||
core.ProcessParentBlockHash(block.ParentHash(), evm, api.backend.ChainConfig().IsVerkle(block.Number(), block.Time()))
|
||||
}
|
||||
for i, tx := range block.Transactions() {
|
||||
if err := ctx.Err(); err != nil {
|
||||
|
|
@ -605,7 +605,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
|||
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||
}
|
||||
if api.backend.ChainConfig().IsPrague(block.Number(), block.Time()) {
|
||||
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
||||
core.ProcessParentBlockHash(block.ParentHash(), evm, api.backend.ChainConfig().IsVerkle(block.Number(), block.Time()))
|
||||
}
|
||||
|
||||
// JS tracers have high overhead. In this case run a parallel
|
||||
|
|
@ -782,7 +782,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
|||
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||
}
|
||||
if chainConfig.IsPrague(block.Number(), block.Time()) {
|
||||
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
||||
core.ProcessParentBlockHash(block.ParentHash(), evm, api.backend.ChainConfig().IsVerkle(block.Number(), block.Time()))
|
||||
}
|
||||
for i, tx := range block.Transactions() {
|
||||
// Prepare the transaction for un-traced execution
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir
|
|||
core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, env.evm)
|
||||
}
|
||||
if miner.chainConfig.IsPrague(header.Number, header.Time) {
|
||||
core.ProcessParentBlockHash(header.ParentHash, env.evm)
|
||||
core.ProcessParentBlockHash(header.ParentHash, env.evm, false)
|
||||
}
|
||||
return env, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue