Skip to content

Commit 272982c

Browse files
Unheilbarreductionista
authored andcommitted
add GetEstimateFee (#17751)
* add GetEstimateFee * add todo * add GetEstimateFee to CW * implement EstimateFee for CW * bump common * bump solana * add comment * update common * bump solana * bump solana * bump deps * bump dep * update solana ref * update ref
1 parent e6ac85d commit 272982c

2 files changed

Lines changed: 127 additions & 0 deletions

File tree

core/capabilities/targets/mocks/contract_writer.go

Lines changed: 62 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/services/relay/evm/chain_writer.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"math/big"
77
"strings"
88

9+
"github.com/ethereum/go-ethereum"
910
"github.com/ethereum/go-ethereum/accounts/abi"
1011
"github.com/ethereum/go-ethereum/common"
1112

@@ -216,6 +217,70 @@ func (w *chainWriter) GetFeeComponents(ctx context.Context) (*commontypes.ChainF
216217
}, nil
217218
}
218219

220+
// GetEstimateFee returns total cost of TX execution in the underlying chain's currency.
221+
// The value (val) is included in the fee calculation.
222+
func (w *chainWriter) GetEstimateFee(ctx context.Context, contract, method string, args any, toAddress string, meta *commontypes.TxMeta, val *big.Int) (commontypes.EstimateFee, error) {
223+
calldata, err := w.encoder.Encode(ctx, args, codec.WrapItemType(contract, method, true))
224+
if err != nil {
225+
return commontypes.EstimateFee{}, fmt.Errorf("%w: failed to encode args", err)
226+
}
227+
228+
to := common.HexToAddress(toAddress)
229+
var v assets.Eth
230+
if val != nil {
231+
v = assets.Eth(*val)
232+
}
233+
234+
contractConfig, ok := w.contracts[contract]
235+
if !ok {
236+
return commontypes.EstimateFee{}, fmt.Errorf("contract config not found: %v", contract)
237+
}
238+
239+
methodConfig, ok := contractConfig.Configs[method]
240+
if !ok {
241+
return commontypes.EstimateFee{}, fmt.Errorf("method config not found: %v", method)
242+
}
243+
244+
gasLimit := methodConfig.GasLimit
245+
if meta != nil && meta.GasLimit != nil {
246+
gasLimit = meta.GasLimit.Uint64()
247+
}
248+
249+
from := common.Address{}
250+
cost, err := w.getMaxCost(ctx, v, calldata, gasLimit, w.maxGasPrice, &from, &to)
251+
if err != nil {
252+
return commontypes.EstimateFee{}, err
253+
}
254+
255+
return commontypes.EstimateFee{
256+
Fee: cost,
257+
Decimals: 18,
258+
}, nil
259+
}
260+
261+
func (w *chainWriter) getMaxCost(ctx context.Context, amount assets.Eth, calldata []byte,
262+
gasLimit uint64, maxGasPrice *assets.Wei, fromAddress, toAddress *common.Address) (*big.Int, error) {
263+
fee, err := w.GetFeeComponents(ctx)
264+
var gasPrice *big.Int
265+
if err != nil {
266+
w.logger.Warnf("%w: GetFeeComponents failed; use maxFeePrice instead", err)
267+
gasPrice = fee.ExecutionFee
268+
} else {
269+
gasPrice = (*big.Int)(maxGasPrice)
270+
}
271+
272+
estimateGas, err := w.client.EstimateGas(ctx, ethereum.CallMsg{To: toAddress, Data: calldata})
273+
if err != nil {
274+
w.logger.Warnf("%w: EstimateGas failed; use gasLimit instead", err)
275+
estimateGas = gasLimit
276+
}
277+
278+
totalFee := new(big.Int).Mul(gasPrice, big.NewInt(int64(estimateGas)))
279+
amountWithFees := new(big.Int).Add(amount.ToInt(), totalFee)
280+
281+
return amountWithFees, nil
282+
}
283+
219284
func (w *chainWriter) Close() error {
220285
return w.StopOnce(w.Name(), func() error {
221286
return nil

0 commit comments

Comments
 (0)