github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/transaction_receipt_query_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 "encoding/hex" 28 "encoding/json" 29 "testing" 30 31 "github.com/hashgraph/hedera-protobufs-go/services" 32 "github.com/stretchr/testify/assert" 33 34 "github.com/stretchr/testify/require" 35 ) 36 37 func TestUnitTransactionReceiptQueryValidate(t *testing.T) { 38 t.Parallel() 39 40 client, err := _NewMockClient() 41 client.SetLedgerID(*NewLedgerIDTestnet()) 42 require.NoError(t, err) 43 client.SetAutoValidateChecksums(true) 44 accountID, err := AccountIDFromString("0.0.123-esxsf") 45 transactionID := TransactionIDGenerate(accountID) 46 require.NoError(t, err) 47 48 receiptQuery := NewTransactionReceiptQuery(). 49 SetTransactionID(transactionID) 50 51 err = receiptQuery.validateNetworkOnIDs(client) 52 require.NoError(t, err) 53 } 54 55 func TestUnitTransactionReceiptQueryValidateWrong(t *testing.T) { 56 t.Parallel() 57 58 client, err := _NewMockClient() 59 client.SetLedgerID(*NewLedgerIDTestnet()) 60 require.NoError(t, err) 61 client.SetAutoValidateChecksums(true) 62 accountID, err := AccountIDFromString("0.0.123-rmkykd") 63 transactionID := TransactionIDGenerate(accountID) 64 require.NoError(t, err) 65 66 receiptQuery := NewTransactionReceiptQuery(). 67 SetTransactionID(transactionID) 68 69 err = receiptQuery.validateNetworkOnIDs(client) 70 assert.Error(t, err) 71 if err != nil { 72 assert.Equal(t, "network mismatch or wrong checksum given, given checksum: rmkykd, correct checksum esxsf, network: testnet", err.Error()) 73 } 74 } 75 76 func TestUnitTransactionReceiptQueryGet(t *testing.T) { 77 t.Parallel() 78 79 txID := TransactionIDGenerate(AccountID{Account: 7}) 80 81 balance := NewTransactionReceiptQuery(). 82 SetTransactionID(txID). 83 SetIncludeDuplicates(true). 84 SetIncludeChildren(true). 85 SetQueryPayment(NewHbar(2)). 86 SetMaxQueryPayment(NewHbar(1)). 87 SetNodeAccountIDs([]AccountID{{Account: 10}, {Account: 11}, {Account: 12}}) 88 89 balance.GetTransactionID() 90 balance.GetIncludeChildren() 91 balance.GetIncludeDuplicates() 92 balance.GetNodeAccountIDs() 93 balance.GetMinBackoff() 94 balance.GetMaxBackoff() 95 balance.GetMaxRetryCount() 96 balance.GetPaymentTransactionID() 97 balance.GetQueryPayment() 98 balance.GetMaxQueryPayment() 99 } 100 101 func TestUnitTransactionReceiptQueryNothingSet(t *testing.T) { 102 t.Parallel() 103 104 balance := NewTransactionReceiptQuery() 105 106 balance.GetTransactionID() 107 balance.GetIncludeChildren() 108 balance.GetIncludeDuplicates() 109 balance.GetNodeAccountIDs() 110 balance.GetMinBackoff() 111 balance.GetMaxBackoff() 112 balance.GetMaxRetryCount() 113 balance.GetPaymentTransactionID() 114 balance.GetQueryPayment() 115 balance.GetMaxQueryPayment() 116 } 117 118 func TestUnitTransactionPlatformNotActiveGracefulHandling(t *testing.T) { 119 t.Parallel() 120 121 responses := [][]interface{}{{ 122 &services.TransactionResponse{ 123 NodeTransactionPrecheckCode: services.ResponseCodeEnum_OK, 124 }, 125 &services.Response{ 126 Response: &services.Response_TransactionGetReceipt{ 127 TransactionGetReceipt: &services.TransactionGetReceiptResponse{ 128 Header: &services.ResponseHeader{ 129 Cost: 0, 130 ResponseType: services.ResponseType_ANSWER_ONLY, 131 }, 132 Receipt: &services.TransactionReceipt{ 133 Status: services.ResponseCodeEnum_PLATFORM_NOT_ACTIVE, 134 }, 135 }, 136 }, 137 }, 138 &services.Response{ 139 Response: &services.Response_TransactionGetReceipt{ 140 TransactionGetReceipt: &services.TransactionGetReceiptResponse{ 141 Header: &services.ResponseHeader{ 142 Cost: 0, 143 ResponseType: services.ResponseType_ANSWER_ONLY, 144 }, 145 Receipt: &services.TransactionReceipt{ 146 Status: services.ResponseCodeEnum_SUCCESS, 147 }, 148 }, 149 }, 150 }, 151 }} 152 client, server := NewMockClientAndServer(responses) 153 defer server.Close() 154 tx, err := NewTransferTransaction(). 155 SetNodeAccountIDs([]AccountID{{Account: 3}}). 156 AddHbarTransfer(AccountID{Account: 2}, HbarFromTinybar(-1)). 157 AddHbarTransfer(AccountID{Account: 3}, HbarFromTinybar(1)). 158 Execute(client) 159 client.SetMaxAttempts(2) 160 require.NoError(t, err) 161 _, err = tx.SetValidateStatus(true).GetReceipt(client) 162 require.NoError(t, err) 163 } 164 165 func TestUnitTransactionReceiptNotFound(t *testing.T) { 166 t.Parallel() 167 168 responses := [][]interface{}{{ 169 &services.TransactionResponse{ 170 NodeTransactionPrecheckCode: services.ResponseCodeEnum_OK, 171 }, 172 &services.Response{ 173 Response: &services.Response_TransactionGetReceipt{ 174 TransactionGetReceipt: &services.TransactionGetReceiptResponse{ 175 Header: &services.ResponseHeader{ 176 Cost: 0, 177 ResponseType: services.ResponseType_ANSWER_ONLY, 178 }, 179 Receipt: &services.TransactionReceipt{ 180 Status: services.ResponseCodeEnum_RECEIPT_NOT_FOUND, 181 }, 182 }, 183 }, 184 }, 185 &services.Response{ 186 Response: &services.Response_TransactionGetReceipt{ 187 TransactionGetReceipt: &services.TransactionGetReceiptResponse{ 188 Header: &services.ResponseHeader{ 189 Cost: 0, 190 ResponseType: services.ResponseType_ANSWER_ONLY, 191 }, 192 Receipt: &services.TransactionReceipt{ 193 Status: services.ResponseCodeEnum_RECEIPT_NOT_FOUND, 194 }, 195 }, 196 }, 197 }, 198 }} 199 client, server := NewMockClientAndServer(responses) 200 defer server.Close() 201 tx, err := NewTransferTransaction(). 202 SetNodeAccountIDs([]AccountID{{Account: 3}}). 203 AddHbarTransfer(AccountID{Account: 2}, HbarFromTinybar(-1)). 204 AddHbarTransfer(AccountID{Account: 3}, HbarFromTinybar(1)). 205 Execute(client) 206 client.SetMaxAttempts(2) 207 require.NoError(t, err) 208 receipt, err := tx.SetValidateStatus(true).GetReceipt(client) 209 require.Error(t, err) 210 require.Equal(t, "exceptional precheck status RECEIPT_NOT_FOUND", err.Error()) 211 require.Equal(t, StatusReceiptNotFound, receipt.Status) 212 } 213 214 func TestUnitTransactionReceiptUknown(t *testing.T) { 215 t.Parallel() 216 217 responses := [][]interface{}{{ 218 &services.TransactionResponse{ 219 NodeTransactionPrecheckCode: services.ResponseCodeEnum_OK, 220 }, 221 &services.Response{ 222 Response: &services.Response_TransactionGetReceipt{ 223 TransactionGetReceipt: &services.TransactionGetReceiptResponse{ 224 Header: &services.ResponseHeader{ 225 Cost: 0, 226 ResponseType: services.ResponseType_ANSWER_ONLY, 227 }, 228 Receipt: &services.TransactionReceipt{ 229 Status: services.ResponseCodeEnum_UNKNOWN, 230 }, 231 }, 232 }, 233 }, 234 &services.Response{ 235 Response: &services.Response_TransactionGetReceipt{ 236 TransactionGetReceipt: &services.TransactionGetReceiptResponse{ 237 Header: &services.ResponseHeader{ 238 Cost: 0, 239 ResponseType: services.ResponseType_ANSWER_ONLY, 240 }, 241 Receipt: &services.TransactionReceipt{ 242 Status: services.ResponseCodeEnum_SUCCESS, 243 }, 244 }, 245 }, 246 }, 247 }} 248 client, server := NewMockClientAndServer(responses) 249 defer server.Close() 250 tx, err := NewTransferTransaction(). 251 SetNodeAccountIDs([]AccountID{{Account: 3}}). 252 AddHbarTransfer(AccountID{Account: 2}, HbarFromTinybar(-1)). 253 AddHbarTransfer(AccountID{Account: 3}, HbarFromTinybar(1)). 254 Execute(client) 255 client.SetMaxAttempts(2) 256 require.NoError(t, err) 257 receipt, err := tx.SetValidateStatus(true).GetReceipt(client) 258 require.NoError(t, err) 259 require.Equal(t, StatusSuccess, receipt.Status) 260 } 261 262 func TestUnitTransactionReceiptToJson(t *testing.T) { 263 t.Parallel() 264 265 responses := [][]interface{}{{ 266 &services.TransactionResponse{ 267 NodeTransactionPrecheckCode: services.ResponseCodeEnum_OK, 268 }, 269 &services.Response{ 270 Response: &services.Response_TransactionGetReceipt{ 271 TransactionGetReceipt: &services.TransactionGetReceiptResponse{ 272 Header: &services.ResponseHeader{ 273 Cost: 0, 274 ResponseType: services.ResponseType_ANSWER_ONLY, 275 }, 276 Receipt: &services.TransactionReceipt{ 277 Status: services.ResponseCodeEnum_SUCCESS, 278 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{ 279 AccountNum: 123, 280 }}, 281 ContractID: &services.ContractID{Contract: &services.ContractID_ContractNum{ 282 ContractNum: 456, 283 }}, 284 FileID: &services.FileID{FileNum: 789}, 285 TokenID: &services.TokenID{TokenNum: 987}, 286 SerialNumbers: []int64{1, 2, 3}, 287 TopicID: &services.TopicID{TopicNum: 654}, 288 ScheduleID: &services.ScheduleID{ScheduleNum: 321}, 289 NodeId: 1, 290 ScheduledTransactionID: &services.TransactionID{ 291 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{ 292 AccountNum: 123, 293 }}, 294 TransactionValidStart: &services.Timestamp{ 295 Seconds: 1694689200, 296 }, 297 }, 298 TopicSequenceNumber: 10, 299 TopicRunningHash: []byte{10}, 300 ExchangeRate: &services.ExchangeRateSet{ 301 CurrentRate: &services.ExchangeRate{ 302 HbarEquiv: 30000, 303 CentEquiv: 154271, 304 ExpirationTime: &services.TimestampSeconds{ 305 Seconds: 1694689200, 306 }, 307 }, 308 }, 309 }, 310 ChildTransactionReceipts: []*services.TransactionReceipt{ 311 { 312 Status: services.ResponseCodeEnum_SUCCESS, 313 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{ 314 AccountNum: 123, 315 }}, 316 ContractID: &services.ContractID{Contract: &services.ContractID_ContractNum{ 317 ContractNum: 456, 318 }}, 319 FileID: &services.FileID{FileNum: 789}, 320 TokenID: &services.TokenID{TokenNum: 987}, 321 SerialNumbers: []int64{1, 2, 3}, 322 TopicID: &services.TopicID{TopicNum: 654}, 323 ScheduleID: &services.ScheduleID{ScheduleNum: 321}, 324 ScheduledTransactionID: &services.TransactionID{ 325 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{ 326 AccountNum: 123, 327 }}, 328 TransactionValidStart: &services.Timestamp{ 329 Seconds: 1694689200, 330 }, 331 }, 332 TopicSequenceNumber: 10, 333 TopicRunningHash: []byte{10}, 334 ExchangeRate: &services.ExchangeRateSet{ 335 CurrentRate: &services.ExchangeRate{ 336 HbarEquiv: 30000, 337 CentEquiv: 154271, 338 ExpirationTime: &services.TimestampSeconds{ 339 Seconds: 1694689200, 340 }, 341 }, 342 }, 343 }, 344 }, 345 DuplicateTransactionReceipts: []*services.TransactionReceipt{ 346 { 347 Status: services.ResponseCodeEnum_SUCCESS, 348 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{ 349 AccountNum: 123, 350 }}, 351 ContractID: &services.ContractID{Contract: &services.ContractID_ContractNum{ 352 ContractNum: 456, 353 }}, 354 FileID: &services.FileID{FileNum: 789}, 355 TokenID: &services.TokenID{TokenNum: 987}, 356 SerialNumbers: []int64{1, 2, 3}, 357 TopicID: &services.TopicID{TopicNum: 654}, 358 ScheduleID: &services.ScheduleID{ScheduleNum: 321}, 359 ScheduledTransactionID: &services.TransactionID{ 360 AccountID: &services.AccountID{Account: &services.AccountID_AccountNum{ 361 AccountNum: 123, 362 }}, 363 TransactionValidStart: &services.Timestamp{ 364 Seconds: 1694689200, 365 }, 366 }, 367 TopicSequenceNumber: 10, 368 TopicRunningHash: []byte{10}, 369 ExchangeRate: &services.ExchangeRateSet{ 370 CurrentRate: &services.ExchangeRate{ 371 HbarEquiv: 30000, 372 CentEquiv: 154271, 373 ExpirationTime: &services.TimestampSeconds{ 374 Seconds: 1694689200, 375 }, 376 }, 377 }, 378 }, 379 }, 380 }, 381 }, 382 }, 383 }} 384 client, server := NewMockClientAndServer(responses) 385 defer server.Close() 386 tx, err := NewTransferTransaction(). 387 SetNodeAccountIDs([]AccountID{{Account: 3}}). 388 AddHbarTransfer(AccountID{Account: 2}, HbarFromTinybar(-1)). 389 AddHbarTransfer(AccountID{Account: 3}, HbarFromTinybar(1)). 390 Execute(client) 391 require.NoError(t, err) 392 receipt, err := tx.SetValidateStatus(true).GetReceipt(client) 393 require.NoError(t, err) 394 jsonBytes, err := receipt.MarshalJSON() 395 require.NoError(t, err) 396 expected := `{"accountId":"0.0.123","children":[{"accountId":"0.0.123","children":[],"contractId":"0.0.456","duplicates":[],"exchangeRate": 397 {"hbars":30000,"cents":154271,"expirationTime":"2023-09-14T11:00:00.000Z"},"fileId":"0.0.789","nodeId":0,"scheduleId":"0.0.321", 398 "scheduledTransactionId":"0.0.123@1694689200.000000000","serialNumbers":[1,2,3],"status":"SUCCESS","tokenId":"0.0.987","topicId":"0.0.654", 399 "topicRunningHash":"0a","topicRunningHashVersion":0,"topicSequenceNumber":10,"totalSupply":0}],"contractId":"0.0.456", 400 "duplicates":[{"accountId":"0.0.123","children":[],"contractId":"0.0.456","duplicates":[],"exchangeRate":{"hbars":30000,"cents":154271, 401 "expirationTime":"2023-09-14T11:00:00.000Z"},"fileId":"0.0.789","nodeId":0,"scheduleId":"0.0.321","scheduledTransactionId":"0.0.123@1694689200.000000000", 402 "serialNumbers":[1,2,3],"status":"SUCCESS","tokenId":"0.0.987","topicId":"0.0.654","topicRunningHash":"0a","topicRunningHashVersion":0, 403 "topicSequenceNumber":10,"totalSupply":0}],"exchangeRate":{"hbars":30000,"cents":154271,"expirationTime":"2023-09-14T11:00:00.000Z"}, 404 "fileId":"0.0.789","nodeId":1,"scheduleId":"0.0.321","scheduledTransactionId":"0.0.123@1694689200.000000000","serialNumbers":[1,2,3],"status":"SUCCESS", 405 "tokenId":"0.0.987","topicId":"0.0.654","topicRunningHash":"0a","topicRunningHashVersion":0,"topicSequenceNumber":10,"totalSupply":0}` 406 407 assert.JSONEqf(t, expected, string(jsonBytes), "json should be equal") 408 409 } 410 411 func TestUnitTransactionResponseToJson(t *testing.T) { 412 t.Parallel() 413 414 responses := [][]interface{}{{ 415 &services.TransactionResponse{ 416 NodeTransactionPrecheckCode: services.ResponseCodeEnum_OK, 417 }, 418 &services.Response{ 419 Response: &services.Response_TransactionGetReceipt{ 420 TransactionGetReceipt: &services.TransactionGetReceiptResponse{ 421 Header: &services.ResponseHeader{ 422 Cost: 0, 423 ResponseType: services.ResponseType_ANSWER_ONLY, 424 }, 425 Receipt: &services.TransactionReceipt{ 426 Status: services.ResponseCodeEnum_SUCCESS, 427 }, 428 }, 429 }, 430 }, 431 }} 432 client, server := NewMockClientAndServer(responses) 433 defer server.Close() 434 tx, err := NewTransferTransaction(). 435 SetNodeAccountIDs([]AccountID{{Account: 3}}). 436 AddHbarTransfer(AccountID{Account: 2}, HbarFromTinybar(-1)). 437 AddHbarTransfer(AccountID{Account: 3}, HbarFromTinybar(1)). 438 Execute(client) 439 require.NoError(t, err) 440 jsonBytes, err := tx.MarshalJSON() 441 require.NoError(t, err) 442 obj := make(map[string]interface{}) 443 obj["nodeID"] = tx.NodeID.String() 444 obj["hash"] = hex.EncodeToString(tx.Hash) 445 obj["transactionID"] = tx.TransactionID.String() 446 expectedJSON, err := json.Marshal(obj) 447 require.NoError(t, err) 448 assert.Equal(t, expectedJSON, jsonBytes) 449 }