Skip to content

Commit

Permalink
Compute ETX fee multiplier according to ETX distance
Browse files Browse the repository at this point in the history
ETXs emitted from a chain must contain a BaseFee that scales according to the
distance the ETX travels, to account for BaseFee differences between chains.
Additionally, emitted ETXs must contain sufficient tip to encourage speedy
processing at the destination, since ETXs are costly to sit in pending status.
  • Loading branch information
wizeguyy committed Jul 18, 2023
1 parent 2013913 commit 2963248
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 8 deletions.
1 change: 1 addition & 0 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ type bigModExp struct {
var (
big0 = big.NewInt(0)
big1 = big.NewInt(1)
big2 = big.NewInt(2)
big3 = big.NewInt(3)
big4 = big.NewInt(4)
big7 = big.NewInt(7)
Expand Down
24 changes: 18 additions & 6 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ func (evm *EVM) CreateETX(toAddr common.Address, fromAddr common.Address, etxGas
return []byte{}, 0, fmt.Errorf("CreateETX error: %s", err.Error())
}

if err := evm.ValidateETXGasPriceAndTip(fromAddr, etxGasPrice, etxGasTip); err != nil {
if err := evm.ValidateETXGasPriceAndTip(fromAddr, toAddr, etxGasPrice, etxGasTip); err != nil {
return []byte{}, 0, err
}

Expand Down Expand Up @@ -559,8 +559,19 @@ func (evm *EVM) CreateETX(toAddr common.Address, fromAddr common.Address, etxGas
return []byte{}, gas - params.ETXGas, nil
}

// Emitted ETXs must include some multiple of BaseFee as miner tip, to
// encourage processing at the destination.
func calcEtxFeeMultiplier(fromAddr, toAddr common.Address) *big.Int {
confirmationCtx := fromAddr.Location().CommonDom(*toAddr.Location()).Context()
multiplier := big.NewInt(common.NumZonesInRegion)
if confirmationCtx == common.PRIME_CTX {
multiplier = big.NewInt(0).Mul(multiplier, big.NewInt(common.NumRegionsInPrime))
}
return multiplier
}

// Validate ETX gas price and tip
func (evm *EVM) ValidateETXGasPriceAndTip(fromAddr common.Address, etxGasPrice *big.Int, etxGasTip *big.Int) error {
func (evm *EVM) ValidateETXGasPriceAndTip(fromAddr, toAddr common.Address, etxGasPrice *big.Int, etxGasTip *big.Int) error {
if l := etxGasPrice.BitLen(); l > 256 {
return fmt.Errorf("max fee per gas higher than 2^256-1: address %v, etxGasPrice bit length: %d",
fromAddr, l)
Expand All @@ -575,15 +586,16 @@ func (evm *EVM) ValidateETXGasPriceAndTip(fromAddr common.Address, etxGasPrice *
}
// This will panic if baseFee is nil, but basefee presence is verified
// as part of header validation.
mulBaseFee := new(big.Int).Mul(evm.Context.BaseFee, big.NewInt(int64(params.ETXBaseFeeMultiplier)))
feeMul := calcEtxFeeMultiplier(fromAddr, toAddr)
mulBaseFee := new(big.Int).Mul(evm.Context.BaseFee, feeMul)
if etxGasPrice.Cmp(mulBaseFee) < 0 {
return fmt.Errorf("etx max fee per gas less than %dx block base fee: address %v, maxFeePerGas: %s baseFee: %s",
params.ETXBaseFeeMultiplier, fromAddr, etxGasPrice, evm.Context.BaseFee)
feeMul, fromAddr, etxGasPrice, evm.Context.BaseFee)
}
mulTip := new(big.Int).Mul(evm.TXGasTip, big.NewInt(int64(params.ETXBaseFeeMultiplier)))
mulTip := new(big.Int).Mul(evm.TXGasTip, feeMul)
if etxGasTip.Cmp(mulTip) < 0 {
return fmt.Errorf("etx miner tip cap less than %dx tx miner tip cap: address %v, etxGasTip: %s txGasTip: %s",
params.ETXBaseFeeMultiplier, fromAddr, etxGasTip, evm.TXGasTip)
feeMul, fromAddr, etxGasTip, evm.TXGasTip)
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ func opETX(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte
return nil, nil
}
// Fail if ETX gas price or tip are not valid
if err := interpreter.evm.ValidateETXGasPriceAndTip(scope.Contract.Caller(), gasFeeCap.ToBig(), gasTipCap.ToBig()); err != nil {
if err := interpreter.evm.ValidateETXGasPriceAndTip(scope.Contract.Caller(), toAddr, gasFeeCap.ToBig(), gasTipCap.ToBig()); err != nil {
temp.Clear()
stack.push(&temp)
fmt.Printf("%x opETX error: %s\n", scope.Contract.self.Address(), err.Error())
Expand Down
1 change: 0 additions & 1 deletion params/protocol_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ const (
LogDataGas uint64 = 8 // Per byte in a LOG* operation's data.
CallStipend uint64 = 2300 // Free gas given at beginning of call.
ETXGas uint64 = 21000 // Per ETX generated by opETX or normal cross-chain transfer.
ETXBaseFeeMultiplier uint64 = 2 // Multiplier for the base fee of ETXs.

Sha3Gas uint64 = 30 // Once per SHA3 operation.
Sha3WordGas uint64 = 6 // Once per word of the SHA3 operation's data.
Expand Down

0 comments on commit 2963248

Please sign in to comment.