mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 13:16:42 +00:00
bal execution refactor (wip)
This commit is contained in:
parent
cb541b833d
commit
4282087fb0
6 changed files with 6 additions and 327 deletions
|
|
@ -210,8 +210,6 @@ type BlockChainConfig struct {
|
|||
|
||||
// StateSizeTracking indicates whether the state size tracking is enabled.
|
||||
StateSizeTracking bool
|
||||
// EnableBAL enables block access list creation and verification for post-Cancun blocks which contain access lists.
|
||||
EnableBAL bool
|
||||
}
|
||||
|
||||
// DefaultConfig returns the default config.
|
||||
|
|
@ -1924,7 +1922,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
|
|||
start := time.Now()
|
||||
// construct or verify block access lists if BALs are enabled and
|
||||
// we are post-selfdestruct removal fork.
|
||||
enableBAL := (bc.cfg.EnableBAL && bc.chainConfig.IsCancun(block.Number(), block.Time())) || bc.chainConfig.IsAmsterdam(block.Number(), block.Time())
|
||||
enableBAL := (bc.cfg.EnableBALForTesting && bc.chainConfig.IsCancun(block.Number(), block.Time())) || bc.chainConfig.IsAmsterdam(block.Number(), block.Time())
|
||||
blockHasAccessList := block.Body().AccessList != nil
|
||||
makeBAL := enableBAL && !blockHasAccessList
|
||||
validateBAL := enableBAL && blockHasAccessList
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ func (r *BALReader) ModifiedAccounts() (res []common.Address) {
|
|||
}
|
||||
|
||||
func (r *BALReader) ValidateStateReads(allReads bal.StateAccesses) error {
|
||||
fmt.Printf("bal is %v\n", r.block.Body().AccessList.String())
|
||||
// 1. remove any slots from 'allReads' which were written
|
||||
// 2. validate that the read set in the BAL matches 'allReads' exactly
|
||||
for addr, reads := range allReads {
|
||||
|
|
@ -178,6 +179,7 @@ func (r *BALReader) ValidateStateReads(allReads bal.StateAccesses) error {
|
|||
}
|
||||
}
|
||||
|
||||
fmt.Printf("addr is %x\n", addr)
|
||||
expectedReads := r.accesses[addr].StorageReads
|
||||
if len(reads) != len(expectedReads) {
|
||||
return fmt.Errorf("mismatch between the number of computed reads and number of expected reads")
|
||||
|
|
|
|||
|
|
@ -1,218 +0,0 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/stateless"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/types/bal"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/trie/utils"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
type AccessListCreationDB struct {
|
||||
idx uint16
|
||||
inner BlockProcessingDB
|
||||
accessList *bal.ConstructionBlockAccessList
|
||||
}
|
||||
|
||||
func NewBlockAccessListBuilder(db BlockProcessingDB) *AccessListCreationDB {
|
||||
return &AccessListCreationDB{0, db, bal.NewConstructionBlockAccessList()}
|
||||
}
|
||||
func (a *AccessListCreationDB) SetAccessListIndex(idx int) {
|
||||
a.idx = uint16(idx)
|
||||
}
|
||||
|
||||
// ConstructedBlockAccessList retrieves the access list that has been constructed
|
||||
// by the StateDB instance, or nil if BAL construction was not enabled.
|
||||
func (a *AccessListCreationDB) ConstructedBlockAccessList() *bal.ConstructionBlockAccessList {
|
||||
return a.accessList
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) CreateAccount(address common.Address) {
|
||||
a.inner.CreateAccount(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) CreateContract(address common.Address) {
|
||||
a.inner.CreateContract(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) SubBalance(address common.Address, u *uint256.Int, reason tracing.BalanceChangeReason) uint256.Int {
|
||||
return a.inner.SubBalance(address, u, reason)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) AddBalance(address common.Address, u *uint256.Int, reason tracing.BalanceChangeReason) uint256.Int {
|
||||
return a.inner.AddBalance(address, u, reason)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetBalance(address common.Address) *uint256.Int {
|
||||
return a.inner.GetBalance(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetNonce(address common.Address) uint64 {
|
||||
return a.inner.GetNonce(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) SetNonce(address common.Address, u uint64, reason tracing.NonceChangeReason) {
|
||||
a.inner.SetNonce(address, u, reason)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetCodeHash(address common.Address) common.Hash {
|
||||
return a.inner.GetCodeHash(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetCode(address common.Address) []byte {
|
||||
return a.inner.GetCode(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) SetCode(addr common.Address, code []byte, reason tracing.CodeChangeReason) (prev []byte) {
|
||||
return a.inner.SetCode(addr, code, reason)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetCodeSize(address common.Address) int {
|
||||
return a.inner.GetCodeSize(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) AddRefund(u uint64) {
|
||||
a.inner.AddRefund(u)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) SubRefund(u uint64) {
|
||||
a.inner.SubRefund(u)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetRefund() uint64 {
|
||||
return a.inner.GetRefund()
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetStateAndCommittedState(address common.Address, hash common.Hash) (common.Hash, common.Hash) {
|
||||
return a.inner.GetStateAndCommittedState(address, hash)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetState(address common.Address, hash common.Hash) common.Hash {
|
||||
return a.inner.GetState(address, hash)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) SetState(address common.Address, hash common.Hash, hash2 common.Hash) common.Hash {
|
||||
return a.inner.SetState(address, hash, hash2)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetStorageRoot(addr common.Address) common.Hash {
|
||||
return a.inner.GetStorageRoot(addr)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetTransientState(addr common.Address, key common.Hash) common.Hash {
|
||||
return a.inner.GetTransientState(addr, key)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) SetTransientState(addr common.Address, key, value common.Hash) {
|
||||
a.inner.SetTransientState(addr, key, value)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) SelfDestruct(address common.Address) uint256.Int {
|
||||
return a.inner.SelfDestruct(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) HasSelfDestructed(address common.Address) bool {
|
||||
return a.inner.HasSelfDestructed(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) SelfDestruct6780(address common.Address) (uint256.Int, bool) {
|
||||
return a.inner.SelfDestruct6780(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) Exist(address common.Address) bool {
|
||||
return a.inner.Exist(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) Empty(address common.Address) bool {
|
||||
return a.inner.Empty(address)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) AddressInAccessList(addr common.Address) bool {
|
||||
return a.inner.AddressInAccessList(addr)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) {
|
||||
return a.inner.SlotInAccessList(addr, slot)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) AddAddressToAccessList(addr common.Address) {
|
||||
a.inner.AddAddressToAccessList(addr)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) AddSlotToAccessList(addr common.Address, slot common.Hash) {
|
||||
a.inner.AddSlotToAccessList(addr, slot)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) PointCache() *utils.PointCache {
|
||||
return a.inner.PointCache()
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) {
|
||||
a.inner.Prepare(rules, sender, coinbase, dest, precompiles, txAccesses)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) RevertToSnapshot(i int) {
|
||||
a.inner.RevertToSnapshot(i)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) Snapshot() int {
|
||||
return a.inner.Snapshot()
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) AddLog(log *types.Log) {
|
||||
a.inner.AddLog(log)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) AddPreimage(hash common.Hash, bytes []byte) {
|
||||
a.inner.AddPreimage(hash, bytes)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) Witness() *stateless.Witness {
|
||||
return a.inner.Witness()
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) AccessEvents() *AccessEvents {
|
||||
return a.inner.AccessEvents()
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) TxIndex() int {
|
||||
return a.inner.TxIndex()
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) Finalise(b bool) (*bal.StateDiff, *bal.StateAccesses) {
|
||||
diff, accesses := a.inner.Finalise(b)
|
||||
a.accessList.ApplyDiff(uint(a.idx), diff)
|
||||
a.accessList.ApplyAccesses(*accesses) // TODO: can remove the pointer on accesses (map is already a reference type)
|
||||
return nil, nil // TODO: not sure what to do here. The diff has been applied to the access list so it is "owned" by the access list, not sure why a caller would need it...
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash, blockTime uint64) []*types.Log {
|
||||
return a.inner.GetLogs(hash, blockNumber, blockHash, blockTime)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) IntermediateRoot(deleteEmpty bool) common.Hash {
|
||||
return a.inner.IntermediateRoot(deleteEmpty)
|
||||
}
|
||||
|
||||
func (a *AccessListCreationDB) Database() Database {
|
||||
return a.inner.Database()
|
||||
}
|
||||
func (a *AccessListCreationDB) GetTrie() Trie {
|
||||
return a.inner.GetTrie()
|
||||
}
|
||||
func (s *AccessListCreationDB) SetTxContext(thash common.Hash, ti int) {
|
||||
s.inner.SetTxContext(thash, ti)
|
||||
}
|
||||
|
||||
func (s *AccessListCreationDB) Error() error {
|
||||
return s.inner.Error()
|
||||
}
|
||||
|
||||
func (s *AccessListCreationDB) Copy() BlockProcessingDB {
|
||||
return &AccessListCreationDB{s.idx, s.inner.Copy(), s.accessList.Copy()}
|
||||
}
|
||||
|
||||
var _ BlockProcessingDB = &AccessListCreationDB{}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/stateless"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/types/bal"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/trie/utils"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
type BlockProcessingDB interface {
|
||||
CreateAccount(common.Address)
|
||||
CreateContract(common.Address)
|
||||
|
||||
SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) uint256.Int
|
||||
AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) uint256.Int
|
||||
GetBalance(common.Address) *uint256.Int
|
||||
|
||||
GetNonce(common.Address) uint64
|
||||
SetNonce(common.Address, uint64, tracing.NonceChangeReason)
|
||||
|
||||
GetCodeHash(common.Address) common.Hash
|
||||
GetCode(common.Address) []byte
|
||||
|
||||
// SetCode sets the new code for the address, and returns the previous code, if any.
|
||||
SetCode(addr common.Address, code []byte, reason tracing.CodeChangeReason) (prev []byte)
|
||||
GetCodeSize(common.Address) int
|
||||
|
||||
AddRefund(uint64)
|
||||
SubRefund(uint64)
|
||||
GetRefund() uint64
|
||||
|
||||
GetStateAndCommittedState(common.Address, common.Hash) (common.Hash, common.Hash)
|
||||
GetState(common.Address, common.Hash) common.Hash
|
||||
SetState(common.Address, common.Hash, common.Hash) common.Hash
|
||||
GetStorageRoot(addr common.Address) common.Hash
|
||||
|
||||
GetTransientState(addr common.Address, key common.Hash) common.Hash
|
||||
SetTransientState(addr common.Address, key, value common.Hash)
|
||||
|
||||
SelfDestruct(common.Address) uint256.Int
|
||||
HasSelfDestructed(common.Address) bool
|
||||
|
||||
// SelfDestruct6780 is post-EIP6780 selfdestruct, which means that it's a
|
||||
// send-all-to-beneficiary, unless the contract was created in this same
|
||||
// transaction, in which case it will be destructed.
|
||||
// This method returns the prior balance, along with a boolean which is
|
||||
// true iff the object was indeed destructed.
|
||||
SelfDestruct6780(common.Address) (uint256.Int, bool)
|
||||
|
||||
// Exist reports whether the given account exists in
|
||||
// Notably this also returns true for self-destructed accounts within the current transaction.
|
||||
Exist(common.Address) bool
|
||||
// Empty returns whether the given account is empty. Empty
|
||||
// is defined according to EIP161 (balance = nonce = code = 0).
|
||||
Empty(common.Address) bool
|
||||
|
||||
AddressInAccessList(addr common.Address) bool
|
||||
SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool)
|
||||
// AddAddressToAccessList adds the given address to the access list. This operation is safe to perform
|
||||
// even if the feature/fork is not active yet
|
||||
AddAddressToAccessList(addr common.Address)
|
||||
// AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform
|
||||
// even if the feature/fork is not active yet
|
||||
AddSlotToAccessList(addr common.Address, slot common.Hash)
|
||||
|
||||
// PointCache returns the point cache used in computations
|
||||
PointCache() *utils.PointCache
|
||||
|
||||
Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList)
|
||||
|
||||
RevertToSnapshot(int)
|
||||
Snapshot() int
|
||||
|
||||
AddLog(*types.Log)
|
||||
AddPreimage(common.Hash, []byte)
|
||||
|
||||
Witness() *stateless.Witness
|
||||
|
||||
AccessEvents() *AccessEvents
|
||||
|
||||
// Finalise must be invoked at the end of a transaction
|
||||
Finalise(bool) (*bal.StateDiff, *bal.StateAccesses)
|
||||
|
||||
// These two methods are not used in the EVM. however, I need them to be part of the interface
|
||||
// so that block processing/production can use instances of this interface so that the StateDB
|
||||
// wrapped with BAL creation functionality can be passed in case of BALs
|
||||
GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash, blockTime uint64) []*types.Log
|
||||
|
||||
IntermediateRoot(deleteEmpty bool) common.Hash
|
||||
|
||||
Database() Database
|
||||
GetTrie() Trie
|
||||
SetTxContext(thash common.Hash, ti int)
|
||||
Error() error
|
||||
|
||||
TxIndex() int
|
||||
|
||||
Copy() BlockProcessingDB
|
||||
}
|
||||
|
|
@ -778,7 +778,7 @@ func (s *StateDB) CreateContract(addr common.Address) {
|
|||
|
||||
// Copy creates a deep, independent copy of the state.
|
||||
// Snapshots of the copied state cannot be applied to the copy.
|
||||
func (s *StateDB) Copy() BlockProcessingDB {
|
||||
func (s *StateDB) Copy() *StateDB {
|
||||
// Copy all the basic fields, initialize the memory ones
|
||||
state := &StateDB{
|
||||
db: s.db,
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ func (t *BlockTest) createTestBlockChain(config *params.ChainConfig, snapshotter
|
|||
StatelessSelfValidation: witness,
|
||||
},
|
||||
NoPrefetch: true,
|
||||
EnableBAL: createAndVerifyBAL,
|
||||
EnableBALForTesting: createAndVerifyBAL,
|
||||
}
|
||||
if snapshotter {
|
||||
options.SnapshotLimit = 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue