From 301befd2dfaeca645f6c9268c0e3ecafbd4b97c5 Mon Sep 17 00:00:00 2001 From: YangHau Date: Thu, 16 May 2019 21:15:03 +0800 Subject: [PATCH] feat(api): Impl api_send_trytes() Implement api_send_trytes() which can send raw transaction trytes array. Call it in the following JSON format {"trytes":["TRYTES_2673_1","TRYTES_2673_2"]} --- accelerator/BUILD | 3 ++ accelerator/apis.c | 28 +++++++++++ accelerator/apis.h | 21 ++++++++ accelerator/common_core.c | 50 ++++++++++--------- accelerator/errors.h | 4 ++ serializer/serializer.c | 102 ++++++++++++++++++++++++++++++++++++++ serializer/serializer.h | 27 ++++++++++ tests/driver.c | 18 +++++++ tests/test_common.cc | 35 +++++++++++++ tests/test_define.h | 40 +++++++++++++++ tests/test_serializer.c | 49 ++++++++++++++++++ 11 files changed, 354 insertions(+), 23 deletions(-) diff --git a/accelerator/BUILD b/accelerator/BUILD index b955c49d..5fb3ebd5 100644 --- a/accelerator/BUILD +++ b/accelerator/BUILD @@ -43,6 +43,9 @@ cc_library( "//request", "//response", "@com_github_uthash//:uthash", + "@entangled//cclient/api", + "@entangled//cclient/serialization:serializer", + "@entangled//cclient/serialization:serializer_json", "@entangled//common/model:bundle", "@entangled//utils:time", ], diff --git a/accelerator/apis.c b/accelerator/apis.c index 737a1c44..5d3ac51d 100644 --- a/accelerator/apis.c +++ b/accelerator/apis.c @@ -317,3 +317,31 @@ status_t api_send_transfer(const iota_config_t* const tangle, ta_get_transaction_object_res_free(&txn_obj_res); return ret; } + +status_t api_send_trytes(const iota_config_t* const tangle, + const iota_client_service_t* const service, + const char* const obj, char** json_result) { + status_t ret = SC_OK; + hash8019_array_p trytes = hash8019_array_new(); + + if (!trytes) { + ret = SC_TA_OOM; + goto done; + } + + ret = ta_send_trytes_req_deserialize(obj, trytes); + if (ret != SC_OK) { + goto done; + } + + ret = ta_send_trytes(tangle, service, trytes); + if (ret != SC_OK) { + goto done; + } + + ret = ta_send_trytes_res_serialize(trytes, json_result); + +done: + hash_array_free(trytes); + return ret; +} diff --git a/accelerator/apis.h b/accelerator/apis.h index 1585d215..d2de85fe 100644 --- a/accelerator/apis.h +++ b/accelerator/apis.h @@ -186,6 +186,27 @@ status_t api_find_transactions_obj_by_tag( const iota_client_service_t* const service, const char* const obj, char** json_result); +/** + * @brief Attach trytes to Tangle and return transaction hashes + * + * Persist trytes locally before sending to network. + * This allows for reattachments and prevents key reuse if trytes can't + * be recovered by querying the network after broadcasting. + * + * @param[in] tangle IOTA API parameter configurations + * @param[in] service IRI node end point service + * @param[in] obj trytes to attach, store and broadcast in json array + * @param[out] json_result Result containing list of attached transaction hashes + * in json format + * + * @return + * - SC_OK on success + * - non-zero on error + */ +status_t api_send_trytes(const iota_config_t* const tangle, + const iota_client_service_t* const service, + const char* const obj, char** json_result); + #ifdef __cplusplus } #endif diff --git a/accelerator/common_core.c b/accelerator/common_core.c index 2f2184a7..b24a80de 100644 --- a/accelerator/common_core.c +++ b/accelerator/common_core.c @@ -160,47 +160,51 @@ status_t ta_send_trytes(const iota_config_t* const tangle, const iota_client_service_t* const service, hash8019_array_p trytes) { status_t ret = SC_OK; - ta_get_tips_res_t* get_txn_res = ta_get_tips_res_new(); + get_transactions_to_approve_req_t* tx_approve_req = + get_transactions_to_approve_req_new(); + get_transactions_to_approve_res_t* tx_approve_res = + get_transactions_to_approve_res_new(); attach_to_tangle_req_t* attach_req = attach_to_tangle_req_new(); attach_to_tangle_res_t* attach_res = attach_to_tangle_res_new(); - if (!get_txn_res || !attach_req || !attach_res) { + if (!tx_approve_req || !tx_approve_res || !attach_req || !attach_res) { ret = SC_CCLIENT_OOM; goto done; } - // get transaction to approve - ret = - cclient_get_txn_to_approve(service, tangle->milestone_depth, get_txn_res); - if (ret) { + get_transactions_to_approve_req_set_depth(tx_approve_req, + tangle->milestone_depth); + if (iota_client_get_transactions_to_approve(service, tx_approve_req, + tx_approve_res)) { + ret = SC_CCLIENT_FAILED_RESPONSE; goto done; } - // attach to tangle - memcpy(attach_req->trunk, hash243_stack_peek(get_txn_res->tips), - FLEX_TRIT_SIZE_243); - hash243_stack_pop(&get_txn_res->tips); - memcpy(attach_req->branch, hash243_stack_peek(get_txn_res->tips), - FLEX_TRIT_SIZE_243); - hash243_stack_pop(&get_txn_res->tips); - attach_req->mwm = tangle->mwm; - + // copy trytes to attach_req->trytes flex_trit_t* elt = NULL; - HASH_ARRAY_FOREACH(trytes, elt) { hash_array_push(attach_req->trytes, elt); } - - ret = ta_attach_to_tangle(attach_req, attach_res); - if (ret) { + HASH_ARRAY_FOREACH(trytes, elt) { + attach_to_tangle_req_trytes_add(attach_req, elt); + } + attach_to_tangle_req_init( + attach_req, get_transactions_to_approve_res_trunk(tx_approve_res), + get_transactions_to_approve_res_branch(tx_approve_res), tangle->mwm); + if (ta_attach_to_tangle(attach_req, attach_res) != SC_OK) { goto done; } // store and broadcast - ret = iota_client_store_and_broadcast(service, - (store_transactions_req_t*)attach_res); - if (ret) { + if (iota_client_store_and_broadcast( + service, (store_transactions_req_t*)attach_res) != RC_OK) { ret = SC_CCLIENT_FAILED_RESPONSE; + goto done; } + // set the value of attach_res->trytes as output trytes result + memcpy(trytes, attach_res->trytes, + hash_array_len(attach_res->trytes) * sizeof(hash8019_array_p)); + done: - ta_get_tips_res_free(&get_txn_res); + get_transactions_to_approve_req_free(&tx_approve_req); + get_transactions_to_approve_res_free(&tx_approve_res); attach_to_tangle_req_free(&attach_req); attach_to_tangle_res_free(&attach_res); return ret; diff --git a/accelerator/errors.h b/accelerator/errors.h index 0f002d93..07e5c0da 100644 --- a/accelerator/errors.h +++ b/accelerator/errors.h @@ -79,6 +79,10 @@ typedef enum { /**< JSON key not found */ SC_CCLIENT_JSON_PARSE = 0x07 | SC_MODULE_CCLIENT | SC_SEVERITY_MAJOR, /**< json parsing error, might the wrong format */ + SC_CCLIENT_FLEX_TRITS = 0x09 | SC_MODULE_CCLIENT | SC_SEVERITY_MAJOR, + /**< Flex trits converting error */ + SC_CCLIENT_JSON_CREATE = 0x0A | SC_MODULE_CCLIENT | SC_SEVERITY_MAJOR, + /**< json create object error, might OOM. */ // Serializer module SC_SERIALIZER_JSON_CREATE = 0x01 | SC_MODULE_SERIALIZER | SC_SEVERITY_FATAL, diff --git a/serializer/serializer.c b/serializer/serializer.c index 338d5b9c..e129047b 100644 --- a/serializer/serializer.c +++ b/serializer/serializer.c @@ -75,6 +75,61 @@ static status_t ta_hash243_queue_to_json_array(hash243_queue_t queue, return SC_OK; } +static status_t ta_json_array_to_hash8019_array(cJSON const* const obj, + char const* const obj_name, + hash8019_array_p array) { + status_t ret = SC_OK; + flex_trit_t hash[FLEX_TRIT_SIZE_8019] = {}; + cJSON* json_item = cJSON_GetObjectItemCaseSensitive(obj, obj_name); + if (!cJSON_IsArray(json_item)) { + return SC_CCLIENT_JSON_PARSE; + } + + cJSON* current_obj = NULL; + cJSON_ArrayForEach(current_obj, json_item) { + if (current_obj->valuestring != NULL) { + flex_trits_from_trytes(hash, NUM_TRITS_SERIALIZED_TRANSACTION, + (tryte_t const*)current_obj->valuestring, + NUM_TRYTES_SERIALIZED_TRANSACTION, + NUM_TRYTES_SERIALIZED_TRANSACTION); + hash_array_push(array, hash); + } + } + return ret; +} + +status_t ta_hash8019_array_to_json_array(hash8019_array_p array, + cJSON* const json_root, + char const* const obj_name) { + size_t array_count = 0; + cJSON* array_obj = NULL; + tryte_t trytes_out[NUM_TRYTES_SERIALIZED_TRANSACTION + 1] = {}; + size_t trits_count = 0; + flex_trit_t* elt = NULL; + + array_count = hash_array_len(array); + if (array_count > 0) { + array_obj = cJSON_CreateArray(); + if (array_obj == NULL) { + return SC_SERIALIZER_JSON_CREATE; + } + cJSON_AddItemToObject(json_root, obj_name, array_obj); + + HASH_ARRAY_FOREACH(array, elt) { + trits_count = flex_trits_to_trytes( + trytes_out, NUM_TRYTES_SERIALIZED_TRANSACTION, elt, + NUM_TRITS_SERIALIZED_TRANSACTION, NUM_TRITS_SERIALIZED_TRANSACTION); + trytes_out[NUM_TRYTES_SERIALIZED_TRANSACTION] = '\0'; + if (trits_count == 0) { + return SC_CCLIENT_FLEX_TRITS; + } + cJSON_AddItemToArray(array_obj, + cJSON_CreateString((char const*)trytes_out)); + } + } + return SC_OK; +} + static status_t ta_json_get_string(cJSON const* const json_obj, char const* const obj_name, char* const text) { @@ -344,6 +399,53 @@ status_t ta_send_transfer_req_deserialize(const char* const obj, return ret; } +status_t ta_send_trytes_req_deserialize(const char* const obj, + hash8019_array_p out_trytes) { + if (obj == NULL || out_trytes == NULL) { + return SC_SERIALIZER_NULL; + } + status_t ret = SC_OK; + cJSON* json_obj = cJSON_Parse(obj); + + if (json_obj == NULL) { + ret = SC_SERIALIZER_JSON_PARSE; + goto done; + } + + ret = ta_json_array_to_hash8019_array(json_obj, "trytes", out_trytes); + if (ret != SC_OK) { + goto done; + } + +done: + cJSON_Delete(json_obj); + return ret; +} + +status_t ta_send_trytes_res_serialize(const hash8019_array_p trytes, + char** obj) { + if (trytes == NULL) { + return SC_SERIALIZER_NULL; + } + + status_t ret = SC_OK; + cJSON* json_root = cJSON_CreateObject(); + + ret = ta_hash8019_array_to_json_array(trytes, json_root, "trytes"); + if (ret != SC_OK) { + goto done; + } + + *obj = cJSON_PrintUnformatted(json_root); + if (*obj == NULL) { + ret = SC_SERIALIZER_JSON_PARSE; + } + +done: + cJSON_Delete(json_root); + return ret; +} + status_t ta_get_transaction_object_res_serialize( char** obj, const ta_get_transaction_object_res_t* const res) { status_t ret = SC_OK; diff --git a/serializer/serializer.h b/serializer/serializer.h index cdcbbc74..d0cf54d7 100644 --- a/serializer/serializer.h +++ b/serializer/serializer.h @@ -73,6 +73,33 @@ status_t ta_get_tips_res_serialize(char** obj, status_t ta_send_transfer_req_deserialize(const char* const obj, ta_send_transfer_req_t* req); +/** + * @brief Deserialze JSON string to hash8019_array_p + * + * @param[in] obj Input values in JSON + * @param[out] out_trytes trytes arrary in the request data in type of + * hash8019_array_p + * + * @return + * - SC_OK on success + * - non-zero on error + */ +status_t ta_send_trytes_req_deserialize(const char* const obj, + hash8019_array_p out_trytes); + +/** + * @brief Serialze hash8019_array_p to JSON string + * + * @param[in] trytes trytes array returned in type of hash8019_array_p + * @param[out] obj output serialized JSON values + * + * @return + * - SC_OK on success + * - non-zero on error + */ +status_t ta_send_trytes_res_serialize(const hash8019_array_p trytes, + char** obj); + /** * @brief Serialze type of ta_get_transaction_object_res_t to JSON string * diff --git a/tests/driver.c b/tests/driver.c index bd2cd0c5..668af778 100644 --- a/tests/driver.c +++ b/tests/driver.c @@ -116,6 +116,23 @@ void test_send_transfer(void) { printf("Average time of send_transfer: %lf\n", sum / TEST_COUNT); } +void test_send_trytes(void) { + const char* json = + "{\"trytes\":[\"" TRYTES_2673_1 "\",\"" TRYTES_2673_2 "\"]}"; + char* json_result; + double sum = 0; + + for (size_t count = 0; count < TEST_COUNT; count++) { + test_time_start(&start_time); + TEST_ASSERT_EQUAL_INT32( + SC_OK, + api_send_trytes(&ta_core.tangle, &ta_core.service, json, &json_result)); + test_time_end(&start_time, &end_time, &sum); + free(json_result); + } + printf("Average time of send_trytes: %lf\n", sum / TEST_COUNT); +} + void test_get_transaction_object(void) { char* json_result; double sum = 0; @@ -212,6 +229,7 @@ int main(void) { RUN_TEST(test_get_tips_pair); RUN_TEST(test_get_tips); RUN_TEST(test_send_transfer); + RUN_TEST(test_send_trytes); RUN_TEST(test_get_transaction_object); RUN_TEST(test_find_transactions_by_tag); RUN_TEST(test_find_transactions_obj_by_tag); diff --git a/tests/test_common.cc b/tests/test_common.cc index b5e44f3c..557b0eaf 100644 --- a/tests/test_common.cc +++ b/tests/test_common.cc @@ -193,6 +193,41 @@ TEST(GetBundleTest, RetreiveBundleTest) { bundle_transactions_free(&bundle); } +TEST(SendTrytesTest, SendTrytesTest) { + size_t trits_count; + hash8019_array_p trytes = hash8019_array_new(); + flex_trit_t tx_trits[FLEX_TRIT_SIZE_8019]; + tryte_t trytes_out[NUM_TRYTES_SERIALIZED_TRANSACTION + 1] = {}; + + flex_trits_from_trytes( + tx_trits, NUM_TRITS_SERIALIZED_TRANSACTION, (const tryte_t*)TRYTES_2673_1, + NUM_TRYTES_SERIALIZED_TRANSACTION, NUM_TRYTES_SERIALIZED_TRANSACTION); + hash_array_push(trytes, tx_trits); + + flex_trits_from_trytes( + tx_trits, NUM_TRITS_SERIALIZED_TRANSACTION, (const tryte_t*)TRYTES_2673_2, + NUM_TRYTES_SERIALIZED_TRANSACTION, NUM_TRYTES_SERIALIZED_TRANSACTION); + hash_array_push(trytes, tx_trits); + + EXPECT_EQ(ta_send_trytes(&tangle, &service, trytes), SC_OK); + + trits_count = flex_trits_to_trytes( + trytes_out, NUM_TRYTES_SERIALIZED_TRANSACTION, hash_array_at(trytes, 0), + NUM_TRITS_SERIALIZED_TRANSACTION, NUM_TRITS_SERIALIZED_TRANSACTION); + trytes_out[NUM_TRYTES_SERIALIZED_TRANSACTION] = '\0'; + EXPECT_EQ(NUM_TRITS_SERIALIZED_TRANSACTION, trits_count); + EXPECT_STREQ(TRYTES_2673_1, (char*)trytes_out); + + trits_count = flex_trits_to_trytes( + trytes_out, NUM_TRYTES_SERIALIZED_TRANSACTION, hash_array_at(trytes, 1), + NUM_TRITS_SERIALIZED_TRANSACTION, NUM_TRITS_SERIALIZED_TRANSACTION); + trytes_out[NUM_TRYTES_SERIALIZED_TRANSACTION] = '\0'; + EXPECT_EQ(NUM_TRITS_SERIALIZED_TRANSACTION, trits_count); + EXPECT_STREQ(TRYTES_2673_2, (char*)trytes_out); + + hash_array_free(trytes); +} + int main(int argc, char** argv) { // GTest manage to cleanup after testing, so only need to initialize here cache_init(REDIS_HOST, REDIS_PORT); diff --git a/tests/test_define.h b/tests/test_define.h index ee12df5c..f095790d 100644 --- a/tests/test_define.h +++ b/tests/test_define.h @@ -73,6 +73,46 @@ extern "C" { "PYTHONTEST99999999999999999999999999999999999999999999NC99999999XRVYE999" \ "999999999" +#define TRYTES_2673_2 \ + "BYSWEAUTWXHXZ9YBZISEK9LUHWGMHXCGEVNZHRLUWQFCUSDXZHOFHWHL9MQPVJXXZLIXPX" \ + "PXF9KYEREFSKCPKYIIKPZVLHUTDFQKKVVBBN9ATTLPCNPJDWDEVIYYLGPZGCWXOBDXMLJC9V" \ + "O9QXTTBLAXTTBFUAROYEGQIVB9MJWJKXJMCUPTWAUGFZBTZCSJVRBGMYXTVBDDS9MYUJCPZ9" \ + "YDWWQNIPUAIJXXSNLKUBSCOIJPCLEFPOXFJREXQCUVUMKSDOVQGGHRNILCO9GNCLWFM9APMN" \ + "MWYASHXQAYBEXF9QRIHIBHYEJOYHRQJAOKAQ9AJJFQ9WEIWIJOTZATIBOXQLBMIJU9PCGBLV" \ + "DDVFP9CFFSXTDUXMEGOOFXWRTLFGV9XXMYWEMGQEEEDBTIJ9OJOXFAPFQXCDAXOUDMLVYRMR" \ + "LUDBETOLRJQAEDDLNVIRQJUBZBO9CCFDHIX9MSQCWYAXJVWHCUPTRSXJDESISQPRKZAFKFRU" \ + "LCGVRSBLVFOPEYLEE99JD9SEBALQINPDAZHFAB9RNBH9AZWIJOTLBZVIEJIAYGMC9AZGNFWG" \ + "RSWAXTYSXVROVNKCOQQIWGPNQZKHUNODGYADPYLZZZUQRTJRTODOUKAOITNOMWNGHJBBA99Q" \ + "UMBHRENGBHTH9KHUAOXBVIVDVYYZMSEYSJWIOGGXZVRGN999EEGQMCOYVJQRIRROMPCQBLDY" \ + "IGQO9AMORPYFSSUGACOJXGAQSPDY9YWRRPESNXXBDQ9OZOXVIOMLGTSWAMKMTDRSPGJKGBXQ" \ + "IVNRJRFRYEZ9VJDLHIKPSKMYC9YEGHFDS9SGVDHRIXBEMLFIINOHVPXIFAZCJKBHVMQZEVWC" \ + "OSNWQRDYWVAIBLSCBGESJUIBWZECPUCAYAWMTQKRMCHONIPKJYYTEGZCJYCT9ABRWTJLRQXK" \ + "MWY9GWZMHYZNWPXULNZAPVQLPMYQZCYNEPOCGOHBJUZLZDPIXVHLDMQYJUUBEDXXPXFLNRGI" \ + "PWBRNQQZJSGSJTTYHIGGFAWJVXWL9THTPWOOHTNQWCNYOYZXALHAZXVMIZE9WMQUDCHDJMIB" \ + "WKTYH9AC9AFOT9DPCADCV9ZWUTE9QNOMSZPTZDJLJZCJGHXUNBJFUBJWQUEZDMHXGBPTNSPZ" \ + "BR9TGSKVOHMOQSWPGFLSWNESFKSAZY9HHERAXALZCABFYPOVLAHMIHVDBGKUMDXC9WHHTIRY" \ + "HZVWNXSVQUWCR9M9RAGMFEZZKZ9XEOQGOSLFQCHHOKLDSA9QCMDGCGMRYJZLBVIFOLBIJPRO" \ + "KMHOYTBTJIWUZWJMCTKCJKKTR9LCVYPVJI9AHGI9JOWMIWZAGMLDFJA9WU9QAMEFGABIBEZN" \ + "NAL9OXSBFLOEHKDGHWFQSHMPLYFCNXAAZYJLMQDEYRGL9QKCEUEJ9LLVUOINVSZZQHCIKPAG" \ + "MT9CAYIIMTTBCPKWTYHOJIIY9GYNPAJNUJ9BKYYXSV9JSPEXYMCFAIKTGNRSQGUNIYZCRT9F" \ + "OWENSZQPD9ALUPYYAVICHVYELYFPUYDTWUSWNIYFXPX9MICCCOOZIWRNJIDALWGWRATGLJXN" \ + "AYTNIZWQ9YTVDBOFZRKO9CFWRPAQQRXTPACOWCPRLYRYSJARRKSQPR9TCFXDVIXLP9XVL99E" \ + "RRDSOHBFJDJQQGGGCZNDQ9NYCTQJWVZIAELCRBJJFDMCNZU9FIZRPGNURTXOCDSQGXTQHKHU" \ + "ECGWFUUYS9J9NYQ9U9P9UUP9YMZHWWWCIASCFLCMSKTELZWUGCDE9YOKVOVKTAYPHDF9ZCCQ" \ + "AYPJIJNGSHUIHHCOSSOOBUDOKE9CJZGYSSGNCQJVBEFTZFJ9SQUHOASKRRGBSHWKBCBWBTJH" \ + "OGQ9WOMQFHWJVEG9NYX9KWBTCAIXNXHEBDIOFO9ALYMFGRICLCKKLG9FOBOX9PDWNQRGHBKH" \ + "GKKRLWTBEQMCWQRLHAVYYZDIIPKVQTHYTWQMTOACXZOQCDTJTBAAUWXSGJF9PNQIJ9AJRUMU" \ + "VCPWYVYVARKR9RKGOUHHNKNVGGPDDLGKPQNOYHNKAVVKCXWXOQPZNSLATUJT9AUWRMPPSWHS" \ + "TTYDFAQDXOCYTZHOYYGAIM9CELMZ9AZPWB9MJXGHOKDNNSZVUDAGXTJJSSZCPZVPZBYNNTUQ" \ + "ABSXQWZCHDQSLGK9UOHCFKBIBNETK9999999999999999999999999999999999999999999" \ + "99999999999999999999999999999999999999NOXDXXKUDWLOFJLIPQIBRBMGDYCPGDNLQO" \ + "LQS99EQYKBIU9VHCJVIPFUYCQDNY9APGEVYLCENJIOBLWNB999999999XKBRHUD99C999999" \ + "99NKZKEKWLDKMJCI9N9XQOLWEPAYWSH9999999999999999999999999KDDTGZLIPBNZKMLT" \ + "OLOXQVNGLASESDQVPTXALEKRMIOHQLUHD9ELQDBQETS9QFGTYOYWLNTSKKMVJAUXSIROUICD" \ + "OXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X99" \ + "99IROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXX" \ + "VXFWP9X9999" + #define TRYTES_2187_1 \ "XCRBOBVBVBYB999999999999999999999999999999999999999999999999999999999999" \ "999999999999999999999999999999999999999999999999999999999999999999999999" \ diff --git a/tests/test_serializer.c b/tests/test_serializer.c index 836d8e0f..e3ca190d 100644 --- a/tests/test_serializer.c +++ b/tests/test_serializer.c @@ -301,6 +301,53 @@ void test_deserialize_send_mam_message(void) { send_mam_req_free(&req); } +void test_deserialize_ta_send_trytes_req(void) { + const char* json = + "{\"trytes\":[\"" TRYTES_2673_1 "\",\"" TRYTES_2673_2 "\"]}"; + hash8019_array_p out_trytes = hash8019_array_new(); + ta_send_trytes_req_deserialize(json, out_trytes); + + flex_trit_t hash[FLEX_TRIT_SIZE_8019] = {}; + flex_trits_from_trytes( + hash, NUM_TRITS_SERIALIZED_TRANSACTION, (const tryte_t*)TRYTES_2673_1, + NUM_TRYTES_SERIALIZED_TRANSACTION, NUM_TRYTES_SERIALIZED_TRANSACTION); + TEST_ASSERT_EQUAL_MEMORY(hash, hash_array_at(out_trytes, 0), + NUM_TRYTES_SERIALIZED_TRANSACTION); + + flex_trits_from_trytes( + hash, NUM_TRITS_SERIALIZED_TRANSACTION, (const tryte_t*)TRYTES_2673_2, + NUM_TRYTES_SERIALIZED_TRANSACTION, NUM_TRYTES_SERIALIZED_TRANSACTION); + TEST_ASSERT_EQUAL_MEMORY(hash, hash_array_at(out_trytes, 1), + NUM_TRYTES_SERIALIZED_TRANSACTION); + + hash_array_free(out_trytes); +} + +void test_serialize_ta_send_trytes_res(void) { + const char* json = + "{\"trytes\":[\"" TRYTES_2673_1 "\",\"" TRYTES_2673_2 "\"]}"; + char* json_result; + hash8019_array_p trytes = hash8019_array_new(); + + flex_trit_t hash[FLEX_TRIT_SIZE_8019] = {}; + flex_trits_from_trytes( + hash, NUM_TRITS_SERIALIZED_TRANSACTION, (const tryte_t*)TRYTES_2673_1, + NUM_TRYTES_SERIALIZED_TRANSACTION, NUM_TRYTES_SERIALIZED_TRANSACTION); + hash_array_push(trytes, hash); + + flex_trits_from_trytes( + hash, NUM_TRITS_SERIALIZED_TRANSACTION, (const tryte_t*)TRYTES_2673_2, + NUM_TRYTES_SERIALIZED_TRANSACTION, NUM_TRYTES_SERIALIZED_TRANSACTION); + hash_array_push(trytes, hash); + + ta_send_trytes_res_serialize(trytes, &json_result); + + TEST_ASSERT_EQUAL_STRING(json, json_result); + + hash_array_free(trytes); + free(json_result); +} + int main(void) { UNITY_BEGIN(); @@ -313,5 +360,7 @@ int main(void) { RUN_TEST(test_serialize_send_mam_message); RUN_TEST(test_deserialize_send_mam_message_response); RUN_TEST(test_deserialize_send_mam_message); + RUN_TEST(test_deserialize_ta_send_trytes_req); + RUN_TEST(test_serialize_ta_send_trytes_res); return UNITY_END(); }