Skip to content

Commit

Permalink
refactor: token ratio
Browse files Browse the repository at this point in the history
  • Loading branch information
PinelliaC committed Jul 18, 2024
1 parent efd1e22 commit cff6c61
Showing 1 changed file with 36 additions and 34 deletions.
70 changes: 36 additions & 34 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,22 +294,19 @@ func (st *StateTransition) to() common.Address {
return *st.msg.To
}

func (st *StateTransition) buyGas(metaTxV3 bool) (*big.Int, error) {
func (st *StateTransition) buyGas(metaTxV3 bool) error {
if !metaTxV3 {
if err := st.applyMetaTransaction(); err != nil {
return nil, err
return err
}
}

mgval := new(big.Int).SetUint64(st.msg.GasLimit)
mgval = mgval.Mul(mgval, st.msg.GasPrice)
var l1Cost *big.Int

if st.msg.RunMode == GasEstimationMode || st.msg.RunMode == GasEstimationWithSkipCheckBalanceMode {
st.CalculateRollupGasDataFromMessage()
}
if st.evm.Context.L1CostFunc != nil && st.msg.RunMode != EthcallMode {
l1Cost = st.evm.Context.L1CostFunc(st.evm.Context.BlockNumber.Uint64(), st.evm.Context.Time, st.msg.RollupDataGas, st.msg.IsDepositTx, st.msg.To)
}

balanceCheck := new(big.Int).Set(mgval)
if st.msg.GasFeeCap != nil {
Expand All @@ -322,26 +319,26 @@ func (st *StateTransition) buyGas(metaTxV3 bool) (*big.Int, error) {
pureGasFeeValue := new(big.Int).Sub(balanceCheck, st.msg.Value)
sponsorAmount, selfPayAmount := types.CalculateSponsorPercentAmount(st.msg.MetaTxParams, pureGasFeeValue)
if have, want := st.state.GetBalance(st.msg.MetaTxParams.GasFeeSponsor), sponsorAmount; have.Cmp(want) < 0 {
return nil, fmt.Errorf("%w: gas fee sponsor %v have %v want %v", ErrInsufficientFunds, st.msg.MetaTxParams.GasFeeSponsor.Hex(), have, want)
return fmt.Errorf("%w: gas fee sponsor %v have %v want %v", ErrInsufficientFunds, st.msg.MetaTxParams.GasFeeSponsor.Hex(), have, want)
}
selfPayAmount = new(big.Int).Add(selfPayAmount, st.msg.Value)
if have, want := st.state.GetBalance(st.msg.From), selfPayAmount; have.Cmp(want) < 0 {
return nil, fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
}
if st.msg.MetaTxParams.GasFeeSponsor == st.msg.From {
if have, want := st.state.GetBalance(st.msg.From), pureGasFeeValue; have.Cmp(want) < 0 {
return nil, fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
}
}
} else {
if have, want := st.state.GetBalance(st.msg.From), balanceCheck; have.Cmp(want) < 0 {
return nil, fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
}
}
}

if err := st.gp.SubGas(st.msg.GasLimit); err != nil {
return nil, err
return err
}
st.gasRemaining += st.msg.GasLimit

Expand All @@ -359,7 +356,7 @@ func (st *StateTransition) buyGas(metaTxV3 bool) (*big.Int, error) {
st.state.SubBalance(st.msg.From, mgval)
}
}
return l1Cost, nil
return nil
}

func (st *StateTransition) applyMetaTransaction() error {
Expand All @@ -374,7 +371,7 @@ func (st *StateTransition) applyMetaTransaction() error {
return nil
}

func (st *StateTransition) preCheck(metaTxV3 bool) (*big.Int, error) {
func (st *StateTransition) preCheck(metaTxV3 bool) error {
if st.msg.IsDepositTx {
// No fee fields to check, no nonce to check, and no need to check if EOA (L1 already verified it for us)
// Gas is free, but no refunds!
Expand All @@ -383,35 +380,35 @@ func (st *StateTransition) preCheck(metaTxV3 bool) (*big.Int, error) {
// Don't touch the gas pool for system transactions
if st.msg.IsSystemTx {
if st.evm.ChainConfig().IsOptimismRegolith(st.evm.Context.Time) {
return nil, fmt.Errorf("%w: address %v", ErrSystemTxNotSupported,
return fmt.Errorf("%w: address %v", ErrSystemTxNotSupported,
st.msg.From.Hex())
}
return common.Big0, nil
return nil
}
if err := st.gp.SubGas(st.msg.GasLimit); err != nil {
return nil, err
return err
}
return common.Big0, nil // gas used by deposits may not be used by other txs
return nil // gas used by deposits may not be used by other txs
}
// Only check transactions that are not fake
msg := st.msg
if !msg.SkipAccountChecks {
// Make sure this transaction's nonce is correct.
stNonce := st.state.GetNonce(msg.From)
if msgNonce := msg.Nonce; stNonce < msgNonce {
return nil, fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
msg.From.Hex(), msgNonce, stNonce)
} else if stNonce > msgNonce {
return nil, fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow,
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow,
msg.From.Hex(), msgNonce, stNonce)
} else if stNonce+1 < stNonce {
return nil, fmt.Errorf("%w: address %v, nonce: %d", ErrNonceMax,
return fmt.Errorf("%w: address %v, nonce: %d", ErrNonceMax,
msg.From.Hex(), stNonce)
}
// Make sure the sender is an EOA
codeHash := st.state.GetCodeHash(msg.From)
if codeHash != (common.Hash{}) && codeHash != types.EmptyCodeHash {
return nil, fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
msg.From.Hex(), codeHash)
}
}
Expand All @@ -421,21 +418,21 @@ func (st *StateTransition) preCheck(metaTxV3 bool) (*big.Int, error) {
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
if !st.evm.Config.NoBaseFee || msg.GasFeeCap.BitLen() > 0 || msg.GasTipCap.BitLen() > 0 {
if l := msg.GasFeeCap.BitLen(); l > 256 {
return nil, fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
msg.From.Hex(), l)
}
if l := msg.GasTipCap.BitLen(); l > 256 {
return nil, fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
msg.From.Hex(), l)
}
if msg.GasFeeCap.Cmp(msg.GasTipCap) < 0 {
return nil, fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
msg.From.Hex(), msg.GasTipCap, msg.GasFeeCap)
}
// This will panic if baseFee is nil, but basefee presence is verified
// as part of header validation.
if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
return nil, fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee)
}
}
Expand Down Expand Up @@ -513,7 +510,7 @@ func (st *StateTransition) innerTransitionDb() (*ExecutionResult, error) {

// Check clauses 1-3, buy gas if everything is correct
tokenRatio := st.state.GetState(types.GasOracleAddr, types.TokenRatioSlot).Big().Uint64()
l1Cost, err := st.preCheck(rules.IsMetaTxV3)
err := st.preCheck(rules.IsMetaTxV3)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -552,8 +549,13 @@ func (st *StateTransition) innerTransitionDb() (*ExecutionResult, error) {
}
st.gasRemaining -= gas

var l1Gas uint64
if !st.msg.IsDepositTx && !st.msg.IsSystemTx {
var l1Gas uint64
var l1Cost *big.Int
if st.evm.Context.L1CostFunc != nil && st.msg.RunMode != EthcallMode {
l1Cost = st.evm.Context.L1CostFunc(st.evm.Context.BlockNumber.Uint64(), st.evm.Context.Time, st.msg.RollupDataGas, st.msg.IsDepositTx, st.msg.To)
}

if st.msg.GasPrice.Cmp(common.Big0) > 0 && l1Cost != nil {
l1Gas = new(big.Int).Div(l1Cost, st.msg.GasPrice).Uint64()
}
Expand Down Expand Up @@ -624,7 +626,7 @@ func (st *StateTransition) innerTransitionDb() (*ExecutionResult, error) {
if st.msg.IsDepositTx && rules.IsOptimismRegolith {
// Skip coinbase payments for deposit tx in Regolith
return &ExecutionResult{
UsedGas: st.gasUsed(),
UsedGas: st.gasUsed(tokenRatio),
Err: vmerr,
ReturnData: ret,
}, nil
Expand All @@ -639,23 +641,23 @@ func (st *StateTransition) innerTransitionDb() (*ExecutionResult, error) {
// are 0. This avoids a negative effectiveTip being applied to
// the coinbase when simulating calls.
} else {
fee := new(big.Int).SetUint64(st.gasUsed())
fee := new(big.Int).SetUint64(st.gasUsed(tokenRatio))
fee.Mul(fee, effectiveTip)
st.state.AddBalance(st.evm.Context.Coinbase, fee)
}

// Check that we are post bedrock to enable op-geth to be able to create pseudo pre-bedrock blocks (these are pre-bedrock, but don't follow l2 geth rules)
// Note optimismConfig will not be nil if rules.IsOptimismBedrock is true
if optimismConfig := st.evm.ChainConfig().Optimism; optimismConfig != nil && rules.IsOptimismBedrock {
st.state.AddBalance(params.OptimismBaseFeeRecipient, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.evm.Context.BaseFee))
st.state.AddBalance(params.OptimismBaseFeeRecipient, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed(tokenRatio)), st.evm.Context.BaseFee))
// Can not collect l1 fee here again, all l1 fee has been collected by CoinBase & OptimismBaseFeeRecipient
//if cost := st.evm.Context.L1CostFunc(st.evm.Context.BlockNumber.Uint64(), st.evm.Context.Time, st.msg.RollupDataGas, st.msg.IsDepositTx); cost != nil {
// st.state.AddBalance(params.OptimismL1FeeRecipient, cost)
//}
}

return &ExecutionResult{
UsedGas: st.gasUsed(),
UsedGas: st.gasUsed(tokenRatio),
Err: vmerr,
ReturnData: ret,
}, nil
Expand All @@ -668,7 +670,7 @@ func (st *StateTransition) refundGas(refundQuotient, tokenRatio uint64, rules pa
return
}
// Apply refund counter, capped to a refund quotient
refund := st.gasUsed() / refundQuotient
refund := st.gasUsed(tokenRatio) / refundQuotient
if refund > st.state.GetRefund() {
refund = st.state.GetRefund()
}
Expand Down Expand Up @@ -698,8 +700,8 @@ func (st *StateTransition) refundGas(refundQuotient, tokenRatio uint64, rules pa
}

// gasUsed returns the amount of gas used up by the state transition.
func (st *StateTransition) gasUsed() uint64 {
return st.initialGas - st.gasRemaining
func (st *StateTransition) gasUsed(tokenRatio uint64) uint64 {
return st.initialGas/tokenRatio - st.gasRemaining
}

func (st *StateTransition) mintBVMETH(ethValue *big.Int, rules params.Rules) {
Expand Down

0 comments on commit cff6c61

Please sign in to comment.