From 95cb35129b49508cba672d5aef13742f5d4a3d55 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Fri, 5 Feb 2021 12:16:58 +0100 Subject: [PATCH] adjust for cross group transaction test and also fix false order for real version --- .../HTTPInterface/AdminNodeServerTestPage.cpp | 493 +++++++++++++----- src/cpp/lib/DataTypeConverter.cpp | 7 + src/cpp/lib/DataTypeConverter.h | 1 + src/cpp/model/gradido/Transaction.cpp | 119 ++++- src/cpp/model/gradido/Transaction.h | 3 + src/cpp/model/gradido/TransactionBody.cpp | 91 +++- src/cpp/model/gradido/TransactionBody.h | 2 + src/cpp/model/gradido/TransactionTransfer.cpp | 57 +- src/cpp/model/gradido/TransactionTransfer.h | 14 + src/cpsp/adminNodeServerTest.cpsp | 198 +++++-- 10 files changed, 783 insertions(+), 202 deletions(-) diff --git a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp index b9bfa69b4..a406800f5 100644 --- a/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp +++ b/src/cpp/HTTPInterface/AdminNodeServerTestPage.cpp @@ -45,11 +45,14 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques const char* pageName = "Node Server Test"; PageType page = PAGE_CHOOSE_TEST; Poco::AutoPtr node_server; + Poco::AutoPtr node_server2; Poco::AutoPtr user; Poco::AutoPtr hedera_topic; - int hedera_timeout = 9; + Poco::AutoPtr hedera_topic2; + int hedera_timeout = 4; + int sleep_ms_between_transactions = 1000; - bool steps[6]; memset(steps, 1, 6 * sizeof(bool)); + bool steps[8]; memset(steps, 1, 8 * sizeof(bool)); if(!form.empty()) @@ -61,6 +64,13 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques node_server = controller::NodeServer::load(node_server_id); } } + node_server_id_string = form.get("test-node-servers2", ""); + if(node_server_id_string != "") { + int node_server_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { + node_server2 = controller::NodeServer::load(node_server_id); + } + } auto topic_id_string = form.get("test-hedera-topic", ""); if(topic_id_string != "") { int topic_id = 0; @@ -68,18 +78,25 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques hedera_topic = controller::HederaTopic::load(topic_id); } } + topic_id_string = form.get("test-hedera-topic2", ""); + if(topic_id_string != "") { + int topic_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { + hedera_topic2 = controller::HederaTopic::load(topic_id); + } + } auto test_timeout_string = form.get("test-timeout", ""); if(test_timeout_string != "") { DataTypeConverter::strToInt(test_timeout_string, hedera_timeout); } auto submit = form.get("submit", ""); - if(submit == "Run 4-Test") { + if(submit == "Run 6-Test") { page = PAGE_RUN_4_SET_TEST; } else if(submit == "json-rpc getTransactions") { page = PAGE_GET_TRANSACTION_RPC_CALL; } std::string step_temp; - for(int i = 0; i < 6; i++) { + for(int i = 0; i < 8; i++) { std::string name = "step-"; name += std::to_string(i+2); step_temp = form.get(name, ""); @@ -162,206 +179,302 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques responseStream << "\t\t
"; // end include header_large.cpsp responseStream << "\n"; -#line 82 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 99 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( getErrorsHtml() ); responseStream << "\n"; responseStream << "
\n"; responseStream << "\t\n"; responseStream << "\t
\n"; responseStream << "\t \n"; +#line 103 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\" onclick=\"openTab(event, 'test-4')\">Test 6-Set (3 AddMember, Creation, 2 Transfer)\n"; responseStream << "\t \n"; responseStream << "\t
\n"; responseStream << "\t
\n"; responseStream << "\t\t
\n"; - responseStream << "\t\t\t

Test 4-Set (2 AddMember, Creation, Transfer)\n"; + responseStream << "\t\t\t

Test 6-Set (3 AddMember, Creation, 2 Transfer)\n"; responseStream << "\t\t

\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t
\n"; - responseStream << "\t\t\t\t

1. Create two new accounts and show user public keys for comparisation

\n"; + responseStream << "\t\t\t\t

1. Create three new accounts and show user public keys for comparisation

\n"; responseStream << "\t\t\t\t

2. Send a add-member transaction to hedera topic with one signature (first user)

\n"; responseStream << "\t\t\t\t

3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

\n"; responseStream << "\t\t\t\t

4. Send a creation transaction to second user, signed by first user

\n"; responseStream << "\t\t\t\t

5. Send a transfer transaction from second user to first user signed by second user

\n"; responseStream << "\t\t\t\t

6. Wait x seconds to give hedera time to process transactions

\n"; +#line 117 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << " name=\"step-6\" value=\"1\"/> 6. Send a add-member transaction to hedera topic 2 with one signature (third user)

\n"; responseStream << "\t\t\t\t

7. Ask choosen node for transaction and print result

\n"; - responseStream << "\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t"; -#line 104 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 118 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << " name=\"step-7\" value=\"1\"/> 7. Send a cross group transfer from second user to third user signed by second user

\n"; + responseStream << "\t\t\t\t

8. Wait x seconds to give hedera time to process transactions

\n"; + responseStream << "\t\t\t\t

9. Ask choosen node for transaction and print result

\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\tGroup 1 \n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 124 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(node_servers.size() == 0) { responseStream << "\n"; - responseStream << "\t\t\t\t\tEdit Node-Servers\n"; - responseStream << "\t\t\t\t"; -#line 106 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\t"; +#line 128 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" for(auto it = node_servers.begin(); it != node_servers.end(); it++) { - auto model = (*it)->getModel(); - responseStream << "\n"; - responseStream << "\t\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 112 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t\t\t\t"; +#line 132 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t\n"; - responseStream << "\t\t\t\t"; -#line 115 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 135 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(hedera_topics.size() == 0) { responseStream << "\n"; - responseStream << "\t\t\t\t\tEdit Hedera-Topics\n"; - responseStream << "\t\t\t\t"; -#line 117 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\t"; +#line 139 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" for(auto it = hedera_topics.begin(); it != hedera_topics.end(); it++) { - auto model = (*it)->getModel(); - auto hedera_account = (*it)->getAutoRenewAccount(); - if(hedera_account->getModel()->getNetworkType() != ServerConfig::HEDERA_TESTNET) { - continue; - } - responseStream << "\n"; - responseStream << "\t\t\t\t\t\t\n"; - responseStream << "\t\t\t\t\t"; -#line 127 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t\t\t\t"; +#line 147 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; - responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\tGroup 2 \n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 153 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(node_servers.size() == 0) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\tEdit Node-Servers\n"; + responseStream << "\t\t\t\t\t"; +#line 155 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t\t"; +#line 164 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(hedera_topics.size() == 0) { responseStream << "\n"; + responseStream << "\t\t\t\t\t\tEdit Hedera-Topics\n"; + responseStream << "\t\t\t\t\t"; +#line 166 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t\t\t\n"; + responseStream << "\t\t\t\t
\n"; + responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t seconds \n"; - responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t
\n"; responseStream << "\t
\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t

Test 4-Set (2 AddMember, Creation, Transfer)\n"; responseStream << "\t\t

\n"; responseStream << "\t\t
\n"; responseStream << "\t\t\t
\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t"; -#line 142 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 193 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(node_servers.size() == 0) { responseStream << "\n"; responseStream << "\t\t\t\t\tEdit Node-Servers\n"; responseStream << "\t\t\t\t"; -#line 144 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 195 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t\t\n"; responseStream << "\t\t\t\t\n"; @@ -369,17 +482,19 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques responseStream << "\t\t
\n"; responseStream << "\t
\n"; responseStream << "\t"; -#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 207 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { responseStream << "\n"; responseStream << "\t
    \n"; responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    1. Create two new accounts and show user public keys for comparisation:

    \n"; + responseStream << "\t\t\t

    1. Create three new accounts and show user public keys for comparisation:

    \n"; responseStream << "\t\t\t"; -#line 160 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 211 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" Profiler time2; auto group_id = hedera_topic->getModel()->getGroupId(); + auto group_id2 = hedera_topic2->getModel()->getGroupId(); auto user_group = controller::Group::load(group_id); + auto user_group2 = controller::Group::load(group_id2); auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj"; @@ -395,30 +510,51 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2); user_2->setGradidoKeyPair(gradido_key_pair_2); user_2->login(password2); + + std::string password3 = "jaue_skaiellasealaK"; + auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2); + auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3); + user_3->setGradidoKeyPair(gradido_key_pair_3); + user_3->login(password3); responseStream << "\t\t\t\n"; - responseStream << "\t\t\t

    User 1: "; -#line 180 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t

    "; +#line 240 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_group->getModel()->getName() ); + responseStream << "\n"; + responseStream << "\t\t\t\t

    User 1: "; +#line 241 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( user_1->getPublicHex() ); responseStream << "

    \n"; - responseStream << "\t\t\t

    User 2: "; -#line 181 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t\t

    User 2: "; +#line 242 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( user_2->getPublicHex() ); responseStream << "

    \n"; + responseStream << "\t\t\t
    \n"; + responseStream << "\t\t\t
    "; +#line 244 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_group2->getModel()->getName() ); + responseStream << "\n"; + responseStream << "\t\t\t\t

    User 3: "; +#line 245 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( user_3->getPublicHex() ); + responseStream << "

    \n"; + responseStream << "\t\t\t
    \n"; responseStream << "\t\t\t

    Time: "; -#line 182 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "\n"; responseStream << "\t\t

  • \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    2. Send a add-member transaction to hedera topic with one signature (first user)

    \n"; responseStream << "\t\t\t"; -#line 186 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[0]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 190 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 255 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group); transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); @@ -426,127 +562,202 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques auto transaction1_json = transaction1->getTransactionAsJson(true); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 196 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 261 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction1_json) ); responseStream << "

    \n"; responseStream << "\t\t\t"; -#line 197 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 262 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 263 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "\n"; responseStream << "\t\t

  • \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

    \n"; responseStream << "\t\t\t"; -#line 202 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 267 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[1]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 271 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); transaction2->sign(user_2); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); transaction2->sign(user_1); auto transaction2_json = transaction2->getTransactionAsJson(true); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 280 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction2_json) ); responseStream << "

    \n"; responseStream << "\t\t\t"; -#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 282 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "\n"; responseStream << "\t\t

  • \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    4. Send a creation transaction to second user, signed by first user

    \n"; responseStream << "\t\t\t"; -#line 219 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 286 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[2]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 223 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 290 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); transaction3->sign(user_1); auto transaction3_json = transaction3->getTransactionAsJson(true); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 228 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 297 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction3_json) ); responseStream << "

    \n"; responseStream << "\t\t\t"; -#line 229 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 298 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 230 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 299 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t\t

    5. Send a transfer transaction from second user to first user signed by second user

    \n"; responseStream << "\t\t\t"; -#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 303 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); if(!steps[3]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 238 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 307 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(hedera_timeout * 100); + Poco::Thread::sleep(sleep_ms_between_transactions); transaction4[0]->sign(user_2); auto transaction4_json = transaction4[0]->getTransactionAsJson(true); responseStream << "\n"; responseStream << "\t\t\t

    "; -#line 246 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 315 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction4_json) ); responseStream << "

    \n"; responseStream << "\t\t\t"; -#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 316 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 317 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    6. Wait "; -#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << "\t\t\t

    6. Send a add-member transaction to hedera topic 2 with one signature (third user)

    \n"; + responseStream << "\t\t\t"; +#line 321 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[4]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 325 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2); + transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction5->sign(user_3); + auto transaction5_json = transaction5->getTransactionAsJson(true); + responseStream << "\n"; + responseStream << "\t\t\t

    "; +#line 332 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction5_json) ); + responseStream << "

    \n"; + responseStream << "\t\t\t"; +#line 333 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t

    Time: "; +#line 334 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "

    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    7. Send a cross group transfer from second user to third user signed by second user

    \n"; + responseStream << "\t\t\t"; +#line 338 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + time2.reset(); + if(!steps[5]) { responseStream << "\n"; + responseStream << "\t\t\t\t

    skipped

    \n"; + responseStream << "\t\t\t"; +#line 342 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } else { + auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy(); + auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false); + if(!transaction6.size()) { + responseStream << "\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t\treport_problem\n"; + responseStream << "\t\t\t\t\tError creating Transaction\n"; + responseStream << "\t\t\t\t
    \n"; + responseStream << "\t\t\t\t"; +#line 351 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + + } else { + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction6[0]->sign(user_2); + auto transaction6_json = transaction6[0]->getTransactionAsJson(true); + responseStream << "\n"; + responseStream << "\t\t\t\t\t

    "; +#line 357 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( DataTypeConverter::replaceNewLineWithBr(transaction6_json) ); + responseStream << "

    \t\t\n"; + responseStream << "\t\t\t\t"; +#line 358 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << "\n"; + responseStream << "\t\t\t"; +#line 359 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + } responseStream << " \n"; + responseStream << "\t\t\t

    Time: "; +#line 360 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + responseStream << ( time2.string() ); + responseStream << "

    \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t
  • \n"; + responseStream << "\t\t\t

    8. Wait "; +#line 363 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( hedera_timeout ); responseStream << " seconds to give hedera time to process transactions

    \n"; responseStream << "\t\t\t"; -#line 252 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" - if(!steps[4]) { responseStream << "\n"; +#line 364 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" + if(!steps[6]) { responseStream << "\n"; responseStream << "\t\t\t\t

    skipped

    \n"; responseStream << "\t\t\t"; -#line 254 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 366 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { Poco::Thread::sleep(hedera_timeout * 1000); } responseStream << "\n"; responseStream << "\t\t
  • \n"; responseStream << "\t\t
  • \n"; - responseStream << "\t\t\t

    7. Ask choosen node for transaction and print result

    \n"; + responseStream << "\t\t\t

    9. Ask choosen node for transaction and print result

    \n"; responseStream << "\t\t\t"; -#line 260 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 372 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" time2.reset(); - if(!steps[5] || node_server.isNull()) { + if(!steps[7] || node_server.isNull()) { responseStream << "

    skipped

    \n"; responseStream << "\t\t\t"; -#line 263 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 375 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else { auto node_server_model = node_server->getModel(); JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort()); @@ -559,20 +770,20 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); std::string answear_string = ss.str(); responseStream << "\n"; responseStream << "\t\t\t\t\t"; -#line 274 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 386 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 274 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 386 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } } responseStream << "\n"; responseStream << "\t\t\t

    Time: "; -#line 277 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 389 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time2.string() ); responseStream << "

    \n"; responseStream << "\t\t
  • \n"; responseStream << "\t
\n"; responseStream << "\t"; -#line 280 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 392 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) { Profiler time3; auto node_server_model = node_server->getModel(); @@ -587,23 +798,23 @@ void AdminNodeServerTestPage::handleRequest(Poco::Net::HTTPServerRequest& reques Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER); std::string answear_string = ss.str(); responseStream << "\n"; responseStream << "\t\t\t"; -#line 293 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 405 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( DataTypeConverter::replaceNewLineWithBr(answear_string) ); -#line 293 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 405 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\t

Time: "; -#line 296 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 408 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" responseStream << ( time3.string() ); responseStream << "

\n"; responseStream << "\t"; -#line 297 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" +#line 409 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminNodeServerTest.cpsp" } responseStream << "\n"; responseStream << "\t\n"; responseStream << "
\n"; responseStream << "\n"; // begin include footer.cpsp diff --git a/src/cpp/lib/DataTypeConverter.cpp b/src/cpp/lib/DataTypeConverter.cpp index eed9967a8..62417f638 100644 --- a/src/cpp/lib/DataTypeConverter.cpp +++ b/src/cpp/lib/DataTypeConverter.cpp @@ -304,6 +304,13 @@ namespace DataTypeConverter return microseconds; } + Poco::Timestamp convertFromProtoTimestamp(const proto::gradido::Timestamp& timestamp) + { + // microseconds + google::protobuf::int64 microseconds = timestamp.seconds() * (google::protobuf::int64)10e5 + (google::protobuf::int64)(timestamp.nanos()) / (google::protobuf::int64)10e2; + return microseconds; + } + void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::Timestamp* protoTimestamp) { auto microsecondsTotal = pocoTimestamp.epochMicroseconds(); diff --git a/src/cpp/lib/DataTypeConverter.h b/src/cpp/lib/DataTypeConverter.h index e4a0487fe..38249f740 100644 --- a/src/cpp/lib/DataTypeConverter.h +++ b/src/cpp/lib/DataTypeConverter.h @@ -56,6 +56,7 @@ namespace DataTypeConverter { std::string convertTimespanToLocalizedString(Poco::Timespan duration, LanguageCatalog* lang); Poco::Timestamp convertFromProtoTimestamp(const proto::Timestamp& timestamp); + Poco::Timestamp convertFromProtoTimestamp(const proto::gradido::Timestamp& timestamp); void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::Timestamp* protoTimestamp); void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::gradido::Timestamp* protoTimestamp); Poco::Timestamp convertFromProtoTimestampSeconds(const proto::gradido::TimestampSeconds& timestampSeconds); diff --git a/src/cpp/model/gradido/Transaction.cpp b/src/cpp/model/gradido/Transaction.cpp index 2207da9e7..70fc217cb 100644 --- a/src/cpp/model/gradido/Transaction.cpp +++ b/src/cpp/model/gradido/Transaction.cpp @@ -136,17 +136,24 @@ namespace model { else { auto sender_group = controller::Group::load(sender_model->getGroupId()); + if (sender_group.isNull()) + { + em->addError(new ParamError(function_name, "couldn't find group with id: ", sender_model->getGroupId())); + em->sendErrorsAsEmail(); + return results; + } Poco::AutoPtr transaction_group; Poco::AutoPtr topic_group; // default constructor set it to now Poco::Timestamp pairedTransactionId; // create only inbound transaction, and outbound before sending to hedera //for (int i = 0; i < 1; i++) { - if (inbound) { + if (!inbound) { transaction_group = receiverGroup; topic_group = sender_group; } - else if(!inbound) { + // transaction send to receiver blockchain + else if(inbound) { transaction_group = sender_group; topic_group = receiverGroup; } @@ -166,20 +173,107 @@ namespace model { auto body = TransactionBody::create(memo, sender, receiverPubkey, amount, pairedTransactionId, transaction_group); Poco::AutoPtr transaction = new Transaction(body); transaction->getModel()->setHederaId(topic_id->getModel()->getID()); + auto transfer_transaction = transaction->getTransactionBody()->getTransferTransaction(); + transfer_transaction->setOwnGroupAlias(sender_group->getModel()->getAlias()); + transfer_transaction->setTargetGroupAlias(receiverGroup->getModel()->getAlias()); + results.push_back(transaction); // } } + for (auto it = results.begin(); it != results.end(); it++) { - (*it)->insertPendingTaskIntoDB(sender, model::table::TASK_TYPE_TRANSFER); - PendingTasksManager::getInstance()->addTask(*it); + if (!(*it)->getTransactionBody()->getTransferTransaction()->isInbound()) { + (*it)->insertPendingTaskIntoDB(sender, model::table::TASK_TYPE_TRANSFER); + PendingTasksManager::getInstance()->addTask(*it); + } } + return results; } - + bool Transaction::setTopicIdByGroup(const std::string& alias) + { + static const char* function_name = "Transaction::setTopicIdByGroup"; + auto topic_groups = controller::Group::load(alias); + if (topic_groups.size() != 1) { + addError(new ParamError(function_name, "not one group found for alias: ", alias)); + sendErrorsAsEmail(); + return false; + } + auto topic = controller::HederaId::find(topic_groups[0]->getModel()->getID(), ServerConfig::g_HederaNetworkType); + if (topic.isNull()) { + addError(new ParamError(function_name, "no topic found for group id", topic_groups[0]->getModel()->getID())); + addError(new ParamError(function_name, "and network type: ", ServerConfig::g_HederaNetworkType)); + sendErrorsAsEmail(); + return false; + } + getModel()->setHederaId(topic->getModel()->getID()); + return true; + } + + Poco::AutoPtr Transaction::createTransfer(const MemoryBin* senderPubkey, Poco::AutoPtr receiver, std::string senderGroupAlias, Poco::UInt32 amount, const std::string& memo) + { + Poco::AutoPtr result; + auto em = ErrorManager::getInstance(); + static const char* function_name = "Transaction::create transfer 2"; + + if (receiver.isNull() || !receiver->getModel() || !senderPubkey || !amount) { + return result; + } + + //std::vector> bodys; + auto receiver_model = receiver->getModel(); + auto network_type = ServerConfig::g_HederaNetworkType; + + auto sender_groups = controller::Group::load(senderGroupAlias); + if (!sender_groups.size()) { + em->addError(new ParamError(function_name, "couldn't find group", senderGroupAlias)); + em->sendErrorsAsEmail(); + return result; + } + Poco::AutoPtr transaction_group; + Poco::AutoPtr topic_group = controller::Group::load(receiver_model->getGroupId()); + if (topic_group.isNull()) { + em->addError(new ParamError(function_name, "topic group not found", receiver_model->getGroupId())); + em->sendErrorsAsEmail(); + return result; + } + // default constructor set it to now + Poco::Timestamp pairedTransactionId; + // create only inbound transaction, and outbound before sending to hedera + //for (int i = 0; i < 1; i++) { + + //transaction_group = receiverGroup; + //topic_group = sender_group; + + auto topic_id = controller::HederaId::find(topic_group->getModel()->getID(), network_type); + if (topic_id.isNull()) { + em->addError(new ParamError(function_name, "could'n find topic for group: ", receiver_model->getGroupId())); + em->addError(new ParamError(function_name, "network type: ", network_type)); + em->sendErrorsAsEmail(); + return result; + } + if (transaction_group.isNull()) { + em->addError(new Error(function_name, "transaction group is zero, inbound")); + em->sendErrorsAsEmail(); + return result; + } + + auto body = TransactionBody::create(memo, senderPubkey, receiver, amount, pairedTransactionId, transaction_group); + result = new Transaction(body); + result->getModel()->setHederaId(topic_id->getModel()->getID()); + + // } + + //result->insertPendingTaskIntoDB(receiver, model::table::TASK_TYPE_TRANSFER); + //PendingTasksManager::getInstance()->addTask(result); + + return result; + } + Poco::AutoPtr Transaction::load(model::table::PendingTask* dbModel) { @@ -313,9 +407,18 @@ namespace model { { if (getTransactionBody()->isTransfer()) { auto transfer = getTransactionBody()->getTransferTransaction(); - if (transfer->isInbound()) { - auto transaction = transfer->createOutbound(getTransactionBody()->getMemo()); - transaction->sign(user); + if (transfer->isOutbound()) { + auto transaction = transfer->createInbound(getTransactionBody()->getMemo()); + if (!transaction.isNull()) { + transaction->sign(user); + // dirty hack because gn crashes if its get transactions out of order + Poco::Thread::sleep(1000); + } + else { + addError(new Error(function_name, "Error creating outbound transaction")); + return false; + } + } } UniLib::controller::TaskPtr transaction_send_task(new SendTransactionTask(Poco::AutoPtr(this, true))); diff --git a/src/cpp/model/gradido/Transaction.h b/src/cpp/model/gradido/Transaction.h index c135fd89f..c8147a6a1 100644 --- a/src/cpp/model/gradido/Transaction.h +++ b/src/cpp/model/gradido/Transaction.h @@ -31,6 +31,7 @@ namespace model { //! \brief transfer //! \return for cross group transaction return two transactions static std::vector> createTransfer(Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo, bool inbound = true); + Poco::AutoPtr createTransfer(const MemoryBin* senderPubkey, Poco::AutoPtr receiver, std::string senderGroupAlias, Poco::UInt32 amount, const std::string& memo); //! \brief creation transaction static Poco::AutoPtr createCreation(Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::DateTime targetDate, const std::string& memo); static Poco::AutoPtr load(model::table::PendingTask* dbModel); @@ -60,6 +61,8 @@ namespace model { std::string getTransactionAsJson(bool replaceBase64WithHex = false); + bool setTopicIdByGroup(const std::string& alias); + protected: diff --git a/src/cpp/model/gradido/TransactionBody.cpp b/src/cpp/model/gradido/TransactionBody.cpp index 3859ef969..2e69085e0 100644 --- a/src/cpp/model/gradido/TransactionBody.cpp +++ b/src/cpp/model/gradido/TransactionBody.cpp @@ -61,7 +61,7 @@ namespace model { { auto group_model = group->getModel(); proto::gradido::CrossGroupTransfer* cross_group_transfer = nullptr; - if (group->getModel()->getID() == sender->getModel()->getGroupId()) { + if (group->getModel()->getID() != sender->getModel()->getGroupId()) { cross_group_transfer = gradido_transfer->mutable_outbound(); } else { @@ -84,6 +84,95 @@ namespace model { return obj; } + Poco::AutoPtr TransactionBody::create(const std::string& memo, const MemoryBin* senderPublicKey, Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId /*= Poco::Timestamp()*/, Poco::AutoPtr group/* = nullptr*/) + { + if (receiver.isNull() || !receiver->getModel()) { + return nullptr; + } + auto receiver_model = receiver->getModel(); + + + Poco::AutoPtr obj = new TransactionBody; + obj->mTransactionBody.set_memo(memo); + auto gradido_transfer = obj->mTransactionBody.mutable_transfer(); + proto::gradido::TransferAmount* transfer_amount = nullptr; + std::string* sender = nullptr; + + auto group_model = group->getModel(); + proto::gradido::CrossGroupTransfer* cross_group_transfer = nullptr; + + cross_group_transfer = gradido_transfer->mutable_inbound(); + + transfer_amount = cross_group_transfer->mutable_sender(); + sender = transfer_amount->mutable_pubkey(); + auto paired_transaction_id = cross_group_transfer->mutable_paired_transaction_id(); + DataTypeConverter::convertToProtoTimestamp(pairedTransactionId, paired_transaction_id); + cross_group_transfer->set_other_group(group_model->getAlias()); + + transfer_amount->set_amount(amount); + transfer_amount->set_pubkey(senderPublicKey, KeyPairEd25519::getPublicKeySize()); + cross_group_transfer->set_receiver(receiver_model->getPublicKey(), receiver_model->getPublicKeySize()); + *sender = std::string((const char*)senderPublicKey->data(), senderPublicKey->size()); + + obj->mType = TRANSACTION_TRANSFER; + obj->mTransactionSpecific = new TransactionTransfer(memo, obj->mTransactionBody.transfer()); + obj->mTransactionSpecific->prepare(); + + return obj; + } + + Poco::AutoPtr TransactionBody::create(const std::string& memo, const MemoryBin* senderPublicKey, const MemoryBin* receiverPublicKey, Poco::UInt32 amount, const std::string groupAlias, TransactionTransferType transferType, Poco::Timestamp pairedTransactionId/* = Poco::Timestamp()*/) + { + assert(transferType == TRANSFER_CROSS_GROUP_INBOUND || transferType == TRANSFER_CROSS_GROUP_OUTBOUND || transferType == TRANSFER_LOCAL); + if (!senderPublicKey || !receiverPublicKey) { + return nullptr; + } + + Poco::AutoPtr obj = new TransactionBody; + obj->mTransactionBody.set_memo(memo); + auto gradido_transfer = obj->mTransactionBody.mutable_transfer(); + proto::gradido::TransferAmount* transfer_amount = nullptr; + proto::gradido::CrossGroupTransfer* cross_group_transfer = nullptr; + proto::gradido::LocalTransfer* local_transfer = nullptr; + + switch (transferType) + { + case TRANSFER_CROSS_GROUP_INBOUND: + cross_group_transfer = gradido_transfer->mutable_inbound(); + break; + case TRANSFER_CROSS_GROUP_OUTBOUND: + cross_group_transfer = gradido_transfer->mutable_outbound(); + break; + case TRANSFER_LOCAL: + local_transfer = gradido_transfer->mutable_local(); + break; + } + + + if (local_transfer) { + transfer_amount = local_transfer->mutable_sender(); + local_transfer->set_receiver((const char*)receiverPublicKey->data(), receiverPublicKey->size()); + } + else if (cross_group_transfer) { + transfer_amount = cross_group_transfer->mutable_sender(); + auto paired_transaction_id = cross_group_transfer->mutable_paired_transaction_id(); + DataTypeConverter::convertToProtoTimestamp(pairedTransactionId, paired_transaction_id); + cross_group_transfer->set_other_group(groupAlias); + + cross_group_transfer->set_receiver((const char*)receiverPublicKey->data(), receiverPublicKey->size()); + } + + + transfer_amount->set_amount(amount); + transfer_amount->set_pubkey((const unsigned char*)senderPublicKey->data(), senderPublicKey->size()); + + obj->mType = TRANSACTION_TRANSFER; + obj->mTransactionSpecific = new TransactionTransfer(memo, obj->mTransactionBody.transfer()); + obj->mTransactionSpecific->prepare(); + + return obj; + } + Poco::AutoPtr TransactionBody::create(const std::string& memo, Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::DateTime targetDate) { if (receiver.isNull() || !receiver->getModel()) { diff --git a/src/cpp/model/gradido/TransactionBody.h b/src/cpp/model/gradido/TransactionBody.h index 9d026ecf9..f88344eb2 100644 --- a/src/cpp/model/gradido/TransactionBody.h +++ b/src/cpp/model/gradido/TransactionBody.h @@ -34,6 +34,8 @@ namespace model { //! \param group if group.isNull() it is a local transfer, else cross group transfer, //! \param group if group is same as sender group outbound, else inbound static Poco::AutoPtr create(const std::string& memo, Poco::AutoPtr sender, const MemoryBin* receiverPublicKey, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId = Poco::Timestamp(), Poco::AutoPtr group = nullptr); + static Poco::AutoPtr create(const std::string& memo, const MemoryBin* senderPublicKey, Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::Timestamp pairedTransactionId = Poco::Timestamp(), Poco::AutoPtr group = nullptr); + static Poco::AutoPtr create(const std::string& memo, const MemoryBin* senderPublicKey, const MemoryBin* receiverPublicKey, Poco::UInt32 amount, const std::string groupAlias, TransactionTransferType transferType, Poco::Timestamp pairedTransactionId = Poco::Timestamp()); //! \brief GradidoCreation Transaction static Poco::AutoPtr create(const std::string& memo, Poco::AutoPtr receiver, Poco::UInt32 amount, Poco::DateTime targetDate); diff --git a/src/cpp/model/gradido/TransactionTransfer.cpp b/src/cpp/model/gradido/TransactionTransfer.cpp index 6dfff3c6e..6e458a87a 100644 --- a/src/cpp/model/gradido/TransactionTransfer.cpp +++ b/src/cpp/model/gradido/TransactionTransfer.cpp @@ -1,5 +1,7 @@ #include "TransactionTransfer.h" #include "Transaction.h" +#include "../../SingletonManager/ErrorManager.h" +#include "../../controller/HederaId.h" namespace model { namespace gradido { @@ -204,26 +206,63 @@ namespace model { { const char* function_name = "TransactionTransfer::createOutbound"; auto mm = MemoryManager::getInstance(); + auto em = ErrorManager::getInstance(); if (!mProtoTransfer.has_inbound()) { return nullptr; } // Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo //Transaction::createTransfer() auto inbound = mProtoTransfer.inbound(); - auto sender = controller::User::create(); - if (1 != sender->load((const unsigned char*)inbound.sender().pubkey().data())) { - return nullptr; - } + + auto sender_pubkey = mm->getFreeMemory(inbound.sender().pubkey().size()); + memcpy(*sender_pubkey, inbound.sender().pubkey().data(), inbound.sender().pubkey().size()); auto receiver_pubkey = mm->getFreeMemory(inbound.receiver().size()); memcpy(*receiver_pubkey, inbound.receiver().data(), inbound.receiver().size()); - auto groups = controller::Group::load(inbound.other_group()); - if (1 != groups.size()) { + + auto body = TransactionBody::create( + memo, sender_pubkey, receiver_pubkey, + inbound.sender().amount(), mTargetGroupAlias, TRANSFER_CROSS_GROUP_OUTBOUND, + DataTypeConverter::convertFromProtoTimestamp(inbound.paired_transaction_id()) + ); + + auto transaction = Poco::AutoPtr(new Transaction(body)); + transaction->setTopicIdByGroup(mOwnGroupAlias); + + mm->releaseMemory(receiver_pubkey); + mm->releaseMemory(sender_pubkey); + return transaction; + + } + + Poco::AutoPtr TransactionTransfer::createInbound(const std::string& memo) + { + const char* function_name = "TransactionTransfer::createInbound"; + auto mm = MemoryManager::getInstance(); + + if (!mProtoTransfer.has_outbound()) { return nullptr; } - auto transaction = Transaction::createTransfer(sender, receiver_pubkey, groups[0], inbound.sender().amount(), memo, false); - mm->releaseMemory(receiver_pubkey); - return transaction[0]; + // Poco::AutoPtr sender, const MemoryBin* receiverPubkey, Poco::AutoPtr receiverGroup, Poco::UInt32 amount, const std::string& memo + //Transaction::createTransfer() + auto outbound = mProtoTransfer.outbound(); + auto sender_pubkey = mm->getFreeMemory(outbound.sender().pubkey().size()); + memcpy(*sender_pubkey, outbound.sender().pubkey().data(), outbound.sender().pubkey().size()); + auto receiver_pubkey = mm->getFreeMemory(outbound.receiver().size()); + memcpy(*receiver_pubkey, outbound.receiver().data(), outbound.receiver().size()); + + auto body = TransactionBody::create( + memo, sender_pubkey, receiver_pubkey, + outbound.sender().amount(), mOwnGroupAlias, TRANSFER_CROSS_GROUP_INBOUND, + DataTypeConverter::convertFromProtoTimestamp(outbound.paired_transaction_id()) + ); + + auto transaction = Poco::AutoPtr(new Transaction(body)); + transaction->setTopicIdByGroup(mTargetGroupAlias); + + mm->releaseMemory(receiver_pubkey); + mm->releaseMemory(sender_pubkey); + return transaction; } const std::string& TransactionTransfer::getKontoNameCell(int index) diff --git a/src/cpp/model/gradido/TransactionTransfer.h b/src/cpp/model/gradido/TransactionTransfer.h index 558c8a7db..57259059f 100644 --- a/src/cpp/model/gradido/TransactionTransfer.h +++ b/src/cpp/model/gradido/TransactionTransfer.h @@ -22,6 +22,13 @@ namespace model { class Transaction; + enum TransactionTransferType + { + TRANSFER_LOCAL, + TRANSFER_CROSS_GROUP_INBOUND, + TRANSFER_CROSS_GROUP_OUTBOUND + }; + class TransactionTransfer : public TransactionBase { public: @@ -37,10 +44,15 @@ namespace model { std::string getTargetGroupAlias(); bool isInbound() { return mProtoTransfer.has_inbound(); } + bool isOutbound() { return mProtoTransfer.has_outbound(); } Poco::AutoPtr createOutbound(const std::string& memo); + Poco::AutoPtr createInbound(const std::string& memo); void transactionAccepted(Poco::AutoPtr user); + inline void setOwnGroupAlias(const std::string& ownGroupAlias) { mOwnGroupAlias = ownGroupAlias; } + inline void setTargetGroupAlias(const std::string& targetGroupAlias) { mTargetGroupAlias = targetGroupAlias; } + protected: const static std::string mInvalidIndexMessage; @@ -62,6 +74,8 @@ namespace model { const proto::gradido::GradidoTransfer& mProtoTransfer; std::vector mKontoTable; + std::string mOwnGroupAlias; + std::string mTargetGroupAlias; }; } } diff --git a/src/cpsp/adminNodeServerTest.cpsp b/src/cpsp/adminNodeServerTest.cpsp index f504caa0d..6bebc8c06 100644 --- a/src/cpsp/adminNodeServerTest.cpsp +++ b/src/cpsp/adminNodeServerTest.cpsp @@ -29,11 +29,14 @@ enum PageType const char* pageName = "Node Server Test"; PageType page = PAGE_CHOOSE_TEST; Poco::AutoPtr node_server; + Poco::AutoPtr node_server2; Poco::AutoPtr user; Poco::AutoPtr hedera_topic; - int hedera_timeout = 9; + Poco::AutoPtr hedera_topic2; + int hedera_timeout = 4; + int sleep_ms_between_transactions = 1000; - bool steps[6]; memset(steps, 1, 6 * sizeof(bool)); + bool steps[8]; memset(steps, 1, 8 * sizeof(bool)); if(!form.empty()) @@ -45,6 +48,13 @@ enum PageType node_server = controller::NodeServer::load(node_server_id); } } + node_server_id_string = form.get("test-node-servers2", ""); + if(node_server_id_string != "") { + int node_server_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(node_server_id_string, node_server_id )) { + node_server2 = controller::NodeServer::load(node_server_id); + } + } auto topic_id_string = form.get("test-hedera-topic", ""); if(topic_id_string != "") { int topic_id = 0; @@ -52,18 +62,25 @@ enum PageType hedera_topic = controller::HederaTopic::load(topic_id); } } + topic_id_string = form.get("test-hedera-topic2", ""); + if(topic_id_string != "") { + int topic_id = 0; + if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) { + hedera_topic2 = controller::HederaTopic::load(topic_id); + } + } auto test_timeout_string = form.get("test-timeout", ""); if(test_timeout_string != "") { DataTypeConverter::strToInt(test_timeout_string, hedera_timeout); } auto submit = form.get("submit", ""); - if(submit == "Run 4-Test") { + if(submit == "Run 6-Test") { page = PAGE_RUN_4_SET_TEST; } else if(submit == "json-rpc getTransactions") { page = PAGE_GET_TRANSACTION_RPC_CALL; } std::string step_temp; - for(int i = 0; i < 6; i++) { + for(int i = 0; i < 8; i++) { std::string name = "step-"; name += std::to_string(i+2); step_temp = form.get(name, ""); @@ -83,52 +100,86 @@ enum PageType
- +
style="display:block" <% } %>>
-

Test 4-Set (2 AddMember, Creation, Transfer) +

Test 6-Set (3 AddMember, Creation, 2 Transfer)

-

1. Create two new accounts and show user public keys for comparisation

+

1. Create three new accounts and show user public keys for comparisation

checked="checked" <% } %> name="step-2" value="1"/> 2. Send a add-member transaction to hedera topic with one signature (first user)

checked="checked" <% } %> name="step-3" value="1"/> 3. Send a add-member transaction to hedera topic with two signatures (first user and second user)

checked="checked" <% } %> name="step-4" value="1"/> 4. Send a creation transaction to second user, signed by first user

checked="checked" <% } %> name="step-5" value="1"/> 5. Send a transfer transaction from second user to first user signed by second user

-

checked="checked" <% } %> name="step-6" value="1"/> 6. Wait x seconds to give hedera time to process transactions

-

checked="checked" <% } %> name="step-7" value="1"/> 7. Ask choosen node for transaction and print result

- - - <% if(node_servers.size() == 0) { %> - Edit Node-Servers - <% } %> - checked="checked" <% } %> name="step-6" value="1"/> 6. Send a add-member transaction to hedera topic 2 with one signature (third user)

+

checked="checked" <% } %> name="step-7" value="1"/> 7. Send a cross group transfer from second user to third user signed by second user

+

checked="checked" <% } %> name="step-8" value="1"/> 8. Wait x seconds to give hedera time to process transactions

+

checked="checked" <% } %> name="step-9" value="1"/> 9. Ask choosen node for transaction and print result

+
+ Group 1 + + <% if(node_servers.size() == 0) { %> + Edit Node-Servers <% } %> - - - <% if(hedera_topics.size() == 0) { %> - Edit Hedera-Topics - <% } %> - + <% for(auto it = node_servers.begin(); it != node_servers.end(); it++) { + auto model = (*it)->getModel(); + %> + + <% } %> + + + <% if(hedera_topics.size() == 0) { %> + Edit Hedera-Topics <% } %> - + +
+
+ Group 2 + + <% if(node_servers.size() == 0) { %> + Edit Node-Servers + <% } %> + + + <% if(hedera_topics.size() == 0) { %> + Edit Hedera-Topics + <% } %> + +
+ seconds - +
@@ -156,11 +207,13 @@ enum PageType <% if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { %>
  • -

    1. Create two new accounts and show user public keys for comparisation:

    +

    1. Create three new accounts and show user public keys for comparisation:

    <% Profiler time2; auto group_id = hedera_topic->getModel()->getGroupId(); + auto group_id2 = hedera_topic2->getModel()->getGroupId(); auto user_group = controller::Group::load(group_id); + auto user_group2 = controller::Group::load(group_id2); auto mnemonic_type = ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; std::string password1 = "hsaj(2askaslASlllak3wjjeudsaj"; @@ -176,9 +229,21 @@ enum PageType auto gradido_key_pair_2 = KeyPairEd25519::create(passphrase_2); user_2->setGradidoKeyPair(gradido_key_pair_2); user_2->login(password2); + + std::string password3 = "jaue_skaiellasealaK"; + auto user_3 = controller::User::create("testEmail3@gmail.com", "Morpheus", "Miaufull", group_id2); + auto passphrase_3 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]); + auto gradido_key_pair_3 = KeyPairEd25519::create(passphrase_3); + user_3->setGradidoKeyPair(gradido_key_pair_3); + user_3->login(password3); %> -

    User 1: <%= user_1->getPublicHex() %>

    -

    User 2: <%= user_2->getPublicHex() %>

    +
    <%= user_group->getModel()->getName() %> +

    User 1: <%= user_1->getPublicHex() %>

    +

    User 2: <%= user_2->getPublicHex() %>

    +
    +
    <%= user_group2->getModel()->getName() %> +

    User 3: <%= user_3->getPublicHex() %>

    +

    Time: <%= time2.string() %>

  • @@ -207,6 +272,8 @@ enum PageType auto transaction2 = model::gradido::Transaction::createGroupMemberUpdate(user_2, user_group); transaction2->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(2); transaction2->sign(user_2); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); transaction2->sign(user_1); auto transaction2_json = transaction2->getTransactionAsJson(true); %> @@ -222,6 +289,8 @@ enum PageType

    skipped

    <% } else { auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation"); + // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time + Poco::Thread::sleep(sleep_ms_between_transactions); transaction3->sign(user_1); auto transaction3_json = transaction3->getTransactionAsJson(true); %> @@ -239,7 +308,7 @@ enum PageType auto user_1_pubkey = user_1->getModel()->getPublicKeyCopy(); auto transaction4 = model::gradido::Transaction::createTransfer(user_2, user_1_pubkey, user_group, 5000000, "Test Transfer"); // wait before sending fourth transaction, gn seems to crash by more than 3 transaction at nearly the same time - Poco::Thread::sleep(hedera_timeout * 100); + Poco::Thread::sleep(sleep_ms_between_transactions); transaction4[0]->sign(user_2); auto transaction4_json = transaction4[0]->getTransactionAsJson(true); %> @@ -248,17 +317,60 @@ enum PageType

    Time: <%= time2.string() %>

  • -

    6. Wait <%= hedera_timeout %> seconds to give hedera time to process transactions

    - <% if(!steps[4]) { %> +

    6. Send a add-member transaction to hedera topic 2 with one signature (third user)

    + <% + time2.reset(); + if(!steps[4]) { %> +

    skipped

    + <% } else { + auto transaction5 = model::gradido::Transaction::createGroupMemberUpdate(user_3, user_group2); + transaction5->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1); + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction5->sign(user_3); + auto transaction5_json = transaction5->getTransactionAsJson(true); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction5_json) %>

    + <% } %> +

    Time: <%= time2.string() %>

    +
  • +
  • +

    7. Send a cross group transfer from second user to third user signed by second user

    + <% + time2.reset(); + if(!steps[5]) { %> +

    skipped

    + <% } else { + auto user_3_pubkey = user_3->getModel()->getPublicKeyCopy(); + auto transaction6 = model::gradido::Transaction::createTransfer(user_2, user_3_pubkey, user_group2, 4000000, "Test Group Transfer", false); + if(!transaction6.size()) { + %> + + <% + } else { + Poco::Thread::sleep(sleep_ms_between_transactions); + transaction6[0]->sign(user_2); + auto transaction6_json = transaction6[0]->getTransactionAsJson(true); + %> +

    <%= DataTypeConverter::replaceNewLineWithBr(transaction6_json) %>

    + <% } %> + <% } %> +

    Time: <%= time2.string() %>

    +
  • +
  • +

    8. Wait <%= hedera_timeout %> seconds to give hedera time to process transactions

    + <% if(!steps[6]) { %>

    skipped

    <% } else { Poco::Thread::sleep(hedera_timeout * 1000); } %>
  • -

    7. Ask choosen node for transaction and print result

    +

    9. Ask choosen node for transaction and print result

    <% time2.reset(); - if(!steps[5] || node_server.isNull()) { + if(!steps[7] || node_server.isNull()) { %>

    skipped

    <% } else { auto node_server_model = node_server->getModel();