Improvements on resolving nonce (#5658)
* chore_: unused `BuildTx` function removed from the processor interface and types that are implement it Since the `BuildTx` function is not used anywhere, it's removed from the code. * fix_: resolving nonce improvements When the app sends more than a single tx from the same account on the same chain, some chains do not return appropriate nonce (they do not consider pending txs), because of that we place more tx with the same nonce, where all but the first one fail. Changes in this PR keep track of nonces being used in the same sending/bridging flow, which means for the first tx from the multi txs the app asks the chain for the nonce, and every next nonce is resolved by incrementing the last used nonce by 1.
This commit is contained in:
parent
74fa567cda
commit
79b1c547d1
|
@ -2228,7 +2228,8 @@ func (b *GethStatusBackend) SendTransaction(sendArgs transactions.SendTxArgs, pa
|
|||
return hash, err
|
||||
}
|
||||
|
||||
return b.transactor.SendTransaction(sendArgs, verifiedAccount)
|
||||
hash, _, err = b.transactor.SendTransaction(sendArgs, verifiedAccount, -1)
|
||||
return hash, err
|
||||
}
|
||||
|
||||
func (b *GethStatusBackend) SendTransactionWithChainID(chainID uint64, sendArgs transactions.SendTxArgs, password string) (hash types.Hash, err error) {
|
||||
|
@ -2237,7 +2238,8 @@ func (b *GethStatusBackend) SendTransactionWithChainID(chainID uint64, sendArgs
|
|||
return hash, err
|
||||
}
|
||||
|
||||
return b.transactor.SendTransactionWithChainID(chainID, sendArgs, verifiedAccount)
|
||||
hash, _, err = b.transactor.SendTransactionWithChainID(chainID, sendArgs, -1, verifiedAccount)
|
||||
return hash, err
|
||||
}
|
||||
|
||||
func (b *GethStatusBackend) SendTransactionWithSignature(sendArgs transactions.SendTxArgs, sig []byte) (hash types.Hash, err error) {
|
||||
|
|
|
@ -388,7 +388,7 @@ func (s *Service) suggestedFeesToSendTxArgs(from common.Address, to *common.Addr
|
|||
}
|
||||
|
||||
func (s *Service) estimateL1Fee(ctx context.Context, chainID uint64, sendArgs transactions.SendTxArgs) (uint64, error) {
|
||||
transaction, err := s.transactor.ValidateAndBuildTransaction(chainID, sendArgs)
|
||||
transaction, _, err := s.transactor.ValidateAndBuildTransaction(chainID, sendArgs, -1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
|
@ -8,10 +8,9 @@ import (
|
|||
big "math/big"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
|
||||
common "github.com/ethereum/go-ethereum/common"
|
||||
types "github.com/ethereum/go-ethereum/core/types"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
account "github.com/status-im/status-go/account"
|
||||
types0 "github.com/status-im/status-go/eth-node/types"
|
||||
pathprocessor "github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
||||
|
@ -56,33 +55,19 @@ func (mr *MockPathProcessorMockRecorder) AvailableFor(params interface{}) *gomoc
|
|||
}
|
||||
|
||||
// BuildTransaction mocks base method.
|
||||
func (m *MockPathProcessor) BuildTransaction(sendArgs *pathprocessor.MultipathProcessorTxArgs) (*types.Transaction, error) {
|
||||
func (m *MockPathProcessor) BuildTransaction(sendArgs *pathprocessor.MultipathProcessorTxArgs, lastUsedNonce int64) (*types.Transaction, uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BuildTransaction", sendArgs)
|
||||
ret := m.ctrl.Call(m, "BuildTransaction", sendArgs, lastUsedNonce)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
ret1, _ := ret[1].(uint64)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// BuildTransaction indicates an expected call of BuildTransaction.
|
||||
func (mr *MockPathProcessorMockRecorder) BuildTransaction(sendArgs interface{}) *gomock.Call {
|
||||
func (mr *MockPathProcessorMockRecorder) BuildTransaction(sendArgs, lastUsedNonce interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildTransaction", reflect.TypeOf((*MockPathProcessor)(nil).BuildTransaction), sendArgs)
|
||||
}
|
||||
|
||||
// BuildTx mocks base method.
|
||||
func (m *MockPathProcessor) BuildTx(params pathprocessor.ProcessorInputParams) (*types.Transaction, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BuildTx", params)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BuildTx indicates an expected call of BuildTx.
|
||||
func (mr *MockPathProcessorMockRecorder) BuildTx(params interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildTx", reflect.TypeOf((*MockPathProcessor)(nil).BuildTx), params)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildTransaction", reflect.TypeOf((*MockPathProcessor)(nil).BuildTransaction), sendArgs, lastUsedNonce)
|
||||
}
|
||||
|
||||
// CalculateAmountOut mocks base method.
|
||||
|
@ -116,18 +101,6 @@ func (mr *MockPathProcessorMockRecorder) CalculateFees(params interface{}) *gomo
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateFees", reflect.TypeOf((*MockPathProcessor)(nil).CalculateFees), params)
|
||||
}
|
||||
|
||||
// Clear mocks base method.
|
||||
func (m *MockPathProcessor) Clear() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Clear")
|
||||
}
|
||||
|
||||
// Clear indicates an expected call of Clear.
|
||||
func (mr *MockPathProcessorMockRecorder) Clear() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clear", reflect.TypeOf((*MockPathProcessor)(nil).Clear))
|
||||
}
|
||||
|
||||
// EstimateGas mocks base method.
|
||||
func (m *MockPathProcessor) EstimateGas(params pathprocessor.ProcessorInputParams) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -188,16 +161,52 @@ func (mr *MockPathProcessorMockRecorder) PackTxInputData(params interface{}) *go
|
|||
}
|
||||
|
||||
// Send mocks base method.
|
||||
func (m *MockPathProcessor) Send(sendArgs *pathprocessor.MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (types0.Hash, error) {
|
||||
func (m *MockPathProcessor) Send(sendArgs *pathprocessor.MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (types0.Hash, uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Send", sendArgs, verifiedAccount)
|
||||
ret := m.ctrl.Call(m, "Send", sendArgs, lastUsedNonce, verifiedAccount)
|
||||
ret0, _ := ret[0].(types0.Hash)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
ret1, _ := ret[1].(uint64)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// Send indicates an expected call of Send.
|
||||
func (mr *MockPathProcessorMockRecorder) Send(sendArgs, verifiedAccount interface{}) *gomock.Call {
|
||||
func (mr *MockPathProcessorMockRecorder) Send(sendArgs, lastUsedNonce, verifiedAccount interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockPathProcessor)(nil).Send), sendArgs, verifiedAccount)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockPathProcessor)(nil).Send), sendArgs, lastUsedNonce, verifiedAccount)
|
||||
}
|
||||
|
||||
// MockPathProcessorClearable is a mock of PathProcessorClearable interface.
|
||||
type MockPathProcessorClearable struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockPathProcessorClearableMockRecorder
|
||||
}
|
||||
|
||||
// MockPathProcessorClearableMockRecorder is the mock recorder for MockPathProcessorClearable.
|
||||
type MockPathProcessorClearableMockRecorder struct {
|
||||
mock *MockPathProcessorClearable
|
||||
}
|
||||
|
||||
// NewMockPathProcessorClearable creates a new mock instance.
|
||||
func NewMockPathProcessorClearable(ctrl *gomock.Controller) *MockPathProcessorClearable {
|
||||
mock := &MockPathProcessorClearable{ctrl: ctrl}
|
||||
mock.recorder = &MockPathProcessorClearableMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockPathProcessorClearable) EXPECT() *MockPathProcessorClearableMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Clear mocks base method.
|
||||
func (m *MockPathProcessorClearable) Clear() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Clear")
|
||||
}
|
||||
|
||||
// Clear indicates an expected call of Clear.
|
||||
func (mr *MockPathProcessorClearableMockRecorder) Clear() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clear", reflect.TypeOf((*MockPathProcessorClearable)(nil).Clear))
|
||||
}
|
||||
|
|
|
@ -25,14 +25,12 @@ type PathProcessor interface {
|
|||
EstimateGas(params ProcessorInputParams) (uint64, error)
|
||||
// CalculateAmountOut calculates the amount out
|
||||
CalculateAmountOut(params ProcessorInputParams) (*big.Int, error)
|
||||
// Send sends the tx
|
||||
Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (types.Hash, error)
|
||||
// Send sends the tx, returns the hash and the used nonce (lastUsedNonce is -1 if it's the first tx)
|
||||
Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (types.Hash, uint64, error)
|
||||
// GetContractAddress returns the contract address
|
||||
GetContractAddress(params ProcessorInputParams) (common.Address, error)
|
||||
// BuildTransaction builds the transaction based on MultipathProcessorTxArgs
|
||||
BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error)
|
||||
// BuildTx builds the transaction based on ProcessorInputParams
|
||||
BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error)
|
||||
// BuildTransaction builds the transaction based on MultipathProcessorTxArgs, returns the transaction and the used nonce (lastUsedNonce is -1 if it's the first tx)
|
||||
BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error)
|
||||
}
|
||||
|
||||
type PathProcessorClearable interface {
|
||||
|
|
|
@ -283,27 +283,6 @@ func (s *CelerBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64,
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *CelerBridgeProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
CbridgeTx: &CelerBridgeTxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
ChainID: params.ToChain.ChainID,
|
||||
Symbol: params.FromToken.Symbol,
|
||||
Recipient: params.ToAddr,
|
||||
Amount: (*hexutil.Big)(params.AmountIn),
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
}
|
||||
|
||||
func (s *CelerBridgeProcessor) GetContractAddress(params ProcessorInputParams) (common.Address, error) {
|
||||
transferConfig, err := s.getTransferConfig(params.FromChain.IsTest)
|
||||
if err != nil {
|
||||
|
@ -322,7 +301,7 @@ func (s *CelerBridgeProcessor) GetContractAddress(params ProcessorInputParams) (
|
|||
return common.Address{}, ErrContractNotFound
|
||||
}
|
||||
|
||||
func (s *CelerBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn) (*ethTypes.Transaction, error) {
|
||||
func (s *CelerBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn, lastUsedNonce int64) (*ethTypes.Transaction, error) {
|
||||
fromChain := s.rpcClient.NetworkManager.Find(sendArgs.ChainID)
|
||||
if fromChain == nil {
|
||||
return nil, ErrNetworkNotFound
|
||||
|
@ -347,6 +326,11 @@ func (s *CelerBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, s
|
|||
return nil, createBridgeCellerErrorResponse(err)
|
||||
}
|
||||
|
||||
if lastUsedNonce >= 0 {
|
||||
lastUsedNonceHexUtil := hexutil.Uint64(uint64(lastUsedNonce) + 1)
|
||||
sendArgs.CbridgeTx.Nonce = &lastUsedNonceHexUtil
|
||||
}
|
||||
|
||||
var tx *ethTypes.Transaction
|
||||
txOpts := sendArgs.CbridgeTx.ToTransactOpts(signerFn)
|
||||
if token.IsNative() {
|
||||
|
@ -379,17 +363,18 @@ func (s *CelerBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, s
|
|||
return tx, nil
|
||||
}
|
||||
|
||||
func (s *CelerBridgeProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (types.Hash, error) {
|
||||
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.CbridgeTx.From, verifiedAccount))
|
||||
func (s *CelerBridgeProcessor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (types.Hash, uint64, error) {
|
||||
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.CbridgeTx.From, verifiedAccount), lastUsedNonce)
|
||||
if err != nil {
|
||||
return types.HexToHash(""), createBridgeCellerErrorResponse(err)
|
||||
return types.HexToHash(""), 0, createBridgeCellerErrorResponse(err)
|
||||
}
|
||||
|
||||
return types.Hash(tx.Hash()), nil
|
||||
return types.Hash(tx.Hash()), tx.Nonce(), nil
|
||||
}
|
||||
|
||||
func (s *CelerBridgeProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
return s.sendOrBuild(sendArgs, nil)
|
||||
func (s *CelerBridgeProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
tx, err := s.sendOrBuild(sendArgs, nil, lastUsedNonce)
|
||||
return tx, tx.Nonce(), err
|
||||
}
|
||||
|
||||
func (s *CelerBridgeProcessor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
|
||||
|
|
|
@ -277,34 +277,12 @@ func (h *HopBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64, e
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (h *HopBridgeProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
HopTx: &HopBridgeTxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
Symbol: params.FromToken.Symbol,
|
||||
Recipient: params.ToAddr,
|
||||
Amount: (*hexutil.Big)(params.AmountIn),
|
||||
BonderFee: (*hexutil.Big)(params.BonderFee),
|
||||
ChainID: params.ToChain.ChainID,
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return h.BuildTransaction(sendArgs)
|
||||
}
|
||||
|
||||
func (h *HopBridgeProcessor) GetContractAddress(params ProcessorInputParams) (common.Address, error) {
|
||||
address, _, err := hop.GetContractAddress(params.FromChain.ChainID, params.FromToken.Symbol)
|
||||
return address, createBridgeHopErrorResponse(err)
|
||||
}
|
||||
|
||||
func (h *HopBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn) (tx *ethTypes.Transaction, err error) {
|
||||
func (h *HopBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn, lastUsedNonce int64) (tx *ethTypes.Transaction, err error) {
|
||||
fromChain := h.networkManager.Find(sendArgs.HopTx.ChainID)
|
||||
if fromChain == nil {
|
||||
return tx, fmt.Errorf("ChainID not supported %d", sendArgs.HopTx.ChainID)
|
||||
|
@ -312,9 +290,14 @@ func (h *HopBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, sig
|
|||
|
||||
token := h.tokenManager.FindToken(fromChain, sendArgs.HopTx.Symbol)
|
||||
|
||||
nonce, err := h.transactor.NextNonce(h.contractMaker.RPCClient, fromChain.ChainID, sendArgs.HopTx.From)
|
||||
if err != nil {
|
||||
return tx, createBridgeHopErrorResponse(err)
|
||||
var nonce uint64
|
||||
if lastUsedNonce < 0 {
|
||||
nonce, err = h.transactor.NextNonce(h.contractMaker.RPCClient, fromChain.ChainID, sendArgs.HopTx.From)
|
||||
if err != nil {
|
||||
return tx, createBridgeHopErrorResponse(err)
|
||||
}
|
||||
} else {
|
||||
nonce = uint64(lastUsedNonce) + 1
|
||||
}
|
||||
|
||||
argNonce := hexutil.Uint64(nonce)
|
||||
|
@ -366,16 +349,17 @@ func (h *HopBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, sig
|
|||
return tx, nil
|
||||
}
|
||||
|
||||
func (h *HopBridgeProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
tx, err := h.sendOrBuild(sendArgs, getSigner(sendArgs.HopTx.ChainID, sendArgs.HopTx.From, verifiedAccount))
|
||||
func (h *HopBridgeProcessor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (hash types.Hash, nonce uint64, err error) {
|
||||
tx, err := h.sendOrBuild(sendArgs, getSigner(sendArgs.HopTx.ChainID, sendArgs.HopTx.From, verifiedAccount), lastUsedNonce)
|
||||
if err != nil {
|
||||
return types.Hash{}, createBridgeHopErrorResponse(err)
|
||||
return types.Hash{}, 0, createBridgeHopErrorResponse(err)
|
||||
}
|
||||
return types.Hash(tx.Hash()), nil
|
||||
return types.Hash(tx.Hash()), tx.Nonce(), nil
|
||||
}
|
||||
|
||||
func (h *HopBridgeProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
return h.sendOrBuild(sendArgs, nil)
|
||||
func (h *HopBridgeProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
tx, err := h.sendOrBuild(sendArgs, nil, lastUsedNonce)
|
||||
return tx, tx.Nonce(), createBridgeHopErrorResponse(err)
|
||||
}
|
||||
|
||||
func (h *HopBridgeProcessor) CalculateFees(params ProcessorInputParams) (*big.Int, *big.Int, error) {
|
||||
|
|
|
@ -8,7 +8,6 @@ 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"
|
||||
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/contracts"
|
||||
|
@ -104,32 +103,12 @@ func (s *ENSPublicKeyProcessor) EstimateGas(params ProcessorInputParams) (uint64
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *ENSPublicKeyProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
inputData, err := s.PackTxInputData(params)
|
||||
if err != nil {
|
||||
return nil, createENSPublicKeyErrorResponse(err)
|
||||
}
|
||||
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(ZeroBigIntValue),
|
||||
Data: inputData,
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
func (s *ENSPublicKeyProcessor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (hash types.Hash, usedNonce uint64, err error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *ENSPublicKeyProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *ENSPublicKeyProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx)
|
||||
func (s *ENSPublicKeyProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce)
|
||||
}
|
||||
|
||||
func (s *ENSPublicKeyProcessor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/contracts"
|
||||
|
@ -140,32 +139,12 @@ func (s *ENSRegisterProcessor) EstimateGas(params ProcessorInputParams) (uint64,
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *ENSRegisterProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
inputData, err := s.PackTxInputData(params)
|
||||
if err != nil {
|
||||
return nil, createENSRegisterProcessorErrorResponse(err)
|
||||
}
|
||||
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(ZeroBigIntValue),
|
||||
Data: inputData,
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
func (s *ENSRegisterProcessor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (hash types.Hash, usedNonce uint64, err error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *ENSRegisterProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *ENSRegisterProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx)
|
||||
func (s *ENSRegisterProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce)
|
||||
}
|
||||
|
||||
func (s *ENSRegisterProcessor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
|
||||
|
|
|
@ -8,7 +8,6 @@ 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"
|
||||
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/contracts"
|
||||
|
@ -103,32 +102,12 @@ func (s *ENSReleaseProcessor) EstimateGas(params ProcessorInputParams) (uint64,
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *ENSReleaseProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
inputData, err := s.PackTxInputData(params)
|
||||
if err != nil {
|
||||
return nil, createENSReleaseErrorResponse(err)
|
||||
}
|
||||
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(ZeroBigIntValue),
|
||||
Data: inputData,
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
func (s *ENSReleaseProcessor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (hash types.Hash, usedNonce uint64, err error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *ENSReleaseProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *ENSReleaseProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx)
|
||||
func (s *ENSReleaseProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce)
|
||||
}
|
||||
|
||||
func (s *ENSReleaseProcessor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
|
||||
|
|
|
@ -108,34 +108,7 @@ func (s *ERC1155Processor) EstimateGas(params ProcessorInputParams) (uint64, err
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *ERC1155Processor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
contractAddress := types.Address(params.FromToken.Address)
|
||||
|
||||
// We store ERC1155 Token ID using big.Int.String() in token.Symbol
|
||||
tokenID, success := new(big.Int).SetString(params.FromToken.Symbol, 10)
|
||||
if !success {
|
||||
return nil, createERC1155ErrorResponse(fmt.Errorf("failed to convert ERC1155's Symbol %s to big.Int", params.FromToken.Symbol))
|
||||
}
|
||||
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
ERC1155TransferTx: &ERC1155TxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &contractAddress,
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
TokenID: (*hexutil.Big)(tokenID),
|
||||
Recipient: params.ToAddr,
|
||||
Amount: (*hexutil.Big)(params.AmountIn),
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
}
|
||||
|
||||
func (s *ERC1155Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn) (tx *ethTypes.Transaction, err error) {
|
||||
func (s *ERC1155Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn, lastUsedNonce int64) (tx *ethTypes.Transaction, err error) {
|
||||
ethClient, err := s.rpcClient.EthClient(sendArgs.ChainID)
|
||||
if err != nil {
|
||||
return tx, createERC1155ErrorResponse(err)
|
||||
|
@ -146,9 +119,14 @@ func (s *ERC1155Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signe
|
|||
return tx, createERC1155ErrorResponse(err)
|
||||
}
|
||||
|
||||
nonce, err := s.transactor.NextNonce(s.rpcClient, sendArgs.ChainID, sendArgs.ERC1155TransferTx.From)
|
||||
if err != nil {
|
||||
return tx, createERC1155ErrorResponse(err)
|
||||
var nonce uint64
|
||||
if lastUsedNonce < 0 {
|
||||
nonce, err = s.transactor.NextNonce(s.rpcClient, sendArgs.ChainID, sendArgs.ERC1155TransferTx.From)
|
||||
if err != nil {
|
||||
return tx, createERC1155ErrorResponse(err)
|
||||
}
|
||||
} else {
|
||||
nonce = uint64(lastUsedNonce) + 1
|
||||
}
|
||||
|
||||
argNonce := hexutil.Uint64(nonce)
|
||||
|
@ -172,16 +150,17 @@ func (s *ERC1155Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signe
|
|||
return tx, nil
|
||||
}
|
||||
|
||||
func (s *ERC1155Processor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.ERC1155TransferTx.From, verifiedAccount))
|
||||
func (s *ERC1155Processor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (hash types.Hash, usedNonce uint64, err error) {
|
||||
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.ERC1155TransferTx.From, verifiedAccount), lastUsedNonce)
|
||||
if err != nil {
|
||||
return hash, createERC1155ErrorResponse(err)
|
||||
return hash, 0, createERC1155ErrorResponse(err)
|
||||
}
|
||||
return types.Hash(tx.Hash()), nil
|
||||
return types.Hash(tx.Hash()), tx.Nonce(), nil
|
||||
}
|
||||
|
||||
func (s *ERC1155Processor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
return s.sendOrBuild(sendArgs, nil)
|
||||
func (s *ERC1155Processor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
tx, err := s.sendOrBuild(sendArgs, nil, lastUsedNonce)
|
||||
return tx, tx.Nonce(), err
|
||||
}
|
||||
|
||||
func (s *ERC1155Processor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
|
||||
|
|
|
@ -106,33 +106,7 @@ func (s *ERC721Processor) EstimateGas(params ProcessorInputParams) (uint64, erro
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *ERC721Processor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
contractAddress := types.Address(params.FromToken.Address)
|
||||
|
||||
// We store ERC721 Token ID using big.Int.String() in token.Symbol
|
||||
tokenID, success := new(big.Int).SetString(params.FromToken.Symbol, 10)
|
||||
if !success {
|
||||
return nil, createERC721ErrorResponse(fmt.Errorf("failed to convert ERC721's Symbol %s to big.Int", params.FromToken.Symbol))
|
||||
}
|
||||
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
ERC721TransferTx: &ERC721TxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &contractAddress,
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
TokenID: (*hexutil.Big)(tokenID),
|
||||
Recipient: params.ToAddr,
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
}
|
||||
|
||||
func (s *ERC721Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn) (tx *ethTypes.Transaction, err error) {
|
||||
func (s *ERC721Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn, lastUsedNonce int64) (tx *ethTypes.Transaction, err error) {
|
||||
ethClient, err := s.rpcClient.EthClient(sendArgs.ChainID)
|
||||
if err != nil {
|
||||
return tx, createERC721ErrorResponse(err)
|
||||
|
@ -143,9 +117,14 @@ func (s *ERC721Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signer
|
|||
return tx, createERC721ErrorResponse(err)
|
||||
}
|
||||
|
||||
nonce, err := s.transactor.NextNonce(s.rpcClient, sendArgs.ChainID, sendArgs.ERC721TransferTx.From)
|
||||
if err != nil {
|
||||
return tx, createERC721ErrorResponse(err)
|
||||
var nonce uint64
|
||||
if lastUsedNonce < 0 {
|
||||
nonce, err = s.transactor.NextNonce(s.rpcClient, sendArgs.ChainID, sendArgs.ERC721TransferTx.From)
|
||||
if err != nil {
|
||||
return tx, createERC721ErrorResponse(err)
|
||||
}
|
||||
} else {
|
||||
nonce = uint64(lastUsedNonce) + 1
|
||||
}
|
||||
|
||||
argNonce := hexutil.Uint64(nonce)
|
||||
|
@ -165,16 +144,17 @@ func (s *ERC721Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signer
|
|||
return tx, nil
|
||||
}
|
||||
|
||||
func (s *ERC721Processor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.ERC721TransferTx.From, verifiedAccount))
|
||||
func (s *ERC721Processor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (hash types.Hash, usedNonce uint64, err error) {
|
||||
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.ERC721TransferTx.From, verifiedAccount), lastUsedNonce)
|
||||
if err != nil {
|
||||
return hash, createERC721ErrorResponse(err)
|
||||
return hash, 0, createERC721ErrorResponse(err)
|
||||
}
|
||||
return types.Hash(tx.Hash()), nil
|
||||
return types.Hash(tx.Hash()), tx.Nonce(), nil
|
||||
}
|
||||
|
||||
func (s *ERC721Processor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
return s.sendOrBuild(sendArgs, nil)
|
||||
func (s *ERC721Processor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
tx, err := s.sendOrBuild(sendArgs, nil, lastUsedNonce)
|
||||
return tx, tx.Nonce(), err
|
||||
}
|
||||
|
||||
func (s *ERC721Processor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/contracts"
|
||||
|
@ -132,32 +131,12 @@ func (s *StickersBuyProcessor) EstimateGas(params ProcessorInputParams) (uint64,
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *StickersBuyProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
inputData, err := s.PackTxInputData(params)
|
||||
if err != nil {
|
||||
return nil, createStickersBuyErrorResponse(err)
|
||||
}
|
||||
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(ZeroBigIntValue),
|
||||
Data: inputData,
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
func (s *StickersBuyProcessor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (hash types.Hash, usedNonce uint64, err error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *StickersBuyProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *StickersBuyProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx)
|
||||
func (s *StickersBuyProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce)
|
||||
}
|
||||
|
||||
func (s *StickersBuyProcessor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
|
||||
|
|
|
@ -209,27 +209,6 @@ func (s *SwapParaswapProcessor) GetContractAddress(params ProcessorInputParams)
|
|||
return
|
||||
}
|
||||
|
||||
func (s *SwapParaswapProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
SwapTx: &SwapParaswapTxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
Symbol: params.FromToken.Symbol,
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
ChainIDTo: params.ToChain.ChainID,
|
||||
TokenIDFrom: params.FromToken.Symbol,
|
||||
TokenIDTo: params.ToToken.Symbol,
|
||||
},
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
}
|
||||
|
||||
func (s *SwapParaswapProcessor) prepareTransaction(sendArgs *MultipathProcessorTxArgs) error {
|
||||
slippageBP := uint(sendArgs.SwapTx.SlippagePercentage * 100) // convert to basis points
|
||||
|
||||
|
@ -276,21 +255,21 @@ func (s *SwapParaswapProcessor) prepareTransaction(sendArgs *MultipathProcessorT
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *SwapParaswapProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
func (s *SwapParaswapProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
err := s.prepareTransaction(sendArgs)
|
||||
if err != nil {
|
||||
return nil, createSwapParaswapErrorResponse(err)
|
||||
return nil, 0, createSwapParaswapErrorResponse(err)
|
||||
}
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, sendArgs.SwapTx.SendTxArgs)
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, sendArgs.SwapTx.SendTxArgs, lastUsedNonce)
|
||||
}
|
||||
|
||||
func (s *SwapParaswapProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (types.Hash, error) {
|
||||
func (s *SwapParaswapProcessor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (types.Hash, uint64, error) {
|
||||
err := s.prepareTransaction(sendArgs)
|
||||
if err != nil {
|
||||
return types.Hash{}, createSwapParaswapErrorResponse(err)
|
||||
return types.Hash{}, 0, createSwapParaswapErrorResponse(err)
|
||||
}
|
||||
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, sendArgs.SwapTx.SendTxArgs, verifiedAccount)
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, sendArgs.SwapTx.SendTxArgs, lastUsedNonce, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *SwapParaswapProcessor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
|
||||
|
|
|
@ -8,7 +8,6 @@ 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"
|
||||
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/contracts/ierc20"
|
||||
|
@ -114,51 +113,12 @@ func (s *TransferProcessor) EstimateGas(params ProcessorInputParams) (uint64, er
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *TransferProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
if params.FromToken.IsNative() {
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
}
|
||||
abi, err := abi.JSON(strings.NewReader(ierc20.IERC20ABI))
|
||||
if err != nil {
|
||||
return nil, createTransferErrorResponse(err)
|
||||
}
|
||||
input, err := abi.Pack("transfer",
|
||||
params.ToAddr,
|
||||
params.AmountIn,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, createTransferErrorResponse(err)
|
||||
}
|
||||
sendArgs := &MultipathProcessorTxArgs{
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(ZeroBigIntValue),
|
||||
Data: input,
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
func (s *TransferProcessor) Send(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (types.Hash, uint64, error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *TransferProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (types.Hash, error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *TransferProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx)
|
||||
func (s *TransferProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs, lastUsedNonce int64) (*ethTypes.Transaction, uint64, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx, lastUsedNonce)
|
||||
}
|
||||
|
||||
func (s *TransferProcessor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
|
||||
|
|
|
@ -158,12 +158,21 @@ func sendTransactions(data []*pathprocessor.MultipathProcessorTxArgs, pathProces
|
|||
map[uint64][]types.Hash, error) {
|
||||
|
||||
hashes := make(map[uint64][]types.Hash)
|
||||
usedNonces := make(map[uint64]int64)
|
||||
for _, tx := range data {
|
||||
hash, err := pathProcessors[tx.Name].Send(tx, account)
|
||||
|
||||
lastUsedNonce := int64(-1)
|
||||
if nonce, ok := usedNonces[tx.ChainID]; ok {
|
||||
lastUsedNonce = nonce
|
||||
}
|
||||
|
||||
hash, usedNonce, err := pathProcessors[tx.Name].Send(tx, lastUsedNonce, account)
|
||||
if err != nil {
|
||||
return nil, err // TODO: One of transfers within transaction could have been sent. Need to notify user about it
|
||||
}
|
||||
|
||||
hashes[tx.ChainID] = append(hashes[tx.ChainID], hash)
|
||||
usedNonces[tx.ChainID] = int64(usedNonce)
|
||||
}
|
||||
return hashes, nil
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ func (tm *TransactionManager) BuildTransaction(chainID uint64, sendArgs transact
|
|||
return nil, err
|
||||
}
|
||||
|
||||
txBeingSigned, err := tm.transactor.ValidateAndBuildTransaction(chainID, sendArgs)
|
||||
txBeingSigned, _, err := tm.transactor.ValidateAndBuildTransaction(chainID, sendArgs, -1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -11,8 +11,15 @@ import (
|
|||
func (tm *TransactionManager) buildTransactions(pathProcessors map[string]pathprocessor.PathProcessor) ([]string, error) {
|
||||
tm.transactionsForKeycardSigning = make(map[common.Hash]*TransactionDescription)
|
||||
var hashes []string
|
||||
usedNonces := make(map[uint64]int64)
|
||||
for _, bridgeTx := range tm.multipathTransactionsData {
|
||||
builtTx, err := pathProcessors[bridgeTx.Name].BuildTransaction(bridgeTx)
|
||||
|
||||
lastUsedNonce := int64(-1)
|
||||
if nonce, ok := usedNonces[bridgeTx.ChainID]; ok {
|
||||
lastUsedNonce = nonce
|
||||
}
|
||||
|
||||
builtTx, usedNonce, err := pathProcessors[bridgeTx.Name].BuildTransaction(bridgeTx, lastUsedNonce)
|
||||
if err != nil {
|
||||
return hashes, err
|
||||
}
|
||||
|
@ -26,6 +33,8 @@ func (tm *TransactionManager) buildTransactions(pathProcessors map[string]pathpr
|
|||
builtTx: builtTx,
|
||||
}
|
||||
|
||||
usedNonces[bridgeTx.ChainID] = int64(usedNonce)
|
||||
|
||||
hashes = append(hashes, txHash.String())
|
||||
}
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ func TestSendTransactionsETHSuccess(t *testing.T) {
|
|||
// Verify that the SendTransactionWithChainID method is called for each transaction with proper arguments
|
||||
// Return values are not checked, because they must be checked in Transactor tests
|
||||
for _, tx := range expectedData {
|
||||
transactor.EXPECT().SendTransactionWithChainID(tx.ChainID, *(tx.TransferTx), account).Return(types.Hash{}, nil)
|
||||
transactor.EXPECT().SendTransactionWithChainID(tx.ChainID, *(tx.TransferTx), int64(-1), account).Return(types.Hash{}, uint64(0), nil)
|
||||
}
|
||||
|
||||
// Call the SendTransactions method
|
||||
|
@ -182,7 +182,7 @@ func TestSendTransactionsApproveSuccess(t *testing.T) {
|
|||
// Verify that the SendTransactionWithChainID method is called for each transaction with proper arguments
|
||||
// Return values are not checked, because they must be checked in Transactor tests
|
||||
for _, tx := range expectedData {
|
||||
transactor.EXPECT().SendTransactionWithChainID(tx.ChainID, *(tx.TransferTx), account).Return(types.Hash{}, nil)
|
||||
transactor.EXPECT().SendTransactionWithChainID(tx.ChainID, *(tx.TransferTx), int64(-1), account).Return(types.Hash{}, uint64(0), nil)
|
||||
}
|
||||
|
||||
// Call the SendTransactions method
|
||||
|
@ -205,7 +205,7 @@ func TestSendTransactionsETHFailOnBridge(t *testing.T) {
|
|||
|
||||
expectedErr := transactions.ErrInvalidTxSender // Any error to verify
|
||||
// In case of bridge error, verify that the error is returned
|
||||
transferBridge.EXPECT().Send(gomock.Any(), gomock.Any()).Return(types.Hash{}, transactions.ErrInvalidTxSender)
|
||||
transferBridge.EXPECT().Send(gomock.Any(), int64(-1), gomock.Any()).Return(types.Hash{}, uint64(0), transactions.ErrInvalidTxSender)
|
||||
|
||||
// Call the SendTransactions method
|
||||
_, err := tm.SendTransactions(context.Background(), multiTransaction, data, bridges, account)
|
||||
|
@ -220,8 +220,8 @@ func TestSendTransactionsETHFailOnTransactor(t *testing.T) {
|
|||
// Verify that the SendTransactionWithChainID method is called for each transaction with proper arguments
|
||||
// Return values are not checked, because they must be checked in Transactor tests. Only error propagation matters here
|
||||
expectedErr := transactions.ErrInvalidTxSender // Any error to verify
|
||||
transactor.EXPECT().SendTransactionWithChainID(expectedData[0].ChainID, *(expectedData[0].TransferTx), account).Return(types.Hash{}, nil)
|
||||
transactor.EXPECT().SendTransactionWithChainID(expectedData[1].ChainID, *(expectedData[1].TransferTx), account).Return(types.Hash{}, expectedErr)
|
||||
transactor.EXPECT().SendTransactionWithChainID(expectedData[0].ChainID, *(expectedData[0].TransferTx), int64(-1), account).Return(types.Hash{}, uint64(0), nil)
|
||||
transactor.EXPECT().SendTransactionWithChainID(expectedData[1].ChainID, *(expectedData[1].TransferTx), int64(-1), account).Return(types.Hash{}, uint64(0), expectedErr)
|
||||
|
||||
// Call the SendTransactions method
|
||||
_, err := tm.SendTransactions(context.Background(), multiTransaction, data, bridges, account)
|
||||
|
|
|
@ -280,7 +280,7 @@ func TestBuildTransaction(t *testing.T) {
|
|||
}
|
||||
|
||||
expectedTx := gethtypes.NewTransaction(nonce, common.Address(*sendArgs.To), sendArgs.Value.ToInt(), gas, sendArgs.GasPrice.ToInt(), nil)
|
||||
transactor.EXPECT().ValidateAndBuildTransaction(chainID, sendArgs).Return(expectedTx, nil)
|
||||
transactor.EXPECT().ValidateAndBuildTransaction(chainID, sendArgs, int64(-1)).Return(expectedTx, uint64(0), nil)
|
||||
|
||||
response, err := manager.BuildTransaction(chainID, sendArgs)
|
||||
require.NoError(t, err)
|
||||
|
@ -334,7 +334,7 @@ func TestBuildTransaction_InvalidSendTxArgs(t *testing.T) {
|
|||
}
|
||||
|
||||
expectedErr := fmt.Errorf("invalid SendTxArgs")
|
||||
transactor.EXPECT().ValidateAndBuildTransaction(chainID, sendArgs).Return(nil, expectedErr)
|
||||
transactor.EXPECT().ValidateAndBuildTransaction(chainID, sendArgs, int64(-1)).Return(nil, uint64(0), expectedErr)
|
||||
tx, err := manager.BuildTransaction(chainID, sendArgs)
|
||||
require.Equal(t, expectedErr, err)
|
||||
require.Nil(t, tx)
|
||||
|
|
|
@ -79,7 +79,7 @@ func (api *API) sendTransaction(chainID uint64, sendArgs transactions.SendTxArgs
|
|||
return hash, err
|
||||
}
|
||||
|
||||
hash, err = api.s.transactor.SendTransactionWithChainID(chainID, sendArgs, verifiedAccount)
|
||||
hash, _, err = api.s.transactor.SendTransactionWithChainID(chainID, sendArgs, -1, verifiedAccount)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -8,10 +8,9 @@ import (
|
|||
big "math/big"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
|
||||
common "github.com/ethereum/go-ethereum/common"
|
||||
types "github.com/ethereum/go-ethereum/core/types"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
account "github.com/status-im/status-go/account"
|
||||
types0 "github.com/status-im/status-go/eth-node/types"
|
||||
params "github.com/status-im/status-go/params"
|
||||
|
@ -118,33 +117,35 @@ func (mr *MockTransactorIfaceMockRecorder) SendRawTransaction(chainID, rawTx int
|
|||
}
|
||||
|
||||
// SendTransaction mocks base method.
|
||||
func (m *MockTransactorIface) SendTransaction(sendArgs transactions.SendTxArgs, verifiedAccount *account.SelectedExtKey) (types0.Hash, error) {
|
||||
func (m *MockTransactorIface) SendTransaction(sendArgs transactions.SendTxArgs, verifiedAccount *account.SelectedExtKey, lastUsedNonce int64) (types0.Hash, uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SendTransaction", sendArgs, verifiedAccount)
|
||||
ret := m.ctrl.Call(m, "SendTransaction", sendArgs, verifiedAccount, lastUsedNonce)
|
||||
ret0, _ := ret[0].(types0.Hash)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
ret1, _ := ret[1].(uint64)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// SendTransaction indicates an expected call of SendTransaction.
|
||||
func (mr *MockTransactorIfaceMockRecorder) SendTransaction(sendArgs, verifiedAccount interface{}) *gomock.Call {
|
||||
func (mr *MockTransactorIfaceMockRecorder) SendTransaction(sendArgs, verifiedAccount, lastUsedNonce interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendTransaction", reflect.TypeOf((*MockTransactorIface)(nil).SendTransaction), sendArgs, verifiedAccount)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendTransaction", reflect.TypeOf((*MockTransactorIface)(nil).SendTransaction), sendArgs, verifiedAccount, lastUsedNonce)
|
||||
}
|
||||
|
||||
// SendTransactionWithChainID mocks base method.
|
||||
func (m *MockTransactorIface) SendTransactionWithChainID(chainID uint64, sendArgs transactions.SendTxArgs, verifiedAccount *account.SelectedExtKey) (types0.Hash, error) {
|
||||
func (m *MockTransactorIface) SendTransactionWithChainID(chainID uint64, sendArgs transactions.SendTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (types0.Hash, uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SendTransactionWithChainID", chainID, sendArgs, verifiedAccount)
|
||||
ret := m.ctrl.Call(m, "SendTransactionWithChainID", chainID, sendArgs, lastUsedNonce, verifiedAccount)
|
||||
ret0, _ := ret[0].(types0.Hash)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
ret1, _ := ret[1].(uint64)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// SendTransactionWithChainID indicates an expected call of SendTransactionWithChainID.
|
||||
func (mr *MockTransactorIfaceMockRecorder) SendTransactionWithChainID(chainID, sendArgs, verifiedAccount interface{}) *gomock.Call {
|
||||
func (mr *MockTransactorIfaceMockRecorder) SendTransactionWithChainID(chainID, sendArgs, lastUsedNonce, verifiedAccount interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendTransactionWithChainID", reflect.TypeOf((*MockTransactorIface)(nil).SendTransactionWithChainID), chainID, sendArgs, verifiedAccount)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendTransactionWithChainID", reflect.TypeOf((*MockTransactorIface)(nil).SendTransactionWithChainID), chainID, sendArgs, lastUsedNonce, verifiedAccount)
|
||||
}
|
||||
|
||||
// SendTransactionWithSignature mocks base method.
|
||||
|
@ -177,16 +178,17 @@ func (mr *MockTransactorIfaceMockRecorder) StoreAndTrackPendingTx(from, symbol,
|
|||
}
|
||||
|
||||
// ValidateAndBuildTransaction mocks base method.
|
||||
func (m *MockTransactorIface) ValidateAndBuildTransaction(chainID uint64, sendArgs transactions.SendTxArgs) (*types.Transaction, error) {
|
||||
func (m *MockTransactorIface) ValidateAndBuildTransaction(chainID uint64, sendArgs transactions.SendTxArgs, lastUsedNonce int64) (*types.Transaction, uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidateAndBuildTransaction", chainID, sendArgs)
|
||||
ret := m.ctrl.Call(m, "ValidateAndBuildTransaction", chainID, sendArgs, lastUsedNonce)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
ret1, _ := ret[1].(uint64)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// ValidateAndBuildTransaction indicates an expected call of ValidateAndBuildTransaction.
|
||||
func (mr *MockTransactorIfaceMockRecorder) ValidateAndBuildTransaction(chainID, sendArgs interface{}) *gomock.Call {
|
||||
func (mr *MockTransactorIfaceMockRecorder) ValidateAndBuildTransaction(chainID, sendArgs, lastUsedNonce interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateAndBuildTransaction", reflect.TypeOf((*MockTransactorIface)(nil).ValidateAndBuildTransaction), chainID, sendArgs)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateAndBuildTransaction", reflect.TypeOf((*MockTransactorIface)(nil).ValidateAndBuildTransaction), chainID, sendArgs, lastUsedNonce)
|
||||
}
|
||||
|
|
|
@ -48,9 +48,9 @@ func (e *ErrBadNonce) Error() string {
|
|||
type TransactorIface interface {
|
||||
NextNonce(rpcClient rpc.ClientInterface, chainID uint64, from types.Address) (uint64, error)
|
||||
EstimateGas(network *params.Network, from common.Address, to common.Address, value *big.Int, input []byte) (uint64, error)
|
||||
SendTransaction(sendArgs SendTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error)
|
||||
SendTransactionWithChainID(chainID uint64, sendArgs SendTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error)
|
||||
ValidateAndBuildTransaction(chainID uint64, sendArgs SendTxArgs) (tx *gethtypes.Transaction, err error)
|
||||
SendTransaction(sendArgs SendTxArgs, verifiedAccount *account.SelectedExtKey, lastUsedNonce int64) (hash types.Hash, nonce uint64, err error)
|
||||
SendTransactionWithChainID(chainID uint64, sendArgs SendTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (hash types.Hash, nonce uint64, err error)
|
||||
ValidateAndBuildTransaction(chainID uint64, sendArgs SendTxArgs, lastUsedNonce int64) (tx *gethtypes.Transaction, nonce uint64, err error)
|
||||
AddSignatureToTransaction(chainID uint64, tx *gethtypes.Transaction, sig []byte) (*gethtypes.Transaction, error)
|
||||
SendRawTransaction(chainID uint64, rawTx string) error
|
||||
BuildTransactionWithSignature(chainID uint64, args SendTxArgs, sig []byte) (*gethtypes.Transaction, error)
|
||||
|
@ -139,21 +139,21 @@ func (t *Transactor) EstimateGas(network *params.Network, from common.Address, t
|
|||
}
|
||||
|
||||
// SendTransaction is an implementation of eth_sendTransaction. It queues the tx to the sign queue.
|
||||
func (t *Transactor) SendTransaction(sendArgs SendTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
hash, err = t.validateAndPropagate(t.rpcWrapper, verifiedAccount, sendArgs)
|
||||
func (t *Transactor) SendTransaction(sendArgs SendTxArgs, verifiedAccount *account.SelectedExtKey, lastUsedNonce int64) (hash types.Hash, nonce uint64, err error) {
|
||||
hash, nonce, err = t.validateAndPropagate(t.rpcWrapper, verifiedAccount, sendArgs, lastUsedNonce)
|
||||
return
|
||||
}
|
||||
|
||||
func (t *Transactor) SendTransactionWithChainID(chainID uint64, sendArgs SendTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
func (t *Transactor) SendTransactionWithChainID(chainID uint64, sendArgs SendTxArgs, lastUsedNonce int64, verifiedAccount *account.SelectedExtKey) (hash types.Hash, nonce uint64, err error) {
|
||||
wrapper := newRPCWrapper(t.rpcWrapper.RPCClient, chainID)
|
||||
hash, err = t.validateAndPropagate(wrapper, verifiedAccount, sendArgs)
|
||||
hash, nonce, err = t.validateAndPropagate(wrapper, verifiedAccount, sendArgs, lastUsedNonce)
|
||||
return
|
||||
}
|
||||
|
||||
func (t *Transactor) ValidateAndBuildTransaction(chainID uint64, sendArgs SendTxArgs) (tx *gethtypes.Transaction, err error) {
|
||||
func (t *Transactor) ValidateAndBuildTransaction(chainID uint64, sendArgs SendTxArgs, lastUsedNonce int64) (tx *gethtypes.Transaction, nonce uint64, err error) {
|
||||
wrapper := newRPCWrapper(t.rpcWrapper.RPCClient, chainID)
|
||||
tx, err = t.validateAndBuildTransaction(wrapper, sendArgs)
|
||||
return
|
||||
tx, err = t.validateAndBuildTransaction(wrapper, sendArgs, lastUsedNonce)
|
||||
return tx, tx.Nonce(), err
|
||||
}
|
||||
|
||||
func (t *Transactor) AddSignatureToTransaction(chainID uint64, tx *gethtypes.Transaction, sig []byte) (*gethtypes.Transaction, error) {
|
||||
|
@ -361,7 +361,7 @@ func (t *Transactor) validateAccount(args SendTxArgs, selectedAccount *account.S
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *Transactor) validateAndBuildTransaction(rpcWrapper *rpcWrapper, args SendTxArgs) (tx *gethtypes.Transaction, err error) {
|
||||
func (t *Transactor) validateAndBuildTransaction(rpcWrapper *rpcWrapper, args SendTxArgs, lastUsedNonce int64) (tx *gethtypes.Transaction, err error) {
|
||||
if !args.Valid() {
|
||||
return tx, ErrInvalidSendTxArgs
|
||||
}
|
||||
|
@ -370,9 +370,14 @@ func (t *Transactor) validateAndBuildTransaction(rpcWrapper *rpcWrapper, args Se
|
|||
if args.Nonce != nil {
|
||||
nonce = uint64(*args.Nonce)
|
||||
} else {
|
||||
nonce, err = t.NextNonce(rpcWrapper.RPCClient, rpcWrapper.chainID, args.From)
|
||||
if err != nil {
|
||||
return tx, err
|
||||
// some chains, like arbitrum doesn't count pending txs in the nonce, so we need to calculate it manually
|
||||
if lastUsedNonce < 0 {
|
||||
nonce, err = t.NextNonce(rpcWrapper.RPCClient, rpcWrapper.chainID, args.From)
|
||||
if err != nil {
|
||||
return tx, err
|
||||
}
|
||||
} else {
|
||||
nonce = uint64(lastUsedNonce) + 1
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,23 +438,24 @@ func (t *Transactor) validateAndBuildTransaction(rpcWrapper *rpcWrapper, args Se
|
|||
return tx, nil
|
||||
}
|
||||
|
||||
func (t *Transactor) validateAndPropagate(rpcWrapper *rpcWrapper, selectedAccount *account.SelectedExtKey, args SendTxArgs) (hash types.Hash, err error) {
|
||||
func (t *Transactor) validateAndPropagate(rpcWrapper *rpcWrapper, selectedAccount *account.SelectedExtKey, args SendTxArgs, lastUsedNonce int64) (hash types.Hash, nonce uint64, err error) {
|
||||
if err = t.validateAccount(args, selectedAccount); err != nil {
|
||||
return hash, err
|
||||
return hash, nonce, err
|
||||
}
|
||||
|
||||
tx, err := t.validateAndBuildTransaction(rpcWrapper, args)
|
||||
tx, err := t.validateAndBuildTransaction(rpcWrapper, args, lastUsedNonce)
|
||||
if err != nil {
|
||||
return hash, err
|
||||
return hash, nonce, err
|
||||
}
|
||||
|
||||
chainID := big.NewInt(int64(rpcWrapper.chainID))
|
||||
signedTx, err := gethtypes.SignTx(tx, gethtypes.NewLondonSigner(chainID), selectedAccount.AccountKey.PrivateKey)
|
||||
if err != nil {
|
||||
return hash, err
|
||||
return hash, nonce, err
|
||||
}
|
||||
|
||||
return t.sendTransaction(rpcWrapper, common.Address(args.From), args.Symbol, args.MultiTransactionID, signedTx)
|
||||
hash, err = t.sendTransaction(rpcWrapper, common.Address(args.From), args.Symbol, args.MultiTransactionID, signedTx)
|
||||
return hash, tx.Nonce(), err
|
||||
}
|
||||
|
||||
func (t *Transactor) buildTransaction(args SendTxArgs) *gethtypes.Transaction {
|
||||
|
|
|
@ -207,7 +207,7 @@ func (s *TransactorSuite) TestGasValues() {
|
|||
}
|
||||
s.setupTransactionPoolAPI(args, testNonce, testNonce, selectedAccount, nil)
|
||||
|
||||
hash, err := s.manager.SendTransaction(args, selectedAccount)
|
||||
hash, _, err := s.manager.SendTransaction(args, selectedAccount, -1)
|
||||
s.NoError(err)
|
||||
s.False(reflect.DeepEqual(hash, common.Hash{}))
|
||||
})
|
||||
|
@ -256,7 +256,7 @@ func (s *TransactorSuite) TestBuildAndValidateTransaction() {
|
|||
}
|
||||
s.setupBuildTransactionMocks(args, selectedAccount)
|
||||
|
||||
tx, err := s.manager.ValidateAndBuildTransaction(chainID, args)
|
||||
tx, _, err := s.manager.ValidateAndBuildTransaction(chainID, args, -1)
|
||||
s.NoError(err)
|
||||
s.Equal(tx.Gas(), uint64(gas), "The gas shouldn't be estimated, but should use the gas from the Tx")
|
||||
s.Equal(tx.GasFeeCap(), expectedGasPrice, "The maxFeePerGas should be the same as in the original Tx")
|
||||
|
@ -275,7 +275,7 @@ func (s *TransactorSuite) TestBuildAndValidateTransaction() {
|
|||
}
|
||||
s.setupBuildTransactionMocks(args, selectedAccount)
|
||||
|
||||
tx, err := s.manager.ValidateAndBuildTransaction(chainID, args)
|
||||
tx, _, err := s.manager.ValidateAndBuildTransaction(chainID, args, -1)
|
||||
s.NoError(err)
|
||||
s.Equal(tx.Gas(), expectedGas, "The gas should be estimated if not present in the original Tx")
|
||||
s.Equal(tx.Nonce(), expectedNonce, "The nonce should be added if not present in the original Tx")
|
||||
|
@ -298,7 +298,7 @@ func (s *TransactorSuite) TestBuildAndValidateTransaction() {
|
|||
}
|
||||
s.setupBuildTransactionMocks(args, selectedAccount)
|
||||
|
||||
tx, err := s.manager.ValidateAndBuildTransaction(chainID, args)
|
||||
tx, _, err := s.manager.ValidateAndBuildTransaction(chainID, args, -1)
|
||||
s.NoError(err)
|
||||
s.Equal(tx.Gas(), uint64(gas), "The gas shouldn't be estimated, but should use the gas from the Tx")
|
||||
s.Equal(tx.GasPrice(), expectedGasPrice, "The gasPrice should be the same as in the original Tx")
|
||||
|
@ -314,7 +314,7 @@ func (s *TransactorSuite) TestBuildAndValidateTransaction() {
|
|||
}
|
||||
s.setupBuildTransactionMocks(args, selectedAccount)
|
||||
|
||||
tx, err := s.manager.ValidateAndBuildTransaction(chainID, args)
|
||||
tx, _, err := s.manager.ValidateAndBuildTransaction(chainID, args, -1)
|
||||
s.NoError(err)
|
||||
s.Equal(tx.Gas(), expectedGas, "The gas should be estimated if not present in the original Tx")
|
||||
s.Equal(tx.GasPrice(), expectedGasPrice, "The gasPrice should be estimated if not present in the original Tx")
|
||||
|
@ -333,7 +333,7 @@ func (s *TransactorSuite) TestArgsValidation() {
|
|||
selectedAccount := &account.SelectedExtKey{
|
||||
Address: account.FromAddress(utils.TestConfig.Account1.WalletAddress),
|
||||
}
|
||||
_, err := s.manager.SendTransaction(args, selectedAccount)
|
||||
_, _, err := s.manager.SendTransaction(args, selectedAccount, -1)
|
||||
s.EqualError(err, ErrInvalidSendTxArgs.Error())
|
||||
}
|
||||
|
||||
|
@ -346,14 +346,14 @@ func (s *TransactorSuite) TestAccountMismatch() {
|
|||
var err error
|
||||
|
||||
// missing account
|
||||
_, err = s.manager.SendTransaction(args, nil)
|
||||
_, _, err = s.manager.SendTransaction(args, nil, -1)
|
||||
s.EqualError(err, account.ErrNoAccountSelected.Error())
|
||||
|
||||
// mismatched accounts
|
||||
selectedAccount := &account.SelectedExtKey{
|
||||
Address: account.FromAddress(utils.TestConfig.Account2.WalletAddress),
|
||||
}
|
||||
_, err = s.manager.SendTransaction(args, selectedAccount)
|
||||
_, _, err = s.manager.SendTransaction(args, selectedAccount, -1)
|
||||
s.EqualError(err, ErrInvalidTxSender.Error())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue