12
12
13
13
#define MAM_LOGGER "mam_core"
14
14
15
+ typedef struct channel_info_s {
16
+ int32_t ch_mss_depth ;
17
+ tryte_t * chid ;
18
+ } channel_info_t ;
19
+
15
20
static logger_id_t logger_id ;
16
21
17
22
void ta_mam_logger_init () { logger_id = logger_helper_enable (MAM_LOGGER , LOGGER_DEBUG , true); }
@@ -230,7 +235,7 @@ static status_t ta_mam_init(mam_api_t *const api, const iota_config_t *const ico
230
235
}
231
236
232
237
static status_t create_channel_fetch_all_transactions (const iota_client_service_t * const service , mam_api_t * const api ,
233
- const size_t channel_depth , tryte_t * const chid ,
238
+ const size_t channel_depth , bool first_iter , tryte_t * const chid ,
234
239
hash81_array_p tag_array ) {
235
240
status_t ret = SC_OK ;
236
241
find_transactions_req_t * txn_req = find_transactions_req_new ();
@@ -241,10 +246,14 @@ static status_t create_channel_fetch_all_transactions(const iota_client_service_
241
246
goto done ;
242
247
}
243
248
244
- if (mam_api_channel_create (api , channel_depth , chid ) != RC_OK ) {
245
- ret = SC_MAM_FAILED_CREATE_OR_GET_ID ;
246
- ta_log_error ("%s\n" , ta_error_to_string (ret ));
247
- goto done ;
249
+ // We have created a channel when we want to get to the given channel at the first loop in
250
+ // `ta_mam_written_msg_to_bundle()`, so we don't need to create a channel once again.
251
+ if (!first_iter ) {
252
+ if (mam_api_channel_create (api , channel_depth , chid ) != RC_OK ) {
253
+ ret = SC_MAM_FAILED_CREATE_OR_GET_ID ;
254
+ ta_log_error ("%s\n" , "SC_MAM_FAILED_CREATE_OR_GET_ID" );
255
+ goto done ;
256
+ }
248
257
}
249
258
250
259
flex_trit_t chid_flex_trit [NUM_TRITS_ADDRESS ];
@@ -271,6 +280,35 @@ static status_t create_channel_fetch_all_transactions(const iota_client_service_
271
280
return ret ;
272
281
}
273
282
283
+ static bool is_setting_changed (const iota_client_service_t * const service , mam_api_t * const api ,
284
+ const size_t channel_depth , tryte_t * const chid ) {
285
+ bool changed = true;
286
+ find_transactions_req_t * txn_req = find_transactions_req_new ();
287
+ transaction_array_t * txn_res = transaction_array_new ();
288
+
289
+ if (mam_api_channel_create (api , channel_depth , chid ) != RC_OK ) {
290
+ ta_log_error ("%s\n" , ta_error_to_string (SC_MAM_FAILED_CREATE_OR_GET_ID ));
291
+ goto done ;
292
+ }
293
+
294
+ flex_trit_t chid_flex_trit [NUM_TRITS_ADDRESS ];
295
+ flex_trits_from_trytes (chid_flex_trit , NUM_TRITS_ADDRESS , chid , NUM_TRYTES_ADDRESS , NUM_TRYTES_ADDRESS );
296
+ hash243_queue_push (& txn_req -> addresses , chid_flex_trit );
297
+ // TODO use `ta_find_transaction_objects(service, txn_req, txn_res)` instead of the original entangled function
298
+ retcode_t ret_rc = iota_client_find_transaction_objects (service , txn_req , txn_res );
299
+ if (ret_rc && ret_rc != RC_NULL_PARAM ) {
300
+ ta_log_error ("%s\n" , SC_MAM_FAILED_DESTROYED );
301
+ goto done ;
302
+ }
303
+
304
+ changed = (transaction_array_len (txn_res ) == 0 );
305
+
306
+ done :
307
+ find_transactions_req_free (& txn_req );
308
+ transaction_array_free (txn_res );
309
+ return changed ;
310
+ }
311
+
274
312
/**
275
313
* @brief Write payload to bundle on the smallest secret key.
276
314
*
@@ -290,27 +328,62 @@ static status_t create_channel_fetch_all_transactions(const iota_client_service_
290
328
* @return return code
291
329
*/
292
330
static status_t ta_mam_written_msg_to_bundle (const iota_client_service_t * const service , mam_api_t * const api ,
293
- const size_t channel_depth , mam_encrypt_key_t mam_key ,
331
+ const channel_info_t * channel_info , mam_encrypt_key_t mam_key ,
294
332
char const * const payload , bundle_transactions_t * * bundle ,
295
333
tryte_t * const chid , tryte_t * const msg_id ,
296
334
mam_send_operation_t * mam_operation ) {
297
335
status_t ret = SC_OK ;
298
- if (!service || !api || !chid || !msg_id || channel_depth < 1 ) {
336
+ if (!service || !api || !chid || !msg_id || ! channel_info || channel_info -> ch_mss_depth < 1 ) {
299
337
ret = SC_MAM_NULL ;
300
338
ta_log_error ("%s\n" , ta_error_to_string (ret ));
301
339
return ret ;
302
340
}
303
341
trit_t msg_id_trits [MAM_MSG_ID_SIZE ];
304
342
hash81_array_p tag_array = hash81_array_new ();
343
+
344
+ // Get to the assigned beginning channel ID. If the initial setting is different, then tangle-accelerator won't be
345
+ // able to generate same chid.
346
+ if (channel_info -> chid ) {
347
+ // The current setting hasn't been used on Tangle, so we should take the normal procedure.
348
+ if (is_setting_changed (service , api , channel_info -> ch_mss_depth , chid )) {
349
+ goto end_find_starting_chid ;
350
+ }
351
+
352
+ int cnt = 0 ;
353
+ while (memcmp (channel_info -> chid , chid , NUM_TRYTES_ADDRESS )) {
354
+ if (mam_api_channel_create (api , channel_info -> ch_mss_depth , chid ) != RC_OK ) {
355
+ ret = SC_MAM_FAILED_CREATE_OR_GET_ID ;
356
+ ta_log_error ("%s\n" , ta_error_to_string (ret ));
357
+ goto done ;
358
+ }
359
+
360
+ if (cnt ++ > 100 ) {
361
+ ret = SC_MAM_EXCEEDED_CHID_ITER ;
362
+ ta_log_error ("%s\n" , ta_error_to_string (ret ));
363
+ goto done ;
364
+ }
365
+ }
366
+
367
+ end_find_starting_chid :
368
+ ta_log_debug ("%s\n" , "Finish finding starting chid" );
369
+ }
370
+
371
+ // If a starting chid is provided, then we don't need to create a new chid in the first iteration of the following
372
+ // loop.
373
+ // FIXME: We should figure out a way to avoid passing 'first_iter_with_given_chid' to
374
+ // 'create_channel_fetch_all_transactions()'
375
+ bool first_iter_with_given_chid = (bool )channel_info -> chid ;
305
376
for (;;) {
306
377
hash_array_free (tag_array );
307
378
tag_array = hash81_array_new ();
308
379
309
- ret = create_channel_fetch_all_transactions (service , api , channel_depth , chid , tag_array );
380
+ ret = create_channel_fetch_all_transactions (service , api , channel_info -> ch_mss_depth , first_iter_with_given_chid ,
381
+ chid , tag_array );
310
382
if (ret ) {
311
383
ta_log_error ("%s\n" , ta_error_to_string (ret ));
312
384
goto done ;
313
385
}
386
+ first_iter_with_given_chid = false;
314
387
315
388
/*
316
389
* Three cases should be considered:
@@ -320,7 +393,7 @@ static status_t ta_mam_written_msg_to_bundle(const iota_client_service_t *const
320
393
*/
321
394
322
395
// Calculate the smallest available msg_ord
323
- const int ch_leaf_num = 1 << channel_depth ;
396
+ const int ch_leaf_num = 1 << channel_info -> ch_mss_depth ;
324
397
int ch_remain_key_num = ch_leaf_num ;
325
398
int used_key_num = hash_array_len (tag_array );
326
399
do {
@@ -447,11 +520,6 @@ static status_t ta_mam_api_bundle_read(mam_api_t *const api, bundle_transactions
447
520
* External functions
448
521
***********************************************************************************************************/
449
522
450
- void bundle_transactions_renew (bundle_transactions_t * * bundle ) {
451
- bundle_transactions_free (bundle );
452
- bundle_transactions_new (bundle );
453
- }
454
-
455
523
status_t ta_send_mam_message (const ta_config_t * const info , const iota_config_t * const iconf ,
456
524
const iota_client_service_t * const service , ta_send_mam_req_t const * const req ,
457
525
ta_send_mam_res_t * const res ) {
@@ -473,10 +541,10 @@ status_t ta_send_mam_message(const ta_config_t *const info, const iota_config_t
473
541
mam_send_operation_t mam_operation ;
474
542
while (!msg_sent ) {
475
543
bundle_transactions_renew (& bundle );
544
+ struct channel_info_s channel_info = {.ch_mss_depth = data -> ch_mss_depth , .chid = data -> chid };
476
545
477
- // Create channel merkle tree and find the smallest unused secret key.
478
546
// Write both Header and Packet into one single bundle.
479
- ret = ta_mam_written_msg_to_bundle (service , & mam , data -> ch_mss_depth , mam_key , data -> message , & bundle , chid , msg_id ,
547
+ ret = ta_mam_written_msg_to_bundle (service , & mam , & channel_info , mam_key , data -> message , & bundle , chid , msg_id ,
480
548
& mam_operation );
481
549
if (ret == SC_OK ) {
482
550
msg_sent = true;
0 commit comments