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

Commit f0a5fa1

Browse files
author
Wu Yu Wei
authored
Merge pull request #125 from HowJMay/mam_send_message
feat(mam): Implement api_mam_send_message()
2 parents 18dabe8 + 0d45c6f commit f0a5fa1

File tree

9 files changed

+245
-23
lines changed

9 files changed

+245
-23
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
}
@@ -221,6 +221,95 @@ status_t api_receive_mam_message(const iota_client_service_t* const service,
221221
return ret;
222222
}
223223

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

4343
for (size_t count = 0; count < TEST_COUNT; count++) {
4444
test_time_start(&start_time);
45-
TEST_ASSERT_FALSE(
45+
TEST_ASSERT_EQUAL_INT32(
46+
SC_OK,
4647
api_generate_address(&ta_core.tangle, &ta_core.service, &json_result));
4748
test_time_end(&start_time, &end_time, &sum);
4849
free(json_result);
@@ -56,7 +57,8 @@ void test_get_tips_pair(void) {
5657

5758
for (size_t count = 0; count < TEST_COUNT; count++) {
5859
test_time_start(&start_time);
59-
TEST_ASSERT_FALSE(
60+
TEST_ASSERT_EQUAL_INT32(
61+
SC_OK,
6062
api_get_tips_pair(&ta_core.tangle, &ta_core.service, &json_result));
6163
test_time_end(&start_time, &end_time, &sum);
6264
free(json_result);
@@ -70,7 +72,8 @@ void test_get_tips(void) {
7072

7173
for (size_t count = 0; count < TEST_COUNT; count++) {
7274
test_time_start(&start_time);
73-
TEST_ASSERT_FALSE(api_get_tips(&ta_core.service, &json_result));
75+
TEST_ASSERT_EQUAL_INT32(SC_OK,
76+
api_get_tips(&ta_core.service, &json_result));
7477
test_time_end(&start_time, &end_time, &sum);
7578
free(json_result);
7679
}
@@ -88,8 +91,9 @@ void test_send_transfer(void) {
8891

8992
for (size_t count = 0; count < TEST_COUNT; count++) {
9093
test_time_start(&start_time);
91-
TEST_ASSERT_FALSE(api_send_transfer(&ta_core.tangle, &ta_core.service, json,
92-
&json_result));
94+
TEST_ASSERT_EQUAL_INT32(
95+
SC_OK, api_send_transfer(&ta_core.tangle, &ta_core.service, json,
96+
&json_result));
9397
test_time_end(&start_time, &end_time, &sum);
9498
free(json_result);
9599
}
@@ -102,8 +106,9 @@ void test_get_transaction_object(void) {
102106

103107
for (size_t count = 0; count < TEST_COUNT; count++) {
104108
test_time_start(&start_time);
105-
TEST_ASSERT_FALSE(api_get_transaction_object(&ta_core.service, TRYTES_81_3,
106-
&json_result));
109+
TEST_ASSERT_EQUAL_INT32(
110+
SC_OK, api_get_transaction_object(&ta_core.service, TRYTES_81_3,
111+
&json_result));
107112
test_time_end(&start_time, &end_time, &sum);
108113
free(json_result);
109114
}
@@ -116,8 +121,10 @@ void test_find_transactions_by_tag(void) {
116121

117122
for (size_t count = 0; count < TEST_COUNT; count++) {
118123
test_time_start(&start_time);
119-
TEST_ASSERT_FALSE(api_find_transactions_by_tag(&ta_core.service,
120-
FIND_TAG_MSG, &json_result));
124+
125+
TEST_ASSERT_EQUAL_INT32(
126+
SC_OK, api_find_transactions_by_tag(&ta_core.service, FIND_TAG_MSG,
127+
&json_result));
121128
test_time_end(&start_time, &end_time, &sum);
122129
free(json_result);
123130
}
@@ -130,24 +137,57 @@ void test_find_transactions_obj_by_tag(void) {
130137

131138
for (size_t count = 0; count < TEST_COUNT; count++) {
132139
test_time_start(&start_time);
133-
TEST_ASSERT_FALSE(api_find_transactions_obj_by_tag(
134-
&ta_core.service, FIND_TAG_MSG, &json_result));
140+
141+
TEST_ASSERT_EQUAL_INT32(
142+
SC_OK, api_find_transactions_obj_by_tag(&ta_core.service, FIND_TAG_MSG,
143+
&json_result));
135144
test_time_end(&start_time, &end_time, &sum);
136145
free(json_result);
137146
}
138147
printf("Average time of find_tx_obj_by_tag: %lf\n", sum / TEST_COUNT);
139148
}
140149

150+
void test_send_mam_message(void) {
151+
double sum = 0;
152+
153+
char* bundle_hash_result;
154+
char* channel_id_result;
155+
156+
for (size_t count = 0; count < TEST_COUNT; count++) {
157+
test_time_start(&start_time);
158+
TEST_ASSERT_EQUAL_INT32(
159+
SC_OK,
160+
api_mam_send_message(&ta_core.tangle, &ta_core.service, TEST_PAYLOAD,
161+
&bundle_hash_result, &channel_id_result));
162+
test_time_end(&start_time, &end_time, &sum);
163+
164+
for (size_t i = 0; i < FLEX_TRIT_SIZE_243; i++) {
165+
printf("%c", channel_id_result[i]);
166+
}
167+
printf("\n");
168+
printf("Bundle: ");
169+
for (size_t i = 0; i < FLEX_TRIT_SIZE_243; i++) {
170+
printf("%c", bundle_hash_result[i]);
171+
}
172+
printf("\n");
173+
174+
free(bundle_hash_result);
175+
free(channel_id_result);
176+
}
177+
printf("Average time of receive_mam_message: %lf\n", sum / TEST_COUNT);
178+
}
179+
141180
void test_receive_mam_message(void) {
142181
char* json_result;
143182
double sum = 0;
144-
status_t ret = SC_OK;
183+
145184
for (size_t count = 0; count < TEST_COUNT; count++) {
146-
clock_gettime(CLOCK_REALTIME, &start_time);
147-
ret = api_receive_mam_message(&ta_core.service, TEST_BUNDLE_HASH,
148-
&json_result);
149-
TEST_ASSERT_EQUAL_INT32(ret, SC_OK);
150-
clock_gettime(CLOCK_REALTIME, &end_time);
185+
test_time_start(&start_time);
186+
187+
TEST_ASSERT_EQUAL_INT32(
188+
SC_OK, api_receive_mam_message(&ta_core.service, TEST_BUNDLE_HASH,
189+
&json_result));
190+
test_time_end(&start_time, &end_time, &sum);
151191
free(json_result);
152192
}
153193
printf("Average time of receive_mam_message: %lf\n", sum / TEST_COUNT);
@@ -167,6 +207,7 @@ int main(void) {
167207
RUN_TEST(test_find_transactions_by_tag);
168208
RUN_TEST(test_find_transactions_obj_by_tag);
169209
RUN_TEST(test_receive_mam_message);
210+
RUN_TEST(test_send_mam_message);
170211
ta_config_destroy(&ta_core.service);
171212
return UNITY_END();
172213
}

0 commit comments

Comments
 (0)