add receipt query debug message

This commit is contained in:
Dario 2020-11-28 13:18:32 +01:00 committed by Ulf Gebhardt
parent bfe4f6ad01
commit 29861a142b
No known key found for this signature in database
GPG Key ID: 81308EFE29ABFEBD
28 changed files with 735 additions and 227 deletions

View File

@ -3,6 +3,7 @@ Poco/1.9.4@pocoproject/stable
libsodium/1.0.18@bincrafters/stable
boost/1.71.0@conan/stable
gtest/1.8.1@bincrafters/stable
mpfr/4.1.0
[generators]
cmake

View File

@ -12,6 +12,5 @@ CREATE TABLE `hedera_topics` (
`running_hash` VARBINARY(64) DEFAULT NULL,
`running_hash_version` int unsigned DEFAULT 0,
`updated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `topic_hedera_id` (`topic_hedera_id`)
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -46,8 +46,9 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
Profiler hedera_time;
std::string name = "";
std::string topic_id_string = "";
int auto_renew_account = 0;
int auto_renew_period = 604800; // 7 Tage
int auto_renew_period = 7890000; // 3 Monate
int group_id = 0;
@ -94,9 +95,19 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
else if(!form.empty())
{
name = form.get("topic-name", "");
topic_id_string = form.get("topic-id", "");
auto auto_renew_account_string = form.get("topic-auto-renew-account", "0");
auto auto_renew_period_string = form.get("topic-auto-renew-period", "604800");
auto auto_renew_period_string = form.get("topic-auto-renew-period", "7890000");
auto group_id_string = form.get("topic-group", "-1");
Poco::AutoPtr<controller::HederaId> topic_id;
if(topic_id_string != "" && sm->isValid(topic_id_string, VALIDATE_HEDERA_ID)) {
topic_id = controller::HederaId::create(topic_id_string);
if(topic_id.isNull()) {
addError(new Error("Hedera Id", "cannot parse hedera id"));
}
} else {
if(name != "" && !sm->isValid(name, VALIDATE_NAME)) {
addError(new Error("Topic", "Name not valid, at least 3 Character"));
@ -117,6 +128,7 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
addError(new Error("Int convert error", "Error converting auto renew period to int"));
}
}
}
if(!sm->isValid(group_id_string, VALIDATE_ONLY_INTEGER)) {
addError(new Error("Topic", "group_id not an integer"));
@ -127,6 +139,21 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
}
//const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId
// add or create topic?
// add topic
if(!topic_id.isNull()) {
if(topic_id->getModel()->insertIntoDB(true)) {
auto hedera_topic = controller::HederaTopic::loadFromHedera(topic_id, group_id, user);
if(!hedera_topic.isNull()) {
hedera_topic->getModel()->insertIntoDB(false);
} else {
addError(new Error("Hedera Topic", "error load topic from hedera"));
}
} else {
addError(new Error("Hedera Id", "Error saving hedera id"));
}
// create topic
} else {
auto hedera_topic = controller::HederaTopic::create(name, auto_renew_account, auto_renew_period, group_id);
if(!hedera_topic->getModel()->insertIntoDB(true)) {
addError(new Error("Topic", "error saving into db"));
@ -142,7 +169,7 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
}
}
}
}
}
@ -227,7 +254,7 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "\t}\n";
responseStream << "\t\n";
responseStream << "</style>\n";
#line 152 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 180 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( getErrorsHtml() );
responseStream << "\n";
responseStream << "<div class=\"content-container info-container\">\n";
@ -240,7 +267,7 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "\t\t</div>\t\n";
responseStream << "\t\t<div class=\"content-list-table\">\n";
responseStream << "\t\t\t<div class=\"row\">\n";
responseStream << "\t\t\t\t<div class=\"cell header-cell c2\">Topic ID</div>\t\t\t\n";
responseStream << "\t\t\t\t<div class=\"cell header-cell c3\">Topic ID</div>\t\t\t\n";
responseStream << "\t\t\t\t<div class=\"cell header-cell c3\">Name</div>\n";
responseStream << "\t\t\t\t<div class=\"cell header-cell c3\">Network Type</div>\n";
responseStream << "\t\t\t\t<div class=\"cell header-cell c4\">Auto Renew Account Balance</div>\n";
@ -252,7 +279,7 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "\t\t\t\t<div class=\"cell header-cell c5\">Aktionen</div>\n";
responseStream << "\t\t\t</div>\n";
responseStream << "\t\t\t";
#line 174 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 202 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
for(auto it = hedera_topics.begin(); it != hedera_topics.end(); it++) {
auto hedera_topic_model = (*it)->getModel();
auto updateUrl = ServerConfig::g_serverPath + "/topic?action=getTopicInfos&topic_id=" + std::to_string(hedera_topic_model->getID());
@ -272,138 +299,192 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
responseStream << "\n";
responseStream << "\t\t\t\t<div class=\"row\">\n";
responseStream << "\t\t\t\t\t<div class=\"cell c2\">";
#line 193 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t\t\t\t\t<div class=\"cell c3\">";
#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( topic_hedera_id_string );
responseStream << "</div>\n";
responseStream << "\t\t\t\t\t<div class=\"cell c3\">";
#line 194 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 222 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( hedera_topic_model->getName() );
responseStream << "</div>\n";
responseStream << "\t\t\t\t\t<div class=\"cell c3\">";
#line 195 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 223 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(renew_account_model->getNetworkType()) );
responseStream << "</div>\n";
responseStream << "\t\t\t\t\t<div class=\"cell c4\">";
#line 196 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 224 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( renew_account_model->getBalanceString() );
responseStream << "</div>\n";
responseStream << "\t\t\t\t\t<div class=\"cell c4\">";
#line 197 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( hedera_topic_model->getAutoRenewPeriodString() );
responseStream << "</div>\n";
responseStream << "\t\t\t\t\t<div class=\"cell c3\">";
#line 198 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 226 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( hedera_topic_model->getGroupId() );
responseStream << "</div>\n";
responseStream << "\t\t\t\t\t<div class=\"cell c3 ";
#line 199 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( timeout_color );
responseStream << "\">";
#line 199 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( hedera_topic_model->getCurrentTimeoutString() );
responseStream << "</div>\n";
responseStream << "\t\t\t\t\t<div class=\"cell c2\">";
#line 200 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 228 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( hedera_topic_model->getSequenceNumber() );
responseStream << "</div>\n";
responseStream << "\t\t\t\t\t<div class=\"cell c3\">";
#line 201 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 229 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( hedera_topic_model->getUpdatedString() );
responseStream << "</div>\n";
responseStream << "\t\t\t\t\t<div class=\"cell c5\">";
#line 202 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 230 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
if(!topic_hedera_id.isNull()) { responseStream << "\n";
responseStream << "\t\t\t\t\t\t<button class=\"form-button\" title=\"Query on Hedera, cost some fees\" onclick=\"window.location.href='";
#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 231 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( updateUrl );
responseStream << "'\" >\n";
responseStream << "\t\t\t\t\t\t\tget topic infos\n";
responseStream << "\t\t\t\t\t\t</button>\n";
responseStream << "\t\t\t\t\t\t";
#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << "\n";
responseStream << "\t\t\t\t\t</div>\n";
responseStream << "\t\t\t\t</div>\n";
responseStream << "\t\t\t";
#line 209 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 237 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << "\n";
responseStream << "\t\t</div>\n";
responseStream << "\t</div>\n";
responseStream << "\t<div class=\"center-form-title\">\n";
responseStream << "\t <h3>Ein neues Topic anlegen</h3>\n";
responseStream << "\t<!-- Tab links -->\n";
responseStream << "\t<div class=\"tab\">\n";
responseStream << "\t <button class=\"tablinks\" onclick=\"openTab(event, 'topic-create')\">New Topic</button>\n";
responseStream << "\t <button class=\"tablinks\" onclick=\"openTab(event, 'topic-add')\">Add Topic</button>\n";
responseStream << "\t</div>\n";
responseStream << "\t<div class=\"center-form-form\">\n";
responseStream << "\t\t<form method=\"POST\" action=\"";
#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t<div id=\"topic-create\" class=\"tabcontent\">\n";
responseStream << "\t\t<div class=\"center-form-title\">\n";
responseStream << "\t\t\t<h3>Ein neues Topic anlegen</h3>\n";
responseStream << "\t\t</div>\n";
responseStream << "\t\t<div class=\"center-form-form\">\n";
responseStream << "\t\t\t<form method=\"POST\" action=\"";
#line 250 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( ServerConfig::g_serverPath );
responseStream << "/topic\">\n";
responseStream << "\t\t\t<label class=\"form-label\" for=\"topic-name\">Name</label>\n";
responseStream << "\t\t\t<input type=\"text\" class=\"form-control\" id=\"topic-name\" name=\"topic-name\" value=\"";
#line 218 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t\t\t\t<label class=\"form-label\" for=\"topic-name\">Name</label>\n";
responseStream << "\t\t\t\t<input type=\"text\" class=\"form-control\" id=\"topic-name\" name=\"topic-name\" value=\"";
#line 252 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( name );
responseStream << "\">\n";
responseStream << "\t\t\t<label class=\"form-label\" for=\"topic-auto-renew-account\">Auto Renew Hedera Account</label>\n";
responseStream << "\t\t\t<select name=\"topic-auto-renew-account\" id=\"topic-auto-renew-account\">\n";
responseStream << "\t\t\t\t";
#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t\t\t\t<label class=\"form-label\" for=\"topic-auto-renew-account\">Auto Renew Hedera Account</label>\n";
responseStream << "\t\t\t\t<select name=\"topic-auto-renew-account\" id=\"topic-auto-renew-account\">\n";
responseStream << "\t\t\t\t\t";
#line 255 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) {
auto model = (*it)->getModel();
responseStream << "\n";
responseStream << "\t\t\t\t\t<option title=\"";
#line 224 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t\t\t\t\t\t<option title=\"";
#line 258 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( model->toString() );
responseStream << "\" value=\"";
#line 224 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 258 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( model->getID() );
responseStream << "\" ";
#line 224 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 258 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
if(auto_renew_account == model->getID()) { responseStream << "selected=\"selected\"";
#line 224 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 258 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << ">";
#line 224 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 258 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( (*it)->toShortSelectOptionName() );
responseStream << "</option>\n";
responseStream << "\t\t\t\t";
#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t\t\t\t\t";
#line 259 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << "\n";
responseStream << "\t\t\t</select>\n";
responseStream << "\t\t\t<label class=\"form-label\" for=\"topic-auto-renew-period\">Auto Renew Period in seconds</label>\n";
responseStream << "\t\t\t<div><input class=\"form-control input-40\" id=\"topic-auto-renew-period\" value=\"";
#line 228 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t\t\t\t</select>\n";
responseStream << "\t\t\t\t<label class=\"form-label\" for=\"topic-auto-renew-period\">Auto Renew Period in seconds</label>\n";
responseStream << "\t\t\t\t<div><input class=\"form-control input-40\" id=\"topic-auto-renew-period\" value=\"";
#line 262 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( auto_renew_period );
responseStream << "\" type=\"number\" name=\"topic-auto-renew-period\"/><span style=\"margin-left:8px\" id=\"readable-auto-renew-period\"></span><div>\n";
responseStream << "\t\t\t<label class=\"form-label\" for=\"topic-group\">Group</label>\n";
responseStream << "\t\t\t<select class=\"form-control\" name=\"topic-group\" id=\"topic-group\">\t\t\t\n";
responseStream << "\t\t\t\t<option value=\"-1\">Keine Gruppe</option>\n";
responseStream << "\t\t\t\t";
#line 232 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\" type=\"number\" name=\"topic-auto-renew-period\"/><span style=\"margin-left:8px\" id=\"readable-auto-renew-period\"></span></div>\n";
responseStream << "\t\t\t\t<label class=\"form-label\" for=\"topic-group\">Group</label>\n";
responseStream << "\t\t\t\t<select class=\"form-control\" name=\"topic-group\" id=\"topic-group\">\t\t\t\n";
responseStream << "\t\t\t\t\t<option value=\"-1\">Keine Gruppe</option>\n";
responseStream << "\t\t\t\t\t";
#line 266 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
for(auto it = groups.begin(); it != groups.end(); it++) {
auto group_model = (*it)->getModel(); responseStream << "\n";
responseStream << "\t\t\t\t\t<option title=\"";
#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t\t\t\t\t\t<option title=\"";
#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( group_model->getDescription() );
responseStream << "\" value=\"";
#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( group_model->getID() );
responseStream << "\" ";
#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
if(group_id == group_model->getID()) { responseStream << "selected=\"selected\"";
#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << ">";
#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 268 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( group_model->getName() );
responseStream << "</option>\n";
responseStream << "\t\t\t\t";
#line 235 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t\t\t\t\t";
#line 269 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << "\n";
responseStream << "\t\t\t</select>\n";
responseStream << "\t\t\t\n";
responseStream << "\t\t\t<input class=\"center-form-submit form-button\" type=\"submit\" name=\"submit\" value=\"";
#line 238 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << "\t\t\t\t</select>\n";
responseStream << "\t\t\t\t\n";
responseStream << "\t\t\t\t<input class=\"center-form-submit form-button\" type=\"submit\" name=\"submit\" value=\"";
#line 272 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( gettext("Create Topic") );
responseStream << "\">\n";
responseStream << "\t\t\t</form>\n";
responseStream << "\t\t</div>\n";
responseStream << "\t</div>\n";
responseStream << "\t<div id=\"topic-add\" class=\"tabcontent\">\n";
responseStream << "\t\t<div class=\"center-form-title\">\n";
responseStream << "\t\t\t<h3>Ein bestehendes Topic eintragen</h3>\n";
responseStream << "\t\t</div>\n";
responseStream << "\t\t<div class=\"center-form-form\">\n";
responseStream << "\t\t\t<form method=\"POST\" action=\"";
#line 281 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( ServerConfig::g_serverPath );
responseStream << "/topic\">\n";
responseStream << "\t\t\t\t<label class=\"form-label\" for=\"topic-id\">TopicId</label>\n";
responseStream << "\t\t\t\t<input type=\"text\" class=\"form-control\" id=\"topic-id\" name=\"topic-id\" value=\"";
#line 283 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( topic_id_string );
responseStream << "\" placeholder=\"0.0.XXXX\">\n";
responseStream << "\t\t\t\t<label class=\"form-label\" for=\"topic-group\">Group</label>\n";
responseStream << "\t\t\t\t<select class=\"form-control\" name=\"topic-group\" id=\"topic-group\">\t\t\t\n";
responseStream << "\t\t\t\t\t<option value=\"-1\">Keine Gruppe</option>\n";
responseStream << "\t\t\t\t\t";
#line 287 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
for(auto it = groups.begin(); it != groups.end(); it++) {
auto group_model = (*it)->getModel(); responseStream << "\n";
responseStream << "\t\t\t\t\t\t<option title=\"";
#line 289 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( group_model->getDescription() );
responseStream << "\" value=\"";
#line 289 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( group_model->getID() );
responseStream << "\" ";
#line 289 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
if(group_id == group_model->getID()) { responseStream << "selected=\"selected\"";
#line 289 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << ">";
#line 289 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( group_model->getName() );
responseStream << "</option>\n";
responseStream << "\t\t\t\t\t";
#line 290 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
} responseStream << "\n";
responseStream << "\t\t\t\t</select>\n";
responseStream << "\t\t\t\t\n";
responseStream << "\t\t\t\t<input class=\"center-form-submit form-button\" type=\"submit\" name=\"submit\" value=\"";
#line 293 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( gettext("Add Topic") );
responseStream << "\">\n";
responseStream << "\t\t</form>\n";
responseStream << "\t\t\t</form>\n";
responseStream << "\t\t</div>\n";
responseStream << "\t</div>\n";
responseStream << "</div>\n";
// begin include footer.cpsp
@ -431,9 +512,13 @@ void AdminTopicPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
// end include footer.cpsp
responseStream << "\n";
responseStream << "<script type=\"text/javascript\" src=\"";
#line 243 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
#line 299 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "/js/time_calculations.js\"></script>\n";
responseStream << "<script type=\"text/javascript\" src=\"";
#line 300 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminTopic.cpsp"
responseStream << ( ServerConfig::g_php_serverPath );
responseStream << "/js/tabs.js\"></script>\n";
responseStream << "<script type=\"text/javascript\">\n";
responseStream << "\tvar input = document.getElementById(\"topic-auto-renew-period\");\n";
responseStream << "\tvar span = document.getElementById(\"readable-auto-renew-period\");\n";

View File

@ -75,7 +75,7 @@ Poco::Data::Session ConnectionManager::getConnection(ConnectionType type)
auto session = mSessionPools.getPool(mSessionPoolNames[type]).get();
//return mSessionPoolNames[type];
/*if (!session.isConnected()) {
if (!session.isConnected()) {
printf("reconnect called\n");
try {
session.reconnect();
@ -86,7 +86,7 @@ Poco::Data::Session ConnectionManager::getConnection(ConnectionType type)
return mSessionPools.getPool(mSessionPoolNames[type]).get();
}
}*/
}//*/
//std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S");
//printf("[getConnection] %s impl: %p\n", dateTimeString.data(), session.impl());
return session;

View File

@ -48,6 +48,7 @@ bool SessionManager::init()
case VALIDATE_PASSWORD: mValidations[i] = new Poco::RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&+-_])[A-Za-z0-9@$!%*?&+-_]{8,}$"); break;
case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break;
case VALIDATE_GROUP_ALIAS: mValidations[i] = new Poco::RegularExpression("^[a-z0-9-]{3,120}"); break;
case VALIDATE_HEDERA_ID: mValidations[i] = new Poco::RegularExpression("^[0-9]*\.[0-9]*\.[0-9]\.$"); break;
case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break;
case VALIDATE_ONLY_INTEGER: mValidations[i] = new Poco::RegularExpression("^[0-9]*$"); break;
case VALIDATE_ONLY_DECIMAL: mValidations[i] = new Poco::RegularExpression("^[0-9]*(\.|,)[0-9]*$"); break;

View File

@ -28,6 +28,7 @@ enum SessionValidationTypes {
VALIDATE_PASSWORD,
VALIDATE_PASSPHRASE,
VALIDATE_GROUP_ALIAS,
VALIDATE_HEDERA_ID,
VALIDATE_HAS_NUMBER,
VALIDATE_ONLY_INTEGER,
VALIDATE_ONLY_DECIMAL,

View File

@ -1,5 +1,8 @@
#include "HederaId.h"
#include "../SingletonManager/ErrorManager.h"
#include "../SingletonManager/SessionManager.h"
#include "../lib/DataTypeConverter.h"
using namespace Poco::Data::Keywords;
@ -23,6 +26,31 @@ namespace controller {
return Poco::AutoPtr<HederaId>(hedera_id);
}
Poco::AutoPtr<HederaId> HederaId::create(std::string hederaIdString)
{
auto sm = SessionManager::getInstance();
if (!sm->isValid(hederaIdString, VALIDATE_HEDERA_ID)) {
return nullptr;
}
std::vector<std::string> number_strings;
std::istringstream f(hederaIdString);
std::string s;
while (getline(f, s, '.')) {
std::cout << s << std::endl;
number_strings.push_back(s);
}
Poco::UInt64 numbers[3];
for (int i = 0; i < 3; i++) {
if (DataTypeConverter::NUMBER_PARSE_OKAY != DataTypeConverter::strToInt(number_strings[i], numbers[i])) {
return nullptr;
}
}
auto db = new model::table::HederaId(numbers[0], numbers[1], numbers[2]);
auto hedera_id = new HederaId(db);
return Poco::AutoPtr<HederaId>(hedera_id);
}
Poco::AutoPtr<HederaId> HederaId::load(int id)
{
auto db = new model::table::HederaId();

View File

@ -20,6 +20,7 @@ namespace controller {
~HederaId();
static Poco::AutoPtr<HederaId> create(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num);
static Poco::AutoPtr<HederaId> create(std::string hederaIdString);
static Poco::AutoPtr<HederaId> load(int id);
//! \return hedera topic id for group and network type (should exist only one)

View File

@ -67,6 +67,17 @@ HederaRequestReturn HederaRequest::request(model::hedera::Query* query, model::h
queryName = "crypto transaction get receipt";
status = stub->getTransactionReceipts(&context, *proto_query, proto_response);
}
else if (proto_query->has_transactiongetrecord()) {
auto stub = proto::CryptoService::NewStub(channel);
queryName = "crypto transaction get record";
status = stub->getTxRecordByTxID(&context, *proto_query, proto_response);
}
else {
addError(new Error("Hedera Request", "unknown or empty query"));
return HEDERA_REQUEST_UNKNOWN_QUERY;
}
if (status.ok())
{
auto response_code = response->getResponseCode();

View File

@ -69,19 +69,17 @@ namespace controller {
return mAutoRenewAccount;
}
bool HederaTopic::updateWithGetTopicInfos(Poco::AutoPtr<User> user)
bool HederaTopic::getTopicInfosFromHedera(Poco::AutoPtr<controller::HederaId> topicHederaId, Poco::AutoPtr<User> user, model::hedera::Response& response)
{
auto payer_account = getAutoRenewAccount();
auto payer_account = controller::HederaAccount::pick(ServerConfig::g_HederaNetworkType);
auto node_server = NodeServer::pick(payer_account->getModel()->getNetworkType(), getModel()->getGroupId());
auto hedera_topic_id = getTopicHederaId();
if (hedera_topic_id.isNull()) {
if (topicHederaId.isNull()) {
addError(new Error("Hedera Topic", "no hedera topic id exist"));
return false;
}
auto query = model::hedera::Query::getTopicInfo(hedera_topic_id, payer_account->getHederaId(), node_server);
auto query = model::hedera::Query::getTopicInfo(topicHederaId, payer_account->getHederaId(), node_server);
query->setResponseType(proto::COST_ANSWER);
model::hedera::Response response;
HederaRequest request;
query->sign(payer_account->getCryptoKey()->getKeyPair(user));
if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response)) {
@ -94,6 +92,29 @@ namespace controller {
if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response)) {
return true;
}
else {
addError(new Error("Hedera Query", "Error by query for consensus get topic info"));
}
}
else {
addError(new Error("Hedera Query", "Error by getting costs for consensus get topic info"));
}
getErrors(&request);
return false;
}
bool HederaTopic::updateWithGetTopicInfos(Poco::AutoPtr<User> user)
{
model::hedera::Response response;
if (!getTopicInfosFromHedera(getTopicHederaId(), user, response)) {
return false;
}
auto consensus_topic_info = response.getConsensusTopicInfo();
//addNotification(new ParamSuccess("consensus get topic info", "memo: ", consensus_topic_info->getMemo()));
//addNotification(new ParamSuccess("consensus get topic info", "string: ", consensus_topic_info->toStringHtml()));
@ -117,18 +138,36 @@ namespace controller {
return true;
}
else {
addError(new Error("Hedera Query", "Error by query for consensus get topic info"));
}
}
else {
addError(new Error("Hedera Query", "Error by getting costs for consensus get topic info"));
}
Poco::AutoPtr<HederaTopic> HederaTopic::loadFromHedera(Poco::AutoPtr<controller::HederaId> hederaId, Poco::UInt32 groupId, Poco::AutoPtr<User> user)
{
auto db = new model::table::HederaTopic();
auto hedera_topic = new HederaTopic(db);
getErrors(&request);
model::hedera::Response response;
if (!hedera_topic->getTopicInfosFromHedera(hederaId, user, response)) {
delete hedera_topic;
return false;
}
auto consensus_topic_info = response.getConsensusTopicInfo();
//addNotification(new ParamSuccess("consensus get topic info", "memo: ", consensus_topic_info->getMemo()));
//addNotification(new ParamSuccess("consensus get topic info", "string: ", consensus_topic_info->toStringHtml()));
auto group_name = consensus_topic_info->getMemo();
auto groups = controller::Group::load(group_name);
db->setTopicHederaID(hederaId->getModel()->getID());
db->setName(group_name);
if (1 == groups.size()) {
db->setGroupId(groups[0]->getModel()->getID());
}
else if (groupId > 0) {
db->setGroupId(groupId);
}
db->setAutoRenewPeriod(consensus_topic_info->getAutoRenewPeriod().seconds());
db->setCurrentTimeout(consensus_topic_info->getExpirationTime());
db->setSequeceNumber(consensus_topic_info->getSequenceNumber());
return Poco::AutoPtr<HederaTopic>(hedera_topic);
}
Poco::AutoPtr<HederaTask> HederaTopic::createTopic(Poco::AutoPtr<controller::HederaAccount> operatorAccount, Poco::AutoPtr<controller::User> user)
@ -149,13 +188,19 @@ namespace controller {
if (model->getName() != "") {
hederaCreateTopic.setMemo(model->getName());
}
hederaTransactionBody->setCreateTopic(hederaCreateTopic);
if (!hederaTransactionBody->setCreateTopic(hederaCreateTopic)) {
addError(new Error(function_name, "error validating create topic transaction"));
return nullptr;
}
model::hedera::Transaction hederaTransaction;
if (!hederaTransaction.sign(operatorAccount->getCryptoKey()->getKeyPair(user), std::move(hederaTransactionBody))) {
addError(new Error(function_name, "error signing hedera transaction"));
return nullptr;
}
auto proto_transaction = hederaTransaction.getTransaction();
Poco::AutoPtr<HederaTask> receiptTask(new HederaTask(&hederaTransaction));
auto receipt_task_model = receiptTask->getModel();
receipt_task_model->setParentPendingTaskId(model->getID());
@ -175,6 +220,7 @@ namespace controller {
}
else {
addError(new ParamError(function_name, "precheck code error", receiptTask->getTransactionResponse()->getPrecheckCodeString()));
return nullptr;
}
}
@ -184,4 +230,6 @@ namespace controller {
}
}
}

View File

@ -12,6 +12,7 @@
*/
#include "TableControllerBase.h"
#include "../model/table/HederaTopic.h"
#include "../model/hedera/Response.h"
#include "HederaId.h"
#include "HederaAccount.h"
@ -25,6 +26,7 @@ namespace controller {
~HederaTopic();
static Poco::AutoPtr<HederaTopic> create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId);
static Poco::AutoPtr<HederaTopic> loadFromHedera(Poco::AutoPtr<controller::HederaId> hederaId, Poco::UInt32 groupId, Poco::AutoPtr<User> user);
static std::vector<Poco::AutoPtr<HederaTopic>> listAll();
static Poco::AutoPtr<HederaTopic> load(int id);
@ -44,6 +46,9 @@ namespace controller {
protected:
HederaTopic(model::table::HederaTopic* dbModel);
bool getTopicInfosFromHedera(Poco::AutoPtr<controller::HederaId> topicHederaId, Poco::AutoPtr<User> user, model::hedera::Response& response);
Poco::AutoPtr<HederaId> mTopicHederaId;
Poco::AutoPtr<HederaAccount> mAutoRenewAccount;

View File

@ -114,6 +114,7 @@ namespace controller {
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
static const char* function_name = "PendingTask::startTimer";
auto em = ErrorManager::getInstance();
if (isTimeoutTask()) {
auto next_run_time = getNextRunTime();
if (next_run_time >= Poco::DateTime()) {
@ -128,7 +129,15 @@ namespace controller {
em->addError(new ParamError(function_name, "task type", getModel()->getTaskTypeString()));
em->sendErrorsAsEmail();
}
mTimer.setStartInterval(Poco::Timespan(getNextRunTime() - Poco::DateTime()).milliseconds());
next_run_time = getNextRunTime();
auto interval = next_run_time - Poco::DateTime();
printf("interval: %d\n", interval.milliseconds());
if (interval.milliseconds() > 0) {
mTimer.setStartInterval(interval.milliseconds());
}
else {
mTimer.setStartInterval(100);
}
Poco::TimerCallback<PendingTask> callback(*this, &PendingTask::calledFromTimer);
mTimer.start(callback);
}
@ -136,13 +145,18 @@ namespace controller {
}
void PendingTask::calledFromTimer(Poco::Timer& timer)
{
printf("[PendingTask::calledFromTimer]\n");
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
auto result = run();
printf("run result: %d\n", result);
if (result != 1 && result != -1) {
timer.restart(0);
return;
}
mTimer.setStartInterval(Poco::Timespan(getNextRunTime() - Poco::DateTime()).milliseconds());
Poco::TimerCallback<PendingTask> callback(*this, &PendingTask::calledFromTimer);
mTimer.start(callback);
auto interval = Poco::Timespan(getNextRunTime() - Poco::DateTime()).milliseconds();
if (interval <= 0) {
interval = 100;
}
timer.restart(interval);
}
}

49
src/cpp/lib/DecayRate.cpp Normal file
View File

@ -0,0 +1,49 @@
#include "DecayRate.h"
#include <gmp.h>
#include <mpfr.h>
DecayRate::DecayRate()
: mDecayRate(0.0)
{
}
DecayRate::~DecayRate()
{
}
void DecayRate::calculateDecayRate(int daysPerYear/* = 356*/, Profiler* time/* = nullptr*/)
{
mpfr_t capital_n_log; mpfr_init(capital_n_log);
mpfr_t capital_0_log; mpfr_init(capital_0_log);
mpfr_t capital_diff; mpfr_init(capital_diff);
mpfr_t decay_rate_per_second; mpfr_init(decay_rate_per_second);
mpfr_t seconds_per_year;
mpfr_t days_per_year;
mpfr_init_set_ui(days_per_year, daysPerYear, MPFR_RNDN);
mpfr_init(seconds_per_year);
/*
typedef enum {
MPFR_RNDN=0, // round to nearest, with ties to even
MPFR_RNDZ, // round toward zero
MPFR_RNDU, // round toward +Inf
MPFR_RNDD, // round toward -Inf
MPFR_RNDA, // round away from zero
MPFR_RNDF, // faithful rounding
MPFR_RNDNA = -1 // round to nearest, with ties away from zero (mpfr_round)
} mpfr_rnd_t;
*/
//mpfr_rnd_t
// seconds per year = 60*60*24*daysPerYear
mpfr_mul_ui(seconds_per_year, days_per_year, 60 * 60 * 24, MPFR_RNDN);
mpfr_log_ui(capital_n_log, 50, MPFR_RNDN);
mpfr_log_ui(capital_0_log, 100, MPFR_RNDN);
mpfr_sub(capital_diff, capital_n_log, capital_0_log, MPFR_RNDN);
mpfr_div(decay_rate_per_second, capital_diff, seconds_per_year, MPFR_RNDN);
mDecayRate = mpfr_get_d(decay_rate_per_second, MPFR_RNDN);
}

28
src/cpp/lib/DecayRate.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef __GRADIDO_LOGIN_SERVER_LIB_INTEREST_RATE_H
#define __GRADIDO_LOGIN_SERVER_LIB_INTEREST_RATE_H
/*!
* @author: Dario Rekowski
*
* @date: 2020-11-24
*
* @brief: to calculate interest rate for gradido and maybe also decay
*/
#include "Poco/Types.h"
#include "Profiler.h"
class DecayRate
{
public:
DecayRate();
~DecayRate();
void calculateDecayRate(int daysPerYear = 356, Profiler* time = nullptr);
inline double getDecayRate() { return mDecayRate; }
protected:
double mDecayRate;
};
#endif //__GRADIDO_LOGIN_SERVER_LIB_INTEREST_RATE_H

View File

@ -11,8 +11,8 @@ namespace model {
auto auto_renew_period = mProtoCreateTopic->mutable_autorenewperiod();
auto_renew_period->set_seconds(autoRenewPeriod);
auto auto_renew_account = mProtoCreateTopic->mutable_autorenewaccount();
if (!autoRenewHederaAccountId.isNull()) {
auto auto_renew_account = mProtoCreateTopic->mutable_autorenewaccount();
autoRenewHederaAccountId->copyToProtoAccountId(auto_renew_account);
}
@ -40,7 +40,8 @@ namespace model {
bool ConsensusCreateTopic::validate()
{
if (mProtoCreateTopic->autorenewperiod().seconds() > 86400) {// && 0 != mProtoCreateTopic->autorenewaccount().accountnum()) {
if (mProtoCreateTopic->autorenewperiod().seconds() == 7890000) {// && 0 != mProtoCreateTopic->autorenewaccount().accountnum()) {
return true;
}
return false;

View File

@ -3,6 +3,8 @@
#include "Poco/Timestamp.h"
#include "../../SingletonManager/MemoryManager.h"
#include <google/protobuf/util/json_util.h>
#include "Transaction.h"
#include "TransactionBody.h"
#include "CryptoTransferTransaction.h"
@ -56,8 +58,8 @@ namespace model {
assert(!topicId.isNull() && topicId->getModel());
assert(!payerAccountId.isNull() && payerAccountId->getModel());
printf("[Query::getBalance] topic id: %s\n", topicId->getModel()->toString().data());
printf("[Query::getBalance] payer account id: %s\n", payerAccountId->getModel()->toString().data());
printf("[Query::getTopicInfo] topic id: %s\n", topicId->getModel()->toString().data());
printf("[Query::getTopicInfo] payer account id: %s\n", payerAccountId->getModel()->toString().data());
auto query = new Query;
auto get_topic_info = query->mQueryProto.mutable_consensusgettopicinfo();
@ -85,14 +87,43 @@ namespace model {
{
assert(!payerAccount.isNull());
auto query = new Query;
query->mQueryHeader = QueryHeader::createWithPaymentTransaction(payerAccount, connection, 0);
query->mQueryHeader = QueryHeader::createWithPaymentTransaction(payerAccount, connection, 1000);
auto transaction_get_receipt_query = query->mQueryProto.mutable_transactiongetreceipt();
transaction_get_receipt_query->set_allocated_header(query->mQueryHeader->getProtoQueryHeader());
auto transaction_id = transaction_get_receipt_query->transactionid();
transaction_id = transactionId;
auto transaction_id = transaction_get_receipt_query->mutable_transactionid();
*transaction_id = transactionId;
return query;
}
Query* Query::getTransactionGetRecordQuery(
const proto::TransactionID& transactionId,
Poco::AutoPtr<controller::HederaAccount> payerAccount,
const controller::NodeServerConnection& connection
)
{
assert(!payerAccount.isNull());
auto query = new Query;
query->mQueryHeader = QueryHeader::createWithPaymentTransaction(payerAccount, connection, 1000);
auto transaction_get_record_query = query->mQueryProto.mutable_transactiongetrecord();
transaction_get_record_query->set_allocated_header(query->mQueryHeader->getProtoQueryHeader());
auto transaction_id = transaction_get_record_query->mutable_transactionid();
*transaction_id = transactionId;
return query;
}
std::string Query::getConnectionString() const
{
if (mTransactionBody) {
return mTransactionBody->getConnectionString();
}
if (!mQueryHeader.isNull()) {
return mQueryHeader->getConnectionString();
}
return "";
}
proto::QueryHeader* Query::getQueryHeader()
{
@ -132,6 +163,31 @@ namespace model {
return query_header->responsetype();
}
std::string Query::toJsonString() const
{
std::string json_message = "";
std::string json_message_body = "";
google::protobuf::util::JsonPrintOptions options;
options.add_whitespace = true;
options.always_print_primitive_fields = true;
auto status = google::protobuf::util::MessageToJsonString(mQueryProto, &json_message, options);
if (!status.ok()) {
return "error parsing query";
}
if (mTransactionBody) {
status = google::protobuf::util::MessageToJsonString(*mTransactionBody->getProtoTransactionBody(), &json_message_body, options);
if (!status.ok()) {
return "error parsing body";
}
//\"bodyBytes\": \"MigKIC7Sihz14RbYNhVAa8V3FSIhwvd0pWVvZqDnVA91dtcbIgRnZGQx\"
int startBodyBytes = json_message.find("bodyBytes") + std::string("\"bodyBytes\": \"").size() - 2;
int endCur = json_message.find_first_of('\"', startBodyBytes + 2) + 1;
json_message.replace(startBodyBytes, endCur - startBodyBytes, json_message_body);
}
return json_message;
}
}
}

View File

@ -29,6 +29,11 @@ namespace model {
Poco::AutoPtr<controller::HederaAccount> payerAccount,
const controller::NodeServerConnection& connection
);
static Query* getTransactionGetRecordQuery(
const proto::TransactionID& transactionId,
Poco::AutoPtr<controller::HederaAccount> payerAccount,
const controller::NodeServerConnection& connection
);
bool sign(std::unique_ptr<KeyPairHedera> keyPairHedera);
void setResponseType(proto::ResponseType type);
@ -36,10 +41,12 @@ namespace model {
inline bool setTransactionFee(Poco::UInt64 fee) { return mTransactionBody->updateCryptoTransferAmount(fee);}
inline const proto::Query* getProtoQuery() const { return &mQueryProto; }
inline std::string getConnectionString() const { return mTransactionBody->getConnectionString(); }
std::string getConnectionString() const;
proto::QueryHeader* getQueryHeader();
std::string toJsonString() const;
protected:
Query();
proto::Query mQueryProto;

View File

@ -23,11 +23,11 @@ namespace model {
Poco::AutoPtr<QueryHeader> query_header(new QueryHeader);
auto proto_query_header = query_header->getProtoQueryHeader();
proto_query_header->set_responsetype(proto::ANSWER_ONLY);
auto payment_transaction = proto_query_header->payment();
auto payment_transaction = proto_query_header->mutable_payment();
query_header->mConnectionString = connection.getUriWithPort();
Transaction transactionObj(&payment_transaction);
Transaction transactionObj(payment_transaction);
TransactionBody body(operatorAccount->getHederaId(), connection);
CryptoTransferTransaction transfer_transaction;
transfer_transaction.addSender(operatorAccount->getHederaId(), cost);

View File

@ -33,6 +33,17 @@ namespace model {
if (mResponseProto.has_transactiongetreceipt()) {
return new TransactionReceipt(mResponseProto.transactiongetreceipt().receipt());
}
if (mResponseProto.has_transactiongetrecord()) {
return new TransactionReceipt(mResponseProto.transactiongetrecord().transactionrecord().receipt());
}
return nullptr;
}
TransactionRecord* Response::getTransactionRecord()
{
if (mResponseProto.has_transactiongetrecord()) {
return new TransactionRecord(mResponseProto.transactiongetrecord().transactionrecord());
}
return nullptr;
}

View File

@ -13,6 +13,7 @@
#include "../../proto/hedera/Response.pb.h"
#include "ConsensusTopicInfo.h"
#include "TransactionReceipt.h"
#include "TransactionRecord.h"
#include "Poco/Types.h"
namespace model {
@ -27,6 +28,7 @@ namespace model {
Poco::UInt64 getAccountBalance();
std::unique_ptr<ConsensusTopicInfo> getConsensusTopicInfo();
TransactionReceipt* getTransactionReceipt();
TransactionRecord* getTransactionRecord();
Poco::UInt64 getQueryCost();
proto::ResponseCodeEnum getResponseCode();

View File

@ -75,6 +75,7 @@ namespace model {
consensusCreateTopicTransaction.resetPointer();
mHasBody = true;
mType = TRANSACTION_CONSENSUS_CREATE_TOPIC;
mTransactionBody.set_transactionfee(1000000000);
return true;
}
return false;
@ -126,11 +127,15 @@ namespace model {
auto transaction_id = mTransactionBody.mutable_transactionid();
auto timestamp = transaction_id->mutable_transactionvalidstart();
Poco::Timestamp now;
auto micros = now.epochMicroseconds();
auto s = now.epochTime();
auto res = now.resolution();
auto microseconds = now.epochMicroseconds() - now.epochTime() * now.resolution(); // 1*10^6
timestamp->set_seconds(now.epochTime()-1);
//timestamp->set_nanos(microseconds * 1000);
// 1s = 1000000000 ns
timestamp->set_seconds(now.epochTime()-2);
timestamp->set_nanos(microseconds * 1000);
// make sure timestamp is some nanos old
timestamp->set_nanos(microseconds * 900);
//timestamp->set_nanos(microseconds * 900);
printf("hedera transaction body timestamp: %d.%d\n", timestamp->seconds(), timestamp->nanos());
}
}

View File

@ -0,0 +1,12 @@
#include "TransactionRecord.h"
namespace model {
namespace hedera {
TransactionRecord::TransactionRecord(const proto::TransactionRecord& transaction_record)
: mProtoRecord(transaction_record)
{
}
}
}

View File

@ -0,0 +1,26 @@
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECORD_H
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECORD_H
#include "../../proto/hedera/TransactionRecord.pb.h"
namespace model
{
namespace hedera
{
class TransactionRecord
{
public:
TransactionRecord(const proto::TransactionRecord& transaction_record);
inline proto::TransactionRecord* getProto() { return &mProtoRecord; }
protected:
proto::TransactionRecord mProtoRecord;
};
}
}
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECORD_H

View File

@ -32,6 +32,7 @@ namespace model {
std::string HederaTopic::toString()
{
std::stringstream ss;
ss << std::endl;
ss << "Topic Hedera id: " << std::to_string(mTopicHederaId) << std::endl;
ss << "Name: " << mName << std::endl;
ss << "Auto Renew Account Hedera id: " << std::to_string(mAutoRenewAccountHederaId) << std::endl;
@ -39,7 +40,7 @@ namespace model {
ss << "Group id: " << std::to_string(mGroupId) << std::endl;
ss << "Admin Key id: " << std::to_string(mAdminKeyId) << std::endl;
ss << "Submit Key id: " << std::to_string(mSubmitKeyId) << std::endl;
ss << "Hedera Topic Tiemout: " << Poco::DateTimeFormatter::format(mCurrentTimeout, "%f.%m.%Y %H:%M:%S") << std::endl;
ss << "Hedera Topic Timeout: " << Poco::DateTimeFormatter::format(mCurrentTimeout, "%f.%m.%Y %H:%M:%S") << std::endl;
ss << "Hedera Topic Sequence Number: " << std::to_string(mSequenceNumber) << std::endl;
ss << "Updated: " << Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S") << std::endl;
return ss.str();
@ -88,7 +89,8 @@ namespace model {
lock();
select << "SELECT id FROM " << getTableName()
<< " where topic_hedera_id = ? "
, into(mID), use(mTopicHederaId);
<< " AND name = ? "
, into(mID), use(mTopicHederaId), use(mName);
unlock();
return select;
}

View File

@ -34,9 +34,12 @@ namespace model {
std::string getUpdatedString() const;
inline void setTopicHederaID(Poco::UInt32 topidHederaId) { mTopicHederaId = topidHederaId;}
inline void setSequeceNumber(Poco::UInt64 sequenceNumber) { mSequenceNumber = sequenceNumber; }
inline void setCurrentTimeout(Poco::DateTime currentTimeOut) { mCurrentTimeout = currentTimeOut; }
inline void setName(std::string name) { mName = name; }
inline void setAutoRenewPeriod(Poco::UInt32 autoRenewPeriod) { mAutoRenewPeriod = autoRenewPeriod; }
inline void setGroupId(Poco::UInt32 groupId) { mGroupId = groupId; }
inline void setCurrentTimeout(Poco::DateTime currentTimeOut) { mCurrentTimeout = currentTimeOut; }
inline void setSequeceNumber(Poco::UInt64 sequenceNumber) { mSequenceNumber = sequenceNumber; }
protected:
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);

View File

@ -43,6 +43,8 @@ namespace model {
size_t updateIntoDB(std::string fieldNames[2], const T1& fieldValue1, const T2& fieldValue2);
template<class T1, class T2, class T3>
size_t updateIntoDB(std::string fieldNames[3], const T1& fieldValue1, const T2& fieldValue2, const T3& fieldValue3);
template<class T1, class T2, class T3, class T4>
size_t updateIntoDB(std::string fieldNames[4], const T1& fieldValue1, const T2& fieldValue2, const T3& fieldValue3, const T4& fieldValue4);
template<class T>
size_t loadFromDB(const std::string& fieldName, const T& fieldValue);
//! \brief count columes for "SELECT count(id) from <tableName> where <fieldName> = <fieldValue> group by id";
@ -200,7 +202,8 @@ namespace model {
UNIQUE_LOCK;
auto cm = ConnectionManager::getInstance();
try {
Poco::Data::Statement select = _loadAllFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER));
auto connection = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
Poco::Data::Statement select = _loadAllFromDB(connection);
select, Poco::Data::Keywords::into(results);
size_t resultCount = 0;
@ -383,6 +386,45 @@ namespace model {
return resultCount;
}
template<class T1, class T2, class T3, class T4>
size_t ModelBase::updateIntoDB(std::string fieldNames[4], const T1& fieldValue1, const T2& fieldValue2, const T3& fieldValue3, const T4& fieldValue4)
{
auto cm = ConnectionManager::getInstance();
Poco::ScopedLock<Poco::Mutex> _poco_lock(mWorkMutex);
UNIQUE_LOCK;
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
Poco::Data::Statement update(session);
if (mID == 0) {
addError(new Error("ModelBase::updateIntoDB", "id is zero"));
return 0;
}
update << "UPDATE " << getTableName() << " SET ";
for (int i = 0; i < 4; i++) {
if (i) update << ", ";
update << fieldNames[i] << " = ? ";
}
update << "WHERE id = ?"
, Poco::Data::Keywords::bind(fieldValue1), Poco::Data::Keywords::bind(fieldValue2)
, Poco::Data::Keywords::bind(fieldValue3), Poco::Data::Keywords::bind(fieldValue4)
, Poco::Data::Keywords::bind(mID);
size_t resultCount = 0;
try {
resultCount = update.execute();
}
catch (Poco::Exception& ex) {
addError(new ParamError(getTableName(), "mysql error by update 4", ex.displayText()));
for (int i = 0; i < 3; i++) {
addError(new ParamError(getTableName(), "field name for update: ", fieldNames[i]));
}
}
return resultCount;
}
// ******************** Generic Tasks ************************************

View File

@ -68,6 +68,7 @@ Poco::AutoPtr<HederaTask> HederaTask::load(model::table::PendingTask* dbModel)
Poco::DateTime HederaTask::getNextRunTime()
{
printf("[HederaTask::getNextRunTime]\n");
std::shared_lock<std::shared_mutex> _lock(mWorkingMutex);
return mLastCheck + 2000 * mTryCount * 2000;
}
@ -84,7 +85,6 @@ int HederaTask::run()
return 0;
}
return result;
}
@ -104,6 +104,7 @@ void HederaTask::setTransactionReceipt(model::hedera::TransactionReceipt* transa
//! \return 1 if hedera query failed
//! \return -1 if run after failed
//! \return -2 if not enough data for query
//! \return -3 if error in query
int HederaTask::tryQueryReceipt()
{
@ -121,9 +122,11 @@ int HederaTask::tryQueryReceipt()
addError(new ParamError(function_name, "couldn't find unencrypted operator account for hedera network type: ", ServerConfig::g_HederaNetworkType));
return -2;
}
//auto query = model::hedera::Query::getTransactionGetReceiptQuery(mTransactionID, operator_account, connection);
auto query = model::hedera::Query::getTransactionGetReceiptQuery(mTransactionID, operator_account, connection);
HederaRequest request;
model::hedera::Response response;
try {
if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response)) {
mTransactionReceipt = response.getTransactionReceipt();
if (mTransactionReceipt) {
@ -136,6 +139,16 @@ int HederaTask::tryQueryReceipt()
}
}
else {
if (response.getResponseCode() == proto::NOT_SUPPORTED) {
return -3;
}
mLastCheck = Poco::Timestamp();
mTryCount++;
}
}
catch (std::exception& ex) {
addError(new ParamError(function_name, "exception calling hedera request: ", ex.what()));
mLastCheck = Poco::Timestamp();
mTryCount++;
}

View File

@ -25,8 +25,9 @@
Profiler hedera_time;
std::string name = "";
std::string topic_id_string = "";
int auto_renew_account = 0;
int auto_renew_period = 604800; // 7 Tage
int auto_renew_period = 7890000; // 3 Monate
int group_id = 0;
@ -73,9 +74,19 @@
else if(!form.empty())
{
name = form.get("topic-name", "");
topic_id_string = form.get("topic-id", "");
auto auto_renew_account_string = form.get("topic-auto-renew-account", "0");
auto auto_renew_period_string = form.get("topic-auto-renew-period", "604800");
auto auto_renew_period_string = form.get("topic-auto-renew-period", "7890000");
auto group_id_string = form.get("topic-group", "-1");
Poco::AutoPtr<controller::HederaId> topic_id;
if(topic_id_string != "" && sm->isValid(topic_id_string, VALIDATE_HEDERA_ID)) {
topic_id = controller::HederaId::create(topic_id_string);
if(topic_id.isNull()) {
addError(new Error("Hedera Id", "cannot parse hedera id"));
}
} else {
if(name != "" && !sm->isValid(name, VALIDATE_NAME)) {
addError(new Error("Topic", "Name not valid, at least 3 Character"));
@ -96,6 +107,7 @@
addError(new Error("Int convert error", "Error converting auto renew period to int"));
}
}
}
if(!sm->isValid(group_id_string, VALIDATE_ONLY_INTEGER)) {
addError(new Error("Topic", "group_id not an integer"));
@ -106,6 +118,21 @@
}
//const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId
// add or create topic?
// add topic
if(!topic_id.isNull()) {
if(topic_id->getModel()->insertIntoDB(true)) {
auto hedera_topic = controller::HederaTopic::loadFromHedera(topic_id, group_id, user);
if(!hedera_topic.isNull()) {
hedera_topic->getModel()->insertIntoDB(false);
} else {
addError(new Error("Hedera Topic", "error load topic from hedera"));
}
} else {
addError(new Error("Hedera Id", "Error saving hedera id"));
}
// create topic
} else {
auto hedera_topic = controller::HederaTopic::create(name, auto_renew_account, auto_renew_period, group_id);
if(!hedera_topic->getModel()->insertIntoDB(true)) {
addError(new Error("Topic", "error saving into db"));
@ -121,7 +148,7 @@
}
}
}
}
}
@ -141,6 +168,7 @@
//std::vector<Poco::AutoPtr<controller::HederaTopic>> hedera_topics;
%><%@ include file="header_large.cpsp" %>
<style type="text/css">
.center-form-form .input-40 {
margin-left:0;
@ -160,7 +188,7 @@
</div>
<div class="content-list-table">
<div class="row">
<div class="cell header-cell c2">Topic ID</div>
<div class="cell header-cell c3">Topic ID</div>
<div class="cell header-cell c3">Name</div>
<div class="cell header-cell c3">Network Type</div>
<div class="cell header-cell c4">Auto Renew Account Balance</div>
@ -190,7 +218,7 @@
%>
<div class="row">
<div class="cell c2"><%= topic_hedera_id_string %></div>
<div class="cell c3"><%= topic_hedera_id_string %></div>
<div class="cell c3"><%= hedera_topic_model->getName() %></div>
<div class="cell c3"><%= model::table::HederaAccount::hederaNetworkTypeToString(renew_account_model->getNetworkType()) %></div>
<div class="cell c4"><%= renew_account_model->getBalanceString() %></div>
@ -209,6 +237,12 @@
<% } %>
</div>
</div>
<!-- Tab links -->
<div class="tab">
<button class="tablinks" onclick="openTab(event, 'topic-create')">New Topic</button>
<button class="tablinks" onclick="openTab(event, 'topic-add')">Add Topic</button>
</div>
<div id="topic-create" class="tabcontent">
<div class="center-form-title">
<h3>Ein neues Topic anlegen</h3>
</div>
@ -225,7 +259,28 @@
<% } %>
</select>
<label class="form-label" for="topic-auto-renew-period">Auto Renew Period in seconds</label>
<div><input class="form-control input-40" id="topic-auto-renew-period" value="<%= auto_renew_period %>" type="number" name="topic-auto-renew-period"/><span style="margin-left:8px" id="readable-auto-renew-period"></span><div>
<div><input class="form-control input-40" id="topic-auto-renew-period" value="<%= auto_renew_period %>" type="number" name="topic-auto-renew-period"/><span style="margin-left:8px" id="readable-auto-renew-period"></span></div>
<label class="form-label" for="topic-group">Group</label>
<select class="form-control" name="topic-group" id="topic-group">
<option value="-1">Keine Gruppe</option>
<% for(auto it = groups.begin(); it != groups.end(); it++) {
auto group_model = (*it)->getModel(); %>
<option title="<%= group_model->getDescription() %>" value="<%= group_model->getID() %>" <% if(group_id == group_model->getID()) {%>selected="selected"<% } %>><%= group_model->getName() %></option>
<% } %>
</select>
<input class="center-form-submit form-button" type="submit" name="submit" value="<%= gettext("Create Topic") %>">
</form>
</div>
</div>
<div id="topic-add" class="tabcontent">
<div class="center-form-title">
<h3>Ein bestehendes Topic eintragen</h3>
</div>
<div class="center-form-form">
<form method="POST" action="<%= ServerConfig::g_serverPath %>/topic">
<label class="form-label" for="topic-id">TopicId</label>
<input type="text" class="form-control" id="topic-id" name="topic-id" value="<%= topic_id_string %>" placeholder="0.0.XXXX">
<label class="form-label" for="topic-group">Group</label>
<select class="form-control" name="topic-group" id="topic-group">
<option value="-1">Keine Gruppe</option>
@ -239,8 +294,10 @@
</form>
</div>
</div>
</div>
<%@ include file="footer.cpsp" %>
<script type="text/javascript" src="<%= ServerConfig::g_php_serverPath %>/js/time_calculations.js"></script>
<script type="text/javascript" src="<%= ServerConfig::g_php_serverPath %>/js/tabs.js"></script>
<script type="text/javascript">
var input = document.getElementById("topic-auto-renew-period");
var span = document.getElementById("readable-auto-renew-period");