diff --git a/packages/evm/jsonrpc/chainbackend.go b/packages/evm/jsonrpc/chainbackend.go index 6c279e1696..7542d76ee6 100644 --- a/packages/evm/jsonrpc/chainbackend.go +++ b/packages/evm/jsonrpc/chainbackend.go @@ -4,7 +4,6 @@ package jsonrpc import ( - "math/big" "time" "github.com/ethereum/go-ethereum" @@ -29,6 +28,5 @@ type ChainBackend interface { ISCLatestState() state.State ISCStateByBlockIndex(blockIndex uint32) (state.State, error) ISCStateByTrieRoot(trieRoot trie.Hash) (state.State, error) - EVMGasPrice() *big.Int BaseToken() *parameters.BaseToken } diff --git a/packages/evm/jsonrpc/evmchain.go b/packages/evm/jsonrpc/evmchain.go index 51f3bb2a73..69ba658a87 100644 --- a/packages/evm/jsonrpc/evmchain.go +++ b/packages/evm/jsonrpc/evmchain.go @@ -404,7 +404,22 @@ func (e *EVMChain) EstimateGas(callMsg ethereum.CallMsg, blockNumberOrHash *rpc. func (e *EVMChain) GasPrice() *big.Int { e.log.Debugf("GasPrice()") - return e.backend.EVMGasPrice() + + iscState := e.backend.ISCLatestState() + governancePartition := subrealm.NewReadOnly(iscState, kv.Key(governance.Contract.Hname().Bytes())) + feePolicy := governance.MustGetGasFeePolicy(governancePartition) + + // convert to wei (18 decimals) + decimalsDifference := 18 - parameters.L1().BaseToken.Decimals + price := big.NewInt(10) + price.Exp(price, new(big.Int).SetUint64(uint64(decimalsDifference)), nil) + + price.Mul(price, new(big.Int).SetUint64(uint64(feePolicy.GasPerToken.B))) + price.Div(price, new(big.Int).SetUint64(uint64(feePolicy.GasPerToken.A))) + price.Mul(price, new(big.Int).SetUint64(uint64(feePolicy.EVMGasRatio.A))) + price.Div(price, new(big.Int).SetUint64(uint64(feePolicy.EVMGasRatio.B))) + + return price } func (e *EVMChain) StorageAt(address common.Address, key common.Hash, blockNumberOrHash *rpc.BlockNumberOrHash) (common.Hash, error) { diff --git a/packages/evm/jsonrpc/waspevmbackend.go b/packages/evm/jsonrpc/waspevmbackend.go index 97edcfe173..28d7af826b 100644 --- a/packages/evm/jsonrpc/waspevmbackend.go +++ b/packages/evm/jsonrpc/waspevmbackend.go @@ -5,7 +5,6 @@ package jsonrpc import ( "fmt" - "math/big" "sync" "time" @@ -26,7 +25,6 @@ import ( "github.com/iotaledger/wasp/packages/trie" "github.com/iotaledger/wasp/packages/util" "github.com/iotaledger/wasp/packages/vm/core/governance" - "github.com/iotaledger/wasp/packages/vm/gas" ) type WaspEVMBackend struct { @@ -120,30 +118,6 @@ func (b *WaspEVMBackend) EVMTraceTransaction( ) } -func (b *WaspEVMBackend) EVMGasPrice() *big.Int { - latestState := b.ISCLatestState() - res, err := chainutil.CallView(latestState, b.chain, governance.Contract.Hname(), governance.ViewGetFeePolicy.Hname(), nil) - if err != nil { - panic(fmt.Sprintf("couldn't call gasFeePolicy view: %s ", err.Error())) - } - feePolicy, err := gas.FeePolicyFromBytes(res.Get(governance.ParamFeePolicyBytes)) - if err != nil { - panic(fmt.Sprintf("couldn't decode fee policy: %s ", err.Error())) - } - - // convert to wei (18 decimals) - decimalsDifference := 18 - parameters.L1().BaseToken.Decimals - price := big.NewInt(10) - price.Exp(price, new(big.Int).SetUint64(uint64(decimalsDifference)), nil) - - price.Mul(price, new(big.Int).SetUint64(uint64(feePolicy.EVMGasRatio.A))) - price.Div(price, new(big.Int).SetUint64(uint64(feePolicy.EVMGasRatio.B))) - price.Mul(price, new(big.Int).SetUint64(uint64(feePolicy.GasPerToken.A))) - price.Div(price, new(big.Int).SetUint64(uint64(feePolicy.GasPerToken.B))) - - return price -} - func (b *WaspEVMBackend) ISCCallView(chainState state.State, scName, funName string, args dict.Dict) (dict.Dict, error) { return chainutil.CallView(chainState, b.chain, isc.Hn(scName), isc.Hn(funName), args) } diff --git a/packages/solo/evm.go b/packages/solo/evm.go index fa0096e01e..d096de106a 100644 --- a/packages/solo/evm.go +++ b/packages/solo/evm.go @@ -3,7 +3,6 @@ package solo import ( "crypto/ecdsa" "fmt" - "math/big" "time" "github.com/ethereum/go-ethereum" @@ -65,10 +64,6 @@ func (b *jsonRPCSoloBackend) EVMTraceTransaction( ) } -func (b *jsonRPCSoloBackend) EVMGasPrice() *big.Int { - return big.NewInt(0) -} - func (b *jsonRPCSoloBackend) ISCCallView(chainState state.State, scName, funName string, args dict.Dict) (dict.Dict, error) { return b.Chain.CallViewAtState(chainState, scName, funName, args) } diff --git a/packages/vm/core/evm/evmtest/evm_test.go b/packages/vm/core/evm/evmtest/evm_test.go index 9c74951ea3..6a0c98b7c7 100644 --- a/packages/vm/core/evm/evmtest/evm_test.go +++ b/packages/vm/core/evm/evmtest/evm_test.go @@ -1776,6 +1776,33 @@ func TestEVMCallViewGas(t *testing.T) { require.NoError(t, err) } +func TestGasPrice(t *testing.T) { + env := initEVM(t) + + price1 := env.evmChain.GasPrice().Uint64() + require.NotZero(t, price1) + + { + feePolicy := env.soloChain.GetGasFeePolicy() + feePolicy.GasPerToken.B *= 2 // 1 gas is paid with 2 tokens + err := env.setFeePolicy(*feePolicy) + require.NoError(t, err) + } + + price2 := env.evmChain.GasPrice().Uint64() + require.EqualValues(t, price1*2, price2) + + { + feePolicy := env.soloChain.GetGasFeePolicy() + feePolicy.EVMGasRatio.A *= 2 // 1 EVM gas unit consumes 2 ISC gas units + err := env.setFeePolicy(*feePolicy) + require.NoError(t, err) + } + + price3 := env.evmChain.GasPrice().Uint64() + require.EqualValues(t, price2*2, price3) +} + func TestTraceTransaction(t *testing.T) { env := initEVM(t) ethKey, ethAddr := env.soloChain.NewEthereumAccountWithL2Funds() diff --git a/packages/vm/core/evm/evmtest/utils_test.go b/packages/vm/core/evm/evmtest/utils_test.go index e9eaf939cb..332ba2daf5 100644 --- a/packages/vm/core/evm/evmtest/utils_test.go +++ b/packages/vm/core/evm/evmtest/utils_test.go @@ -156,7 +156,7 @@ func (e *soloChainEnv) setEVMGasRatio(newGasRatio util.Ratio32, opts ...iscCallO return err } -func (e *soloChainEnv) setFeePolicy(p gas.FeePolicy, opts ...iscCallOptions) error { +func (e *soloChainEnv) setFeePolicy(p gas.FeePolicy, opts ...iscCallOptions) error { //nolint:unparam opt := e.parseISCCallOptions(opts) req := solo.NewCallParams( governance.Contract.Name, governance.FuncSetFeePolicy.Name,