Skip to content
This repository has been archived by the owner on Mar 12, 2020. It is now read-only.

Commit

Permalink
ciri/api: attach_to_tangle implementation (#1039)
Browse files Browse the repository at this point in the history
* cclient: fix attach_to_tangle req branch

* common/helpers: fix pow_bundle to match IRI attach_to_tangle

* ciri/api: attach_to_tangle implementation

* ciri/api: attach_to_tangle test
  • Loading branch information
thibault-martinez committed Apr 1, 2019
1 parent eea4e86 commit 639dff5
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 20 deletions.
2 changes: 1 addition & 1 deletion cclient/request/attach_to_tangle.c
Expand Up @@ -34,7 +34,7 @@ void attach_to_tangle_req_free(attach_to_tangle_req_t **req) {
void attach_to_tangle_req_init(attach_to_tangle_req_t *req, flex_trit_t const *const trunk,
flex_trit_t const *const branch, uint8_t mwm) {
memcpy(req->trunk, trunk, FLEX_TRIT_SIZE_243);
memcpy(req->trunk, branch, FLEX_TRIT_SIZE_243);
memcpy(req->branch, branch, FLEX_TRIT_SIZE_243);
req->mwm = mwm;
}

Expand Down
1 change: 1 addition & 0 deletions ciri/api/BUILD
Expand Up @@ -18,6 +18,7 @@ cc_library(
"//cclient/response:responses",
"//ciri:core",
"//common:errors",
"//common/helpers:pow",
"//utils:logger_helper",
],
)
Expand Down
27 changes: 27 additions & 0 deletions ciri/api/api.c
Expand Up @@ -8,6 +8,7 @@
#include <string.h>

#include "ciri/api/api.h"
#include "common/helpers/pow.h"
#include "utils/logger_helper.h"
#include "utils/time.h"

Expand Down Expand Up @@ -268,10 +269,36 @@ retcode_t iota_api_get_transactions_to_approve(iota_api_t const *const api, tang

retcode_t iota_api_attach_to_tangle(iota_api_t const *const api, attach_to_tangle_req_t const *const req,
attach_to_tangle_res_t *const res, error_res_t **const error) {
retcode_t ret = RC_OK;
bundle_transactions_t *bundle = NULL;
iota_transaction_t *tx_iter = NULL;
flex_trit_t *trytes_iter = NULL;
iota_transaction_t tx;
flex_trit_t tx_trytes[FLEX_TRIT_SIZE_8019];

if (api == NULL || req == NULL || res == NULL || error == NULL) {
return RC_NULL_PARAM;
}

bundle_transactions_new(&bundle);

HASH_ARRAY_FOREACH(req->trytes, trytes_iter) {
transaction_deserialize_from_trits(&tx, trytes_iter, false);
bundle_transactions_add(bundle, &tx);
}

if ((ret = iota_pow_bundle(bundle, req->trunk, req->branch, req->mwm)) != RC_OK) {
goto done;
}

BUNDLE_FOREACH(bundle, tx_iter) {
transaction_serialize_on_flex_trits(tx_iter, tx_trytes);
hash_array_push(res->trytes, tx_trytes);
}

done:
bundle_transactions_free(&bundle);

return RC_OK;
}

Expand Down
10 changes: 10 additions & 0 deletions ciri/api/tests/BUILD
Expand Up @@ -23,6 +23,16 @@ cc_test(
],
)

cc_test(
name = "test_attach_to_tangle",
srcs = ["test_attach_to_tangle.c"],
deps = [
"//ciri/api",
"//consensus/test_utils",
"@unity",
],
)

cc_test(
name = "test_broadcast_transactions",
srcs = ["test_broadcast_transactions.c"],
Expand Down
78 changes: 78 additions & 0 deletions ciri/api/tests/test_attach_to_tangle.c
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2018 IOTA Stiftung
* https://github.com/iotaledger/entangled
*
* Refer to the LICENSE file for licensing information
*/

#include <unity/unity.h>

#include "ciri/api/api.h"
#include "consensus/test_utils/bundle.h"

static iota_api_t api;

void test_attach_to_tangle(void) {
attach_to_tangle_req_t *req = attach_to_tangle_req_new();
attach_to_tangle_res_t *res = attach_to_tangle_res_new();
error_res_t *error = NULL;
tryte_t const *const txs_trytes[4] = {TX_1_OF_4_VALUE_BUNDLE_TRYTES, TX_2_OF_4_VALUE_BUNDLE_TRYTES,
TX_3_OF_4_VALUE_BUNDLE_TRYTES, TX_4_OF_4_VALUE_BUNDLE_TRYTES};
flex_trit_t tx_trits[FLEX_TRIT_SIZE_8019];
tryte_t const *const trunk =
(tryte_t *)"QBDYOWCHXVFNDEFXJXIBYZLWVHYISYUWRIDFNXZDTQTSNSCPOIMB9NIW9GEY9DZWMCPBFCVEBROZ99999";
tryte_t const *const branch =
(tryte_t *)"A9VNT9ZZXOFMUAAR9SKZITFCXVGXPFMDLH9DCNZOCQCNNEWZBAQCOJHFIIIOSDHNZ9YKLUYVZKFW99999";
uint8_t mwm = 10;
flex_trit_t flex_trunk[FLEX_TRIT_SIZE_243];
flex_trit_t flex_branch[FLEX_TRIT_SIZE_243];
flex_trit_t *trytes_iter = NULL;
iota_transaction_t tx;
int i = 0;
flex_trit_t prev_trunk[FLEX_TRIT_SIZE_243];

flex_trits_from_trytes(flex_trunk, NUM_TRITS_TRUNK, trunk, NUM_TRYTES_TRUNK, NUM_TRYTES_TRUNK);
flex_trits_from_trytes(flex_branch, NUM_TRITS_BRANCH, branch, NUM_TRYTES_BRANCH, NUM_TRYTES_BRANCH);

attach_to_tangle_req_init(req, flex_trunk, flex_branch, mwm);

for (size_t i = 0; i < 4; i++) {
flex_trits_from_trytes(tx_trits, NUM_TRITS_SERIALIZED_TRANSACTION, txs_trytes[i], NUM_TRYTES_SERIALIZED_TRANSACTION,
NUM_TRYTES_SERIALIZED_TRANSACTION);
TEST_ASSERT(attach_to_tangle_req_trytes_add(req, tx_trits) == RC_OK);
}

TEST_ASSERT(iota_api_attach_to_tangle(&api, req, res, &error) == RC_OK);
TEST_ASSERT(error == NULL);

TEST_ASSERT_EQUAL_INT(hash_array_len(res->trytes), 4);

HASH_ARRAY_FOREACH(res->trytes, trytes_iter) {
transaction_deserialize_from_trits(&tx, trytes_iter, true);
TEST_ASSERT(transaction_weight_magnitude(&tx) >= mwm);
if (i != 3) {
if (i != 0) {
TEST_ASSERT_EQUAL_MEMORY(transaction_hash(&tx), prev_trunk, FLEX_TRIT_SIZE_243);
}
TEST_ASSERT_EQUAL_MEMORY(transaction_branch(&tx), flex_trunk, FLEX_TRIT_SIZE_243);
memcpy(prev_trunk, transaction_trunk(&tx), FLEX_TRIT_SIZE_243);
} else {
TEST_ASSERT_EQUAL_MEMORY(transaction_hash(&tx), prev_trunk, FLEX_TRIT_SIZE_243);
TEST_ASSERT_EQUAL_MEMORY(transaction_trunk(&tx), flex_trunk, FLEX_TRIT_SIZE_243);
TEST_ASSERT_EQUAL_MEMORY(transaction_branch(&tx), flex_branch, FLEX_TRIT_SIZE_243);
}
i++;
}

attach_to_tangle_req_free(&req);
attach_to_tangle_res_free(&res);
error_res_free(&error);
}

int main(void) {
UNITY_BEGIN();

RUN_TEST(test_attach_to_tangle);

return UNITY_END();
}
35 changes: 16 additions & 19 deletions common/helpers/pow.c
Expand Up @@ -108,12 +108,9 @@ IOTA_EXPORT retcode_t iota_pow_bundle(bundle_transactions_t *const bundle, flex_
tx = (iota_transaction_t *)utarray_front(bundle);
cur_idx = tx->essence.last_index + 1;

ctrunk = (flex_trit_t *)trunk;

do {
cur_idx--;

// Find current tx
for (tx = (iota_transaction_t *)utarray_front(bundle); tx != NULL && tx->essence.current_index != cur_idx;
tx = (iota_transaction_t *)utarray_next(bundle, tx))
;
Expand All @@ -122,37 +119,37 @@ IOTA_EXPORT retcode_t iota_pow_bundle(bundle_transactions_t *const bundle, flex_
return RC_HELPERS_POW_INVALID_TX;
}

// Set trunk & branch
transaction_set_trunk(tx, ctrunk);
transaction_set_branch(tx, branch);
if (transaction_current_index(tx) == transaction_last_index(tx)) {
transaction_set_trunk(tx, trunk);
transaction_set_branch(tx, branch);
} else {
transaction_set_trunk(tx, ctrunk);
transaction_set_branch(tx, trunk);
free(ctrunk);
}
transaction_set_attachment_timestamp(tx, current_timestamp_ms());
transaction_set_attachment_timestamp_lower(tx, 0);
transaction_set_attachment_timestamp_upper(tx, 3812798742493LL);
if (flex_trits_are_null(transaction_tag(tx), FLEX_TRIT_SIZE_27)) {
memcpy(transaction_tag(tx), transaction_obsolete_tag(tx), FLEX_TRIT_SIZE_27);
}

transaction_serialize_on_flex_trits(tx, txflex);

// Do PoW
if ((nonce = iota_pow_flex(txflex, NUM_TRITS_SERIALIZED_TRANSACTION, mwm)) == NULL) {
return RC_OOM;
}
transaction_set_nonce(tx, nonce);
free(nonce);

if (ctrunk != trunk) {
free(ctrunk);
}

transaction_serialize_on_flex_trits(tx, txflex);

if ((ctrunk = iota_flex_digest(txflex, NUM_TRITS_SERIALIZED_TRANSACTION)) == NULL) {
return RC_OOM;
if (transaction_current_index(tx) != 0) {
transaction_serialize_on_flex_trits(tx, txflex);
if ((ctrunk = iota_flex_digest(txflex, NUM_TRITS_SERIALIZED_TRANSACTION)) == NULL) {
return RC_OOM;
}
}

} while (cur_idx != 0);

if (ctrunk != trunk) {
free(ctrunk);
}

return RC_OK;
}

0 comments on commit 639dff5

Please sign in to comment.