test(wallet)_: created Transactor interface
- Moved some methods from Transactor to users of it to clean interface. - Mocked Bridge interface and Transactor interface for tests - Wrote unit tests for SendTransaction
This commit is contained in:
parent
4d1149100f
commit
a135b27980
2
Makefile
2
Makefile
|
@ -342,6 +342,8 @@ mock: ##@other Regenerate mocks
|
|||
mockgen -package=fake -destination=transactions/fake/mock.go -source=transactions/fake/txservice.go
|
||||
mockgen -package=status -destination=services/status/account_mock.go -source=services/status/service.go
|
||||
mockgen -package=peer -destination=services/peer/discoverer_mock.go -source=services/peer/service.go
|
||||
mockgen -package=mock_transactor -destination=transactions/mock_transactor/transactor.go -source=transactions/transactor.go
|
||||
mockgen -package=mock_bridge -destination=services/wallet/bridge/mock_bridge/bridge.go -source=services/wallet/bridge/bridge.go
|
||||
|
||||
docker-test: ##@tests Run tests in a docker container with golang.
|
||||
docker run --privileged --rm -it -v "$(PWD):$(DOCKER_TEST_WORKDIR)" -w "$(DOCKER_TEST_WORKDIR)" $(DOCKER_TEST_IMAGE) go test ${ARGS}
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
|
||||
"github.com/imdario/mergo"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
@ -1950,7 +1951,12 @@ func (b *GethStatusBackend) SendTransactionWithChainID(chainID uint64, sendArgs
|
|||
}
|
||||
|
||||
func (b *GethStatusBackend) SendTransactionWithSignature(sendArgs transactions.SendTxArgs, sig []byte) (hash types.Hash, err error) {
|
||||
return b.transactor.BuildTransactionAndSendWithSignature(b.transactor.NetworkID(), sendArgs, sig)
|
||||
txWithSignature, err := b.transactor.BuildTransactionWithSignature(b.transactor.NetworkID(), sendArgs, sig)
|
||||
if err != nil {
|
||||
return hash, err
|
||||
}
|
||||
|
||||
return b.transactor.SendTransactionWithSignature(common.Address(sendArgs.From), sendArgs.Symbol, sendArgs.MultiTransactionID, txWithSignature)
|
||||
}
|
||||
|
||||
// HashTransaction validate the transaction and returns new sendArgs and the transaction hash.
|
||||
|
|
|
@ -602,13 +602,13 @@ func (api *API) SendTransactionWithSignature(ctx context.Context, chainID uint64
|
|||
if err != nil {
|
||||
return hash, err
|
||||
}
|
||||
return api.s.transactionManager.SendTransactionWithSignature(chainID, txType, params, sig)
|
||||
return api.s.transactionManager.SendTransactionWithSignature(chainID, params, sig)
|
||||
}
|
||||
|
||||
func (api *API) CreateMultiTransaction(ctx context.Context, multiTransactionCommand *transfer.MultiTransactionCommand, data []*bridge.TransactionBridge, password string) (*transfer.MultiTransactionCommandResult, error) {
|
||||
log.Debug("[WalletAPI:: CreateMultiTransaction] create multi transaction")
|
||||
|
||||
cmd, err := api.s.transactionManager.CreateMultiTransactionFromCommand(ctx, multiTransactionCommand, data)
|
||||
cmd, err := api.s.transactionManager.CreateMultiTransactionFromCommand(multiTransactionCommand, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -43,13 +43,13 @@ type CBridgeTxArgs struct {
|
|||
type CBridge struct {
|
||||
rpcClient *rpc.Client
|
||||
httpClient *thirdparty.HTTPClient
|
||||
transactor *transactions.Transactor
|
||||
transactor transactions.TransactorIface
|
||||
tokenManager *token.Manager
|
||||
prodTransferConfig *cbridge.GetTransferConfigsResponse
|
||||
testTransferConfig *cbridge.GetTransferConfigsResponse
|
||||
}
|
||||
|
||||
func NewCbridge(rpcClient *rpc.Client, transactor *transactions.Transactor, tokenManager *token.Manager) *CBridge {
|
||||
func NewCbridge(rpcClient *rpc.Client, transactor transactions.TransactorIface, tokenManager *token.Manager) *CBridge {
|
||||
return &CBridge{
|
||||
rpcClient: rpcClient,
|
||||
httpClient: thirdparty.NewHTTPClient(),
|
||||
|
|
|
@ -30,10 +30,10 @@ type ERC1155TransferTxArgs struct {
|
|||
|
||||
type ERC1155TransferBridge struct {
|
||||
rpcClient *rpc.Client
|
||||
transactor *transactions.Transactor
|
||||
transactor transactions.TransactorIface
|
||||
}
|
||||
|
||||
func NewERC1155TransferBridge(rpcClient *rpc.Client, transactor *transactions.Transactor) *ERC1155TransferBridge {
|
||||
func NewERC1155TransferBridge(rpcClient *rpc.Client, transactor transactions.TransactorIface) *ERC1155TransferBridge {
|
||||
return &ERC1155TransferBridge{rpcClient: rpcClient, transactor: transactor}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,10 +29,10 @@ type ERC721TransferTxArgs struct {
|
|||
|
||||
type ERC721TransferBridge struct {
|
||||
rpcClient *rpc.Client
|
||||
transactor *transactions.Transactor
|
||||
transactor transactions.TransactorIface
|
||||
}
|
||||
|
||||
func NewERC721TransferBridge(rpcClient *rpc.Client, transactor *transactions.Transactor) *ERC721TransferBridge {
|
||||
func NewERC721TransferBridge(rpcClient *rpc.Client, transactor transactions.TransactorIface) *ERC721TransferBridge {
|
||||
return &ERC721TransferBridge{rpcClient: rpcClient, transactor: transactor}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,14 +107,14 @@ func (bf *BonderFee) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
|
||||
type HopBridge struct {
|
||||
transactor *transactions.Transactor
|
||||
transactor transactions.TransactorIface
|
||||
httpClient *thirdparty.HTTPClient
|
||||
tokenManager *token.Manager
|
||||
contractMaker *contracts.ContractMaker
|
||||
bonderFee *BonderFee
|
||||
}
|
||||
|
||||
func NewHopBridge(rpcClient *rpc.Client, transactor *transactions.Transactor, tokenManager *token.Manager) *HopBridge {
|
||||
func NewHopBridge(rpcClient *rpc.Client, transactor transactions.TransactorIface, tokenManager *token.Manager) *HopBridge {
|
||||
return &HopBridge{
|
||||
contractMaker: &contracts.ContractMaker{RPCClient: rpcClient},
|
||||
httpClient: thirdparty.NewHTTPClient(),
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# To generate mocks, from status-go root directory:
|
||||
mockgen -source=services/wallet/bridge/bridge.go -destination=services/wallet/bridge/mock_bridge/bridge.go -package=mock_bridge
|
|
@ -0,0 +1,192 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: services/wallet/bridge/bridge.go
|
||||
|
||||
// Package mock_bridge is a generated GoMock package.
|
||||
package mock_bridge
|
||||
|
||||
import (
|
||||
big "math/big"
|
||||
reflect "reflect"
|
||||
|
||||
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"
|
||||
bridge "github.com/status-im/status-go/services/wallet/bridge"
|
||||
token "github.com/status-im/status-go/services/wallet/token"
|
||||
)
|
||||
|
||||
// MockBridge is a mock of Bridge interface.
|
||||
type MockBridge struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockBridgeMockRecorder
|
||||
}
|
||||
|
||||
// MockBridgeMockRecorder is the mock recorder for MockBridge.
|
||||
type MockBridgeMockRecorder struct {
|
||||
mock *MockBridge
|
||||
}
|
||||
|
||||
// NewMockBridge creates a new mock instance.
|
||||
func NewMockBridge(ctrl *gomock.Controller) *MockBridge {
|
||||
mock := &MockBridge{ctrl: ctrl}
|
||||
mock.recorder = &MockBridgeMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockBridge) EXPECT() *MockBridgeMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AvailableFor mocks base method.
|
||||
func (m *MockBridge) AvailableFor(from, to *params.Network, token, toToken *token.Token) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AvailableFor", from, to, token, toToken)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AvailableFor indicates an expected call of AvailableFor.
|
||||
func (mr *MockBridgeMockRecorder) AvailableFor(from, to, token, toToken interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AvailableFor", reflect.TypeOf((*MockBridge)(nil).AvailableFor), from, to, token, toToken)
|
||||
}
|
||||
|
||||
// BuildTransaction mocks base method.
|
||||
func (m *MockBridge) BuildTransaction(sendArgs *bridge.TransactionBridge) (*types.Transaction, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BuildTransaction", sendArgs)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BuildTransaction indicates an expected call of BuildTransaction.
|
||||
func (mr *MockBridgeMockRecorder) BuildTransaction(sendArgs interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildTransaction", reflect.TypeOf((*MockBridge)(nil).BuildTransaction), sendArgs)
|
||||
}
|
||||
|
||||
// BuildTx mocks base method.
|
||||
func (m *MockBridge) BuildTx(fromNetwork, toNetwork *params.Network, fromAddress, toAddress common.Address, token *token.Token, amountIn, bonderFee *big.Int) (*types.Transaction, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BuildTx", fromNetwork, toNetwork, fromAddress, toAddress, token, amountIn, bonderFee)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BuildTx indicates an expected call of BuildTx.
|
||||
func (mr *MockBridgeMockRecorder) BuildTx(fromNetwork, toNetwork, fromAddress, toAddress, token, amountIn, bonderFee interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildTx", reflect.TypeOf((*MockBridge)(nil).BuildTx), fromNetwork, toNetwork, fromAddress, toAddress, token, amountIn, bonderFee)
|
||||
}
|
||||
|
||||
// CalculateAmountOut mocks base method.
|
||||
func (m *MockBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CalculateAmountOut", from, to, amountIn, symbol)
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CalculateAmountOut indicates an expected call of CalculateAmountOut.
|
||||
func (mr *MockBridgeMockRecorder) CalculateAmountOut(from, to, amountIn, symbol interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateAmountOut", reflect.TypeOf((*MockBridge)(nil).CalculateAmountOut), from, to, amountIn, symbol)
|
||||
}
|
||||
|
||||
// CalculateFees mocks base method.
|
||||
func (m *MockBridge) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CalculateFees", from, to, token, amountIn)
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
ret1, _ := ret[1].(*big.Int)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// CalculateFees indicates an expected call of CalculateFees.
|
||||
func (mr *MockBridgeMockRecorder) CalculateFees(from, to, token, amountIn interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateFees", reflect.TypeOf((*MockBridge)(nil).CalculateFees), from, to, token, amountIn)
|
||||
}
|
||||
|
||||
// EstimateGas mocks base method.
|
||||
func (m *MockBridge) EstimateGas(fromNetwork, toNetwork *params.Network, from, to common.Address, token, toToken *token.Token, amountIn *big.Int) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EstimateGas", fromNetwork, toNetwork, from, to, token, toToken, amountIn)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// EstimateGas indicates an expected call of EstimateGas.
|
||||
func (mr *MockBridgeMockRecorder) EstimateGas(fromNetwork, toNetwork, from, to, token, toToken, amountIn interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateGas", reflect.TypeOf((*MockBridge)(nil).EstimateGas), fromNetwork, toNetwork, from, to, token, toToken, amountIn)
|
||||
}
|
||||
|
||||
// GetContractAddress mocks base method.
|
||||
func (m *MockBridge) GetContractAddress(network *params.Network, token *token.Token) (common.Address, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetContractAddress", network, token)
|
||||
ret0, _ := ret[0].(common.Address)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetContractAddress indicates an expected call of GetContractAddress.
|
||||
func (mr *MockBridgeMockRecorder) GetContractAddress(network, token interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContractAddress", reflect.TypeOf((*MockBridge)(nil).GetContractAddress), network, token)
|
||||
}
|
||||
|
||||
// Name mocks base method.
|
||||
func (m *MockBridge) Name() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Name")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Name indicates an expected call of Name.
|
||||
func (mr *MockBridgeMockRecorder) Name() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockBridge)(nil).Name))
|
||||
}
|
||||
|
||||
// PackTxInputData mocks base method.
|
||||
func (m *MockBridge) PackTxInputData(contractType string, fromNetwork, toNetwork *params.Network, from, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PackTxInputData", contractType, fromNetwork, toNetwork, from, to, token, amountIn)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PackTxInputData indicates an expected call of PackTxInputData.
|
||||
func (mr *MockBridgeMockRecorder) PackTxInputData(contractType, fromNetwork, toNetwork, from, to, token, amountIn interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackTxInputData", reflect.TypeOf((*MockBridge)(nil).PackTxInputData), contractType, fromNetwork, toNetwork, from, to, token, amountIn)
|
||||
}
|
||||
|
||||
// Send mocks base method.
|
||||
func (m *MockBridge) Send(sendArgs *bridge.TransactionBridge, verifiedAccount *account.SelectedExtKey) (types0.Hash, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Send", sendArgs, verifiedAccount)
|
||||
ret0, _ := ret[0].(types0.Hash)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Send indicates an expected call of Send.
|
||||
func (mr *MockBridgeMockRecorder) Send(sendArgs, verifiedAccount interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockBridge)(nil).Send), sendArgs, verifiedAccount)
|
||||
}
|
|
@ -28,10 +28,10 @@ type SwapTxArgs struct {
|
|||
type SwapParaswap struct {
|
||||
paraswapClient *paraswap.ClientV5
|
||||
priceRoute paraswap.Route
|
||||
transactor *transactions.Transactor
|
||||
transactor transactions.TransactorIface
|
||||
}
|
||||
|
||||
func NewSwapParaswap(rpcClient *rpc.Client, transactor *transactions.Transactor, tokenManager *walletToken.Manager) *SwapParaswap {
|
||||
func NewSwapParaswap(rpcClient *rpc.Client, transactor transactions.TransactorIface, tokenManager *walletToken.Manager) *SwapParaswap {
|
||||
return &SwapParaswap{
|
||||
paraswapClient: paraswap.NewClientV5(walletCommon.EthereumMainnet),
|
||||
transactor: transactor,
|
||||
|
|
|
@ -21,10 +21,10 @@ import (
|
|||
|
||||
type TransferBridge struct {
|
||||
rpcClient *rpc.Client
|
||||
transactor *transactions.Transactor
|
||||
transactor transactions.TransactorIface
|
||||
}
|
||||
|
||||
func NewTransferBridge(rpcClient *rpc.Client, transactor *transactions.Transactor) *TransferBridge {
|
||||
func NewTransferBridge(rpcClient *rpc.Client, transactor transactions.TransactorIface) *TransferBridge {
|
||||
return &TransferBridge{rpcClient: rpcClient, transactor: transactor}
|
||||
}
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ func (tm *TransactionManager) removeMultiTransactionByAddress(address common.Add
|
|||
|
||||
details := NewMultiTxDetails()
|
||||
details.FromAddress = address
|
||||
mtxs, err := tm.storage.ReadMultiTransactionsByDetails(details)
|
||||
mtxs, err := tm.storage.ReadMultiTransactions(details)
|
||||
|
||||
ids := make([]wallet_common.MultiTransactionIDType, 0)
|
||||
for _, mtx := range mtxs {
|
||||
|
|
|
@ -9,20 +9,38 @@ import (
|
|||
wallet_common "github.com/status-im/status-go/services/wallet/common"
|
||||
)
|
||||
|
||||
// DO NOT CREATE IT MANUALLY! Use NewMultiTxDetails() instead
|
||||
// Since we already use MultitransactionIDType in DB, and its default value is 0 (Send)
|
||||
// this type is used to with default value 0 to represent invalid type to avoid bugs
|
||||
// when devs forget to call NewMultiTxDetails()
|
||||
type MultiTransactionDBType MultiTransactionType
|
||||
|
||||
const (
|
||||
MultiTransactionDBTypeInvalid = 0
|
||||
MultiTransactionDBSend = iota
|
||||
MultiTransactionDBSwap
|
||||
MultiTransactionDBBridge
|
||||
)
|
||||
|
||||
func mtDBTypeToMTType(mtDBType MultiTransactionDBType) MultiTransactionType {
|
||||
if mtDBType == MultiTransactionDBTypeInvalid {
|
||||
return MultiTransactionTypeInvalid
|
||||
}
|
||||
|
||||
return MultiTransactionType(mtDBType - 1)
|
||||
}
|
||||
|
||||
type MultiTxDetails struct {
|
||||
IDs []wallet_common.MultiTransactionIDType
|
||||
AnyAddress common.Address
|
||||
FromAddress common.Address
|
||||
ToAddress common.Address
|
||||
ToChainID uint64
|
||||
CrossTxID string
|
||||
Type MultiTransactionType
|
||||
Type MultiTransactionDBType
|
||||
}
|
||||
|
||||
func NewMultiTxDetails() *MultiTxDetails {
|
||||
details := &MultiTxDetails{}
|
||||
details.Type = MultiTransactionTypeInvalid
|
||||
return details
|
||||
return &MultiTxDetails{}
|
||||
}
|
||||
|
||||
type MultiTransactionDB struct {
|
||||
|
@ -65,34 +83,7 @@ func (mtDB *MultiTransactionDB) CreateMultiTransaction(multiTransaction *MultiTr
|
|||
return err
|
||||
}
|
||||
|
||||
func (mtDB *MultiTransactionDB) ReadMultiTransactions(ids []wallet_common.MultiTransactionIDType) ([]*MultiTransaction, error) {
|
||||
placeholders := make([]string, len(ids))
|
||||
args := make([]interface{}, len(ids))
|
||||
for i, v := range ids {
|
||||
placeholders[i] = "?"
|
||||
args[i] = v
|
||||
}
|
||||
|
||||
stmt, err := mtDB.db.Prepare(fmt.Sprintf(`SELECT %s
|
||||
FROM multi_transactions
|
||||
WHERE id in (%s)`,
|
||||
selectMultiTransactionColumns,
|
||||
strings.Join(placeholders, ",")))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query(args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
return rowsToMultiTransactions(rows)
|
||||
}
|
||||
|
||||
func (mtDB *MultiTransactionDB) ReadMultiTransactionsByDetails(details *MultiTxDetails) ([]*MultiTransaction, error) {
|
||||
func (mtDB *MultiTransactionDB) ReadMultiTransactions(details *MultiTxDetails) ([]*MultiTransaction, error) {
|
||||
if details == nil {
|
||||
return nil, fmt.Errorf("details is nil")
|
||||
}
|
||||
|
@ -101,6 +92,14 @@ func (mtDB *MultiTransactionDB) ReadMultiTransactionsByDetails(details *MultiTxD
|
|||
|
||||
args := []interface{}{}
|
||||
|
||||
if len(details.IDs) > 0 {
|
||||
placeholders := make([]string, len(details.IDs))
|
||||
for i, v := range details.IDs {
|
||||
placeholders[i] = "?"
|
||||
args = append(args, v)
|
||||
}
|
||||
whereClause += fmt.Sprintf("id in (%s) AND ", strings.Join(placeholders, ","))
|
||||
}
|
||||
if (details.AnyAddress != common.Address{}) {
|
||||
whereClause += "(from_address=? OR to_address=?) AND "
|
||||
args = append(args, details.AnyAddress, details.AnyAddress)
|
||||
|
@ -121,9 +120,9 @@ func (mtDB *MultiTransactionDB) ReadMultiTransactionsByDetails(details *MultiTxD
|
|||
whereClause += "cross_tx_id=? AND "
|
||||
args = append(args, details.CrossTxID)
|
||||
}
|
||||
if details.Type != MultiTransactionTypeInvalid {
|
||||
if details.Type != MultiTransactionDBTypeInvalid {
|
||||
whereClause += "type=? AND "
|
||||
args = append(args, details.Type)
|
||||
args = append(args, mtDBTypeToMTType(details.Type))
|
||||
}
|
||||
|
||||
stmt, err := mtDB.db.Prepare(fmt.Sprintf(`SELECT %s
|
||||
|
|
|
@ -32,7 +32,9 @@ func TestCreateMultiTransaction(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// Add assertions here to verify the result of the CreateMultiTransaction method
|
||||
mtx, err := mtDB.ReadMultiTransactions([]wallet_common.MultiTransactionIDType{multiTransaction.ID})
|
||||
details := NewMultiTxDetails()
|
||||
details.IDs = []wallet_common.MultiTransactionIDType{multiTransaction.ID}
|
||||
mtx, err := mtDB.ReadMultiTransactions(details)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, mtx, 1)
|
||||
require.True(t, areMultiTransactionsEqual(&multiTransaction, mtx[0]))
|
||||
|
@ -50,6 +52,9 @@ func TestReadMultiTransactions(t *testing.T) {
|
|||
tr3 := generateTestTransfer(3)
|
||||
mt3 := GenerateTestSwapMultiTransaction(tr3, "SNT", 100)
|
||||
|
||||
require.NotEqual(t, mt1.ID, mt2.ID)
|
||||
require.NotEqual(t, mt1.ID, mt3.ID)
|
||||
|
||||
err := mtDB.CreateMultiTransaction(&mt1)
|
||||
require.NoError(t, err)
|
||||
err = mtDB.CreateMultiTransaction(&mt2)
|
||||
|
@ -58,8 +63,9 @@ func TestReadMultiTransactions(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// Read multi transactions
|
||||
ids := []wallet_common.MultiTransactionIDType{mt1.ID, mt2.ID, mt3.ID}
|
||||
mtx, err := mtDB.ReadMultiTransactions(ids)
|
||||
details := NewMultiTxDetails()
|
||||
details.IDs = []wallet_common.MultiTransactionIDType{mt1.ID, mt2.ID, mt3.ID}
|
||||
mtx, err := mtDB.ReadMultiTransactions(details)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, mtx, 3)
|
||||
require.True(t, areMultiTransactionsEqual(&mt1, mtx[0]))
|
||||
|
@ -96,7 +102,9 @@ func TestUpdateMultiTransaction(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// Read the updated multi transaction
|
||||
mtx, err := mtDB.ReadMultiTransactions([]wallet_common.MultiTransactionIDType{multiTransaction.ID})
|
||||
details := NewMultiTxDetails()
|
||||
details.IDs = []wallet_common.MultiTransactionIDType{multiTransaction.ID}
|
||||
mtx, err := mtDB.ReadMultiTransactions(details)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, mtx, 1)
|
||||
require.True(t, areMultiTransactionsEqual(&multiTransaction, mtx[0]))
|
||||
|
@ -118,7 +126,8 @@ func TestDeleteMultiTransaction(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// Read the deleted multi transaction
|
||||
mtx, err := mtDB.ReadMultiTransactions([]wallet_common.MultiTransactionIDType{multiTransaction.ID})
|
||||
mtx, err := mtDB.ReadMultiTransactions(&MultiTxDetails{
|
||||
IDs: []wallet_common.MultiTransactionIDType{multiTransaction.ID}})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, mtx, 0)
|
||||
}
|
||||
|
|
|
@ -37,6 +37,11 @@ type TestTransfer struct {
|
|||
Token *token.Token
|
||||
}
|
||||
|
||||
type TestCollectibleTransfer struct {
|
||||
TestTransfer
|
||||
TestCollectible
|
||||
}
|
||||
|
||||
func SeedToToken(seed int) *token.Token {
|
||||
tokenIndex := seed % len(TestTokens)
|
||||
return TestTokens[tokenIndex]
|
||||
|
@ -79,6 +84,28 @@ func generateTestTransfer(seed int) TestTransfer {
|
|||
}
|
||||
}
|
||||
|
||||
// Will be used in tests to generate a collectible transfer
|
||||
// nolint:unused
|
||||
func generateTestCollectibleTransfer(seed int) TestCollectibleTransfer {
|
||||
collectibleIndex := seed % len(TestCollectibles)
|
||||
collectible := TestCollectibles[collectibleIndex]
|
||||
tr := TestCollectibleTransfer{
|
||||
TestTransfer: TestTransfer{
|
||||
TestTransaction: generateTestTransaction(seed),
|
||||
To: eth_common.HexToAddress(fmt.Sprintf("0x3%d", seed)),
|
||||
Value: int64(seed),
|
||||
Token: &token.Token{
|
||||
Address: collectible.TokenAddress,
|
||||
Name: "Collectible",
|
||||
ChainID: uint64(collectible.ChainID),
|
||||
},
|
||||
},
|
||||
TestCollectible: collectible,
|
||||
}
|
||||
tr.TestTransaction.ChainID = collectible.ChainID
|
||||
return tr
|
||||
}
|
||||
|
||||
func GenerateTestSendMultiTransaction(tr TestTransfer) MultiTransaction {
|
||||
return MultiTransaction{
|
||||
ID: multiTransactionIDGenerator(),
|
||||
|
@ -422,21 +449,13 @@ func (s *InMemMultiTransactionStorage) DeleteMultiTransaction(id common.MultiTra
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *InMemMultiTransactionStorage) ReadMultiTransactions(ids []common.MultiTransactionIDType) ([]*MultiTransaction, error) {
|
||||
var multiTxs []*MultiTransaction
|
||||
for _, id := range ids {
|
||||
multiTx, ok := s.storage[id]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
multiTxs = append(multiTxs, multiTx)
|
||||
}
|
||||
return multiTxs, nil
|
||||
}
|
||||
|
||||
func (s *InMemMultiTransactionStorage) ReadMultiTransactionsByDetails(details *MultiTxDetails) ([]*MultiTransaction, error) {
|
||||
func (s *InMemMultiTransactionStorage) ReadMultiTransactions(details *MultiTxDetails) ([]*MultiTransaction, error) {
|
||||
var multiTxs []*MultiTransaction
|
||||
for _, multiTx := range s.storage {
|
||||
if len(details.IDs) > 0 && !testutils.SliceContains(details.IDs, multiTx.ID) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (details.AnyAddress != eth_common.Address{}) &&
|
||||
(multiTx.FromAddress != details.AnyAddress && multiTx.ToAddress != details.AnyAddress) {
|
||||
continue
|
||||
|
@ -454,7 +473,7 @@ func (s *InMemMultiTransactionStorage) ReadMultiTransactionsByDetails(details *M
|
|||
continue
|
||||
}
|
||||
|
||||
if details.Type != MultiTransactionTypeInvalid && multiTx.Type != details.Type {
|
||||
if details.Type != MultiTransactionDBTypeInvalid && multiTx.Type != mtDBTypeToMTType(details.Type) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ type TransactionDescription struct {
|
|||
type TransactionManager struct {
|
||||
storage MultiTransactionStorage
|
||||
gethManager *account.GethManager
|
||||
transactor *transactions.Transactor
|
||||
transactor transactions.TransactorIface
|
||||
config *params.NodeConfig
|
||||
accountsDB *accounts.Database
|
||||
pendingTracker *transactions.PendingTxTracker
|
||||
|
@ -49,8 +49,7 @@ type TransactionManager struct {
|
|||
|
||||
type MultiTransactionStorage interface {
|
||||
CreateMultiTransaction(tx *MultiTransaction) error
|
||||
ReadMultiTransactions(ids []wallet_common.MultiTransactionIDType) ([]*MultiTransaction, error)
|
||||
ReadMultiTransactionsByDetails(details *MultiTxDetails) ([]*MultiTransaction, error)
|
||||
ReadMultiTransactions(details *MultiTxDetails) ([]*MultiTransaction, error)
|
||||
UpdateMultiTransaction(tx *MultiTransaction) error
|
||||
DeleteMultiTransaction(id wallet_common.MultiTransactionIDType) error
|
||||
}
|
||||
|
@ -58,7 +57,7 @@ type MultiTransactionStorage interface {
|
|||
func NewTransactionManager(
|
||||
storage MultiTransactionStorage,
|
||||
gethManager *account.GethManager,
|
||||
transactor *transactions.Transactor,
|
||||
transactor transactions.TransactorIface,
|
||||
config *params.NodeConfig,
|
||||
accountsDB *accounts.Database,
|
||||
pendingTxManager *transactions.PendingTxTracker,
|
||||
|
|
|
@ -23,7 +23,7 @@ func (tm *TransactionManager) UpdateMultiTransaction(multiTransaction *MultiTran
|
|||
return tm.storage.UpdateMultiTransaction(multiTransaction)
|
||||
}
|
||||
|
||||
func (tm *TransactionManager) CreateMultiTransactionFromCommand(ctx context.Context, command *MultiTransactionCommand,
|
||||
func (tm *TransactionManager) CreateMultiTransactionFromCommand(command *MultiTransactionCommand,
|
||||
data []*bridge.TransactionBridge) (*MultiTransaction, error) {
|
||||
|
||||
multiTransaction := multiTransactionFromCommand(command)
|
||||
|
@ -107,7 +107,7 @@ func (tm *TransactionManager) ProceedWithTransactionsSignatures(ctx context.Cont
|
|||
}
|
||||
|
||||
func (tm *TransactionManager) GetMultiTransactions(ctx context.Context, ids []wallet_common.MultiTransactionIDType) ([]*MultiTransaction, error) {
|
||||
return tm.storage.ReadMultiTransactions(ids)
|
||||
return tm.storage.ReadMultiTransactions(&MultiTxDetails{IDs: ids})
|
||||
}
|
||||
|
||||
func (tm *TransactionManager) GetBridgeOriginMultiTransaction(ctx context.Context, toChainID uint64, crossTxID string) (*MultiTransaction, error) {
|
||||
|
@ -115,7 +115,7 @@ func (tm *TransactionManager) GetBridgeOriginMultiTransaction(ctx context.Contex
|
|||
details.ToChainID = toChainID
|
||||
details.CrossTxID = crossTxID
|
||||
|
||||
multiTxs, err := tm.storage.ReadMultiTransactionsByDetails(details)
|
||||
multiTxs, err := tm.storage.ReadMultiTransactions(details)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ func (tm *TransactionManager) GetBridgeDestinationMultiTransaction(ctx context.C
|
|||
details.ToChainID = toChainID
|
||||
details.CrossTxID = crossTxID
|
||||
|
||||
multiTxs, err := tm.storage.ReadMultiTransactionsByDetails(details)
|
||||
multiTxs, err := tm.storage.ReadMultiTransactions(details)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
package transfer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/rpc"
|
||||
"github.com/status-im/status-go/services/wallet/bridge"
|
||||
"github.com/status-im/status-go/services/wallet/bridge/mock_bridge"
|
||||
"github.com/status-im/status-go/transactions"
|
||||
"github.com/status-im/status-go/transactions/mock_transactor"
|
||||
)
|
||||
|
||||
func deepCopy(tx *transactions.SendTxArgs) *transactions.SendTxArgs {
|
||||
return &transactions.SendTxArgs{
|
||||
From: tx.From,
|
||||
To: tx.To,
|
||||
Value: tx.Value,
|
||||
Data: tx.Data,
|
||||
}
|
||||
}
|
||||
|
||||
func deepCopyTransactionBridgeWithTransferTx(tx *bridge.TransactionBridge) *bridge.TransactionBridge {
|
||||
return &bridge.TransactionBridge{
|
||||
BridgeName: tx.BridgeName,
|
||||
ChainID: tx.ChainID,
|
||||
TransferTx: deepCopy(tx.TransferTx),
|
||||
HopTx: tx.HopTx,
|
||||
CbridgeTx: tx.CbridgeTx,
|
||||
ERC721TransferTx: tx.ERC721TransferTx,
|
||||
ERC1155TransferTx: tx.ERC1155TransferTx,
|
||||
SwapTx: tx.SwapTx,
|
||||
}
|
||||
}
|
||||
|
||||
func setupTransactionManager(t *testing.T) (*TransactionManager, *mock_transactor.MockTransactorIface, *gomock.Controller) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
// Create a mock transactor
|
||||
transactor := mock_transactor.NewMockTransactorIface(ctrl)
|
||||
// Create a new instance of the TransactionManager
|
||||
tm := NewTransactionManager(NewInMemMultiTransactionStorage(), nil, transactor, nil, nil, nil, nil)
|
||||
|
||||
return tm, transactor, ctrl
|
||||
}
|
||||
|
||||
func setupAccount(_ *testing.T, address common.Address) *account.SelectedExtKey {
|
||||
// Dummy account
|
||||
return &account.SelectedExtKey{
|
||||
Address: types.Address(address),
|
||||
AccountKey: &types.Key{},
|
||||
}
|
||||
}
|
||||
|
||||
func setupTransactionData(_ *testing.T, transactor transactions.TransactorIface) (*MultiTransaction, []*bridge.TransactionBridge, map[string]bridge.Bridge, []*bridge.TransactionBridge) {
|
||||
SetMultiTransactionIDGenerator(StaticIDCounter())
|
||||
|
||||
// Create mock data for the test
|
||||
ethTransfer := generateTestTransfer(0)
|
||||
multiTransaction := GenerateTestSendMultiTransaction(ethTransfer)
|
||||
|
||||
// Initialize the bridges
|
||||
var rpcClient *rpc.Client = nil
|
||||
bridges := make(map[string]bridge.Bridge)
|
||||
transferBridge := bridge.NewTransferBridge(rpcClient, transactor)
|
||||
bridges[transferBridge.Name()] = transferBridge
|
||||
|
||||
data := []*bridge.TransactionBridge{
|
||||
{
|
||||
ChainID: 1,
|
||||
BridgeName: transferBridge.Name(),
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(ethTransfer.From),
|
||||
To: (*types.Address)(ðTransfer.To),
|
||||
Value: (*hexutil.Big)(big.NewInt(ethTransfer.Value / 3)),
|
||||
Data: types.HexBytes("0x0"),
|
||||
// Symbol: multiTransaction.FromAsset, // This will be set by transaction manager
|
||||
// MultiTransactionID: multiTransaction.ID, // This will be set by transaction manager
|
||||
},
|
||||
},
|
||||
{
|
||||
ChainID: 420,
|
||||
BridgeName: transferBridge.Name(),
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(ethTransfer.From),
|
||||
To: (*types.Address)(ðTransfer.To),
|
||||
Value: (*hexutil.Big)(big.NewInt(ethTransfer.Value * 2 / 3)),
|
||||
Data: types.HexBytes("0x0"),
|
||||
// Symbol: multiTransaction.FromAsset, // This will be set by transaction manager
|
||||
// MultiTransactionID: multiTransaction.ID, // This will be set by transaction manager
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expectedData := make([]*bridge.TransactionBridge, 0)
|
||||
for _, tx := range data {
|
||||
txCopy := deepCopyTransactionBridgeWithTransferTx(tx)
|
||||
updateDataFromMultiTx([]*bridge.TransactionBridge{txCopy}, &multiTransaction)
|
||||
expectedData = append(expectedData, txCopy)
|
||||
}
|
||||
|
||||
return &multiTransaction, data, bridges, expectedData
|
||||
}
|
||||
|
||||
func TestSendTransactionsETHSuccess(t *testing.T) {
|
||||
tm, transactor, _ := setupTransactionManager(t)
|
||||
account := setupAccount(t, common.HexToAddress("0x1234567890abcdef1234567890abcdef12345678"))
|
||||
multiTransaction, data, bridges, expectedData := setupTransactionData(t, transactor)
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// Call the SendTransactions method
|
||||
_, err := tm.SendTransactions(context.Background(), multiTransaction, data, bridges, account)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSendTransactionsETHFailOnBridge(t *testing.T) {
|
||||
tm, transactor, ctrl := setupTransactionManager(t)
|
||||
account := setupAccount(t, common.HexToAddress("0x1234567890abcdef1234567890abcdef12345678"))
|
||||
multiTransaction, data, _, _ := setupTransactionData(t, transactor)
|
||||
|
||||
// Initialize the bridges
|
||||
bridges := make(map[string]bridge.Bridge)
|
||||
transferBridge := mock_bridge.NewMockBridge(ctrl)
|
||||
|
||||
// Set bridge name for the mock to the one used in data
|
||||
transferBridge.EXPECT().Name().Return(data[0].BridgeName).AnyTimes()
|
||||
bridges[transferBridge.Name()] = transferBridge
|
||||
|
||||
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)
|
||||
|
||||
// Call the SendTransactions method
|
||||
_, err := tm.SendTransactions(context.Background(), multiTransaction, data, bridges, account)
|
||||
require.Error(t, expectedErr, err)
|
||||
}
|
||||
|
||||
func TestSendTransactionsETHFailOnTransactor(t *testing.T) {
|
||||
tm, transactor, _ := setupTransactionManager(t)
|
||||
account := setupAccount(t, common.HexToAddress("0x1234567890abcdef1234567890abcdef12345678"))
|
||||
multiTransaction, data, bridges, expectedData := setupTransactionData(t, transactor)
|
||||
|
||||
// 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)
|
||||
|
||||
// Call the SendTransactions method
|
||||
_, err := tm.SendTransactions(context.Background(), multiTransaction, data, bridges, account)
|
||||
require.Error(t, expectedErr, err)
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
# To generate mocks, from status-go root directory:
|
||||
mockgen -source=transactions/transactor.go -destination=transactions/mock_transactor/transactor.go -package=mock_transactor
|
|
@ -0,0 +1,177 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: transactions/transactor.go
|
||||
|
||||
// Package mock_transactor is a generated GoMock package.
|
||||
package mock_transactor
|
||||
|
||||
import (
|
||||
big "math/big"
|
||||
reflect "reflect"
|
||||
|
||||
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"
|
||||
rpc "github.com/status-im/status-go/rpc"
|
||||
common0 "github.com/status-im/status-go/services/wallet/common"
|
||||
transactions "github.com/status-im/status-go/transactions"
|
||||
)
|
||||
|
||||
// MockTransactorIface is a mock of TransactorIface interface.
|
||||
type MockTransactorIface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockTransactorIfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockTransactorIfaceMockRecorder is the mock recorder for MockTransactorIface.
|
||||
type MockTransactorIfaceMockRecorder struct {
|
||||
mock *MockTransactorIface
|
||||
}
|
||||
|
||||
// NewMockTransactorIface creates a new mock instance.
|
||||
func NewMockTransactorIface(ctrl *gomock.Controller) *MockTransactorIface {
|
||||
mock := &MockTransactorIface{ctrl: ctrl}
|
||||
mock.recorder = &MockTransactorIfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockTransactorIface) EXPECT() *MockTransactorIfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AddSignatureToTransaction mocks base method.
|
||||
func (m *MockTransactorIface) AddSignatureToTransaction(chainID uint64, tx *types.Transaction, sig []byte) (*types.Transaction, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AddSignatureToTransaction", chainID, tx, sig)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AddSignatureToTransaction indicates an expected call of AddSignatureToTransaction.
|
||||
func (mr *MockTransactorIfaceMockRecorder) AddSignatureToTransaction(chainID, tx, sig interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSignatureToTransaction", reflect.TypeOf((*MockTransactorIface)(nil).AddSignatureToTransaction), chainID, tx, sig)
|
||||
}
|
||||
|
||||
// BuildTransactionWithSignature mocks base method.
|
||||
func (m *MockTransactorIface) BuildTransactionWithSignature(chainID uint64, args transactions.SendTxArgs, sig []byte) (*types.Transaction, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BuildTransactionWithSignature", chainID, args, sig)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BuildTransactionWithSignature indicates an expected call of BuildTransactionWithSignature.
|
||||
func (mr *MockTransactorIfaceMockRecorder) BuildTransactionWithSignature(chainID, args, sig interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildTransactionWithSignature", reflect.TypeOf((*MockTransactorIface)(nil).BuildTransactionWithSignature), chainID, args, sig)
|
||||
}
|
||||
|
||||
// EstimateGas mocks base method.
|
||||
func (m *MockTransactorIface) EstimateGas(network *params.Network, from, to common.Address, value *big.Int, input []byte) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EstimateGas", network, from, to, value, input)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// EstimateGas indicates an expected call of EstimateGas.
|
||||
func (mr *MockTransactorIfaceMockRecorder) EstimateGas(network, from, to, value, input interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateGas", reflect.TypeOf((*MockTransactorIface)(nil).EstimateGas), network, from, to, value, input)
|
||||
}
|
||||
|
||||
// NextNonce mocks base method.
|
||||
func (m *MockTransactorIface) NextNonce(rpcClient *rpc.Client, chainID uint64, from types0.Address) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "NextNonce", rpcClient, chainID, from)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// NextNonce indicates an expected call of NextNonce.
|
||||
func (mr *MockTransactorIfaceMockRecorder) NextNonce(rpcClient, chainID, from interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NextNonce", reflect.TypeOf((*MockTransactorIface)(nil).NextNonce), rpcClient, chainID, from)
|
||||
}
|
||||
|
||||
// SendRawTransaction mocks base method.
|
||||
func (m *MockTransactorIface) SendRawTransaction(chainID uint64, rawTx string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SendRawTransaction", chainID, rawTx)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SendRawTransaction indicates an expected call of SendRawTransaction.
|
||||
func (mr *MockTransactorIfaceMockRecorder) SendRawTransaction(chainID, rawTx interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendRawTransaction", reflect.TypeOf((*MockTransactorIface)(nil).SendRawTransaction), chainID, rawTx)
|
||||
}
|
||||
|
||||
// SendTransaction mocks base method.
|
||||
func (m *MockTransactorIface) SendTransaction(sendArgs transactions.SendTxArgs, verifiedAccount *account.SelectedExtKey) (types0.Hash, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SendTransaction", sendArgs, verifiedAccount)
|
||||
ret0, _ := ret[0].(types0.Hash)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SendTransaction indicates an expected call of SendTransaction.
|
||||
func (mr *MockTransactorIfaceMockRecorder) SendTransaction(sendArgs, verifiedAccount interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendTransaction", reflect.TypeOf((*MockTransactorIface)(nil).SendTransaction), sendArgs, verifiedAccount)
|
||||
}
|
||||
|
||||
// SendTransactionWithChainID mocks base method.
|
||||
func (m *MockTransactorIface) SendTransactionWithChainID(chainID uint64, sendArgs transactions.SendTxArgs, verifiedAccount *account.SelectedExtKey) (types0.Hash, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SendTransactionWithChainID", chainID, sendArgs, verifiedAccount)
|
||||
ret0, _ := ret[0].(types0.Hash)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SendTransactionWithChainID indicates an expected call of SendTransactionWithChainID.
|
||||
func (mr *MockTransactorIfaceMockRecorder) SendTransactionWithChainID(chainID, sendArgs, 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)
|
||||
}
|
||||
|
||||
// SendTransactionWithSignature mocks base method.
|
||||
func (m *MockTransactorIface) SendTransactionWithSignature(from common.Address, symbol string, multiTransactionID common0.MultiTransactionIDType, tx *types.Transaction) (types0.Hash, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SendTransactionWithSignature", from, symbol, multiTransactionID, tx)
|
||||
ret0, _ := ret[0].(types0.Hash)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SendTransactionWithSignature indicates an expected call of SendTransactionWithSignature.
|
||||
func (mr *MockTransactorIfaceMockRecorder) SendTransactionWithSignature(from, symbol, multiTransactionID, tx interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendTransactionWithSignature", reflect.TypeOf((*MockTransactorIface)(nil).SendTransactionWithSignature), from, symbol, multiTransactionID, tx)
|
||||
}
|
||||
|
||||
// ValidateAndBuildTransaction mocks base method.
|
||||
func (m *MockTransactorIface) ValidateAndBuildTransaction(chainID uint64, sendArgs transactions.SendTxArgs) (*types.Transaction, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidateAndBuildTransaction", chainID, sendArgs)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidateAndBuildTransaction indicates an expected call of ValidateAndBuildTransaction.
|
||||
func (mr *MockTransactorIfaceMockRecorder) ValidateAndBuildTransaction(chainID, sendArgs interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateAndBuildTransaction", reflect.TypeOf((*MockTransactorIface)(nil).ValidateAndBuildTransaction), chainID, sendArgs)
|
||||
}
|
|
@ -44,6 +44,19 @@ func (e *ErrBadNonce) Error() string {
|
|||
return fmt.Sprintf("bad nonce. expected %d, got %d", e.expectedNonce, e.nonce)
|
||||
}
|
||||
|
||||
// Transactor is an interface that defines the methods for validating and sending transactions.
|
||||
type TransactorIface interface {
|
||||
NextNonce(rpcClient *rpc.Client, 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)
|
||||
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)
|
||||
SendTransactionWithSignature(from common.Address, symbol string, multiTransactionID wallet_common.MultiTransactionIDType, tx *gethtypes.Transaction) (hash types.Hash, err error)
|
||||
}
|
||||
|
||||
// Transactor validates, signs transactions.
|
||||
// It uses upstream to propagate transactions to the Ethereum network.
|
||||
type Transactor struct {
|
||||
|
@ -218,29 +231,9 @@ func (t *Transactor) SendTransactionWithSignature(from common.Address, symbol st
|
|||
return t.sendTransaction(rpcWrapper, from, symbol, multiTransactionID, tx)
|
||||
}
|
||||
|
||||
func (t *Transactor) AddSignatureToTransactionAndSend(chainID uint64, from common.Address, symbol string,
|
||||
multiTransactionID wallet_common.MultiTransactionIDType, tx *gethtypes.Transaction, sig []byte) (hash types.Hash, err error) {
|
||||
txWithSignature, err := t.AddSignatureToTransaction(chainID, tx, sig)
|
||||
if err != nil {
|
||||
return hash, err
|
||||
}
|
||||
|
||||
return t.SendTransactionWithSignature(from, symbol, multiTransactionID, txWithSignature)
|
||||
}
|
||||
|
||||
// BuildTransactionAndSendWithSignature receive a transaction and a signature, serialize them together and propage it to the network.
|
||||
// BuildTransactionAndSendWithSignature receive a transaction and a signature, serialize them together
|
||||
// It's different from eth_sendRawTransaction because it receives a signature and not a serialized transaction with signature.
|
||||
// Since the transactions is already signed, we assume it was validated and used the right nonce.
|
||||
func (t *Transactor) BuildTransactionAndSendWithSignature(chainID uint64, args SendTxArgs, sig []byte) (hash types.Hash, err error) {
|
||||
txWithSignature, err := t.BuildTransactionWithSignature(chainID, args, sig)
|
||||
if err != nil {
|
||||
return hash, err
|
||||
}
|
||||
|
||||
hash, err = t.SendTransactionWithSignature(common.Address(args.From), args.Symbol, args.MultiTransactionID, txWithSignature)
|
||||
return hash, err
|
||||
}
|
||||
|
||||
func (t *Transactor) BuildTransactionWithSignature(chainID uint64, args SendTxArgs, sig []byte) (*gethtypes.Transaction, error) {
|
||||
if !args.Valid() {
|
||||
return nil, ErrInvalidSendTxArgs
|
||||
|
|
|
@ -313,11 +313,18 @@ func (s *TransactorSuite) TestSendTransactionWithSignature() {
|
|||
Return(common.Hash{}, nil)
|
||||
}
|
||||
|
||||
_, err = s.manager.BuildTransactionAndSendWithSignature(s.nodeConfig.NetworkID, args, sig)
|
||||
tx, err = s.manager.BuildTransactionWithSignature(s.nodeConfig.NetworkID, args, sig)
|
||||
if scenario.expectError {
|
||||
s.Error(err)
|
||||
} else {
|
||||
s.NoError(err)
|
||||
|
||||
_, err = s.manager.SendTransactionWithSignature(common.Address(args.From), args.Symbol, args.MultiTransactionID, tx)
|
||||
if scenario.expectError {
|
||||
s.Error(err)
|
||||
} else {
|
||||
s.NoError(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -325,7 +332,7 @@ func (s *TransactorSuite) TestSendTransactionWithSignature() {
|
|||
|
||||
func (s *TransactorSuite) TestSendTransactionWithSignature_InvalidSignature() {
|
||||
args := SendTxArgs{}
|
||||
_, err := s.manager.BuildTransactionAndSendWithSignature(1, args, []byte{})
|
||||
_, err := s.manager.BuildTransactionWithSignature(1, args, []byte{})
|
||||
s.Equal(ErrInvalidSignatureSize, err)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue