github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/transaction_unit_test.go (about) 1 //go:build all || unit 2 // +build all unit 3 4 package hedera 5 6 /*- 7 * 8 * Hedera Go SDK 9 * 10 * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC 11 * 12 * Licensed under the Apache License, Version 2.0 (the "License"); 13 * you may not use this file except in compliance with the License. 14 * You may obtain a copy of the License at 15 * 16 * http://www.apache.org/licenses/LICENSE-2.0 17 * 18 * Unless required by applicable law or agreed to in writing, software 19 * distributed under the License is distributed on an "AS IS" BASIS, 20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 * See the License for the specific language governing permissions and 22 * limitations under the License. 23 * 24 */ 25 26 import ( 27 "fmt" 28 "reflect" 29 "testing" 30 "time" 31 32 "github.com/hashgraph/hedera-protobufs-go/sdk" 33 "github.com/hashgraph/hedera-protobufs-go/services" 34 protobuf "google.golang.org/protobuf/proto" 35 36 "github.com/stretchr/testify/assert" 37 38 "github.com/stretchr/testify/require" 39 ) 40 41 func TestUnitTransactionSerializationDeserialization(t *testing.T) { 42 t.Parallel() 43 44 transaction, err := _NewMockTransaction() 45 require.NoError(t, err) 46 47 _, err = transaction.Freeze() 48 require.NoError(t, err) 49 50 _, err = transaction.GetSignatures() 51 require.NoError(t, err) 52 53 _, err = transaction.GetTransactionHash() 54 require.NoError(t, err) 55 56 transaction. 57 SetTransactionMemo("memo"). 58 SetMaxTransactionFee(NewHbar(5)) 59 60 txBytes, err := transaction.ToBytes() 61 require.NoError(t, err) 62 63 deserializedTX, err := TransactionFromBytes(txBytes) 64 require.NoError(t, err) 65 66 var deserializedTXTyped TransferTransaction 67 switch tx := deserializedTX.(type) { 68 case TransferTransaction: 69 deserializedTXTyped = tx 70 default: 71 panic("Transaction was not TransferTransaction") 72 } 73 74 require.Equal(t, "memo", deserializedTXTyped.memo) 75 require.Equal(t, NewHbar(5), deserializedTXTyped.GetMaxTransactionFee()) 76 assert.Equal(t, transaction.String(), deserializedTXTyped.String()) 77 } 78 79 func TestUnitTransactionValidateBodiesEqual(t *testing.T) { 80 t.Parallel() 81 82 key, err := PrivateKeyFromString(mockPrivateKey) 83 require.NoError(t, err) 84 transaction := services.TransactionBody{ 85 TransactionID: testTransactionID._ToProtobuf(), 86 NodeAccountID: AccountID{Account: 3}._ToProtobuf(), 87 TransactionFee: 0, 88 TransactionValidDuration: nil, 89 GenerateRecord: false, 90 Memo: "", 91 Data: &services.TransactionBody_CryptoCreateAccount{ 92 CryptoCreateAccount: &services.CryptoCreateTransactionBody{ 93 Key: key._ToProtoKey(), 94 InitialBalance: 0, 95 ProxyAccountID: AccountID{Account: 123}._ToProtobuf(), 96 SendRecordThreshold: 0, 97 ReceiveRecordThreshold: 0, 98 ReceiverSigRequired: false, 99 AutoRenewPeriod: nil, 100 ShardID: nil, 101 RealmID: nil, 102 NewRealmAdminKey: nil, 103 Memo: "", 104 MaxAutomaticTokenAssociations: 0, 105 }, 106 }, 107 } 108 109 transactionBody, err := protobuf.Marshal(&transaction) 110 require.NoError(t, err) 111 112 signed, err := protobuf.Marshal(&services.SignedTransaction{ 113 BodyBytes: transactionBody, 114 }) 115 require.NoError(t, err) 116 list, err := protobuf.Marshal(&sdk.TransactionList{ 117 TransactionList: []*services.Transaction{ 118 { 119 SignedTransactionBytes: signed, 120 }, 121 { 122 SignedTransactionBytes: signed, 123 }, 124 { 125 SignedTransactionBytes: signed, 126 }, 127 }, 128 }) 129 130 deserializedTX, err := TransactionFromBytes(list) 131 require.NoError(t, err) 132 133 var deserializedTXTyped AccountCreateTransaction 134 switch tx := deserializedTX.(type) { 135 case AccountCreateTransaction: 136 deserializedTXTyped = tx 137 default: 138 panic("Transaction was not AccountCreateTransaction") 139 } 140 141 assert.Equal(t, uint64(transaction.TransactionID.AccountID.GetAccountNum()), deserializedTXTyped.GetTransactionID().AccountID.Account) 142 } 143 144 func DisabledTestUnitTransactionValidateBodiesNotEqual(t *testing.T) { 145 t.Parallel() 146 147 key, err := PrivateKeyFromString(mockPrivateKey) 148 require.NoError(t, err) 149 transaction := services.TransactionBody{ 150 TransactionID: testTransactionID._ToProtobuf(), 151 NodeAccountID: AccountID{Account: 3}._ToProtobuf(), 152 TransactionFee: 0, 153 TransactionValidDuration: nil, 154 GenerateRecord: false, 155 Memo: "", 156 Data: &services.TransactionBody_CryptoCreateAccount{ 157 CryptoCreateAccount: &services.CryptoCreateTransactionBody{ 158 Key: key._ToProtoKey(), 159 InitialBalance: 0, 160 ProxyAccountID: AccountID{Account: 123}._ToProtobuf(), 161 SendRecordThreshold: 0, 162 ReceiveRecordThreshold: 0, 163 ReceiverSigRequired: false, 164 AutoRenewPeriod: nil, 165 ShardID: nil, 166 RealmID: nil, 167 NewRealmAdminKey: nil, 168 Memo: "", 169 MaxAutomaticTokenAssociations: 0, 170 }, 171 }, 172 } 173 174 transaction2 := services.TransactionBody{ 175 TransactionID: testTransactionID._ToProtobuf(), 176 NodeAccountID: AccountID{Account: 3}._ToProtobuf(), 177 TransactionFee: 0, 178 TransactionValidDuration: nil, 179 GenerateRecord: false, 180 Memo: "", 181 Data: &services.TransactionBody_CryptoCreateAccount{ 182 CryptoCreateAccount: &services.CryptoCreateTransactionBody{ 183 Key: key._ToProtoKey(), 184 InitialBalance: 0, 185 ProxyAccountID: AccountID{Account: 1}._ToProtobuf(), 186 SendRecordThreshold: 0, 187 ReceiveRecordThreshold: 0, 188 ReceiverSigRequired: false, 189 AutoRenewPeriod: nil, 190 ShardID: nil, 191 RealmID: nil, 192 NewRealmAdminKey: nil, 193 Memo: "", 194 MaxAutomaticTokenAssociations: 0, 195 }, 196 }, 197 } 198 199 transactionBody, err := protobuf.Marshal(&transaction) 200 require.NoError(t, err) 201 202 signed, err := protobuf.Marshal(&services.SignedTransaction{ 203 BodyBytes: transactionBody, 204 }) 205 206 transactionBody2, err := protobuf.Marshal(&transaction2) 207 require.NoError(t, err) 208 209 signed2, err := protobuf.Marshal(&services.SignedTransaction{ 210 BodyBytes: transactionBody2, 211 }) 212 213 require.NoError(t, err) 214 list, err := protobuf.Marshal(&sdk.TransactionList{ 215 TransactionList: []*services.Transaction{ 216 { 217 SignedTransactionBytes: signed, 218 }, 219 { 220 SignedTransactionBytes: signed2, 221 }, 222 { 223 SignedTransactionBytes: signed2, 224 }, 225 }, 226 }) 227 228 _, err = TransactionFromBytes(list) 229 require.Error(t, err) 230 if err != nil { 231 assert.Equal(t, fmt.Sprintf("failed to validate transaction bodies"), err.Error()) 232 } 233 } 234 235 func TestUnitTransactionToFromBytes(t *testing.T) { 236 t.Parallel() 237 238 duration := time.Second * 10 239 operatorID := AccountID{Account: 5} 240 recepientID := AccountID{Account: 4} 241 node := []AccountID{{Account: 3}} 242 transaction, err := NewTransferTransaction(). 243 SetTransactionID(testTransactionID). 244 SetNodeAccountIDs(node). 245 AddHbarTransfer(operatorID, NewHbar(-1)). 246 AddHbarTransfer(recepientID, NewHbar(1)). 247 SetTransactionMemo("go sdk example multi_app_transfer/main.go"). 248 SetTransactionValidDuration(duration). 249 Freeze() 250 require.NoError(t, err) 251 252 _ = transaction.GetTransactionID() 253 nodeID := transaction.GetNodeAccountIDs() 254 require.NotEmpty(t, nodeID) 255 require.False(t, nodeID[0]._IsZero()) 256 257 var tx services.TransactionBody 258 _ = protobuf.Unmarshal(transaction.signedTransactions._Get(0).(*services.SignedTransaction).BodyBytes, &tx) 259 require.Equal(t, tx.TransactionID.String(), testTransactionID._ToProtobuf().String()) 260 require.Equal(t, tx.NodeAccountID.String(), node[0]._ToProtobuf().String()) 261 require.Equal(t, tx.Memo, "go sdk example multi_app_transfer/main.go") 262 require.Equal(t, duration, _DurationFromProtobuf(tx.TransactionValidDuration)) 263 require.Equal(t, tx.GetCryptoTransfer().Transfers.AccountAmounts, 264 []*services.AccountAmount{ 265 { 266 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{5}}, 267 Amount: -100000000, 268 }, 269 { 270 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{4}}, 271 Amount: 100000000, 272 }, 273 }) 274 275 txBytes, err := transaction.ToBytes() 276 require.NoError(t, err) 277 278 newTransaction, err := TransactionFromBytes(txBytes) 279 280 _ = protobuf.Unmarshal(newTransaction.(TransferTransaction).signedTransactions._Get(0).(*services.SignedTransaction).BodyBytes, &tx) 281 require.Equal(t, tx.TransactionID.String(), testTransactionID._ToProtobuf().String()) 282 require.Equal(t, tx.NodeAccountID.String(), node[0]._ToProtobuf().String()) 283 require.Equal(t, tx.Memo, "go sdk example multi_app_transfer/main.go") 284 require.Equal(t, duration, _DurationFromProtobuf(tx.TransactionValidDuration)) 285 require.Equal(t, tx.GetCryptoTransfer().Transfers.AccountAmounts, 286 []*services.AccountAmount{ 287 { 288 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{5}}, 289 Amount: -100000000, 290 }, 291 { 292 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{4}}, 293 Amount: 100000000, 294 }, 295 }) 296 } 297 298 func TestUnitTransactionToFromBytesWithClient(t *testing.T) { 299 t.Parallel() 300 301 duration := time.Second * 10 302 operatorID := AccountID{Account: 5} 303 recepientID := AccountID{Account: 4} 304 client, err := _NewMockClient() 305 client.SetLedgerID(*NewLedgerIDTestnet()) 306 require.NoError(t, err) 307 privateKey, err := PrivateKeyFromString(mockPrivateKey) 308 client.SetOperator(AccountID{Account: 2}, privateKey) 309 310 transaction, err := NewTransferTransaction(). 311 AddHbarTransfer(operatorID, NewHbar(-1)). 312 AddHbarTransfer(recepientID, NewHbar(1)). 313 SetTransactionMemo("go sdk example multi_app_transfer/main.go"). 314 SetTransactionValidDuration(duration). 315 FreezeWith(client) 316 require.NoError(t, err) 317 318 var tx services.TransactionBody 319 _ = protobuf.Unmarshal(transaction.signedTransactions._Get(0).(*services.SignedTransaction).BodyBytes, &tx) 320 require.NotNil(t, tx.TransactionID, tx.NodeAccountID) 321 require.Equal(t, tx.Memo, "go sdk example multi_app_transfer/main.go") 322 require.Equal(t, duration, _DurationFromProtobuf(tx.TransactionValidDuration)) 323 require.Equal(t, tx.GetCryptoTransfer().Transfers.AccountAmounts, 324 []*services.AccountAmount{ 325 { 326 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{5}}, 327 Amount: -100000000, 328 }, 329 { 330 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{4}}, 331 Amount: 100000000, 332 }, 333 }) 334 335 initialTxID := tx.TransactionID 336 initialNode := tx.NodeAccountID 337 338 txBytes, err := transaction.ToBytes() 339 require.NoError(t, err) 340 341 newTransaction, err := TransactionFromBytes(txBytes) 342 343 _ = protobuf.Unmarshal(newTransaction.(TransferTransaction).signedTransactions._Get(0).(*services.SignedTransaction).BodyBytes, &tx) 344 require.NotNil(t, tx.TransactionID, tx.NodeAccountID) 345 require.Equal(t, tx.TransactionID.String(), initialTxID.String()) 346 require.Equal(t, tx.NodeAccountID.String(), initialNode.String()) 347 require.Equal(t, tx.Memo, "go sdk example multi_app_transfer/main.go") 348 require.Equal(t, duration, _DurationFromProtobuf(tx.TransactionValidDuration)) 349 require.Equal(t, tx.GetCryptoTransfer().Transfers.AccountAmounts, 350 []*services.AccountAmount{ 351 { 352 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{5}}, 353 Amount: -100000000, 354 }, 355 { 356 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{4}}, 357 Amount: 100000000, 358 }, 359 }) 360 } 361 362 func TestUnitQueryRegression(t *testing.T) { 363 t.Parallel() 364 365 accountID := AccountID{Account: 5} 366 node := []AccountID{{Account: 3}} 367 client, err := _NewMockClient() 368 client.SetLedgerID(*NewLedgerIDTestnet()) 369 require.NoError(t, err) 370 privateKey, err := PrivateKeyFromString(mockPrivateKey) 371 client.SetOperator(AccountID{Account: 2}, privateKey) 372 373 query := NewAccountInfoQuery(). 374 SetAccountID(accountID). 375 SetNodeAccountIDs(node). 376 SetPaymentTransactionID(testTransactionID). 377 SetMaxQueryPayment(NewHbar(1)). 378 SetQueryPayment(HbarFromTinybar(25)) 379 380 body := query.buildQuery() 381 _, err = query.generatePayments(client, HbarFromTinybar(20)) 382 require.NoError(t, err) 383 384 var paymentTx services.TransactionBody 385 _ = protobuf.Unmarshal(query.Query.paymentTransactions[0].BodyBytes, &paymentTx) 386 387 require.Equal(t, body.GetCryptoGetInfo().AccountID.String(), accountID._ToProtobuf().String()) 388 require.Equal(t, paymentTx.NodeAccountID.String(), node[0]._ToProtobuf().String()) 389 require.Equal(t, paymentTx.TransactionFee, uint64(NewHbar(1).tinybar)) 390 require.Equal(t, paymentTx.TransactionValidDuration, &services.Duration{Seconds: 120}) 391 require.Equal(t, paymentTx.Data, &services.TransactionBody_CryptoTransfer{ 392 CryptoTransfer: &services.CryptoTransferTransactionBody{ 393 Transfers: &services.TransferList{ 394 AccountAmounts: []*services.AccountAmount{ 395 { 396 AccountID: node[0]._ToProtobuf(), 397 Amount: HbarFromTinybar(20).AsTinybar(), 398 }, 399 { 400 AccountID: client.GetOperatorAccountID()._ToProtobuf(), 401 Amount: -HbarFromTinybar(20).AsTinybar(), 402 }, 403 }, 404 }, 405 }, 406 }) 407 } 408 func TestUnitTransactionInitFeeMaxTransactionWithouthSettingFee(t *testing.T) { 409 t.Parallel() 410 411 //Default Max Fee for TransferTransaction 412 fee := NewHbar(1) 413 client, err := _NewMockClient() 414 client.SetLedgerID(*NewLedgerIDTestnet()) 415 require.NoError(t, err) 416 transaction, err := NewTransferTransaction(). 417 AddHbarTransfer(AccountID{Account: 2}, HbarFromTinybar(-100)). 418 AddHbarTransfer(AccountID{Account: 3}, HbarFromTinybar(100)). 419 FreezeWith(client) 420 require.NoError(t, err) 421 require.Equal(t, uint64(fee.AsTinybar()), transaction.transactionFee) 422 } 423 424 func TestUnitTransactionInitFeeMaxTransactionFeeSetExplicitly(t *testing.T) { 425 t.Parallel() 426 427 clientMaxFee := NewHbar(14) 428 explicitMaxFee := NewHbar(15) 429 client, err := _NewMockClient() 430 client.SetLedgerID(*NewLedgerIDTestnet()) 431 client.SetDefaultMaxTransactionFee(clientMaxFee) 432 require.NoError(t, err) 433 transaction, err := NewTransferTransaction(). 434 AddHbarTransfer(AccountID{Account: 2}, HbarFromTinybar(-100)). 435 AddHbarTransfer(AccountID{Account: 3}, HbarFromTinybar(100)). 436 SetMaxTransactionFee(explicitMaxFee). 437 FreezeWith(client) 438 require.NoError(t, err) 439 require.Equal(t, uint64(explicitMaxFee.AsTinybar()), transaction.transactionFee) 440 } 441 442 func TestUnitTransactionInitFeeMaxTransactionFromClientDefault(t *testing.T) { 443 t.Parallel() 444 445 fee := NewHbar(14) 446 client, err := _NewMockClient() 447 client.SetLedgerID(*NewLedgerIDTestnet()) 448 client.SetDefaultMaxTransactionFee(fee) 449 require.NoError(t, err) 450 transaction, err := NewTransferTransaction(). 451 AddHbarTransfer(AccountID{Account: 2}, HbarFromTinybar(-100)). 452 AddHbarTransfer(AccountID{Account: 3}, HbarFromTinybar(100)). 453 FreezeWith(client) 454 require.NoError(t, err) 455 require.Equal(t, uint64(fee.AsTinybar()), transaction.transactionFee) 456 } 457 458 func TestUnitTransactionSignSwitchCases(t *testing.T) { 459 t.Parallel() 460 461 newKey, client, nodeAccountId := signSwitchCaseaSetup(t) 462 463 txs := []Executable{ 464 NewAccountCreateTransaction(), 465 NewAccountDeleteTransaction(), 466 NewAccountUpdateTransaction(), 467 NewAccountAllowanceApproveTransaction(), 468 NewAccountAllowanceDeleteTransaction(), 469 NewFileCreateTransaction(), 470 NewFileDeleteTransaction(), 471 NewFileUpdateTransaction(), 472 NewLiveHashAddTransaction(), 473 NewLiveHashDeleteTransaction(), 474 NewTokenAssociateTransaction(), 475 NewTokenBurnTransaction(), 476 NewTokenCreateTransaction(), 477 NewTokenDeleteTransaction(), 478 NewTokenDissociateTransaction(), 479 NewTokenFeeScheduleUpdateTransaction(), 480 NewTokenFreezeTransaction(), 481 NewTokenGrantKycTransaction(), 482 NewTokenMintTransaction(), 483 NewTokenRevokeKycTransaction(), 484 NewTokenUnfreezeTransaction(), 485 NewTokenUpdateTransaction(), 486 NewTokenWipeTransaction(), 487 NewTopicCreateTransaction(), 488 NewTopicDeleteTransaction(), 489 NewTopicUpdateTransaction(), 490 NewTransferTransaction(), 491 } 492 493 for _, tx := range txs { 494 495 txVal, signature, transferTxBytes := signSwitchCaseaHelper(t, tx, newKey, client) 496 497 signTests := signTestsForTransaction(txVal, newKey, signature, client) 498 499 for _, tt := range signTests { 500 t.Run(tt.name, func(t *testing.T) { 501 transactionInterface, err := TransactionFromBytes(transferTxBytes) 502 require.NoError(t, err) 503 504 tx, err := tt.sign(transactionInterface, newKey) 505 assert.NoError(t, err) 506 assert.NotEmpty(t, tx) 507 508 signs, err := TransactionGetSignatures(transactionInterface) 509 assert.NoError(t, err) 510 511 // verify with range because var signs = map[AccountID]map[*PublicKey][]byte, where *PublicKey is unknown memory address 512 for key := range signs[nodeAccountId] { 513 assert.Equal(t, signs[nodeAccountId][key], signature) 514 } 515 }) 516 } 517 } 518 } 519 520 func TestUnitTransactionSignSwitchCasesPointers(t *testing.T) { 521 t.Parallel() 522 523 newKey, client, nodeAccountId := signSwitchCaseaSetup(t) 524 525 txs := []interface{}{ 526 NewAccountCreateTransaction(), 527 NewAccountDeleteTransaction(), 528 NewAccountUpdateTransaction(), 529 NewAccountAllowanceApproveTransaction(), 530 NewAccountAllowanceDeleteTransaction(), 531 NewFileCreateTransaction(), 532 NewFileDeleteTransaction(), 533 NewFileUpdateTransaction(), 534 NewLiveHashAddTransaction(), 535 NewLiveHashDeleteTransaction(), 536 NewTokenAssociateTransaction(), 537 NewTokenBurnTransaction(), 538 NewTokenCreateTransaction(), 539 NewTokenDeleteTransaction(), 540 NewTokenDissociateTransaction(), 541 NewTokenFeeScheduleUpdateTransaction(), 542 NewTokenFreezeTransaction(), 543 NewTokenGrantKycTransaction(), 544 NewTokenMintTransaction(), 545 NewTokenRevokeKycTransaction(), 546 NewTokenUnfreezeTransaction(), 547 NewTokenUpdateTransaction(), 548 NewTokenWipeTransaction(), 549 NewTopicCreateTransaction(), 550 NewTopicDeleteTransaction(), 551 NewTopicUpdateTransaction(), 552 NewTransferTransaction(), 553 } 554 555 for _, tx := range txs { 556 557 txVal, signature, transferTxBytes := signSwitchCaseaHelper(t, tx, newKey, client) 558 signTests := signTestsForTransaction(txVal, newKey, signature, client) 559 560 for _, tt := range signTests { 561 t.Run(tt.name, func(t *testing.T) { 562 transactionInterface, err := TransactionFromBytes(transferTxBytes) 563 require.NoError(t, err) 564 565 // Convert the transactionInterface to a pointer 566 ptr := reflect.New(reflect.TypeOf(transactionInterface)) 567 ptr.Elem().Set(reflect.ValueOf(transactionInterface)) 568 569 tx, err := tt.sign(ptr.Interface(), newKey) 570 assert.NoError(t, err) 571 assert.NotEmpty(t, tx) 572 573 signs, err := TransactionGetSignatures(ptr.Interface()) 574 assert.NoError(t, err) 575 576 // verify with range because var signs = map[AccountID]map[*PublicKey][]byte, where *PublicKey is unknown memory address 577 for key := range signs[nodeAccountId] { 578 assert.Equal(t, signs[nodeAccountId][key], signature) 579 } 580 }) 581 } 582 } 583 } 584 585 func TestUnitTransactionAttributes(t *testing.T) { 586 t.Parallel() 587 588 client, err := _NewMockClient() 589 require.NoError(t, err) 590 client.SetLedgerID(*NewLedgerIDTestnet()) 591 nodeAccountIds := client.network._GetNodeAccountIDsForExecute() 592 593 txs := []interface{}{ 594 NewAccountCreateTransaction(), 595 NewAccountDeleteTransaction(), 596 NewAccountUpdateTransaction(), 597 NewAccountAllowanceApproveTransaction(), 598 NewAccountAllowanceDeleteTransaction(), 599 NewContractCreateTransaction(), 600 NewContractDeleteTransaction(), 601 NewContractExecuteTransaction(), 602 NewContractUpdateTransaction(), 603 NewFileAppendTransaction(), 604 NewFileCreateTransaction(), 605 NewFileDeleteTransaction(), 606 NewFileUpdateTransaction(), 607 NewLiveHashAddTransaction(), 608 NewLiveHashDeleteTransaction(), 609 NewScheduleCreateTransaction(), 610 NewScheduleDeleteTransaction(), 611 NewScheduleSignTransaction(), 612 NewSystemDeleteTransaction(), 613 NewSystemUndeleteTransaction(), 614 NewTokenAssociateTransaction(), 615 NewTokenBurnTransaction(), 616 NewTokenCreateTransaction(), 617 NewTokenDeleteTransaction(), 618 NewTokenDissociateTransaction(), 619 NewTokenFeeScheduleUpdateTransaction(), 620 NewTokenFreezeTransaction(), 621 NewTokenGrantKycTransaction(), 622 NewTokenMintTransaction(), 623 NewTokenRevokeKycTransaction(), 624 NewTokenUnfreezeTransaction(), 625 NewTokenUpdateTransaction(), 626 NewTokenWipeTransaction(), 627 NewTopicCreateTransaction(), 628 NewTopicDeleteTransaction(), 629 NewTopicUpdateTransaction(), 630 NewTransferTransaction(), 631 } 632 633 for _, tx := range txs { 634 txName := reflect.TypeOf(tx).Elem().Name() 635 636 tests := createTransactionTests(txName, nodeAccountIds) 637 638 for _, tt := range tests { 639 t.Run(tt.name, func(t *testing.T) { 640 txSet, err := tt.set(tx) 641 require.NoError(t, err) 642 643 txGet, err := tt.get(txSet) 644 require.NoError(t, err) 645 646 tt.assert(t, txGet) 647 }) 648 } 649 } 650 } 651 652 func TestUnitTransactionAttributesDereferanced(t *testing.T) { 653 t.Parallel() 654 655 client, err := _NewMockClient() 656 require.NoError(t, err) 657 client.SetLedgerID(*NewLedgerIDTestnet()) 658 nodeAccountIds := client.network._GetNodeAccountIDsForExecute() 659 660 txs := []interface{}{ 661 NewAccountCreateTransaction(), 662 NewAccountDeleteTransaction(), 663 NewAccountUpdateTransaction(), 664 NewAccountAllowanceApproveTransaction(), 665 NewAccountAllowanceDeleteTransaction(), 666 NewContractCreateTransaction(), 667 NewContractDeleteTransaction(), 668 NewContractExecuteTransaction(), 669 NewContractUpdateTransaction(), 670 NewFileAppendTransaction(), 671 NewFileCreateTransaction(), 672 NewFileDeleteTransaction(), 673 NewFileUpdateTransaction(), 674 NewLiveHashAddTransaction(), 675 NewLiveHashDeleteTransaction(), 676 NewScheduleCreateTransaction(), 677 NewScheduleDeleteTransaction(), 678 NewScheduleSignTransaction(), 679 NewSystemDeleteTransaction(), 680 NewSystemUndeleteTransaction(), 681 NewTokenAssociateTransaction(), 682 NewTokenBurnTransaction(), 683 NewTokenCreateTransaction(), 684 NewTokenDeleteTransaction(), 685 NewTokenDissociateTransaction(), 686 NewTokenFeeScheduleUpdateTransaction(), 687 NewTokenFreezeTransaction(), 688 NewTokenGrantKycTransaction(), 689 NewTokenMintTransaction(), 690 NewTokenRevokeKycTransaction(), 691 NewTokenUnfreezeTransaction(), 692 NewTokenUpdateTransaction(), 693 NewTokenWipeTransaction(), 694 NewTopicCreateTransaction(), 695 NewTopicDeleteTransaction(), 696 NewTopicUpdateTransaction(), 697 NewTransferTransaction(), 698 } 699 700 for _, tx := range txs { 701 txName := reflect.TypeOf(tx).Elem().Name() 702 703 tests := createTransactionTests(txName, nodeAccountIds) 704 705 for _, tt := range tests { 706 t.Run(tt.name, func(t *testing.T) { 707 txValue := reflect.ValueOf(tx).Elem().Interface() 708 txSet, err := tt.set(txValue) 709 require.NoError(t, err) 710 711 txGet, err := tt.get(txSet) 712 require.NoError(t, err) 713 714 tt.assert(t, txGet) 715 }) 716 } 717 } 718 } 719 720 func TestUnitTransactionAttributesSerialization(t *testing.T) { 721 t.Parallel() 722 723 client, err := _NewMockClient() 724 require.NoError(t, err) 725 client.SetLedgerID(*NewLedgerIDTestnet()) 726 727 txs := []interface{}{ 728 NewAccountCreateTransaction(), 729 NewAccountDeleteTransaction(), 730 NewAccountUpdateTransaction(), 731 NewAccountAllowanceApproveTransaction(), 732 NewAccountAllowanceDeleteTransaction(), 733 NewContractCreateTransaction(), 734 NewContractDeleteTransaction(), 735 NewContractExecuteTransaction(), 736 NewContractUpdateTransaction(), 737 NewFileCreateTransaction(), 738 NewFileDeleteTransaction(), 739 NewFileUpdateTransaction(), 740 NewLiveHashAddTransaction(), 741 NewLiveHashDeleteTransaction(), 742 NewScheduleCreateTransaction(), 743 NewScheduleDeleteTransaction(), 744 NewScheduleSignTransaction(), 745 NewSystemDeleteTransaction(), 746 NewSystemUndeleteTransaction(), 747 NewTokenAssociateTransaction(), 748 NewTokenBurnTransaction(), 749 NewTokenCreateTransaction(), 750 NewTokenDeleteTransaction(), 751 NewTokenDissociateTransaction(), 752 NewTokenFeeScheduleUpdateTransaction(), 753 NewTokenFreezeTransaction(), 754 NewTokenGrantKycTransaction(), 755 NewTokenMintTransaction(), 756 NewTokenRevokeKycTransaction(), 757 NewTokenUnfreezeTransaction(), 758 NewTokenUpdateTransaction(), 759 NewTokenWipeTransaction(), 760 NewTopicCreateTransaction(), 761 NewTopicDeleteTransaction(), 762 NewTopicUpdateTransaction(), 763 NewTransferTransaction(), 764 } 765 766 for _, tx := range txs { 767 txName := reflect.TypeOf(tx).Elem().Name() 768 769 // Get the reflect.Value of the pointer to the Transaction 770 txPtr := reflect.ValueOf(tx) 771 txPtr.MethodByName("FreezeWith").Call([]reflect.Value{reflect.ValueOf(client)}) 772 773 tests := []struct { 774 name string 775 act func(transactionInterface interface{}) 776 }{ 777 { 778 name: "TransactionString/" + txName, 779 act: func(transactionInterface interface{}) { 780 txString, err := TransactionString(transactionInterface) 781 require.NoError(t, err) 782 require.NotEmpty(t, txString) 783 }, 784 }, 785 { 786 name: "TransactionToBytes/" + txName, 787 act: func(transactionInterface interface{}) { 788 txBytes, err := TransactionToBytes(transactionInterface) 789 require.NoError(t, err) 790 require.NotEmpty(t, txBytes) 791 }, 792 }, 793 } 794 795 for _, tt := range tests { 796 t.Run(tt.name, func(t *testing.T) { 797 tt.act(tx) 798 txValue := reflect.ValueOf(tx).Elem().Interface() 799 tt.act(txValue) 800 }) 801 } 802 } 803 } 804 805 func signSwitchCaseaSetup(t *testing.T) (PrivateKey, *Client, AccountID) { 806 newKey, err := GeneratePrivateKey() 807 require.NoError(t, err) 808 809 client, err := _NewMockClient() 810 require.NoError(t, err) 811 client.SetLedgerID(*NewLedgerIDTestnet()) 812 813 nodeAccountIds := client.network._GetNodeAccountIDsForExecute() 814 nodeAccountId := nodeAccountIds[0] 815 816 return newKey, client, nodeAccountId 817 } 818 819 func signSwitchCaseaHelper(t *testing.T, tx interface{}, newKey PrivateKey, client *Client) (txVal reflect.Value, signature []byte, transferTxBytes []byte) { 820 // Get the reflect.Value of the pointer to the transaction 821 txPtr := reflect.ValueOf(tx) 822 txPtr.MethodByName("FreezeWith").Call([]reflect.Value{reflect.ValueOf(client)}) 823 824 // Get the reflect.Value of the transaction 825 txVal = txPtr.Elem() 826 827 // Get the transaction field by name 828 txField := txVal.FieldByName("Transaction") 829 830 // Get the value of the Transaction field 831 txValue := txField.Interface().(Transaction) 832 833 refl_signature := reflect.ValueOf(newKey).MethodByName("SignTransaction").Call([]reflect.Value{reflect.ValueOf(&txValue)}) 834 signature = refl_signature[0].Interface().([]byte) 835 836 transferTxBytes, err := TransactionToBytes(tx) 837 assert.NoError(t, err) 838 assert.NotEmpty(t, transferTxBytes) 839 840 return txVal, signature, transferTxBytes 841 } 842 843 func signTestsForTransaction(txVal reflect.Value, newKey PrivateKey, signature []byte, client *Client) []struct { 844 name string 845 sign func(transactionInterface interface{}, key Key) (interface{}, error) 846 } { 847 return []struct { 848 name string 849 sign func(transactionInterface interface{}, key Key) (interface{}, error) 850 }{ 851 { 852 name: "TransactionSign/" + txVal.Type().Name(), 853 sign: func(transactionInterface interface{}, key Key) (interface{}, error) { 854 privateKey, ok := key.(PrivateKey) 855 if !ok { 856 panic("key is not a PrivateKey") 857 } 858 return TransactionSign(transactionInterface, privateKey) 859 }, 860 }, 861 { 862 name: "TransactionSignWith/" + txVal.Type().Name(), 863 sign: func(transactionInterface interface{}, key Key) (interface{}, error) { 864 return TransactionSignWth(transactionInterface, newKey.PublicKey(), newKey.Sign) 865 }, 866 }, 867 { 868 name: "TransactionSignWithOperator/" + txVal.Type().Name(), 869 sign: func(transactionInterface interface{}, key Key) (interface{}, error) { 870 return TransactionSignWithOperator(transactionInterface, client) 871 }, 872 }, 873 { 874 name: "TransactionAddSignature/" + txVal.Type().Name(), 875 sign: func(transactionInterface interface{}, key Key) (interface{}, error) { 876 return TransactionAddSignature(transactionInterface, newKey.PublicKey(), signature) 877 }, 878 }, 879 } 880 } 881 882 type transactionTest struct { 883 name string 884 set func(transactionInterface interface{}) (interface{}, error) 885 get func(transactionInterface interface{}) (interface{}, error) 886 assert func(t *testing.T, actual interface{}) 887 } 888 889 func createTransactionTests(txName string, nodeAccountIds []AccountID) []transactionTest { 890 return []transactionTest{ 891 { 892 name: "TransactionTransactionID/" + txName, 893 set: func(transactionInterface interface{}) (interface{}, error) { 894 transactionID := TransactionID{AccountID: &AccountID{Account: 9999}, ValidStart: &time.Time{}, scheduled: false, Nonce: nil} 895 return TransactionSetTransactionID(transactionInterface, transactionID) 896 }, 897 get: func(transactionInterface interface{}) (interface{}, error) { 898 return TransactionGetTransactionID(transactionInterface) 899 }, 900 assert: func(t *testing.T, actual interface{}) { 901 transactionID := TransactionID{AccountID: &AccountID{Account: 9999}, ValidStart: &time.Time{}, scheduled: false, Nonce: nil} 902 A := actual.(TransactionID) 903 904 require.Equal(t, transactionID.AccountID, A.AccountID) 905 }, 906 }, 907 { 908 name: "TransactionTransactionMemo/" + txName, 909 set: func(transactionInterface interface{}) (interface{}, error) { 910 return TransactionSetTransactionMemo(transactionInterface, "test memo") 911 }, 912 get: func(transactionInterface interface{}) (interface{}, error) { 913 return TransactionGetTransactionMemo(transactionInterface) 914 }, 915 assert: func(t *testing.T, actual interface{}) { 916 require.Equal(t, "test memo", actual) 917 }, 918 }, 919 { 920 name: "TransactionMaxTransactionFee/" + txName, 921 set: func(transactionInterface interface{}) (interface{}, error) { 922 return TransactionSetMaxTransactionFee(transactionInterface, NewHbar(1)) 923 }, 924 get: func(transactionInterface interface{}) (interface{}, error) { 925 return TransactionGetMaxTransactionFee(transactionInterface) 926 }, 927 assert: func(t *testing.T, actual interface{}) { 928 require.Equal(t, NewHbar(1), actual) 929 }, 930 }, 931 { 932 name: "TransactionTransactionValidDuration/" + txName, 933 set: func(transactionInterface interface{}) (interface{}, error) { 934 return TransactionSetTransactionValidDuration(transactionInterface, time.Second*10) 935 }, 936 get: func(transactionInterface interface{}) (interface{}, error) { 937 return TransactionGetTransactionValidDuration(transactionInterface) 938 }, 939 assert: func(t *testing.T, actual interface{}) { 940 require.Equal(t, time.Second*10, actual) 941 }, 942 }, 943 { 944 name: "TransactionNodeAccountIDs/" + txName, 945 set: func(transactionInterface interface{}) (interface{}, error) { 946 return TransactionSetNodeAccountIDs(transactionInterface, nodeAccountIds) 947 }, 948 get: func(transactionInterface interface{}) (interface{}, error) { 949 return TransactionGetNodeAccountIDs(transactionInterface) 950 }, 951 assert: func(t *testing.T, actual interface{}) { 952 require.Equal(t, nodeAccountIds, actual) 953 }, 954 }, 955 { 956 name: "TransactionMinBackoff/" + txName, 957 set: func(transactionInterface interface{}) (interface{}, error) { 958 tx, _ := TransactionSetMaxBackoff(transactionInterface, time.Second*200) 959 return TransactionSetMinBackoff(tx, time.Second*10) 960 }, 961 get: func(transactionInterface interface{}) (interface{}, error) { 962 return TransactionGetMinBackoff(transactionInterface) 963 }, 964 assert: func(t *testing.T, actual interface{}) { 965 require.Equal(t, time.Second*10, actual) 966 }, 967 }, 968 { 969 name: "TransactionMaxBackoff/" + txName, 970 set: func(transactionInterface interface{}) (interface{}, error) { 971 return TransactionSetMaxBackoff(transactionInterface, time.Second*200) 972 }, 973 get: func(transactionInterface interface{}) (interface{}, error) { 974 return TransactionGetMaxBackoff(transactionInterface) 975 }, 976 assert: func(t *testing.T, actual interface{}) { 977 require.Equal(t, time.Second*200, actual) 978 }, 979 }, 980 } 981 } 982 983 // TransactionGetTransactionHash //needs to be tested in e2e tests 984 // TransactionGetTransactionHashPerNode //needs to be tested in e2e tests 985 // TransactionExecute //needs to be tested in e2e tests