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

ciri/api: attach_to_tangle implementation #1039

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cclient/request/attach_to_tangle.c
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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;
}