|
|
|
|
@@ -10,6 +10,7 @@ import (
|
|
|
|
|
"github.com/ethereum/go-ethereum"
|
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
|
|
|
"github.com/ethereum/go-ethereum/rpc"
|
|
|
|
|
"github.com/shopspring/decimal"
|
|
|
|
|
@@ -296,7 +297,7 @@ func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network,
|
|
|
|
|
GasPrice: gasPrice,
|
|
|
|
|
Value: amountBase,
|
|
|
|
|
}
|
|
|
|
|
gasLimit, err := client.EstimateGas(timeoutCtx, callMsg)
|
|
|
|
|
gasLimit, err := estimateGas(timeoutCtx, network, client, rpcClient, callMsg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Warn("Failed to estimate gas", zap.Error(err), zap.Any("call_mesasge", callMsg))
|
|
|
|
|
return nil, merrors.Internal("failed to estimate gas: " + err.Error())
|
|
|
|
|
@@ -344,7 +345,7 @@ func EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network,
|
|
|
|
|
GasPrice: gasPrice,
|
|
|
|
|
Data: input,
|
|
|
|
|
}
|
|
|
|
|
gasLimit, err := client.EstimateGas(timeoutCtx, callMsg)
|
|
|
|
|
gasLimit, err := estimateGas(timeoutCtx, network, client, rpcClient, callMsg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Warn("Failed to estimate gas", zap.Error(err), zap.Any("call_message", callMsg))
|
|
|
|
|
return nil, merrors.Internal("failed to estimate gas: " + err.Error())
|
|
|
|
|
@@ -457,7 +458,7 @@ func SubmitTransfer(ctx context.Context, deps driver.Deps, network shared.Networ
|
|
|
|
|
GasPrice: gasPrice,
|
|
|
|
|
Value: amountInt,
|
|
|
|
|
}
|
|
|
|
|
gasLimit, err := client.EstimateGas(ctx, callMsg)
|
|
|
|
|
gasLimit, err := estimateGas(ctx, network, client, rpcClient, callMsg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Warn("Failed to estimate gas", zap.Error(err),
|
|
|
|
|
zap.String("transfer_ref", transfer.TransferRef),
|
|
|
|
|
@@ -507,7 +508,7 @@ func SubmitTransfer(ctx context.Context, deps driver.Deps, network shared.Networ
|
|
|
|
|
GasPrice: gasPrice,
|
|
|
|
|
Data: input,
|
|
|
|
|
}
|
|
|
|
|
gasLimit, err := client.EstimateGas(ctx, callMsg)
|
|
|
|
|
gasLimit, err := estimateGas(ctx, network, client, rpcClient, callMsg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Warn("Failed to estimate gas", zap.Error(err),
|
|
|
|
|
zap.String("transfer_ref", transfer.TransferRef),
|
|
|
|
|
@@ -661,6 +662,63 @@ func erc20Decimals(ctx context.Context, client *rpc.Client, token common.Address
|
|
|
|
|
return val, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type gasEstimator interface {
|
|
|
|
|
EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func estimateGas(ctx context.Context, network shared.Network, client gasEstimator, rpcClient *rpc.Client, callMsg ethereum.CallMsg) (uint64, error) {
|
|
|
|
|
if isTronNetwork(network) {
|
|
|
|
|
if rpcClient == nil {
|
|
|
|
|
return 0, merrors.Internal("rpc client not initialised")
|
|
|
|
|
}
|
|
|
|
|
return estimateGasTron(ctx, rpcClient, callMsg)
|
|
|
|
|
}
|
|
|
|
|
return client.EstimateGas(ctx, callMsg)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func estimateGasTron(ctx context.Context, rpcClient *rpc.Client, callMsg ethereum.CallMsg) (uint64, error) {
|
|
|
|
|
call := tronEstimateCall(callMsg)
|
|
|
|
|
var hexResp string
|
|
|
|
|
if err := rpcClient.CallContext(ctx, &hexResp, "eth_estimateGas", call); err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
val, err := shared.DecodeHexBig(hexResp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
if val == nil {
|
|
|
|
|
return 0, merrors.Internal("failed to decode gas estimate")
|
|
|
|
|
}
|
|
|
|
|
return val.Uint64(), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func tronEstimateCall(callMsg ethereum.CallMsg) map[string]string {
|
|
|
|
|
call := make(map[string]string)
|
|
|
|
|
if callMsg.From != (common.Address{}) {
|
|
|
|
|
call["from"] = strings.ToLower(callMsg.From.Hex())
|
|
|
|
|
}
|
|
|
|
|
if callMsg.To != nil {
|
|
|
|
|
call["to"] = strings.ToLower(callMsg.To.Hex())
|
|
|
|
|
}
|
|
|
|
|
if callMsg.Gas > 0 {
|
|
|
|
|
call["gas"] = hexutil.EncodeUint64(callMsg.Gas)
|
|
|
|
|
}
|
|
|
|
|
if callMsg.GasPrice != nil {
|
|
|
|
|
call["gasPrice"] = hexutil.EncodeBig(callMsg.GasPrice)
|
|
|
|
|
}
|
|
|
|
|
if callMsg.Value != nil {
|
|
|
|
|
call["value"] = hexutil.EncodeBig(callMsg.Value)
|
|
|
|
|
}
|
|
|
|
|
if len(callMsg.Data) > 0 {
|
|
|
|
|
call["data"] = hexutil.Encode(callMsg.Data)
|
|
|
|
|
}
|
|
|
|
|
return call
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func isTronNetwork(network shared.Network) bool {
|
|
|
|
|
return strings.HasPrefix(strings.ToLower(strings.TrimSpace(network.Name)), "tron")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func toBaseUnits(amount string, decimals uint8) (*big.Int, error) {
|
|
|
|
|
value, err := decimal.NewFromString(strings.TrimSpace(amount))
|
|
|
|
|
if err != nil {
|
|
|
|
|
|