From eca3d0d62e13cf4bc9cbc7ecb7072cb11ec13d0a Mon Sep 17 00:00:00 2001 From: Stephan D Date: Fri, 26 Dec 2025 00:53:25 +0100 Subject: [PATCH] replaced evm function for tron --- .../gateway/driver/evm/estimate_gas_test.go | 31 +++++++++ .../service/gateway/driver/evm/evm.go | 66 +++++++++++++++++-- 2 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 api/gateway/chain/internal/service/gateway/driver/evm/estimate_gas_test.go diff --git a/api/gateway/chain/internal/service/gateway/driver/evm/estimate_gas_test.go b/api/gateway/chain/internal/service/gateway/driver/evm/estimate_gas_test.go new file mode 100644 index 0000000..ebef980 --- /dev/null +++ b/api/gateway/chain/internal/service/gateway/driver/evm/estimate_gas_test.go @@ -0,0 +1,31 @@ +package evm + +import ( + "math/big" + "strings" + "testing" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestTronEstimateCallUsesData(t *testing.T) { + from := common.HexToAddress("0xfa89b4d534bdeb2713d4ffd893e79d6535fb58f8") + to := common.HexToAddress("0xa614f803b6fd780986a42c78ec9c7f77e6ded13c") + callMsg := ethereum.CallMsg{ + From: from, + To: &to, + GasPrice: big.NewInt(100), + Data: []byte{0xa9, 0x05, 0x9c, 0xbb}, + } + + call := tronEstimateCall(callMsg) + + require.Equal(t, strings.ToLower(from.Hex()), call["from"]) + require.Equal(t, strings.ToLower(to.Hex()), call["to"]) + require.Equal(t, "0x64", call["gasPrice"]) + require.Equal(t, "0xa9059cbb", call["data"]) + _, hasInput := call["input"] + require.False(t, hasInput) +} diff --git a/api/gateway/chain/internal/service/gateway/driver/evm/evm.go b/api/gateway/chain/internal/service/gateway/driver/evm/evm.go index cfa913a..94016c2 100644 --- a/api/gateway/chain/internal/service/gateway/driver/evm/evm.go +++ b/api/gateway/chain/internal/service/gateway/driver/evm/evm.go @@ -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 {