mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
apply specular changes
Co-authored-by: Simon Oswald <git@simonoswald.xyz> Co-authored-by: MoonShiesty <moonshiesty@protonmail.com>
This commit is contained in:
parent
3f40e65c48
commit
0e4999d59f
4 changed files with 201 additions and 0 deletions
|
|
@ -1375,6 +1375,99 @@ func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addre
|
|||
return s.accessList.Contains(addr, slot)
|
||||
}
|
||||
|
||||
// <specular modification>
|
||||
func (s *StateDB) GetCurrentLogs() []*types.Log {
|
||||
return s.logs[s.thash]
|
||||
}
|
||||
|
||||
func (s *StateDB) GetCurrentAccessListForProof() (map[common.Address]int, []map[common.Hash]struct{}) {
|
||||
return s.accessList.addresses, s.accessList.slots
|
||||
}
|
||||
|
||||
func (s *StateDB) GetStateRootForProof(addr common.Address) common.Hash {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
return common.Hash{}
|
||||
}
|
||||
return stateObject.data.Root
|
||||
}
|
||||
|
||||
func (s *StateDB) GetRootForProof() common.Hash {
|
||||
return s.trie.Hash()
|
||||
}
|
||||
|
||||
func (s *StateDB) CommitForProof() {
|
||||
addressesToPrefetch := make([][]byte, 0, len(s.journal.dirties))
|
||||
for addr := range s.journal.dirties {
|
||||
obj, exist := s.stateObjects[addr]
|
||||
if !exist {
|
||||
continue
|
||||
}
|
||||
if obj.empty() { // rollup-specific: we ignore suicided accounts here
|
||||
obj.deleted = true
|
||||
|
||||
// We need to maintain account deletions explicitly (will remain
|
||||
// set indefinitely). Note only the first occurred self-destruct
|
||||
// event is tracked.
|
||||
if _, ok := s.stateObjectsDestruct[obj.address]; !ok {
|
||||
s.stateObjectsDestruct[obj.address] = obj.origin
|
||||
}
|
||||
// Note, we can't do this only at the end of a block because multiple
|
||||
// transactions within the same block might self destruct and then
|
||||
// resurrect an account; but the snapshotter needs both events.
|
||||
delete(s.accounts, obj.addrHash) // Clear out any previously updated account data (may be recreated via a resurrect)
|
||||
delete(s.storages, obj.addrHash) // Clear out any previously updated storage data (may be recreated via a resurrect)
|
||||
delete(s.accountsOrigin, obj.address) // Clear out any previously updated account data (may be recreated via a resurrect)
|
||||
delete(s.storagesOrigin, obj.address) // Clear out any previously updated storage data (may be recreated via a resurrect)
|
||||
} else {
|
||||
obj.finalise(true) // Prefetch slots in the background
|
||||
}
|
||||
s.stateObjectsPending[addr] = struct{}{}
|
||||
s.stateObjectsDirty[addr] = struct{}{}
|
||||
addressesToPrefetch = append(addressesToPrefetch, common.CopyBytes(addr[:])) // Copy needed for closure
|
||||
}
|
||||
if s.prefetcher != nil && len(addressesToPrefetch) > 0 {
|
||||
s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, addressesToPrefetch)
|
||||
}
|
||||
for addr := range s.stateObjectsPending {
|
||||
if obj := s.stateObjects[addr]; !obj.deleted {
|
||||
obj.updateRoot()
|
||||
}
|
||||
}
|
||||
if s.prefetcher != nil {
|
||||
if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie != nil {
|
||||
s.trie = trie
|
||||
}
|
||||
}
|
||||
for addr := range s.stateObjectsPending {
|
||||
if obj := s.stateObjects[addr]; obj.deleted {
|
||||
s.deleteStateObject(obj)
|
||||
} else {
|
||||
s.updateStateObject(obj)
|
||||
}
|
||||
}
|
||||
if len(s.stateObjectsPending) > 0 {
|
||||
s.stateObjectsPending = make(map[common.Address]struct{})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateDB) DeleteSuicidedAccountForProof(addr common.Address) {
|
||||
obj, exist := s.stateObjects[addr]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
obj.deleted = true
|
||||
if s.prefetcher != nil {
|
||||
s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, [][]byte{common.CopyBytes(addr[:])})
|
||||
if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie != nil {
|
||||
s.trie = trie
|
||||
}
|
||||
}
|
||||
s.deleteStateObject(obj)
|
||||
}
|
||||
|
||||
// <specular modification/>
|
||||
|
||||
// convertAccountSet converts a provided account set from address keyed to hash keyed.
|
||||
func (s *StateDB) convertAccountSet(set map[common.Address]*types.StateAccount) map[common.Hash]struct{} {
|
||||
ret := make(map[common.Hash]struct{}, len(set))
|
||||
|
|
|
|||
|
|
@ -146,6 +146,65 @@ type Message struct {
|
|||
SkipAccountChecks bool
|
||||
}
|
||||
|
||||
// <specular modification>
|
||||
|
||||
// The vm package doesn't have access to the Message type defined above.
|
||||
// Getters are defined for EVMHook which uses MessageInterface instead.
|
||||
|
||||
func (m *Message) GetTo() *common.Address {
|
||||
return m.To
|
||||
}
|
||||
|
||||
func (m *Message) GetFrom() common.Address {
|
||||
return m.From
|
||||
}
|
||||
|
||||
func (m *Message) GetNonce() uint64 {
|
||||
return m.Nonce
|
||||
}
|
||||
|
||||
func (m *Message) GetValue() *big.Int {
|
||||
return m.Value
|
||||
}
|
||||
|
||||
func (m *Message) GetGasLimit() uint64 {
|
||||
return m.GasLimit
|
||||
}
|
||||
|
||||
func (m *Message) GetGasPrice() *big.Int {
|
||||
return m.GasPrice
|
||||
}
|
||||
|
||||
func (m *Message) GetGasFeeCap() *big.Int {
|
||||
return m.GasFeeCap
|
||||
}
|
||||
|
||||
func (m *Message) GetGasTipCap() *big.Int {
|
||||
return m.GasTipCap
|
||||
}
|
||||
|
||||
func (m *Message) GetData() []byte {
|
||||
return m.Data
|
||||
}
|
||||
|
||||
func (m *Message) GetAccessList() types.AccessList {
|
||||
return m.AccessList
|
||||
}
|
||||
|
||||
func (m *Message) GetBlobGasFeeCap() *big.Int {
|
||||
return m.BlobGasFeeCap
|
||||
}
|
||||
|
||||
func (m *Message) GetBlobHashes() []common.Hash {
|
||||
return m.BlobHashes
|
||||
}
|
||||
|
||||
func (m *Message) GetSkipAccountChecks() bool {
|
||||
return m.SkipAccountChecks
|
||||
}
|
||||
|
||||
// <specular modification/>
|
||||
|
||||
// TransactionToMessage converts a transaction into a Message.
|
||||
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) {
|
||||
msg := &Message{
|
||||
|
|
@ -389,6 +448,15 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
}
|
||||
st.gasRemaining -= gas
|
||||
|
||||
// <specular modification>
|
||||
if st.evm.Config.SpecularEVMPreTransferHook != nil {
|
||||
err = st.evm.Config.SpecularEVMPreTransferHook(st.msg, st.evm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// <specular modification/>
|
||||
|
||||
// Check clause 6
|
||||
if msg.Value.Sign() > 0 && !st.evm.Context.CanTransfer(st.state, msg.From, msg.Value) {
|
||||
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex())
|
||||
|
|
|
|||
|
|
@ -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/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
|
@ -78,6 +79,17 @@ type StateDB interface {
|
|||
|
||||
AddLog(*types.Log)
|
||||
AddPreimage(common.Hash, []byte)
|
||||
|
||||
// <specular modification>
|
||||
Copy() *state.StateDB
|
||||
GetCurrentLogs() []*types.Log
|
||||
GetCurrentAccessListForProof() (map[common.Address]int, []map[common.Hash]struct{})
|
||||
GetStateRootForProof(common.Address) common.Hash
|
||||
GetRootForProof() common.Hash
|
||||
GetStorageRoot(addr common.Address) common.Hash
|
||||
CommitForProof()
|
||||
DeleteSuicidedAccountForProof(addr common.Address)
|
||||
// <specular modification/>
|
||||
}
|
||||
|
||||
// CallContext provides a basic interface for the EVM calling conventions. The EVM
|
||||
|
|
|
|||
|
|
@ -17,18 +17,46 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
// <specular modification>
|
||||
type MessageInterface interface {
|
||||
GetTo() *common.Address
|
||||
GetFrom() common.Address
|
||||
GetNonce() uint64
|
||||
GetValue() *big.Int
|
||||
GetGasLimit() uint64
|
||||
GetGasPrice() *big.Int
|
||||
GetGasFeeCap() *big.Int
|
||||
GetGasTipCap() *big.Int
|
||||
GetData() []byte
|
||||
GetAccessList() types.AccessList
|
||||
GetBlobGasFeeCap() *big.Int
|
||||
GetBlobHashes() []common.Hash
|
||||
GetSkipAccountChecks() bool
|
||||
}
|
||||
|
||||
type EVMHook func(msg MessageInterface, evm *EVM) error
|
||||
|
||||
// <specular modification/>
|
||||
|
||||
// Config are the configuration options for the Interpreter
|
||||
type Config struct {
|
||||
Tracer EVMLogger // Opcode logger
|
||||
NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
|
||||
EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages
|
||||
ExtraEips []int // Additional EIPS that are to be enabled
|
||||
|
||||
// <specular modification>
|
||||
SpecularEVMPreTransferHook EVMHook
|
||||
// <specular modification/>
|
||||
}
|
||||
|
||||
// ScopeContext contains the things that are per-call, such as stack and memory,
|
||||
|
|
|
|||
Loading…
Reference in a new issue