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

Commit 1765061

Browse files
committed
feat(mam): Implement api_mam_send_message()
Implement `api_mam_send_message()` and related test, function. The function was implemented is `mam_send_bundle()` whose arg is bundle.
1 parent e97eb27 commit 1765061

File tree

9 files changed

+218
-6
lines changed

9 files changed

+218
-6
lines changed

accelerator/apis.c

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ status_t api_get_tips_pair(const iota_config_t* const tangle,
5454
goto done;
5555
}
5656

57-
ret = cclient_get_txn_to_approve(service, tangle->depth, res);
57+
ret = cclient_get_txn_to_approve(service, tangle->milestone_depth, res);
5858
if (ret) {
5959
goto done;
6060
}
@@ -214,6 +214,95 @@ status_t api_receive_mam_message(const iota_client_service_t* const service,
214214
return ret;
215215
}
216216

217+
status_t api_mam_send_message(const iota_config_t* const tangle,
218+
const iota_client_service_t* const service,
219+
char const* const payload,
220+
char** bundle_hash_result,
221+
char** channel_id_result) {
222+
status_t ret = SC_OK;
223+
mam_api_t mam;
224+
const bool last_packet = true;
225+
bundle_transactions_t* bundle = NULL;
226+
mam_psk_t_set_t psks = NULL;
227+
bundle_transactions_new(&bundle);
228+
tryte_t channel_id[MAM_CHANNEL_ID_SIZE];
229+
trit_t msg_id[MAM_MSG_ID_SIZE];
230+
231+
size_t payload_size = strlen(payload) * 2;
232+
if ((payload_size == 0) || ((payload_size * 3) > SIZE_MAX)) {
233+
return SC_MAM_OOM;
234+
}
235+
tryte_t* payload_trytes = (tryte_t*)malloc(payload_size * sizeof(tryte_t));
236+
if (!payload_trytes) {
237+
return SC_MAM_OOM;
238+
}
239+
ascii_to_trytes(payload, payload_trytes);
240+
241+
*bundle_hash_result = (tryte_t*)malloc(sizeof(tryte_t) * NUM_TRYTES_ADDRESS);
242+
if (!(*bundle_hash_result)) {
243+
return SC_MAM_OOM;
244+
}
245+
*channel_id_result = (tryte_t*)malloc(sizeof(tryte_t) * NUM_TRYTES_ADDRESS);
246+
if (!(*channel_id_result)) {
247+
return SC_MAM_OOM;
248+
}
249+
250+
// Creating MAM API
251+
if (mam_api_init(&mam, (tryte_t*)SEED)) {
252+
ret = SC_MAM_FAILED_INIT;
253+
goto done;
254+
}
255+
256+
// Create mam channel
257+
if (mam_channel_t_set_size(mam.channels) == 0) {
258+
mam_api_create_channel(&mam, tangle->mss_depth, channel_id);
259+
} else {
260+
mam_channel_t* channel = &mam.channels->value;
261+
trits_to_trytes(trits_begin(mam_channel_id(channel)), channel_id,
262+
NUM_TRITS_ADDRESS);
263+
}
264+
265+
// Write header and packet
266+
if (!mam_psk_t_set_contains(&psks, &psk)) {
267+
if (mam_psk_t_set_add(&psks, &psk) != RC_OK) {
268+
ret = SC_MAM_FAILED_WRITE;
269+
goto done;
270+
}
271+
}
272+
if (mam_api_bundle_write_header_on_channel(&mam, channel_id, psks, NULL, 0,
273+
bundle, msg_id) != RC_OK) {
274+
ret = SC_MAM_FAILED_WRITE;
275+
goto done;
276+
}
277+
if (mam_api_bundle_write_packet(&mam, msg_id, payload_trytes, payload_size, 0,
278+
last_packet, bundle) != RC_OK) {
279+
ret = SC_MAM_FAILED_WRITE;
280+
goto done;
281+
}
282+
memcpy(*channel_id_result, channel_id, sizeof(tryte_t) * NUM_TRYTES_ADDRESS);
283+
284+
// Sending bundle
285+
if (ta_send_bundle(tangle, service, bundle) != SC_OK) {
286+
ret = SC_MAM_FAILED_RESPONSE;
287+
goto done;
288+
}
289+
memcpy(*bundle_hash_result,
290+
((iota_transaction_t*)utarray_front(bundle))->essence.bundle,
291+
sizeof(tryte_t) * NUM_TRYTES_ADDRESS);
292+
293+
done:
294+
// Destroying MAM API
295+
if (ret != SC_MAM_FAILED_INIT) {
296+
if (mam_api_destroy(&mam) != RC_OK) {
297+
ret = SC_MAM_FAILED_DESTROYED;
298+
}
299+
}
300+
free(payload_trytes);
301+
mam_psk_t_set_free(&psks);
302+
bundle_transactions_free(&bundle);
303+
return ret;
304+
}
305+
217306
status_t api_send_transfer(const iota_config_t* const tangle,
218307
const iota_client_service_t* const service,
219308
const char* const obj, char** json_result) {

accelerator/apis.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,29 @@ status_t api_receive_mam_message(const iota_client_service_t* const service,
9292
const char* const bundle_hash,
9393
char** json_result);
9494

95+
/**
96+
* @brief Send a MAM message with given Payload.
97+
*
98+
* Send a MAM message from given Payload(ascii message).
99+
* There is no need to decode the ascii payload to tryte, since the
100+
* api_mam_send_message() will take this job.
101+
*
102+
* @param[in] tangle IOTA API parameter configurations
103+
* @param[in] service IRI node end point service
104+
* @param[in] payload message to send undecoded ascii string.
105+
* @param[out] bundle_hashes_result the bundle hash of sent message
106+
* @param[out] channel_id_result the channel id the sent message to
107+
*
108+
* @return
109+
* - SC_OK on success
110+
* - non-zero on error
111+
*/
112+
status_t api_mam_send_message(const iota_config_t* const tangle,
113+
const iota_client_service_t* const service,
114+
char const* const payload,
115+
char** bundle_hash_result,
116+
char** channel_id_result);
117+
95118
/**
96119
* @brief Send transfer to tangle.
97120
*

accelerator/common_core.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ status_t ta_send_trytes(const iota_config_t* const tangle,
169169
}
170170

171171
// get transaction to approve
172-
ret = cclient_get_txn_to_approve(service, tangle->depth, get_txn_res);
172+
ret =
173+
cclient_get_txn_to_approve(service, tangle->milestone_depth, get_txn_res);
173174
if (ret) {
174175
goto done;
175176
}
@@ -520,3 +521,27 @@ status_t ta_get_bundle(const iota_client_service_t* const service,
520521
find_transactions_req_free(&find_tx_req);
521522
return ret;
522523
}
524+
525+
status_t ta_send_bundle(const iota_config_t* const tangle,
526+
const iota_client_service_t* const service,
527+
bundle_transactions_t* const bundle) {
528+
Kerl kerl;
529+
kerl_init(&kerl);
530+
bundle_finalize(bundle, &kerl);
531+
transaction_array_t* out_tx_objs = transaction_array_new();
532+
hash8019_array_p raw_trytes = hash8019_array_new();
533+
iota_transaction_t* curr_tx = NULL;
534+
flex_trit_t trits_8019[FLEX_TRIT_SIZE_8019];
535+
536+
BUNDLE_FOREACH(bundle, curr_tx) {
537+
transaction_serialize_on_flex_trits(curr_tx, trits_8019);
538+
hash_array_push(raw_trytes, trits_8019);
539+
}
540+
541+
ta_send_trytes(tangle, service, raw_trytes);
542+
543+
hash_array_free(raw_trytes);
544+
transaction_array_free(out_tx_objs);
545+
546+
return SC_OK;
547+
}

accelerator/common_core.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,24 @@ status_t ta_get_bundle(const iota_client_service_t* const service,
195195
tryte_t const* const bundle_hash,
196196
bundle_transactions_t* const bundle);
197197

198+
/**
199+
* @brief Send bundle object.
200+
*
201+
* Send the unpacked bundle which contains transactions. MAM functions should
202+
* send message with this function.
203+
*
204+
* @param[in] service IRI node end point service
205+
* @param[in] bundle bundle object to send
206+
* @param[out] bundle Result containing bundle object in bundle_transactions_t
207+
*
208+
* @return
209+
* - SC_OK on success
210+
* - non-zero on error
211+
*/
212+
status_t ta_send_bundle(const iota_config_t* const tangle,
213+
const iota_client_service_t* const service,
214+
bundle_transactions_t* const bundle);
215+
198216
#ifdef __cplusplus
199217
}
200218
#endif

accelerator/config.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ status_t ta_config_init(ta_config_t* const info, iota_config_t* const tangle,
2323
info->thread_count = TA_THREAD_COUNT;
2424

2525
log_info(logger_id, "Initializing IRI configuration\n");
26-
tangle->depth = DEPTH;
26+
tangle->milestone_depth = MILESTONE_DEPTH;
27+
tangle->mss_depth = MSS_DEPTH;
2728
tangle->mwm = MWM;
2829
tangle->seed = SEED;
2930

accelerator/config.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ extern "C" {
2323
#define TA_THREAD_COUNT 10
2424
#define IRI_HOST "localhost"
2525
#define IRI_PORT 14265
26-
#define DEPTH 3
26+
#define MILESTONE_DEPTH 3
27+
#define MSS_DEPTH 4
2728
#define MWM 14
2829
#define SEED \
2930
"AMRWQP9BUMJALJHBXUCHOD9HFFD9LGTGEAWMJWWXSDVOF9PI9YGJAPBQLQUOMNYEQCZPGCTHGV" \
@@ -45,8 +46,9 @@ typedef struct ta_info_s {
4546

4647
/** struct type of iota configuration */
4748
typedef struct ta_config_s {
48-
uint8_t depth; /**< Depth of API argument */
49-
uint8_t mwm; /**< Minimum weight magnitude of API argument */
49+
uint8_t milestone_depth; /**< Depth of API argument */
50+
uint8_t mss_depth; /**< Depth of MSS layer merkle tree */
51+
uint8_t mwm; /**< Minimum weight magnitude of API argument */
5052
/** Seed to generate address. This does not do any signature yet. */
5153
const char* seed;
5254
} iota_config_t;

accelerator/errors.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ typedef enum {
103103
/**< Error in mam destroy */
104104
SC_MAM_NO_PAYLOAD = 0x07 | SC_MODULE_MAM | SC_SEVERITY_FATAL,
105105
/**< No payload or no chid */
106+
SC_MAM_FAILED_WRITE = 0x08 | SC_MODULE_MAM | SC_SEVERITY_FATAL,
107+
/**< Failed to write */
106108
} status_t;
107109

108110
typedef enum {

tests/driver.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,37 @@ void test_find_transactions_obj_by_tag(void) {
138138
printf("Average time of find_tx_obj_by_tag: %lf\n", sum / TEST_COUNT);
139139
}
140140

141+
void test_send_mam_message(void) {
142+
double sum = 0;
143+
status_t ret = SC_OK;
144+
145+
char* bundle_hash_result;
146+
char* channel_id_result;
147+
148+
for (size_t count = 0; count < TEST_COUNT; count++) {
149+
test_time_start(&start_time);
150+
TEST_ASSERT_EQUAL_INT32(
151+
SC_OK,
152+
api_mam_send_message(&ta_core.tangle, &ta_core.service, TEST_PAYLOAD,
153+
&bundle_hash_result, &channel_id_result));
154+
test_time_end(&start_time, &end_time, &sum);
155+
156+
for (size_t i = 0; i < FLEX_TRIT_SIZE_243; i++) {
157+
printf("%c", channel_id_result[i]);
158+
}
159+
printf("\n");
160+
printf("Bundle: ");
161+
for (size_t i = 0; i < FLEX_TRIT_SIZE_243; i++) {
162+
printf("%c", bundle_hash_result[i]);
163+
}
164+
printf("\n");
165+
166+
free(bundle_hash_result);
167+
free(channel_id_result);
168+
}
169+
printf("Average time of receive_mam_message: %lf\n", sum / TEST_COUNT);
170+
}
171+
141172
void test_receive_mam_message(void) {
142173
char* json_result;
143174
double sum = 0;

tests/test_define.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,27 @@ extern "C" {
113113
"WYEVIWJN9DF9SBQHBUWYUECD9KD9BQHQXHOGQDTVKKYBRQUFQYGOFOTHREGVSKSSEVXMFOEHWN" \
114114
"KHLHDKQ"
115115

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

0 commit comments

Comments
 (0)