2022-10-05 06:44:10 +00:00
|
|
|
package util_test
|
|
|
|
|
|
|
|
import (
|
2024-04-01 17:51:33 +00:00
|
|
|
"fmt"
|
2023-04-11 15:45:50 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2024-04-03 13:40:11 +00:00
|
|
|
"strings"
|
2022-10-05 06:44:10 +00:00
|
|
|
"testing"
|
2023-11-27 11:20:18 +00:00
|
|
|
"time"
|
2022-10-05 06:44:10 +00:00
|
|
|
|
|
|
|
"github.com/nspcc-dev/neo-go/internal/testcli"
|
2023-11-27 11:20:18 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
2022-10-05 06:44:10 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
2024-04-03 13:40:11 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
2023-11-27 11:20:18 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
2023-04-11 15:45:50 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2022-10-05 06:44:10 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestUtilConvert(t *testing.T) {
|
|
|
|
e := testcli.NewExecutor(t, false)
|
|
|
|
|
|
|
|
e.Run(t, "neo-go", "util", "convert", util.Uint160{1, 2, 3}.StringLE())
|
|
|
|
e.CheckNextLine(t, "f975") // int to hex
|
|
|
|
e.CheckNextLine(t, "\\+XU=") // int to base64
|
|
|
|
e.CheckNextLine(t, "NKuyBkoGdZZSLyPbJEetheRhMrGSCQx7YL") // BE to address
|
|
|
|
e.CheckNextLine(t, "NL1JGiyJXdTkvFksXbFxgLJcWLj8Ewe7HW") // LE to address
|
|
|
|
e.CheckNextLine(t, "Hex to String") // hex to string
|
|
|
|
e.CheckNextLine(t, "5753853598078696051256155186041784866529345536") // hex to int
|
|
|
|
e.CheckNextLine(t, "0102030000000000000000000000000000000000") // swap endianness
|
|
|
|
e.CheckNextLine(t, "Base64 to String") // base64 to string
|
|
|
|
e.CheckNextLine(t, "368753434210909009569191652203865891677393101439813372294890211308228051") // base64 to bigint
|
|
|
|
e.CheckNextLine(t, "30303030303030303030303030303030303030303030303030303030303030303030303330323031") // string to hex
|
|
|
|
e.CheckNextLine(t, "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzMDIwMQ==") // string to base64
|
|
|
|
e.CheckEOF(t)
|
|
|
|
}
|
2023-04-11 15:45:50 +00:00
|
|
|
|
|
|
|
func TestUtilOps(t *testing.T) {
|
|
|
|
e := testcli.NewExecutor(t, false)
|
|
|
|
base64Str := "EUA="
|
|
|
|
hexStr := "1140"
|
|
|
|
|
|
|
|
check := func(t *testing.T) {
|
|
|
|
e.CheckNextLine(t, "INDEX.*OPCODE.*PARAMETER")
|
|
|
|
e.CheckNextLine(t, "PUSH1")
|
|
|
|
e.CheckNextLine(t, "RET")
|
|
|
|
e.CheckEOF(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
e.Run(t, "neo-go", "util", "ops", base64Str) // base64
|
|
|
|
check(t)
|
|
|
|
|
|
|
|
e.Run(t, "neo-go", "util", "ops", hexStr) // base64 is checked firstly by default, but it's invalid script if decoded from base64
|
|
|
|
e.CheckNextLine(t, "INDEX.*OPCODE.*PARAMETER")
|
|
|
|
e.CheckNextLine(t, ".*ERROR: incorrect opcode")
|
|
|
|
e.CheckEOF(t)
|
|
|
|
|
|
|
|
e.Run(t, "neo-go", "util", "ops", "--hex", hexStr) // explicitly specify hex encoding
|
|
|
|
check(t)
|
|
|
|
|
|
|
|
e.RunWithError(t, "neo-go", "util", "ops", "%&~*") // unknown encoding
|
|
|
|
|
|
|
|
tmp := filepath.Join(t.TempDir(), "script_base64.txt")
|
|
|
|
require.NoError(t, os.WriteFile(tmp, []byte(base64Str), os.ModePerm))
|
|
|
|
e.Run(t, "neo-go", "util", "ops", "--in", tmp) // base64 from file
|
|
|
|
check(t)
|
|
|
|
|
|
|
|
tmp = filepath.Join(t.TempDir(), "script_hex.txt")
|
|
|
|
require.NoError(t, os.WriteFile(tmp, []byte(hexStr), os.ModePerm))
|
|
|
|
e.Run(t, "neo-go", "util", "ops", "--hex", "--in", tmp) // hex from file
|
|
|
|
check(t)
|
|
|
|
}
|
2023-11-27 11:20:18 +00:00
|
|
|
|
|
|
|
func TestUtilCancelTx(t *testing.T) {
|
|
|
|
e := testcli.NewExecutorSuspended(t)
|
|
|
|
|
|
|
|
w, err := wallet.NewWalletFromFile("../testdata/testwallet.json")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
transferArgs := []string{
|
|
|
|
"neo-go", "wallet", "nep17", "transfer",
|
|
|
|
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
|
|
|
|
"--wallet", testcli.ValidatorWallet,
|
|
|
|
"--to", w.Accounts[0].Address,
|
|
|
|
"--token", "NEO",
|
|
|
|
"--from", testcli.ValidatorAddr,
|
|
|
|
"--force",
|
|
|
|
}
|
|
|
|
args := []string{"neo-go", "util", "canceltx",
|
|
|
|
"-r", "http://" + e.RPC.Addresses()[0],
|
|
|
|
"--wallet", testcli.ValidatorWallet,
|
|
|
|
"--address", testcli.ValidatorAddr}
|
|
|
|
|
|
|
|
e.In.WriteString("one\r")
|
|
|
|
e.Run(t, append(transferArgs, "--amount", "1")...)
|
|
|
|
line := e.GetNextLine(t)
|
|
|
|
txHash, err := util.Uint256DecodeStringLE(line)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, ok := e.Chain.GetMemPool().TryGetValue(txHash)
|
|
|
|
require.True(t, ok)
|
|
|
|
|
|
|
|
t.Run("invalid", func(t *testing.T) {
|
|
|
|
t.Run("missing tx argument", func(t *testing.T) {
|
|
|
|
e.RunWithError(t, args...)
|
|
|
|
})
|
|
|
|
t.Run("excessive arguments", func(t *testing.T) {
|
|
|
|
e.RunWithError(t, append(args, txHash.StringLE(), txHash.StringLE())...)
|
|
|
|
})
|
|
|
|
t.Run("invalid hash", func(t *testing.T) {
|
|
|
|
e.RunWithError(t, append(args, "notahash")...)
|
|
|
|
})
|
|
|
|
t.Run("not signed by main signer", func(t *testing.T) {
|
|
|
|
e.In.WriteString("one\r")
|
|
|
|
e.RunWithError(t, "neo-go", "util", "canceltx",
|
|
|
|
"-r", "http://"+e.RPC.Addresses()[0],
|
|
|
|
"--wallet", testcli.ValidatorWallet,
|
|
|
|
"--address", testcli.MultisigAddr, txHash.StringLE())
|
|
|
|
})
|
|
|
|
t.Run("wrong rpc endpoint", func(t *testing.T) {
|
|
|
|
e.In.WriteString("one\r")
|
|
|
|
e.RunWithError(t, "neo-go", "util", "canceltx",
|
|
|
|
"-r", "http://localhost:20331",
|
|
|
|
"--wallet", testcli.ValidatorWallet, txHash.StringLE())
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
e.In.WriteString("one\r")
|
|
|
|
e.Run(t, append(args, txHash.StringLE())...)
|
|
|
|
resHash, err := util.Uint256DecodeStringLE(e.GetNextLine(t))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, _, err = e.Chain.GetTransaction(resHash)
|
|
|
|
require.NoError(t, err)
|
|
|
|
e.CheckEOF(t)
|
|
|
|
go e.Chain.Run()
|
|
|
|
|
|
|
|
require.Eventually(t, func() bool {
|
|
|
|
_, aerErr := e.Chain.GetAppExecResults(resHash, trigger.Application)
|
|
|
|
return aerErr == nil
|
|
|
|
}, time.Second*2, time.Millisecond*50)
|
|
|
|
}
|
2023-12-28 11:58:38 +00:00
|
|
|
|
|
|
|
func TestAwaitUtilCancelTx(t *testing.T) {
|
|
|
|
e := testcli.NewExecutor(t, true)
|
|
|
|
|
|
|
|
w, err := wallet.NewWalletFromFile("../testdata/testwallet.json")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
transferArgs := []string{
|
|
|
|
"neo-go", "wallet", "nep17", "transfer",
|
|
|
|
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
|
|
|
|
"--wallet", testcli.ValidatorWallet,
|
|
|
|
"--to", w.Accounts[0].Address,
|
|
|
|
"--token", "NEO",
|
|
|
|
"--from", testcli.ValidatorAddr,
|
|
|
|
"--force",
|
|
|
|
}
|
|
|
|
args := []string{"neo-go", "util", "canceltx",
|
|
|
|
"-r", "http://" + e.RPC.Addresses()[0],
|
|
|
|
"--wallet", testcli.ValidatorWallet,
|
|
|
|
"--address", testcli.ValidatorAddr,
|
|
|
|
"--await"}
|
|
|
|
|
|
|
|
e.In.WriteString("one\r")
|
|
|
|
e.Run(t, append(transferArgs, "--amount", "1")...)
|
|
|
|
line := e.GetNextLine(t)
|
|
|
|
txHash, err := util.Uint256DecodeStringLE(line)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, ok := e.Chain.GetMemPool().TryGetValue(txHash)
|
|
|
|
require.True(t, ok)
|
|
|
|
|
2024-04-01 17:51:33 +00:00
|
|
|
// Allow both cases: either target or conflicting tx acceptance.
|
2023-12-28 11:58:38 +00:00
|
|
|
e.In.WriteString("one\r")
|
2024-04-03 13:40:11 +00:00
|
|
|
err = e.RunUnchecked(t, append(args, txHash.StringLE())...)
|
|
|
|
switch {
|
|
|
|
case err == nil:
|
2024-04-01 17:51:33 +00:00
|
|
|
response := e.GetNextLine(t)
|
|
|
|
require.Equal(t, "Conflicting transaction accepted", response)
|
2024-03-20 11:16:04 +00:00
|
|
|
resHash, _ := e.CheckAwaitableTxPersisted(t)
|
2024-04-01 17:51:33 +00:00
|
|
|
require.NotEqual(t, resHash, txHash)
|
2024-04-03 13:40:11 +00:00
|
|
|
case strings.Contains(err.Error(), fmt.Sprintf("target transaction %s is accepted", txHash)) ||
|
|
|
|
strings.Contains(err.Error(), fmt.Sprintf("failed to send conflicting transaction: Invalid transaction attribute (-507) - invalid attribute: conflicting transaction %s is already on chain", txHash)):
|
|
|
|
tx, _ := e.GetTransaction(t, txHash)
|
|
|
|
aer, err := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 1, len(aer))
|
|
|
|
require.Equal(t, vmstate.Halt, aer[0].VMState)
|
|
|
|
default:
|
|
|
|
t.Fatal(fmt.Errorf("unexpected error: %w", err))
|
2024-03-20 11:16:04 +00:00
|
|
|
}
|
2023-12-28 11:58:38 +00:00
|
|
|
}
|