replaced evm function for tron

This commit is contained in:
Stephan D
2025-12-26 00:53:25 +01:00
parent aba743406a
commit eca3d0d62e
2 changed files with 93 additions and 4 deletions

View File

@@ -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)
}

View File

@@ -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 {