66 "math/big"
77 "time"
88
9+ storetypes "github.com/cosmos/cosmos-sdk/store/types"
10+
911 "github.com/cosmos/cosmos-sdk/codec"
1012 sdk "github.com/cosmos/cosmos-sdk/types"
1113 icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"
@@ -21,13 +23,17 @@ import (
2123 "github.com/ethereum/go-ethereum/core/vm"
2224)
2325
24- // TODO: Replace this const with adjusted gas cost corresponding to input when executing precompile contract.
25- const ICAContractRequiredGas = 10000
26+ const (
27+ RegisterAccountMethodName = "registerAccount"
28+ QueryAccountMethodName = "queryAccount"
29+ SubmitMsgsMethodName = "submitMsgs"
30+ )
2631
2732var (
28- icaABI abi.ABI
29- icaCallbackABI abi.ABI
30- icaContractAddress = common .BytesToAddress ([]byte {102 })
33+ icaABI abi.ABI
34+ icaCallbackABI abi.ABI
35+ icaContractAddress = common .BytesToAddress ([]byte {102 })
36+ icaGasRequiredByMethod = map [[4 ]byte ]uint64 {}
3137)
3238
3339func init () {
@@ -37,6 +43,21 @@ func init() {
3743 if err := icaCallbackABI .UnmarshalJSON ([]byte (icacallback .ICACallbackMetaData .ABI )); err != nil {
3844 panic (err )
3945 }
46+
47+ for methodName := range icaABI .Methods {
48+ var methodID [4 ]byte
49+ copy (methodID [:], icaABI .Methods [methodName ].ID [:4 ])
50+ switch methodName {
51+ case RegisterAccountMethodName :
52+ icaGasRequiredByMethod [methodID ] = 300000
53+ case QueryAccountMethodName :
54+ icaGasRequiredByMethod [methodID ] = 100000
55+ case SubmitMsgsMethodName :
56+ icaGasRequiredByMethod [methodID ] = 300000
57+ default :
58+ icaGasRequiredByMethod [methodID ] = 0
59+ }
60+ }
4061}
4162
4263func OnPacketResultCallback (args ... interface {}) ([]byte , error ) {
@@ -49,14 +70,16 @@ type IcaContract struct {
4970 cdc codec.Codec
5071 icaauthKeeper types.Icaauthkeeper
5172 cronosKeeper types.CronosKeeper
73+ kvGasConfig storetypes.GasConfig
5274}
5375
54- func NewIcaContract (icaauthKeeper types.Icaauthkeeper , cronosKeeper types.CronosKeeper , cdc codec.Codec ) vm.PrecompiledContract {
76+ func NewIcaContract (icaauthKeeper types.Icaauthkeeper , cronosKeeper types.CronosKeeper , cdc codec.Codec , kvGasConfig storetypes. GasConfig ) vm.PrecompiledContract {
5577 return & IcaContract {
5678 BaseContract : NewBaseContract (icaContractAddress ),
5779 cdc : cdc ,
5880 icaauthKeeper : icaauthKeeper ,
5981 cronosKeeper : cronosKeeper ,
82+ kvGasConfig : kvGasConfig ,
6083 }
6184}
6285
@@ -66,7 +89,15 @@ func (ic *IcaContract) Address() common.Address {
6689
6790// RequiredGas calculates the contract gas use
6891func (ic * IcaContract ) RequiredGas (input []byte ) uint64 {
69- return ICAContractRequiredGas
92+ // base cost to prevent large input size
93+ baseCost := uint64 (len (input )) * ic .kvGasConfig .WriteCostPerByte
94+ var methodID [4 ]byte
95+ copy (methodID [:], input [:4 ])
96+ requiredGas , ok := icaGasRequiredByMethod [methodID ]
97+ if ok {
98+ return requiredGas + baseCost
99+ }
100+ return baseCost
70101}
71102
72103func (ic * IcaContract ) IsStateful () bool {
@@ -87,7 +118,7 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([
87118 converter := cronosevents .IcaConvertEvent
88119 var execErr error
89120 switch method .Name {
90- case "registerAccount" :
121+ case RegisterAccountMethodName :
91122 if readonly {
92123 return nil , errors .New ("the method is not readonly" )
93124 }
@@ -109,7 +140,7 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([
109140 return nil , execErr
110141 }
111142 return method .Outputs .Pack (true )
112- case "queryAccount" :
143+ case QueryAccountMethodName :
113144 args , err := method .Inputs .Unpack (contract .Input [4 :])
114145 if err != nil {
115146 return nil , errors .New ("fail to unpack input arguments" )
@@ -131,7 +162,7 @@ func (ic *IcaContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([
131162 icaAddress = response .InterchainAccountAddress
132163 }
133164 return method .Outputs .Pack (icaAddress )
134- case "submitMsgs" :
165+ case SubmitMsgsMethodName :
135166 if readonly {
136167 return nil , errors .New ("the method is not readonly" )
137168 }
0 commit comments