Skip to content

Commit

Permalink
Make transaction-args CIP-64/66 compatible
Browse files Browse the repository at this point in the history
  • Loading branch information
ezdac committed May 14, 2024
1 parent 8252069 commit 3fc30ba
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 9 deletions.
2 changes: 1 addition & 1 deletion eth/tracers/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
config.BlockOverrides.Apply(&vmctx)
}
// Execute the trace
msg, err := args.ToMessage(api.backend.RPCGasCap(), block.BaseFee())
msg, err := args.ToMessage(api.backend.RPCGasCap(), block.BaseFee(), vmctx.ExchangeRates)
if err != nil {
return nil, err
}
Expand Down
24 changes: 19 additions & 5 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ import (
"github.com/ethereum/go-ethereum/trie"
)

var emptyExchangeRates = make(common.ExchangeRates)

// EthereumAPI provides an API to access Ethereum related information.
type EthereumAPI struct {
b Backend
Expand Down Expand Up @@ -1161,14 +1163,14 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S
defer cancel()

// Get a new instance of the EVM.
msg, err := args.ToMessage(globalGasCap, header.BaseFee)
if err != nil {
return nil, err
}
blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil, b.ChainConfig(), state)
if blockOverrides != nil {
blockOverrides.Apply(&blockCtx)
}
msg, err := args.ToMessage(globalGasCap, header.BaseFee, blockCtx.ExchangeRates)
if err != nil {
return nil, err
}
evm, vmError := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}, &blockCtx)

// Wait for the context to be done and cancel the evm. Even if the
Expand Down Expand Up @@ -1821,7 +1823,19 @@ func AccessList(ctx context.Context, b CeloBackend, blockNrOrHash rpc.BlockNumbe
statedb := db.Copy()
// Set the accesslist to the last al
args.AccessList = &accessList
msg, err := args.ToMessage(b.RPCGasCap(), header.BaseFee)
baseFee := header.BaseFee

exchangeRates := emptyExchangeRates
if args.FeeCurrency != nil {
// Always use the header's parent here, since we want to create the list at the
// queried block, but want to use the exchange rates before (at the beginning of)
// the queried block
exchangeRates, err = b.GetExchangeRates(ctx, header.ParentHash)
if err != nil {
return nil, 0, nil, fmt.Errorf("get exchange rates for block: %v err: %w", header.Hash(), err)
}
}
msg, err := args.ToMessage(b.RPCGasCap(), baseFee, exchangeRates)
if err != nil {
return nil, 0, nil, err
}
Expand Down
57 changes: 54 additions & 3 deletions internal/ethapi/transaction_args.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/exchange"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
Expand Down Expand Up @@ -60,8 +61,12 @@ type TransactionArgs struct {
BlobFeeCap *hexutil.Big `json:"maxFeePerBlobGas"`
BlobHashes []common.Hash `json:"blobVersionedHashes,omitempty"`

// Celo specific (CIP-64)
// Celo specific

// CIP-64, CIP-66
FeeCurrency *common.Address `json:"feeCurrency,omitempty"`
// CIP-66
MaxFeeInFeeCurrency *hexutil.Big `json:"maxFeeInFeeCurrency,omitempty"`
}

// from retrieves the transaction sender address.
Expand Down Expand Up @@ -124,6 +129,9 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b CeloBackend) err
Value: args.Value,
Data: (*hexutil.Bytes)(&data),
AccessList: args.AccessList,

FeeCurrency: args.FeeCurrency,
MaxFeeInFeeCurrency: args.MaxFeeInFeeCurrency,
}
latestBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
estimated, err := DoEstimateGas(ctx, b, callArgs, latestBlockNr, nil, b.RPCGasCap())
Expand Down Expand Up @@ -205,6 +213,12 @@ func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b CeloBackend)
if err != nil {
return err
}
if args.IsFeeCurrencyDenominated() {
price, err = b.ConvertToCurrency(ctx, head.Hash(), price, args.FeeCurrency)
if err != nil {
return fmt.Errorf("can't convert suggested gasTipCap to fee-currency: %w", err)
}
}
args.GasPrice = (*hexutil.Big)(price)
}
return nil
Expand All @@ -216,6 +230,15 @@ func (args *TransactionArgs) setCancunFeeDefaults(ctx context.Context, head *typ
if args.BlobHashes != nil && args.BlobFeeCap == nil {
// ExcessBlobGas must be set for a Cancun block.
blobBaseFee := eip4844.CalcBlobFee(*head.ExcessBlobGas)
if args.IsFeeCurrencyDenominated() {
// wether the blob-fee will be used like that in Cel2 or not,
// at least this keeps it consistent with the rest of the gas-fees
var err error
blobBaseFee, err = b.ConvertToCurrency(ctx, head.Hash(), blobBaseFee, args.FeeCurrency)
if err != nil {
return fmt.Errorf("can't convert blob-fee to fee-currency: %w", err)
}
}
// Set the max fee to be 2 times larger than the previous block's blob base fee.
// The additional slack allows the tx to not become invalidated if the base
// fee is rising.
Expand All @@ -233,16 +256,30 @@ func (args *TransactionArgs) setLondonFeeDefaults(ctx context.Context, head *typ
if err != nil {
return err
}
if args.IsFeeCurrencyDenominated() {
tip, err = b.ConvertToCurrency(ctx, head.Hash(), tip, args.FeeCurrency)
if err != nil {
return fmt.Errorf("can't convert suggested gasTipCap to fee-currency: %w", err)
}
}
args.MaxPriorityFeePerGas = (*hexutil.Big)(tip)
}
// Set maxFeePerGas if it is missing.
if args.MaxFeePerGas == nil {
// Set the max fee to be 2 times larger than the previous block's base fee.
// The additional slack allows the tx to not become invalidated if the base
// fee is rising.
baseFee := head.BaseFee
if args.IsFeeCurrencyDenominated() {
var err error
baseFee, err = b.ConvertToCurrency(ctx, head.Hash(), baseFee, args.FeeCurrency)
if err != nil {
return fmt.Errorf("can't convert base-fee to fee-currency: %w", err)
}
}
val := new(big.Int).Add(
args.MaxPriorityFeePerGas.ToInt(),
new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
new(big.Int).Mul(baseFee, big.NewInt(2)),
)
args.MaxFeePerGas = (*hexutil.Big)(val)
}
Expand All @@ -256,7 +293,7 @@ func (args *TransactionArgs) setLondonFeeDefaults(ctx context.Context, head *typ
// ToMessage converts the transaction arguments to the Message type used by the
// core evm. This method is used in calls and traces that do not require a real
// live transaction.
func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (*core.Message, error) {
func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int, exchangeRates common.ExchangeRates) (*core.Message, error) {
// Reject invalid combinations of pre- and post-1559 fee styles
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
Expand Down Expand Up @@ -308,6 +345,13 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (*
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
gasPrice = new(big.Int)
if gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 {
if args.IsFeeCurrencyDenominated() {
var err error
baseFee, err = exchange.ConvertGoldToCurrency(exchangeRates, args.FeeCurrency, baseFee)
if err != nil {
return nil, err
}
}
gasPrice = math.BigMin(new(big.Int).Add(gasTipCap, baseFee), gasFeeCap)
}
}
Expand Down Expand Up @@ -417,3 +461,10 @@ func (args *TransactionArgs) ToTransaction() *types.Transaction {
func (args *TransactionArgs) IsEIP4844() bool {
return args.BlobHashes != nil || args.BlobFeeCap != nil
}

// IsFeeCurrencyDenominated returns wether the gas-price related
// fields are denominated in a given fee currency or in the native token.
// This effectively is only true for CIP-64 transactions.
func (args *TransactionArgs) IsFeeCurrencyDenominated() bool {
return args.FeeCurrency != nil && args.MaxFeeInFeeCurrency == nil
}

0 comments on commit 3fc30ba

Please sign in to comment.