Skip to content

Commit

Permalink
Remove exchange rate calculation for non CELO denominated txs in stat…
Browse files Browse the repository at this point in the history
…e_transition
  • Loading branch information
hbandura committed Apr 16, 2024
1 parent 6c57fae commit 876d6c8
Showing 1 changed file with 26 additions and 25 deletions.
51 changes: 26 additions & 25 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,12 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool, vmRunner vm.EVMRunner, sysCtx *SysContractCallCtx) *StateTransition {
var gasPriceMinimum *big.Int
if evm.ChainConfig().IsEspresso(evm.Context.BlockNumber) {
var feeCurrency *common.Address = msg.FeeCurrency()
if msg.MaxFeeInFeeCurrency() != nil {
// Celo denominated tx
feeCurrency = nil
gasPriceMinimum = sysCtx.GetGasPriceMinimum(nil)
} else {
gasPriceMinimum = sysCtx.GetGasPriceMinimum(msg.FeeCurrency())
}
gasPriceMinimum = sysCtx.GetGasPriceMinimum(feeCurrency)
} else {
gasPriceMinimum, _ = gpm.GetBaseFeeForCurrency(vmRunner, msg.FeeCurrency(), nil)
}
Expand Down Expand Up @@ -264,7 +264,7 @@ func (st *StateTransition) to() common.Address {
}

// payFees deducts gas and gateway fees from sender balance and adds the purchased amount of gas to the state.
func (st *StateTransition) payFees(espresso bool, feeCurrencyRate *currency.ExchangeRate) error {
func (st *StateTransition) payFees(espresso bool, denominatedCurrencyRate *currency.ExchangeRate) error {
var isWhiteListed bool
if espresso {
isWhiteListed = st.sysCtx.IsWhitelisted(st.msg.FeeCurrency())
Expand All @@ -275,7 +275,7 @@ func (st *StateTransition) payFees(espresso bool, feeCurrencyRate *currency.Exch
log.Trace("Fee currency not whitelisted", "fee currency address", st.msg.FeeCurrency())
return ErrNonWhitelistedFeeCurrency
}
if err := st.canPayFee(st.msg.From(), st.msg.FeeCurrency(), espresso, feeCurrencyRate); err != nil {
if err := st.canPayFee(st.msg.From(), st.msg.FeeCurrency(), espresso, denominatedCurrencyRate); err != nil {
return err
}
if err := st.gp.SubGas(st.msg.Gas()); err != nil {
Expand All @@ -284,7 +284,7 @@ func (st *StateTransition) payFees(espresso bool, feeCurrencyRate *currency.Exch

st.initialGas = st.msg.Gas()
st.gas += st.msg.Gas()
err := st.debitFee(st.msg.From(), st.msg.FeeCurrency(), feeCurrencyRate)
err := st.debitFee(st.msg.From(), st.msg.FeeCurrency(), denominatedCurrencyRate)
return err
}

Expand All @@ -297,7 +297,7 @@ func (st *StateTransition) payFees(espresso bool, feeCurrencyRate *currency.Exch
// For non-native tokens(cUSD, cEUR, ...) as feeCurrency:
// - Pre-Espresso: it ensures balance > GasPrice * gas + gatewayFee (3)
// - Post-Espresso: it ensures balance >= GasFeeCap * gas + gatewayFee (4)
func (st *StateTransition) canPayFee(accountOwner common.Address, feeCurrency *common.Address, espresso bool, feeCurrencyRate *currency.ExchangeRate) error {
func (st *StateTransition) canPayFee(accountOwner common.Address, feeCurrency *common.Address, espresso bool, denominatedCurrencyRate *currency.ExchangeRate) error {
if feeCurrency == nil {
balance := st.state.GetBalance(st.msg.From())
if espresso {
Expand Down Expand Up @@ -340,7 +340,7 @@ func (st *StateTransition) canPayFee(accountOwner common.Address, feeCurrency *c
if st.msg.MaxFeeInFeeCurrency() != nil {
// Celo Denominated Tx: max fee is a tx field
// Translate fees to feeCurrency
feeGap = feeCurrencyRate.FromBase(feeGap)
feeGap = denominatedCurrencyRate.FromBase(feeGap)
// Check that fee <= MaxFeeInFeeCurrency
if feeGap.Cmp(st.msg.MaxFeeInFeeCurrency()) > 0 {
return ErrDenominatedLowMaxFee
Expand All @@ -363,7 +363,7 @@ func (st *StateTransition) canPayFee(accountOwner common.Address, feeCurrency *c
return nil
}

func (st *StateTransition) debitFee(from common.Address, feeCurrency *common.Address, feeCurrencyRate *currency.ExchangeRate) (err error) {
func (st *StateTransition) debitFee(from common.Address, feeCurrency *common.Address, denominatedCurrencyRate *currency.ExchangeRate) (err error) {
if st.evm.Config.SkipDebitCredit {
return nil
}
Expand All @@ -378,16 +378,12 @@ func (st *StateTransition) debitFee(from common.Address, feeCurrency *common.Add
st.state.SubBalance(from, effectiveFee)
return nil
} else {
var currencyFee *big.Int
if st.msg.MaxFeeInFeeCurrency() == nil {
// Normal feeCurrency tx
currencyFee = effectiveFee
if st.msg.MaxFeeInFeeCurrency() != nil {
st.erc20FeeDebited = denominatedCurrencyRate.FromBase(effectiveFee)
} else {
// Celo denominated tx
currencyFee = feeCurrencyRate.FromBase(effectiveFee)
st.erc20FeeDebited = effectiveFee
}
st.erc20FeeDebited = currencyFee
return erc20gas.DebitFees(st.evm, from, currencyFee, feeCurrency)
return erc20gas.DebitFees(st.evm, from, st.erc20FeeDebited, feeCurrency)
}
}

Expand Down Expand Up @@ -482,9 +478,14 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
if st.msg.FeeCurrency() == nil && st.msg.MaxFeeInFeeCurrency() != nil {
return nil, ErrDenominatedNoCurrency
}
feeCurrencyRate, err := currency.GetExchangeRate(st.vmRunner, st.msg.FeeCurrency())
if err != nil {
return nil, err
var denominatedCurrencyRate *currency.ExchangeRate
// Get rate only for CELO denominated txs (H fork)
if st.msg.MaxFeeInFeeCurrency() != nil {
var err error
denominatedCurrencyRate, err = currency.GetExchangeRate(st.vmRunner, st.msg.FeeCurrency())
if err != nil {
return nil, err
}
}

// Check clauses 1-2
Expand Down Expand Up @@ -517,7 +518,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.msg.Gas(), gas)
}
// Check clauses 3-4, pay the fees (which buys gas), and subtract the intrinsic gas
err = st.payFees(espresso, feeCurrencyRate)
err = st.payFees(espresso, denominatedCurrencyRate)
if err != nil {
log.Error("Transaction failed to buy gas", "err", err, "gas", gas)
return nil, err
Expand Down Expand Up @@ -553,7 +554,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
st.refundGas(params.RefundQuotientEIP3529)
}

err = st.creditTxFees(feeCurrencyRate)
err = st.creditTxFees(denominatedCurrencyRate)
if err != nil {
return nil, err
}
Expand All @@ -565,7 +566,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
}

// creditTxFees calculates the amounts and recipients of transaction fees and credits the accounts.
func (st *StateTransition) creditTxFees(feeCurrencyRate *currency.ExchangeRate) error {
func (st *StateTransition) creditTxFees(denominatedCurrencyRate *currency.ExchangeRate) error {
if st.evm.Config.SkipDebitCredit {
return nil
}
Expand Down Expand Up @@ -596,8 +597,8 @@ func (st *StateTransition) creditTxFees(feeCurrencyRate *currency.ExchangeRate)
// conversions have limited accuracy, the only way to achieve this
// is to calculate one of the three credit values based on the two
// others after the exchange rate conversion.
tipTxFee = feeCurrencyRate.FromBase(tipTxFee)
baseTxFee = feeCurrencyRate.FromBase(baseTxFee)
tipTxFee = denominatedCurrencyRate.FromBase(tipTxFee)
baseTxFee = denominatedCurrencyRate.FromBase(baseTxFee)
totalTxFee.Add(tipTxFee, baseTxFee)
refund.Sub(st.erc20FeeDebited, totalTxFee) // refund = debited - tip - basefee
// No need to exchange gateway fee since it's it's deprecated on G fork,
Expand Down

0 comments on commit 876d6c8

Please sign in to comment.