mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
core: extend TxContext to have all data related to TXPARAM* family
This commit is contained in:
parent
c051a69bfb
commit
4e1fc9bc25
5 changed files with 143 additions and 23 deletions
44
core/evm.go
44
core/evm.go
|
|
@ -25,6 +25,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"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/rlp"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
|
|
@ -82,13 +84,55 @@ func NewEVMTxContext(msg *Message) vm.TxContext {
|
|||
Origin: msg.From,
|
||||
GasPrice: new(big.Int).Set(msg.GasPrice),
|
||||
BlobHashes: msg.BlobHashes,
|
||||
|
||||
// EIP-7701 fields
|
||||
TxType: msg.TxType,
|
||||
Nonce: msg.Nonce,
|
||||
Sender: msg.Sender,
|
||||
Deployer: msg.Deployer,
|
||||
Paymaster: msg.Paymaster,
|
||||
SenderExecutionData: msg.Data,
|
||||
SenderExecutionGas: msg.GasLimit,
|
||||
}
|
||||
if msg.BlobGasFeeCap != nil {
|
||||
ctx.BlobFeeCap = new(big.Int).Set(msg.BlobGasFeeCap)
|
||||
}
|
||||
if msg.GasTipCap != nil {
|
||||
ctx.MaxPriorityFeePerGas = new(big.Int).Set(msg.GasTipCap)
|
||||
}
|
||||
if msg.GasFeeCap != nil {
|
||||
ctx.MaxFeePerGas = new(big.Int).Set(msg.GasFeeCap)
|
||||
}
|
||||
|
||||
// Compute AccessListHash
|
||||
if len(msg.AccessList) > 0 {
|
||||
ctx.AccessListHash = rlpHash(msg.AccessList)
|
||||
}
|
||||
|
||||
// Compute AuthorizationListHash
|
||||
if len(msg.SetCodeAuthorizations) > 0 {
|
||||
ctx.AuthorizationListHash = rlpHash(msg.SetCodeAuthorizations)
|
||||
}
|
||||
|
||||
// TxHashForSignature is nil for AA transactions
|
||||
// For non-AA transactions, we leave it nil as we don't have access to the
|
||||
// original transaction here. If needed, this should be set by the caller.
|
||||
if !msg.Abstract {
|
||||
// TODO: compute TxHashForSignature for non-AA transactions if needed
|
||||
}
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
// rlpHash computes the keccak256 hash of the RLP encoding of x.
|
||||
func rlpHash(x interface{}) common.Hash {
|
||||
encoded, err := rlp.EncodeToBytes(x)
|
||||
if err != nil {
|
||||
return common.Hash{}
|
||||
}
|
||||
return crypto.Keccak256Hash(encoded)
|
||||
}
|
||||
|
||||
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
|
||||
func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
|
||||
// Cache will initially contain [refHash.parent],
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ func toWordSize(size uint64) uint64 {
|
|||
// A Message contains the data derived from a single transaction that is relevant to state
|
||||
// processing.
|
||||
type Message struct {
|
||||
TxType uint8
|
||||
To *common.Address
|
||||
From common.Address
|
||||
Nonce uint64
|
||||
|
|
@ -187,6 +188,7 @@ type Message struct {
|
|||
// TransactionToMessage converts a transaction into a Message.
|
||||
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) {
|
||||
msg := &Message{
|
||||
TxType: tx.Type(),
|
||||
Nonce: tx.Nonce(),
|
||||
GasLimit: tx.Gas(),
|
||||
GasPrice: new(big.Int).Set(tx.GasPrice()),
|
||||
|
|
|
|||
|
|
@ -599,82 +599,128 @@ func opAcceptRole(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
|
||||
type paramLoader func(*EVM, uint64) []byte
|
||||
|
||||
// uint64ToBytes32 converts a uint64 to a 32-byte big-endian slice.
|
||||
func uint64ToBytes32(v uint64) []byte {
|
||||
return common.LeftPadBytes(new(uint256.Int).SetUint64(v).Bytes(), 32)
|
||||
}
|
||||
|
||||
func loadType(evm *EVM, id uint64) []byte {
|
||||
// TODO: plumb in type to TxContext
|
||||
return nil
|
||||
return uint64ToBytes32(uint64(evm.TxContext.TxType))
|
||||
}
|
||||
|
||||
func loadNonce(evm *EVM, id uint64) []byte {
|
||||
// TODO: plumb in nonce to TxContext
|
||||
return nil
|
||||
return uint64ToBytes32(evm.TxContext.Nonce)
|
||||
}
|
||||
|
||||
func loadSender(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
return common.LeftPadBytes(evm.TxContext.Origin.Bytes(), 32)
|
||||
}
|
||||
|
||||
func loadSenderValidationData(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
if evm.TxContext.Sender == nil {
|
||||
return nil
|
||||
}
|
||||
return evm.TxContext.Sender.Data
|
||||
}
|
||||
|
||||
func loadDeployer(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
// 0 or 32 bytes: return nil when not set
|
||||
if evm.TxContext.Deployer == nil {
|
||||
return nil
|
||||
}
|
||||
return common.LeftPadBytes(evm.TxContext.Deployer.Target.Bytes(), 32)
|
||||
}
|
||||
|
||||
func loadDeployerData(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
// dynamic, default empty array
|
||||
if evm.TxContext.Deployer == nil {
|
||||
return nil
|
||||
}
|
||||
return evm.TxContext.Deployer.Data
|
||||
}
|
||||
|
||||
func loadPaymaster(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
// 0 or 32 bytes: return nil when not set
|
||||
if evm.TxContext.Paymaster == nil {
|
||||
return nil
|
||||
}
|
||||
return common.LeftPadBytes(evm.TxContext.Paymaster.Target.Bytes(), 32)
|
||||
}
|
||||
|
||||
func loadPaymasterData(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
// dynamic, default empty array
|
||||
if evm.TxContext.Paymaster == nil {
|
||||
return nil
|
||||
}
|
||||
return evm.TxContext.Paymaster.Data
|
||||
}
|
||||
|
||||
func loadSenderExecutionData(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
return evm.TxContext.SenderExecutionData
|
||||
}
|
||||
|
||||
func loadMaxPriorityFeePerGas(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
if evm.TxContext.MaxPriorityFeePerGas == nil {
|
||||
return make([]byte, 32)
|
||||
}
|
||||
return common.LeftPadBytes(evm.TxContext.MaxPriorityFeePerGas.Bytes(), 32)
|
||||
}
|
||||
|
||||
func loadMaxFeePerGas(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
if evm.TxContext.MaxFeePerGas == nil {
|
||||
return make([]byte, 32)
|
||||
}
|
||||
return common.LeftPadBytes(evm.TxContext.MaxFeePerGas.Bytes(), 32)
|
||||
}
|
||||
|
||||
func loadSenderValidationGas(evm *EVM, id uint64) []byte {
|
||||
if evm.TxContext.Sender == nil {
|
||||
return uint64ToBytes32(0)
|
||||
}
|
||||
return uint64ToBytes32(evm.TxContext.Sender.Gas)
|
||||
}
|
||||
|
||||
func loadPaymasterValidationGas(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
// 32 bytes, default 0
|
||||
if evm.TxContext.Paymaster == nil {
|
||||
return uint64ToBytes32(0)
|
||||
}
|
||||
return uint64ToBytes32(evm.TxContext.Paymaster.Gas)
|
||||
}
|
||||
|
||||
func loadSenderExecutionGas(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
return uint64ToBytes32(evm.TxContext.SenderExecutionGas)
|
||||
}
|
||||
|
||||
func loadPaymasterPostOpGas(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
// 32 bytes, default 0
|
||||
if evm.TxContext.Paymaster == nil {
|
||||
return uint64ToBytes32(0)
|
||||
}
|
||||
return uint64ToBytes32(evm.TxContext.Paymaster.PostOpGas)
|
||||
}
|
||||
|
||||
func loadAccessListHash(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
return evm.TxContext.AccessListHash[:]
|
||||
}
|
||||
|
||||
func loadAuthorizationListHash(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
return evm.TxContext.AuthorizationListHash[:]
|
||||
}
|
||||
|
||||
func loadExecutionStatus(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
return uint64ToBytes32(evm.TxContext.ExecutionStatus)
|
||||
}
|
||||
|
||||
func loadExecutionGasUsed(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
return uint64ToBytes32(evm.TxContext.ExecutionGasUsed)
|
||||
}
|
||||
|
||||
func loadTxHashForSignature(evm *EVM, id uint64) []byte {
|
||||
return nil
|
||||
if evm.TxContext.TxHashForSignature == nil {
|
||||
return nil
|
||||
}
|
||||
return evm.TxContext.TxHashForSignature[:]
|
||||
}
|
||||
|
||||
// idToParam is a map of identifier to transaction parameter loader.
|
||||
|
|
@ -690,7 +736,7 @@ var idToParam = map[uint64]paramLoader{
|
|||
0x08: loadSenderExecutionData,
|
||||
0x0B: loadMaxPriorityFeePerGas,
|
||||
0x0C: loadMaxFeePerGas,
|
||||
0x0D: loadSenderValidationData,
|
||||
0x0D: loadSenderValidationGas,
|
||||
0x0E: loadPaymasterValidationGas,
|
||||
0x0F: loadSenderExecutionGas,
|
||||
0x10: loadPaymasterPostOpGas,
|
||||
|
|
|
|||
|
|
@ -80,7 +80,29 @@ type TxContext struct {
|
|||
BlobFeeCap *big.Int // Is used to zero the blobbasefee if NoBaseFee is set
|
||||
AccessEvents *state.AccessEvents // Capture all state accesses for this tx
|
||||
|
||||
// TODO: add EIP-7701 fields
|
||||
// EIP-7701: Transaction parameters for TXPARAM* opcodes
|
||||
TxType uint8 // 0x00: transaction type
|
||||
Nonce uint64 // 0x01: transaction nonce
|
||||
// Origin is sender (0x02)
|
||||
|
||||
// AA authorization structs (nil for non-AA txs)
|
||||
Sender *types.AbstractAuthorization // 0x03: Data, 0x0D: Gas
|
||||
Deployer *types.AbstractAuthorization // 0x04: Target, 0x05: Data
|
||||
Paymaster *types.PaymasterAuthorization // 0x06: Target, 0x07: Data, 0x0E: Gas, 0x10: PostOpGas
|
||||
|
||||
SenderExecutionData []byte // 0x08: execution calldata
|
||||
SenderExecutionGas uint64 // 0x0F: execution gas limit
|
||||
MaxPriorityFeePerGas *big.Int // 0x0B: max priority fee per gas
|
||||
MaxFeePerGas *big.Int // 0x0C: max fee per gas
|
||||
|
||||
// Hashes (computed when creating TxContext)
|
||||
AccessListHash common.Hash // 0x11: hash of access list
|
||||
AuthorizationListHash common.Hash // 0x12: hash of authorization list
|
||||
TxHashForSignature *common.Hash // 0xff: hash for signature (nil for AA txs)
|
||||
|
||||
// Mutable execution state (set during AA tx processing)
|
||||
ExecutionStatus uint64 // 0xf1: execution result status
|
||||
ExecutionGasUsed uint64 // 0xf2: gas used during execution
|
||||
}
|
||||
|
||||
// EVM is the Ethereum Virtual Machine base object and provides
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@ func NewEnv(cfg *Config) *vm.EVM {
|
|||
GasPrice: cfg.GasPrice,
|
||||
BlobHashes: cfg.BlobHashes,
|
||||
BlobFeeCap: cfg.BlobFeeCap,
|
||||
|
||||
// EIP-7701: Set basic fields for non-AA transactions
|
||||
// AA-specific fields (Sender, Deployer, Paymaster) remain nil
|
||||
MaxPriorityFeePerGas: cfg.GasPrice,
|
||||
MaxFeePerGas: cfg.GasPrice,
|
||||
SenderExecutionGas: cfg.GasLimit,
|
||||
}
|
||||
blockContext := vm.BlockContext{
|
||||
CanTransfer: core.CanTransfer,
|
||||
|
|
|
|||
Loading…
Reference in a new issue