2017-10-11 14:20:51 +00:00
|
|
|
package transactions
|
2017-05-16 12:09:52 +00:00
|
|
|
|
|
|
|
import (
|
2019-08-29 08:06:22 +00:00
|
|
|
"io/ioutil"
|
2017-05-16 12:09:52 +00:00
|
|
|
"math/big"
|
2019-08-29 08:06:22 +00:00
|
|
|
"os"
|
2017-05-16 12:09:52 +00:00
|
|
|
"reflect"
|
2017-10-11 14:20:51 +00:00
|
|
|
"testing"
|
2017-05-16 12:09:52 +00:00
|
|
|
|
2020-01-02 09:10:19 +00:00
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
|
2017-05-16 12:09:52 +00:00
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
2020-01-02 09:10:19 +00:00
|
|
|
|
2018-06-08 11:29:50 +00:00
|
|
|
"github.com/status-im/status-go/account"
|
2019-12-11 13:59:37 +00:00
|
|
|
"github.com/status-im/status-go/eth-node/types"
|
2019-08-29 08:06:22 +00:00
|
|
|
"github.com/status-im/status-go/multiaccounts"
|
|
|
|
"github.com/status-im/status-go/multiaccounts/accounts"
|
2018-06-08 11:29:50 +00:00
|
|
|
"github.com/status-im/status-go/params"
|
2019-10-04 15:21:24 +00:00
|
|
|
"github.com/status-im/status-go/t/e2e"
|
|
|
|
"github.com/status-im/status-go/t/utils"
|
2018-06-08 11:29:50 +00:00
|
|
|
"github.com/status-im/status-go/transactions"
|
2017-05-16 12:09:52 +00:00
|
|
|
)
|
|
|
|
|
2018-04-04 17:39:38 +00:00
|
|
|
type initFunc func([]byte, *transactions.SendTxArgs)
|
2018-03-23 11:54:09 +00:00
|
|
|
|
2019-07-26 14:45:10 +00:00
|
|
|
func buildLoginParams(mainAccountAddress, chatAddress, password string) account.LoginParams {
|
|
|
|
return account.LoginParams{
|
2019-12-11 13:59:37 +00:00
|
|
|
ChatAddress: types.HexToAddress(chatAddress),
|
2019-07-26 14:45:10 +00:00
|
|
|
Password: password,
|
2019-12-11 13:59:37 +00:00
|
|
|
MainAccount: types.HexToAddress(mainAccountAddress),
|
2019-07-26 14:45:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-11 14:20:51 +00:00
|
|
|
func TestTransactionsTestSuite(t *testing.T) {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.Init()
|
2017-10-11 14:20:51 +00:00
|
|
|
suite.Run(t, new(TransactionsTestSuite))
|
|
|
|
}
|
|
|
|
|
|
|
|
type TransactionsTestSuite struct {
|
|
|
|
e2e.BackendTestSuite
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *TransactionsTestSuite) TestCallRPCSendTransaction() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID)
|
2018-04-18 15:13:27 +00:00
|
|
|
|
2017-10-23 16:03:07 +00:00
|
|
|
s.StartTestBackend()
|
2017-10-11 14:20:51 +00:00
|
|
|
defer s.StopTestBackend()
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.EnsureNodeSync(s.Backend.StatusNode().EnsureSync)
|
2017-10-11 14:20:51 +00:00
|
|
|
|
2018-08-07 14:21:43 +00:00
|
|
|
s.sendTransactionUsingRPCClient(s.Backend.CallRPC)
|
|
|
|
}
|
2017-10-11 14:20:51 +00:00
|
|
|
|
2018-08-07 14:21:43 +00:00
|
|
|
func (s *TransactionsTestSuite) TestCallUpstreamRPCSendTransaction() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID, params.StatusChainNetworkID)
|
2017-10-11 14:20:51 +00:00
|
|
|
|
2019-10-04 15:21:24 +00:00
|
|
|
addr, err := utils.GetRemoteURL()
|
2018-08-07 14:21:43 +00:00
|
|
|
s.NoError(err)
|
|
|
|
s.StartTestBackend(e2e.WithUpstream(addr))
|
|
|
|
defer s.StopTestBackend()
|
2018-04-10 10:02:54 +00:00
|
|
|
|
2018-08-07 14:21:43 +00:00
|
|
|
s.sendTransactionUsingRPCClient(s.Backend.CallRPC)
|
|
|
|
}
|
2017-10-11 14:20:51 +00:00
|
|
|
|
2018-08-07 14:21:43 +00:00
|
|
|
func (s *TransactionsTestSuite) TestCallPrivateRPCSendTransaction() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID)
|
2017-10-11 14:20:51 +00:00
|
|
|
|
2018-08-07 14:21:43 +00:00
|
|
|
s.StartTestBackend()
|
|
|
|
defer s.StopTestBackend()
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.EnsureNodeSync(s.Backend.StatusNode().EnsureSync)
|
2017-10-11 14:20:51 +00:00
|
|
|
|
2018-08-07 14:21:43 +00:00
|
|
|
s.sendTransactionUsingRPCClient(s.Backend.CallPrivateRPC)
|
2017-10-11 14:20:51 +00:00
|
|
|
}
|
|
|
|
|
2018-08-07 14:21:43 +00:00
|
|
|
func (s *TransactionsTestSuite) TestCallUpstreamPrivateRPCSendTransaction() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID, params.StatusChainNetworkID)
|
2017-10-26 12:33:42 +00:00
|
|
|
|
2019-10-04 15:21:24 +00:00
|
|
|
addr, err := utils.GetRemoteURL()
|
2017-10-25 12:37:42 +00:00
|
|
|
s.NoError(err)
|
|
|
|
s.StartTestBackend(e2e.WithUpstream(addr))
|
2017-10-11 14:20:51 +00:00
|
|
|
defer s.StopTestBackend()
|
|
|
|
|
2018-08-07 14:21:43 +00:00
|
|
|
s.sendTransactionUsingRPCClient(s.Backend.CallPrivateRPC)
|
|
|
|
}
|
|
|
|
|
2018-12-20 08:31:17 +00:00
|
|
|
func (s *TransactionsTestSuite) sendTransactionUsingRPCClient(
|
|
|
|
callRPCFn func(string) (string, error),
|
|
|
|
) {
|
2019-10-04 15:21:24 +00:00
|
|
|
err := s.Backend.SelectAccount(buildLoginParams(
|
|
|
|
utils.TestConfig.Account1.WalletAddress,
|
|
|
|
utils.TestConfig.Account1.ChatAddress,
|
|
|
|
utils.TestConfig.Account1.Password,
|
|
|
|
))
|
2017-10-11 14:20:51 +00:00
|
|
|
s.NoError(err)
|
|
|
|
|
2018-12-20 08:31:17 +00:00
|
|
|
result, err := callRPCFn(`{
|
2017-10-11 14:20:51 +00:00
|
|
|
"jsonrpc": "2.0",
|
|
|
|
"id": 1,
|
|
|
|
"method": "eth_sendTransaction",
|
|
|
|
"params": [{
|
2019-10-04 15:21:24 +00:00
|
|
|
"from": "` + utils.TestConfig.Account1.WalletAddress + `",
|
2018-08-16 11:37:53 +00:00
|
|
|
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
|
2017-10-11 14:20:51 +00:00
|
|
|
"value": "0x9184e72a"
|
|
|
|
}]
|
|
|
|
}`)
|
2018-12-20 08:31:17 +00:00
|
|
|
s.NoError(err)
|
2018-08-16 11:37:53 +00:00
|
|
|
s.Contains(result, `"error":{"code":-32700,"message":"method is unsupported by RPC interface"}`)
|
2017-10-11 14:20:51 +00:00
|
|
|
}
|
|
|
|
|
2018-04-07 19:16:32 +00:00
|
|
|
func (s *TransactionsTestSuite) TestEmptyToFieldPreserved() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID)
|
2018-04-18 15:13:27 +00:00
|
|
|
|
2019-08-29 08:06:22 +00:00
|
|
|
tmpdir, err := ioutil.TempDir("", "transactions-tests-")
|
|
|
|
s.Require().NoError(err)
|
|
|
|
defer os.Remove(tmpdir)
|
|
|
|
|
2019-12-11 13:59:37 +00:00
|
|
|
wallet := types.HexToAddress(utils.TestConfig.Account1.WalletAddress)
|
2019-12-05 08:00:57 +00:00
|
|
|
s.StartTestBackendWithAccount(multiaccounts.Account{KeyUID: utils.TestConfig.Account1.WalletAddress}, utils.TestConfig.Account1.Password,
|
2019-08-29 08:06:22 +00:00
|
|
|
[]accounts.Account{{Address: wallet, Wallet: true, Chat: true}},
|
|
|
|
e2e.WithDataDir(tmpdir),
|
|
|
|
)
|
|
|
|
defer s.LogoutAndStop()
|
2018-04-07 19:16:32 +00:00
|
|
|
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.EnsureNodeSync(s.Backend.StatusNode().EnsureSync)
|
2018-04-07 19:16:32 +00:00
|
|
|
|
2018-08-16 11:37:53 +00:00
|
|
|
args := transactions.SendTxArgs{
|
2019-12-19 18:27:27 +00:00
|
|
|
From: account.FromAddress(utils.TestConfig.Account1.WalletAddress),
|
2018-04-07 19:16:32 +00:00
|
|
|
}
|
2018-08-16 11:37:53 +00:00
|
|
|
|
2019-10-04 15:21:24 +00:00
|
|
|
hash, err := s.Backend.SendTransaction(args, utils.TestConfig.Account1.Password)
|
2018-08-16 11:37:53 +00:00
|
|
|
s.NoError(err)
|
|
|
|
s.NotNil(hash)
|
2018-04-07 19:16:32 +00:00
|
|
|
}
|
|
|
|
|
2018-03-23 11:54:09 +00:00
|
|
|
// TestSendContractCompat tries to send transaction using the legacy "Data"
|
|
|
|
// field, which is supported for backward compatibility reasons.
|
|
|
|
func (s *TransactionsTestSuite) TestSendContractTxCompat() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID)
|
2018-04-18 15:13:27 +00:00
|
|
|
|
2018-04-04 17:39:38 +00:00
|
|
|
initFunc := func(byteCode []byte, args *transactions.SendTxArgs) {
|
2019-12-19 18:27:27 +00:00
|
|
|
args.Data = (types.HexBytes)(byteCode)
|
2018-03-23 11:54:09 +00:00
|
|
|
}
|
|
|
|
s.testSendContractTx(initFunc, nil, "")
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestSendContractCompat tries to send transaction using both the legacy
|
|
|
|
// "Data" and "Input" fields. Also makes sure that the error is returned if
|
|
|
|
// they have different values.
|
|
|
|
func (s *TransactionsTestSuite) TestSendContractTxCollision() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID)
|
2018-04-18 15:13:27 +00:00
|
|
|
|
2018-03-23 11:54:09 +00:00
|
|
|
// Scenario 1: Both fields are filled and have the same value, expect success
|
2018-04-04 17:39:38 +00:00
|
|
|
initFunc := func(byteCode []byte, args *transactions.SendTxArgs) {
|
2019-12-19 18:27:27 +00:00
|
|
|
args.Input = (types.HexBytes)(byteCode)
|
|
|
|
args.Data = (types.HexBytes)(byteCode)
|
2018-03-23 11:54:09 +00:00
|
|
|
}
|
|
|
|
s.testSendContractTx(initFunc, nil, "")
|
|
|
|
|
|
|
|
// Scenario 2: Both fields are filled with different values, expect an error
|
|
|
|
inverted := func(source []byte) []byte {
|
|
|
|
inverse := make([]byte, len(source))
|
|
|
|
copy(inverse, source)
|
|
|
|
for i, b := range inverse {
|
|
|
|
inverse[i] = b ^ 0xFF
|
|
|
|
}
|
|
|
|
return inverse
|
|
|
|
}
|
|
|
|
|
2018-04-04 17:39:38 +00:00
|
|
|
initFunc2 := func(byteCode []byte, args *transactions.SendTxArgs) {
|
2019-12-19 18:27:27 +00:00
|
|
|
args.Input = (types.HexBytes)(byteCode)
|
|
|
|
args.Data = (types.HexBytes)(inverted(byteCode))
|
2018-03-23 11:54:09 +00:00
|
|
|
}
|
2018-04-04 17:39:38 +00:00
|
|
|
s.testSendContractTx(initFunc2, transactions.ErrInvalidSendTxArgs, "expected error when invalid tx args are sent")
|
2018-03-23 11:54:09 +00:00
|
|
|
}
|
|
|
|
|
2017-10-11 14:20:51 +00:00
|
|
|
func (s *TransactionsTestSuite) TestSendContractTx() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID)
|
2018-04-18 15:13:27 +00:00
|
|
|
|
2018-04-04 17:39:38 +00:00
|
|
|
initFunc := func(byteCode []byte, args *transactions.SendTxArgs) {
|
2019-12-19 18:27:27 +00:00
|
|
|
args.Input = (types.HexBytes)(byteCode)
|
2018-03-23 11:54:09 +00:00
|
|
|
}
|
|
|
|
s.testSendContractTx(initFunc, nil, "")
|
|
|
|
}
|
|
|
|
|
2018-04-10 10:02:54 +00:00
|
|
|
func (s *TransactionsTestSuite) testSendContractTx(setInputAndDataValue initFunc, expectedError error, expectedErrorDescription string) {
|
2019-08-29 08:06:22 +00:00
|
|
|
tmpdir, err := ioutil.TempDir("", "transactions-tests-")
|
|
|
|
s.Require().NoError(err)
|
|
|
|
defer os.Remove(tmpdir)
|
2018-04-10 10:02:54 +00:00
|
|
|
|
2019-12-11 13:59:37 +00:00
|
|
|
wallet := types.HexToAddress(utils.TestConfig.Account1.WalletAddress)
|
2019-12-05 08:00:57 +00:00
|
|
|
s.StartTestBackendWithAccount(multiaccounts.Account{KeyUID: utils.TestConfig.Account1.WalletAddress}, utils.TestConfig.Account1.Password,
|
2019-08-29 08:06:22 +00:00
|
|
|
[]accounts.Account{{Address: wallet, Wallet: true, Chat: true}},
|
|
|
|
e2e.WithDataDir(tmpdir),
|
|
|
|
)
|
|
|
|
defer s.LogoutAndStop()
|
2018-04-10 10:02:54 +00:00
|
|
|
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.EnsureNodeSync(s.Backend.StatusNode().EnsureSync)
|
2018-04-10 10:02:54 +00:00
|
|
|
|
2017-05-16 12:09:52 +00:00
|
|
|
// this call blocks, up until Complete Transaction is called
|
2019-12-11 13:59:37 +00:00
|
|
|
byteCode, err := types.DecodeHex(`0x6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636ffa1caa14603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60008160020290505b9190505600a165627a7a72305820ccdadd737e4ac7039963b54cee5e5afb25fa859a275252bdcf06f653155228210029`)
|
2017-10-11 14:20:51 +00:00
|
|
|
s.NoError(err)
|
2017-05-16 12:09:52 +00:00
|
|
|
|
2018-02-27 10:39:30 +00:00
|
|
|
gas := uint64(params.DefaultGas)
|
2018-04-04 17:39:38 +00:00
|
|
|
args := transactions.SendTxArgs{
|
2019-12-19 18:27:27 +00:00
|
|
|
From: account.FromAddress(utils.TestConfig.Account1.WalletAddress),
|
2017-05-16 12:09:52 +00:00
|
|
|
To: nil, // marker, contract creation is expected
|
2019-12-11 13:59:37 +00:00
|
|
|
//Value: (*hexutil.Big)(new(big.Int).Mul(big.NewInt(1), common.Ether)),
|
2018-03-23 11:54:09 +00:00
|
|
|
Gas: (*hexutil.Uint64)(&gas),
|
|
|
|
}
|
|
|
|
|
|
|
|
setInputAndDataValue(byteCode, &args)
|
2019-10-04 15:21:24 +00:00
|
|
|
hash, err := s.Backend.SendTransaction(args, utils.TestConfig.Account1.Password)
|
2018-03-23 11:54:09 +00:00
|
|
|
if expectedError != nil {
|
|
|
|
s.Equal(expectedError, err, expectedErrorDescription)
|
|
|
|
return
|
|
|
|
}
|
2018-08-16 11:37:53 +00:00
|
|
|
s.NoError(err)
|
2019-12-11 13:59:37 +00:00
|
|
|
s.False(reflect.DeepEqual(hash, types.Hash{}))
|
2017-05-16 12:09:52 +00:00
|
|
|
}
|
|
|
|
|
2017-10-23 11:05:52 +00:00
|
|
|
func (s *TransactionsTestSuite) TestSendEther() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID)
|
2019-08-29 08:06:22 +00:00
|
|
|
tmpdir, err := ioutil.TempDir("", "transactions-tests-")
|
|
|
|
s.Require().NoError(err)
|
|
|
|
defer os.Remove(tmpdir)
|
2018-04-18 15:13:27 +00:00
|
|
|
|
2019-12-11 13:59:37 +00:00
|
|
|
wallet := types.HexToAddress(utils.TestConfig.Account1.WalletAddress)
|
2019-12-05 08:00:57 +00:00
|
|
|
s.StartTestBackendWithAccount(multiaccounts.Account{KeyUID: utils.TestConfig.Account1.WalletAddress}, utils.TestConfig.Account1.Password,
|
2019-08-29 08:06:22 +00:00
|
|
|
[]accounts.Account{{Address: wallet, Wallet: true, Chat: true}},
|
|
|
|
e2e.WithDataDir(tmpdir),
|
|
|
|
)
|
|
|
|
defer s.LogoutAndStop()
|
2017-10-16 21:54:56 +00:00
|
|
|
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.EnsureNodeSync(s.Backend.StatusNode().EnsureSync)
|
2017-10-23 11:05:52 +00:00
|
|
|
|
2018-08-16 11:37:53 +00:00
|
|
|
hash, err := s.Backend.SendTransaction(transactions.SendTxArgs{
|
2019-12-19 18:27:27 +00:00
|
|
|
From: account.FromAddress(utils.TestConfig.Account1.WalletAddress),
|
|
|
|
To: account.ToAddress(utils.TestConfig.Account2.WalletAddress),
|
2017-10-16 21:54:56 +00:00
|
|
|
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
2019-10-04 15:21:24 +00:00
|
|
|
}, utils.TestConfig.Account1.Password)
|
2018-08-16 11:37:53 +00:00
|
|
|
s.NoError(err)
|
2019-12-11 13:59:37 +00:00
|
|
|
s.False(reflect.DeepEqual(hash, types.Hash{}))
|
2017-05-16 12:09:52 +00:00
|
|
|
}
|
|
|
|
|
2017-10-11 14:20:51 +00:00
|
|
|
func (s *TransactionsTestSuite) TestSendEtherTxUpstream() {
|
2019-10-04 15:21:24 +00:00
|
|
|
utils.CheckTestSkipForNetworks(s.T(), params.MainNetworkID, params.StatusChainNetworkID)
|
2017-10-26 12:33:42 +00:00
|
|
|
|
2019-08-29 08:06:22 +00:00
|
|
|
tmpdir, err := ioutil.TempDir("", "transactions-tests-")
|
|
|
|
s.Require().NoError(err)
|
|
|
|
defer os.Remove(tmpdir)
|
2019-10-04 15:21:24 +00:00
|
|
|
addr, err := utils.GetRemoteURL()
|
2017-10-25 12:37:42 +00:00
|
|
|
s.NoError(err)
|
2017-09-19 11:19:18 +00:00
|
|
|
|
2019-12-11 13:59:37 +00:00
|
|
|
wallet := types.HexToAddress(utils.TestConfig.Account1.WalletAddress)
|
2019-12-05 08:00:57 +00:00
|
|
|
s.StartTestBackendWithAccount(multiaccounts.Account{KeyUID: utils.TestConfig.Account1.WalletAddress}, utils.TestConfig.Account1.Password,
|
2019-08-29 08:06:22 +00:00
|
|
|
[]accounts.Account{{Address: wallet, Wallet: true, Chat: true}},
|
|
|
|
e2e.WithUpstream(addr),
|
|
|
|
e2e.WithDataDir(tmpdir),
|
|
|
|
)
|
|
|
|
defer s.LogoutAndStop()
|
2017-09-19 11:19:18 +00:00
|
|
|
|
2018-08-16 11:37:53 +00:00
|
|
|
hash, err := s.Backend.SendTransaction(transactions.SendTxArgs{
|
2019-12-19 18:27:27 +00:00
|
|
|
From: account.FromAddress(utils.TestConfig.Account1.WalletAddress),
|
|
|
|
To: account.ToAddress(utils.TestConfig.Account2.WalletAddress),
|
2017-09-19 11:19:18 +00:00
|
|
|
GasPrice: (*hexutil.Big)(big.NewInt(28000000000)),
|
|
|
|
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
2019-10-04 15:21:24 +00:00
|
|
|
}, utils.TestConfig.Account1.Password)
|
2017-10-11 14:20:51 +00:00
|
|
|
s.NoError(err)
|
2019-12-11 13:59:37 +00:00
|
|
|
s.False(reflect.DeepEqual(hash, types.Hash{}))
|
2018-02-05 15:48:54 +00:00
|
|
|
}
|