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 }