Skip to content
This repository has been archived by the owner on Dec 26, 2022. It is now read-only.

Commit

Permalink
feat(mam): Implement api_mam_send_message()
Browse files Browse the repository at this point in the history
Implement `api_mam_send_message()` and related test, function.

The function was implemented is `mam_send_bundle()` whose arg is bundle.
  • Loading branch information
howjmay committed Apr 2, 2019
1 parent e97eb27 commit 1765061
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 6 deletions.
91 changes: 90 additions & 1 deletion accelerator/apis.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ status_t api_get_tips_pair(const iota_config_t* const tangle,
goto done;
}

ret = cclient_get_txn_to_approve(service, tangle->depth, res);
ret = cclient_get_txn_to_approve(service, tangle->milestone_depth, res);
if (ret) {
goto done;
}
Expand Down Expand Up @@ -214,6 +214,95 @@ status_t api_receive_mam_message(const iota_client_service_t* const service,
return ret;
}

status_t api_mam_send_message(const iota_config_t* const tangle,
const iota_client_service_t* const service,
char const* const payload,
char** bundle_hash_result,
char** channel_id_result) {
status_t ret = SC_OK;
mam_api_t mam;
const bool last_packet = true;
bundle_transactions_t* bundle = NULL;
mam_psk_t_set_t psks = NULL;
bundle_transactions_new(&bundle);
tryte_t channel_id[MAM_CHANNEL_ID_SIZE];
trit_t msg_id[MAM_MSG_ID_SIZE];

size_t payload_size = strlen(payload) * 2;
if ((payload_size == 0) || ((payload_size * 3) > SIZE_MAX)) {
return SC_MAM_OOM;
}
tryte_t* payload_trytes = (tryte_t*)malloc(payload_size * sizeof(tryte_t));
if (!payload_trytes) {
return SC_MAM_OOM;
}
ascii_to_trytes(payload, payload_trytes);

*bundle_hash_result = (tryte_t*)malloc(sizeof(tryte_t) * NUM_TRYTES_ADDRESS);
if (!(*bundle_hash_result)) {
return SC_MAM_OOM;
}
*channel_id_result = (tryte_t*)malloc(sizeof(tryte_t) * NUM_TRYTES_ADDRESS);
if (!(*channel_id_result)) {
return SC_MAM_OOM;
}

// Creating MAM API
if (mam_api_init(&mam, (tryte_t*)SEED)) {
ret = SC_MAM_FAILED_INIT;
goto done;
}

// Create mam channel
if (mam_channel_t_set_size(mam.channels) == 0) {
mam_api_create_channel(&mam, tangle->mss_depth, channel_id);
} else {
mam_channel_t* channel = &mam.channels->value;
trits_to_trytes(trits_begin(mam_channel_id(channel)), channel_id,
NUM_TRITS_ADDRESS);
}

// Write header and packet
if (!mam_psk_t_set_contains(&psks, &psk)) {
if (mam_psk_t_set_add(&psks, &psk) != RC_OK) {
ret = SC_MAM_FAILED_WRITE;
goto done;
}
}
if (mam_api_bundle_write_header_on_channel(&mam, channel_id, psks, NULL, 0,
bundle, msg_id) != RC_OK) {
ret = SC_MAM_FAILED_WRITE;
goto done;
}
if (mam_api_bundle_write_packet(&mam, msg_id, payload_trytes, payload_size, 0,
last_packet, bundle) != RC_OK) {
ret = SC_MAM_FAILED_WRITE;
goto done;
}
memcpy(*channel_id_result, channel_id, sizeof(tryte_t) * NUM_TRYTES_ADDRESS);

// Sending bundle
if (ta_send_bundle(tangle, service, bundle) != SC_OK) {
ret = SC_MAM_FAILED_RESPONSE;
goto done;
}
memcpy(*bundle_hash_result,
((iota_transaction_t*)utarray_front(bundle))->essence.bundle,
sizeof(tryte_t) * NUM_TRYTES_ADDRESS);

done:
// Destroying MAM API
if (ret != SC_MAM_FAILED_INIT) {
if (mam_api_destroy(&mam) != RC_OK) {
ret = SC_MAM_FAILED_DESTROYED;
}
}
free(payload_trytes);
mam_psk_t_set_free(&psks);
bundle_transactions_free(&bundle);
return ret;
}

status_t api_send_transfer(const iota_config_t* const tangle,
const iota_client_service_t* const service,
const char* const obj, char** json_result) {
Expand Down
23 changes: 23 additions & 0 deletions accelerator/apis.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,29 @@ status_t api_receive_mam_message(const iota_client_service_t* const service,
const char* const bundle_hash,
char** json_result);

/**
* @brief Send a MAM message with given Payload.
*
* Send a MAM message from given Payload(ascii message).
* There is no need to decode the ascii payload to tryte, since the
* api_mam_send_message() will take this job.
*
* @param[in] tangle IOTA API parameter configurations
* @param[in] service IRI node end point service
* @param[in] payload message to send undecoded ascii string.
* @param[out] bundle_hashes_result the bundle hash of sent message
* @param[out] channel_id_result the channel id the sent message to
*
* @return
* - SC_OK on success
* - non-zero on error
*/
status_t api_mam_send_message(const iota_config_t* const tangle,
const iota_client_service_t* const service,
char const* const payload,
char** bundle_hash_result,
char** channel_id_result);

/**
* @brief Send transfer to tangle.
*
Expand Down
27 changes: 26 additions & 1 deletion accelerator/common_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ status_t ta_send_trytes(const iota_config_t* const tangle,
}

// get transaction to approve
ret = cclient_get_txn_to_approve(service, tangle->depth, get_txn_res);
ret =
cclient_get_txn_to_approve(service, tangle->milestone_depth, get_txn_res);
if (ret) {
goto done;
}
Expand Down Expand Up @@ -520,3 +521,27 @@ status_t ta_get_bundle(const iota_client_service_t* const service,
find_transactions_req_free(&find_tx_req);
return ret;
}

status_t ta_send_bundle(const iota_config_t* const tangle,
const iota_client_service_t* const service,
bundle_transactions_t* const bundle) {
Kerl kerl;
kerl_init(&kerl);
bundle_finalize(bundle, &kerl);
transaction_array_t* out_tx_objs = transaction_array_new();
hash8019_array_p raw_trytes = hash8019_array_new();
iota_transaction_t* curr_tx = NULL;
flex_trit_t trits_8019[FLEX_TRIT_SIZE_8019];

BUNDLE_FOREACH(bundle, curr_tx) {
transaction_serialize_on_flex_trits(curr_tx, trits_8019);
hash_array_push(raw_trytes, trits_8019);
}

ta_send_trytes(tangle, service, raw_trytes);

hash_array_free(raw_trytes);
transaction_array_free(out_tx_objs);

return SC_OK;
}
18 changes: 18 additions & 0 deletions accelerator/common_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,24 @@ status_t ta_get_bundle(const iota_client_service_t* const service,
tryte_t const* const bundle_hash,
bundle_transactions_t* const bundle);

/**
* @brief Send bundle object.
*
* Send the unpacked bundle which contains transactions. MAM functions should
* send message with this function.
*
* @param[in] service IRI node end point service
* @param[in] bundle bundle object to send
* @param[out] bundle Result containing bundle object in bundle_transactions_t
*
* @return
* - SC_OK on success
* - non-zero on error
*/
status_t ta_send_bundle(const iota_config_t* const tangle,
const iota_client_service_t* const service,
bundle_transactions_t* const bundle);

#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 2 additions & 1 deletion accelerator/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ status_t ta_config_init(ta_config_t* const info, iota_config_t* const tangle,
info->thread_count = TA_THREAD_COUNT;

log_info(logger_id, "Initializing IRI configuration\n");
tangle->depth = DEPTH;
tangle->milestone_depth = MILESTONE_DEPTH;
tangle->mss_depth = MSS_DEPTH;
tangle->mwm = MWM;
tangle->seed = SEED;

Expand Down
8 changes: 5 additions & 3 deletions accelerator/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ extern "C" {
#define TA_THREAD_COUNT 10
#define IRI_HOST "localhost"
#define IRI_PORT 14265
#define DEPTH 3
#define MILESTONE_DEPTH 3
#define MSS_DEPTH 4
#define MWM 14
#define SEED \
"AMRWQP9BUMJALJHBXUCHOD9HFFD9LGTGEAWMJWWXSDVOF9PI9YGJAPBQLQUOMNYEQCZPGCTHGV" \
Expand All @@ -45,8 +46,9 @@ typedef struct ta_info_s {

/** struct type of iota configuration */
typedef struct ta_config_s {
uint8_t depth; /**< Depth of API argument */
uint8_t mwm; /**< Minimum weight magnitude of API argument */
uint8_t milestone_depth; /**< Depth of API argument */
uint8_t mss_depth; /**< Depth of MSS layer merkle tree */
uint8_t mwm; /**< Minimum weight magnitude of API argument */
/** Seed to generate address. This does not do any signature yet. */
const char* seed;
} iota_config_t;
Expand Down
2 changes: 2 additions & 0 deletions accelerator/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ typedef enum {
/**< Error in mam destroy */
SC_MAM_NO_PAYLOAD = 0x07 | SC_MODULE_MAM | SC_SEVERITY_FATAL,
/**< No payload or no chid */
SC_MAM_FAILED_WRITE = 0x08 | SC_MODULE_MAM | SC_SEVERITY_FATAL,
/**< Failed to write */
} status_t;

typedef enum {
Expand Down
31 changes: 31 additions & 0 deletions tests/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,37 @@ void test_find_transactions_obj_by_tag(void) {
printf("Average time of find_tx_obj_by_tag: %lf\n", sum / TEST_COUNT);
}

void test_send_mam_message(void) {
double sum = 0;
status_t ret = SC_OK;

char* bundle_hash_result;
char* channel_id_result;

for (size_t count = 0; count < TEST_COUNT; count++) {
test_time_start(&start_time);
TEST_ASSERT_EQUAL_INT32(
SC_OK,
api_mam_send_message(&ta_core.tangle, &ta_core.service, TEST_PAYLOAD,
&bundle_hash_result, &channel_id_result));
test_time_end(&start_time, &end_time, &sum);

for (size_t i = 0; i < FLEX_TRIT_SIZE_243; i++) {
printf("%c", channel_id_result[i]);
}
printf("\n");
printf("Bundle: ");
for (size_t i = 0; i < FLEX_TRIT_SIZE_243; i++) {
printf("%c", bundle_hash_result[i]);
}
printf("\n");

free(bundle_hash_result);
free(channel_id_result);
}
printf("Average time of receive_mam_message: %lf\n", sum / TEST_COUNT);
}

void test_receive_mam_message(void) {
char* json_result;
double sum = 0;
Expand Down
21 changes: 21 additions & 0 deletions tests/test_define.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,27 @@ extern "C" {
"WYEVIWJN9DF9SBQHBUWYUECD9KD9BQHQXHOGQDTVKKYBRQUFQYGOFOTHREGVSKSSEVXMFOEHWN" \
"KHLHDKQ"

#define TEST_PAYLOAD \
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer aliquam " \
"velit ac placerat dignissim. Suspendisse interdum nisl velit, quis " \
"consequat lacus gravida vitae. Mauris in faucibus eros. Phasellus " \
"eleifend bibendum magna in iaculis. Nullam quis nibh posuere, efficitur " \
"metus nec, cursus justo. Cras in eros velit. Suspendisse tempus a ipsum " \
"et vehicula. Nulla sed ipsum porttitor, molestie enim ut, porttitor " \
"neque. Aenean rutrum nunc eros, vitae ullamcorper neque pretium ut. Etiam " \
"tempor libero sit amet fringilla eleifend. Maecenas varius nunc vel porta " \
"bibendum. Vestibulum ultricies sagittis elit eu rutrum. Duis id orci at " \
"eros vehicula suscipit a ac tortor. Morbi nulla nisi, laoreet vel leo " \
"vel, dignissim convallis sem. Nunc id lacus consectetur, iaculis metus " \
"ac, dictum erat. Curabitur eget erat eu eros hendrerit dapibus quis nec " \
"diam. Sed vulputate velit a mi ullamcorper, ut vestibulum felis " \
"tincidunt. Fusce et euismod elit. Phasellus augue turpis, efficitur a " \
"augue ac, rutrum vehicula nisl. Morbi ullamcorper, dui non ultrices " \
"consequat, odio felis aliquam dui, et mattis nibh purus vitae felis. " \
"Pellentesque rhoncus diam enim, in porttitor turpis dignissim in. " \
"Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere " \
"cubilia Curae;"

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 1765061

Please sign in to comment.