github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/rpcclient/neo/neo_test.go (about)

     1  package neo
     2  
     3  import (
     4  	"errors"
     5  	"math/big"
     6  	"testing"
     7  
     8  	"github.com/google/uuid"
     9  	"github.com/nspcc-dev/neo-go/pkg/core/state"
    10  	"github.com/nspcc-dev/neo-go/pkg/core/transaction"
    11  	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
    12  	"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
    13  	"github.com/nspcc-dev/neo-go/pkg/util"
    14  	"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  type testAct struct {
    19  	err error
    20  	ser error
    21  	res *result.Invoke
    22  	rre *result.Invoke
    23  	rer error
    24  	tx  *transaction.Transaction
    25  	txh util.Uint256
    26  	vub uint32
    27  	inv *result.Invoke
    28  }
    29  
    30  func (t *testAct) Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error) {
    31  	return t.res, t.err
    32  }
    33  func (t *testAct) MakeRun(script []byte) (*transaction.Transaction, error) {
    34  	return t.tx, t.err
    35  }
    36  func (t *testAct) MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error) {
    37  	return t.tx, t.err
    38  }
    39  func (t *testAct) SendRun(script []byte) (util.Uint256, uint32, error) {
    40  	return t.txh, t.vub, t.err
    41  }
    42  func (t *testAct) MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error) {
    43  	return t.tx, t.err
    44  }
    45  func (t *testAct) MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error) {
    46  	return t.tx, t.err
    47  }
    48  func (t *testAct) SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error) {
    49  	return t.txh, t.vub, t.err
    50  }
    51  func (t *testAct) Run(script []byte) (*result.Invoke, error) {
    52  	return t.rre, t.rer
    53  }
    54  func (t *testAct) MakeUnsignedUncheckedRun(script []byte, sysFee int64, attrs []transaction.Attribute) (*transaction.Transaction, error) {
    55  	return t.tx, t.err
    56  }
    57  func (t *testAct) Sign(tx *transaction.Transaction) error {
    58  	return t.ser
    59  }
    60  func (t *testAct) SignAndSend(tx *transaction.Transaction) (util.Uint256, uint32, error) {
    61  	return t.txh, t.vub, t.err
    62  }
    63  func (t *testAct) CallAndExpandIterator(contract util.Uint160, method string, maxItems int, params ...any) (*result.Invoke, error) {
    64  	return t.inv, t.err
    65  }
    66  func (t *testAct) TerminateSession(sessionID uuid.UUID) error {
    67  	return t.err
    68  }
    69  func (t *testAct) TraverseIterator(sessionID uuid.UUID, iterator *result.Iterator, num int) ([]stackitem.Item, error) {
    70  	return t.res.Stack, t.err
    71  }
    72  
    73  func TestGetAccountState(t *testing.T) {
    74  	ta := &testAct{}
    75  	neo := NewReader(ta)
    76  
    77  	ta.err = errors.New("")
    78  	_, err := neo.GetAccountState(util.Uint160{})
    79  	require.Error(t, err)
    80  
    81  	ta.err = nil
    82  	ta.res = &result.Invoke{
    83  		State: "HALT",
    84  		Stack: []stackitem.Item{
    85  			stackitem.Make(42),
    86  		},
    87  	}
    88  	_, err = neo.GetAccountState(util.Uint160{})
    89  	require.Error(t, err)
    90  
    91  	ta.res = &result.Invoke{
    92  		State: "HALT",
    93  		Stack: []stackitem.Item{
    94  			stackitem.Null{},
    95  		},
    96  	}
    97  	st, err := neo.GetAccountState(util.Uint160{})
    98  	require.NoError(t, err)
    99  	require.Nil(t, st)
   100  
   101  	ta.res = &result.Invoke{
   102  		State: "HALT",
   103  		Stack: []stackitem.Item{
   104  			stackitem.Make([]stackitem.Item{
   105  				stackitem.Make(100500),
   106  				stackitem.Make(42),
   107  				stackitem.Null{},
   108  			}),
   109  		},
   110  	}
   111  	st, err = neo.GetAccountState(util.Uint160{})
   112  	require.NoError(t, err)
   113  	require.Equal(t, &state.NEOBalance{
   114  		NEP17Balance: state.NEP17Balance{
   115  			Balance: *big.NewInt(100500),
   116  		},
   117  		BalanceHeight: 42,
   118  	}, st)
   119  }
   120  
   121  func TestGetAllCandidates(t *testing.T) {
   122  	ta := &testAct{}
   123  	neo := NewReader(ta)
   124  
   125  	ta.err = errors.New("")
   126  	_, err := neo.GetAllCandidates()
   127  	require.Error(t, err)
   128  
   129  	ta.err = nil
   130  	iid := uuid.New()
   131  	ta.res = &result.Invoke{
   132  		State: "HALT",
   133  		Stack: []stackitem.Item{
   134  			stackitem.NewInterop(result.Iterator{
   135  				ID: &iid,
   136  			}),
   137  		},
   138  	}
   139  	_, err = neo.GetAllCandidates()
   140  	require.Error(t, err)
   141  
   142  	// Session-based iterator.
   143  	sid := uuid.New()
   144  	ta.res = &result.Invoke{
   145  		Session: sid,
   146  		State:   "HALT",
   147  		Stack: []stackitem.Item{
   148  			stackitem.NewInterop(result.Iterator{
   149  				ID: &iid,
   150  			}),
   151  		},
   152  	}
   153  	iter, err := neo.GetAllCandidates()
   154  	require.NoError(t, err)
   155  
   156  	k, err := keys.NewPrivateKey()
   157  	require.NoError(t, err)
   158  	ta.res = &result.Invoke{
   159  		Stack: []stackitem.Item{
   160  			stackitem.Make([]stackitem.Item{
   161  				stackitem.Make(k.PublicKey().Bytes()),
   162  				stackitem.Make(100500),
   163  			}),
   164  		},
   165  	}
   166  	vals, err := iter.Next(10)
   167  	require.NoError(t, err)
   168  	require.Equal(t, 1, len(vals))
   169  	require.Equal(t, result.Validator{
   170  		PublicKey: *k.PublicKey(),
   171  		Votes:     100500,
   172  	}, vals[0])
   173  
   174  	ta.err = errors.New("")
   175  	_, err = iter.Next(1)
   176  	require.Error(t, err)
   177  
   178  	err = iter.Terminate()
   179  	require.Error(t, err)
   180  
   181  	// Value-based iterator.
   182  	ta.err = nil
   183  	ta.res = &result.Invoke{
   184  		State: "HALT",
   185  		Stack: []stackitem.Item{
   186  			stackitem.NewInterop(result.Iterator{
   187  				Values: []stackitem.Item{
   188  					stackitem.Make(k.PublicKey().Bytes()),
   189  					stackitem.Make(100500),
   190  				},
   191  			}),
   192  		},
   193  	}
   194  	iter, err = neo.GetAllCandidates()
   195  	require.NoError(t, err)
   196  
   197  	ta.err = errors.New("")
   198  	err = iter.Terminate()
   199  	require.NoError(t, err)
   200  }
   201  
   202  func TestGetCandidates(t *testing.T) {
   203  	ta := &testAct{}
   204  	neo := NewReader(ta)
   205  
   206  	ta.err = errors.New("")
   207  	_, err := neo.GetCandidates()
   208  	require.Error(t, err)
   209  
   210  	ta.err = nil
   211  	ta.res = &result.Invoke{
   212  		State: "HALT",
   213  		Stack: []stackitem.Item{
   214  			stackitem.Make([]stackitem.Item{}),
   215  		},
   216  	}
   217  	cands, err := neo.GetCandidates()
   218  	require.NoError(t, err)
   219  	require.Equal(t, 0, len(cands))
   220  
   221  	ta.res = &result.Invoke{
   222  		State: "HALT",
   223  		Stack: []stackitem.Item{stackitem.Make(42)},
   224  	}
   225  	_, err = neo.GetCandidates()
   226  	require.Error(t, err)
   227  
   228  	ta.res = &result.Invoke{
   229  		State: "HALT",
   230  		Stack: []stackitem.Item{
   231  			stackitem.Make([]stackitem.Item{
   232  				stackitem.Make(42),
   233  			}),
   234  		},
   235  	}
   236  	_, err = neo.GetCandidates()
   237  	require.Error(t, err)
   238  
   239  	ta.res = &result.Invoke{
   240  		State: "HALT",
   241  		Stack: []stackitem.Item{
   242  			stackitem.Make([]stackitem.Item{
   243  				stackitem.Make([]stackitem.Item{}),
   244  			}),
   245  		},
   246  	}
   247  	_, err = neo.GetCandidates()
   248  	require.Error(t, err)
   249  
   250  	ta.res = &result.Invoke{
   251  		State: "HALT",
   252  		Stack: []stackitem.Item{
   253  			stackitem.Make([]stackitem.Item{
   254  				stackitem.Make([]stackitem.Item{
   255  					stackitem.Null{},
   256  					stackitem.Null{},
   257  				}),
   258  			}),
   259  		},
   260  	}
   261  	_, err = neo.GetCandidates()
   262  	require.Error(t, err)
   263  
   264  	ta.res = &result.Invoke{
   265  		State: "HALT",
   266  		Stack: []stackitem.Item{
   267  			stackitem.Make([]stackitem.Item{
   268  				stackitem.Make([]stackitem.Item{
   269  					stackitem.Make("some"),
   270  					stackitem.Null{},
   271  				}),
   272  			}),
   273  		},
   274  	}
   275  	_, err = neo.GetCandidates()
   276  	require.Error(t, err)
   277  
   278  	k, err := keys.NewPrivateKey()
   279  	require.NoError(t, err)
   280  	ta.res = &result.Invoke{
   281  		State: "HALT",
   282  		Stack: []stackitem.Item{
   283  			stackitem.Make([]stackitem.Item{
   284  				stackitem.Make([]stackitem.Item{
   285  					stackitem.Make(k.PublicKey().Bytes()),
   286  					stackitem.Null{},
   287  				}),
   288  			}),
   289  		},
   290  	}
   291  	_, err = neo.GetCandidates()
   292  	require.Error(t, err)
   293  
   294  	ta.res = &result.Invoke{
   295  		State: "HALT",
   296  		Stack: []stackitem.Item{
   297  			stackitem.Make([]stackitem.Item{
   298  				stackitem.Make([]stackitem.Item{
   299  					stackitem.Make(k.PublicKey().Bytes()),
   300  					stackitem.Make("canbeabigint"),
   301  				}),
   302  			}),
   303  		},
   304  	}
   305  	_, err = neo.GetCandidates()
   306  	require.Error(t, err)
   307  }
   308  
   309  func TestGetKeys(t *testing.T) {
   310  	ta := &testAct{}
   311  	neo := NewReader(ta)
   312  
   313  	k, err := keys.NewPrivateKey()
   314  	require.NoError(t, err)
   315  
   316  	for _, m := range []func() (keys.PublicKeys, error){neo.GetCommittee, neo.GetNextBlockValidators} {
   317  		ta.err = errors.New("")
   318  		_, err := m()
   319  		require.Error(t, err)
   320  
   321  		ta.err = nil
   322  		ta.res = &result.Invoke{
   323  			State: "HALT",
   324  			Stack: []stackitem.Item{
   325  				stackitem.Make([]stackitem.Item{stackitem.Make(k.PublicKey().Bytes())}),
   326  			},
   327  		}
   328  		ks, err := m()
   329  		require.NoError(t, err)
   330  		require.NotNil(t, ks)
   331  		require.Equal(t, 1, len(ks))
   332  		require.Equal(t, k.PublicKey(), ks[0])
   333  	}
   334  }
   335  
   336  func TestGetInts(t *testing.T) {
   337  	ta := &testAct{}
   338  	neo := NewReader(ta)
   339  
   340  	meth := []func() (int64, error){
   341  		neo.GetGasPerBlock,
   342  		neo.GetRegisterPrice,
   343  	}
   344  
   345  	ta.err = errors.New("")
   346  	for _, m := range meth {
   347  		_, err := m()
   348  		require.Error(t, err)
   349  	}
   350  
   351  	ta.err = nil
   352  	ta.res = &result.Invoke{
   353  		State: "HALT",
   354  		Stack: []stackitem.Item{
   355  			stackitem.Make(42),
   356  		},
   357  	}
   358  	for _, m := range meth {
   359  		val, err := m()
   360  		require.NoError(t, err)
   361  		require.Equal(t, int64(42), val)
   362  	}
   363  }
   364  
   365  func TestUnclaimedGas(t *testing.T) {
   366  	ta := &testAct{}
   367  	neo := NewReader(ta)
   368  
   369  	ta.err = errors.New("")
   370  	_, err := neo.UnclaimedGas(util.Uint160{}, 100500)
   371  	require.Error(t, err)
   372  
   373  	ta.err = nil
   374  	ta.res = &result.Invoke{
   375  		State: "HALT",
   376  		Stack: []stackitem.Item{
   377  			stackitem.Make([]stackitem.Item{}),
   378  		},
   379  	}
   380  	_, err = neo.UnclaimedGas(util.Uint160{}, 100500)
   381  	require.Error(t, err)
   382  
   383  	ta.res = &result.Invoke{
   384  		State: "HALT",
   385  		Stack: []stackitem.Item{
   386  			stackitem.Make(42),
   387  		},
   388  	}
   389  	val, err := neo.UnclaimedGas(util.Uint160{}, 100500)
   390  	require.NoError(t, err)
   391  	require.Equal(t, big.NewInt(42), val)
   392  }
   393  
   394  func TestIntSetters(t *testing.T) {
   395  	ta := new(testAct)
   396  	neo := New(ta)
   397  
   398  	meth := []func(int64) (util.Uint256, uint32, error){
   399  		neo.SetGasPerBlock,
   400  		neo.SetRegisterPrice,
   401  	}
   402  
   403  	ta.err = errors.New("")
   404  	for _, m := range meth {
   405  		_, _, err := m(42)
   406  		require.Error(t, err)
   407  	}
   408  
   409  	ta.err = nil
   410  	ta.txh = util.Uint256{1, 2, 3}
   411  	ta.vub = 42
   412  	for _, m := range meth {
   413  		h, vub, err := m(100)
   414  		require.NoError(t, err)
   415  		require.Equal(t, ta.txh, h)
   416  		require.Equal(t, ta.vub, vub)
   417  	}
   418  }
   419  
   420  func TestIntTransactions(t *testing.T) {
   421  	ta := new(testAct)
   422  	neo := New(ta)
   423  
   424  	for _, fun := range []func(int64) (*transaction.Transaction, error){
   425  		neo.SetGasPerBlockTransaction,
   426  		neo.SetGasPerBlockUnsigned,
   427  		neo.SetRegisterPriceTransaction,
   428  		neo.SetRegisterPriceUnsigned,
   429  	} {
   430  		ta.err = errors.New("")
   431  		_, err := fun(1)
   432  		require.Error(t, err)
   433  
   434  		ta.err = nil
   435  		ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   436  		tx, err := fun(1)
   437  		require.NoError(t, err)
   438  		require.Equal(t, ta.tx, tx)
   439  	}
   440  }
   441  
   442  func TestVote(t *testing.T) {
   443  	ta := new(testAct)
   444  	neo := New(ta)
   445  
   446  	k, err := keys.NewPrivateKey()
   447  	require.NoError(t, err)
   448  
   449  	ta.err = errors.New("")
   450  	_, _, err = neo.Vote(util.Uint160{}, nil)
   451  	require.Error(t, err)
   452  	_, _, err = neo.Vote(util.Uint160{}, k.PublicKey())
   453  	require.Error(t, err)
   454  	_, err = neo.VoteTransaction(util.Uint160{}, nil)
   455  	require.Error(t, err)
   456  	_, err = neo.VoteTransaction(util.Uint160{}, k.PublicKey())
   457  	require.Error(t, err)
   458  	_, err = neo.VoteUnsigned(util.Uint160{}, nil)
   459  	require.Error(t, err)
   460  	_, err = neo.VoteUnsigned(util.Uint160{}, k.PublicKey())
   461  	require.Error(t, err)
   462  
   463  	ta.err = nil
   464  	ta.txh = util.Uint256{1, 2, 3}
   465  	ta.vub = 42
   466  
   467  	h, vub, err := neo.Vote(util.Uint160{}, nil)
   468  	require.NoError(t, err)
   469  	require.Equal(t, ta.txh, h)
   470  	require.Equal(t, ta.vub, vub)
   471  	h, vub, err = neo.Vote(util.Uint160{}, k.PublicKey())
   472  	require.NoError(t, err)
   473  	require.Equal(t, ta.txh, h)
   474  	require.Equal(t, ta.vub, vub)
   475  
   476  	ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   477  	tx, err := neo.VoteTransaction(util.Uint160{}, nil)
   478  	require.NoError(t, err)
   479  	require.Equal(t, ta.tx, tx)
   480  	tx, err = neo.VoteUnsigned(util.Uint160{}, k.PublicKey())
   481  	require.NoError(t, err)
   482  	require.Equal(t, ta.tx, tx)
   483  }
   484  
   485  func TestRegisterCandidate(t *testing.T) {
   486  	ta := new(testAct)
   487  	neo := New(ta)
   488  
   489  	k, err := keys.NewPrivateKey()
   490  	require.NoError(t, err)
   491  	pk := k.PublicKey()
   492  
   493  	ta.rer = errors.New("")
   494  	_, _, err = neo.RegisterCandidate(pk)
   495  	require.Error(t, err)
   496  	_, err = neo.RegisterCandidateTransaction(pk)
   497  	require.Error(t, err)
   498  	_, err = neo.RegisterCandidateUnsigned(pk)
   499  	require.Error(t, err)
   500  
   501  	ta.rer = nil
   502  	ta.txh = util.Uint256{1, 2, 3}
   503  	ta.vub = 42
   504  	ta.rre = &result.Invoke{
   505  		GasConsumed: 100500,
   506  	}
   507  	ta.res = &result.Invoke{
   508  		State: "HALT",
   509  		Stack: []stackitem.Item{
   510  			stackitem.Make(42),
   511  		},
   512  	}
   513  
   514  	h, vub, err := neo.RegisterCandidate(pk)
   515  	require.NoError(t, err)
   516  	require.Equal(t, ta.txh, h)
   517  	require.Equal(t, ta.vub, vub)
   518  
   519  	ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   520  	tx, err := neo.RegisterCandidateTransaction(pk)
   521  	require.NoError(t, err)
   522  	require.Equal(t, ta.tx, tx)
   523  	tx, err = neo.RegisterCandidateUnsigned(pk)
   524  	require.NoError(t, err)
   525  	require.Equal(t, ta.tx, tx)
   526  
   527  	ta.ser = errors.New("")
   528  	_, err = neo.RegisterCandidateTransaction(pk)
   529  	require.Error(t, err)
   530  
   531  	ta.err = errors.New("")
   532  	_, err = neo.RegisterCandidateUnsigned(pk)
   533  	require.Error(t, err)
   534  }
   535  
   536  func TestUnregisterCandidate(t *testing.T) {
   537  	ta := new(testAct)
   538  	neo := New(ta)
   539  
   540  	k, err := keys.NewPrivateKey()
   541  	require.NoError(t, err)
   542  	pk := k.PublicKey()
   543  
   544  	ta.err = errors.New("")
   545  	_, _, err = neo.UnregisterCandidate(pk)
   546  	require.Error(t, err)
   547  	_, err = neo.UnregisterCandidateTransaction(pk)
   548  	require.Error(t, err)
   549  	_, err = neo.UnregisterCandidateUnsigned(pk)
   550  	require.Error(t, err)
   551  
   552  	ta.err = nil
   553  	ta.txh = util.Uint256{1, 2, 3}
   554  	ta.vub = 42
   555  
   556  	h, vub, err := neo.UnregisterCandidate(pk)
   557  	require.NoError(t, err)
   558  	require.Equal(t, ta.txh, h)
   559  	require.Equal(t, ta.vub, vub)
   560  
   561  	ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   562  	tx, err := neo.UnregisterCandidateTransaction(pk)
   563  	require.NoError(t, err)
   564  	require.Equal(t, ta.tx, tx)
   565  	tx, err = neo.UnregisterCandidateUnsigned(pk)
   566  	require.NoError(t, err)
   567  	require.Equal(t, ta.tx, tx)
   568  }