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  }