mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
removed all files belonging to hedera or old outdated code
This commit is contained in:
parent
95fe600210
commit
43b6e1830b
@ -1,19 +0,0 @@
|
||||
INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `host`, `home`, `description`) VALUES
|
||||
(2, 'dockerStage2', 'docker stage2 gradido group', 'localhost', 'nginx', '/', 'gradido test group for docker and stage2');
|
||||
|
||||
INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES
|
||||
(1, 0, 0, 3),
|
||||
(2, 0, 0, 3327),
|
||||
(3, 0, 0, 413151);
|
||||
|
||||
INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES
|
||||
(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 2, '2000-01-01 00:00:00');
|
||||
|
||||
INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES
|
||||
(1, 1, 2, 1, 1000000000000, 1, '2021-01-07 10:22:52');
|
||||
|
||||
INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `running_hash`, `running_hash_version`, `updated`) VALUES
|
||||
(1, 3, 'dockerStage2', 1, 7890000, 1, 0, 0, '2021-06-08 23:17:19', 0, NULL, 0, '2021-03-09 16:42:34');
|
||||
|
||||
|
||||
|
||||
@ -19,9 +19,7 @@ include_directories(
|
||||
"dependencies/mariadb-connector-c/include"
|
||||
"dependencies/mariadb-connector-c/build/include"
|
||||
"dependencies/spirit-po/include"
|
||||
"dependencies/grpc/include"
|
||||
"dependencies/grpc/third_party/protobuf/src"
|
||||
"dependencies/grpc/third_party/googletest/googletest/include"
|
||||
"dependencies/protobuf/src"
|
||||
"build"
|
||||
"build/proto"
|
||||
"build/http_pages"
|
||||
@ -39,56 +37,27 @@ IF(UNIX)
|
||||
"dependencies/poco/NetSSL_OpenSSL/include"
|
||||
)
|
||||
ENDIF()
|
||||
############################## config and add grpc ###################################
|
||||
|
||||
set(GRPC_PATH "${DEP_PATH}/grpc/build")
|
||||
set(GRPC_ABSL_PATH "${GRPC_PATH}/third_party/abseil-cpp/absl/types")
|
||||
set(GRPC_CARES_PATH "${GRPC_PATH}/third_party/cares/cares/lib")
|
||||
set(GRPC_BORING_SSL_PATH "${GRPC_PATH}/third_party/boringssl-with-bazel")
|
||||
set(GRPC_RE2_PATH "${GRPC_PATH}/third_party/re2")
|
||||
set(GRPC_PROTOBUF_PATH "${GRPC_PATH}/third_party/protobuf")
|
||||
|
||||
if(WIN32)
|
||||
set(GRPC_PATH "${GRPC_PATH}/Debug")
|
||||
set(GRPC_ABSL_PATH "${GRPC_ABSL_PATH}/Debug")
|
||||
set(GRPC_CARES_PATH "${GRPC_CARES_PATH}/Debug")
|
||||
set(GRPC_BORING_SSL_PATH "${GRPC_CGRPC_BORING_SSL_PATHARES_PATH}/Debug")
|
||||
set(GRPC_RE2_PATH "${GRPC_RE2_PATH}/Debug")
|
||||
set(GRPC_PROTOBUF_DEBUG_PATH "${GRPC_PROTOBUF_PATH}/Debug")
|
||||
endif()
|
||||
|
||||
|
||||
set(BUILD_TESTING OFF)
|
||||
#set(gRPC_SSL_PROVIDER "package")
|
||||
add_subdirectory("dependencies/grpc/")
|
||||
#set(gRPC_SSL_PROVIDER "package")
|
||||
message(STATUS "Using gRPC via add_subdirectory.")
|
||||
|
||||
set(GRPC_LIBS libprotobuf grpc++_reflection grpc++)
|
||||
############################## find protobuf #########################################
|
||||
add_subdirectory(dependencies/protobuf/cmake)
|
||||
|
||||
############################## parse protobuf files ###################################
|
||||
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/proto GRADIDO_PROTO_MODEL_PATH)
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/proto/hedera/hedera-protobuf/src/main/proto HEDERA_PROTO_MODEL_PATH)
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/build/proto PROTOBINDING_PATH)
|
||||
file(MAKE_DIRECTORY ${PROTOBINDING_PATH})
|
||||
file(MAKE_DIRECTORY ${PROTOBINDING_PATH}/gradido)
|
||||
file(MAKE_DIRECTORY ${PROTOBINDING_PATH}/hedera)
|
||||
|
||||
FILE(GLOB DATAMODEL_GRADIDO_PROTOS "${GRADIDO_PROTO_MODEL_PATH}/gradido/*.proto")
|
||||
FILE(GLOB DATAMODEL_HEDERA_PROTOS "${HEDERA_PROTO_MODEL_PATH}/*.proto")
|
||||
|
||||
IF(WIN32)
|
||||
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin PATHS "build/dependencies/grpc/bin/Debug")
|
||||
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin PATHS "build/dependencies/grpc/bin/Release")
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "build/dependencies/grpc/third_party/protobuf/bin/Debug" )
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "build/dependencies/grpc/third_party/protobuf/bin/Release" )
|
||||
ELSE()
|
||||
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin PATHS "build/dependencies/grpc/bin")
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "build/dependencies/grpc/third_party/protobuf/bin" )
|
||||
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "build/dependencies/protobuf/cmake/bin" )
|
||||
ENDIF()
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/grpc/third_party/protobuf/src GOOGLE_PROTOBUF_INCLUDES)
|
||||
MESSAGE("protoc: ${PROTOBUF_PROTOC_EXECUTABLE} in build/dependencies/grpc/bin/${CMAKE_BUILD_TYPE}")
|
||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/protobuf/src GOOGLE_PROTOBUF_INCLUDES)
|
||||
MESSAGE("protoc: ${PROTOBUF_PROTOC_EXECUTABLE} in build/dependencies/protobuf/bin/${CMAKE_BUILD_TYPE}")
|
||||
FOREACH(proto ${DATAMODEL_GRADIDO_PROTOS})
|
||||
FILE(TO_NATIVE_PATH ${proto} proto_native)
|
||||
get_filename_component(proto_parsed ${proto} NAME_WLE)
|
||||
@ -113,30 +82,6 @@ FOREACH(proto ${DATAMODEL_GRADIDO_PROTOS})
|
||||
|
||||
ENDFOREACH(proto)
|
||||
|
||||
FOREACH(proto ${DATAMODEL_HEDERA_PROTOS})
|
||||
FILE(TO_NATIVE_PATH ${proto} proto_native)
|
||||
get_filename_component(proto_parsed ${proto} NAME_WLE)
|
||||
FILE(TO_NATIVE_PATH ${PROTOBINDING_PATH}/hedera/${proto_parsed}.pb.h proto_parsed_native)
|
||||
IF(${proto_native} IS_NEWER_THAN ${proto_parsed_native})
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND
|
||||
${PROTOBUF_PROTOC_EXECUTABLE}
|
||||
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN}
|
||||
--proto_path=${HEDERA_PROTO_MODEL_PATH}
|
||||
--proto_path=${GOOGLE_PROTOBUF_INCLUDES}
|
||||
--cpp_out=${PROTOBINDING_PATH}/hedera
|
||||
--grpc_out ${PROTOBINDING_PATH}/hedera
|
||||
${proto_native}
|
||||
RESULT_VARIABLE rv
|
||||
)
|
||||
# Optional, but that can show the user if something have gone wrong with the proto generation
|
||||
IF(${rv})
|
||||
MESSAGE("Generation of data model returned ${rv} for proto ${proto_native}")
|
||||
ELSE()
|
||||
MESSAGE("Parsed: src/proto/hedera/hedera-protobuf/src/main/proto/${proto_parsed}.proto")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDFOREACH(proto)
|
||||
|
||||
############################## parse cpsp Files ####################################
|
||||
|
||||
@ -212,13 +157,11 @@ FILE(GLOB LIB_SRC "src/cpp/lib/*.h" "src/cpp/lib/*.cpp")
|
||||
FILE(GLOB MODEL "src/cpp/model/*.h" "src/cpp/model/*.cpp")
|
||||
FILE(GLOB MODEL_TABLE "src/cpp/model/table/*.h" "src/cpp/model/table/*.cpp")
|
||||
FILE(GLOB MODEL_EMAIL "src/cpp/model/email/*.h" "src/cpp/model/email/*.cpp")
|
||||
FILE(GLOB MODEL_HEDERA "src/cpp/model/hedera/*.h" "src/cpp/model/hedera/*.cpp")
|
||||
FILE(GLOB MODEL_GRADIDO "src/cpp/model/gradido/*.h" "src/cpp/model/gradido/*.cpp")
|
||||
FILE(GLOB CRYPTO "src/cpp/Crypto/*.h" "src/cpp/Crypto/*.cpp")
|
||||
FILE(GLOB MAIN "src/cpp/*.cpp" "src/cpp/*.c" "src/cpp/*.h")
|
||||
FILE(GLOB MYSQL "src/cpp/MySQL/*.cpp" "src/cpp/MySQL/*.h" "src/cpp/MySQL/Poco/*.h")
|
||||
FILE(GLOB PROTO_GRADIDO "build/proto/gradido/*.cc" "build/proto/gradido/*.h")
|
||||
FILE(GLOB PROTO_HEDERA "build/proto/hedera/*.cc" "build/proto/hedera/*.h")
|
||||
|
||||
# used only for test project
|
||||
FILE(GLOB TEST "src/cpp/test/*.cpp" "src/cpp/test/*.h")
|
||||
@ -230,9 +173,9 @@ FILE(GLOB TEST_CONTROLLER "src/cpp/test/controller/*.cpp" "src/cpp/test/controll
|
||||
SET(LOCAL_SRCS
|
||||
${CONTROLLER} ${TINF} ${MAIN} ${HTTPInterface} ${COMPILED_PAGES}
|
||||
${JSONInterface} ${CRYPTO}
|
||||
${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} ${MODEL_HEDERA} ${MODEL_GRADIDO}
|
||||
${MODEL} ${MODEL_TABLE} ${MODEL_EMAIL} ${MODEL_GRADIDO}
|
||||
${SINGLETON_MANAGER} ${LIB_SRC} ${MYSQL} ${TASKS}
|
||||
${PROTO_GRADIDO} ${PROTO_HEDERA}
|
||||
${PROTO_GRADIDO}
|
||||
)
|
||||
SET(LOCAL_TEST_SRC
|
||||
${TEST} ${TEST_CRYPTO} ${TEST_MODEL} ${TEST_MODEL_TABLE} ${TEST_CONTROLLER}
|
||||
@ -243,13 +186,11 @@ if(MSVC)
|
||||
# src
|
||||
source_group("controller" FILES ${CONTROLLER})
|
||||
source_group("proto\\gradido" FILES ${PROTO_GRADIDO})
|
||||
source_group("proto\\hedera" FILES ${PROTO_HEDERA})
|
||||
source_group("tinf" FILES ${TINF})
|
||||
source_group("Crypto" FILES ${CRYPTO})
|
||||
source_group("tasks" FILES ${TASKS})
|
||||
source_group("model\\table" FILES ${MODEL_TABLE})
|
||||
source_group("model\\email" FILES ${MODEL_EMAIL})
|
||||
source_group("model\\hedera" FILES ${MODEL_HEDERA})
|
||||
source_group("model\\gradido" FILES ${MODEL_GRADIDO})
|
||||
source_group("model" FILES ${MODEL})
|
||||
source_group("mysql" FILES ${MYSQL})
|
||||
@ -266,7 +207,6 @@ if(MSVC)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
add_executable(Gradido_LoginServer ${LOCAL_SRCS})
|
||||
|
||||
############################## config and add mariadb ###################################
|
||||
@ -318,7 +258,7 @@ if(WIN32)
|
||||
#TARGET_LINK_LIBRARIES(Gradido_LoginServer optimized ${MYSQL_LIBRARIES} Shlwapi)
|
||||
#TARGET_LINK_LIBRARIES(Gradido_LoginServer debug ${COMPILED_MARIADB_CLIENT_DEBUG} Shlwapi)
|
||||
else() # unix
|
||||
target_link_libraries(Gradido_LoginServer ${POCO_LIBS} libmariadb sodium)
|
||||
target_link_libraries(Gradido_LoginServer ${POCO_LIBS} libmariadb sodium libprotobuf)
|
||||
endif()
|
||||
|
||||
# install
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
CREATE TABLE `crypto_keys` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`private_key` varbinary(80) NOT NULL,
|
||||
`public_key` binary(32) NOT NULL,
|
||||
`crypto_key_type_id` int NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE(`public_key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -1,12 +0,0 @@
|
||||
CREATE TABLE `hedera_accounts` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int unsigned NOT NULL,
|
||||
`account_hedera_id` int unsigned NOT NULL,
|
||||
`account_key_id` int unsigned NOT NULL,
|
||||
`balance` bigint unsigned NOT NULL DEFAULT '0',
|
||||
`network_type` int NOT NULL DEFAULT '0',
|
||||
`updated` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `account_hedera_id` (`account_hedera_id`),
|
||||
UNIQUE KEY `account_key_id` (`account_key_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -1,7 +0,0 @@
|
||||
CREATE TABLE `hedera_ids` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`shardNum` bigint NOT NULL DEFAULT '0',
|
||||
`realmNum` bigint NOT NULL DEFAULT '0',
|
||||
`num` bigint NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -1,16 +0,0 @@
|
||||
CREATE TABLE `hedera_topics` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`topic_hedera_id` int unsigned NOT NULL,
|
||||
`name` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`auto_renew_account_hedera_id` int unsigned DEFAULT NULL,
|
||||
`auto_renew_period` int unsigned NOT NULL DEFAULT '0',
|
||||
`group_id` int unsigned NOT NULL,
|
||||
`admin_key_id` int unsigned DEFAULT NULL,
|
||||
`submit_key_id` int unsigned DEFAULT NULL,
|
||||
`current_timeout` DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',
|
||||
`sequence_number` bigint unsigned DEFAULT '0',
|
||||
`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`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -1,10 +0,0 @@
|
||||
CREATE TABLE `node_servers` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`url` VARCHAR(255) NOT NULL,
|
||||
`port` INT UNSIGNED NOT NULL,
|
||||
`group_id` INT UNSIGNED NULL DEFAULT '0',
|
||||
`server_type` INT UNSIGNED NOT NULL DEFAULT '0',
|
||||
`node_hedera_id` INT UNSIGNED NULL DEFAULT '0',
|
||||
`last_live_sign` DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -1,7 +1,6 @@
|
||||
CREATE TABLE `pending_tasks` (
|
||||
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int UNSIGNED DEFAULT 0,
|
||||
`hedera_id` int UNSIGNED DEFAULT 0,
|
||||
`request` varbinary(2048) NOT NULL,
|
||||
`created` datetime NOT NULL,
|
||||
`finished` datetime DEFAULT '2000-01-01 000000',
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "SingletonManager/SessionManager.h"
|
||||
#include "SingletonManager/EmailManager.h"
|
||||
#include "SingletonManager/PendingTasksManager.h"
|
||||
#include "SingletonManager/CronManager.h"
|
||||
|
||||
#include "controller/User.h"
|
||||
|
||||
@ -168,7 +167,7 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
|
||||
createConsoleFileAsyncLogger("emailLog", log_Path + "emailLog.txt");
|
||||
|
||||
// *************** load from config ********************************************
|
||||
|
||||
|
||||
std::string cfg_Path = Poco::Path::config() + "grd_login/";
|
||||
try {
|
||||
if(mConfigPath != "") {
|
||||
@ -224,7 +223,7 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
|
||||
errorLog.error("[Gradido_LoginServer::main] Poco Exception by register MySQL Connector: %s", ex.displayText());
|
||||
return Application::EXIT_CONFIG;
|
||||
}
|
||||
|
||||
|
||||
auto conn = ConnectionManager::getInstance();
|
||||
//conn->setConnection()
|
||||
//printf("try connect login server mysql db\n");
|
||||
@ -255,7 +254,7 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
|
||||
errorLog.error("[Gradido_LoginServer::main] error init server SSL Client");
|
||||
return Application::EXIT_CONFIG;
|
||||
}
|
||||
|
||||
|
||||
// schedule email verification resend
|
||||
controller::User::checkIfVerificationEmailsShouldBeResend(ServerConfig::g_CronJobsTimer);
|
||||
controller::User::addMissingEmailHashes();
|
||||
@ -281,14 +280,12 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
|
||||
// load pending tasks not finished in last session
|
||||
PendingTasksManager::getInstance()->load();
|
||||
int php_server_ping = config().getInt("phpServer.ping", 600000);
|
||||
CronManager::getInstance()->init(php_server_ping);
|
||||
|
||||
printf("[Gradido_LoginServer::main] started in %s\n", usedTime.string().data());
|
||||
std::clog << "[Gradido_LoginServer::main] started in " << usedTime.string().data() << std::endl;
|
||||
// wait for CTRL-C or kill
|
||||
waitForTerminationRequest();
|
||||
|
||||
CronManager::getInstance()->stop();
|
||||
|
||||
// Stop the HTTPServer
|
||||
srv.stop();
|
||||
|
||||
@ -24,17 +24,11 @@
|
||||
#include "DebugMnemonicPage.h"
|
||||
#include "AdminCheckUserBackupPage.h"
|
||||
#include "TranslatePassphrasePage.h"
|
||||
#include "PassphrasedTransactionPage.h"
|
||||
#include "AdminUserPasswordResetPage.h"
|
||||
#include "RegisterDirectPage.h"
|
||||
#include "AdminGroupsPage.h"
|
||||
#include "AdminTopicPage.h"
|
||||
#include "AdminHederaAccountPage.h"
|
||||
#include "AdminNodeServerPage.h"
|
||||
#include "AdminNodeServerTestPage.h"
|
||||
|
||||
#include "DecodeTransactionPage.h"
|
||||
#include "RepairDefectPassphrasePage.h"
|
||||
|
||||
|
||||
#include "../SingletonManager/SessionManager.h"
|
||||
@ -121,7 +115,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
|
||||
// TODO: count invalid session requests from IP and block IP for some time to prevent brute force session hijacking
|
||||
// or use log file and configure fail2ban for this to do
|
||||
|
||||
|
||||
if (url_first_part == "/checkEmail") {
|
||||
//return new CheckEmailPage(s);
|
||||
//printf("url checkEmail\n");
|
||||
@ -147,12 +141,8 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
mLogging.information(dateTimeString + " decode");
|
||||
return basicSetup(new DecodeTransactionPage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/passphrased_transaction") {
|
||||
return basicSetup(new PassphrasedTransactionPage, request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/adminNodeServerTest") {
|
||||
return basicSetup(new AdminNodeServerTestPage, request, timeUsed);
|
||||
}
|
||||
|
||||
|
||||
if (s) {
|
||||
if (externReferer != "") {
|
||||
|
||||
@ -178,9 +168,6 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
if (url_first_part == "/transform_passphrase") {
|
||||
return basicSetup(new TranslatePassphrasePage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/repairPassphrase") {
|
||||
return basicSetup(new RepairDefectPassphrasePage(s), request, timeUsed);
|
||||
}
|
||||
if (userModel && userModel->getRole() == model::table::ROLE_ADMIN) {
|
||||
if (url_first_part == "/adminRegister") {
|
||||
return basicSetup(new RegisterAdminPage(s), request, timeUsed);
|
||||
@ -200,21 +187,12 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
if (url_first_part == "/groups") {
|
||||
return basicSetup(new AdminGroupsPage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/topic") {
|
||||
return basicSetup(new AdminTopicPage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/hedera_account") {
|
||||
return basicSetup(new AdminHederaAccountPage(s), request, timeUsed);
|
||||
}
|
||||
if (url_first_part == "/nodes") {
|
||||
return basicSetup(new AdminNodeServerPage(s), request, timeUsed);
|
||||
}
|
||||
}
|
||||
|
||||
if(url_first_part == "/logout") {
|
||||
sm->releaseSession(s);
|
||||
// remove cookie(s)
|
||||
|
||||
|
||||
//printf("session released\n");
|
||||
return basicSetup(new LoginPage(nullptr), request, timeUsed);
|
||||
}
|
||||
@ -223,7 +201,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
sm->releaseSession(s);
|
||||
|
||||
return basicSetup(new LoginPage(nullptr), request, timeUsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
auto sessionState = s->getSessionState();
|
||||
//printf("session state: %s\n", s->getSessionStateString());
|
||||
@ -241,7 +219,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
||||
if (url_first_part == "/login" || url_first_part == "/") {
|
||||
return basicSetup(new LoginPage(s), request, timeUsed);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if (url_first_part == "/config") {
|
||||
@ -305,7 +283,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
||||
response.addCookie(Poco::Net::HTTPCookie("user", std::to_string(cookie_id)));
|
||||
*/
|
||||
}
|
||||
else {
|
||||
else {
|
||||
//sm->releaseSession(session);
|
||||
return basicSetup(new CheckEmailPage(session), request, timeUsed);
|
||||
}
|
||||
@ -325,7 +303,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
||||
//! -2 = critical error
|
||||
//! 0 = ok
|
||||
*/
|
||||
// update session, mark as verified
|
||||
// update session, mark as verified
|
||||
int retUpdateEmailVerification = session->updateEmailVerification(verificationCode);
|
||||
printf("[%s] return from update email verification: %d\n", __FUNCTION__, retUpdateEmailVerification);
|
||||
if (0 == retUpdateEmailVerification) {
|
||||
@ -340,7 +318,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
||||
pageRequestHandler = new PassphrasePage(session);
|
||||
}
|
||||
return basicSetup(pageRequestHandler, request, timeUsed);
|
||||
|
||||
|
||||
}
|
||||
else if (1 == retUpdateEmailVerification) {
|
||||
//auto user = session->getUser();
|
||||
@ -358,7 +336,7 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
||||
else if (-2 == retUpdateEmailVerification) {
|
||||
return basicSetup(new Error500Page(session), request, timeUsed);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (session) {
|
||||
sm->releaseSession(session);
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include "JsonCreateUser.h"
|
||||
#include "JsonGetLogin.h"
|
||||
#include "JsonUnknown.h"
|
||||
#include "JsonTransaction.h"
|
||||
#include "JsonGetRunningUserTasks.h"
|
||||
#include "JsonGetUsers.h"
|
||||
#include "JsonLoginViaEmailVerificationCode.h"
|
||||
@ -28,7 +27,7 @@
|
||||
#include "JsonSearch.h"
|
||||
|
||||
|
||||
JsonRequestHandlerFactory::JsonRequestHandlerFactory()
|
||||
JsonRequestHandlerFactory::JsonRequestHandlerFactory()
|
||||
: mRemoveGETParameters("^/([a-zA-Z0-9_-]*)"), mLogging(Poco::Logger::get("requestLog"))
|
||||
{
|
||||
}
|
||||
@ -75,9 +74,6 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c
|
||||
else if (url_first_part == "/checkSessionState") {
|
||||
return new JsonCheckSessionState;
|
||||
}
|
||||
else if (url_first_part == "/checkTransaction") {
|
||||
return new JsonTransaction;
|
||||
}
|
||||
else if (url_first_part == "/createTransaction") {
|
||||
return new JsonCreateTransaction;
|
||||
}
|
||||
@ -86,7 +82,7 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c
|
||||
}
|
||||
else if (url_first_part == "/getUsers") {
|
||||
return new JsonGetUsers;
|
||||
}
|
||||
}
|
||||
else if (url_first_part == "/networkInfos") {
|
||||
return new JsonNetworkInfos;
|
||||
}
|
||||
@ -136,7 +132,7 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c
|
||||
else if (url_first_part == "/logout") {
|
||||
return new JsonLogout(client_host);
|
||||
}
|
||||
|
||||
|
||||
return new JsonUnknown;
|
||||
}
|
||||
|
||||
|
||||
@ -1,171 +0,0 @@
|
||||
#include "JsonTransaction.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/Dynamic/Struct.h"
|
||||
|
||||
#include "../SingletonManager/SessionManager.h"
|
||||
#include "../ServerConfig.h"
|
||||
|
||||
Poco::JSON::Object* JsonTransaction::handle(Poco::Dynamic::Var params)
|
||||
{
|
||||
Poco::JSON::Object* result = new Poco::JSON::Object;
|
||||
int session_id = 0;
|
||||
|
||||
// if is json object
|
||||
if (params.type() == typeid(Poco::JSON::Object::Ptr)) {
|
||||
Poco::JSON::Object::Ptr paramJsonObject = params.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
try {
|
||||
/// Throws a RangeException if the value does not fit
|
||||
/// into the result variable.
|
||||
/// Throws a NotImplementedException if conversion is
|
||||
/// not available for the given type.
|
||||
/// Throws InvalidAccessException if Var is empty.
|
||||
paramJsonObject->get("session_id").convert(session_id);
|
||||
auto sm = SessionManager::getInstance();
|
||||
if (session_id != 0) {
|
||||
auto session = sm->getSession(session_id);
|
||||
if (!session) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "session not found");
|
||||
return result;
|
||||
}
|
||||
|
||||
int balance = 0;
|
||||
|
||||
if (!paramJsonObject->isNull("balance")) {
|
||||
paramJsonObject->get("balance").convert(balance);
|
||||
if (balance) {
|
||||
auto nu = session->getNewUser();
|
||||
if (!nu.isNull()) {
|
||||
nu->setBalance(balance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string transactionBase64String;
|
||||
Poco::Dynamic::Var transaction_base64 = paramJsonObject->get("transaction_base64");
|
||||
int alreadyEnlisted = 0;
|
||||
bool auto_sign = false;
|
||||
auto auto_sign_json = paramJsonObject->get("auto_sign");
|
||||
if (!auto_sign_json.isEmpty()) {
|
||||
auto_sign_json.convert(auto_sign);
|
||||
}
|
||||
|
||||
if (transaction_base64.isString()) {
|
||||
paramJsonObject->get("transaction_base64").convert(transactionBase64String);
|
||||
|
||||
if (!session->startProcessingTransaction(transactionBase64String, auto_sign)) {
|
||||
if (auto_sign) {
|
||||
auto errorJson = session->getErrorsArray();
|
||||
result->set("state", "error");
|
||||
result->set("msg", "error processing transaction");
|
||||
result->set("details", errorJson);
|
||||
return result;
|
||||
}
|
||||
auto lastError = session->getLastError();
|
||||
if (lastError) delete lastError;
|
||||
result->set("state", "error");
|
||||
result->set("msg", "already enlisted");
|
||||
return result;
|
||||
}
|
||||
|
||||
} else {
|
||||
Poco::DynamicStruct ds = *paramJsonObject;
|
||||
int alreadyEnlisted = 0;
|
||||
|
||||
for (int i = 0; i < ds["transaction_base64"].size(); i++) {
|
||||
ds["transaction_base64"][i].convert(transactionBase64String);
|
||||
if (!session->startProcessingTransaction(transactionBase64String, auto_sign)) {
|
||||
auto lastError = session->getLastError();
|
||||
if (lastError) delete lastError;
|
||||
alreadyEnlisted++;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyEnlisted > 0) {
|
||||
result->set("state", "warning");
|
||||
result->set("msg", std::to_string(alreadyEnlisted) + " already enlisted");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
result->set("state", "success");
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
printf("[JsonTransaction::handle] try to use params as jsonObject: %s\n", ex.displayText().data());
|
||||
result->set("state", "error");
|
||||
result->set("msg", "json exception");
|
||||
result->set("details", ex.displayText());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (params.isVector()) {
|
||||
const Poco::URI::QueryParameters queryParams = params.extract<Poco::URI::QueryParameters>();
|
||||
auto transactionIT = queryParams.begin();
|
||||
for (auto it = queryParams.begin(); it != queryParams.end(); it++) {
|
||||
if (it->first == "session_id") {
|
||||
session_id = stoi(it->second);
|
||||
//break;
|
||||
}
|
||||
else if (it->first == "transaction_base64") {
|
||||
transactionIT = it;
|
||||
}
|
||||
}
|
||||
if (session_id) {
|
||||
auto sm = SessionManager::getInstance();
|
||||
auto session = sm->getSession(session_id);
|
||||
if (!session) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "session not found");
|
||||
return result;
|
||||
}
|
||||
if (!session->startProcessingTransaction(transactionIT->second)) {
|
||||
auto lastError = session->getLastError();
|
||||
if (lastError) delete lastError;
|
||||
result->set("state", "error");
|
||||
result->set("msg", "already enlisted");
|
||||
return result;
|
||||
}
|
||||
result->set("state", "success");
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "session id not set");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (params.isStruct()) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "struct not implemented yet");
|
||||
}
|
||||
else if (params.isArray()) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "array not implemented yet");
|
||||
}
|
||||
else if (params.isList()) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "list not implemented yet");
|
||||
}
|
||||
else if (params.isString()) {
|
||||
result->set("state", "error");
|
||||
result->set("msg", "string not implemented yet");
|
||||
}
|
||||
else if (params.isDeque()) {
|
||||
result->set("state", "error");
|
||||
result->set("meg", "deque not implemented yet");
|
||||
}
|
||||
else {
|
||||
|
||||
result->set("state", "error");
|
||||
result->set("msg", "format not implemented");
|
||||
result->set("details", std::string(params.type().name()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
#ifndef __JSON_INTERFACE_JSON_TRANSACTION_
|
||||
#define __JSON_INTERFACE_JSON_TRANSACTION_
|
||||
|
||||
#include "JsonRequestHandler.h"
|
||||
|
||||
class Session;
|
||||
|
||||
class JsonTransaction : public JsonRequestHandler
|
||||
{
|
||||
public:
|
||||
Poco::JSON::Object* handle(Poco::Dynamic::Var params);
|
||||
|
||||
protected:
|
||||
bool startProcessingTransaction(Session* session, const std::string& transactionBase64);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // __JSON_INTERFACE_JSON_TRANSACTION_
|
||||
@ -21,7 +21,6 @@
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
#include "Poco/Environment.h"
|
||||
|
||||
#include "model/table/HederaAccount.h"
|
||||
|
||||
|
||||
using Poco::Net::SSLManager;
|
||||
@ -62,22 +61,19 @@ namespace ServerConfig {
|
||||
std::string g_gRPCRelayServerFullURL;
|
||||
MemoryBin* g_CryptoAppSecret = nullptr;
|
||||
AllowUnsecure g_AllowUnsecureFlags = NOT_UNSECURE;
|
||||
HederaConsensusMessageFormat g_ConsensusMessageFormat = HEDERA_CONSENSUS_FORMAT_BINARY;
|
||||
HederaNetworkType g_HederaNetworkType = HEDERA_TESTNET;
|
||||
Poco::Timespan g_HederaDefaultTimeout;
|
||||
|
||||
#ifdef __linux__
|
||||
#include <stdio.h>
|
||||
#ifdef __linux__
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif //#ifdef __linux__
|
||||
#endif //#ifdef __linux__
|
||||
|
||||
std::string getHostIpString()
|
||||
{
|
||||
#ifdef __linux__
|
||||
#ifdef __linux__
|
||||
struct ifaddrs * ifAddrStruct = NULL;
|
||||
struct ifaddrs * ifa = NULL;
|
||||
void * tmpAddrPtr = NULL;
|
||||
@ -107,7 +103,7 @@ namespace ServerConfig {
|
||||
}
|
||||
if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct);
|
||||
return ipAddressString;
|
||||
#else //__linux__
|
||||
#else //__linux__
|
||||
std::string ipAddressString = "";
|
||||
auto host = Poco::Net::DNS::thisHost();
|
||||
for (auto it = host.addresses().begin(); it != host.addresses().end(); it++) {
|
||||
@ -126,10 +122,10 @@ namespace ServerConfig {
|
||||
//break;
|
||||
}
|
||||
return ipAddressString;
|
||||
#endif // __linux__
|
||||
#endif // __linux__
|
||||
}
|
||||
|
||||
bool replaceZeroIPWithLocalhostIP(std::string& url)
|
||||
bool replaceZeroIPWithLocalhostIP(std::string& url)
|
||||
{
|
||||
auto pos = url.find("0.0.0.0", 0);
|
||||
if (pos != std::string::npos) {
|
||||
@ -138,7 +134,7 @@ namespace ServerConfig {
|
||||
url.replace(pos, 7, ipAddressString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//printf("ipaddress: %s\n", ipAddress.data());
|
||||
|
||||
return true;
|
||||
@ -157,22 +153,6 @@ namespace ServerConfig {
|
||||
return SERVER_TYPE_PRODUCTION;
|
||||
}
|
||||
|
||||
HederaConsensusMessageFormat getHederaConsensusMessageFormatFromString(const std::string& hederaConsensusMessageFormatString)
|
||||
{
|
||||
if ("json" == hederaConsensusMessageFormatString) {
|
||||
return HEDERA_CONSENSUS_FORMAT_JSON;
|
||||
}
|
||||
if ("binary" == hederaConsensusMessageFormatString || "bin" == hederaConsensusMessageFormatString) {
|
||||
return HEDERA_CONSENSUS_FORMAT_BINARY;
|
||||
}
|
||||
if ("base64" == hederaConsensusMessageFormatString) {
|
||||
return HEDERA_CONSENSUS_FORMAT_BASE64_URLSAVE_NO_PADDING;
|
||||
}
|
||||
return HEDERA_CONSENSUS_FORMAT_BINARY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool loadMnemonicWordLists()
|
||||
{
|
||||
@ -227,7 +207,7 @@ namespace ServerConfig {
|
||||
g_ServerCryptoKey = new ObfusArray(realBinSize, key);
|
||||
g_ServerKeySeed = new ObfusArray(9*8);
|
||||
Poco::Int64 i1 = randombytes_random();
|
||||
Poco::Int64 i2 = randombytes_random();
|
||||
Poco::Int64 i2 = randombytes_random();
|
||||
g_ServerKeySeed->put(0, i1 | (i2 << 8));
|
||||
|
||||
//g_ServerAdminPublic = cfg.getString("crypto.server_admin_public");
|
||||
@ -245,20 +225,12 @@ namespace ServerConfig {
|
||||
replaceZeroIPWithLocalhostIP(g_php_serverPath);
|
||||
g_php_serverHost = cfg.getString("phpServer.host", "");
|
||||
replaceZeroIPWithLocalhostIP(g_php_serverHost);
|
||||
//g_ServerSetupType
|
||||
//g_ServerSetupType
|
||||
auto serverSetupTypeString = cfg.getString("ServerSetupType", "");
|
||||
g_ServerSetupType = getServerSetupTypeFromString(serverSetupTypeString);
|
||||
|
||||
g_devDefaultGroup = cfg.getString("dev.default_group", "");
|
||||
|
||||
auto hedera_consensus_message_format_string = cfg.getString("hedera.consensus.message_format", "bin");
|
||||
g_ConsensusMessageFormat = getHederaConsensusMessageFormatFromString(hedera_consensus_message_format_string);
|
||||
|
||||
auto hedera_network_type_string = cfg.getString("hedera.nettype", "Testnet");
|
||||
g_HederaNetworkType = model::table::HederaAccount::hederaNetworkTypeFromString(hedera_network_type_string);
|
||||
if (HEDERA_UNKNOWN == g_HederaNetworkType) {
|
||||
g_HederaNetworkType = HEDERA_TESTNET;
|
||||
}
|
||||
|
||||
// app secret for encrypt user private keys
|
||||
// TODO: encrypt with server admin key
|
||||
@ -284,8 +256,7 @@ namespace ServerConfig {
|
||||
if (cfg.getInt("unsecure.allow_all_passwords", 0) == 1) {
|
||||
g_AllowUnsecureFlags = (AllowUnsecure)(g_AllowUnsecureFlags | UNSECURE_ALLOW_ALL_PASSWORDS);
|
||||
}
|
||||
|
||||
g_HederaDefaultTimeout = cfg.getInt("hedera.default_timeout", 5);
|
||||
|
||||
|
||||
g_gRPCRelayServerFullURL = cfg.getString("grpc.server", "");
|
||||
|
||||
@ -338,8 +309,8 @@ namespace ServerConfig {
|
||||
try {
|
||||
#ifdef POCO_NETSSL_WIN
|
||||
g_SSL_CLient_Context = new Context(Context::CLIENT_USE, "cacert.pem", Context::VERIFY_RELAXED, Context::OPT_DEFAULTS);
|
||||
#else
|
||||
|
||||
#else
|
||||
|
||||
g_SSL_CLient_Context = new Context(Context::CLIENT_USE, "", "", Poco::Path::config() + "grd_login/cacert.pem", Context::VERIFY_RELAXED, 9, true, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
|
||||
#endif
|
||||
} catch(Poco::Exception& ex) {
|
||||
@ -391,7 +362,7 @@ namespace ServerConfig {
|
||||
Poco::LocalDateTime now;
|
||||
|
||||
std::string dateTimeStr = Poco::DateTimeFormatter::format(now, Poco::DateTimeFormat::ISO8601_FORMAT);
|
||||
file << dateTimeStr << std::endl;
|
||||
file << dateTimeStr << std::endl;
|
||||
|
||||
for (std::string line; std::getline(datas, line); ) {
|
||||
file << line << std::endl;
|
||||
@ -400,4 +371,4 @@ namespace ServerConfig {
|
||||
file.close();
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,21 +48,6 @@ namespace ServerConfig {
|
||||
UNSECURE_ALLOW_ALL_PASSWORDS = 8
|
||||
};
|
||||
|
||||
enum HederaConsensusMessageFormat {
|
||||
HEDERA_CONSENSUS_FORMAT_BINARY,
|
||||
HEDERA_CONSENSUS_FORMAT_JSON,
|
||||
HEDERA_CONSENSUS_FORMAT_BASE64_URLSAVE_NO_PADDING
|
||||
};
|
||||
|
||||
enum HederaNetworkType {
|
||||
HEDERA_MAINNET,
|
||||
HEDERA_TESTNET,
|
||||
HEDERA_NET_COUNT,
|
||||
HEDERA_UNKNOWN
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
extern Mnemonic g_Mnemonic_WordLists[MNEMONIC_MAX];
|
||||
|
||||
@ -92,16 +77,13 @@ namespace ServerConfig {
|
||||
extern std::string g_gRPCRelayServerFullURL;
|
||||
extern MemoryBin* g_CryptoAppSecret;
|
||||
extern AllowUnsecure g_AllowUnsecureFlags;
|
||||
extern HederaConsensusMessageFormat g_ConsensusMessageFormat;
|
||||
extern HederaNetworkType g_HederaNetworkType;
|
||||
extern Poco::Timespan g_HederaDefaultTimeout;
|
||||
|
||||
|
||||
bool loadMnemonicWordLists();
|
||||
bool initServerCrypto(const Poco::Util::LayeredConfiguration& cfg);
|
||||
bool initEMailAccount(const Poco::Util::LayeredConfiguration& cfg);
|
||||
bool initSSLClientContext();
|
||||
|
||||
|
||||
|
||||
void writeToFile(std::istream& datas, std::string fileName);
|
||||
|
||||
@ -109,4 +91,4 @@ namespace ServerConfig {
|
||||
};
|
||||
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_SERVER_CONFIG__
|
||||
#endif //__GRADIDO_LOGIN_SERVER_SERVER_CONFIG__
|
||||
|
||||
@ -1,200 +0,0 @@
|
||||
#include "CronManager.h"
|
||||
#include "../lib/JsonRequest.h"
|
||||
|
||||
#include "../ServerConfig.h"
|
||||
|
||||
|
||||
|
||||
CronManager::CronManager()
|
||||
: mInitalized(false), mMainTimer(1000, 600000)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CronManager::~CronManager()
|
||||
{
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock(mMainWorkMutex);
|
||||
|
||||
mMainTimer.stop();
|
||||
mInitalized = false;
|
||||
|
||||
}
|
||||
|
||||
CronManager* CronManager::getInstance()
|
||||
{
|
||||
static CronManager one;
|
||||
return &one;
|
||||
}
|
||||
|
||||
bool CronManager::init(long defaultPeriodicIntervallMilliseconds/* = 600000*/)
|
||||
{
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock(mMainWorkMutex);
|
||||
mInitalized = true;
|
||||
controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_COMMUNITY);
|
||||
|
||||
mDefaultIntervalMilliseconds = defaultPeriodicIntervallMilliseconds;
|
||||
mMainTimer.setPeriodicInterval(defaultPeriodicIntervallMilliseconds);
|
||||
Poco::TimerCallback<CronManager> callback(*this, &CronManager::runUpdateStep);
|
||||
mMainTimer.start(callback);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CronManager::stop()
|
||||
{
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock(mMainWorkMutex);
|
||||
mInitalized = false;
|
||||
mMainTimer.stop();
|
||||
}
|
||||
|
||||
void CronManager::runUpdateStep(Poco::Timer& timer)
|
||||
{
|
||||
auto current = Poco::DateTime();
|
||||
//printf("%s [CronManager::runUpdateStep] \n", Poco::DateTimeFormatter::format(current, "%d.%m.%y %H:%M:%S.%i").data());
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock(mMainWorkMutex);
|
||||
if (!mInitalized) {
|
||||
return;
|
||||
}
|
||||
mNodeServersToPingMutex.lock();
|
||||
for (auto it = mNodeServersToPing.begin(); it != mNodeServersToPing.end(); it++)
|
||||
{
|
||||
// TODO: Make sure that task not already running, for example if community server needs more time for processing that between calls
|
||||
// or with schedule update run to short time between calls
|
||||
UniLib::controller::TaskPtr ping_node_server_task(new PingServerTask(*it));
|
||||
ping_node_server_task->scheduleTask(ping_node_server_task);
|
||||
}
|
||||
mNodeServersToPingMutex.unlock();
|
||||
|
||||
mTimestampsMutex.lock();
|
||||
//printf("update timestamp sizes: %d\n", mUpdateTimestamps.size());
|
||||
bool timerRestarted = false;
|
||||
|
||||
if (mUpdateTimestamps.size() > 0)
|
||||
{
|
||||
Poco::Timestamp now;
|
||||
// update maximal once per second
|
||||
now += Poco::Timespan(1, 0);
|
||||
while (mUpdateTimestamps.size() > 0 && mUpdateTimestamps.front() < now) {
|
||||
// printf("remove update time in past: %d\n", mUpdateTimestamps.front().epochTime());
|
||||
mUpdateTimestamps.pop_front();
|
||||
}
|
||||
if (mUpdateTimestamps.size() > 0) {
|
||||
Poco::Timespan next_run = mUpdateTimestamps.front() - now;
|
||||
//printf("timer restart called with: %d\n", next_run.seconds());
|
||||
//mMainTimer.setPeriodicInterval(next_run.totalMilliseconds());
|
||||
mMainTimer.restart(next_run.totalMilliseconds());
|
||||
mUpdateTimestamps.pop_front();
|
||||
timerRestarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!timerRestarted && mMainTimer.getPeriodicInterval() != mDefaultIntervalMilliseconds) {
|
||||
//printf("reset to default interval\n");
|
||||
mMainTimer.setPeriodicInterval(mDefaultIntervalMilliseconds);
|
||||
//mMainTimer.restart(mDefaultIntervalMilliseconds);
|
||||
}
|
||||
mTimestampsMutex.unlock();
|
||||
//printf("[CronManager::runUpdateStep] end\n");
|
||||
}
|
||||
|
||||
void CronManager::scheduleUpdateRun(Poco::Timespan timespanInFuture)
|
||||
{
|
||||
Poco::Timestamp timestamp;
|
||||
timestamp += timespanInFuture;
|
||||
|
||||
mTimestampsMutex.lock();
|
||||
//printf("[CronManager::scheduleUpdateRun] push:\n%d\n", timestamp.epochTime());
|
||||
mUpdateTimestamps.push_back(timestamp);
|
||||
mUpdateTimestamps.sort();
|
||||
auto frontTimestamp = mUpdateTimestamps.front();
|
||||
auto backTimestamp = mUpdateTimestamps.back();
|
||||
//printf("[CronManager::scheduleUpdateRun] front timestamp and back timestamp:\n%d\n%d\n", frontTimestamp.epochTime(), backTimestamp.epochTime());
|
||||
//printf("current: \n%d\n", Poco::Timestamp().epochTime());
|
||||
Poco::Timespan next_run = mUpdateTimestamps.front() - Poco::Timestamp();
|
||||
|
||||
Poco::DateTime now;
|
||||
std::string now_string = Poco::DateTimeFormatter::format(now, "%d.%m.%y %H:%M:%S.%i");
|
||||
//printf("%s [CronManager::scheduleUpdateRun] next run in %d seconds, %d millis (intervall: %d, default: %d)\n",
|
||||
//now_string.data(), next_run.seconds(), next_run.milliseconds(), mMainTimer.getPeriodicInterval(), mDefaultIntervalMilliseconds);
|
||||
if (next_run.seconds() > 0 && mMainTimer.getPeriodicInterval() == mDefaultIntervalMilliseconds) {
|
||||
if (mMainWorkMutex.tryLock(100)) {
|
||||
mMainTimer.restart(next_run.totalMilliseconds());
|
||||
mUpdateTimestamps.pop_front();
|
||||
mMainWorkMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
mTimestampsMutex.unlock();
|
||||
//printf("[CronManager::scheduleUpdateRun] end\n");
|
||||
}
|
||||
|
||||
|
||||
void CronManager::addNodeServerToPing(Poco::AutoPtr<controller::NodeServer> nodeServer)
|
||||
{
|
||||
if (nodeServer.isNull() || !nodeServer->getModel()) {
|
||||
return;
|
||||
}
|
||||
if (isNodeServerInList(nodeServer)) {
|
||||
return;
|
||||
}
|
||||
mNodeServersToPingMutex.lock();
|
||||
mNodeServersToPing.push_back(nodeServer);
|
||||
mNodeServersToPingMutex.unlock();
|
||||
|
||||
}
|
||||
void CronManager::removeNodeServerToPing(Poco::AutoPtr<controller::NodeServer> nodeServer)
|
||||
{
|
||||
if (nodeServer.isNull() || !nodeServer->getModel()) {
|
||||
return;
|
||||
}
|
||||
mNodeServersToPingMutex.lock();
|
||||
int node_server_id = nodeServer->getModel()->getID();
|
||||
for (auto it = mNodeServersToPing.begin(); it != mNodeServersToPing.end(); it++) {
|
||||
if ((*it)->getModel()->getID() == node_server_id) {
|
||||
mNodeServersToPing.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mNodeServersToPingMutex.unlock();
|
||||
}
|
||||
|
||||
bool CronManager::isNodeServerInList(Poco::AutoPtr<controller::NodeServer> nodeServer)
|
||||
{
|
||||
bool result = false;
|
||||
mNodeServersToPingMutex.lock();
|
||||
int node_server_id = nodeServer->getModel()->getID();
|
||||
for (auto it = mNodeServersToPing.begin(); it != mNodeServersToPing.end(); it++) {
|
||||
if ((*it)->getModel()->getID() == node_server_id) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mNodeServersToPingMutex.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
// ***********************************************************************************************************
|
||||
PingServerTask::PingServerTask(Poco::AutoPtr<controller::NodeServer> nodeServer)
|
||||
: CPUTask(ServerConfig::g_CPUScheduler), mNodeServer(nodeServer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PingServerTask::~PingServerTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int PingServerTask::run()
|
||||
{
|
||||
//return 0;
|
||||
auto current = Poco::DateTime();
|
||||
if (model::table::NODE_SERVER_GRADIDO_COMMUNITY == mNodeServer->getModel()->getNodeServerType()) {
|
||||
std::string url_port = mNodeServer->getModel()->getUrlWithPort();
|
||||
printf("%s [PingServerTask::run] call update for %s\n", Poco::DateTimeFormatter::format(current, "%d.%m.%y %H:%M:%S.%i").data(), url_port.data());
|
||||
|
||||
auto json_request = mNodeServer->createJsonRequest();
|
||||
json_request.request("updateReadNode");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_CRON_MANAGER_H
|
||||
#define __GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_CRON_MANAGER_H
|
||||
|
||||
#include "Poco/Timer.h"
|
||||
#include "../controller/NodeServer.h"
|
||||
#include "../tasks/CPUTask.h"
|
||||
|
||||
|
||||
/*!
|
||||
* \author: Dario Rekowski
|
||||
*
|
||||
* \date: 2020-11-03
|
||||
*
|
||||
* \brief: Manager for "Cron"-like Tasks.
|
||||
*
|
||||
* Ping for example community server to get new blocks from nodes
|
||||
* or Hedera Tasks to (re)try receiving Transaction Receipts
|
||||
*
|
||||
*/
|
||||
class CronManager
|
||||
{
|
||||
public:
|
||||
~CronManager();
|
||||
|
||||
static CronManager* getInstance();
|
||||
|
||||
bool init(long defaultPeriodicIntervallMilliseconds = 600000);
|
||||
void stop();
|
||||
|
||||
void runUpdateStep(Poco::Timer& timer);
|
||||
void scheduleUpdateRun(Poco::Timespan timespanInFuture);
|
||||
|
||||
|
||||
void addNodeServerToPing(Poco::AutoPtr<controller::NodeServer> nodeServer);
|
||||
void removeNodeServerToPing(Poco::AutoPtr<controller::NodeServer> nodeServer);
|
||||
|
||||
protected:
|
||||
CronManager();
|
||||
|
||||
bool isNodeServerInList(Poco::AutoPtr<controller::NodeServer> nodeServer);
|
||||
bool mInitalized;
|
||||
|
||||
Poco::Timer mMainTimer;
|
||||
std::list<Poco::AutoPtr<controller::NodeServer>> mNodeServersToPing;
|
||||
std::list<Poco::Timestamp> mUpdateTimestamps;
|
||||
Poco::FastMutex mNodeServersToPingMutex;
|
||||
Poco::FastMutex mMainWorkMutex;
|
||||
Poco::FastMutex mTimestampsMutex;
|
||||
long mDefaultIntervalMilliseconds;
|
||||
};
|
||||
|
||||
class PingServerTask : public UniLib::controller::CPUTask
|
||||
{
|
||||
public:
|
||||
PingServerTask(Poco::AutoPtr<controller::NodeServer> nodeServer);
|
||||
virtual ~PingServerTask();
|
||||
|
||||
const char* getResourceType() const { return "PingServerTask"; }
|
||||
|
||||
int run();
|
||||
|
||||
protected:
|
||||
Poco::AutoPtr<controller::NodeServer> mNodeServer;
|
||||
};
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_SINGLETON_MANAGER_CRON_MANAGER_H
|
||||
@ -1,150 +0,0 @@
|
||||
|
||||
#include "CryptoKey.h"
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
CryptoKey::CryptoKey(model::table::CryptoKey* dbModel)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
}
|
||||
|
||||
CryptoKey::~CryptoKey()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<CryptoKey> CryptoKey::create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr<controller::User> user, bool saveEncrypted/* = true*/)
|
||||
{
|
||||
auto mm = MemoryManager::getInstance();
|
||||
|
||||
MemoryBin* private_key = nullptr;
|
||||
auto public_key = hederaKeyPair->getPublicKeyCopy();
|
||||
|
||||
model::table::KeyType key_type;
|
||||
if (saveEncrypted) {
|
||||
key_type = model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED;
|
||||
private_key = hederaKeyPair->getCryptedPrivKey(user->getPassword());
|
||||
}
|
||||
else {
|
||||
key_type = model::table::KEY_TYPE_ED25519_HEDERA_CLEAR;
|
||||
private_key = hederaKeyPair->getPrivateKeyCopy();
|
||||
}
|
||||
auto db = new model::table::CryptoKey(private_key, public_key, key_type);
|
||||
|
||||
mm->releaseMemory(private_key);
|
||||
mm->releaseMemory(public_key);
|
||||
|
||||
auto cryptoKey = new CryptoKey(db);
|
||||
return Poco::AutoPtr<CryptoKey>(cryptoKey);
|
||||
}
|
||||
|
||||
Poco::AutoPtr<CryptoKey> CryptoKey::load(int id)
|
||||
{
|
||||
auto db = new model::table::CryptoKey();
|
||||
if (1 == db->loadFromDB("id", id)) {
|
||||
auto cryptoKey = new CryptoKey(db);
|
||||
return Poco::AutoPtr<CryptoKey>(cryptoKey);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<CryptoKey> CryptoKey::load(MemoryBin* publicKey)
|
||||
{
|
||||
return load(*publicKey, publicKey->size());
|
||||
}
|
||||
|
||||
Poco::AutoPtr<CryptoKey> CryptoKey::load(const unsigned char* publicKey, size_t size)
|
||||
{
|
||||
assert(publicKey);
|
||||
assert(size);
|
||||
|
||||
Poco::Data::BLOB public_key_blob(publicKey, size);
|
||||
auto db = new model::table::CryptoKey();
|
||||
auto count = db->loadFromDB<Poco::Data::BLOB>("public_key", public_key_blob);
|
||||
if (!count) return nullptr;
|
||||
if (1 == count) return new CryptoKey(db);
|
||||
|
||||
auto em = ErrorManager::getInstance();
|
||||
em->addError(new Error("CryptoKey::load", "found more than one crypto key with same public key"));
|
||||
em->sendErrorsAsEmail();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<KeyPairHedera> CryptoKey::getKeyPair(Poco::AutoPtr<controller::User> user) const
|
||||
{
|
||||
auto model = getModel();
|
||||
assert(model);
|
||||
|
||||
if (!model->isEncrypted()) {
|
||||
return getKeyPair();
|
||||
}
|
||||
|
||||
if (!model->hasPrivateKey()) {
|
||||
printf("[CryptoKey::getKeyPair] return null, no private key\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto password = user->getPassword();
|
||||
auto mm = MemoryManager::getInstance();
|
||||
if (!password) {
|
||||
printf("[CryptoKey::getKeyPair] return null, password empty\n");
|
||||
}
|
||||
MemoryBin* clearPrivateKey = nullptr;
|
||||
auto encrypted_private_key = model->getPrivateKey();
|
||||
//auto encrypted_private_key_hex_string = DataTypeConverter::binToHex(encrypted_private_key);
|
||||
//printf("[CryptoKey::getKeyPair] encrypted private key hex: %s\n", encrypted_private_key_hex_string.data());
|
||||
if (password->decrypt(model->getPrivateKey(), &clearPrivateKey) != SecretKeyCryptography::AUTH_DECRYPT_OK) {
|
||||
printf("[CryptoKey::getKeyPair] return null, error decrypting\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto key_pair = std::make_unique<KeyPairHedera>(clearPrivateKey->data(), clearPrivateKey->size(), model->getPublicKey(), model->getPublicKeySize());
|
||||
mm->releaseMemory(clearPrivateKey);
|
||||
return key_pair;
|
||||
}
|
||||
|
||||
std::unique_ptr<KeyPairHedera> CryptoKey::getKeyPair() const
|
||||
{
|
||||
auto model = getModel();
|
||||
assert(model);
|
||||
if (!model->hasPrivateKey() || model->isEncrypted()) {
|
||||
printf("[CryptoKey::getKeyPair] no private key or encrypted\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
return std::make_unique<KeyPairHedera>(model->getPrivateKey(), model->getPublicKey(), model->getPublicKeySize());
|
||||
}
|
||||
|
||||
bool CryptoKey::changeEncryption(Poco::AutoPtr<controller::User> user)
|
||||
{
|
||||
auto key_pair = getKeyPair(user);
|
||||
if (!key_pair || !key_pair->hasPrivateKey()) {
|
||||
addError(new Error("Crypto Key", "key pair or private key was null"));
|
||||
return false;
|
||||
}
|
||||
auto model = getModel();
|
||||
auto mm = MemoryManager::getInstance();
|
||||
// update key type
|
||||
model->changeKeyTypeToggleEncrypted();
|
||||
MemoryBin* private_key = nullptr;
|
||||
if (model->isEncrypted()) {
|
||||
private_key = key_pair->getCryptedPrivKey(user->getPassword());
|
||||
}
|
||||
else {
|
||||
private_key = key_pair->getPrivateKeyCopy();
|
||||
}
|
||||
if (!private_key) {
|
||||
addError(new Error("Crypto Key", " private_key not get"));
|
||||
return false;
|
||||
}
|
||||
model->setPrivateKey(private_key);
|
||||
// save changes into db
|
||||
model->updatePrivkeyAndKeyType();
|
||||
|
||||
mm->releaseMemory(private_key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE
|
||||
|
||||
#include "../model/table/CryptoKey.h"
|
||||
#include "../Crypto/KeyPairHedera.h"
|
||||
|
||||
#include "Poco/SharedPtr.h"
|
||||
|
||||
#include "TableControllerBase.h"
|
||||
#include "User.h"
|
||||
|
||||
|
||||
|
||||
namespace controller {
|
||||
|
||||
class HederaAccount;
|
||||
|
||||
class CryptoKey : public TableControllerBase, public NotificationList
|
||||
{
|
||||
friend HederaAccount;
|
||||
public:
|
||||
|
||||
~CryptoKey();
|
||||
|
||||
static Poco::AutoPtr<CryptoKey> create(const KeyPairHedera* hederaKeyPair, Poco::AutoPtr<controller::User> user, bool saveEncrypted = true);
|
||||
|
||||
//! if returned ptr is NULL, dataset not found
|
||||
static Poco::AutoPtr<CryptoKey> load(int id);
|
||||
static Poco::AutoPtr<CryptoKey> load(MemoryBin* publicKey);
|
||||
static Poco::AutoPtr<CryptoKey> load(const unsigned char* publicKey, size_t size);
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
|
||||
inline Poco::AutoPtr<model::table::CryptoKey> getModel() { return _getModel<model::table::CryptoKey>(); }
|
||||
inline const model::table::CryptoKey* getModel() const { return _getModel<model::table::CryptoKey>(); }
|
||||
|
||||
std::unique_ptr<KeyPairHedera> getKeyPair(Poco::AutoPtr<controller::User> user) const;
|
||||
std::unique_ptr<KeyPairHedera> getKeyPair() const;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool changeEncryption(Poco::AutoPtr<controller::User> user);
|
||||
CryptoKey(model::table::CryptoKey* dbModel);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_CRYPTO_KEY_INCLUDE
|
||||
@ -1,294 +0,0 @@
|
||||
|
||||
#include "HederaAccount.h"
|
||||
#include "NodeServer.h"
|
||||
#include "CryptoKey.h"
|
||||
#include "../model/hedera/Query.h"
|
||||
//#include "../model/hedera/Tr"
|
||||
#include "HederaRequest.h"
|
||||
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace controller {
|
||||
|
||||
HederaAccount::HederaAccount(model::table::HederaAccount* dbModel)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
}
|
||||
|
||||
HederaAccount::~HederaAccount()
|
||||
{
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaAccount::create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/, ServerConfig::HederaNetworkType type/* = HEDERA_MAINNET*/)
|
||||
{
|
||||
auto db = new model::table::HederaAccount(user_id, account_hedera_id, account_key_id, balance, type);
|
||||
auto group = new HederaAccount(db);
|
||||
return Poco::AutoPtr<HederaAccount>(group);
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<HederaAccount>> HederaAccount::load(const std::string& fieldName, int fieldValue)
|
||||
{
|
||||
auto db = new model::table::HederaAccount();
|
||||
auto hedera_account_list = db->loadFromDB<int, model::table::HederaAccountTuple>(fieldName, fieldValue, 2);
|
||||
std::vector<Poco::AutoPtr<HederaAccount>> resultVector;
|
||||
resultVector.reserve(hedera_account_list.size());
|
||||
for (auto it = hedera_account_list.begin(); it != hedera_account_list.end(); it++) {
|
||||
//mHederaID
|
||||
auto db = new model::table::HederaAccount(*it);
|
||||
auto hedera_account = new HederaAccount(db);
|
||||
resultVector.push_back(hedera_account);
|
||||
}
|
||||
return resultVector;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaAccount::load(int id)
|
||||
{
|
||||
auto db = new model::table::HederaAccount();
|
||||
if (1 == db->loadFromDB("id", id)) {
|
||||
return new HederaAccount(db);
|
||||
}
|
||||
db->release();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<controller::HederaId> HederaAccount::getHederaId()
|
||||
{
|
||||
if (mHederaID.isNull()) {
|
||||
mHederaID = HederaId::load(getModel()->getAccountHederaId());
|
||||
}
|
||||
return mHederaID;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaAccount::load(Poco::AutoPtr<controller::HederaId> hederaId)
|
||||
{
|
||||
if (!hederaId->isExistInDB()) return nullptr;
|
||||
|
||||
auto db = new model::table::HederaAccount();
|
||||
auto result_count = db->loadFromDB("account_hedera_id", hederaId->getModel()->getID());
|
||||
if (1 == result_count) {
|
||||
return new HederaAccount(db);
|
||||
}
|
||||
// maybe change later to using error manager and send email
|
||||
printf("[HederaAccount::load] result_count not expected: %d\n", result_count);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaAccount::pick(ServerConfig::HederaNetworkType networkType, bool encrypted/* = false*/, int user_id/* = 0*/)
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
Poco::Tuple<int, int, int, int, Poco::UInt64, Poco::UInt64, Poco::UInt64, Poco::UInt64> result_tuple;
|
||||
int crypto_key_type = encrypted ? model::table::KEY_TYPE_ED25519_HEDERA_ENCRYPTED : model::table::KEY_TYPE_ED25519_HEDERA_CLEAR;
|
||||
int network_type_int = (int)networkType;
|
||||
|
||||
select
|
||||
<< "SELECT account.id, account.user_id, account.account_hedera_id, account.account_key_id, account.balance, i.shardNum, i.realmNum, i.num "
|
||||
<< "FROM hedera_accounts as account "
|
||||
<< "JOIN hedera_ids as i ON(i.id = account_hedera_id) "
|
||||
<< "JOIN crypto_keys as k ON(k.id = account.account_key_id) "
|
||||
<< "WHERE account.network_type = ? "
|
||||
<< "AND k.crypto_key_type_id = ? ";
|
||||
|
||||
if (user_id > 0) {
|
||||
select << " AND account.user_id = ? ";
|
||||
}
|
||||
select << "ORDER BY RAND() LIMIT 1 "
|
||||
, into(result_tuple), use(network_type_int) , use(crypto_key_type);
|
||||
|
||||
if (user_id > 0) {
|
||||
select, use(user_id);
|
||||
}
|
||||
|
||||
try {
|
||||
select.executeAsync();
|
||||
select.wait();
|
||||
auto result_count = select.rowsExtracted();
|
||||
if (1 == result_count) {
|
||||
auto db = new model::table::HederaAccount(
|
||||
result_tuple.get<1>(), result_tuple.get<2>(), result_tuple.get<3>(),
|
||||
result_tuple.get<4>(), networkType
|
||||
);
|
||||
db->setID(result_tuple.get<0>());
|
||||
Poco::AutoPtr<HederaAccount> hedera_account(new HederaAccount(db));
|
||||
auto hedera_id_db = new model::table::HederaId(result_tuple.get<5>(), result_tuple.get<6>(), result_tuple.get<7>());
|
||||
Poco::AutoPtr<HederaId> hedera_id(new HederaId(hedera_id_db));
|
||||
hedera_account->setHederaId(hedera_id);
|
||||
return hedera_account;
|
||||
}
|
||||
else if(result_count > 1) {
|
||||
printf("[HederaAccount::pick] extracted rows not like expected\n");
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
auto em = ErrorManager::getInstance();
|
||||
static const char* function_name = "HederaAccount::pick";
|
||||
printf("exception: %s\n", ex.displayText().data());
|
||||
em->addError(new ParamError(function_name, "mysql error: ", ex.displayText()));
|
||||
em->addError(new ParamError(function_name, "network type: ", networkType));
|
||||
em->addError(new ParamError(function_name, "encrypted: ", (int)encrypted));
|
||||
em->sendErrorsAsEmail();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<HederaAccount>> HederaAccount::listAll()
|
||||
{
|
||||
auto db = new model::table::HederaAccount();
|
||||
std::vector<model::table::HederaAccountTuple> group_list;
|
||||
// throw an unresolved external symbol error
|
||||
group_list = db->loadAllFromDB<model::table::HederaAccountTuple>();
|
||||
|
||||
// work around for not working call to loadAllFromDB
|
||||
/*auto cm = ConnectionManager::getInstance();
|
||||
|
||||
Poco::Data::Statement select(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER));
|
||||
|
||||
select << "SELECT id, alias, name, url, description FROM " << db->getTableName()
|
||||
, Poco::Data::Keywords::into(group_list);
|
||||
|
||||
size_t resultCount = 0;
|
||||
try {
|
||||
resultCount = select.execute();
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
printf("[Group::listAll] poco exception: %s\n", ex.displayText().data());
|
||||
}
|
||||
//*/ //work around end
|
||||
std::vector<Poco::AutoPtr<HederaAccount>> resultVector;
|
||||
|
||||
resultVector.reserve(group_list.size());
|
||||
for (auto it = group_list.begin(); it != group_list.end(); it++) {
|
||||
Poco::AutoPtr<HederaAccount> group_ptr(new HederaAccount(new model::table::HederaAccount(*it)));
|
||||
resultVector.push_back(group_ptr);
|
||||
}
|
||||
return resultVector;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<controller::CryptoKey> HederaAccount::getCryptoKey() const
|
||||
{
|
||||
auto model = getModel();
|
||||
return controller::CryptoKey::load(model->getCryptoKeyId());
|
||||
}
|
||||
|
||||
bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr<controller::User> user)
|
||||
{
|
||||
static const char* functionName = "HederaAccount::updateBalanceFromHedera";
|
||||
|
||||
if (user.isNull() || !user->getModel()) {
|
||||
printf("[%s] invalid user\n", functionName);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto account_model = getModel();
|
||||
auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType()));
|
||||
if (hedera_node.url == "") {
|
||||
addError(new Error("Hedera Node", "no hedera node found"));
|
||||
return false;
|
||||
}
|
||||
auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId());
|
||||
if (crypto_key.isNull()) {
|
||||
addError(new Error("Keys", "could not found crypto key for account"));
|
||||
printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId());
|
||||
return false;
|
||||
}
|
||||
auto hedera_key_pair = crypto_key->getKeyPair(user);
|
||||
if (!hedera_key_pair) {
|
||||
addError(new Error("Keys", "error decrypting private key"));
|
||||
printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto query = model::hedera::Query::getBalance(getHederaId(), hedera_node);
|
||||
|
||||
if (!query) {
|
||||
printf("[%s] error creating query\n", functionName);
|
||||
}
|
||||
query->sign(std::move(hedera_key_pair));
|
||||
|
||||
HederaRequest request;
|
||||
model::hedera::Response response;
|
||||
try {
|
||||
if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response) && proto::OK == response.getResponseCode()) {
|
||||
account_model->updateIntoDB("balance", response.getAccountBalance());
|
||||
}
|
||||
else {
|
||||
addError(new Error("Hedera", "Hedera request failed"));
|
||||
addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode())));
|
||||
}
|
||||
//request.requestViaPHPRelay(query);
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data());
|
||||
}
|
||||
|
||||
if (0 == errorCount() && 0 == request.errorCount()) {
|
||||
return true;
|
||||
}
|
||||
getErrors(&request);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HederaAccount::hederaAccountCreate(int autoRenewPeriodSeconds, double initialBalance)
|
||||
{
|
||||
auto account_model = getModel();
|
||||
auto new_key_pair = KeyPairHedera::create();
|
||||
auto transaction_body = createTransactionBody();
|
||||
//CryptoCreateTransaction(const unsigned char* publicKey, Poco::UInt64 initialBalance, int autoRenewPeriod);
|
||||
model::hedera::CryptoCreateTransaction create_transaction(new_key_pair->getPublicKey(), initialBalance, autoRenewPeriodSeconds);
|
||||
transaction_body->setCryptoCreate(create_transaction);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HederaAccount::changeEncryption(Poco::AutoPtr<controller::User> user)
|
||||
{
|
||||
assert(!user.isNull() && user->getModel());
|
||||
auto model = getModel();
|
||||
assert(!model.isNull());
|
||||
|
||||
if (user->getModel()->getID() != model->getUserId()) {
|
||||
addError(new Error("Hedera Account", "wrong user"));
|
||||
return false;
|
||||
}
|
||||
auto crypto_key = controller::CryptoKey::load(model->getCryptoKeyId());
|
||||
if (crypto_key.isNull()) {
|
||||
addError(new Error("Hedera Account", "couldn't find crypto key"));
|
||||
return false;
|
||||
}
|
||||
bool result = crypto_key->changeEncryption(user);
|
||||
getErrors(crypto_key);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<model::hedera::TransactionBody> HederaAccount::createTransactionBody()
|
||||
{
|
||||
auto account_model = getModel();
|
||||
auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType()));
|
||||
auto hedera_id = getHederaId();
|
||||
if (hedera_id.isNull()) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<model::hedera::TransactionBody>(mHederaID, hedera_node);
|
||||
}
|
||||
|
||||
|
||||
std::string HederaAccount::toShortSelectOptionName()
|
||||
{
|
||||
std::stringstream ss;
|
||||
auto model = getModel();
|
||||
ss << model::table::HederaAccount::hederaNetworkTypeToString((ServerConfig::HederaNetworkType)model->getNetworkType()) << " ";
|
||||
ss << getHederaId()->getModel()->toString() << " " << ((double)model->getBalance() / 100000000.0) << " Hbar";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE
|
||||
|
||||
#include "HederaId.h"
|
||||
#include "User.h"
|
||||
#include "../model/table/HederaAccount.h"
|
||||
|
||||
#include "../model/hedera/TransactionBody.h"
|
||||
|
||||
#include "Poco/SharedPtr.h"
|
||||
|
||||
#include "TableControllerBase.h"
|
||||
#include "CryptoKey.h"
|
||||
|
||||
namespace controller {
|
||||
class HederaAccount : public TableControllerBase, public NotificationList
|
||||
{
|
||||
public:
|
||||
~HederaAccount();
|
||||
|
||||
static Poco::AutoPtr<HederaAccount> create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, ServerConfig::HederaNetworkType type = ServerConfig::HEDERA_MAINNET);
|
||||
|
||||
static std::vector<Poco::AutoPtr<HederaAccount>> load(const std::string& fieldName, int fieldValue);
|
||||
static Poco::AutoPtr<HederaAccount> load(int id);
|
||||
static Poco::AutoPtr<HederaAccount> load(Poco::AutoPtr<controller::HederaId> hederaId);
|
||||
static std::vector<Poco::AutoPtr<HederaAccount>> listAll();
|
||||
//! \brief for picking a account for paying transaction, mostly consensusSendMessage
|
||||
static Poco::AutoPtr<HederaAccount> pick(ServerConfig::HederaNetworkType networkType, bool encrypted = false, int user_id = 0);
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
|
||||
std::string toShortSelectOptionName();
|
||||
|
||||
inline Poco::AutoPtr<model::table::HederaAccount> getModel() { return _getModel<model::table::HederaAccount>(); }
|
||||
inline const model::table::HederaAccount* getModel() const { return _getModel<model::table::HederaAccount>(); }
|
||||
|
||||
inline void setHederaId(Poco::AutoPtr<controller::HederaId> hederaId) { mHederaID = hederaId; }
|
||||
Poco::AutoPtr<controller::HederaId> getHederaId();
|
||||
|
||||
Poco::AutoPtr<controller::CryptoKey> getCryptoKey() const;
|
||||
|
||||
bool hederaAccountGetBalance(Poco::AutoPtr<controller::User> user);
|
||||
bool hederaAccountCreate(int autoRenewPeriodSeconds, double initialBalance);
|
||||
bool changeEncryption(Poco::AutoPtr<controller::User> user);
|
||||
|
||||
//! \brief create Transaction body with this hedera account as operator
|
||||
std::unique_ptr<model::hedera::TransactionBody> createTransactionBody();
|
||||
|
||||
protected:
|
||||
|
||||
HederaAccount(model::table::HederaAccount* dbModel);
|
||||
Poco::AutoPtr<HederaId> mHederaID;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ACCOUNT_INCLUDE
|
||||
@ -1,127 +0,0 @@
|
||||
#include "HederaId.h"
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../SingletonManager/SessionManager.h"
|
||||
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace controller {
|
||||
|
||||
HederaId::HederaId(model::table::HederaId* dbModel)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
}
|
||||
|
||||
HederaId::~HederaId()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaId> HederaId::create(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num)
|
||||
{
|
||||
auto db = new model::table::HederaId(shardNum, realmNum, num);
|
||||
|
||||
auto hedera_id = new HederaId(db);
|
||||
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++) {
|
||||
unsigned long long temp_number;
|
||||
if (DataTypeConverter::NUMBER_PARSE_OKAY != DataTypeConverter::strToInt(number_strings[i], temp_number)) {
|
||||
return nullptr;
|
||||
}
|
||||
numbers[i] = temp_number;
|
||||
}
|
||||
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();
|
||||
if (1 == db->loadFromDB("id", id)) {
|
||||
auto cryptoKey = new HederaId(db);
|
||||
return Poco::AutoPtr<HederaId>(cryptoKey);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaId> HederaId::find(int groupId, ServerConfig::HederaNetworkType networkType)
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
model::table::HederaIdTuple result_tuple;
|
||||
int network_type_int = (int)networkType;
|
||||
|
||||
Poco::Data::Statement select(session);
|
||||
select << "SELECT h.id, h.shardNum, h.realmNum, h.num FROM hedera_ids as h "
|
||||
<< "JOIN hedera_topics as topic ON(topic.topic_hedera_id = h.id) "
|
||||
<< "JOIN hedera_accounts as account ON(account.id = topic.auto_renew_account_hedera_id) "
|
||||
<< "WHERE topic.group_id = ? AND account.network_type = ?"
|
||||
, into(result_tuple), use(groupId), use(network_type_int);
|
||||
|
||||
try {
|
||||
select.executeAsync();
|
||||
select.wait();
|
||||
auto result_count = select.rowsExtracted();
|
||||
if (1 == result_count) {
|
||||
return new HederaId(new model::table::HederaId(result_tuple));
|
||||
}
|
||||
else if(result_count > 1) {
|
||||
printf("[HederaId::find] result_count other as expected: %d\n", result_count);
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
auto em = ErrorManager::getInstance();
|
||||
static const char* function_name = "HederaId::find";
|
||||
em->addError(new ParamError(function_name, "mysql error: ", ex.displayText()));
|
||||
em->addError(new ParamError(function_name, "group id: ", groupId));
|
||||
em->addError(new ParamError(function_name, "network type: ", (int)networkType));
|
||||
em->sendErrorsAsEmail();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void HederaId::copyToProtoAccountId(proto::AccountID* protoAccountId) const
|
||||
{
|
||||
auto model = getModel();
|
||||
protoAccountId->set_shardnum(model->getShardNum());
|
||||
protoAccountId->set_realmnum(model->getRealmNum());
|
||||
protoAccountId->set_accountnum(model->getNum());
|
||||
}
|
||||
|
||||
void HederaId::copyToProtoTopicId(proto::TopicID* protoTopicId) const
|
||||
{
|
||||
auto model = getModel();
|
||||
protoTopicId->set_shardnum(model->getShardNum());
|
||||
protoTopicId->set_realmnum(model->getRealmNum());
|
||||
protoTopicId->set_topicnum(model->getNum());
|
||||
}
|
||||
|
||||
bool HederaId::isExistInDB()
|
||||
{
|
||||
auto model = getModel();
|
||||
if (model->getID() > 0) return true;
|
||||
//std::vector<Tuple> loadFromDB(const std::vector<std::string>& fieldNames, const std::vector<WhereFieldType>& fieldValues, MysqlConditionType conditionType = MYSQL_CONDITION_AND, int expectedResults = 0);
|
||||
model->isExistInDB();
|
||||
return model->getID() != 0;
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE
|
||||
|
||||
#include "../model/table/HederaId.h"
|
||||
#include "../model/table/HederaAccount.h"
|
||||
|
||||
#include "Poco/SharedPtr.h"
|
||||
|
||||
#include "TableControllerBase.h"
|
||||
|
||||
#include "proto/hedera/BasicTypes.pb.h"
|
||||
|
||||
namespace controller {
|
||||
class HederaAccount;
|
||||
class HederaId : public TableControllerBase
|
||||
{
|
||||
friend HederaAccount;
|
||||
public:
|
||||
|
||||
~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)
|
||||
static Poco::AutoPtr<HederaId> find(int groupId, ServerConfig::HederaNetworkType networkType);
|
||||
|
||||
bool isExistInDB();
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
|
||||
inline Poco::AutoPtr<model::table::HederaId> getModel() { return _getModel<model::table::HederaId>(); }
|
||||
inline const model::table::HederaId* getModel() const { return _getModel<model::table::HederaId>(); }
|
||||
|
||||
void copyToProtoAccountId(proto::AccountID* protoAccountId) const;
|
||||
void copyToProtoTopicId(proto::TopicID* protoTopicId) const;
|
||||
|
||||
|
||||
protected:
|
||||
HederaId(model::table::HederaId* dbModel);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_ID_INCLUDE
|
||||
@ -1,174 +0,0 @@
|
||||
#include "HederaRequest.h"
|
||||
#include "../proto/hedera/CryptoService.grpc.pb.h"
|
||||
#include "../proto/hedera/ConsensusService.grpc.pb.h"
|
||||
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpcpp/channel.h>
|
||||
#include <grpcpp/client_context.h>
|
||||
#include <grpcpp/create_channel.h>
|
||||
#include <chrono>
|
||||
|
||||
|
||||
HederaRequest::HederaRequest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaRequest::~HederaRequest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaRequestReturn HederaRequest::request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee/* = 0*/)
|
||||
{
|
||||
auto channel = grpc::CreateChannel(query->getConnectionString(), grpc::InsecureChannelCredentials());
|
||||
|
||||
grpc::ClientContext context;
|
||||
std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() +
|
||||
std::chrono::milliseconds(5000);
|
||||
context.set_deadline(deadline);
|
||||
//grpc::CompletionQueue cq;
|
||||
|
||||
auto proto_query = query->getProtoQuery();
|
||||
|
||||
auto proto_query_serialized = proto_query->SerializeAsString();
|
||||
//auto query_hex_string = DataTypeConverter::binToHex((unsigned char*)proto_query_serialized.data(), proto_query_serialized.size());
|
||||
//printf("[HederaRequest::request] query as hex: %s\n", query_hex_string.data());
|
||||
|
||||
auto proto_response = response->getResponsePtr();
|
||||
auto connect_string = query->getConnectionString();
|
||||
|
||||
grpc::Status status;
|
||||
std::string queryName;
|
||||
|
||||
if (proto_query->has_cryptogetaccountbalance())
|
||||
{
|
||||
auto stub = proto::CryptoService::NewStub(channel);
|
||||
// crypto account get balance currently hasn't fees
|
||||
query->setResponseType(proto::ANSWER_ONLY);
|
||||
|
||||
queryName = "crypte get balance";
|
||||
status = stub->cryptoGetBalance(&context, *proto_query, proto_response);
|
||||
|
||||
}
|
||||
else if (proto_query->has_consensusgettopicinfo())
|
||||
{
|
||||
auto stub = proto::ConsensusService::NewStub(channel);
|
||||
|
||||
queryName = "consensus topic get info";
|
||||
status = stub->getTopicInfo(&context, *proto_query, proto_response);
|
||||
|
||||
}
|
||||
else if (proto_query->has_transactiongetreceipt()) {
|
||||
auto stub = proto::CryptoService::NewStub(channel);
|
||||
|
||||
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();
|
||||
if (response_code) {
|
||||
addError(new ParamError("Hedera Request", "precheck code: ", proto::ResponseCodeEnum_Name(response_code)));
|
||||
return HEDERA_REQUEST_PRECHECK_ERROR;
|
||||
}
|
||||
else {
|
||||
return HEDERA_REQUEST_RETURN_OK;
|
||||
}
|
||||
|
||||
}
|
||||
else if("" != queryName)
|
||||
{
|
||||
addError(new ParamError("Hedera Request", "query name: ", queryName));
|
||||
addError(new ParamError("Hedera Request", "error message: ", status.error_message()));
|
||||
addError(new ParamError("Hedera Request", "details: ", status.error_details()));
|
||||
return HEDERA_REQUEST_RETURN_ERROR;
|
||||
}
|
||||
return HEDERA_REQUEST_UNKNOWN_QUERY;
|
||||
}
|
||||
|
||||
|
||||
HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transaction, model::hedera::Response* response)
|
||||
{
|
||||
auto channel = grpc::CreateChannel(transaction->getConnectionString(), grpc::InsecureChannelCredentials());
|
||||
|
||||
grpc::ClientContext context;
|
||||
std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() +
|
||||
std::chrono::milliseconds(5000);
|
||||
context.set_deadline(deadline);
|
||||
|
||||
return HEDERA_REQUEST_RETURN_OK;
|
||||
}
|
||||
|
||||
HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transaction, HederaTask* task)
|
||||
{
|
||||
assert(transaction && task);
|
||||
auto channel = grpc::CreateChannel(transaction->getConnectionString(), grpc::InsecureChannelCredentials());
|
||||
|
||||
grpc::ClientContext context;
|
||||
std::chrono::system_clock::time_point deadline = std::chrono::system_clock::now() +
|
||||
std::chrono::milliseconds(5000);
|
||||
context.set_deadline(deadline);
|
||||
auto transaction_type = transaction->getType();
|
||||
task->setTransactionId(transaction->getTransactionId());
|
||||
if (model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE == transaction_type ||
|
||||
model::hedera::TRANSACTION_CONSENSUS_CREATE_TOPIC == transaction_type) {
|
||||
auto stub = proto::ConsensusService::NewStub(channel);
|
||||
grpc::Status status;
|
||||
std::string service_name;
|
||||
if (model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE == transaction_type) {
|
||||
status = stub->submitMessage(&context, *transaction->getTransaction(), task->getTransactionResponse()->getProtoResponse());
|
||||
service_name = "submitMessage";
|
||||
}
|
||||
else if (model::hedera::TRANSACTION_CONSENSUS_CREATE_TOPIC == transaction_type) {
|
||||
status = stub->createTopic(&context, *transaction->getTransaction(), task->getTransactionResponse()->getProtoResponse());
|
||||
service_name = "createTopic";
|
||||
}
|
||||
if (status.ok()) {
|
||||
return HEDERA_REQUEST_RETURN_OK;
|
||||
}
|
||||
else {
|
||||
addError(new ParamError("Hedera Request", "consensus service error message:", status.error_message()));
|
||||
addError(new ParamError("Hedera Request", "service name", service_name));
|
||||
addError(new ParamError("Hedera Request", "details: ", status.error_details()));
|
||||
return HEDERA_REQUEST_RETURN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
addError(new ParamError("Hedera Request", "not implementet or unknown transaction type", transaction_type));
|
||||
return HEDERA_REQUEST_UNKNOWN_TRANSACTION;
|
||||
}
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "../lib/JsonRequest.h"
|
||||
|
||||
HederaRequestReturn HederaRequest::requestViaPHPRelay(model::hedera::Query* query)
|
||||
{
|
||||
JsonRequest phpRelay("***REMOVED***", 88);
|
||||
Poco::Net::NameValueCollection parameters;
|
||||
std::string query_string = query->getProtoQuery()->SerializeAsString();
|
||||
//auto query_base64 = DataTypeConverter::binToBase64((const unsigned char*)query_string.data(), query_string.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
||||
//auto findPos = query_string.find_first_of("\u");
|
||||
auto query_hex = DataTypeConverter::binToHex((const unsigned char*)query_string.data(), query_string.size());
|
||||
parameters.set("content", query_hex.substr(0, query_hex.size()-1));
|
||||
parameters.set("server", query->getConnectionString());
|
||||
parameters.set("method", "getBalance");
|
||||
parameters.set("service", "crypto");
|
||||
phpRelay.requestGRPCRelay(parameters);
|
||||
//phpRelay.request("")
|
||||
|
||||
return HEDERA_REQUEST_RETURN_OK;
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_
|
||||
#define __GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_
|
||||
/*!
|
||||
*
|
||||
* \author: Dario Rekowski
|
||||
*
|
||||
* \date: 31.08.2020
|
||||
*
|
||||
* \brief: Class for Hedera Requests
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../controller/NodeServer.h"
|
||||
#include "../model/hedera/Query.h"
|
||||
#include "../model/hedera/TransactionGetReceiptQuery.h"
|
||||
#include "../model/hedera/Transaction.h"
|
||||
#include "../model/hedera/Response.h"
|
||||
#include "../model/hedera/TransactionResponse.h"
|
||||
#include "../tasks/HederaTask.h"
|
||||
|
||||
enum HederaRequestReturn
|
||||
{
|
||||
HEDERA_REQUEST_RETURN_OK,
|
||||
HEDERA_REQUEST_RETURN_PARSE_ERROR,
|
||||
HEDERA_REQUEST_PRECHECK_ERROR,
|
||||
HEDERA_REQUEST_RETURN_ERROR,
|
||||
HEDERA_REQUEST_UNKNOWN_TRANSACTION,
|
||||
HEDERA_REQUEST_UNKNOWN_QUERY,
|
||||
HEDERA_REQUEST_CONNECT_ERROR
|
||||
};
|
||||
|
||||
// NodeServerConnection
|
||||
class HederaRequest : public NotificationList
|
||||
{
|
||||
public:
|
||||
HederaRequest();
|
||||
~HederaRequest();
|
||||
|
||||
HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0);
|
||||
HederaRequestReturn request(model::hedera::Transaction* transaction, model::hedera::Response* response);
|
||||
//!
|
||||
//! \param task goes into HederaTaskManager and will be run after transaction
|
||||
HederaRequestReturn request(model::hedera::Transaction* transaction, HederaTask* task);
|
||||
//! for testing, didn't work server say invalid json :/
|
||||
HederaRequestReturn requestViaPHPRelay(model::hedera::Query* query);
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_LIB_HEDERA_REQUEST_
|
||||
//
|
||||
@ -1,235 +0,0 @@
|
||||
#include "HederaTopic.h"
|
||||
//#include "../model/hedera/Transaction.h"
|
||||
#include "HederaRequest.h"
|
||||
#include "../lib/Success.h"
|
||||
|
||||
#include "../model/hedera/ConsensusCreateTopic.h"
|
||||
#include "../model/hedera/Transaction.h"
|
||||
|
||||
#include "../SingletonManager/PendingTasksManager.h"
|
||||
|
||||
namespace controller {
|
||||
HederaTopic::HederaTopic(model::table::HederaTopic* dbModel)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
}
|
||||
HederaTopic::~HederaTopic()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaTopic> HederaTopic::create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId)
|
||||
{
|
||||
auto db = new model::table::HederaTopic(name, autoRenewAccountId, autoRenewPeriod, groupId);
|
||||
|
||||
auto hedera_topic = new HederaTopic(db);
|
||||
return Poco::AutoPtr<HederaTopic>(hedera_topic);
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<HederaTopic>> HederaTopic::listAll()
|
||||
{
|
||||
auto db = new model::table::HederaTopic();
|
||||
std::vector<model::table::HederaTopicTuple> topic_list;
|
||||
// throw an unresolved external symbol error
|
||||
topic_list = db->loadAllFromDB<model::table::HederaTopicTuple>();
|
||||
|
||||
std::vector<Poco::AutoPtr<HederaTopic>> resultVector;
|
||||
|
||||
resultVector.reserve(topic_list.size());
|
||||
for (auto it = topic_list.begin(); it != topic_list.end(); it++) {
|
||||
Poco::AutoPtr<HederaTopic> topic_ptr(new HederaTopic(new model::table::HederaTopic(*it)));
|
||||
resultVector.push_back(topic_ptr);
|
||||
}
|
||||
|
||||
return resultVector;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaTopic> HederaTopic::load(int id)
|
||||
{
|
||||
auto db = new model::table::HederaTopic;
|
||||
if (1 == db->loadFromDB("id", id)) {
|
||||
return new HederaTopic(db);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaId> HederaTopic::getTopicHederaId()
|
||||
{
|
||||
if (mTopicHederaId.isNull()) {
|
||||
mTopicHederaId = HederaId::load(getModel()->getTopicHederaId());
|
||||
}
|
||||
return mTopicHederaId;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaTopic::getAutoRenewAccount()
|
||||
{
|
||||
if (mAutoRenewAccount.isNull()) {
|
||||
mAutoRenewAccount = HederaAccount::load(getModel()->getAutoRenewAccountId());
|
||||
}
|
||||
return mAutoRenewAccount;
|
||||
}
|
||||
|
||||
bool HederaTopic::getTopicInfosFromHedera(Poco::AutoPtr<controller::HederaId> topicHederaId, Poco::AutoPtr<User> user, model::hedera::Response& response)
|
||||
{
|
||||
auto payer_account = controller::HederaAccount::pick(ServerConfig::g_HederaNetworkType);
|
||||
auto node_server = NodeServer::pick(payer_account->getModel()->getNetworkType(), getModel()->getGroupId());
|
||||
|
||||
if (topicHederaId.isNull()) {
|
||||
addError(new Error("Hedera Topic", "no hedera topic id exist"));
|
||||
return false;
|
||||
}
|
||||
auto query = model::hedera::Query::getTopicInfo(topicHederaId, payer_account->getHederaId(), node_server);
|
||||
query->setResponseType(proto::COST_ANSWER);
|
||||
HederaRequest request;
|
||||
query->sign(payer_account->getCryptoKey()->getKeyPair(user));
|
||||
if (HEDERA_REQUEST_RETURN_OK == request.request(query, &response)) {
|
||||
auto queryCost = response.getQueryCost();
|
||||
printf("query cost: %d\n", queryCost);
|
||||
|
||||
query->setTransactionFee(queryCost);
|
||||
query->setResponseType(proto::ANSWER_ONLY);
|
||||
query->sign(payer_account->getCryptoKey()->getKeyPair(user));
|
||||
|
||||
|
||||
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()));
|
||||
auto model = getModel();
|
||||
model->setAutoRenewPeriod(consensus_topic_info->getAutoRenewPeriod().seconds());
|
||||
model->setCurrentTimeout(consensus_topic_info->getExpirationTime());
|
||||
model->setSequeceNumber(consensus_topic_info->getSequenceNumber());
|
||||
|
||||
|
||||
std::string fieldNames[] = { "auto_renew_period", "current_timeout", "sequence_number" };
|
||||
if (model->updateIntoDB(
|
||||
fieldNames,
|
||||
model->getAutoRenewPeriod(),
|
||||
model->getCurrentTimeout(),
|
||||
model->getSequenceNumber()
|
||||
) > 1) {
|
||||
addError(new Error("DB", "error saving changes in DB"));
|
||||
getErrors(model);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
model::hedera::Response response;
|
||||
if (!hedera_topic->getTopicInfosFromHedera(hederaId, user, response)) {
|
||||
delete hedera_topic;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
static const char* function_name = "HederaTopic::createTopic";
|
||||
printf("[HederaTopic::createTopic]\n");
|
||||
auto model = getModel();
|
||||
if (!model->getID()) {
|
||||
addError(new Error(function_name, "no db entry for topic created, id is missing"));
|
||||
return nullptr;
|
||||
}
|
||||
Poco::AutoPtr<controller::HederaId> autoRenewAccountId(nullptr);
|
||||
if (model->getAutoRenewAccountId()) {
|
||||
//autoRenewAccountId = controller::HederaId::load(model->getAutoRenewAccountId());
|
||||
}
|
||||
model::hedera::ConsensusCreateTopic hederaCreateTopic(autoRenewAccountId, model->getAutoRenewPeriod());
|
||||
auto hederaTransactionBody = operatorAccount->createTransactionBody();
|
||||
if (model->getName() != "") {
|
||||
hederaCreateTopic.setMemo(model->getName());
|
||||
}
|
||||
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());
|
||||
receipt_task_model->setUserId(user->getModel()->getID());
|
||||
|
||||
HederaRequest request;
|
||||
printf("[HederaTopic::createTopic] before calling request\n");
|
||||
auto result = request.request(&hederaTransaction, receiptTask.get());
|
||||
if (HEDERA_REQUEST_RETURN_OK == result) {
|
||||
if (proto::OK == receiptTask->getTransactionResponse()->getPrecheckCode()) {
|
||||
auto pt = PendingTasksManager::getInstance();
|
||||
printf("[HederaTopic::createTopic] before add task\n");
|
||||
pt->addTask(receiptTask);
|
||||
printf("[HederaTopic::createTopic] before start timer\n");
|
||||
receiptTask->startTimer();
|
||||
return receiptTask;
|
||||
}
|
||||
else {
|
||||
addError(new ParamError(function_name, "precheck code error", receiptTask->getTransactionResponse()->getPrecheckCodeString()));
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
addError(new Error(function_name, "error in hedera request"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H
|
||||
#define __GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H
|
||||
|
||||
/*!
|
||||
*
|
||||
* \author: Dario Rekowski
|
||||
*
|
||||
* \date: 03.09.2020
|
||||
*
|
||||
* \brief: Class for Hedera Topic, connct db table with hedera object
|
||||
*
|
||||
*/
|
||||
#include "TableControllerBase.h"
|
||||
#include "../model/table/HederaTopic.h"
|
||||
#include "../model/hedera/Response.h"
|
||||
#include "HederaId.h"
|
||||
#include "HederaAccount.h"
|
||||
|
||||
#include "../tasks/HederaTask.h"
|
||||
|
||||
namespace controller {
|
||||
class HederaTopic : public TableControllerBase, public NotificationList
|
||||
{
|
||||
public:
|
||||
|
||||
~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);
|
||||
|
||||
|
||||
bool updateWithGetTopicInfos(Poco::AutoPtr<User> user);
|
||||
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
Poco::AutoPtr<HederaId> getTopicHederaId();
|
||||
Poco::AutoPtr<HederaAccount> getAutoRenewAccount();
|
||||
|
||||
//! \brief hedera call to create a hedera topic
|
||||
Poco::AutoPtr<HederaTask> createTopic(Poco::AutoPtr<controller::HederaAccount> operatorAccount, Poco::AutoPtr<controller::User> user);
|
||||
|
||||
inline Poco::AutoPtr<model::table::HederaTopic> getModel() { return _getModel<model::table::HederaTopic>(); }
|
||||
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_CONTROLLER_HEDERA_TOPIC_H
|
||||
@ -1,208 +0,0 @@
|
||||
#include "NodeServer.h"
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../SingletonManager/ConnectionManager.h"
|
||||
#include "../SingletonManager/CronManager.h"
|
||||
#include "Poco/RegularExpression.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
Poco::RegularExpression g_filterHttp("^https?://");
|
||||
|
||||
std::string NodeServerConnection::getUriWithPort() const
|
||||
{
|
||||
std::string protocol;
|
||||
g_filterHttp.extract(url, protocol);
|
||||
return url.substr(protocol.size()) + ":" + std::to_string(port);
|
||||
}
|
||||
|
||||
std::string NodeServerConnection::getUri() const
|
||||
{
|
||||
std::string protocol;
|
||||
g_filterHttp.extract(url, protocol);
|
||||
return url.substr(protocol.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
NodeServer::NodeServer(model::table::NodeServer* dbModel)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
if (model::table::NODE_SERVER_GRADIDO_COMMUNITY == dbModel->getNodeServerType()) {
|
||||
CronManager::getInstance()->addNodeServerToPing(Poco::AutoPtr<controller::NodeServer>(this, true));
|
||||
}
|
||||
}
|
||||
|
||||
NodeServer::~NodeServer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool NodeServer::deleteFromDB()
|
||||
{
|
||||
auto result = mDBModel->deleteFromDB();
|
||||
if (result && model::table::NODE_SERVER_GRADIDO_COMMUNITY == getModel()->getNodeServerType()) {
|
||||
CronManager::getInstance()->removeNodeServerToPing(Poco::AutoPtr<controller::NodeServer>(this, true));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<NodeServer> NodeServer::create(const std::string& url, int port, int groupId, model::table::NodeServerType type, int nodeHederaId)
|
||||
{
|
||||
auto db = new model::table::NodeServer(url, port, groupId, type, nodeHederaId);
|
||||
auto group = new NodeServer(db);
|
||||
return Poco::AutoPtr<NodeServer>(group);
|
||||
}
|
||||
|
||||
Poco::AutoPtr<NodeServer> NodeServer::load(int id)
|
||||
{
|
||||
auto db = new model::table::NodeServer();
|
||||
if (1 == db->loadFromDB("id", id)) {
|
||||
return new NodeServer(db);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<NodeServer>> NodeServer::load(model::table::NodeServerType type, int group_id/* = 0*/)
|
||||
{
|
||||
auto db = new model::table::NodeServer();
|
||||
std::vector<model::table::NodeServerTuple> node_server_list;
|
||||
|
||||
if (type == model::table::NODE_SERVER_HEDERA_MAINNET_NODE || type == model::table::NODE_SERVER_HEDERA_TESTNET_NODE)
|
||||
{
|
||||
node_server_list = db->loadFromDB<model::table::NodeServerType, model::table::NodeServerTuple>("server_type", type, 4);
|
||||
}
|
||||
else if (type == model::table::NODE_SERVER_GRADIDO_NODE || type == model::table::NODE_SERVER_GRADIDO_COMMUNITY)
|
||||
{
|
||||
if (group_id)
|
||||
{
|
||||
node_server_list = db->loadFromDB<int, model::table::NodeServerTuple>(
|
||||
{ "server_type", "group_id" },
|
||||
{ type, group_id },
|
||||
model::table::MYSQL_CONDITION_AND
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
node_server_list = db->loadFromDB<int, model::table::NodeServerTuple >("server_type", type, 4);
|
||||
}
|
||||
}
|
||||
//auto node_server_list = db->loadFromDB<std::string, model::table::NodeServerTuple>("alias", alias, 0);
|
||||
|
||||
std::vector<Poco::AutoPtr<NodeServer>> resultVector;
|
||||
resultVector.reserve(node_server_list.size());
|
||||
for (auto it = node_server_list.begin(); it != node_server_list.end(); it++) {
|
||||
resultVector.push_back(new NodeServer(new model::table::NodeServer(*it)));
|
||||
}
|
||||
return resultVector;
|
||||
}
|
||||
|
||||
/*
|
||||
SELECT * FROM table_name
|
||||
ORDER BY RAND()
|
||||
LIMIT 1;
|
||||
*/
|
||||
NodeServerConnection NodeServer::pick(ServerConfig::HederaNetworkType type, int group_id /*= 0*/)
|
||||
{
|
||||
model::table::NodeServerType node_server_type = model::table::NODE_SERVER_NONE;
|
||||
if (ServerConfig::HEDERA_MAINNET) node_server_type = model::table::NODE_SERVER_HEDERA_MAINNET_NODE;
|
||||
else if (ServerConfig::HEDERA_TESTNET) node_server_type = model::table::NODE_SERVER_HEDERA_TESTNET_NODE;
|
||||
return pick(node_server_type, group_id);
|
||||
}
|
||||
NodeServerConnection NodeServer::pick(model::table::NodeServerType type, int group_id/* = 0*/)
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
NodeServerConnection result;
|
||||
int hedera_node_id = 0;
|
||||
|
||||
Poco::Data::Statement select(session);
|
||||
select << "SELECT url, port";
|
||||
|
||||
if (model::table::NodeServerIsHederaNode(type)) {
|
||||
select << ", node_hedera_id";
|
||||
}
|
||||
select << " from node_servers where server_type = ? ORDER BY RAND() LIMIT 1"
|
||||
, Poco::Data::Keywords::into(result.url)
|
||||
, Poco::Data::Keywords::into(result.port);
|
||||
if (model::table::NodeServerIsHederaNode(type)) {
|
||||
select, Poco::Data::Keywords::into(hedera_node_id);
|
||||
}
|
||||
select , Poco::Data::Keywords::bind((int)type);
|
||||
try {
|
||||
if (1 == select.execute()) {
|
||||
if (model::table::NodeServerIsHederaNode(type)) {
|
||||
result.hederaId = controller::HederaId::load(hedera_node_id);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
auto em = ErrorManager::getInstance();
|
||||
const char* functionName = "NodeServer::pick";
|
||||
em->addError(new ParamError(functionName, "mysql error by pick: ", ex.message()));
|
||||
em->addError(new ParamError(functionName, "server type: ", model::table::NodeServer::nodeServerTypeToString(type)));
|
||||
em->addError(new ParamError(functionName, "group id", group_id));
|
||||
em->sendErrorsAsEmail();
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<NodeServer>> NodeServer::listAll()
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(session);
|
||||
std::vector<NodeServerFullTuple> rows;
|
||||
// typedef Poco::Tuple<int, std::string, int, int, int, int, Poco::UInt64, Poco::UInt64, Poco::UInt64, Poco::DateTime> NodeServerFullTuple;
|
||||
select << "SELECT n.id, n.url, n.port, n.group_id, n.server_type, n.node_hedera_id, h.shardNum, h.realmNum, h.num, n.last_live_sign "
|
||||
<< "FROM node_servers as n "
|
||||
<< "LEFT JOIN hedera_ids as h ON h.id = n.node_hedera_id"
|
||||
, Poco::Data::Keywords::into(rows);
|
||||
|
||||
try {
|
||||
select.executeAsync();
|
||||
select.wait();
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
auto em = ErrorManager::getInstance();
|
||||
const char* functionName = "NodeServer::listAll";
|
||||
em->addError(new ParamError(functionName, "mysql error by list all: ", ex.message()));
|
||||
em->sendErrorsAsEmail();
|
||||
}
|
||||
std::vector<Poco::AutoPtr<NodeServer>> results;
|
||||
for (auto it = rows.begin(); it != rows.end(); it++) {
|
||||
//NodeServer(const std::string& url, int port, int groupId, NodeServerType type, int nodeHederaId);
|
||||
auto row = *it;
|
||||
model::table::NodeServer* db = new model::table::NodeServer(
|
||||
row.get<1>(), row.get<2>(), row.get<3>(), (model::table::NodeServerType)row.get<4>(), row.get<5>()
|
||||
);
|
||||
db->setLastLiveSign(row.get<9>());
|
||||
db->setID(row.get<0>());
|
||||
Poco::AutoPtr<NodeServer> node_server(new NodeServer(db));
|
||||
node_server->setHederaId(controller::HederaId::create(
|
||||
row.get<6>(), row.get<7>(), row.get<8>()
|
||||
));
|
||||
results.push_back(node_server);
|
||||
|
||||
}
|
||||
return results;
|
||||
|
||||
}
|
||||
|
||||
JsonRequest NodeServer::createJsonRequest()
|
||||
{
|
||||
auto model = getModel();
|
||||
NodeServerConnection connection(model->getUrl(), model->getPort());
|
||||
return JsonRequest(connection.getUri(), model->getPort());
|
||||
}
|
||||
|
||||
std::string NodeServer::getBaseUri()
|
||||
{
|
||||
auto model = getModel();
|
||||
NodeServerConnection connection(model->getUrl(), model->getPort());
|
||||
return connection.getUri();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE
|
||||
|
||||
#include "../model/table/NodeServer.h"
|
||||
#include "../controller/HederaId.h"
|
||||
#include "../lib/JsonRequest.h"
|
||||
|
||||
#include "Poco/SharedPtr.h"
|
||||
|
||||
#include "TableControllerBase.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
struct NodeServerConnection
|
||||
{
|
||||
NodeServerConnection(const std::string& _url, int _port) : url(_url), port(_port) {}
|
||||
NodeServerConnection() :port(0) {};
|
||||
|
||||
// with http:// or https://
|
||||
inline std::string getUrlWithPort() const { return url + ":" + std::to_string(port); }
|
||||
|
||||
// without http:// or https://
|
||||
std::string getUriWithPort() const;
|
||||
std::string getUri() const;
|
||||
|
||||
bool isValid() { return url != "" && port; }
|
||||
std::string url;
|
||||
int port;
|
||||
|
||||
Poco::AutoPtr<controller::HederaId> hederaId;
|
||||
};
|
||||
|
||||
typedef Poco::Tuple<int, std::string, int, int, int, int, Poco::UInt64, Poco::UInt64, Poco::UInt64, Poco::DateTime> NodeServerFullTuple;
|
||||
|
||||
class NodeServer : public TableControllerBase
|
||||
{
|
||||
public:
|
||||
|
||||
~NodeServer();
|
||||
|
||||
static Poco::AutoPtr<NodeServer> create(const std::string& url, int port, int groupId, model::table::NodeServerType type, int nodeHederaId);
|
||||
|
||||
//! \param group_id is zero take everyone
|
||||
static std::vector<Poco::AutoPtr<NodeServer>> load(model::table::NodeServerType type, int group_id = 0);
|
||||
static Poco::AutoPtr<NodeServer> load(int id);
|
||||
static std::vector<Poco::AutoPtr<NodeServer>> listAll();
|
||||
// pick server randomly
|
||||
static NodeServerConnection pick(ServerConfig::HederaNetworkType type, int group_id = 0);
|
||||
static NodeServerConnection pick(model::table::NodeServerType type, int group_id = 0);
|
||||
bool deleteFromDB();
|
||||
|
||||
inline Poco::AutoPtr<model::table::NodeServer> getModel() { return _getModel<model::table::NodeServer>(); }
|
||||
|
||||
inline void setHederaId(Poco::AutoPtr<controller::HederaId> hederaId) { mHederaID = hederaId; }
|
||||
inline Poco::AutoPtr<controller::HederaId> getHederaId() { return mHederaID; }
|
||||
|
||||
std::string getBaseUri();
|
||||
JsonRequest createJsonRequest();
|
||||
protected:
|
||||
NodeServer(model::table::NodeServer* dbModel);
|
||||
Poco::AutoPtr<controller::HederaId> mHederaID;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_CONTROLLER_NODE_SERVER_INCLUDE
|
||||
@ -1,7 +1,6 @@
|
||||
#include "PendingTask.h"
|
||||
|
||||
#include "../model/gradido/Transaction.h"
|
||||
#include "../tasks/HederaTask.h"
|
||||
|
||||
#include "../SingletonManager/PendingTasksManager.h"
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
@ -37,7 +36,7 @@ namespace controller {
|
||||
resultVector.push_back(loadCorrectDerivedClass(new model::table::PendingTask(*it)));
|
||||
}
|
||||
return resultVector;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -57,9 +56,7 @@ namespace controller {
|
||||
if (dbModel->isGradidoTransaction()) {
|
||||
return model::gradido::Transaction::load(dbModel);
|
||||
}
|
||||
else if (dbModel->isGradidoTransaction()) {
|
||||
return HederaTask::load(dbModel);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -70,7 +67,7 @@ namespace controller {
|
||||
// throw an unresolved external symbol error
|
||||
task_list = db->loadAllFromDB<model::table::PendingTaskTuple>();
|
||||
|
||||
|
||||
|
||||
//*/ //work around end
|
||||
std::vector<Poco::AutoPtr<PendingTask>> resultVector;
|
||||
|
||||
@ -85,7 +82,7 @@ namespace controller {
|
||||
bool PendingTask::deleteFromDB()
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
auto result = mDBModel->deleteFromDB();
|
||||
auto result = mDBModel->deleteFromDB();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -109,7 +106,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()) {
|
||||
@ -136,7 +133,7 @@ namespace controller {
|
||||
Poco::TimerCallback<PendingTask> callback(*this, &PendingTask::calledFromTimer);
|
||||
mTimer.start(callback);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void PendingTask::calledFromTimer(Poco::Timer& timer)
|
||||
{
|
||||
@ -205,4 +202,4 @@ namespace controller {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../SingletonManager/SingletonTaskObserver.h"
|
||||
|
||||
#include "NodeServer.h"
|
||||
#include "Group.h"
|
||||
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
@ -24,7 +23,7 @@ namespace controller {
|
||||
: mPassword(nullptr), mGradidoKeyPair(nullptr), mCanDecryptPrivateKey(false), mGradidoCurrentBalance(0)
|
||||
{
|
||||
mDBModel = dbModel;
|
||||
|
||||
|
||||
}
|
||||
|
||||
User::~User()
|
||||
@ -49,20 +48,20 @@ namespace controller {
|
||||
auto user = new User(db);
|
||||
return Poco::AutoPtr<User>(user);
|
||||
}
|
||||
|
||||
|
||||
std::vector<User*> User::search(const std::string& searchString, const std::string& accountState /* = "all" */)
|
||||
{
|
||||
|
||||
|
||||
auto sm = SessionManager::getInstance();
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto db = new model::table::User();
|
||||
static const char* functionName = "User::search";
|
||||
|
||||
|
||||
std::string globalSearch = "%" + searchString + "%";
|
||||
|
||||
std::vector<model::table::UserTuple> resultFromDB;
|
||||
if (accountState == "email not activated") {
|
||||
|
||||
|
||||
std::vector<std::string> fieldNames = { "first_name", "last_name", "email", "email_checked" };
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
std::vector<model::table::UserTuple> results;
|
||||
@ -127,7 +126,7 @@ namespace controller {
|
||||
auto user = new User(db);
|
||||
return Poco::AutoPtr<User>(user);
|
||||
}
|
||||
|
||||
|
||||
void User::reload()
|
||||
{
|
||||
getModel()->loadFromDB("id", getModel()->getID());
|
||||
@ -147,15 +146,15 @@ namespace controller {
|
||||
|
||||
auto pubkey = getModel()->getPublicKey();
|
||||
|
||||
if (pubkey)
|
||||
if (pubkey)
|
||||
{
|
||||
auto pubkeyHex = mm->getFreeMemory(65);
|
||||
memset(*pubkeyHex, 0, 65);
|
||||
sodium_bin2hex(*pubkeyHex, 65, pubkey, 32);
|
||||
mPublicHex = (char*)*pubkeyHex;
|
||||
mm->releaseMemory(pubkeyHex);
|
||||
mm->releaseMemory(pubkeyHex);
|
||||
}
|
||||
|
||||
|
||||
unlock();
|
||||
return mPublicHex;
|
||||
}
|
||||
@ -185,7 +184,7 @@ namespace controller {
|
||||
return 2;
|
||||
}
|
||||
auto observer = SingletonTaskObserver::getInstance();
|
||||
|
||||
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
assert(mPassword.isNull());
|
||||
|
||||
@ -201,7 +200,7 @@ namespace controller {
|
||||
|
||||
observer->removeTask(email_hash, TASK_OBSERVER_PASSWORD_CREATION);
|
||||
|
||||
if (authenticated_encryption->getKeyHashed() == model->getPasswordHashed())
|
||||
if (authenticated_encryption->getKeyHashed() == model->getPasswordHashed())
|
||||
{
|
||||
// printf("[User::login] password key hashed is the same as saved password hash\n");
|
||||
MemoryBin* clear_private_key = nullptr;
|
||||
@ -212,7 +211,7 @@ namespace controller {
|
||||
if (!model->hasPrivateKeyEncrypted()) {
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if (SecretKeyCryptography::AUTH_DECRYPT_OK == authenticated_encryption->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) {
|
||||
if (mGradidoKeyPair) {
|
||||
@ -247,7 +246,7 @@ namespace controller {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// password didn't match
|
||||
//printf("password hashed key: %ull, model pwd hashed keys: %ull\n", authenticated_encryption->getKeyHashed(), model->getPasswordHashed());
|
||||
//printf("password: %d\n", (int)(mPassword.get()));
|
||||
@ -285,12 +284,12 @@ namespace controller {
|
||||
}
|
||||
|
||||
|
||||
int User::setNewPassword(Poco::AutoPtr<SecretKeyCryptography> passwd)
|
||||
int User::setNewPassword(Poco::AutoPtr<SecretKeyCryptography> passwd)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
auto model = getModel();
|
||||
|
||||
if (!mPassword.isNull() && !passwd.isNull())
|
||||
if (!mPassword.isNull() && !passwd.isNull())
|
||||
{
|
||||
// if keys matched
|
||||
if (mPassword->isTheSame(passwd)) {
|
||||
@ -301,16 +300,16 @@ namespace controller {
|
||||
//if (!mGradidoKeyPair) mGradidoKeyPair = new KeyPairEd25519;
|
||||
MemoryBin* clear_private_key = nullptr;
|
||||
if (SecretKeyCryptography::AUTH_DECRYPT_OK == mPassword->decrypt(model->getPrivateKeyEncrypted(), &clear_private_key)) {
|
||||
if (mGradidoKeyPair && mGradidoKeyPair->isTheSame(clear_private_key) != 0)
|
||||
if (mGradidoKeyPair && mGradidoKeyPair->isTheSame(clear_private_key) != 0)
|
||||
{
|
||||
delete mGradidoKeyPair;
|
||||
delete mGradidoKeyPair;
|
||||
mGradidoKeyPair = nullptr;
|
||||
}
|
||||
if (!mGradidoKeyPair)
|
||||
if (!mGradidoKeyPair)
|
||||
{
|
||||
mGradidoKeyPair = new KeyPairEd25519(clear_private_key);
|
||||
}
|
||||
|
||||
|
||||
// check if saved pubkey and from private key extracted pubkey match
|
||||
if (*mGradidoKeyPair != model->getPublicKey()) {
|
||||
delete mGradidoKeyPair;
|
||||
@ -358,7 +357,7 @@ namespace controller {
|
||||
continue;
|
||||
}
|
||||
auto key_pair = user_backup->createGradidoKeyPair();
|
||||
|
||||
|
||||
if (key_pair->isTheSame(user_model->getPublicKey())) {
|
||||
if (createdKeyPair) {
|
||||
*createdKeyPair = key_pair;
|
||||
@ -425,7 +424,7 @@ namespace controller {
|
||||
<< "LEFT JOIN email_opt_in as v ON(u.id = v.user_id) "
|
||||
<< "where u.email_checked = ? "
|
||||
<< "AND v.resend_count <= ? "
|
||||
<< "ORDER BY u.id, v.created " ,
|
||||
<< "ORDER BY u.id, v.created " ,
|
||||
Poco::Data::Keywords::use(email_checked), Poco::Data::Keywords::use(resend_count), Poco::Data::Keywords::into(results)
|
||||
;
|
||||
int result_count = 0;
|
||||
@ -499,7 +498,7 @@ namespace controller {
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(session);
|
||||
std::vector<Poco::Tuple<int, std::string>> results;
|
||||
|
||||
|
||||
select << "select id, email from users "
|
||||
<< "where email_hash IS NULL "
|
||||
, Poco::Data::Keywords::into(results)
|
||||
@ -553,42 +552,25 @@ namespace controller {
|
||||
printf("[%s] return saved group base Url: %s\n", function_name, mGroupBaseUrl.data());
|
||||
return mGroupBaseUrl;
|
||||
}
|
||||
|
||||
|
||||
auto model = getModel();
|
||||
if (!model->getGroupId()) {
|
||||
printf("[%s] return ServerConfig::g_php_serverPath because no group id\n", function_name);
|
||||
return ServerConfig::g_php_serverPath;
|
||||
}
|
||||
auto servers = controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_COMMUNITY, model->getGroupId());
|
||||
if (!servers.size()) {
|
||||
auto group = controller::Group::load(model->getGroupId());
|
||||
if (!group.isNull()) {
|
||||
auto group_model = group->getModel();
|
||||
if (ServerConfig::g_ServerSetupType == ServerConfig::SERVER_TYPE_TEST) {
|
||||
mGroupBaseUrl = "http://" + group_model->getUrl() + group_model->getHome();
|
||||
}
|
||||
else {
|
||||
mGroupBaseUrl = "https://" + group_model->getUrl() + group_model->getHome();
|
||||
}
|
||||
printf("[%s] return group base Url: %s from Group\n", function_name, mGroupBaseUrl.data());
|
||||
return mGroupBaseUrl;
|
||||
}
|
||||
return ServerConfig::g_php_serverPath;
|
||||
}
|
||||
if (servers.size() > 1) {
|
||||
auto em = ErrorManager::getInstance();
|
||||
em->addError(new ParamError(function_name, "error, more than one community server found for group", model->getGroupId()));
|
||||
em->sendErrorsAsEmail();
|
||||
return ServerConfig::g_php_serverPath;
|
||||
}
|
||||
if (ServerConfig::g_ServerSetupType == ServerConfig::SERVER_TYPE_TEST) {
|
||||
mGroupBaseUrl = "http://" + servers[0]->getBaseUri();
|
||||
}
|
||||
else {
|
||||
mGroupBaseUrl = "https://" + servers[0]->getBaseUri();
|
||||
}
|
||||
printf("[%s] return group base Url: %s from NodeServer\n", function_name, mGroupBaseUrl.data());
|
||||
return mGroupBaseUrl;
|
||||
auto group = controller::Group::load(model->getGroupId());
|
||||
if (!group.isNull()) {
|
||||
auto group_model = group->getModel();
|
||||
if (ServerConfig::g_ServerSetupType == ServerConfig::SERVER_TYPE_TEST) {
|
||||
mGroupBaseUrl = "http://" + group_model->getUrl() + group_model->getHome();
|
||||
}
|
||||
else {
|
||||
mGroupBaseUrl = "https://" + group_model->getUrl() + group_model->getHome();
|
||||
}
|
||||
printf("[%s] return group base Url: %s from Group\n", function_name, mGroupBaseUrl.data());
|
||||
return mGroupBaseUrl;
|
||||
}
|
||||
return ServerConfig::g_php_serverPath;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<controller::Group> User::getGroup()
|
||||
|
||||
@ -19,17 +19,17 @@ namespace DataTypeConverter
|
||||
result = stoi(input);
|
||||
return NUMBER_PARSE_OKAY;
|
||||
}
|
||||
catch (const std::invalid_argument& ia)
|
||||
catch (const std::invalid_argument& ia)
|
||||
{
|
||||
printf("[strToInt] exception: invalid argument: %s\n", ia.what());
|
||||
return NUMBER_PARSE_INVALID_ARGUMENT;
|
||||
}
|
||||
catch (const std::out_of_range& oor)
|
||||
catch (const std::out_of_range& oor)
|
||||
{
|
||||
printf("[strToInt] exception: out or range: %s\n", oor.what());
|
||||
return NUMBER_PARSE_OUT_OF_RANGE;
|
||||
}
|
||||
catch (const std::logic_error & ler)
|
||||
catch (const std::logic_error & ler)
|
||||
{
|
||||
printf("[strToInt] exception: logical error: %s\n", ler.what());
|
||||
return NUMBER_PARSE_LOGIC_ERROR;
|
||||
@ -198,13 +198,13 @@ namespace DataTypeConverter
|
||||
return bin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::string binToBase64(const unsigned char* data, size_t size, int variant /*= sodium_base64_VARIANT_ORIGINAL*/)
|
||||
{
|
||||
auto mm = MemoryManager::getInstance();
|
||||
|
||||
|
||||
size_t encodedSize = sodium_base64_encoded_len(size, variant);
|
||||
auto base64 = mm->getFreeMemory(encodedSize);
|
||||
memset(*base64, 0, encodedSize);
|
||||
@ -295,12 +295,6 @@ namespace DataTypeConverter
|
||||
return result;
|
||||
}
|
||||
|
||||
Poco::Timestamp convertFromProtoTimestamp(const proto::Timestamp& timestamp)
|
||||
{
|
||||
// microseconds
|
||||
google::protobuf::int64 microseconds = timestamp.seconds() * (google::protobuf::int64)10e5 + (google::protobuf::int64)(timestamp.nanos()) / (google::protobuf::int64)10e2;
|
||||
return microseconds;
|
||||
}
|
||||
|
||||
Poco::Timestamp convertFromProtoTimestamp(const proto::gradido::Timestamp& timestamp)
|
||||
{
|
||||
@ -309,13 +303,6 @@ namespace DataTypeConverter
|
||||
return microseconds;
|
||||
}
|
||||
|
||||
void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::Timestamp* protoTimestamp)
|
||||
{
|
||||
auto microsecondsTotal = pocoTimestamp.epochMicroseconds();
|
||||
auto secondsTotal = pocoTimestamp.epochTime();
|
||||
protoTimestamp->set_seconds(secondsTotal);
|
||||
protoTimestamp->set_nanos((microsecondsTotal - secondsTotal * pocoTimestamp.resolution()) * 1000);
|
||||
}
|
||||
|
||||
void convertToProtoTimestamp(const Poco::Timestamp pocoTimestamp, proto::gradido::Timestamp* protoTimestamp)
|
||||
{
|
||||
@ -333,11 +320,6 @@ namespace DataTypeConverter
|
||||
}
|
||||
|
||||
|
||||
Poco::Timespan convertFromProtoDuration(const proto::Duration& duration)
|
||||
{
|
||||
return Poco::Timespan(duration.seconds(), 0);
|
||||
}
|
||||
|
||||
int replaceBase64WithHex(Poco::JSON::Object::Ptr json)
|
||||
{
|
||||
//g_rexExpBase64
|
||||
@ -356,7 +338,7 @@ namespace DataTypeConverter
|
||||
count_replacements += replaceBase64WithHex(local_json);
|
||||
json->set(it->first, local_json);
|
||||
}
|
||||
else if (it->second.isString())
|
||||
else if (it->second.isString())
|
||||
{
|
||||
if (it->first == "amount") continue;
|
||||
auto field_value = it->second.extract<std::string>();
|
||||
@ -383,7 +365,7 @@ namespace DataTypeConverter
|
||||
for (Poco::JSON::Array::ValueVec::const_iterator it = json->begin(); it != json->end(); it++)
|
||||
{
|
||||
if (json->isObject(it)) {
|
||||
|
||||
|
||||
auto local_json = it->extract<Poco::JSON::Object::Ptr>();
|
||||
count_replacements += replaceBase64WithHex(local_json);
|
||||
json->set(count, local_json);
|
||||
@ -414,14 +396,14 @@ namespace DataTypeConverter
|
||||
|
||||
std::string replaceNewLineWithBr(std::string& in)
|
||||
{
|
||||
|
||||
|
||||
std::string::size_type pos = 0; // Must initialize
|
||||
while ((pos = in.find("\r\n", pos)) != std::string::npos) {
|
||||
in.replace(pos, 2, "<br>");
|
||||
}
|
||||
pos = 0;
|
||||
while ((pos = in.find("\n", pos)) != std::string::npos) {
|
||||
in.replace(pos, 1, "<br>");
|
||||
in.replace(pos, 1, "<br>");
|
||||
}
|
||||
pos = 0;
|
||||
while ((pos = in.find(" ", pos)) != std::string::npos) {
|
||||
@ -429,4 +411,4 @@ namespace DataTypeConverter
|
||||
}
|
||||
return in;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,8 +11,6 @@
|
||||
#include "Poco/JSON/Array.h"
|
||||
#include "../SingletonManager/LanguageManager.h"
|
||||
|
||||
#include "proto/hedera/Timestamp.pb.h"
|
||||
#include "proto/hedera/Duration.pb.h"
|
||||
#include "proto/gradido/BasicTypes.pb.h"
|
||||
|
||||
#include "sodium.h"
|
||||
@ -58,15 +56,12 @@ namespace DataTypeConverter {
|
||||
//! \brief convert duration in string showing seconds, minutes, hours or days
|
||||
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);
|
||||
inline void convertToProtoTimestampSeconds(const Poco::Timestamp pocoTimestamp, proto::gradido::TimestampSeconds* protoTimestampSeconds) {
|
||||
protoTimestampSeconds->set_seconds(pocoTimestamp.epochTime());
|
||||
}
|
||||
Poco::Timespan convertFromProtoDuration(const proto::Duration& duration);
|
||||
|
||||
//! \brief go through json object and replace every string entry in base64 format into hex format
|
||||
//! \return count of replaced strings
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include "model/table/EmailOptIn.h"
|
||||
|
||||
#include "Poco/DateTimeParser.h"
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#ifndef _TEST_BUILD
|
||||
|
||||
@ -52,18 +51,16 @@ int main(int argc, char** argv)
|
||||
return -3;
|
||||
}
|
||||
printf("[Gradido_LoginServer::main] passed important tests\n");
|
||||
grpc_init();
|
||||
|
||||
Gradido_LoginServer app;
|
||||
try {
|
||||
auto result = app.run(argc, argv);
|
||||
grpc_shutdown();
|
||||
return result;
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
printf("[Gradido_LoginServer::main] exception by starting server: %s\n", ex.displayText().data());
|
||||
}
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
|
||||
#include "../tasks/PrepareEmailTask.h"
|
||||
#include "../tasks/SendEmailTask.h"
|
||||
#include "../tasks/SigningTransaction.h"
|
||||
#include "../tasks/AuthenticatedEncryptionCreateKeyTask.h"
|
||||
#include "../tasks/VerificationEmailResendTask.h"
|
||||
|
||||
@ -53,8 +52,8 @@ Session::~Session()
|
||||
unlock();
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//printf("[Session::~Session] finished \n");
|
||||
}
|
||||
|
||||
@ -70,24 +69,21 @@ void Session::reset()
|
||||
// watch out
|
||||
//updateTimeout();
|
||||
mLastActivity = Poco::DateTime();
|
||||
|
||||
|
||||
mState = SESSION_STATE_EMPTY;
|
||||
|
||||
|
||||
mPassphrase = "";
|
||||
mLastExternReferer = "";
|
||||
mClientLoginIP = Poco::Net::IPAddress();
|
||||
unlock();
|
||||
|
||||
// reset transactions
|
||||
mCurrentActiveProcessingTransaction = nullptr;
|
||||
mProcessingTransactions.clear();
|
||||
|
||||
//printf("[Session::reset] finished\n");
|
||||
}
|
||||
|
||||
int Session::isActive()
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
try {
|
||||
mWorkMutex.tryLock(100);
|
||||
}
|
||||
@ -95,7 +91,7 @@ int Session::isActive()
|
||||
return -1;
|
||||
}
|
||||
ret = (int)mActive;
|
||||
unlock();
|
||||
unlock();
|
||||
return ret;
|
||||
|
||||
}
|
||||
@ -108,21 +104,21 @@ bool Session::isDeadLocked()
|
||||
return false;
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Session::setActive(bool active)
|
||||
{
|
||||
{
|
||||
try {
|
||||
mWorkMutex.tryLock(100);
|
||||
}
|
||||
catch (Poco::TimeoutException &ex) {
|
||||
return false;
|
||||
}
|
||||
mActive = active;
|
||||
unlock();
|
||||
mActive = active;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -187,13 +183,13 @@ bool Session::adminCreateUser(const std::string& first_name, const std::string&
|
||||
addError(new Error(gettext("Email Verification Code"), gettext("Fehler beim speichern!")));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EmailManager::getInstance()->addEmail(new model::Email(email_verification_code, newUser, model::EMAIL_ADMIN_USER_VERIFICATION_CODE));
|
||||
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
mEmailVerificationCodeObject = email_verification_code;
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -223,7 +219,7 @@ bool Session::createUserDirect(const std::string& first_name, const std::string&
|
||||
addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine gültige E-Mail Adresse an.")), false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!sm->checkPwdValidation(password, this, mLanguageCatalog)) {
|
||||
return false;
|
||||
}
|
||||
@ -247,7 +243,7 @@ bool Session::createUserDirect(const std::string& first_name, const std::string&
|
||||
auto user_model = mNewUser->getModel();
|
||||
user_model->insertIntoDB(true);
|
||||
auto user_id = user_model->getID();
|
||||
|
||||
|
||||
// one retry in case of connection error
|
||||
if (!user_id) {
|
||||
user_model->insertIntoDB(true);
|
||||
@ -317,17 +313,17 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
// new mutex, will replace the Poco Mutex complete in the future
|
||||
std::unique_lock<std::shared_mutex> _lock_shared(mSharedMutex);
|
||||
Profiler usedTime;
|
||||
|
||||
|
||||
auto em = ErrorManager::getInstance();
|
||||
if (mEmailVerificationCodeObject.isNull()) {
|
||||
em->addError(new Error(funcName, "email verification object is zero"));
|
||||
em->sendErrorsAsEmail();
|
||||
|
||||
|
||||
return -2;
|
||||
}
|
||||
auto email_verification_code_model = mEmailVerificationCodeObject->getModel();
|
||||
assert(email_verification_code_model);
|
||||
if(email_verification_code_model->getCode() == emailVerificationCode)
|
||||
if(email_verification_code_model->getCode() == emailVerificationCode)
|
||||
{
|
||||
// load correct user from db
|
||||
if (mNewUser.isNull() || !mNewUser->getModel() || mNewUser->getModel()->getID() != email_verification_code_model->getUserId()) {
|
||||
@ -335,7 +331,7 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
if (1 != mNewUser->load(email_verification_code_model->getUserId())) {
|
||||
em->addError(new ParamError(funcName, "user load didn't return 1 with user_id ", email_verification_code_model->getUserId()));
|
||||
em->sendErrorsAsEmail();
|
||||
|
||||
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
@ -344,14 +340,14 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
assert(user_model);
|
||||
bool first_email_activation = false;
|
||||
auto verification_type = email_verification_code_model->getType();
|
||||
if (model::table::EMAIL_OPT_IN_REGISTER == verification_type ||
|
||||
if (model::table::EMAIL_OPT_IN_REGISTER == verification_type ||
|
||||
model::table::EMAIL_OPT_IN_EMPTY == verification_type ||
|
||||
model::table::EMAIL_OPT_IN_REGISTER_DIRECT == verification_type) {
|
||||
first_email_activation = true;
|
||||
}
|
||||
if (first_email_activation && user_model->isEmailChecked()) {
|
||||
addError(new Error(gettext("E-Mail Verification"), gettext("Du hast dein Konto bereits aktiviert!")), false);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (first_email_activation) {
|
||||
@ -363,13 +359,13 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
}
|
||||
|
||||
// no find all active sessions
|
||||
|
||||
|
||||
updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (email_verification_code_model->getType() == model::table::EMAIL_OPT_IN_RESET_PASSWORD) {
|
||||
|
||||
|
||||
if (mEmailVerificationCodeObject->deleteFromDB()) {
|
||||
mEmailVerificationCodeObject.assign(nullptr);
|
||||
}
|
||||
@ -385,18 +381,18 @@ int Session::updateEmailVerification(Poco::UInt64 emailVerificationCode)
|
||||
|
||||
em->addError(new Error(funcName, "invalid code path"));
|
||||
em->sendErrorsAsEmail();
|
||||
|
||||
|
||||
return -2;
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
addError(new Error(gettext("E-Mail Verification"), gettext("Falscher Code für aktiven Login")));
|
||||
//printf("[%s] time: %s\n", funcName, usedTime.string().data());
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
//printf("[%s] time: %s\n", funcName, usedTime.string().data());
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -409,7 +405,7 @@ int Session::sendResetPasswordEmail(Poco::AutoPtr<controller::User> user, bool p
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
|
||||
// creating email verification code also for user without passphrase
|
||||
// first check if already exist
|
||||
// first check if already exist
|
||||
// check if email was already send shortly before
|
||||
bool frequent_resend = false;
|
||||
bool email_already_send = false;
|
||||
@ -450,7 +446,7 @@ int Session::sendResetPasswordEmail(Poco::AutoPtr<controller::User> user, bool p
|
||||
|
||||
int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase, const Mnemonic* wordSource)
|
||||
{
|
||||
|
||||
|
||||
static const char* functionName = "Session::comparePassphraseWithSavedKeys";
|
||||
if (!wordSource) {
|
||||
addError(new Error(functionName, "wordSource is empty"));
|
||||
@ -495,137 +491,6 @@ int Session::comparePassphraseWithSavedKeys(const std::string& inputPassphrase,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Session::startProcessingTransaction(const std::string& proto_message_base64, bool autoSign/* = false*/)
|
||||
{
|
||||
static const char* funcName = "Session::startProcessingTransaction";
|
||||
lock(funcName);
|
||||
HASH hs = ProcessingTransaction::calculateHash(proto_message_base64);
|
||||
// check if it is already running or waiting
|
||||
for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) {
|
||||
if (it->isNull()) {
|
||||
it = mProcessingTransactions.erase(it);
|
||||
}
|
||||
if (hs == (*it)->getHash()) {
|
||||
addError(new Error(funcName, "transaction already in list"));
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Languages lang = LANG_DE;
|
||||
if (!mNewUser.isNull()) {
|
||||
lang = LanguageManager::languageFromString(mNewUser->getModel()->getLanguageKey());
|
||||
}
|
||||
auto user_model = mNewUser->getModel();
|
||||
Poco::AutoPtr<ProcessingTransaction> processorTask(
|
||||
new ProcessingTransaction(
|
||||
proto_message_base64,
|
||||
DRMakeStringHash(user_model->getEmail().data()),
|
||||
lang
|
||||
)
|
||||
);
|
||||
if (autoSign && (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) == ServerConfig::UNSECURE_AUTO_SIGN_TRANSACTIONS) {
|
||||
if (processorTask->run() != 0) {
|
||||
getErrors(processorTask);
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
Poco::AutoPtr<SigningTransaction> signingTransaction(new SigningTransaction(processorTask, mNewUser));
|
||||
//signingTransaction->scheduleTask(signingTransaction);
|
||||
if (signingTransaction->run() != 0) {
|
||||
getErrors(signingTransaction);
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
processorTask->scheduleTask(processorTask);
|
||||
mProcessingTransactions.push_back(processorTask);
|
||||
}
|
||||
unlock();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<ProcessingTransaction> Session::getNextReadyTransaction(size_t* working/* = nullptr*/)
|
||||
{
|
||||
lock("Session::getNextReadyTransaction");
|
||||
if (working) {
|
||||
*working = 0;
|
||||
}
|
||||
else if (!mCurrentActiveProcessingTransaction.isNull())
|
||||
{
|
||||
unlock();
|
||||
return mCurrentActiveProcessingTransaction;
|
||||
}
|
||||
for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) {
|
||||
if (working && !(*it)->isTaskFinished()) {
|
||||
(*working)++;
|
||||
}
|
||||
if (mCurrentActiveProcessingTransaction.isNull() && (*it)->isTaskFinished()) {
|
||||
if (!working) {
|
||||
mCurrentActiveProcessingTransaction = *it;
|
||||
unlock();
|
||||
return mCurrentActiveProcessingTransaction;
|
||||
}
|
||||
// no early exit
|
||||
else {
|
||||
mCurrentActiveProcessingTransaction = *it;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return mCurrentActiveProcessingTransaction;
|
||||
}
|
||||
|
||||
bool Session::finalizeTransaction(bool sign, bool reject)
|
||||
{
|
||||
int result = -1;
|
||||
lock("Session::finalizeTransaction");
|
||||
if (mCurrentActiveProcessingTransaction.isNull()) {
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
mProcessingTransactions.remove(mCurrentActiveProcessingTransaction);
|
||||
|
||||
if (!reject) {
|
||||
if (sign) {
|
||||
Poco::AutoPtr<SigningTransaction> signingTransaction(new SigningTransaction(mCurrentActiveProcessingTransaction, mNewUser));
|
||||
//signingTransaction->scheduleTask(signingTransaction);
|
||||
result = signingTransaction->run();
|
||||
}
|
||||
}
|
||||
mCurrentActiveProcessingTransaction.assign(nullptr);
|
||||
unlock();
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
size_t Session::getProcessingTransactionCount()
|
||||
{
|
||||
size_t count = 0;
|
||||
lock("Session::getProcessingTransactionCount");
|
||||
|
||||
for (auto it = mProcessingTransactions.begin(); it != mProcessingTransactions.end(); it++) {
|
||||
|
||||
(*it)->lock();
|
||||
if ((*it)->errorCount() > 0) {
|
||||
(*it)->sendErrorsAsEmail();
|
||||
(*it)->unlock();
|
||||
it = mProcessingTransactions.erase(it);
|
||||
if (it == mProcessingTransactions.end()) break;
|
||||
}
|
||||
else {
|
||||
(*it)->unlock();
|
||||
}
|
||||
|
||||
}
|
||||
count = mProcessingTransactions.size();
|
||||
unlock();
|
||||
return count;
|
||||
}
|
||||
|
||||
UserState Session::loadUser(const std::string& email, const std::string& password)
|
||||
{
|
||||
static const char* functionName = "Session::loadUser";
|
||||
@ -657,11 +522,11 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
}
|
||||
//printf("before get model\n");
|
||||
auto user_model = mNewUser->getModel();
|
||||
if (user_model && user_model->isDisabled()) {
|
||||
if (user_model && user_model->isDisabled()) {
|
||||
return USER_DISABLED;
|
||||
}
|
||||
if (mNewUser->getUserState() >= USER_LOADED_FROM_DB) {
|
||||
|
||||
|
||||
NotificationList pwd_errors;
|
||||
auto lm = LanguageManager::getInstance();
|
||||
auto lang_key = mNewUser->getModel()->getLanguageKey();
|
||||
@ -677,9 +542,9 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
|
||||
int loginResult = mNewUser->login(password);
|
||||
int exitCount = 0;
|
||||
if (loginResult == -3)
|
||||
if (loginResult == -3)
|
||||
{
|
||||
do
|
||||
do
|
||||
{
|
||||
Poco::Thread::sleep(100);
|
||||
loginResult = mNewUser->login(password);
|
||||
@ -702,7 +567,7 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
return USER_PASSWORD_ENCRYPTION_IN_PROCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (-1 == loginResult)
|
||||
{
|
||||
addError(new Error(functionName, "error in user data set, saved pubkey didn't match extracted pubkey from private key"));
|
||||
@ -711,7 +576,7 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
//unlock();
|
||||
//return USER_KEYS_DONT_MATCH;
|
||||
}
|
||||
if (0 == loginResult)
|
||||
if (0 == loginResult)
|
||||
{
|
||||
return USER_PASSWORD_INCORRECT;
|
||||
}
|
||||
@ -724,9 +589,9 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
auto user_backups = controller::UserBackup::load(user_model->getID());
|
||||
for (auto it = user_backups.begin(); it != user_backups.end(); it++) {
|
||||
auto key = std::unique_ptr<KeyPairEd25519>((*it)->createGradidoKeyPair());
|
||||
if (key->isTheSame(user_model->getPublicKey()))
|
||||
if (key->isTheSame(user_model->getPublicKey()))
|
||||
{
|
||||
|
||||
|
||||
// set valid key pair
|
||||
if (1 == mNewUser->setGradidoKeyPair(key.release())) {
|
||||
// save new encrypted private key
|
||||
@ -742,7 +607,7 @@ UserState Session::loadUser(const std::string& email, const std::string& passwor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
Poco::Thread::sleep(ServerConfig::g_FakeLoginSleepTime);
|
||||
@ -851,7 +716,7 @@ void Session::detectSessionState()
|
||||
else if (checkEmail != -1) {
|
||||
mEmailVerificationCodeObject = emailVerificationCodeObjects[checkEmail];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
printf("[Session::detectSessionState] exception: %s\n", ex.displayText().data());
|
||||
@ -864,13 +729,13 @@ void Session::detectSessionState()
|
||||
updateState(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
updateState(SESSION_STATE_USER_WRITTEN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (USER_NO_KEYS == userState) {
|
||||
|
||||
|
||||
auto user_id = mNewUser->getModel()->getID();
|
||||
auto userBackups = controller::UserBackup::load(user_id);
|
||||
|
||||
@ -903,8 +768,8 @@ void Session::detectSessionState()
|
||||
auto dbConnection = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(dbConnection);
|
||||
Poco::Nullable<Poco::Data::BLOB> passphrase;
|
||||
|
||||
select << "SELECT passphrase from user_backups where user_id = ?;",
|
||||
|
||||
select << "SELECT passphrase from user_backups where user_id = ?;",
|
||||
into(passphrase), use(user_id);
|
||||
try {
|
||||
if (select.execute() == 1 && !passphrase.isNull()) {
|
||||
@ -927,7 +792,7 @@ void Session::detectSessionState()
|
||||
updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
updateState(SESSION_STATE_KEY_PAIR_WRITTEN);
|
||||
|
||||
if (resetPasswd != -1) {
|
||||
@ -945,14 +810,14 @@ Poco::Net::HTTPCookie Session::getLoginCookie()
|
||||
// keks.setHttpOnly();
|
||||
|
||||
keks.setPath("/");
|
||||
// send cookie only via https, on linux, except in test builds
|
||||
// send cookie only via https, on linux, except in test builds
|
||||
#ifndef WIN32
|
||||
if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType ||
|
||||
ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) {
|
||||
keks.setSecure(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return keks;
|
||||
}
|
||||
|
||||
@ -1024,7 +889,7 @@ const char* Session::translateSessionStateToString(SessionStates state)
|
||||
case SESSION_STATE_EMAIL_VERIFICATION_SEND: return "Verification E-Mail sended";
|
||||
case SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED: return "Verification Code checked";
|
||||
case SESSION_STATE_PASSPHRASE_GENERATED: return "Passphrase generated";
|
||||
case SESSION_STATE_PASSPHRASE_SHOWN: return "Passphrase shown";
|
||||
case SESSION_STATE_PASSPHRASE_SHOWN: return "Passphrase shown";
|
||||
case SESSION_STATE_PASSPHRASE_WRITTEN: return "Passphrase written";
|
||||
case SESSION_STATE_KEY_PAIR_GENERATED: return "Gradido Address created";
|
||||
case SESSION_STATE_KEY_PAIR_WRITTEN: return "Gradido Address saved";
|
||||
@ -1041,7 +906,7 @@ const char* Session::translateSessionStateToString(SessionStates state)
|
||||
bool Session::useOrGeneratePassphrase(const std::string& passphase)
|
||||
{
|
||||
if (passphase != "" && User::validatePassphrase(passphase)) {
|
||||
// passphrase is valid
|
||||
// passphrase is valid
|
||||
setPassphrase(passphase);
|
||||
updateState(SESSION_STATE_PASSPHRASE_SHOWN);
|
||||
return true;
|
||||
@ -1081,7 +946,7 @@ bool Session::generateKeys(bool savePrivkey, bool savePassphrase)
|
||||
if (savePassphrase) {
|
||||
auto user_backup = controller::UserBackup::create(user_model->getID(), passphrase->getString(), mnemonic_type);
|
||||
// sync version
|
||||
//user_backup->getModel()->insertIntoDB(false);
|
||||
//user_backup->getModel()->insertIntoDB(false);
|
||||
|
||||
// async version
|
||||
UniLib::controller::TaskPtr save_user_backup_task = new model::table::ModelInsertTask(user_backup->getModel(), false, true);
|
||||
@ -1089,7 +954,7 @@ bool Session::generateKeys(bool savePrivkey, bool savePassphrase)
|
||||
save_user_backup_task->scheduleTask(save_user_backup_task);
|
||||
}
|
||||
|
||||
// keys
|
||||
// keys
|
||||
auto gradido_key_pair = KeyPairEd25519::create(passphrase);
|
||||
auto set_key_result = mNewUser->setGradidoKeyPair(gradido_key_pair);
|
||||
size_t result_save_key = 0;
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#include "../controller/User.h"
|
||||
|
||||
#include "../lib/MultithreadContainer.h"
|
||||
#include "../tasks/ProcessingTransaction.h"
|
||||
|
||||
#include "../SingletonManager/LanguageManager.h"
|
||||
|
||||
@ -83,7 +82,7 @@ public:
|
||||
// TODO: check if email exist and if not, fake waiting on password hashing with profiled times of real password hashing
|
||||
UserState loadUser(const std::string& email, const std::string& password);
|
||||
bool ifUserExist(const std::string& email);
|
||||
|
||||
|
||||
bool deleteUser();
|
||||
|
||||
|
||||
@ -102,7 +101,7 @@ public:
|
||||
//! \return 2 = reset password email already shortly before
|
||||
//! \return 0 = ok
|
||||
int sendResetPasswordEmail(Poco::AutoPtr<controller::User> user, bool passphraseMemorized, const std::string &baseUrl);
|
||||
//
|
||||
//
|
||||
//! \return 0 = not the same
|
||||
//! \return 1 = same
|
||||
//! \return -1 = error
|
||||
@ -111,23 +110,23 @@ public:
|
||||
|
||||
Poco::Net::HTTPCookie getLoginCookie();
|
||||
|
||||
|
||||
|
||||
inline int getHandle() { return mHandleId; }
|
||||
|
||||
// ------------------------ Passphrase functions ----------------------------
|
||||
|
||||
|
||||
inline void setPassphrase(Poco::AutoPtr<Passphrase> passphrase) { mNewPassphrase = passphrase; }
|
||||
inline Poco::AutoPtr<Passphrase> getPassphrase() { return mNewPassphrase; }
|
||||
|
||||
inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; }
|
||||
|
||||
|
||||
inline const std::string& getOldPassphrase() { return mPassphrase; }
|
||||
|
||||
|
||||
bool generateKeys(bool savePrivkey, bool savePassphrase);
|
||||
|
||||
inline void setClientIp(Poco::Net::IPAddress ip) { mClientLoginIP = ip; }
|
||||
inline Poco::Net::IPAddress getClientIp() { return mClientLoginIP; }
|
||||
|
||||
|
||||
inline bool isIPValid(Poco::Net::IPAddress ip) { return mClientLoginIP == ip; }
|
||||
void reset();
|
||||
|
||||
@ -135,9 +134,9 @@ public:
|
||||
const char* getSessionStateString();
|
||||
inline SessionStates getSessionState() { SessionStates s; lock("Session::getSessionState"); s = mState; unlock(); return s; }
|
||||
|
||||
inline Poco::UInt64 getEmailVerificationCode() {
|
||||
inline Poco::UInt64 getEmailVerificationCode() {
|
||||
std::shared_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
if (mEmailVerificationCodeObject.isNull()) return 0; return mEmailVerificationCodeObject->getModel()->getCode();
|
||||
if (mEmailVerificationCodeObject.isNull()) return 0; return mEmailVerificationCodeObject->getModel()->getCode();
|
||||
}
|
||||
inline void setEmailVerificationCodeObject(Poco::AutoPtr<controller::EmailVerificationCode> emailVerficationObject) {
|
||||
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
|
||||
@ -153,7 +152,7 @@ public:
|
||||
|
||||
//! \return -1 if session is locked
|
||||
//! \return 1 if session is active
|
||||
//! \return 0
|
||||
//! \return 0
|
||||
int isActive();
|
||||
//! \return false if session is locked
|
||||
bool setActive(bool active);
|
||||
@ -164,12 +163,6 @@ public:
|
||||
|
||||
// ------------------------ transactions functions ----------------------------
|
||||
|
||||
//! \return true if succeed
|
||||
bool startProcessingTransaction(const std::string& proto_message_base64, bool autoSign = false);
|
||||
//! \param working if set will filled with transaction running
|
||||
Poco::AutoPtr<ProcessingTransaction> getNextReadyTransaction(size_t* working = nullptr);
|
||||
bool finalizeTransaction(bool sign, bool reject);
|
||||
size_t getProcessingTransactionCount();
|
||||
|
||||
inline LanguageCatalog* getLanguageCatalog() { return mLanguageCatalog.isNull() ? nullptr : mLanguageCatalog; }
|
||||
void setLanguage(Languages lang);
|
||||
@ -187,14 +180,14 @@ public:
|
||||
protected:
|
||||
void updateTimeout();
|
||||
inline void setHandle(int newHandle) { mHandleId = newHandle; }
|
||||
|
||||
|
||||
void detectSessionState();
|
||||
static const char* translateSessionStateToString(SessionStates state);
|
||||
|
||||
inline const std::string& getPassphrase() const { return mPassphrase; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
int mHandleId;
|
||||
Poco::AutoPtr<controller::User> mNewUser;
|
||||
std::string mPassphrase;
|
||||
@ -211,8 +204,6 @@ private:
|
||||
SessionStates mState;
|
||||
|
||||
bool mActive;
|
||||
std::list<Poco::AutoPtr<ProcessingTransaction>> mProcessingTransactions;
|
||||
Poco::AutoPtr<ProcessingTransaction> mCurrentActiveProcessingTransaction;
|
||||
|
||||
Poco::AutoPtr<LanguageCatalog> mLanguageCatalog;
|
||||
};
|
||||
|
||||
@ -2,21 +2,13 @@
|
||||
#include "../../SingletonManager/ErrorManager.h"
|
||||
#include "../../SingletonManager/PendingTasksManager.h"
|
||||
#include "../../SingletonManager/LanguageManager.h"
|
||||
#include "../../SingletonManager/CronManager.h"
|
||||
#include "../../ServerConfig.h"
|
||||
|
||||
#include "../../controller/HederaId.h"
|
||||
#include "../../controller/HederaAccount.h"
|
||||
#include "../../controller/HederaRequest.h"
|
||||
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
#include "../../lib/Profiler.h"
|
||||
#include "../../lib/JsonRequest.h"
|
||||
|
||||
#include "../hedera/Transaction.h"
|
||||
#include "../hedera/TransactionId.h"
|
||||
|
||||
#include "../../tasks/HederaTask.h"
|
||||
|
||||
#include <google/protobuf/util/json_util.h>
|
||||
|
||||
@ -65,21 +57,11 @@ namespace model {
|
||||
return nullptr;
|
||||
}
|
||||
auto group_model = group->getModel();
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
auto topic_id = controller::HederaId::find(group_model->getID(), network_type);
|
||||
|
||||
if (topic_id.isNull()) {
|
||||
em->addError(new ParamError(function_name, "could'n find topic for group: ", group_model->getID()));
|
||||
em->addError(new ParamError(function_name, "network type: ", network_type));
|
||||
em->sendErrorsAsEmail();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto body = TransactionBody::create("", user, proto::gradido::GroupMemberUpdate_MemberUpdateType_ADD_USER, group_model->getAlias());
|
||||
|
||||
Poco::AutoPtr<Transaction> result = new Transaction(body);
|
||||
auto model = result->getModel();
|
||||
model->setHederaId(topic_id->getModel()->getID());
|
||||
result->insertPendingTaskIntoDB(user, model::table::TASK_TYPE_GROUP_ADD_MEMBER);
|
||||
PendingTasksManager::getInstance()->addTask(result);
|
||||
return result;
|
||||
@ -99,7 +81,6 @@ namespace model {
|
||||
if (receiver.isNull() || !receiver->getModel()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
auto receiver_model = receiver->getModel();
|
||||
|
||||
auto body = TransactionBody::create(memo, receiver, amount, targetDate, blockchainType);
|
||||
@ -107,17 +88,7 @@ namespace model {
|
||||
|
||||
result->setParam("blockchain_type", (int)blockchainType);
|
||||
auto model = result->getModel();
|
||||
if (blockchainType == BLOCKCHAIN_HEDERA) {
|
||||
auto topic_id = controller::HederaId::find(receiver_model->getGroupId(), 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 nullptr;
|
||||
}
|
||||
model->setHederaId(topic_id->getModel()->getID());
|
||||
}
|
||||
|
||||
result->insertPendingTaskIntoDB(receiver, model::table::TASK_TYPE_CREATION);
|
||||
PendingTasksManager::getInstance()->addTask(result);
|
||||
@ -136,7 +107,6 @@ namespace model {
|
||||
{
|
||||
Poco::AutoPtr<Transaction> transaction;
|
||||
Poco::AutoPtr<TransactionBody> transaction_body;
|
||||
Poco::AutoPtr<controller::HederaId> topic_id;
|
||||
auto em = ErrorManager::getInstance();
|
||||
static const char* function_name = "Transaction::create transfer";
|
||||
|
||||
@ -151,75 +121,6 @@ namespace model {
|
||||
transaction_body = TransactionBody::create(memo, sender, receiverPubkey, amount, blockchainType);
|
||||
transaction = new Transaction(transaction_body);
|
||||
}
|
||||
else if (blockchainType == BLOCKCHAIN_HEDERA)
|
||||
{
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
|
||||
|
||||
// LOCAL Transfer
|
||||
if (receiverGroup.isNull() || sender_model->getGroupId() == receiverGroup->getModel()->getID())
|
||||
{
|
||||
topic_id = controller::HederaId::find(sender_model->getGroupId(), network_type);
|
||||
|
||||
if (topic_id.isNull())
|
||||
{
|
||||
em->addError(new ParamError(function_name, "could'n find topic for group: ", sender_model->getGroupId()));
|
||||
em->addError(new ParamError(function_name, "network type: ", network_type));
|
||||
em->sendErrorsAsEmail();
|
||||
return transaction;
|
||||
}
|
||||
transaction_body = TransactionBody::create(memo, sender, receiverPubkey, amount, blockchainType);
|
||||
transaction = new Transaction(transaction_body);
|
||||
}
|
||||
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 transaction;
|
||||
}
|
||||
Poco::AutoPtr<controller::Group> transaction_group;
|
||||
Poco::AutoPtr<controller::Group> 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) {
|
||||
transaction_group = receiverGroup;
|
||||
topic_group = sender_group;
|
||||
}
|
||||
// transaction send to receiver blockchain
|
||||
else if (inbound) {
|
||||
transaction_group = sender_group;
|
||||
topic_group = receiverGroup;
|
||||
}
|
||||
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: ", sender_model->getGroupId()));
|
||||
em->addError(new ParamError(function_name, "network type: ", network_type));
|
||||
em->sendErrorsAsEmail();
|
||||
return transaction;
|
||||
}
|
||||
if (transaction_group.isNull()) {
|
||||
em->addError(new ParamError(function_name, "transaction group is zero, inbound", inbound));
|
||||
em->sendErrorsAsEmail();
|
||||
return transaction;
|
||||
}
|
||||
|
||||
auto body = TransactionBody::create(memo, sender, receiverPubkey, amount, blockchainType, pairedTransactionId, transaction_group);
|
||||
Poco::AutoPtr<Transaction> transaction = new Transaction(body);
|
||||
|
||||
auto transfer_transaction = transaction->getTransactionBody()->getTransferTransaction();
|
||||
transfer_transaction->setOwnGroupAlias(sender_group->getModel()->getAlias());
|
||||
transfer_transaction->setTargetGroupAlias(receiverGroup->getModel()->getAlias());
|
||||
|
||||
}
|
||||
auto transaction_model = transaction->getModel();
|
||||
transaction_model->setHederaId(topic_id->getModel()->getID());
|
||||
|
||||
}
|
||||
|
||||
transaction->setParam("blockchain_type", (int)blockchainType);
|
||||
transaction->insertPendingTaskIntoDB(sender, model::table::TASK_TYPE_TRANSFER);
|
||||
@ -228,25 +129,6 @@ namespace model {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
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> Transaction::createTransfer(
|
||||
const MemoryBin* senderPubkey,
|
||||
@ -267,7 +149,6 @@ namespace model {
|
||||
|
||||
//std::vector<Poco::AutoPtr<TransactionBody>> bodys;
|
||||
auto receiver_model = receiver->getModel();
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
|
||||
auto sender_groups = controller::Group::load(senderGroupAlias);
|
||||
if (!sender_groups.size()) {
|
||||
@ -298,16 +179,7 @@ namespace model {
|
||||
|
||||
auto body = TransactionBody::create(memo, senderPubkey, receiver, amount, pairedTransactionId, transaction_group);
|
||||
result = new Transaction(body);
|
||||
if (blockchainType == BLOCKCHAIN_HEDERA) {
|
||||
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;
|
||||
}
|
||||
result->getModel()->setHederaId(topic_id->getModel()->getID());
|
||||
}
|
||||
|
||||
result->setParam("blockchain_type", (int)blockchainType);
|
||||
result->insertPendingTaskIntoDB(receiver, model::table::TASK_TYPE_TRANSFER);
|
||||
PendingTasksManager::getInstance()->addTask(result);
|
||||
@ -642,10 +514,8 @@ namespace model {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mTransactionBody->isHederaBlockchain()) {
|
||||
return runSendTransactionHedera();
|
||||
}
|
||||
else if (mTransactionBody->isMysqlBlockchain()) {
|
||||
|
||||
if (mTransactionBody->isMysqlBlockchain()) {
|
||||
return runSendTransactionMysql();
|
||||
}
|
||||
addError(new ParamError(function_name, "not implemented blockchain type", mTransactionBody->getBlockchainTypeString()));
|
||||
@ -654,145 +524,6 @@ namespace model {
|
||||
|
||||
}
|
||||
|
||||
int Transaction::runSendTransactionHedera()
|
||||
{
|
||||
static const char* function_name = "Transaction::runSendTransactionHedera";
|
||||
// send transaction via hedera
|
||||
auto network_type = ServerConfig::g_HederaNetworkType;
|
||||
// TODO: get correct topic id for user group
|
||||
//int user_group_id = 1;
|
||||
//auto topic_id = controller::HederaId::find(user_group_id, network_type);
|
||||
auto topic_id = controller::HederaId::load(getModel()->getHederaId());
|
||||
auto hedera_operator_account = controller::HederaAccount::pick(network_type, false);
|
||||
|
||||
if (!topic_id.isNull() && !hedera_operator_account.isNull())
|
||||
{
|
||||
auto crypto_key = hedera_operator_account->getCryptoKey();
|
||||
if (!crypto_key.isNull())
|
||||
{
|
||||
model::hedera::ConsensusSubmitMessage consensus_submit_message(topic_id);
|
||||
std::string raw_message = mProtoTransaction.SerializeAsString();
|
||||
|
||||
if (ServerConfig::HEDERA_CONSENSUS_FORMAT_BINARY == ServerConfig::g_ConsensusMessageFormat) {
|
||||
consensus_submit_message.setMessage(raw_message);
|
||||
|
||||
// print to txt for debugging gradido node
|
||||
static Poco::FastMutex _file_mutex;
|
||||
Poco::ScopedLock<Poco::FastMutex> _lock_file(_file_mutex);
|
||||
std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S") + "\n";
|
||||
|
||||
std::string json_message = getTransactionAsJson();
|
||||
std::string base64_message = DataTypeConverter::binToBase64((const unsigned char*)raw_message.data(), raw_message.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
||||
if (json_message != "")
|
||||
{
|
||||
Poco::Logger& transactions_log = Poco::Logger::get("transactions_log");
|
||||
transactions_log.information(dateTimeString);
|
||||
transactions_log.information(json_message);
|
||||
}
|
||||
if (base64_message != "")
|
||||
{
|
||||
Poco::Logger& transaction_log_base64 = Poco::Logger::get("transactions_log_base64");
|
||||
transaction_log_base64.information(dateTimeString);
|
||||
transaction_log_base64.information(base64_message);
|
||||
}
|
||||
}
|
||||
else if (ServerConfig::HEDERA_CONSENSUS_FORMAT_BASE64_URLSAVE_NO_PADDING == ServerConfig::g_ConsensusMessageFormat) {
|
||||
consensus_submit_message.setMessage(DataTypeConverter::binToBase64((const unsigned char*)raw_message.data(), raw_message.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING));
|
||||
}
|
||||
else if (ServerConfig::HEDERA_CONSENSUS_FORMAT_JSON == ServerConfig::g_ConsensusMessageFormat) {
|
||||
std::string json_message = getTransactionAsJson();
|
||||
if (json_message != "") {
|
||||
consensus_submit_message.setMessage(json_message);
|
||||
}
|
||||
else {
|
||||
//sendErrorsAsEmail();
|
||||
return -7;
|
||||
}
|
||||
|
||||
}
|
||||
// if using testnet, transfer message base64 encoded to check messages in hedera block explorer
|
||||
//if (network_type == table::HEDERA_TESTNET) {
|
||||
//consensus_submit_message.setMessage(DataTypeConverter::binToBase64((const unsigned char*)raw_message.data(), raw_message.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING));
|
||||
//}
|
||||
//else {
|
||||
|
||||
//}
|
||||
auto hedera_transaction_body = hedera_operator_account->createTransactionBody();
|
||||
hedera_transaction_body->setConsensusSubmitMessage(consensus_submit_message);
|
||||
model::hedera::Transaction hedera_transaction;
|
||||
|
||||
hedera_transaction.sign(crypto_key->getKeyPair(), std::move(hedera_transaction_body));
|
||||
|
||||
HederaRequest hedera_request;
|
||||
Poco::AutoPtr<HederaTask> hedera_task(new HederaTask(this));
|
||||
|
||||
if (HEDERA_REQUEST_RETURN_OK != hedera_request.request(&hedera_transaction, hedera_task))
|
||||
{
|
||||
addError(new Error(function_name, "error send transaction to hedera"));
|
||||
getErrors(&hedera_request);
|
||||
//sendErrorsAsEmail();
|
||||
return -2;
|
||||
}
|
||||
else {
|
||||
auto hedera_transaction_response = hedera_task->getTransactionResponse();
|
||||
auto hedera_precheck_code_string = hedera_transaction_response->getPrecheckCodeString();
|
||||
auto precheck_code = hedera_transaction_response->getPrecheckCode();
|
||||
auto cost = hedera_transaction_response->getCost();
|
||||
|
||||
// for showing in docker
|
||||
std::clog << "hedera response: " << hedera_precheck_code_string
|
||||
<< ", cost: " << cost
|
||||
<< ", type: " << TransactionBody::transactionTypeToString(mTransactionBody->getType())
|
||||
<< std::endl;
|
||||
/*printf("hedera response: %s, cost: %" PRIu64 ", type: %s\n",
|
||||
hedera_precheck_code_string.data(), cost,
|
||||
TransactionBody::transactionTypeToString(mTransactionBody->getType()));*/
|
||||
if (precheck_code == proto::INVALID_TRANSACTION_START) {
|
||||
int zahl = 0;
|
||||
return -5;
|
||||
}
|
||||
else if (precheck_code == proto::OK) {
|
||||
// simply assume if transaction was sended to hedera without error, it was also accepted from gradido node
|
||||
// TODO: later check, but now I haven't any way to communicate with the gradido node
|
||||
mTransactionBody->getTransactionBase()->transactionAccepted(getUser());
|
||||
auto transaction_model = getModel();
|
||||
transaction_model->setFinished(Poco::DateTime());
|
||||
Poco::JSON::Object::Ptr result = new Poco::JSON::Object;
|
||||
model::hedera::TransactionId transaction_id(hedera_task->getTransactionId());
|
||||
result->set("state", "success");
|
||||
result->set("transactionId", transaction_id.convertToJSON());
|
||||
|
||||
transaction_model->setResultJson(result);
|
||||
Profiler timer;
|
||||
transaction_model->updateFinishedAndResult();
|
||||
printf("time for update 2 fields in db: %s\n", timer.string().data());
|
||||
|
||||
// trigger community server update in 5 seconds
|
||||
CronManager::getInstance()->scheduleUpdateRun(Poco::Timespan(5, 0));
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
//model::hedera::TransactionBody hedera_transaction_body()
|
||||
}
|
||||
else
|
||||
{
|
||||
addError(new ParamError(function_name, "hedera crypto key not found for paying for consensus submit message! NetworkType: ", network_type));
|
||||
//sendErrorsAsEmail();
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addError(new Error(function_name, "hedera topic id or operator account not found!"));
|
||||
addError(new ParamError(function_name, "topic id: ", topic_id->getModel()->toString()));
|
||||
addError(new ParamError(function_name, "network type: ", network_type));
|
||||
//sendErrorsAsEmail();
|
||||
return -4;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
int Transaction::runSendTransactionMysql()
|
||||
{
|
||||
static const char* function_name = "Transaction::runSendTransactionMysql";
|
||||
|
||||
@ -86,14 +86,11 @@ namespace model {
|
||||
std::string getTransactionAsJson(bool replaceBase64WithHex = false);
|
||||
inline Poco::AutoPtr<Transaction> getPairedTransaction() { return mPairedTransaction; }
|
||||
|
||||
bool setTopicIdByGroup(const std::string& alias);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool ifEnoughSignsProceed(Poco::AutoPtr<controller::User> user);
|
||||
|
||||
int runSendTransactionHedera();
|
||||
int runSendTransactionMysql();
|
||||
|
||||
Poco::AutoPtr<Transaction> mPairedTransaction;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#include "TransactionTransfer.h"
|
||||
#include "Transaction.h"
|
||||
#include "../../SingletonManager/ErrorManager.h"
|
||||
#include "../../controller/HederaId.h"
|
||||
|
||||
namespace model {
|
||||
namespace gradido {
|
||||
@ -68,7 +67,7 @@ namespace model {
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
const static char functionName[] = { "TransactionTransfer::prepare" };
|
||||
|
||||
mKontoTable.reserve(2);
|
||||
mKontoTable.reserve(2);
|
||||
|
||||
proto::gradido::TransferAmount* sender = nullptr;
|
||||
std::string* receiver_pubkey = nullptr;
|
||||
@ -83,7 +82,7 @@ namespace model {
|
||||
sender = inbound_transfer.mutable_sender();
|
||||
receiver_pubkey = inbound_transfer.mutable_receiver();
|
||||
return prepare(sender, receiver_pubkey);
|
||||
}
|
||||
}
|
||||
else if (mProtoTransfer.has_outbound()) {
|
||||
auto outbound_transfer = mProtoTransfer.outbound();
|
||||
sender = outbound_transfer.mutable_sender();
|
||||
@ -156,7 +155,7 @@ namespace model {
|
||||
receiver_pubkey = outbound_transfer.mutable_receiver();
|
||||
return validate(sender, receiver_pubkey);
|
||||
}
|
||||
|
||||
|
||||
return TRANSACTION_VALID_CODE_ERROR;
|
||||
}
|
||||
|
||||
@ -234,12 +233,11 @@ namespace model {
|
||||
);
|
||||
|
||||
auto transaction = Poco::AutoPtr<Transaction>(new Transaction(body));
|
||||
transaction->setTopicIdByGroup(mOwnGroupAlias);
|
||||
|
||||
mm->releaseMemory(receiver_pubkey);
|
||||
mm->releaseMemory(sender_pubkey);
|
||||
return transaction;
|
||||
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<Transaction> TransactionTransfer::createInbound(const std::string& memo)
|
||||
@ -253,12 +251,12 @@ namespace model {
|
||||
// Poco::AutoPtr<controller::User> sender, const MemoryBin* receiverPubkey, Poco::AutoPtr<controller::Group> 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,
|
||||
@ -266,8 +264,7 @@ namespace model {
|
||||
);
|
||||
|
||||
auto transaction = Poco::AutoPtr<Transaction>(new Transaction(body));
|
||||
transaction->setTopicIdByGroup(mTargetGroupAlias);
|
||||
|
||||
|
||||
mm->releaseMemory(receiver_pubkey);
|
||||
mm->releaseMemory(sender_pubkey);
|
||||
return transaction;
|
||||
@ -276,7 +273,7 @@ namespace model {
|
||||
const std::string& TransactionTransfer::getKontoNameCell(int index)
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
|
||||
if (index >= mKontoTable.size()) {
|
||||
return mInvalidIndexMessage;
|
||||
}
|
||||
@ -299,7 +296,7 @@ namespace model {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
|
||||
|
||||
#include "ConsensusCreateTopic.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
ConsensusCreateTopic::ConsensusCreateTopic(Poco::AutoPtr<controller::HederaId> autoRenewHederaAccountId, Poco::UInt32 autoRenewPeriod)
|
||||
: mProtoCreateTopic(nullptr)
|
||||
{
|
||||
mProtoCreateTopic = new proto::ConsensusCreateTopicTransactionBody;
|
||||
auto auto_renew_period = mProtoCreateTopic->mutable_autorenewperiod();
|
||||
auto_renew_period->set_seconds(autoRenewPeriod);
|
||||
|
||||
if (!autoRenewHederaAccountId.isNull()) {
|
||||
auto auto_renew_account = mProtoCreateTopic->mutable_autorenewaccount();
|
||||
autoRenewHederaAccountId->copyToProtoAccountId(auto_renew_account);
|
||||
}
|
||||
|
||||
}
|
||||
ConsensusCreateTopic::~ConsensusCreateTopic()
|
||||
{
|
||||
if (mProtoCreateTopic) {
|
||||
delete mProtoCreateTopic;
|
||||
mProtoCreateTopic = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ConsensusCreateTopic::setAdminKey(const MemoryBin* adminPublicKey)
|
||||
{
|
||||
auto admin_key = mProtoCreateTopic->mutable_adminkey();
|
||||
auto admin_key_string = admin_key->mutable_ed25519();
|
||||
*admin_key_string = std::string((const char)*adminPublicKey, adminPublicKey->size());
|
||||
}
|
||||
void ConsensusCreateTopic::setSubmitKey(const MemoryBin* submitPublicKey)
|
||||
{
|
||||
auto submit_key = mProtoCreateTopic->mutable_submitkey();
|
||||
auto submit_key_string = submit_key->mutable_ed25519();
|
||||
*submit_key_string = std::string((const char)*submitPublicKey, submitPublicKey->size());
|
||||
}
|
||||
|
||||
bool ConsensusCreateTopic::validate()
|
||||
{
|
||||
|
||||
if (mProtoCreateTopic->autorenewperiod().seconds() == 7890000) {// && 0 != mProtoCreateTopic->autorenewaccount().accountnum()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H
|
||||
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H
|
||||
|
||||
|
||||
#include "../../SingletonManager/MemoryManager.h"
|
||||
#include "../../controller/HederaId.h"
|
||||
#include "proto/hedera/ConsensusCreateTopic.pb.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class ConsensusCreateTopic
|
||||
{
|
||||
public:
|
||||
ConsensusCreateTopic(Poco::AutoPtr<controller::HederaId> autoRenewHederaAccountId, Poco::UInt32 autoRenewPeriod);
|
||||
~ConsensusCreateTopic();
|
||||
|
||||
inline void setMemo(const std::string& memo) { mProtoCreateTopic->set_memo(memo); }
|
||||
void setAdminKey(const MemoryBin* adminPublicKey);
|
||||
void setSubmitKey(const MemoryBin* submitPublicKey);
|
||||
|
||||
bool validate();
|
||||
|
||||
inline proto::ConsensusCreateTopicTransactionBody* getProtoTransactionBody() { return mProtoCreateTopic; }
|
||||
inline void resetPointer() { mProtoCreateTopic = nullptr; }
|
||||
protected:
|
||||
proto::ConsensusCreateTopicTransactionBody* mProtoCreateTopic;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_CREATE_TOPIC_H
|
||||
@ -1,42 +0,0 @@
|
||||
#include "ConsensusSubmitMessage.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
ConsensusSubmitMessage::ConsensusSubmitMessage(Poco::AutoPtr<controller::HederaId> topicID)
|
||||
: mConsensusMessageBody(nullptr)
|
||||
{
|
||||
mConsensusMessageBody = new proto::ConsensusSubmitMessageTransactionBody;
|
||||
topicID->copyToProtoTopicId(mConsensusMessageBody->mutable_topicid());
|
||||
}
|
||||
|
||||
ConsensusSubmitMessage::~ConsensusSubmitMessage()
|
||||
{
|
||||
if (mConsensusMessageBody) {
|
||||
delete mConsensusMessageBody;
|
||||
mConsensusMessageBody = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool ConsensusSubmitMessage::validate()
|
||||
{
|
||||
// TODO: unpack gradido transaction and make simple validation check
|
||||
assert(mConsensusMessageBody);
|
||||
if (0 == mConsensusMessageBody->message().size()) {
|
||||
printf("[ConsensusSubmitMessage::validate] empty message\n");
|
||||
return false;
|
||||
}
|
||||
if (!mConsensusMessageBody->has_topicid()) {
|
||||
printf("[ConsensusSubmitMessage::validate] empty topic id\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConsensusSubmitMessage::setMessage(std::string byteString)
|
||||
{
|
||||
assert(mConsensusMessageBody);
|
||||
mConsensusMessageBody->set_message(byteString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_SUBMIT_MESSAGE_H
|
||||
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_SUBMIT_MESSAGE_H
|
||||
|
||||
#include "proto/hedera/ConsensusSubmitMessage.pb.h"
|
||||
#include "../../controller/HederaId.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
class ConsensusSubmitMessage
|
||||
{
|
||||
public:
|
||||
ConsensusSubmitMessage(Poco::AutoPtr<controller::HederaId> topicID);
|
||||
~ConsensusSubmitMessage();
|
||||
|
||||
inline proto::ConsensusSubmitMessageTransactionBody* getProtoTransactionBody() { return mConsensusMessageBody; }
|
||||
inline void resetPointer() { mConsensusMessageBody = nullptr; }
|
||||
void setMessage(std::string byteString);
|
||||
inline void setMessage(const MemoryBin* message) { setMessage(std::string((const char*)message->data(), message->size())); }
|
||||
|
||||
bool validate();
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
proto::ConsensusSubmitMessageTransactionBody* mConsensusMessageBody;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_SUBMIT_MESSAGE_H
|
||||
@ -1,68 +0,0 @@
|
||||
#include "ConsensusTopicInfo.h"
|
||||
|
||||
#include <sstream>
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
ConsensusTopicInfo::ConsensusTopicInfo(const proto::ConsensusTopicInfo& consensusTopicInfo)
|
||||
: mProto(consensusTopicInfo)
|
||||
{
|
||||
}
|
||||
|
||||
ConsensusTopicInfo::~ConsensusTopicInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MemoryBin* ConsensusTopicInfo::getRunningHashCopy() const
|
||||
{
|
||||
auto mm = MemoryManager::getInstance();
|
||||
auto running_hash = mProto.runninghash();
|
||||
auto running_hash_bin = mm->getFreeMemory(running_hash.size());
|
||||
memcpy(*running_hash_bin, running_hash.data(), running_hash.size());
|
||||
return running_hash_bin;
|
||||
}
|
||||
|
||||
std::string ConsensusTopicInfo::toString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "memo: " << mProto.memo() << std::endl;
|
||||
ss << "running hash: " << DataTypeConverter::binToHex((const unsigned char*)mProto.runninghash().data(), mProto.runninghash().size()) << std::endl;
|
||||
ss << "sequence number: " << mProto.sequencenumber() << std::endl;
|
||||
Poco::DateTime expiration_time = DataTypeConverter::convertFromProtoTimestamp(mProto.expirationtime());
|
||||
|
||||
ss << "expiration time: " << Poco::DateTimeFormatter::format(expiration_time, "%f.%m.%Y %H:%M:%S") << std::endl;
|
||||
ss << "has admin key: " << mProto.has_adminkey() << std::endl;
|
||||
ss << "has submit key: " << mProto.has_submitkey() << std::endl;
|
||||
auto auto_renew_period = DataTypeConverter::convertFromProtoDuration(mProto.autorenewperiod());
|
||||
ss << "auto renew period: " << std::to_string(auto_renew_period.seconds()) << " seconds" << std::endl;
|
||||
auto acc_id = mProto.autorenewaccount();
|
||||
ss << "auto renew account: " << acc_id.shardnum() << ", " << acc_id.realmnum() << ", " << acc_id.accountnum() << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string ConsensusTopicInfo::toStringHtml()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "<ul>";
|
||||
ss << "<li>memo: " << mProto.memo() << "</li>";
|
||||
ss << "<li>running hash: " << DataTypeConverter::binToHex((const unsigned char*)mProto.runninghash().data(), mProto.runninghash().size()) << "</li>";
|
||||
ss << "<li>sequence number: " << mProto.sequencenumber() << "</li>";
|
||||
Poco::DateTime expiration_time = DataTypeConverter::convertFromProtoTimestamp(mProto.expirationtime());
|
||||
|
||||
ss << "<li>expiration time: " << Poco::DateTimeFormatter::format(expiration_time, "%f.%m.%Y %H:%M:%S") << "</li>";
|
||||
ss << "<li>has admin key: " << mProto.has_adminkey() << "</li>";
|
||||
ss << "<li>has submit key: " << mProto.has_submitkey() << "</li>";
|
||||
auto auto_renew_period = DataTypeConverter::convertFromProtoDuration(mProto.autorenewperiod());
|
||||
ss << "<li>auto renew period: " << std::to_string(mProto.autorenewperiod().seconds()) << " seconds" << "</li>";
|
||||
auto acc_id = mProto.autorenewaccount();
|
||||
ss << "<li>auto renew account: " << acc_id.shardnum() << ", " << acc_id.realmnum() << ", " << acc_id.accountnum() << "</li>";
|
||||
ss << "</ul>";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H
|
||||
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H
|
||||
|
||||
#include "../proto/hedera/ConsensusTopicInfo.pb.h"
|
||||
#include "../../SingletonManager/MemoryManager.h"
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
#include "Poco/DateTime.h"
|
||||
|
||||
namespace model
|
||||
{
|
||||
namespace hedera
|
||||
{
|
||||
class ConsensusTopicInfo
|
||||
{
|
||||
public:
|
||||
ConsensusTopicInfo(const proto::ConsensusTopicInfo& consensusTopicInfo);
|
||||
~ConsensusTopicInfo();
|
||||
|
||||
inline std::string getMemo() const { return mProto.memo(); }
|
||||
MemoryBin* getRunningHashCopy() const;
|
||||
Poco::UInt64 getSequenceNumber() const { return mProto.sequencenumber(); }
|
||||
inline Poco::DateTime getExpirationTime() const { return DataTypeConverter::convertFromProtoTimestamp(mProto.expirationtime());}
|
||||
inline proto::Duration getAutoRenewPeriod() const { return mProto.autorenewperiod(); }
|
||||
|
||||
std::string toString();
|
||||
std::string toStringHtml();
|
||||
|
||||
protected:
|
||||
proto::ConsensusTopicInfo mProto;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CONSENSUS_GET_TOPIC_INFO_RESPONSE_H
|
||||
@ -1,34 +0,0 @@
|
||||
#include "CryptoCreateTransaction.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
CryptoCreateTransaction::CryptoCreateTransaction(const unsigned char* publicKey, Poco::UInt64 initialBalance, int autoRenewPeriod)
|
||||
{
|
||||
mCryptoCreateBody = new proto::CryptoCreateTransactionBody;
|
||||
// public key
|
||||
auto key = mCryptoCreateBody->mutable_key();
|
||||
auto public_key = new std::string((const char*)publicKey, KeyPairHedera::getPublicKeySize());
|
||||
key->set_allocated_ed25519(public_key);
|
||||
|
||||
mCryptoCreateBody->set_initialbalance(initialBalance);
|
||||
|
||||
auto auto_renew_period = mCryptoCreateBody->mutable_autorenewperiod();
|
||||
auto_renew_period->set_seconds(autoRenewPeriod);
|
||||
|
||||
}
|
||||
|
||||
CryptoCreateTransaction::~CryptoCreateTransaction()
|
||||
{
|
||||
if (mCryptoCreateBody) {
|
||||
delete mCryptoCreateBody;
|
||||
mCryptoCreateBody = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool CryptoCreateTransaction::validate()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H
|
||||
#define __GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H
|
||||
|
||||
#include "proto/hedera/CryptoCreate.pb.h"
|
||||
|
||||
#include "../../Crypto/KeyPairHedera.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
class CryptoCreateTransaction
|
||||
{
|
||||
public:
|
||||
//! \param publicKey newly created public key from ed25519 public-private key pair for hedera
|
||||
CryptoCreateTransaction(const unsigned char* publicKey, Poco::UInt64 initialBalance, int autoRenewPeriod);
|
||||
~CryptoCreateTransaction();
|
||||
|
||||
proto::CryptoCreateTransactionBody* getProtoTransactionBody() { return mCryptoCreateBody; }
|
||||
inline void resetPointer() { mCryptoCreateBody = nullptr; }
|
||||
|
||||
bool validate();
|
||||
|
||||
protected:
|
||||
proto::CryptoCreateTransactionBody* mCryptoCreateBody;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //__GRADIDO_LOGIN_MODEL_HEDERA_CRYPTO_CREATE_TRANSACTION_H
|
||||
@ -1,48 +0,0 @@
|
||||
#include "CryptoTransferTransaction.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
CryptoTransferTransaction::CryptoTransferTransaction()
|
||||
: mCryptoTransfer(nullptr)
|
||||
{
|
||||
mCryptoTransfer = new proto::CryptoTransferTransactionBody;
|
||||
}
|
||||
|
||||
CryptoTransferTransaction::~CryptoTransferTransaction()
|
||||
{
|
||||
if (mCryptoTransfer) {
|
||||
delete mCryptoTransfer;
|
||||
mCryptoTransfer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CryptoTransferTransaction::addSender(Poco::AutoPtr<controller::HederaId> senderAccountId, Poco::UInt64 amountTinybars)
|
||||
{
|
||||
auto transfers = mCryptoTransfer->mutable_transfers();
|
||||
auto accountAmounts = transfers->add_accountamounts();
|
||||
accountAmounts->set_amount(-(Poco::Int64)amountTinybars);
|
||||
senderAccountId->copyToProtoAccountId(accountAmounts->mutable_accountid());
|
||||
}
|
||||
void CryptoTransferTransaction::addReceiver(Poco::AutoPtr<controller::HederaId> receiverAccountId, Poco::UInt64 amountTinybars)
|
||||
{
|
||||
auto transfers = mCryptoTransfer->mutable_transfers();
|
||||
auto accountAmounts = transfers->add_accountamounts();
|
||||
accountAmounts->set_amount(amountTinybars);
|
||||
receiverAccountId->copyToProtoAccountId(accountAmounts->mutable_accountid());
|
||||
}
|
||||
|
||||
bool CryptoTransferTransaction::validate()
|
||||
{
|
||||
auto transfers = mCryptoTransfer->mutable_transfers();
|
||||
auto account_amounts = transfers->accountamounts();
|
||||
Poco::Int64 sum = 0;
|
||||
for (int i = 0; i < transfers->accountamounts_size(); i++) {
|
||||
auto account_amount = account_amounts.Mutable(i);
|
||||
sum += account_amount->amount();
|
||||
}
|
||||
return 0 == sum && transfers->accountamounts_size() > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H
|
||||
#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H
|
||||
|
||||
/*!
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 02.09.20
|
||||
*
|
||||
* @brief: class for creating a hedera transfer transaction
|
||||
*
|
||||
*/
|
||||
|
||||
#include "proto/hedera/CryptoTransfer.pb.h"
|
||||
#include "../../controller/HederaId.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class CryptoTransferTransaction
|
||||
{
|
||||
public:
|
||||
CryptoTransferTransaction();
|
||||
~CryptoTransferTransaction();
|
||||
|
||||
void addSender(Poco::AutoPtr<controller::HederaId> senderAccountId, Poco::UInt64 amountTinybars);
|
||||
void addReceiver(Poco::AutoPtr<controller::HederaId> receiverAccountId, Poco::UInt64 amountTinybars);
|
||||
|
||||
bool validate();
|
||||
// set pointer to zero, after hand over pointer to transaction body
|
||||
inline void resetPointer() { mCryptoTransfer = nullptr; }
|
||||
|
||||
inline proto::CryptoTransferTransactionBody* getProtoTransactionBody() { return mCryptoTransfer; }
|
||||
|
||||
protected:
|
||||
proto::CryptoTransferTransactionBody* mCryptoTransfer;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_CRYPTO_TRANSFER_TRANSACTION_H
|
||||
@ -1,193 +0,0 @@
|
||||
#include "Query.h"
|
||||
#include "QueryHeader.h"
|
||||
#include "Poco/Timestamp.h"
|
||||
#include "../../SingletonManager/MemoryManager.h"
|
||||
|
||||
#include <google/protobuf/util/json_util.h>
|
||||
|
||||
#include "Transaction.h"
|
||||
#include "TransactionBody.h"
|
||||
#include "CryptoTransferTransaction.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
Query::Query()
|
||||
: mTransactionBody(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Query::~Query()
|
||||
{
|
||||
if (mTransactionBody) {
|
||||
delete mTransactionBody;
|
||||
}
|
||||
}
|
||||
|
||||
Query* Query::getBalance(Poco::AutoPtr<controller::HederaId> accountId, const controller::NodeServerConnection& connection)
|
||||
{
|
||||
|
||||
assert(!accountId.isNull() && accountId->getModel());
|
||||
|
||||
printf("[Query::getBalance] account id: %s\n", accountId->getModel()->toString().data());
|
||||
|
||||
auto query = new Query;
|
||||
auto get_account_balance = query->mQueryProto.mutable_cryptogetaccountbalance();
|
||||
accountId->copyToProtoAccountId(get_account_balance->mutable_accountid());
|
||||
auto query_header = get_account_balance->mutable_header();
|
||||
query_header->set_responsetype(proto::COST_ANSWER);
|
||||
|
||||
query->mTransactionBody = new TransactionBody(accountId, connection);
|
||||
CryptoTransferTransaction crypto_transaction;
|
||||
crypto_transaction.addSender(accountId, 0);
|
||||
crypto_transaction.addReceiver(connection.hederaId, 0);
|
||||
query->mTransactionBody->setCryptoTransfer(crypto_transaction);
|
||||
|
||||
//auto transaction = query_header->mutable_payment();
|
||||
//auto transaction_body = transaction->mutable_body();
|
||||
// body content
|
||||
// node account id
|
||||
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
Query* Query::getTopicInfo(Poco::AutoPtr<controller::HederaId> topicId, Poco::AutoPtr<controller::HederaId> payerAccountId, const controller::NodeServerConnection& connection)
|
||||
{
|
||||
assert(!topicId.isNull() && topicId->getModel());
|
||||
assert(!payerAccountId.isNull() && payerAccountId->getModel());
|
||||
|
||||
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();
|
||||
topicId->copyToProtoTopicId(get_topic_info->mutable_topicid());
|
||||
|
||||
auto query_header = get_topic_info->mutable_header();
|
||||
query_header->set_responsetype(proto::ANSWER_ONLY);
|
||||
|
||||
query->mTransactionBody = new TransactionBody(payerAccountId, connection);
|
||||
CryptoTransferTransaction crypto_transaction;
|
||||
// 0.003317 Hashbars
|
||||
// fee from https://www.hedera.com/fees
|
||||
crypto_transaction.addSender(payerAccountId, 3317);
|
||||
crypto_transaction.addReceiver(connection.hederaId, 3317);
|
||||
query->mTransactionBody->setCryptoTransfer(crypto_transaction);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
Query* Query::getTransactionGetReceiptQuery(
|
||||
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_receipt_query = query->mQueryProto.mutable_transactiongetreceipt();
|
||||
transaction_get_receipt_query->set_allocated_header(query->mQueryHeader->getProtoQueryHeader());
|
||||
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()
|
||||
{
|
||||
if (mQueryProto.has_cryptogetaccountbalance()) {
|
||||
return mQueryProto.mutable_cryptogetaccountbalance()->mutable_header();
|
||||
}
|
||||
else if (mQueryProto.has_consensusgettopicinfo()) {
|
||||
return mQueryProto.mutable_consensusgettopicinfo()->mutable_header();
|
||||
}
|
||||
else {
|
||||
return mQueryHeader->getProtoQueryHeader();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Query::sign(std::unique_ptr<KeyPairHedera> keyPairHedera)
|
||||
{
|
||||
Transaction transaction;
|
||||
mTransactionBody->updateTimestamp();
|
||||
auto sign_result = transaction.sign(std::move(keyPairHedera), mTransactionBody);
|
||||
auto query_header = getQueryHeader();
|
||||
query_header->set_allocated_payment(transaction.getTransaction());
|
||||
transaction.resetPointer();
|
||||
|
||||
return sign_result;
|
||||
}
|
||||
|
||||
void Query::setResponseType(proto::ResponseType type)
|
||||
{
|
||||
auto query_header = getQueryHeader();
|
||||
query_header->set_responsetype(type);
|
||||
}
|
||||
|
||||
proto::ResponseType Query::getResponseType()
|
||||
{
|
||||
auto query_header = getQueryHeader();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H
|
||||
#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H
|
||||
|
||||
/*!
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 31.08.20
|
||||
*
|
||||
* @brief: class for put together hedera querys (ask for state data, not a transaction, but needs a payment transaction)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "proto/hedera/Query.pb.h"
|
||||
#include "../../controller/NodeServer.h"
|
||||
#include "../../Crypto/KeyPairHedera.h"
|
||||
#include "TransactionBody.h"
|
||||
#include "QueryHeader.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class Query
|
||||
{
|
||||
public:
|
||||
~Query();
|
||||
static Query* getBalance(Poco::AutoPtr<controller::HederaId> accountId, const controller::NodeServerConnection& connection);
|
||||
static Query* getTopicInfo(Poco::AutoPtr<controller::HederaId> topicId, Poco::AutoPtr<controller::HederaId> payerAccountId, const controller::NodeServerConnection& connection);
|
||||
static Query* getTransactionGetReceiptQuery(
|
||||
const proto::TransactionID& transactionId,
|
||||
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);
|
||||
proto::ResponseType getResponseType();
|
||||
inline bool setTransactionFee(Poco::UInt64 fee) { return mTransactionBody->updateCryptoTransferAmount(fee);}
|
||||
|
||||
inline const proto::Query* getProtoQuery() const { return &mQueryProto; }
|
||||
std::string getConnectionString() const;
|
||||
|
||||
proto::QueryHeader* getQueryHeader();
|
||||
|
||||
std::string toJsonString() const;
|
||||
|
||||
protected:
|
||||
Query();
|
||||
proto::Query mQueryProto;
|
||||
Poco::AutoPtr<QueryHeader> mQueryHeader;
|
||||
TransactionBody* mTransactionBody;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_H
|
||||
@ -1,43 +0,0 @@
|
||||
#include "QueryHeader.h"
|
||||
|
||||
#include "Transaction.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
QueryHeader::QueryHeader()
|
||||
{
|
||||
mProtoQueryHeader.set_responsetype(proto::ANSWER_ONLY);
|
||||
}
|
||||
|
||||
QueryHeader::~QueryHeader()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::AutoPtr<QueryHeader> QueryHeader::createWithPaymentTransaction(
|
||||
Poco::AutoPtr<controller::HederaAccount> operatorAccount,
|
||||
const controller::NodeServerConnection& connection,
|
||||
Poco::UInt32 cost
|
||||
) {
|
||||
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->mutable_payment();
|
||||
|
||||
query_header->mConnectionString = connection.getUriWithPort();
|
||||
|
||||
Transaction transactionObj(payment_transaction);
|
||||
TransactionBody body(operatorAccount->getHederaId(), connection);
|
||||
CryptoTransferTransaction transfer_transaction;
|
||||
transfer_transaction.addSender(operatorAccount->getHederaId(), cost);
|
||||
transfer_transaction.addReceiver(connection.hederaId, cost);
|
||||
body.setCryptoTransfer(transfer_transaction);
|
||||
transactionObj.sign(operatorAccount->getCryptoKey()->getKeyPair(), &body);
|
||||
transactionObj.resetPointer();
|
||||
|
||||
return query_header;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H
|
||||
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H
|
||||
|
||||
#include "../proto/hedera/QueryHeader.pb.h"
|
||||
#include "Transaction.h"
|
||||
|
||||
#include "../../controller/User.h"
|
||||
#include "../../controller/HederaAccount.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class QueryHeader : public Poco::RefCountedObject
|
||||
{
|
||||
public:
|
||||
~QueryHeader();
|
||||
|
||||
//! for cost look here: https://www.hedera.com/fees
|
||||
//! or make query first with response type COST_ANSWER
|
||||
//! TODO: get cost from network
|
||||
static Poco::AutoPtr<QueryHeader> createWithPaymentTransaction(
|
||||
Poco::AutoPtr<controller::HederaAccount> operatorAccount,
|
||||
const controller::NodeServerConnection& connection,
|
||||
Poco::UInt32 cost
|
||||
);
|
||||
|
||||
void setResponseType(proto::ResponseType type) { mProtoQueryHeader.set_responsetype(type); };
|
||||
proto::ResponseType getResponseType() const { return mProtoQueryHeader.responsetype(); }
|
||||
|
||||
proto::QueryHeader* getProtoQueryHeader() { return &mProtoQueryHeader; }
|
||||
|
||||
const std::string& getConnectionString() const { return mConnectionString; }
|
||||
|
||||
protected:
|
||||
proto::QueryHeader mProtoQueryHeader;
|
||||
std::string mConnectionString;
|
||||
QueryHeader();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_QUERY_HEADER_H
|
||||
@ -1,78 +0,0 @@
|
||||
#include "Response.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
Response::Response()
|
||||
{
|
||||
}
|
||||
|
||||
Response::~Response()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::UInt64 Response::getAccountBalance()
|
||||
{
|
||||
if (isCryptoGetAccountBalanceResponse()) {
|
||||
auto balance_response = mResponseProto.cryptogetaccountbalance();
|
||||
return balance_response.balance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<ConsensusTopicInfo> Response::getConsensusTopicInfo()
|
||||
{
|
||||
if (mResponseProto.has_consensusgettopicinfo()) {
|
||||
return std::make_unique<ConsensusTopicInfo>(mResponseProto.consensusgettopicinfo().topicinfo());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TransactionReceipt* Response::getTransactionReceipt()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
Poco::UInt64 Response::getQueryCost()
|
||||
{
|
||||
proto::ResponseHeader* response_header = nullptr;
|
||||
if (mResponseProto.has_consensusgettopicinfo()) {
|
||||
response_header = mResponseProto.mutable_consensusgettopicinfo()->mutable_header();
|
||||
}
|
||||
else if (mResponseProto.has_cryptogetaccountbalance()) {
|
||||
response_header = mResponseProto.mutable_cryptogetaccountbalance()->mutable_header();
|
||||
}
|
||||
if (response_header) {
|
||||
return response_header->cost();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
proto::ResponseCodeEnum Response::getResponseCode()
|
||||
{
|
||||
if (isCryptoGetAccountBalanceResponse()) {
|
||||
auto balance_response = mResponseProto.cryptogetaccountbalance();
|
||||
return balance_response.header().nodetransactionprecheckcode();
|
||||
}
|
||||
else if (mResponseProto.has_consensusgettopicinfo()) {
|
||||
auto response = mResponseProto.consensusgettopicinfo();
|
||||
return response.header().nodetransactionprecheckcode();
|
||||
}
|
||||
return proto::NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H
|
||||
#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H
|
||||
|
||||
/*!
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 03.09.20
|
||||
*
|
||||
* @brief: class for simply accessing hedera responses
|
||||
*
|
||||
*/
|
||||
|
||||
#include "proto/hedera/Response.pb.h"
|
||||
#include "ConsensusTopicInfo.h"
|
||||
#include "TransactionReceipt.h"
|
||||
#include "TransactionRecord.h"
|
||||
#include "Poco/Types.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class Response
|
||||
{
|
||||
public:
|
||||
Response();
|
||||
~Response();
|
||||
|
||||
inline proto::Response* getResponsePtr() { return &mResponseProto; }
|
||||
Poco::UInt64 getAccountBalance();
|
||||
std::unique_ptr<ConsensusTopicInfo> getConsensusTopicInfo();
|
||||
TransactionReceipt* getTransactionReceipt();
|
||||
TransactionRecord* getTransactionRecord();
|
||||
Poco::UInt64 getQueryCost();
|
||||
proto::ResponseCodeEnum getResponseCode();
|
||||
|
||||
|
||||
inline bool isCryptoGetAccountBalanceResponse() { return mResponseProto.has_cryptogetaccountbalance(); }
|
||||
inline bool isConsensusGetTopicInfoResponse() { return mResponseProto.has_consensusgettopicinfo(); }
|
||||
|
||||
protected:
|
||||
proto::Response mResponseProto;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_RESPONSE_H
|
||||
@ -1,81 +0,0 @@
|
||||
#include "Transaction.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
Transaction::Transaction()
|
||||
: mTransaction(nullptr)
|
||||
{
|
||||
mTransaction = new proto::Transaction;
|
||||
}
|
||||
Transaction::Transaction(proto::Transaction* transaction)
|
||||
: mTransaction(transaction)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Transaction::~Transaction()
|
||||
{
|
||||
if (mTransaction) {
|
||||
delete mTransaction;
|
||||
mTransaction = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Transaction::sign(std::unique_ptr<KeyPairHedera> keyPairHedera, const TransactionBody* transactionBody)
|
||||
{
|
||||
mType = transactionBody->getType();
|
||||
|
||||
auto mm = MemoryManager::getInstance();
|
||||
mConnection = transactionBody->getConnection();
|
||||
auto transaction_body_proto = transactionBody->getProtoTransactionBody();
|
||||
auto body_bytes = transaction_body_proto->SerializeAsString();
|
||||
mTransaction->set_bodybytes(body_bytes.data());
|
||||
auto signature_map = mTransaction->mutable_sigmap();
|
||||
auto signature_pairs = signature_map->mutable_sigpair();
|
||||
signature_map->add_sigpair();
|
||||
auto signature_pair = signature_pairs->Mutable(0);
|
||||
auto public_key = keyPairHedera->getPublicKey();
|
||||
|
||||
auto sign = keyPairHedera->sign(body_bytes);
|
||||
if (!sign) {
|
||||
printf("[Query::sign] error signing message\n");
|
||||
return false;
|
||||
}
|
||||
signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize());
|
||||
signature_pair->set_ed25519(*sign, sign->size());
|
||||
|
||||
mm->releaseMemory(sign);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Transaction::sign(std::unique_ptr<KeyPairHedera> keyPairHedera, std::unique_ptr<TransactionBody> transactionBody)
|
||||
{
|
||||
mType = transactionBody->getType();
|
||||
|
||||
auto mm = MemoryManager::getInstance();
|
||||
mConnection = transactionBody->getConnection();
|
||||
transactionBody->updateTimestamp();
|
||||
auto transaction_body_proto = transactionBody->getProtoTransactionBody();
|
||||
auto body_bytes = transaction_body_proto->SerializeAsString();
|
||||
mTransaction->set_bodybytes(body_bytes.data(), body_bytes.size());
|
||||
auto signature_map = mTransaction->mutable_sigmap();
|
||||
auto signature_pairs = signature_map->mutable_sigpair();
|
||||
signature_map->add_sigpair();
|
||||
auto signature_pair = signature_pairs->Mutable(0);
|
||||
auto public_key = keyPairHedera->getPublicKey();
|
||||
|
||||
mTransactionId = transactionBody->getProtoTransactionBody()->transactionid();
|
||||
|
||||
auto sign = keyPairHedera->sign(body_bytes);
|
||||
if (!sign) {
|
||||
printf("[Query::sign] error signing message\n");
|
||||
return false;
|
||||
}
|
||||
signature_pair->set_pubkeyprefix(public_key, keyPairHedera->getPublicKeySize());
|
||||
signature_pair->set_ed25519(*sign, sign->size());
|
||||
|
||||
mm->releaseMemory(sign);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H
|
||||
#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H
|
||||
|
||||
/*!
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 02.09.20
|
||||
*
|
||||
* @brief: class for composing hedera transaction
|
||||
*
|
||||
*/
|
||||
|
||||
#include "proto/hedera/Transaction.pb.h"
|
||||
#include "../../Crypto/KeyPairHedera.h"
|
||||
#include "TransactionBody.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class Transaction
|
||||
{
|
||||
public:
|
||||
Transaction();
|
||||
Transaction(proto::Transaction* transaction);
|
||||
~Transaction();
|
||||
|
||||
bool sign(std::unique_ptr<KeyPairHedera> keyPairHedera, const TransactionBody* transactionBody);
|
||||
bool sign(std::unique_ptr<KeyPairHedera> keyPairHedera, std::unique_ptr<TransactionBody> transactionBody);
|
||||
|
||||
inline proto::Transaction* getTransaction() { return mTransaction; }
|
||||
inline std::string getConnectionString() const { return mConnection.getUriWithPort(); }
|
||||
const controller::NodeServerConnection& getConnection() const { return mConnection; }
|
||||
void resetPointer() { mTransaction = nullptr; }
|
||||
inline TransactionBodyType getType() const { return mType; }
|
||||
inline proto::TransactionID getTransactionId() const { return mTransactionId; }
|
||||
|
||||
protected:
|
||||
proto::Transaction* mTransaction;
|
||||
controller::NodeServerConnection mConnection;
|
||||
TransactionBodyType mType;
|
||||
proto::TransactionID mTransactionId;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_H
|
||||
@ -1,153 +0,0 @@
|
||||
#include "TransactionBody.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionBody::TransactionBody(Poco::AutoPtr<controller::HederaId> operatorAccountId, const controller::NodeServerConnection& connection)
|
||||
: mConnection(connection), mHasBody(false)
|
||||
{
|
||||
connection.hederaId->copyToProtoAccountId(mTransactionBody.mutable_nodeaccountid());
|
||||
auto transaction_id = mTransactionBody.mutable_transactionid();
|
||||
operatorAccountId->copyToProtoAccountId(transaction_id->mutable_accountid());
|
||||
mTransactionBody.set_transactionfee(10000000);
|
||||
auto transaction_valid_duration = mTransactionBody.mutable_transactionvalidduration();
|
||||
transaction_valid_duration->set_seconds(120);
|
||||
|
||||
updateTimestamp();
|
||||
}
|
||||
|
||||
TransactionBody::~TransactionBody()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool TransactionBody::setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction)
|
||||
{
|
||||
if (mHasBody) {
|
||||
printf("[TransactionBody::setCryptoTransfer] has already a body\n");
|
||||
return false;
|
||||
}
|
||||
if (cryptoTransferTransaction.validate()) {
|
||||
mTransactionBody.set_allocated_cryptotransfer(cryptoTransferTransaction.getProtoTransactionBody());
|
||||
cryptoTransferTransaction.resetPointer();
|
||||
mHasBody = true;
|
||||
mType = TRANSACTION_CRYPTO_TRANSFER;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TransactionBody::updateCryptoTransferAmount(Poco::UInt64 newAmount)
|
||||
{
|
||||
assert(mHasBody);
|
||||
|
||||
if (!mTransactionBody.has_cryptotransfer()) {
|
||||
printf("[TransactionBody::updateCryptoTransferAmount] hasn't crypto transfer\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto crypto_transfer = mTransactionBody.mutable_cryptotransfer();
|
||||
auto transfers = crypto_transfer->mutable_transfers();
|
||||
if (transfers->accountamounts_size() != 2) {
|
||||
printf("[TransactionBody::updateCryptoTransferAmount] structure not like expected, transfers has %d accountamounts\n", transfers->accountamounts_size());
|
||||
return false;
|
||||
}
|
||||
proto::AccountAmount* account_amounts[] = { transfers->mutable_accountamounts(0), transfers->mutable_accountamounts(1) };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (account_amounts[i]->amount() > 0) {
|
||||
account_amounts[i]->set_amount(newAmount);
|
||||
}
|
||||
else if (account_amounts[i]->amount() < 0) {
|
||||
account_amounts[i]->set_amount(-newAmount);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool TransactionBody::setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction)
|
||||
{
|
||||
if (mHasBody) {
|
||||
printf("[TransactionBody::setCreateTopic] has already a body\n");
|
||||
return false;
|
||||
}
|
||||
if (consensusCreateTopicTransaction.validate()) {
|
||||
mTransactionBody.set_allocated_consensuscreatetopic(consensusCreateTopicTransaction.getProtoTransactionBody());
|
||||
consensusCreateTopicTransaction.resetPointer();
|
||||
mHasBody = true;
|
||||
mType = TRANSACTION_CONSENSUS_CREATE_TOPIC;
|
||||
mTransactionBody.set_transactionfee(1000000000);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TransactionBody::setCryptoCreate(CryptoCreateTransaction& cryptoCreateTransaction)
|
||||
{
|
||||
if (mHasBody) {
|
||||
printf("[TransactionBody::setCryptoCreate] has already a body\n");
|
||||
return false;
|
||||
}
|
||||
if (cryptoCreateTransaction.validate()) {
|
||||
mTransactionBody.set_allocated_cryptocreateaccount(cryptoCreateTransaction.getProtoTransactionBody());
|
||||
cryptoCreateTransaction.resetPointer();
|
||||
mHasBody = true;
|
||||
mType = TRANSACTION_CRYPTO_CREATE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TransactionBody::setConsensusSubmitMessage(ConsensusSubmitMessage& consensusSubmitMessageTransaction)
|
||||
{
|
||||
if (mHasBody) {
|
||||
printf("[TransactionBody::setConsensusSubmitMessage] has already a body\n");
|
||||
return false;
|
||||
}
|
||||
if (consensusSubmitMessageTransaction.validate()) {
|
||||
mTransactionBody.set_allocated_consensussubmitmessage(consensusSubmitMessageTransaction.getProtoTransactionBody());
|
||||
consensusSubmitMessageTransaction.resetPointer();
|
||||
mHasBody = true;
|
||||
mType = TRANSACTION_CONSENSUS_SUBMIT_MESSAGE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* TransactionBody::TransactionBodyTypeToString(TransactionBodyType type)
|
||||
{
|
||||
switch (type) {
|
||||
case TRANSACTION_CONSENSUS_CREATE_TOPIC: return "Consensus Create Topic";
|
||||
case TRANSACTION_CONSENSUS_SUBMIT_MESSAGE: return "Consensus Submit Message";
|
||||
case TRANSACTION_CRYPTO_CREATE: return "Crypto Create";
|
||||
case TRANSACTION_CRYPTO_TRANSFER: return "Crypto Transfer";
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
void TransactionBody::setMemo(const std::string& memo)
|
||||
{
|
||||
mTransactionBody.set_memo(memo);
|
||||
}
|
||||
void TransactionBody::setFee(Poco::UInt64 fee)
|
||||
{
|
||||
mTransactionBody.set_transactionfee(fee);
|
||||
}
|
||||
|
||||
void TransactionBody::updateTimestamp()
|
||||
{
|
||||
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
|
||||
// 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);
|
||||
// printf("hedera transaction body timestamp: %d.%d\n", timestamp->seconds(), timestamp->nanos());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,67 +0,0 @@
|
||||
#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H
|
||||
#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H
|
||||
|
||||
/*!
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 02.09.20
|
||||
*
|
||||
* @brief: class for composing transaction body for hedera transaction
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "../../controller/NodeServer.h"
|
||||
#include "CryptoTransferTransaction.h"
|
||||
#include "CryptoCreateTransaction.h"
|
||||
#include "ConsensusCreateTopic.h"
|
||||
#include "ConsensusSubmitMessage.h"
|
||||
|
||||
#include "proto/hedera/TransactionBody.pb.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
enum TransactionBodyType
|
||||
{
|
||||
TRANSACTION_CRYPTO_TRANSFER,
|
||||
TRANSACTION_CRYPTO_CREATE,
|
||||
TRANSACTION_CONSENSUS_CREATE_TOPIC,
|
||||
TRANSACTION_CONSENSUS_SUBMIT_MESSAGE
|
||||
};
|
||||
|
||||
class TransactionBody
|
||||
{
|
||||
public:
|
||||
TransactionBody(Poco::AutoPtr<controller::HederaId> operatorAccountId, const controller::NodeServerConnection& connection);
|
||||
~TransactionBody();
|
||||
|
||||
void setMemo(const std::string& memo);
|
||||
void setFee(Poco::UInt64 fee);
|
||||
|
||||
bool setCryptoTransfer(CryptoTransferTransaction& cryptoTransferTransaction);
|
||||
bool updateCryptoTransferAmount(Poco::UInt64 newAmount);
|
||||
bool setCryptoCreate(CryptoCreateTransaction& cryptoCreateTransaction);
|
||||
bool setCreateTopic(ConsensusCreateTopic& consensusCreateTopicTransaction);
|
||||
bool setConsensusSubmitMessage(ConsensusSubmitMessage& consensusSubmitMessageTransaction);
|
||||
//bool
|
||||
|
||||
inline const proto::TransactionBody* getProtoTransactionBody() const { return &mTransactionBody; }
|
||||
inline std::string getConnectionString() const { return mConnection.getUriWithPort(); }
|
||||
inline controller::NodeServerConnection getConnection() const { return mConnection; }
|
||||
inline TransactionBodyType getType() const { return mType; }
|
||||
static const char* TransactionBodyTypeToString(TransactionBodyType type);
|
||||
|
||||
void updateTimestamp();
|
||||
protected:
|
||||
|
||||
proto::TransactionBody mTransactionBody;
|
||||
controller::NodeServerConnection mConnection;
|
||||
bool mHasBody;
|
||||
TransactionBodyType mType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_BODY_H
|
||||
@ -1,15 +0,0 @@
|
||||
#include "TransactionGetReceipt.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionGetReceipt::TransactionGetReceipt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionGetReceipt::~TransactionGetReceipt()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_H
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_H
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class TransactionGetReceipt
|
||||
{
|
||||
public:
|
||||
TransactionGetReceipt();
|
||||
~TransactionGetReceipt();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_H
|
||||
@ -1,18 +0,0 @@
|
||||
#include "TransactionGetReceiptQuery.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionGetReceiptQuery::TransactionGetReceiptQuery(Poco::AutoPtr<QueryHeader> queryHeader, const Transaction* target)
|
||||
: mQueryHeader(queryHeader)
|
||||
{
|
||||
mProtoReceiptQuery.set_allocated_header(queryHeader->getProtoQueryHeader());
|
||||
auto transaction_id = mProtoReceiptQuery.transactionid();
|
||||
transaction_id = target->getTransactionId();
|
||||
}
|
||||
|
||||
TransactionGetReceiptQuery::~TransactionGetReceiptQuery()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_QUERY_H
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_QUERY_H
|
||||
|
||||
#include "QueryHeader.h"
|
||||
#include "proto/hedera/TransactionGetReceipt.pb.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class TransactionGetReceiptQuery
|
||||
{
|
||||
public:
|
||||
TransactionGetReceiptQuery(Poco::AutoPtr<QueryHeader> queryHeader, const Transaction* target);
|
||||
~TransactionGetReceiptQuery();
|
||||
|
||||
proto::TransactionGetReceiptQuery* getProto() { return &mProtoReceiptQuery; }
|
||||
|
||||
const std::string& getConnectionString() const { return mQueryHeader->getConnectionString(); }
|
||||
|
||||
protected:
|
||||
Poco::AutoPtr<QueryHeader> mQueryHeader;
|
||||
proto::TransactionGetReceiptQuery mProtoReceiptQuery;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_QUERY_H
|
||||
@ -1,47 +0,0 @@
|
||||
#include "TransactionId.h"
|
||||
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionId::TransactionId()
|
||||
: shard(0), realm(0), num(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionId::TransactionId(const proto::TransactionID& transaction)
|
||||
{
|
||||
auto account_id = transaction.accountid();
|
||||
shard = account_id.shardnum();
|
||||
realm = account_id.realmnum();
|
||||
num = account_id.accountnum();
|
||||
mTransactionValidStart = DataTypeConverter::convertFromProtoTimestamp(transaction.transactionvalidstart());
|
||||
|
||||
}
|
||||
|
||||
TransactionId::TransactionId(int shard, int realm, int num, Poco::Timestamp transactionValidStart)
|
||||
: shard(shard), realm(realm), num(num), mTransactionValidStart(transactionValidStart)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionId::~TransactionId()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Poco::JSON::Object::Ptr TransactionId::convertToJSON()
|
||||
{
|
||||
Poco::JSON::Object::Ptr result = new Poco::JSON::Object;
|
||||
result->set("transactionValidStart", mTransactionValidStart);
|
||||
Poco::JSON::Object accountId;
|
||||
accountId.set("shard", shard);
|
||||
accountId.set("realm", realm);
|
||||
accountId.set("num", num);
|
||||
result->set("accountId", accountId);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
#ifndef _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_ID_H
|
||||
#define _GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_ID_H
|
||||
|
||||
/*!
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 02.09.20
|
||||
*
|
||||
* @brief: class for composing hedera transaction
|
||||
*
|
||||
*/
|
||||
|
||||
#include "proto/hedera/BasicTypes.pb.h"
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class TransactionId
|
||||
{
|
||||
public:
|
||||
TransactionId();
|
||||
TransactionId(const proto::TransactionID& transaction);
|
||||
TransactionId(int shard, int realm, int num, Poco::Timestamp transactionValidStart);
|
||||
~TransactionId();
|
||||
|
||||
Poco::JSON::Object::Ptr convertToJSON();
|
||||
|
||||
protected:
|
||||
Poco::Timestamp mTransactionValidStart;
|
||||
union {
|
||||
struct {
|
||||
int shard;
|
||||
int realm;
|
||||
int num;
|
||||
};
|
||||
int val[3];
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //_GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_ID_H
|
||||
@ -1,25 +0,0 @@
|
||||
#include "TransactionReceipt.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
TransactionReceipt::TransactionReceipt(const proto::TransactionReceipt& protoReceipt)
|
||||
: mProtoReceipt(protoReceipt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionReceipt::~TransactionReceipt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MemoryBin* TransactionReceipt::getRunningHash()
|
||||
{
|
||||
auto hash = mProtoReceipt.topicrunninghash();
|
||||
auto hashBin = MemoryManager::getInstance()->getFreeMemory(hash.size());
|
||||
memcpy(*hashBin, hash.data(), hash.size());
|
||||
return hashBin;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H
|
||||
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H
|
||||
|
||||
#include "../proto/hedera/TransactionReceipt.pb.h"
|
||||
#include "../../SingletonManager/MemoryManager.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
class TransactionReceipt
|
||||
{
|
||||
public:
|
||||
TransactionReceipt(const proto::TransactionReceipt& protoReceipt);
|
||||
~TransactionReceipt();
|
||||
|
||||
proto::TopicID getTopicId() { return mProtoReceipt.topicid(); }
|
||||
google::protobuf::uint64 getSequenceNumber() { return mProtoReceipt.topicsequencenumber(); }
|
||||
google::protobuf::uint64 getRunningHashVersion() { return mProtoReceipt.topicrunninghashversion(); }
|
||||
//! caller must release memory after finish with it
|
||||
MemoryBin* getRunningHash();
|
||||
proto::ResponseCodeEnum getStatus() { return mProtoReceipt.status(); }
|
||||
|
||||
inline proto::TransactionReceipt* getProto() { return &mProtoReceipt; }
|
||||
|
||||
protected:
|
||||
proto::TransactionReceipt mProtoReceipt;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RECEIPT_H
|
||||
@ -1,12 +0,0 @@
|
||||
#include "TransactionRecord.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
TransactionRecord::TransactionRecord(const proto::TransactionRecord& transaction_record)
|
||||
: mProtoRecord(transaction_record)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
#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
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
#include "TransactionResponse.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
TransactionResponse::TransactionResponse()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TransactionResponse::~TransactionResponse()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RESPONSE_H
|
||||
#define __GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RESPONSE_H
|
||||
|
||||
#include "proto/hedera/TransactionResponse.pb.h"
|
||||
#include "Poco/Types.h"
|
||||
|
||||
namespace model {
|
||||
namespace hedera {
|
||||
|
||||
class TransactionResponse
|
||||
{
|
||||
public:
|
||||
TransactionResponse();
|
||||
~TransactionResponse();
|
||||
|
||||
inline proto::ResponseCodeEnum getPrecheckCode() const { return mProtoResponse.nodetransactionprecheckcode();}
|
||||
inline std::string getPrecheckCodeString() const { return proto::ResponseCodeEnum_Name(mProtoResponse.nodetransactionprecheckcode()); }
|
||||
inline Poco::UInt64 getCost() const { return mProtoResponse.cost(); }
|
||||
|
||||
proto::TransactionResponse* getProtoResponse() { return &mProtoResponse; }
|
||||
protected:
|
||||
proto::TransactionResponse mProtoResponse;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_RESPONSE_H
|
||||
@ -1,169 +0,0 @@
|
||||
#include "CryptoKey.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
CryptoKey::CryptoKey()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CryptoKey::CryptoKey(MemoryBin* privateKey, MemoryBin* publicKey, KeyType keyType)
|
||||
: mKeyType(keyType)
|
||||
{
|
||||
if (!privateKey) {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>();
|
||||
} else {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>(Poco::Data::BLOB(*privateKey, privateKey->size()));
|
||||
}
|
||||
|
||||
if (!publicKey) {
|
||||
mPublicKey = Poco::Nullable<Poco::Data::BLOB>();
|
||||
} else {
|
||||
mPublicKey = Poco::Nullable<Poco::Data::BLOB>(Poco::Data::BLOB(*publicKey, publicKey->size()));
|
||||
}
|
||||
}
|
||||
|
||||
CryptoKey::~CryptoKey()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string CryptoKey::toString()
|
||||
{
|
||||
assert(mKeyType < KEY_TYPE_COUNT && mKeyType >= 0);
|
||||
std::stringstream ss;
|
||||
ss << "Key Type: " << typeToString(static_cast<KeyType>(mKeyType)) << std::endl;
|
||||
ss << "Public Key: " << DataTypeConverter::binToHex(mPublicKey);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
const char* CryptoKey::typeToString(KeyType type)
|
||||
{
|
||||
switch (type) {
|
||||
case KEY_TYPE_ED25519_SODIUM_ENCRYPTED: return "ed25519 sodium encrypted";
|
||||
case KEY_TYPE_ED25519_HEDERA_ENCRYPTED: return "ed22519 for hedera encrypted";
|
||||
case KEY_TYPE_ED25519_SODIUM_CLEAR: return "ed25519 sodium clear";
|
||||
case KEY_TYPE_ED25519_HEDERA_CLEAR: return "ed25519 hedera clear";
|
||||
}
|
||||
return "<unknown type>";
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CryptoKey::hasPrivateKeyEncrypted() const
|
||||
{
|
||||
const KeyType type = (KeyType)(mKeyType);
|
||||
if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED || type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) {
|
||||
return !mPrivateKey.isNull();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CryptoKey::isEncrypted() const
|
||||
{
|
||||
const KeyType type = (KeyType)(mKeyType);
|
||||
if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED ||
|
||||
type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CryptoKey::setPrivateKey(const MemoryBin* privateKey)
|
||||
{
|
||||
if (!privateKey) {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>();
|
||||
}
|
||||
else {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>(Poco::Data::BLOB(*privateKey, privateKey->size()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool CryptoKey::changeKeyTypeToggleEncrypted()
|
||||
{
|
||||
const KeyType type = (KeyType)(mKeyType);
|
||||
if (type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) {
|
||||
mKeyType = KEY_TYPE_ED25519_SODIUM_CLEAR;
|
||||
return true;
|
||||
}
|
||||
if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED) {
|
||||
mKeyType = KEY_TYPE_ED25519_HEDERA_CLEAR;
|
||||
return true;
|
||||
}
|
||||
if (type == KEY_TYPE_ED25519_SODIUM_CLEAR) {
|
||||
mKeyType = KEY_TYPE_ED25519_SODIUM_ENCRYPTED;
|
||||
return true;
|
||||
}
|
||||
if (type == KEY_TYPE_ED25519_HEDERA_CLEAR) {
|
||||
mKeyType = KEY_TYPE_ED25519_HEDERA_ENCRYPTED;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, private_key, public_key, crypto_key_type_id FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?"
|
||||
, into(mID), into(mPrivateKey), into(mPublicKey), into(mKeyType);
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
Poco::Data::Statement CryptoKey::_loadIdFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where public_key = ?"
|
||||
, into(mID), use(mPublicKey);
|
||||
return select;
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::Statement CryptoKey::_insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (private_key, public_key, crypto_key_type_id) VALUES(?,?,?)"
|
||||
, use(mPrivateKey), use(mPublicKey), use(mKeyType);
|
||||
return insert;
|
||||
}
|
||||
|
||||
size_t CryptoKey::updatePrivkeyAndKeyType()
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
if (mPrivateKey.isNull() || !mID) {
|
||||
return 0;
|
||||
}
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
|
||||
Poco::Data::Statement update(session);
|
||||
|
||||
update << "UPDATE " << getTableName() << " SET private_key = ?, crypto_key_type_id = ? where id = ?;",
|
||||
use(mPrivateKey), use(mKeyType), use(mID);
|
||||
|
||||
|
||||
size_t resultCount = 0;
|
||||
try {
|
||||
return update.execute();
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
addError(new ParamError(getTableName(), "[updatePrivkeyAndKeyType] mysql error by update", ex.displayText().data()));
|
||||
addError(new ParamError(getTableName(), "data set: \n", toString().data()));
|
||||
}
|
||||
//printf("data valid: %s\n", toString().data());
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE
|
||||
|
||||
#include "ModelBase.h"
|
||||
#include "Poco/Types.h"
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
enum KeyType {
|
||||
KEY_TYPE_ED25519_SODIUM_ENCRYPTED = 0,
|
||||
KEY_TYPE_ED25519_HEDERA_ENCRYPTED = 1,
|
||||
KEY_TYPE_ED25519_SODIUM_CLEAR = 2,
|
||||
KEY_TYPE_ED25519_HEDERA_CLEAR = 3,
|
||||
KEY_TYPE_COUNT
|
||||
};
|
||||
|
||||
class CryptoKey : public ModelBase
|
||||
{
|
||||
public:
|
||||
CryptoKey();
|
||||
CryptoKey(MemoryBin* privateKey, MemoryBin* publicKey, KeyType keyType);
|
||||
~CryptoKey();
|
||||
|
||||
// generic db operations
|
||||
const char* getTableName() const { return "crypto_keys"; }
|
||||
std::string toString();
|
||||
|
||||
inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); }
|
||||
inline std::string getPublicKeyHexString() const { return DataTypeConverter::binToHex(mPublicKey); };
|
||||
size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); }
|
||||
|
||||
bool hasPrivateKeyEncrypted() const;
|
||||
bool isEncrypted() const;
|
||||
bool changeKeyTypeToggleEncrypted();
|
||||
inline bool hasPrivateKey() const { return !mPrivateKey.isNull(); }
|
||||
inline const std::vector<unsigned char>& getPrivateKey() const { return mPrivateKey.value().content(); }
|
||||
|
||||
size_t updatePrivkeyAndKeyType();
|
||||
|
||||
//! \brief set encrypted private key
|
||||
//! \param privateKey copy data, didn't move memory bin
|
||||
void setPrivateKey(const MemoryBin* privateKey);
|
||||
|
||||
static const char* typeToString(KeyType type);
|
||||
protected:
|
||||
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
|
||||
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
|
||||
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
|
||||
|
||||
Poco::Nullable<Poco::Data::BLOB> mPrivateKey;
|
||||
Poco::Nullable<Poco::Data::BLOB> mPublicKey;
|
||||
int mKeyType;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_CRYPTO_KEYS_INCLUDE
|
||||
@ -1,135 +0,0 @@
|
||||
#include "HederaAccount.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
HederaAccount::HederaAccount()
|
||||
: mUserId(0), mAccountHederaId(0), mAccountKeyId(0), mBalance(0), mType(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaAccount::HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance/* = 0*/, ServerConfig::HederaNetworkType type /*= ServerConfig::HEDERA_MAINNET*/)
|
||||
: mUserId(user_id), mAccountHederaId(account_hedera_id), mAccountKeyId(account_key_id), mBalance(balance), mType(type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaAccount::HederaAccount(const HederaAccountTuple& tuple)
|
||||
: ModelBase(tuple.get<0>()),
|
||||
mUserId(tuple.get<1>()), mAccountHederaId(tuple.get<2>()), mAccountKeyId(tuple.get<3>()),
|
||||
mBalance(tuple.get<4>()), mType(tuple.get<5>()), mUpdated(tuple.get<6>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaAccount::~HederaAccount()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string HederaAccount::toString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "user id: " << std::to_string(mUserId) << std::endl;
|
||||
ss << "account hedera id: " << std::to_string(mAccountHederaId) << std::endl;
|
||||
ss << "account crypto key id: " << std::to_string(mAccountKeyId) << std::endl;
|
||||
// balance in tinybars, 100,000,000 tinybar = 1 HashBar
|
||||
ss << "account balance: " << std::to_string((double)(mBalance) * 100000000.0) << " HBAR" << std::endl;
|
||||
ss << "Hedera Net Type: " << hederaNetworkTypeToString((ServerConfig::HederaNetworkType)mType) << std::endl;
|
||||
ss << "last update: " << Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S") << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string HederaAccount::getBalanceString()
|
||||
{
|
||||
char buffer[65]; memset(buffer, 0, 65);
|
||||
//100,000,000
|
||||
#ifdef _WIN32
|
||||
sprintf_s(buffer, 64, "%.8f HBAR", (double)(mBalance) / 100000000.0);
|
||||
#else
|
||||
sprintf(buffer, "%.8f HBAR", (double)(mBalance) / 100000000.0);
|
||||
#endif
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
|
||||
const char* HederaAccount::hederaNetworkTypeToString(ServerConfig::HederaNetworkType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ServerConfig::HEDERA_MAINNET: return "Mainnet";
|
||||
case ServerConfig::HEDERA_TESTNET: return "Testnet";
|
||||
case ServerConfig::HEDERA_UNKNOWN: return "unknown";
|
||||
default: return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
ServerConfig::HederaNetworkType HederaAccount::hederaNetworkTypeFromString(const std::string& typeString)
|
||||
{
|
||||
if ("MAINNET" == typeString || "Mainnet" == typeString) {
|
||||
return ServerConfig::HEDERA_MAINNET;
|
||||
}
|
||||
if ("TESTNET" == typeString || "Testnet" == typeString) {
|
||||
return ServerConfig::HEDERA_TESTNET;
|
||||
}
|
||||
return ServerConfig::HEDERA_UNKNOWN;
|
||||
}
|
||||
|
||||
NodeServerType HederaAccount::networkTypeToNodeServerType(ServerConfig::HederaNetworkType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ServerConfig::HEDERA_MAINNET: return NODE_SERVER_HEDERA_MAINNET_NODE;
|
||||
case ServerConfig::HEDERA_TESTNET: return NODE_SERVER_HEDERA_TESTNET_NODE;
|
||||
default: return NODE_SERVER_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
Poco::Data::Statement HederaAccount::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, network_type, updated FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?"
|
||||
, into(mID), into(mUserId), into(mAccountHederaId), into(mAccountKeyId), into(mBalance), into(mType), into(mUpdated);
|
||||
|
||||
return select;
|
||||
|
||||
}
|
||||
|
||||
Poco::Data::Statement HederaAccount::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
select << "SELECT id, user_id, account_hedera_id, account_key_id, balance, network_type, updated FROM " << getTableName()
|
||||
<< " where " << fieldName << " LIKE ?";
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaAccount::_loadIdFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where account_hedera_id = ?"
|
||||
, into(mID), use(mAccountHederaId);
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaAccount::_insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (user_id, account_hedera_id, account_key_id, balance, network_type) VALUES(?,?,?,?,?)"
|
||||
, use(mUserId), use(mAccountHederaId), use(mAccountKeyId), use(mBalance), use(mType);
|
||||
|
||||
return insert;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE
|
||||
|
||||
//#include "ModelBase.h"
|
||||
#include "../../ServerConfig.h"
|
||||
#include "Poco/Tuple.h"
|
||||
|
||||
#include "NodeServer.h"
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
typedef Poco::Tuple<int, int, int, int, Poco::UInt64, int, Poco::DateTime> HederaAccountTuple;
|
||||
|
||||
|
||||
|
||||
class HederaAccount : public ModelBase
|
||||
{
|
||||
public:
|
||||
HederaAccount();
|
||||
HederaAccount(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, ServerConfig::HederaNetworkType type = ServerConfig::HEDERA_MAINNET);
|
||||
HederaAccount(const HederaAccountTuple& tuple);
|
||||
~HederaAccount();
|
||||
|
||||
// generic db operations
|
||||
const char* getTableName() const { return "hedera_accounts"; }
|
||||
std::string toString();
|
||||
|
||||
|
||||
static const char* hederaNetworkTypeToString(ServerConfig::HederaNetworkType type);
|
||||
static NodeServerType networkTypeToNodeServerType(ServerConfig::HederaNetworkType type);
|
||||
static ServerConfig::HederaNetworkType hederaNetworkTypeFromString(const std::string& typeString);
|
||||
|
||||
inline int getAccountHederaId() const { return mAccountHederaId; }
|
||||
inline int getCryptoKeyId() const { return mAccountKeyId; }
|
||||
inline int getUserId() const { return mUserId; }
|
||||
|
||||
inline Poco::UInt64 getBalance() { return mBalance; }
|
||||
inline double getBalanceDouble() { return (double)mBalance / 100000000.0; }
|
||||
std::string getBalanceString();
|
||||
|
||||
inline ServerConfig::HederaNetworkType getNetworkType() { return (ServerConfig::HederaNetworkType)mType; }
|
||||
|
||||
|
||||
inline std::string getUpdatedString() { return Poco::DateTimeFormatter::format(mUpdated, "%f.%m.%Y %H:%M:%S"); }
|
||||
|
||||
protected:
|
||||
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
|
||||
Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName);
|
||||
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
|
||||
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
|
||||
|
||||
int mUserId;
|
||||
int mAccountHederaId;
|
||||
int mAccountKeyId;
|
||||
Poco::UInt64 mBalance;
|
||||
int mType;
|
||||
Poco::DateTime mUpdated;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_ACCOUNTS_INCLUDE
|
||||
@ -1,100 +0,0 @@
|
||||
#include "HederaId.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
HederaId::HederaId()
|
||||
: mShardNum(0), mRealmNum(0), mNum(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaId::HederaId(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num)
|
||||
: mShardNum(shardNum), mRealmNum(realmNum), mNum(num)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaId::HederaId(const HederaIdTuple& tuple)
|
||||
: ModelBase(tuple.get<0>()),
|
||||
mShardNum(tuple.get<1>()), mRealmNum(tuple.get<2>()), mNum(tuple.get<3>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaId::~HederaId()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string HederaId::toString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::to_string(mShardNum) << "." << std::to_string(mRealmNum) << "." << std::to_string(mNum) << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
int HederaId::getID()
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
assert(mNum != 0|| mShardNum != 0 || mRealmNum != 0);
|
||||
if (mID) return mID;
|
||||
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(session);
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where shardNum = ? AND realmNum = ? AND num = ?"
|
||||
, into(mID), use(mShardNum), use(mRealmNum), use(mNum);
|
||||
|
||||
try {
|
||||
if (1 == select.execute()) {
|
||||
return mID;
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
addError(new ParamError("HederaId::getID", "mysql error try to find existing entry", ex.message()));
|
||||
sendErrorsAsEmail();
|
||||
}
|
||||
insertIntoDB(true);
|
||||
return mID;
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::Statement HederaId::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, shardNum, realmNum, num FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?"
|
||||
, into(mID), into(mShardNum), into(mRealmNum), into(mNum);
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaId::_loadIdFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where shardNum = ? AND realmNum = ? AND num = ?"
|
||||
, into(mID), use(mShardNum), use(mRealmNum), use(mNum);
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaId::_insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (shardNum, realmNum, num) VALUES(?,?,?)"
|
||||
, use(mShardNum), use(mRealmNum), use(mNum);
|
||||
|
||||
return insert;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_IDS_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_IDS_INCLUDE
|
||||
|
||||
#include "ModelBase.h"
|
||||
#include "Poco/Types.h"
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
typedef Poco::Tuple<int, Poco::UInt64, Poco::UInt64, Poco::UInt64> HederaIdTuple;
|
||||
|
||||
class HederaId : public ModelBase
|
||||
{
|
||||
public:
|
||||
HederaId();
|
||||
HederaId(Poco::UInt64 shardNum, Poco::UInt64 realmNum, Poco::UInt64 num);
|
||||
HederaId(const HederaIdTuple& tuple);
|
||||
~HederaId();
|
||||
|
||||
// generic db operations
|
||||
const char* getTableName() const { return "hedera_ids"; }
|
||||
std::string toString();
|
||||
|
||||
//! \brief check if hedera id already in db, then return id, else insert in db and return
|
||||
int getID();
|
||||
|
||||
inline Poco::UInt64 getShardNum() const { return mShardNum; }
|
||||
inline Poco::UInt64 getRealmNum() const { return mRealmNum; }
|
||||
inline Poco::UInt64 getNum() const { return mNum; }
|
||||
|
||||
protected:
|
||||
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
|
||||
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
|
||||
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
|
||||
|
||||
Poco::UInt64 mShardNum;
|
||||
Poco::UInt64 mRealmNum;
|
||||
Poco::UInt64 mNum;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_IDS_INCLUDE
|
||||
@ -1,113 +0,0 @@
|
||||
#include "HederaTopic.h"
|
||||
#include "Poco/DateTimeFormatter.h"
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
HederaTopic::HederaTopic()
|
||||
: mTopicHederaId(0), mAutoRenewAccountHederaId(0), mAutoRenewPeriod(0), mGroupId(0), mAdminKeyId(0), mSubmitKeyId(0),mSequenceNumber(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaTopic::HederaTopic(const HederaTopicTuple& tuple)
|
||||
: ModelBase(tuple.get<0>()), mTopicHederaId(tuple.get<1>()), mName(tuple.get<2>()), mAutoRenewAccountHederaId(tuple.get<3>()),
|
||||
mAutoRenewPeriod(tuple.get<4>()), mGroupId(tuple.get<5>()), mAdminKeyId(tuple.get<6>()), mSubmitKeyId(tuple.get<7>()),
|
||||
mCurrentTimeout(tuple.get<8>()), mSequenceNumber(tuple.get<9>()), mUpdated(tuple.get<10>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaTopic::HederaTopic(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId)
|
||||
: mTopicHederaId(0), mName(name), mAutoRenewAccountHederaId(autoRenewAccountId), mAutoRenewPeriod(autoRenewPeriod), mGroupId(groupId),
|
||||
mAdminKeyId(0), mSubmitKeyId(0), mSequenceNumber(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaTopic::~HederaTopic()
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
ss << "Auto Renew Period: " << std::to_string(mAutoRenewPeriod) << " seconds" << std::endl;
|
||||
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 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();
|
||||
}
|
||||
|
||||
std::string HederaTopic::getAutoRenewPeriodString() const
|
||||
{
|
||||
return secondsToReadableDuration(mAutoRenewPeriod) + " (" + std::to_string(mAutoRenewPeriod) + " seconds)";
|
||||
}
|
||||
|
||||
std::string HederaTopic::getCurrentTimeoutString() const
|
||||
{
|
||||
return Poco::DateTimeFormatter::format(mCurrentTimeout, "%Y-%m-%d %H:%M:%S");
|
||||
}
|
||||
std::string HederaTopic::getUpdatedString() const
|
||||
{
|
||||
return Poco::DateTimeFormatter::format(mUpdated, "%Y-%m-%d %H:%M:%S");
|
||||
}
|
||||
|
||||
Poco::Data::Statement HederaTopic::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, topic_hedera_id, name, auto_renew_account_hedera_id, auto_renew_period, "
|
||||
<< "group_id, admin_key_id, submit_key_id, current_timeout, sequence_number, updated FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?"
|
||||
, into(mID), into(mTopicHederaId), into(mName), into(mAutoRenewAccountHederaId), into(mAutoRenewPeriod)
|
||||
, into(mGroupId), into(mAdminKeyId), into(mSubmitKeyId), into(mCurrentTimeout), into(mSequenceNumber), into(mUpdated);
|
||||
|
||||
return select;
|
||||
|
||||
}
|
||||
Poco::Data::Statement HederaTopic::_loadAllFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
//typedef Poco::Tuple<int, int, std::string, int, Poco::UInt32, int, int, int, Poco::DateTime, Poco::UInt64, Poco::DateTime> HederaTopicTuple;
|
||||
|
||||
select << "SELECT id, topic_hedera_id, name, auto_renew_account_hedera_id, auto_renew_period, "
|
||||
<< "group_id, admin_key_id, submit_key_id, current_timeout, sequence_number, updated FROM " << getTableName();
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaTopic::_loadIdFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where topic_hedera_id = ? "
|
||||
<< " AND name = ? "
|
||||
, into(mID), use(mTopicHederaId), use(mName);
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement HederaTopic::_insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (topic_hedera_id, name, auto_renew_account_hedera_id, auto_renew_period,"
|
||||
<< " group_id, admin_key_id, submit_key_id, current_timeout, sequence_number) VALUES(?,?,?,?,?,?,?,?,?)"
|
||||
, use(mTopicHederaId), use(mName), use(mAutoRenewAccountHederaId), use(mAutoRenewPeriod)
|
||||
, use(mGroupId), use(mAdminKeyId), use(mSubmitKeyId), use(mCurrentTimeout), use(mSequenceNumber);
|
||||
|
||||
return insert;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,67 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_TOPICS_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_TOPICS_INCLUDE
|
||||
|
||||
#include "ModelBase.h"
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
|
||||
typedef Poco::Tuple<int, int, std::string, int, Poco::UInt32, int, int, int, Poco::DateTime, Poco::UInt64, Poco::DateTime> HederaTopicTuple;
|
||||
|
||||
class HederaTopic : public ModelBase
|
||||
{
|
||||
public:
|
||||
HederaTopic();
|
||||
HederaTopic(const HederaTopicTuple& tuple);
|
||||
HederaTopic(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId);
|
||||
~HederaTopic();
|
||||
|
||||
// generic db operations
|
||||
const char* getTableName() const { return "hedera_topics"; }
|
||||
std::string toString();
|
||||
|
||||
inline Poco::UInt32 getTopicHederaId() const { return mTopicHederaId; }
|
||||
inline std::string getName() const { return mName; }
|
||||
inline Poco::UInt32 getAutoRenewAccountId() const { return mAutoRenewAccountHederaId; }
|
||||
inline Poco::UInt32 getAutoRenewPeriod() const { return mAutoRenewPeriod; }
|
||||
std::string getAutoRenewPeriodString() const;
|
||||
inline Poco::UInt32 getGroupId() const { return mGroupId;}
|
||||
inline Poco::DateTime getCurrentTimeout() const { return mCurrentTimeout; }
|
||||
std::string getCurrentTimeoutString() const;
|
||||
inline Poco::UInt64 getSequenceNumber() const { return mSequenceNumber; }
|
||||
inline Poco::DateTime getUpdated() const { return mUpdated; }
|
||||
std::string getUpdatedString() const;
|
||||
|
||||
inline void setTopicHederaID(Poco::UInt32 topidHederaId) { mTopicHederaId = topidHederaId;}
|
||||
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);
|
||||
Poco::Data::Statement _loadAllFromDB(Poco::Data::Session session);
|
||||
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
|
||||
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
|
||||
|
||||
Poco::UInt32 mTopicHederaId;
|
||||
std::string mName;
|
||||
Poco::UInt32 mAutoRenewAccountHederaId;
|
||||
// in seconds
|
||||
Poco::UInt32 mAutoRenewPeriod;
|
||||
Poco::UInt32 mGroupId;
|
||||
Poco::UInt32 mAdminKeyId;
|
||||
Poco::UInt32 mSubmitKeyId;
|
||||
Poco::DateTime mCurrentTimeout;
|
||||
Poco::UInt64 mSequenceNumber;
|
||||
Poco::DateTime mUpdated;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_HEDERA_TOPICS_INCLUDE
|
||||
@ -1,132 +0,0 @@
|
||||
|
||||
#include "NodeServer.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
bool NodeServerIsHederaNode(NodeServerType type) {
|
||||
return type == NODE_SERVER_HEDERA_MAINNET_NODE || type == NODE_SERVER_HEDERA_TESTNET_NODE;
|
||||
}
|
||||
bool NodeServerHasGroup(NodeServerType type) {
|
||||
return type == NODE_SERVER_GRADIDO_NODE || type == NODE_SERVER_GRADIDO_COMMUNITY;
|
||||
}
|
||||
|
||||
|
||||
NodeServer::NodeServer()
|
||||
: mPort(0), mGroupId(0), mServerType(0), mNodeHederaId(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NodeServer::NodeServer(const std::string& url, int port, int groupId, NodeServerType type, int nodeHederaId)
|
||||
: mUrl(url), mPort(port), mGroupId(groupId), mServerType(type), mNodeHederaId(nodeHederaId)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
NodeServer::NodeServer(const NodeServerTuple& tuple)
|
||||
: ModelBase(tuple.get<0>()),
|
||||
mUrl(tuple.get<1>()), mPort(tuple.get<2>()), mGroupId(tuple.get<3>()),
|
||||
mServerType(tuple.get<4>()), mNodeHederaId(tuple.get<5>()), mLastLiveSign(tuple.get<6>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NodeServer::~NodeServer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string NodeServer::toString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "id: " << getID() << std::endl;
|
||||
ss << mUrl << ":" << mPort << std::endl;
|
||||
ss << "group id: " << mGroupId << std::endl;
|
||||
ss << "server type: " << nodeServerTypeToString((NodeServerType)mServerType) << std::endl;
|
||||
ss << "node hedera id: " << mNodeHederaId << std::endl;
|
||||
ss << "last live sign: " << Poco::DateTimeFormatter::format(mLastLiveSign, "%f.%m.%Y %H:%M:%S") << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
const char* NodeServer::nodeServerTypeToString(NodeServerType type)
|
||||
{
|
||||
switch (type) {
|
||||
case NODE_SERVER_NONE: return "none";
|
||||
case NODE_SERVER_GRADIDO_NODE: return "Gradido Node";
|
||||
case NODE_SERVER_GRADIDO_COMMUNITY: return "Gradido Community";
|
||||
case NODE_SERVER_HEDERA_MAINNET_NODE: return "Hedera Mainnet Node";
|
||||
case NODE_SERVER_HEDERA_TESTNET_NODE: return "Hedera Testnet Node";
|
||||
default: return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
Poco::Data::Statement NodeServer::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, url, port, group_id, server_type, node_hedera_id, last_live_sign FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?"
|
||||
, into(mID), into(mUrl), into(mPort), into(mGroupId), into(mServerType), into(mNodeHederaId), into(mLastLiveSign);
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
Poco::Data::Statement NodeServer::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
// typedef Poco::Tuple<std::string, std::string, std::string, Poco::Nullable<Poco::Data::BLOB>, int> UserTuple;
|
||||
select << "SELECT id, url, port, group_id, server_type, node_hedera_id, last_live_sign FROM " << getTableName()
|
||||
<< " where " << fieldName << " LIKE ?";
|
||||
|
||||
return select;
|
||||
}
|
||||
Poco::Data::Statement NodeServer::_loadMultipleFromDB(Poco::Data::Session session, const std::vector<std::string> fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
select << "SELECT id, url, port, group_id, server_type, node_hedera_id, last_live_sign FROM " << getTableName()
|
||||
<< " where " << fieldNames[0] << " = ? ";
|
||||
if (conditionType == MYSQL_CONDITION_AND) {
|
||||
for (int i = 1; i < fieldNames.size(); i++) {
|
||||
select << " AND " << fieldNames[i] << " = ?";
|
||||
}
|
||||
}
|
||||
else if (conditionType == MYSQL_CONDITION_OR) {
|
||||
for (int i = 1; i < fieldNames.size(); i++) {
|
||||
select << " OR " << fieldNames[i] << " = ?";
|
||||
}
|
||||
}
|
||||
return select;
|
||||
}
|
||||
|
||||
Poco::Data::Statement NodeServer::_loadIdFromDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " where url = ? AND port = ? "
|
||||
, into(mID), use(mUrl), use(mPort);
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
Poco::Data::Statement NodeServer::_insertIntoDB(Poco::Data::Session session)
|
||||
{
|
||||
Poco::Data::Statement insert(session);
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (url, port, group_id, server_type, node_hedera_id) VALUES(?,?,?,?,?)"
|
||||
, use(mUrl), use(mPort), use(mGroupId), use(mServerType), use(mNodeHederaId);
|
||||
|
||||
return insert;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,75 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_NODE_SERVER_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_NODE_SERVER_INCLUDE
|
||||
|
||||
#include "ModelBase.h"
|
||||
#include "Poco/Tuple.h"
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
|
||||
typedef Poco::Tuple<int, std::string, int, int, int, int, Poco::DateTime> NodeServerTuple;
|
||||
|
||||
enum NodeServerType {
|
||||
NODE_SERVER_NONE,
|
||||
NODE_SERVER_GRADIDO_NODE,
|
||||
NODE_SERVER_GRADIDO_COMMUNITY,
|
||||
NODE_SERVER_HEDERA_MAINNET_NODE,
|
||||
NODE_SERVER_HEDERA_TESTNET_NODE,
|
||||
NODE_SERVER_TYPE_COUNT,
|
||||
NODE_SERVER_TYPE_NONE
|
||||
};
|
||||
bool NodeServerIsHederaNode(NodeServerType type);
|
||||
bool NodeServerHasGroup(NodeServerType type);
|
||||
|
||||
|
||||
class NodeServer : public ModelBase
|
||||
{
|
||||
public:
|
||||
NodeServer();
|
||||
NodeServer(const std::string& url, int port, int groupId, NodeServerType type, int nodeHederaId);
|
||||
NodeServer(const NodeServerTuple& tuple);
|
||||
~NodeServer();
|
||||
|
||||
// generic db operations
|
||||
const char* getTableName() const { return "node_servers"; }
|
||||
std::string toString();
|
||||
|
||||
static const char* nodeServerTypeToString(NodeServerType type);
|
||||
|
||||
inline void setLastLiveSign(Poco::DateTime lastLiveSign) { UNIQUE_LOCK; mLastLiveSign = lastLiveSign; }
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !ATTENTION! if using set port or set url review CronManager code
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
inline std::string getUrl() const { return mUrl; }
|
||||
inline int getPort() const { return mPort; }
|
||||
inline std::string getUrlWithPort() const { return mUrl + ":" + std::to_string(mPort); }
|
||||
inline int getGroupId() const { return mGroupId; }
|
||||
inline NodeServerType getNodeServerType() const { return (NodeServerType)mServerType; }
|
||||
inline bool isHederaNode() const { return NodeServerIsHederaNode((NodeServerType)mServerType);}
|
||||
inline bool hasGroup() const {return NodeServerHasGroup((NodeServerType)mServerType);}
|
||||
inline int getNodeHederaId() const { return mNodeHederaId; }
|
||||
inline Poco::DateTime getLastLiveSign() const { SHARED_LOCK; return mLastLiveSign; }
|
||||
|
||||
protected:
|
||||
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
|
||||
Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName);
|
||||
Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::vector<std::string> fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND);
|
||||
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
|
||||
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
|
||||
|
||||
std::string mUrl;
|
||||
int mPort;
|
||||
int mGroupId;
|
||||
int mServerType;
|
||||
int mNodeHederaId;
|
||||
Poco::DateTime mLastLiveSign;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_NODE_SERVER_INCLUDE
|
||||
@ -10,20 +10,20 @@ namespace model
|
||||
namespace table
|
||||
{
|
||||
PendingTask::PendingTask()
|
||||
: mUserId(0), mHederaId(0), mTaskTypeId(TASK_TYPE_NONE), mChildPendingTaskId(0), mParentPendingTaskId(0)
|
||||
: mUserId(0), mTaskTypeId(TASK_TYPE_NONE), mChildPendingTaskId(0), mParentPendingTaskId(0)
|
||||
{
|
||||
|
||||
}
|
||||
PendingTask::PendingTask(int userId, std::string serializedProtoRequest, TaskType type)
|
||||
: mUserId(userId), mHederaId(0), mRequest((const unsigned char*)serializedProtoRequest.data(), serializedProtoRequest.size()),
|
||||
: mUserId(userId), mRequest((const unsigned char*)serializedProtoRequest.data(), serializedProtoRequest.size()),
|
||||
mTaskTypeId(TASK_TYPE_NONE), mChildPendingTaskId(0), mParentPendingTaskId(0)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
PendingTask::PendingTask(const PendingTaskTuple& tuple)
|
||||
: ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mHederaId(tuple.get<2>()),
|
||||
mRequest(tuple.get<3>()), mCreated(tuple.get<4>()), mFinished(tuple.get<5>()),
|
||||
mResultJsonString(tuple.get<6>()), mParamJsonString(tuple.get<7>()), mTaskTypeId(tuple.get<8>()), mChildPendingTaskId(tuple.get<9>()), mParentPendingTaskId(tuple.get<10>())
|
||||
: ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()),
|
||||
mRequest(tuple.get<2>()), mCreated(tuple.get<3>()), mFinished(tuple.get<4>()),
|
||||
mResultJsonString(tuple.get<5>()), mParamJsonString(tuple.get<6>()), mTaskTypeId(tuple.get<7>()), mChildPendingTaskId(tuple.get<8>()), mParentPendingTaskId(tuple.get<9>())
|
||||
{
|
||||
|
||||
}
|
||||
@ -37,7 +37,7 @@ namespace model
|
||||
UNIQUE_LOCK;
|
||||
mRequest.assignRaw((const unsigned char*)serializedProto.data(), serializedProto.size());
|
||||
}
|
||||
|
||||
|
||||
void PendingTask::setResultJson(Poco::JSON::Object::Ptr result)
|
||||
{
|
||||
UNIQUE_LOCK;
|
||||
@ -186,7 +186,7 @@ namespace model
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
std::string PendingTask::toString()
|
||||
{
|
||||
@ -200,7 +200,7 @@ namespace model
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* PendingTask::typeToString(TaskType type)
|
||||
{
|
||||
switch (type) {
|
||||
@ -208,9 +208,6 @@ namespace model
|
||||
case TASK_TYPE_GROUP_ADD_MEMBER: return "group add member";
|
||||
case TASK_TYPE_CREATION: return "creation";
|
||||
case TASK_TYPE_TRANSFER: return "transfer";
|
||||
case TASK_TYPE_HEDERA_TOPIC_CREATE: return "hedera topic create";
|
||||
case TASK_TYPE_HEDERA_TOPIC_MESSAGE: return "hedera topic send message";
|
||||
case TASK_TYPE_HEDERA_ACCOUNT_CREATE: return "hedera account create";
|
||||
default: return "<unknown>";
|
||||
}
|
||||
return "<invalid>";
|
||||
@ -228,25 +225,17 @@ namespace model
|
||||
};*/
|
||||
bool PendingTask::isGradidoTransaction(TaskType type)
|
||||
{
|
||||
if (type && type < TASK_TYPE_HEDERA_TOPIC_CREATE)
|
||||
return true;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PendingTask::isHederaTransaction(TaskType type)
|
||||
{
|
||||
if (type && type >= TASK_TYPE_HEDERA_TOPIC_CREATE)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::Statement PendingTask::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, user_id, hedera_id, request, created, finished, result_json, param_json, task_type_id, child_pending_task_id, parent_pending_task_id FROM " << getTableName()
|
||||
select << "SELECT id, user_id, request, created, finished, result_json, param_json, task_type_id, child_pending_task_id, parent_pending_task_id FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?"
|
||||
, into(mID), into(mUserId), into(mHederaId), into(mRequest), into(mCreated), into(mFinished), into(mResultJsonString), into(mParamJsonString),
|
||||
, into(mID), into(mUserId), into(mRequest), into(mCreated), into(mFinished), into(mResultJsonString), into(mParamJsonString),
|
||||
into(mTaskTypeId), into(mChildPendingTaskId), into(mParentPendingTaskId);
|
||||
|
||||
return select;
|
||||
@ -256,7 +245,7 @@ namespace model
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, user_id, hedera_id, request, created, finished, result_json, param_json, task_type_id, child_pending_task_id, parent_pending_task_id FROM "
|
||||
select << "SELECT id, user_id, request, created, finished, result_json, param_json, task_type_id, child_pending_task_id, parent_pending_task_id FROM "
|
||||
<< getTableName() << " order by id";
|
||||
|
||||
return select;
|
||||
@ -268,12 +257,11 @@ namespace model
|
||||
|
||||
select << "SELECT id FROM " << getTableName()
|
||||
<< " WHERE user_id = ? "
|
||||
<< " AND hedera_id = ? "
|
||||
<< " AND request = ?"
|
||||
<< " AND TIMESTAMPDIFF(SECOND, created, ?) = 0 "
|
||||
<< " AND task_type_id = ? "
|
||||
, into(mID), use(mUserId), use(mHederaId), use(mRequest), use(mCreated), use(mTaskTypeId);
|
||||
|
||||
, into(mID), use(mUserId), use(mRequest), use(mCreated), use(mTaskTypeId);
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
@ -283,10 +271,10 @@ namespace model
|
||||
Poco::Data::Statement insert(session);
|
||||
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (user_id, hedera_id, request, created, result_json, param_json, task_type_id, child_pending_task_id, parent_pending_task_id) VALUES(?,?,?,?,?,?,?,?,?)"
|
||||
, use(mUserId), use(mHederaId), use(mRequest), use(mCreated), use(mResultJsonString), use(mParamJsonString), use(mTaskTypeId), use(mChildPendingTaskId), use(mParentPendingTaskId);
|
||||
|
||||
<< " (user_id, request, created, result_json, param_json, task_type_id, child_pending_task_id, parent_pending_task_id) VALUES(?,?,?,?,?,?,?,?)"
|
||||
, use(mUserId), use(mRequest), use(mCreated), use(mResultJsonString), use(mParamJsonString), use(mTaskTypeId), use(mChildPendingTaskId), use(mParentPendingTaskId);
|
||||
|
||||
return insert;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,15 +14,11 @@ namespace model {
|
||||
TASK_TYPE_GROUP_CREATE = 1,
|
||||
TASK_TYPE_GROUP_ADD_MEMBER = 2,
|
||||
TASK_TYPE_CREATION = 10,
|
||||
TASK_TYPE_TRANSFER = 11,
|
||||
TASK_TYPE_HEDERA_TOPIC_CREATE = 20,
|
||||
TASK_TYPE_HEDERA_TOPIC_MESSAGE = 21,
|
||||
TASK_TYPE_HEDERA_ACCOUNT_CREATE = 25,
|
||||
TASK_TYPE_HEDERA_ACCOUNT_TRANSFER = 26
|
||||
TASK_TYPE_TRANSFER = 11
|
||||
|
||||
};
|
||||
|
||||
typedef Poco::Tuple<int, int, int, Poco::Data::BLOB, Poco::DateTime, Poco::DateTime, std::string, std::string, int, int, int> PendingTaskTuple;
|
||||
|
||||
typedef Poco::Tuple<int, int, Poco::Data::BLOB, Poco::DateTime, Poco::DateTime, std::string, std::string, int, int, int> PendingTaskTuple;
|
||||
|
||||
class PendingTask : public ModelBase
|
||||
{
|
||||
@ -45,7 +41,6 @@ namespace model {
|
||||
bool updateParam();
|
||||
|
||||
inline int getUserId() const { SHARED_LOCK; return mUserId; }
|
||||
inline int getHederaId() const { SHARED_LOCK; return mHederaId; }
|
||||
inline const std::vector<unsigned char>& getRequest() const { SHARED_LOCK; return mRequest.content(); }
|
||||
inline std::string getRequestCopy() const { SHARED_LOCK; return std::string((const char*)mRequest.content().data(), mRequest.content().size()); }
|
||||
Poco::JSON::Object::Ptr getResultJson() const;
|
||||
@ -57,7 +52,6 @@ namespace model {
|
||||
inline int getParentPendingTaskId() const { SHARED_LOCK; return mParentPendingTaskId; }
|
||||
|
||||
inline void setUserId(int userId) { UNIQUE_LOCK; mUserId = userId; }
|
||||
inline void setHederaId(int hederaId) { UNIQUE_LOCK; mHederaId = hederaId; }
|
||||
void setRequest(const std::string& serializedProto);
|
||||
inline void setFinished(Poco::DateTime date) { UNIQUE_LOCK; mFinished = date; }
|
||||
void setResultJson(Poco::JSON::Object::Ptr result);
|
||||
@ -65,11 +59,9 @@ namespace model {
|
||||
inline void setTaskType(TaskType type) { UNIQUE_LOCK; mTaskTypeId = type; }
|
||||
inline void setChildPendingTaskId(int childPendingTaskId) {UNIQUE_LOCK; mChildPendingTaskId = childPendingTaskId;}
|
||||
inline void setParentPendingTaskId(int parentPendingTaskId) { UNIQUE_LOCK; mParentPendingTaskId = parentPendingTaskId; }
|
||||
|
||||
|
||||
inline bool isGradidoTransaction() { SHARED_LOCK; return isGradidoTransaction((TaskType)mTaskTypeId); }
|
||||
static bool isGradidoTransaction(TaskType type);
|
||||
inline bool isHederaTransaction() { SHARED_LOCK; return isHederaTransaction((TaskType)mTaskTypeId); }
|
||||
static bool isHederaTransaction(TaskType type);
|
||||
|
||||
static const char* typeToString(TaskType type);
|
||||
protected:
|
||||
@ -79,7 +71,6 @@ namespace model {
|
||||
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
|
||||
|
||||
int mUserId;
|
||||
int mHederaId;
|
||||
Poco::Data::BLOB mRequest;
|
||||
Poco::DateTime mCreated;
|
||||
Poco::DateTime mFinished;
|
||||
@ -94,4 +85,4 @@ namespace model {
|
||||
}
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_PENDING_TASKS_INCLUDE
|
||||
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_PENDING_TASKS_INCLUDE
|
||||
|
||||
@ -1,218 +0,0 @@
|
||||
#include "HederaTask.h"
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
#include "../proto/hedera/TransactionGetReceipt.pb.h"
|
||||
|
||||
#include "../controller/NodeServer.h"
|
||||
#include "../controller/HederaAccount.h"
|
||||
#include "../controller/HederaRequest.h"
|
||||
#include "../controller/HederaTopic.h"
|
||||
|
||||
#include "../SingletonManager/PendingTasksManager.h"
|
||||
|
||||
HederaTask::HederaTask(const model::gradido::Transaction* transaction)
|
||||
: controller::PendingTask(new model::table::PendingTask), mTransactionReceipt(nullptr), mTryCount(0)
|
||||
{
|
||||
auto hedera_task_model = getModel();
|
||||
auto gradido_task_model = transaction->getModel();
|
||||
hedera_task_model->setParentPendingTaskId(gradido_task_model->getID());
|
||||
hedera_task_model->setUserId(gradido_task_model->getUserId());
|
||||
hedera_task_model->setTaskType(model::table::TASK_TYPE_HEDERA_TOPIC_MESSAGE);
|
||||
}
|
||||
|
||||
HederaTask::HederaTask(const model::hedera::Transaction* transaction)
|
||||
: controller::PendingTask(new model::table::PendingTask), mTransactionReceipt(nullptr), mTryCount(0)
|
||||
{
|
||||
auto hedera_task_model = getModel();
|
||||
//auto gradido_task_model = transaction->getModel();
|
||||
//hedera_task_model->setUserId(gradido_task_model->getUserId());
|
||||
model::table::TaskType task_type;
|
||||
auto transaction_type = transaction->getType();
|
||||
switch (transaction_type) {
|
||||
case model::hedera::TRANSACTION_CONSENSUS_CREATE_TOPIC:
|
||||
task_type = model::table::TASK_TYPE_HEDERA_TOPIC_CREATE; break;
|
||||
case model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE:
|
||||
task_type = model::table::TASK_TYPE_HEDERA_TOPIC_MESSAGE; break;
|
||||
case model::hedera::TRANSACTION_CRYPTO_CREATE:
|
||||
task_type = model::table::TASK_TYPE_HEDERA_ACCOUNT_CREATE; break;
|
||||
case model::hedera::TRANSACTION_CRYPTO_TRANSFER:
|
||||
task_type = model::table::TASK_TYPE_HEDERA_ACCOUNT_TRANSFER; break;
|
||||
}
|
||||
hedera_task_model->setTaskType(task_type);
|
||||
mTransactionID = transaction->getTransactionId();
|
||||
}
|
||||
|
||||
HederaTask::HederaTask(model::table::PendingTask* dbModel)
|
||||
: controller::PendingTask(dbModel), mTransactionReceipt(nullptr), mTryCount(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HederaTask::~HederaTask()
|
||||
{
|
||||
if (mTransactionReceipt) {
|
||||
delete mTransactionReceipt;
|
||||
mTransactionReceipt = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaTask> HederaTask::load(model::table::PendingTask* dbModel)
|
||||
{
|
||||
if (!dbModel || !dbModel->isHederaTransaction()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new HederaTask(dbModel);
|
||||
}
|
||||
|
||||
|
||||
Poco::DateTime HederaTask::getNextRunTime()
|
||||
{
|
||||
printf("[HederaTask::getNextRunTime]\n");
|
||||
std::shared_lock<std::shared_mutex> _lock(mWorkingMutex);
|
||||
return mLastCheck + 2000 * mTryCount * 2000;
|
||||
}
|
||||
|
||||
int HederaTask::run()
|
||||
{
|
||||
auto result = tryQueryReceipt();
|
||||
// keep also by -1 task in db for debugging
|
||||
if (result != 1 && result != -1) {
|
||||
deleteFromDB();
|
||||
|
||||
}
|
||||
if (result == -1 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void HederaTask::setTransactionReceipt(model::hedera::TransactionReceipt* transactionReceipt)
|
||||
{
|
||||
assert(transactionReceipt);
|
||||
|
||||
std::unique_lock<std::shared_mutex> _lock(mWorkingMutex);
|
||||
if (mTransactionReceipt) {
|
||||
printf("[HederaTask::setTransactionReceipt] warning, receipt already set\n");
|
||||
delete mTransactionReceipt;
|
||||
}
|
||||
mTransactionReceipt = transactionReceipt;
|
||||
}
|
||||
|
||||
//! \return 0 by success
|
||||
//! \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()
|
||||
{
|
||||
printf("[HederaTask::tryQueryReceipt]\n");
|
||||
static const char* function_name = "HederaTask::tryQueryReceipt";
|
||||
std::unique_lock<std::shared_mutex> _lock(mWorkingMutex);
|
||||
auto node_server_type = model::table::HederaAccount::networkTypeToNodeServerType(ServerConfig::g_HederaNetworkType);
|
||||
auto connection = controller::NodeServer::pick(node_server_type);
|
||||
if (!connection.isValid()) {
|
||||
addError(new ParamError(function_name, "couldn't find node server for server type: ", model::table::NodeServer::nodeServerTypeToString(node_server_type)));
|
||||
return -2;
|
||||
}
|
||||
auto operator_account = controller::HederaAccount::pick(ServerConfig::g_HederaNetworkType, false);
|
||||
if (operator_account.isNull()) {
|
||||
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) {
|
||||
if (runAfterGettingReceipt()) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (response.getResponseCode() == proto::NOT_SUPPORTED) {
|
||||
addError(new ParamError(function_name, "query in json-format:", query->toJsonString()));
|
||||
//query->toJsonString()
|
||||
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++;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool HederaTask::runAfterGettingReceipt()
|
||||
{
|
||||
assert(getModel());
|
||||
auto type = getModel()->getTaskType();
|
||||
switch (type) {
|
||||
case model::table::TASK_TYPE_HEDERA_TOPIC_CREATE:
|
||||
return runForHederaTopic();
|
||||
case model::table::TASK_TYPE_HEDERA_TOPIC_MESSAGE:
|
||||
case model::table::TASK_TYPE_HEDERA_ACCOUNT_CREATE:
|
||||
case model::table::TASK_TYPE_HEDERA_ACCOUNT_TRANSFER:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HederaTask::runForHederaTopic()
|
||||
{
|
||||
static const char* function_name = "HederaTask::runForHederaTopic";
|
||||
// parent pending task is set to hedera_topic.id in db
|
||||
auto model = getModel();
|
||||
auto hedera_topic = controller::HederaTopic::load(model->getParentPendingTaskId());
|
||||
if (!hedera_topic.isNull()) {
|
||||
auto hedera_topic_model = hedera_topic->getModel();
|
||||
auto topic_id = mTransactionReceipt->getTopicId();
|
||||
auto hedera_id = controller::HederaId::create(topic_id.shardnum(), topic_id.realmnum(), topic_id.topicnum());
|
||||
if (!hedera_id->getModel()->insertIntoDB(true)) {
|
||||
addError(new Error(function_name, "error saving hedera_id"));
|
||||
addError(new ParamError(function_name, "for hedera topic: ", hedera_topic_model->getID()));
|
||||
addError(new ParamError(function_name, "shardnum: ", topic_id.shardnum()));
|
||||
addError(new ParamError(function_name, "realmnum: ", topic_id.realmnum()));
|
||||
addError(new ParamError(function_name, "topicnum", topic_id.topicnum()));
|
||||
|
||||
return false;
|
||||
}
|
||||
hedera_topic_model->setTopicHederaID(hedera_id->getModel()->getID());
|
||||
hedera_topic_model->setSequeceNumber(mTransactionReceipt->getSequenceNumber());
|
||||
std::string fieldNames[] = { "topic_hedera_id", "sequence_number" };
|
||||
if (1 != hedera_topic_model->updateIntoDB(
|
||||
fieldNames,
|
||||
hedera_topic_model->getTopicHederaId(),
|
||||
hedera_topic_model->getSequenceNumber()
|
||||
)) {
|
||||
addError(new Error(function_name, "error updating topic id"));
|
||||
addError(new ParamError(function_name, "for hedera topic: ", hedera_topic_model->getID()));
|
||||
addError(new ParamError(function_name, "shardnum: ", topic_id.shardnum()));
|
||||
addError(new ParamError(function_name, "realmnum: ", topic_id.realmnum()));
|
||||
addError(new ParamError(function_name, "topicnum", topic_id.topicnum()));
|
||||
return false;
|
||||
}
|
||||
//! TODO think about saving also the last running hash
|
||||
|
||||
}
|
||||
else {
|
||||
addError(new ParamError(function_name, "hedera topic not found, id: ", model->getParentPendingTaskId()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
#ifndef __GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H
|
||||
#define __GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H
|
||||
|
||||
#include "../model/hedera/TransactionResponse.h"
|
||||
#include "../model/hedera/TransactionReceipt.h"
|
||||
#include "../model/hedera/Transaction.h"
|
||||
#include "../model/hedera/Query.h"
|
||||
#include "../proto/hedera/BasicTypes.pb.h"
|
||||
#include "../proto/hedera/Duration.pb.h"
|
||||
|
||||
#include "../model/gradido/Transaction.h"
|
||||
|
||||
#include "../controller/PendingTask.h"
|
||||
#include "../controller/HederaAccount.h"
|
||||
|
||||
#include "Poco/Timestamp.h"
|
||||
|
||||
#include <shared_mutex>
|
||||
|
||||
/*!
|
||||
*
|
||||
* \brief: Managing hedera task, especially check on receipt availability
|
||||
*
|
||||
* \author: Dario Rekowski
|
||||
*
|
||||
*/
|
||||
|
||||
class HederaTask : public controller::PendingTask, public NotificationList
|
||||
{
|
||||
public:
|
||||
|
||||
HederaTask(const model::gradido::Transaction* transaction);
|
||||
HederaTask(const model::hedera::Transaction* transaction);
|
||||
HederaTask(model::table::PendingTask* dbModel);
|
||||
//HederaTask(model::hedera::Query)
|
||||
~HederaTask();
|
||||
|
||||
static Poco::AutoPtr<HederaTask> load(model::table::PendingTask* dbModel);
|
||||
|
||||
inline model::hedera::TransactionResponse* getTransactionResponse() { std::shared_lock<std::shared_mutex> _lock(mWorkingMutex); return &mTransactionResponse; }
|
||||
inline void setTransactionId(const proto::TransactionID& transactionId) { std::unique_lock<std::shared_mutex> _lock(mWorkingMutex); mTransactionID = transactionId; }
|
||||
inline void setValidDuration(const proto::Duration& validDuration) { std::unique_lock<std::shared_mutex> _lock(mWorkingMutex); mValidDuration = validDuration; }
|
||||
//! \param transactionReceipt take ownership and call delete if done
|
||||
void setTransactionReceipt(model::hedera::TransactionReceipt* transactionReceipt);
|
||||
|
||||
inline const proto::TransactionID& getTransactionId() const { std::shared_lock<std::shared_mutex> _lock(mWorkingMutex); return mTransactionID; }
|
||||
inline const proto::Duration& getDuration() const { std::shared_lock<std::shared_mutex> _lock(mWorkingMutex); return mValidDuration; }
|
||||
inline const model::hedera::TransactionReceipt* getTransactionReceipt() const{ std::shared_lock<std::shared_mutex> _lock(mWorkingMutex); return mTransactionReceipt; }
|
||||
|
||||
|
||||
bool isTimeoutTask() { return true; }
|
||||
Poco::DateTime getNextRunTime();
|
||||
int run();
|
||||
|
||||
//! \return 0 by success
|
||||
//! \return 1 if hedera query failed
|
||||
//! \return -1 if run after failed
|
||||
//! \return -2 if not enough data for query
|
||||
int tryQueryReceipt();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool runAfterGettingReceipt();
|
||||
bool runForHederaTopic();
|
||||
|
||||
model::hedera::TransactionResponse mTransactionResponse;
|
||||
model::hedera::TransactionReceipt* mTransactionReceipt;
|
||||
|
||||
|
||||
proto::TransactionID mTransactionID;
|
||||
proto::Duration mValidDuration;
|
||||
|
||||
// last time checked if transaction receipt is available
|
||||
Poco::Timestamp mLastCheck;
|
||||
int mTryCount;
|
||||
|
||||
mutable std::shared_mutex mWorkingMutex;
|
||||
};
|
||||
|
||||
#endif //__GRADIDO_LOGIN_TASKS_HEDERA_TASKS_H
|
||||
@ -1,123 +0,0 @@
|
||||
#include "ProcessingTransaction.h"
|
||||
#include <sodium.h>
|
||||
|
||||
#include "../model/gradido/TransactionCreation.h"
|
||||
#include "../model/gradido/TransactionTransfer.h"
|
||||
#include "../model/gradido/GroupMemberUpdate.h"
|
||||
|
||||
#include "../SingletonManager/SingletonTaskObserver.h"
|
||||
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
#include "../lib/JsonRequest.h"
|
||||
|
||||
ProcessingTransaction::ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash, Languages lang, Poco::DateTime transactionCreated/* = Poco::DateTime()*/)
|
||||
: mProtoMessageBase64(proto_message_base64), mUserEmailHash(userEmailHash),
|
||||
mLang(lang), mTransactionCreated(transactionCreated)
|
||||
{
|
||||
mHashMutex.lock();
|
||||
mHash = calculateHash(proto_message_base64);
|
||||
mHashMutex.unlock();
|
||||
|
||||
auto observer = SingletonTaskObserver::getInstance();
|
||||
if (userEmailHash != 0) {
|
||||
observer->addTask(userEmailHash, TASK_OBSERVER_PREPARE_TRANSACTION);
|
||||
}
|
||||
}
|
||||
|
||||
ProcessingTransaction::ProcessingTransaction(Poco::AutoPtr<model::gradido::TransactionBody> transactionBody, DHASH userEmailHash, Languages lang, Poco::DateTime transactionCreated/* = Poco::DateTime()*/)
|
||||
: mTransactionBody(transactionBody), mUserEmailHash(userEmailHash),
|
||||
mLang(lang), mTransactionCreated(transactionCreated)
|
||||
{
|
||||
auto observer = SingletonTaskObserver::getInstance();
|
||||
if (userEmailHash != 0) {
|
||||
observer->addTask(userEmailHash, TASK_OBSERVER_PREPARE_TRANSACTION);
|
||||
}
|
||||
}
|
||||
ProcessingTransaction::~ProcessingTransaction()
|
||||
{
|
||||
lock();
|
||||
auto observer = SingletonTaskObserver::getInstance();
|
||||
if (mUserEmailHash != 0) {
|
||||
observer->removeTask(mUserEmailHash, TASK_OBSERVER_PREPARE_TRANSACTION);
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
HASH ProcessingTransaction::calculateHash(const std::string& proto_message_base64)
|
||||
{
|
||||
return DRMakeStringHash(proto_message_base64.data(), proto_message_base64.size());
|
||||
}
|
||||
|
||||
std::string ProcessingTransaction::calculateGenericHash(const std::string& protoMessageBase64)
|
||||
{
|
||||
auto mm = MemoryManager::getInstance();
|
||||
auto hash = mm->getFreeMemory(crypto_generichash_BYTES);
|
||||
|
||||
crypto_generichash(*hash, sizeof(DHASH), (const unsigned char*)protoMessageBase64.data(), protoMessageBase64.size(), NULL, 0);
|
||||
std::string base64HashString = DataTypeConverter::binToBase64(hash);
|
||||
mm->releaseMemory(hash);
|
||||
return base64HashString;
|
||||
}
|
||||
|
||||
|
||||
void ProcessingTransaction::reportErrorToCommunityServer(std::string error, std::string errorDetails, std::string created)
|
||||
{
|
||||
auto transaction_hash = calculateGenericHash(mProtoMessageBase64);
|
||||
JsonRequest phpServerRequest(ServerConfig::g_php_serverHost, ServerConfig::g_phpServerPort);
|
||||
Poco::Net::NameValueCollection payload;
|
||||
|
||||
payload.set("created", created);
|
||||
payload.set("transactionGenericHash", transaction_hash);
|
||||
payload.set("error", error);
|
||||
payload.set("errorMessage", errorDetails);
|
||||
|
||||
auto ret = phpServerRequest.request("errorInTransaction", payload);
|
||||
if (ret == JSON_REQUEST_RETURN_ERROR) {
|
||||
addError(new Error("ProcessingTransaction::reportErrorToCommunityServer", "php server error"));
|
||||
getErrors(&phpServerRequest);
|
||||
sendErrorsAsEmail();
|
||||
}
|
||||
}
|
||||
|
||||
int ProcessingTransaction::run()
|
||||
{
|
||||
lock();
|
||||
|
||||
auto mm = MemoryManager::getInstance();
|
||||
auto langM = LanguageManager::getInstance();
|
||||
auto catalog = langM->getFreeCatalog(mLang);
|
||||
|
||||
if (mProtoMessageBase64 != "") {
|
||||
auto protoMessageBin = DataTypeConverter::base64ToBin(mProtoMessageBase64);
|
||||
|
||||
if (!protoMessageBin)
|
||||
{
|
||||
addError(new Error("ProcessingTransaction", "error decoding base64"));
|
||||
reportErrorToCommunityServer(catalog->gettext("decoding error"), catalog->gettext("Error decoding base64 string"), "-1");
|
||||
unlock();
|
||||
return -1;
|
||||
}
|
||||
auto proto_message_string = std::string((const char*)protoMessageBin->data(), protoMessageBin->size());
|
||||
mTransactionBody = model::gradido::TransactionBody::load(proto_message_string);
|
||||
mm->releaseMemory(protoMessageBin);
|
||||
}
|
||||
if (mTransactionBody.isNull()) {
|
||||
addError(new Error("ProcessingTransaction", "error creating Transaction from binary Message"));
|
||||
reportErrorToCommunityServer(catalog->gettext("decoding error"), catalog->gettext("Error by parsing to protobuf message"), "-1");
|
||||
unlock();
|
||||
return -2;
|
||||
}
|
||||
auto transaction_specific = mTransactionBody->getTransactionBase();
|
||||
if (transaction_specific) {
|
||||
if (transaction_specific->prepare()) {
|
||||
getErrors(transaction_specific);
|
||||
addError(new Error("ProcessingTransaction", "error preparing"));
|
||||
reportErrorToCommunityServer(catalog->gettext("format error"), catalog->gettext("format of specific transaction not known, wrong proto version?"), Poco::DateTimeFormatter::format(mTransactionCreated, "%s"));
|
||||
unlock();
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return 0;
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_TASKS_PROCESSING_TRANSACTION_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_TASKS_PROCESSING_TRANSACTION_INCLUDE
|
||||
|
||||
#include "CPUTask.h"
|
||||
|
||||
#include "../lib/NotificationList.h"
|
||||
#include "../lib/DRHash.h"
|
||||
#include "../model/gradido/TransactionBody.h"
|
||||
|
||||
#include "../SingletonManager/LanguageManager.h"
|
||||
|
||||
/*
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 25.10.19
|
||||
* @desc: Task for processing Transactions
|
||||
*/
|
||||
|
||||
|
||||
namespace model {
|
||||
namespace gradido {
|
||||
class TransactionCreation;
|
||||
class TransactionTransfer;
|
||||
class GroupMemberUpdate;
|
||||
}
|
||||
}
|
||||
class SigningTransaction;
|
||||
|
||||
|
||||
class ProcessingTransaction : public UniLib::controller::CPUTask, public NotificationList
|
||||
{
|
||||
friend SigningTransaction;
|
||||
public:
|
||||
//! \param lang for error messages in user language
|
||||
ProcessingTransaction(const std::string& proto_message_base64, DHASH userEmailHash, Languages lang, Poco::DateTime transactionCreated = Poco::DateTime());
|
||||
ProcessingTransaction(Poco::AutoPtr<model::gradido::TransactionBody> transactionBody, DHASH userEmailHash, Languages lang, Poco::DateTime transactionCreated = Poco::DateTime());
|
||||
//ProcessingTransaction(const model::gradido::TransactionBody)
|
||||
virtual ~ProcessingTransaction();
|
||||
|
||||
int run();
|
||||
|
||||
const char* getResourceType() const { return "ProcessingTransaction"; };
|
||||
|
||||
|
||||
static HASH calculateHash(const std::string& proto_message_base64);
|
||||
static std::string calculateGenericHash(const std::string& protoMessageBase64);
|
||||
inline HASH getHash() { mHashMutex.lock(); HASH hs = mHash; mHashMutex.unlock(); return hs; }
|
||||
|
||||
inline Poco::AutoPtr<model::gradido::TransactionBody> getTransactionBody() { return mTransactionBody; }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void reportErrorToCommunityServer(std::string error, std::string errorDetails, std::string created);
|
||||
|
||||
|
||||
std::string mProtoMessageBase64;
|
||||
Poco::AutoPtr<model::gradido::TransactionBody> mTransactionBody;
|
||||
|
||||
|
||||
HASH mHash;
|
||||
DHASH mUserEmailHash;
|
||||
Languages mLang;
|
||||
Poco::Mutex mHashMutex;
|
||||
Poco::DateTime mTransactionCreated;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_TASKS_PROCESSING_TRANSACTION_INCLUDE
|
||||
@ -1,330 +0,0 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "SigningTransaction.h"
|
||||
|
||||
|
||||
#include <google/protobuf/text_format.h>
|
||||
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
#include "../SingletonManager/MemoryManager.h"
|
||||
#include "../SingletonManager/SingletonTaskObserver.h"
|
||||
|
||||
#include "../lib/Profiler.h"
|
||||
|
||||
#include "sodium.h"
|
||||
|
||||
#include "../ServerConfig.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/Net/HTTPSClientSession.h"
|
||||
#include "Poco/Net/HTTPRequest.h"
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
|
||||
// stuff for hedera transaction
|
||||
#include "../controller/HederaAccount.h"
|
||||
#include "../controller/HederaRequest.h"
|
||||
#include "../model/hedera/TransactionBody.h"
|
||||
#include "../model/hedera/Transaction.h"
|
||||
|
||||
SigningTransaction::SigningTransaction(
|
||||
Poco::AutoPtr<ProcessingTransaction> processingeTransaction,
|
||||
Poco::AutoPtr<controller::User> newUser,
|
||||
bool sendErrorsToAdmin/* = true*/)
|
||||
: mProcessingeTransaction(processingeTransaction), mNewUser(newUser), mSendErrorsToAdminEmail(sendErrorsToAdmin)
|
||||
{
|
||||
auto ob = SingletonTaskObserver::getInstance();
|
||||
auto email = getUserEmail();
|
||||
|
||||
if (email != "") {
|
||||
ob->addTask(email, TASK_OBSERVER_SIGN_TRANSACTION);
|
||||
}
|
||||
}
|
||||
|
||||
SigningTransaction::~SigningTransaction()
|
||||
{
|
||||
auto ob = SingletonTaskObserver::getInstance();
|
||||
auto email = getUserEmail();
|
||||
|
||||
if (email != "") {
|
||||
ob->removeTask(email, TASK_OBSERVER_SIGN_TRANSACTION);
|
||||
}
|
||||
}
|
||||
|
||||
std::string SigningTransaction::getUserEmail()
|
||||
{
|
||||
model::table::User* user_model = nullptr;
|
||||
|
||||
if (!mNewUser.isNull()) {
|
||||
user_model = mNewUser->getModel();
|
||||
}
|
||||
if (user_model) {
|
||||
return user_model->getEmail();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int SigningTransaction::run() {
|
||||
auto mm = MemoryManager::getInstance();
|
||||
|
||||
Error* transactionError = new Error("SigningTransaction", mProcessingeTransaction->mProtoMessageBase64.data());
|
||||
addError(transactionError, false);
|
||||
|
||||
//= new Error("SigningTransaction start", mProcessingeTransaction->g)
|
||||
//if (mUser.isNull() || !mUser->hasCryptoKey()) {
|
||||
if(mNewUser.isNull() || !mNewUser->hasPassword()) {
|
||||
addError(new Error("SigningTransaction", "user hasn't crypto key or is null"));
|
||||
if(mSendErrorsToAdminEmail) sendErrorsAsEmail();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//auto privKey = mUser->getPrivKey();
|
||||
//if (!mUser->hasPrivKey()) {
|
||||
auto gradido_key_pair = mNewUser->getGradidoKeyPair();
|
||||
KeyPairEd25519* recovered_gradido_key_pair = nullptr;
|
||||
if(!gradido_key_pair || !gradido_key_pair->hasPrivateKey()) {
|
||||
|
||||
if (!mNewUser->tryLoadPassphraseUserBackup(&recovered_gradido_key_pair)) {
|
||||
if(mNewUser->setGradidoKeyPair(recovered_gradido_key_pair))
|
||||
{
|
||||
mNewUser->getModel()->updatePrivkey();
|
||||
}
|
||||
}
|
||||
else {
|
||||
addError(new Error("SigningTransaction", "user cannot decrypt private key"));
|
||||
if (mSendErrorsToAdminEmail) sendErrorsAsEmail();
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
// get body bytes
|
||||
proto::gradido::GradidoTransaction transaction;
|
||||
auto bodyBytes = transaction.mutable_body_bytes();
|
||||
auto transaction_body = mProcessingeTransaction->getTransactionBody();
|
||||
if (!transaction_body.isNull()) {
|
||||
*bodyBytes = transaction_body->getBodyBytes();
|
||||
}
|
||||
if (*bodyBytes == "") {
|
||||
getErrors(mProcessingeTransaction);
|
||||
if (mSendErrorsToAdminEmail) sendErrorsAsEmail();
|
||||
return -3;
|
||||
}
|
||||
// sign
|
||||
//auto sign = mUser->sign((const unsigned char*)bodyBytes->data(), bodyBytes->size());
|
||||
MemoryBin* sign = nullptr;
|
||||
if (gradido_key_pair) {
|
||||
sign = gradido_key_pair->sign(*bodyBytes);
|
||||
}
|
||||
else if (recovered_gradido_key_pair) {
|
||||
sign = recovered_gradido_key_pair->sign(*bodyBytes);
|
||||
}
|
||||
if (!sign) {
|
||||
ErrorManager::getInstance()->sendErrorsAsEmail();
|
||||
if (mSendErrorsToAdminEmail) sendErrorsAsEmail();
|
||||
mm->releaseMemory(sign);
|
||||
return -4;
|
||||
}
|
||||
|
||||
// pubkey for signature
|
||||
/*auto pubkeyBin = mm->getFreeMemory(ed25519_pubkey_SIZE);
|
||||
size_t realBin = 0;
|
||||
if (sodium_hex2bin(*pubkeyBin, *pubkeyBin, pubkeyHex.data(), pubkeyHex.size(), nullptr, &realBin, nullptr)) {
|
||||
addError(new Error("SigningTransaction", "error in sodium_hex2bin"));
|
||||
sendErrorsAsEmail();
|
||||
mm->releaseMemory(pubkeyBin);
|
||||
mm->releaseMemory(sign);
|
||||
return -5;
|
||||
}
|
||||
*/
|
||||
// add to message
|
||||
auto sigMap = transaction.mutable_sig_map();
|
||||
auto sigPair = sigMap->add_sigpair();
|
||||
|
||||
auto pubkeyBytes = sigPair->mutable_pubkey();
|
||||
auto pubkeyBin = mNewUser->getModel()->getPublicKey();
|
||||
*pubkeyBytes = std::string((const char*)pubkeyBin, crypto_sign_PUBLICKEYBYTES);
|
||||
|
||||
|
||||
auto sigBytes = sigPair->mutable_ed25519();
|
||||
*sigBytes = std::string((char*)*sign, sign->size());
|
||||
mm->releaseMemory(sign);
|
||||
|
||||
/*std::string protoPrettyPrint;
|
||||
google::protobuf::TextFormat::PrintToString(transaction, &protoPrettyPrint);
|
||||
printf("transaction pretty: %s\n", protoPrettyPrint.data());
|
||||
proto::gradido::TransactionBody transactionBody;
|
||||
transactionBody.MergeFromString(transaction.bodybytes());
|
||||
google::protobuf::TextFormat::PrintToString(transactionBody, &protoPrettyPrint);
|
||||
printf("transaction body pretty: \n%s\n", protoPrettyPrint.data());
|
||||
*/
|
||||
// finalize
|
||||
//printf("sigpair size: %d\n", transaction.sigmap().sigpair_size());
|
||||
std::string finalTransactionBin = transaction.SerializeAsString();
|
||||
if (finalTransactionBin == "") {
|
||||
addError(new Error("SigningTransaction", "error serializing final transaction"));
|
||||
if (mSendErrorsToAdminEmail) sendErrorsAsEmail();
|
||||
return -6;
|
||||
}
|
||||
|
||||
auto network_type = ServerConfig::HEDERA_TESTNET;
|
||||
auto topic_id = controller::HederaId::find(1, network_type);
|
||||
auto hedera_operator_account = controller::HederaAccount::pick(network_type, false);
|
||||
|
||||
/*if (!topic_id.isNull() && !hedera_operator_account.isNull()) {
|
||||
auto crypto_key = hedera_operator_account->getCryptoKey();
|
||||
if (!crypto_key.isNull()) {
|
||||
model::hedera::ConsensusSubmitMessage consensus_submit_message(topic_id);
|
||||
consensus_submit_message.setMessage(finalTransactionBin);
|
||||
auto hedera_transaction_body = hedera_operator_account->createTransactionBody();
|
||||
hedera_transaction_body->setConsensusSubmitMessage(consensus_submit_message);
|
||||
model::hedera::Transaction hedera_transaction;
|
||||
hedera_transaction.sign(crypto_key->getKeyPair(), std::move(hedera_transaction_body));
|
||||
|
||||
HederaRequest hedera_request;
|
||||
HederaTask hedera_task;// placeholder
|
||||
if (HEDERA_REQUEST_RETURN_OK != hedera_request.request(&hedera_transaction, &hedera_task)) {
|
||||
addError(new Error("SigningTransaction", "error send transaction to hedera"));
|
||||
getErrors(&hedera_request);
|
||||
sendErrorsAsEmail();
|
||||
}
|
||||
else {
|
||||
auto hedera_precheck_code_string = hedera_task.getTransactionResponse()->getPrecheckCodeString();
|
||||
auto cost = hedera_task.getTransactionResponse()->getCost();
|
||||
printf("hedera response: %s, cost: %" PRIu64 "\n", hedera_precheck_code_string.data(), cost);
|
||||
}
|
||||
//model::hedera::TransactionBody hedera_transaction_body()
|
||||
}
|
||||
else {
|
||||
printf("[SigningTransaction] crypto key not found\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("[SigningTransaction] hedera topic id or operator account not found\n");
|
||||
}*/
|
||||
|
||||
// finale to base64
|
||||
auto finalBase64Size = sodium_base64_encoded_len(finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING);
|
||||
auto finalBase64Bin = mm->getFreeMemory(finalBase64Size);
|
||||
if (!sodium_bin2base64(*finalBase64Bin, finalBase64Size, (const unsigned char*)finalTransactionBin.data(), finalTransactionBin.size(), sodium_base64_VARIANT_URLSAFE_NO_PADDING)) {
|
||||
addError(new Error("SigningTransaction", "error convert final transaction to base64"));
|
||||
if (mSendErrorsToAdminEmail) sendErrorsAsEmail();
|
||||
mm->releaseMemory(finalBase64Bin);
|
||||
return -7;
|
||||
}
|
||||
addError(new Error("Signing transaction final", *finalBase64Bin), false);
|
||||
|
||||
// create json request
|
||||
|
||||
Poco::JSON::Object requestJson;
|
||||
requestJson.set("method", "putTransaction");
|
||||
requestJson.set("transaction", std::string((char*)*finalBase64Bin));
|
||||
//printf("\nbase64 transaction: \n%s\n\n", (char*)*finalBase64Bin);
|
||||
mm->releaseMemory(finalBase64Bin);
|
||||
|
||||
|
||||
//std::string request = requestJson.stringify();
|
||||
|
||||
// send post request via https
|
||||
// 443 = HTTPS Default
|
||||
// or http via port 80 if it is a test server
|
||||
// TODO: adding port into ServerConfig
|
||||
bool choose_ssl = false;
|
||||
try {
|
||||
Profiler phpRequestTime;
|
||||
Poco::Net::HTTPClientSession* clientSession = nullptr;
|
||||
|
||||
if (ServerConfig::g_phpServerPort) {
|
||||
clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, ServerConfig::g_phpServerPort);
|
||||
choose_ssl = true;
|
||||
}
|
||||
else if (ServerConfig::SERVER_TYPE_PRODUCTION == ServerConfig::g_ServerSetupType ||
|
||||
ServerConfig::SERVER_TYPE_STAGING == ServerConfig::g_ServerSetupType) {
|
||||
clientSession = new Poco::Net::HTTPSClientSession(ServerConfig::g_php_serverHost, 443);
|
||||
choose_ssl = true;
|
||||
}
|
||||
else {
|
||||
clientSession = new Poco::Net::HTTPClientSession(ServerConfig::g_php_serverHost, 80);
|
||||
choose_ssl = false;
|
||||
}
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler");
|
||||
|
||||
request.setChunkedTransferEncoding(true);
|
||||
std::ostream& requestStream = clientSession->sendRequest(request);
|
||||
requestJson.stringify(requestStream);
|
||||
|
||||
Poco::Net::HTTPResponse response;
|
||||
std::istream& request_stream = clientSession->receiveResponse(response);
|
||||
|
||||
// debugging answer
|
||||
|
||||
std::stringstream responseStringStream;
|
||||
for (std::string line; std::getline(request_stream, line); ) {
|
||||
responseStringStream << line << std::endl;
|
||||
}
|
||||
Poco::Logger& speedLog= Poco::Logger::get("SpeedLog");
|
||||
speedLog.information("[putTransaction] php server time: %s", phpRequestTime.string());
|
||||
|
||||
// extract parameter from request
|
||||
Poco::JSON::Parser jsonParser;
|
||||
Poco::Dynamic::Var parsedJson;
|
||||
try {
|
||||
parsedJson = jsonParser.parse(responseStringStream.str());
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
//printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data());
|
||||
addError(new ParamError("SigningTransaction", "error parsing request answer", ex.displayText().data()));
|
||||
|
||||
std::string log_Path = "/var/log/grd_login/";
|
||||
//#ifdef _WIN32
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
log_Path = "./";
|
||||
#endif
|
||||
log_Path += "response.html";
|
||||
FILE* f = fopen(log_Path.data(), "wt");
|
||||
if (f) {
|
||||
std::string responseString = responseStringStream.str();
|
||||
fwrite(responseString.data(), 1, responseString.size(), f);
|
||||
fclose(f);
|
||||
}
|
||||
// */
|
||||
if (mSendErrorsToAdminEmail) sendErrorsAsEmail(responseStringStream.str());
|
||||
return -9;
|
||||
}
|
||||
|
||||
//sendErrorsAsEmail("<html><head><title>Hallo</title></head><body><font color='red'>Rote Test </font></body>");
|
||||
|
||||
Poco::JSON::Object object = *parsedJson.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
std::string stateString = "";
|
||||
if (!object.isNull("state")) {
|
||||
auto state = object.get("state");
|
||||
stateString = state.convert<std::string>();
|
||||
}
|
||||
if (stateString != "success") {
|
||||
addError(new Error("SigningTransaction", "php server don't return success"));
|
||||
if (!object.isNull("msg")) {
|
||||
addError(new ParamError("SigningTransaction", "msg:", object.get("msg").convert<std::string>().data()));
|
||||
}
|
||||
if (!object.isNull("details")) {
|
||||
addError(new ParamError("SigningTransaction", "details:", object.get("details").convert<std::string>().data()));
|
||||
}
|
||||
if (!object.isNull("user_error")) {
|
||||
addError(new ParamError("SigningTransaction", "user_error", object.get("user_error").convert<std::string>().data()));
|
||||
}
|
||||
if (mSendErrorsToAdminEmail) sendErrorsAsEmail();
|
||||
return -10;
|
||||
}
|
||||
delete clientSession;
|
||||
//printf("state: %s\n", stateString.data());
|
||||
//int zahl = 1;
|
||||
}
|
||||
catch (Poco::Exception& e) {
|
||||
addError(new ParamError("SigningTransaction", "connect error to php server", e.displayText().data()));
|
||||
addError(new ParamError("SigningTransaction", "url", ServerConfig::g_php_serverHost.data()));
|
||||
addError(new ParamError("SigningTransaction", "choose_ssl", choose_ssl));
|
||||
if (mSendErrorsToAdminEmail) sendErrorsAsEmail();
|
||||
return -8;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
#ifndef GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE
|
||||
#define GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE
|
||||
|
||||
#include "CPUTask.h"
|
||||
|
||||
#include "../lib/NotificationList.h"
|
||||
#include "../controller/User.h"
|
||||
|
||||
#include "../proto/gradido/GradidoTransaction.pb.h"
|
||||
|
||||
#include "ProcessingTransaction.h"
|
||||
|
||||
/*
|
||||
* @author: Dario Rekowski
|
||||
*
|
||||
* @date: 28.10.19
|
||||
* @desc: Task for signing Transactions
|
||||
*/
|
||||
|
||||
class SigningTransaction : public UniLib::controller::CPUTask, public NotificationList
|
||||
{
|
||||
public:
|
||||
SigningTransaction(Poco::AutoPtr<ProcessingTransaction> processingeTransaction, Poco::AutoPtr<controller::User> newUser, bool sendErrorsToAdmin = true);
|
||||
virtual ~SigningTransaction();
|
||||
|
||||
int run();
|
||||
|
||||
const char* getResourceType() const { return "SigningTransaction"; };
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
Poco::AutoPtr<ProcessingTransaction> mProcessingeTransaction;
|
||||
Poco::AutoPtr<controller::User> mNewUser;
|
||||
bool mSendErrorsToAdminEmail;
|
||||
|
||||
private:
|
||||
|
||||
std::string getUserEmail();
|
||||
|
||||
};
|
||||
|
||||
#endif //GRADIDO_LOGIN_SERVER_TASKS_SIGNING_TRANSACTION_INCLUDE
|
||||
@ -1,350 +0,0 @@
|
||||
<%@ page class="AdminHederaAccountPage" %>
|
||||
<%@ page form="true" %>
|
||||
<%@ page baseClass="SessionHTTPRequestHandler" %>
|
||||
<%@ page ctorArg="Session*" %>
|
||||
<%@ header include="HTTPInterface/SessionHTTPRequestHandler.h" %>
|
||||
<%!
|
||||
|
||||
#include "controller/HederaAccount.h"
|
||||
#include "controller/HederaId.h"
|
||||
#include "controller/CryptoKey.h"
|
||||
#include "lib/DataTypeConverter.h"
|
||||
#include "lib/Profiler.h"
|
||||
#include "lib/Success.h"
|
||||
#include "SingletonManager/SessionManager.h"
|
||||
|
||||
#include "ServerConfig.h"
|
||||
|
||||
#include "Poco/URI.h"
|
||||
|
||||
%>
|
||||
<%%
|
||||
const char* pageName = "Hedera Account";
|
||||
auto sm = SessionManager::getInstance();
|
||||
auto mm = MemoryManager::getInstance();
|
||||
auto user = mSession->getNewUser();
|
||||
int auto_renew_period = 604800; // 7 Tage
|
||||
int auto_renew_account = 0;
|
||||
double initial_balance = 0.0;
|
||||
Profiler hedera_time;
|
||||
std::string hedera_time_string;
|
||||
|
||||
Poco::URI uri(request.getURI());
|
||||
auto uri_query = uri.getQueryParameters();
|
||||
std::string action = "";
|
||||
Poco::AutoPtr<controller::HederaAccount> query_hedera_account;
|
||||
|
||||
// parsing get query params
|
||||
if(uri_query.size() >= 2) {
|
||||
if(uri_query[0].first == "action") {
|
||||
action = uri_query[0].second;
|
||||
}
|
||||
if(uri_query[1].first == "account_id") {
|
||||
std::string account_id_from_query;
|
||||
int account_id = 0;
|
||||
account_id_from_query = uri_query[1].second;
|
||||
if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting account_id_from_query to int"));
|
||||
} else {
|
||||
auto hedera_accounts = controller::HederaAccount::load("id", account_id);
|
||||
if(!hedera_accounts.size() || hedera_accounts[0].isNull()) {
|
||||
addError(new Error("Action", "hedera account not found"));
|
||||
} else {
|
||||
query_hedera_account = hedera_accounts[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// actions
|
||||
if(!query_hedera_account.isNull())
|
||||
{
|
||||
if(action == "updateBalance")
|
||||
{
|
||||
hedera_time.reset();
|
||||
if(query_hedera_account->hederaAccountGetBalance(user)) {
|
||||
addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string()));
|
||||
} else {
|
||||
addError(new ParamError("Hedera", "crypto get balance failed in ", hedera_time.string()));
|
||||
}
|
||||
}
|
||||
else if(action == "changeEncryption")
|
||||
{
|
||||
if(query_hedera_account->changeEncryption(user)) {
|
||||
addNotification(new Success("Hedera Account", "success in changing encryption"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!form.empty()) // add or create
|
||||
{
|
||||
auto creationButton = form.get("create","");
|
||||
if(creationButton != "") {
|
||||
|
||||
// collect
|
||||
auto auto_renew_account_string = form.get("account-auto-renew-account", "0");
|
||||
auto auto_renew_period_string = form.get("account-auto-renew-period", "604800");
|
||||
auto account_initial_balance_string = form.get("account-initial-balance", "0");
|
||||
|
||||
if(!sm->isValid(auto_renew_account_string, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Account", "auto renew account id not an integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(auto_renew_account_string, auto_renew_account) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int convert error", "Error converting auto renew account id to int"));
|
||||
}
|
||||
}
|
||||
|
||||
if(!sm->isValid(auto_renew_period_string, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Account", "auto renew period not an integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(auto_renew_period_string, auto_renew_period) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int convert error", "Error converting auto renew period to int"));
|
||||
}
|
||||
}
|
||||
|
||||
if(!sm->isValid(account_initial_balance_string, VALIDATE_ONLY_DECIMAL)) {
|
||||
addError(new Error("Account", "initial balance not an decimal"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToDouble(account_initial_balance_string, initial_balance) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Double convert error", "Error converting initial balance to double"));
|
||||
}
|
||||
}
|
||||
if(0 == errorCount())
|
||||
{
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// collect
|
||||
auto shardNumString = form.get("account-shard-num", "0");
|
||||
auto realmNumString = form.get("account-realm-num", "0");
|
||||
auto numString = form.get("account-num", "0");
|
||||
auto privateKeyString = form.get("account-private-key", "");
|
||||
auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false");
|
||||
auto publicKeyString = form.get("account-public-key", "");
|
||||
auto networkTypeString = form.get("account-network-type", "0");
|
||||
|
||||
//printf("private key encrypted: %s\n", privateKeyEncryptedString.data());
|
||||
|
||||
int shardNum = 0;
|
||||
int realmNum = 0;
|
||||
int num = 0;
|
||||
int networkType = 0;
|
||||
|
||||
MemoryBin* private_key = nullptr;
|
||||
MemoryBin* public_key = nullptr;
|
||||
|
||||
// validate
|
||||
if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Account ID", "shard num not integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting shardNumString to int"));
|
||||
}
|
||||
}
|
||||
if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Account ID", "realm num not integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting realmNumString to int"));
|
||||
}
|
||||
}
|
||||
if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Account ID", "num not integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting num to int"));
|
||||
}
|
||||
}
|
||||
if(!sm->isValid(privateKeyString, VALIDATE_ONLY_HEX)) {
|
||||
addError(new Error("Account Keys", "private key not hex"));
|
||||
}
|
||||
if(!sm->isValid(publicKeyString, VALIDATE_ONLY_HEX)) {
|
||||
addError(new Error("Account Keys", "public key not hex"));
|
||||
}
|
||||
if(!sm->isValid(networkTypeString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Network Type", "not integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(networkTypeString, networkType) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting network type to int"));
|
||||
}
|
||||
if(networkType < 0 || networkType >= (int)ServerConfig::HEDERA_NET_COUNT) {
|
||||
addError(new Error("Network Type", "invalid value"));
|
||||
}
|
||||
}
|
||||
|
||||
if(0 == errorCount()) {
|
||||
|
||||
auto hedera_id = controller::HederaId::create(shardNum, realmNum, num);
|
||||
|
||||
private_key = DataTypeConverter::hexToBin(privateKeyString);
|
||||
public_key = DataTypeConverter::hexToBin(publicKeyString);
|
||||
|
||||
|
||||
KeyPairHedera key_pair(private_key, public_key);
|
||||
auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), crypto_sign_PUBLICKEYBYTES);
|
||||
|
||||
if(crypto_key.isNull()) {
|
||||
crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true");
|
||||
if(!crypto_key->getModel()->insertIntoDB(true)) {
|
||||
addError(new Error("DB Error", "Error saving crypto key in DB"));
|
||||
}
|
||||
} else {
|
||||
printf("crypto key found in db\n");
|
||||
}
|
||||
if(0 == errorCount()) {
|
||||
|
||||
if(hedera_id->isExistInDB()) {
|
||||
auto hedera_account = controller::HederaAccount::load(hedera_id);
|
||||
if(hedera_account.isNull()) {
|
||||
addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist"));
|
||||
} else {
|
||||
addError(new Error("Hedera Account", "Account already exist (same account id"));
|
||||
}
|
||||
|
||||
} else {
|
||||
auto hedera_account = controller::HederaAccount::create(
|
||||
user->getModel()->getID(),
|
||||
hedera_id->getModel()->getID(),
|
||||
crypto_key->getModel()->getID(),
|
||||
0,
|
||||
(ServerConfig::HederaNetworkType)networkType
|
||||
);
|
||||
if(!hedera_account->getModel()->insertIntoDB(false)) {
|
||||
addError(new Error("DB Error", "Error saving hedera account into DB"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mm->releaseMemory(private_key);
|
||||
mm->releaseMemory(public_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!query_hedera_account.isNull()) {
|
||||
getErrors(query_hedera_account);
|
||||
}
|
||||
// list accounts
|
||||
auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID());
|
||||
|
||||
%><%@ include file="include/header_large.cpsp" %>
|
||||
<style type="text/css">
|
||||
.center-form-form .input-40 {
|
||||
margin-left:0;
|
||||
width:40%;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
</style>
|
||||
<%= getErrorsHtml() %>
|
||||
|
||||
<div class="center-form-container">
|
||||
<div class="content-list">
|
||||
<div class="content-list-title">
|
||||
<h2>Deine Hedera Accounts</h2>
|
||||
</div>
|
||||
<div class="content-list-table">
|
||||
<div class="row">
|
||||
<div class="cell header-cell c2">Hedera Id</div>
|
||||
<div class="cell header-cell c3">Balance</div>
|
||||
<div class="cell header-cell c2">Server Type</div>
|
||||
<div class="cell header-cell c3">Verschlüsselt?</div>
|
||||
<div class="cell header-cell c3">Last Updated</div>
|
||||
<div class="cell header-cell c5">Aktionen</div>
|
||||
</div>
|
||||
<% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) {
|
||||
auto hedera_account_model = (*it)->getModel();
|
||||
auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID());
|
||||
std::string changeEncryption("");
|
||||
if(hedera_account_model->getUserId() == user->getModel()->getID()) {
|
||||
changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID());
|
||||
}
|
||||
auto isEncrypted = (*it)->getCryptoKey()->getModel()->isEncrypted();
|
||||
//printf("change encryption: %s\n", changeEncryption.data());
|
||||
|
||||
std::string kabuto_url = "https://explorer.kabuto.sh/";;
|
||||
|
||||
if(hedera_account_model->getNetworkType() == ServerConfig::HEDERA_TESTNET) {
|
||||
kabuto_url += "testnet/";
|
||||
} else if(hedera_account_model->getNetworkType() == ServerConfig::HEDERA_MAINNET) {
|
||||
kabuto_url += "mainnet/";
|
||||
}
|
||||
kabuto_url += "id/";
|
||||
auto hedera_id_string = (*it)->getHederaId()->getModel()->toString();
|
||||
kabuto_url += hedera_id_string;
|
||||
%>
|
||||
<div class="row">
|
||||
<div class="cell c2"><a href="<%= kabuto_url %>" title="Hedera Block Explorer - Kabuto" target="_blank"><%= hedera_id_string %></a></div>
|
||||
<div class="cell c3"><%= hedera_account_model->getBalanceString() %></div>
|
||||
<div class="cell c2"><%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %></div>
|
||||
<div class="cell c3 <%= isEncrypted ? "success-color" : "alert-color"%>"><%= isEncrypted ? "Ja": "Nein" %></div>
|
||||
<div class="cell c3"><%= hedera_account_model->getUpdatedString() %></div>
|
||||
<div class="cell c5">
|
||||
<button class="form-button" title="Anfrage an Hedera, aktuell kostenlos" onclick="window.location.href='<%= updateUrl %>'" >
|
||||
Update Balance
|
||||
</button>
|
||||
<% if(changeEncryption != "") { %>
|
||||
<button class="form-button" title="Ändere den Verschlüsselungsstatus des Private Keys in der Datenbank" onclick="window.location.href='<%= changeEncryption %>'">
|
||||
Change Encryption
|
||||
</button>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center-form-title">
|
||||
<h3>Ein existierenden Account eintragen</h3>
|
||||
</div>
|
||||
<div class="center-form-form">
|
||||
<form method="POST" action="<%= ServerConfig::g_serverPath %>/hedera_account">
|
||||
<label class="form-label">Hedera Account ID</label>
|
||||
<input class="form-control" id="account-shard-num" placeholder="shard" type="number" name="account-shard-num"/>
|
||||
<input class="form-control" id="account-realm-num" placeholder="realm" type="number" name="account-realm-num"/>
|
||||
<input class="form-control" id="account-num" placeholder="num" type="number" name="account-num"/>
|
||||
<label class="form-label" for="account-private-key">Private Key</label>
|
||||
<input class="form-control" id="account-private-key" type="text" name="account-private-key"/>
|
||||
<label class="form-label" for="account-private-key-encrypted" title="Wenn er verschlüsselt ist, kannst nur du Hedera Transaktionen damit bezahlen, wenn er nicht verschlüsselt ist kann er für alle Hedera Transaktionen automatisch verwendet werden. Ich empfehle dafür ein separates Konto mit wenigen Hashbars anzulegen.">Private Key verschlüsseln?</label>
|
||||
<input class="form-control" id="account-private-key-encrypted" type="checkbox" name="account-private-key-encrypted" value="true"/>
|
||||
<label class="form-label" for="account-public-key">Public Key</label>
|
||||
<input class="form-control" id="account-public-key" type="text" name="account-public-key"/>
|
||||
<label class="form-label" for="account-network-type">Network Type</label>
|
||||
<select class="form-control" name="account-network-type" id="account-network-type">
|
||||
<% for(int i = 0; i < ServerConfig::HEDERA_NET_COUNT; i++) { %>
|
||||
<option value="<%= i %>"><%= model::table::HederaAccount::hederaNetworkTypeToString((ServerConfig::HederaNetworkType)i) %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
<input class="center-form-submit form-button" type="submit" name="add" value="<%= gettext("Add Account") %>">
|
||||
</form>
|
||||
</div>
|
||||
<div class="center-form-title">
|
||||
<h3>Ein neuen Account anlegen</h3>
|
||||
<p>Bei Hedera einen neuen Account anlegen und zum Start Hashbars von einem existierenden Account überweisen.</p>
|
||||
</div>
|
||||
<div class="center-form-form">
|
||||
<form method="POST" action="<%= ServerConfig::g_serverPath %>/hedera_account">
|
||||
<label class="form-label" for="account-auto-renew-account">Auto Renew and Founding Hedera Account</label>
|
||||
<select name="account-auto-renew-account" id="account-auto-renew-account">
|
||||
<% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) {
|
||||
auto model = (*it)->getModel();
|
||||
%>
|
||||
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(auto_renew_account == model->getID()) {%>selected="selected"<% } %>><%= (*it)->toShortSelectOptionName() %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
<label class="form-label" for="account-auto-renew-period">Auto Renew Period in seconds</label>
|
||||
<div><input class="form-control input-40" id="account-auto-renew-period" value="<%= auto_renew_period %>" type="number" name="account-auto-renew-period"/><span style="margin-left:8px" id="readable-auto-renew-period"></span><div>
|
||||
<label class="form-label" for="account-initial-balance">Initial Balance for new Account (taken from founding account)</label>
|
||||
<input class="form-control" id="account-initial-balance" name="account-initial-balance" type="number" step="0.00000001" value="<%= std::to_string(initial_balance) %>" />
|
||||
<input class="center-form-submit form-button" type="submit" name="create" value="<%= gettext("Create Account") %>">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<%@ include file="include/footer.cpsp" %>
|
||||
<script type="text/javascript" src="<%= ServerConfig::g_php_serverPath %>/js/time_calculations.js"></script>
|
||||
<script type="text/javascript">
|
||||
var input = document.getElementById("account-auto-renew-period");
|
||||
var span = document.getElementById("readable-auto-renew-period");
|
||||
span.innerHTML = '~ ' + getExactTimeDuration(input.value);
|
||||
input.addEventListener('keyup', function(e) {
|
||||
span.innerHTML = '~ ' + getExactTimeDuration(input.value);
|
||||
});
|
||||
|
||||
</script>
|
||||
@ -1,20 +0,0 @@
|
||||
<%@ page class="AdminHederaTopicPage" %>
|
||||
<%@ page form="true" %>
|
||||
<%@ page baseClass="SessionHTTPRequestHandler" %>
|
||||
<%@ page ctorArg="Session*" %>
|
||||
<%@ header include="HTTPInterface/SessionHTTPRequestHandler.h" %>
|
||||
<%!
|
||||
|
||||
|
||||
%>
|
||||
<%%
|
||||
const char* pageName = "Admin Hedera Topic";
|
||||
|
||||
|
||||
%><%@ include file="include/header_old.cpsp" %>
|
||||
<div class="grd_container">
|
||||
<h1>Admin Hedera Topic</h1>
|
||||
<%= getErrorsHtml() %>
|
||||
|
||||
</div>
|
||||
<%@ include file="include/footer.cpsp" %>
|
||||
@ -1,200 +0,0 @@
|
||||
<%@ page class="AdminNodeServerPage" %>
|
||||
<%@ page form="true" %>
|
||||
<%@ page baseClass="SessionHTTPRequestHandler" %>
|
||||
<%@ page ctorArg="Session*" %>
|
||||
<%@ header include="HTTPInterface/SessionHTTPRequestHandler.h" %>
|
||||
<%!
|
||||
|
||||
#include "controller/NodeServer.h"
|
||||
#include "controller/Group.h"
|
||||
#include "SingletonManager/SessionManager.h"
|
||||
#include "lib/DataTypeConverter.h"
|
||||
|
||||
%>
|
||||
<%%
|
||||
const char* pageName = "Node Server";
|
||||
auto sm = SessionManager::getInstance();
|
||||
auto user = mSession->getNewUser();
|
||||
|
||||
// add
|
||||
if(!form.empty()) {
|
||||
// collect
|
||||
auto url = form.get("node-server-url", "");
|
||||
auto portString = form.get("node-server-port", "");
|
||||
auto nodeServerTypeString = form.get("node-server-type", "0");
|
||||
auto shardNumString = form.get("account-shard-num", "0");
|
||||
auto realmNumString = form.get("account-realm-num", "0");
|
||||
auto numString = form.get("account-num", "0");
|
||||
auto nodeServerGroupString = form.get("node-server-group", "");
|
||||
|
||||
int port = 0;
|
||||
int shardNum = 0;
|
||||
int realmNum = 0;
|
||||
int num = 0;
|
||||
model::table::NodeServerType nodeServerType = model::table::NODE_SERVER_NONE;
|
||||
int group_id = 0;
|
||||
|
||||
|
||||
// validate
|
||||
if(!sm->isValid(url, VALIDATE_ONLY_URL)) {
|
||||
addError(new ParamError("Node Server", "Url not valid, must start with http or https", url));
|
||||
|
||||
}
|
||||
if(!sm->isValid(portString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Node Server", "Port isn't valid integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(portString, port) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int convert error", "Error converting port to int"));
|
||||
}
|
||||
}
|
||||
|
||||
if(!sm->isValid(nodeServerTypeString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Node Server Type", "not integer"));
|
||||
} else {
|
||||
int node_server_type_int = 0;
|
||||
if(DataTypeConverter::strToInt(nodeServerTypeString, node_server_type_int) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting node server type to int"));
|
||||
}
|
||||
if(node_server_type_int < 0 || node_server_type_int >= (int)model::table::NODE_SERVER_TYPE_COUNT) {
|
||||
addError(new Error("Node Server Type", "invalid value"));
|
||||
} else {
|
||||
nodeServerType = (model::table::NodeServerType)node_server_type_int;
|
||||
}
|
||||
}
|
||||
if(model::table::NodeServerIsHederaNode(nodeServerType)) {
|
||||
|
||||
if(!sm->isValid(shardNumString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Account ID", "shard num not integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(shardNumString, shardNum) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting shardNumString to int"));
|
||||
}
|
||||
}
|
||||
if(!sm->isValid(realmNumString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Account ID", "realm num not integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(realmNumString, realmNum) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting realmNumString to int"));
|
||||
}
|
||||
}
|
||||
if(!sm->isValid(numString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Account ID", "num not integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(numString, num) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting num to int"));
|
||||
}
|
||||
}
|
||||
} else if(model::table::NodeServerHasGroup(nodeServerType)) {
|
||||
if(!sm->isValid(nodeServerGroupString, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Group id", "group_id not integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(nodeServerGroupString, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting group_id to int"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(0 == errorCount()) {
|
||||
int hedera_id_int = 0;
|
||||
if(NodeServerIsHederaNode(nodeServerType)) {
|
||||
auto hedera_id = controller::HederaId::create(shardNum, realmNum, num);
|
||||
hedera_id_int = hedera_id->getModel()->getID();
|
||||
}
|
||||
|
||||
auto node_server = controller::NodeServer::create(
|
||||
url, port, group_id, (model::table::NodeServerType)nodeServerType, hedera_id_int
|
||||
);
|
||||
if(!node_server->getModel()->insertIntoDB(false)) {
|
||||
addError(new Error("DB Error", "Error saving Node Server in DB"));
|
||||
}
|
||||
}
|
||||
}
|
||||
auto groups = controller::Group::listAll();
|
||||
std::map<int, int> group_indices;
|
||||
int count = 0;
|
||||
for(auto it = groups.begin(); it != groups.end(); it++) {
|
||||
group_indices.insert(std::pair<int, int>((*it)->getModel()->getID(), count));
|
||||
count++;
|
||||
}
|
||||
|
||||
auto node_servers = controller::NodeServer::listAll();
|
||||
|
||||
|
||||
%><%@ include file="include/header_large.cpsp" %>
|
||||
<%= getErrorsHtml() %>
|
||||
<div class="center-form-container">
|
||||
<div class="content-list">
|
||||
<div class="content-list-title">
|
||||
<h2>Alle Node Server</h2>
|
||||
</div>
|
||||
<div class="content-list-table">
|
||||
<div class="row">
|
||||
<div class="cell header-cell c4">Server Type</div>
|
||||
<div class="cell header-cell c5">Url:Port</div>
|
||||
<div class="cell header-cell c3">Group / Hedera Id</div>
|
||||
</div>
|
||||
<% for(auto it = node_servers.begin(); it != node_servers.end(); it++) {
|
||||
auto node_server_model = (*it)->getModel();
|
||||
%>
|
||||
<div class="row">
|
||||
<div class="cell c4"><%= model::table::NodeServer::nodeServerTypeToString(node_server_model->getNodeServerType()) %></div>
|
||||
<div class="cell c5"><%= node_server_model->getUrlWithPort() %></div>
|
||||
<div class="cell c3">
|
||||
<% if(node_server_model->isHederaNode()) {
|
||||
auto hedera_id_model = (*it)->getHederaId()->getModel(); %>
|
||||
<%= hedera_id_model->toString() %>
|
||||
<% } else if(node_server_model->hasGroup()){
|
||||
auto groupIt = group_indices.find(node_server_model->getGroupId());
|
||||
if(groupIt != group_indices.end()) {
|
||||
auto group_model = groups[groupIt->second]->getModel(); %>
|
||||
<span title="<%= group_model->getDescription() %>"><%= group_model->getName() %></span>
|
||||
<% } else { %>
|
||||
<%= node_server_model->getGroupId() %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center-form-title">
|
||||
<h3>Ein Node Server hinzufügen</h3>
|
||||
</div>
|
||||
<div class="center-form-form">
|
||||
<form method="POST">
|
||||
<label class="form-label" for="node-server-url">URL</label>
|
||||
<input required class="form-control" id="node-server-url" name="node-server-url"/>
|
||||
<label class="form-label" for="node-server-port">Port</label>
|
||||
<input required class="form-control" id="node-server-port" name="node-server-port" type="number"/>
|
||||
<label class="form-label" for="node-server-type">Network Type</label>
|
||||
<select class="form-control" name="node-server-type" id="node-server-type">
|
||||
<% for(int i = 1; i < model::table::NODE_SERVER_TYPE_COUNT; i++) { %>
|
||||
<option value="<%= i %>"><%= model::table::NodeServer::nodeServerTypeToString((model::table::NodeServerType)i) %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
<fieldset>
|
||||
<legend>Nur für Hedera Nodes</legend>
|
||||
<label class="form-label">Hedera Account ID</label>
|
||||
<input class="form-control" id="account-shard-num" placeholder="shard" type="number" name="account-shard-num"/>
|
||||
<input class="form-control" id="account-realm-num" placeholder="realm" type="number" name="account-realm-num"/>
|
||||
<input class="form-control" id="account-num" placeholder="num" type="number" name="account-num"/>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Nur für Gradido Nodes</legend>
|
||||
<label class="form-label" for="node-server-group">Gradido Gruppe</label>
|
||||
<select class="form-control" name="node-server-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() %>"><%= group_model->getName() %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</fieldset>
|
||||
|
||||
<input class="center-form-submit form-button" type="submit" name="submit" value="<%= gettext("Add Node") %>">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<%@ include file="include/footer.cpsp" %>
|
||||
@ -1,423 +0,0 @@
|
||||
<%@ page class="AdminNodeServerTestPage" %>
|
||||
<%@ page form="true" %>
|
||||
<%@ page baseClass="PageRequestMessagedHandler" %>
|
||||
<%@ header include="HTTPInterface/PageRequestMessagedHandler.h" %>
|
||||
<%!
|
||||
|
||||
#include "controller/NodeServer.h"
|
||||
#include "controller/User.h"
|
||||
#include "controller/HederaTopic.h"
|
||||
#include "lib/DataTypeConverter.h"
|
||||
#include "lib/Profiler.h"
|
||||
#include "lib/JsonRPCRequest.h"
|
||||
#include "model/gradido/Transaction.h"
|
||||
|
||||
#include "Poco/Thread.h"
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
|
||||
enum PageType
|
||||
{
|
||||
PAGE_CHOOSE_TEST,
|
||||
PAGE_RUN_4_SET_TEST,
|
||||
PAGE_GET_TRANSACTION_RPC_CALL
|
||||
};
|
||||
|
||||
%>
|
||||
<%%
|
||||
const char* pageName = "Node Server Test";
|
||||
PageType page = PAGE_CHOOSE_TEST;
|
||||
Poco::AutoPtr<controller::NodeServer> node_server;
|
||||
Poco::AutoPtr<controller::NodeServer> node_server2;
|
||||
Poco::AutoPtr<controller::User> user;
|
||||
Poco::AutoPtr<controller::HederaTopic> hedera_topic;
|
||||
Poco::AutoPtr<controller::HederaTopic> hedera_topic2;
|
||||
int hedera_timeout = 4;
|
||||
int sleep_ms_between_transactions = 1000;
|
||||
|
||||
bool steps[8]; memset(steps, 1, 8 * sizeof(bool));
|
||||
|
||||
|
||||
if(!form.empty())
|
||||
{
|
||||
auto node_server_id_string = form.get("test-node-servers", "");
|
||||
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_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;
|
||||
if(DataTypeConverter::NUMBER_PARSE_OKAY == DataTypeConverter::strToInt(topic_id_string, topic_id)) {
|
||||
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 test_part_timeout_string = form.get("test-part-timeout", "");
|
||||
if(test_part_timeout_string != "") {
|
||||
DataTypeConverter::strToInt(test_part_timeout_string, sleep_ms_between_transactions);
|
||||
}
|
||||
auto submit = form.get("submit", "");
|
||||
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 < 8; i++) {
|
||||
std::string name = "step-";
|
||||
name += std::to_string(i+2);
|
||||
step_temp = form.get(name, "");
|
||||
if(step_temp == "1") {
|
||||
steps[i] = true;
|
||||
} else {
|
||||
steps[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto node_servers = controller::NodeServer::load(model::table::NODE_SERVER_GRADIDO_NODE);
|
||||
auto hedera_topics = controller::HederaTopic::listAll();
|
||||
|
||||
%><%@ include file="include/header_large.cpsp" %>
|
||||
<%= getErrorsHtml() %>
|
||||
<div class="center-form-container">
|
||||
<!-- Tab links -->
|
||||
<div class="tab">
|
||||
<button class="tablinks <% if(PAGE_RUN_4_SET_TEST == page) { %> active <% } %>" onclick="openTab(event, 'test-4')">Test 6-Set (3 AddMember, Creation, 2 Transfer)</button>
|
||||
<button class="tablinks <% if(PAGE_GET_TRANSACTION_RPC_CALL == page) { %> active <% } %>" onclick="openTab(event, 'gn-jsonrpc')" title="call via json-rpc to gradido node with getTransactions">getTransactions</button>
|
||||
</div>
|
||||
<div id="test-4" class="tabcontent" <% if(PAGE_RUN_4_SET_TEST == page) { %> style="display:block" <% } %>>
|
||||
<div class="center-form-title">
|
||||
<h3>Test 6-Set (3 AddMember, Creation, 2 Transfer)</</h3>
|
||||
</div>
|
||||
<div class="center-form-form">
|
||||
<form method="POST" action="<%= getBaseUrl() %>/adminNodeServerTest">
|
||||
<p>1. Create three new accounts and show user public keys for comparisation</p>
|
||||
<p><input class="form-checkbox" type="checkbox" <% if(steps[0]) { %> checked="checked" <% } %> name="step-2" value="1"/> 2. Send a add-member transaction to hedera topic with one signature (first user)</p>
|
||||
<p><input class="form-checkbox" type="checkbox" <% if(steps[1]) { %> checked="checked" <% } %> name="step-3" value="1"/> 3. Send a add-member transaction to hedera topic with two signatures (first user and second user)</p>
|
||||
<p><input class="form-checkbox" type="checkbox" <% if(steps[2]) { %> checked="checked" <% } %> name="step-4" value="1"/> 4. Send a creation transaction to second user, signed by first user</p>
|
||||
<p><input class="form-checkbox" type="checkbox" <% if(steps[3]) { %> checked="checked" <% } %> name="step-5" value="1"/> 5. Send a transfer transaction from second user to first user signed by second user</p>
|
||||
<p><input class="form-checkbox" type="checkbox" <% if(steps[4]) { %> checked="checked" <% } %> name="step-6" value="1"/> 6. Send a add-member transaction to hedera topic 2 with one signature (third user)</p>
|
||||
<p><input class="form-checkbox" type="checkbox" <% if(steps[5]) { %> checked="checked" <% } %> name="step-7" value="1"/> 7. Send a cross group transfer from second user to third user signed by second user</p>
|
||||
<p><input class="form-checkbox" type="checkbox" <% if(steps[6]) { %> checked="checked" <% } %> name="step-8" value="1"/> 8. Wait x seconds to give hedera time to process transactions</p>
|
||||
<p><input class="form-checkbox" type="checkbox" <% if(steps[7]) { %> checked="checked" <% } %> name="step-9" value="1"/> 9. Ask choosen node for transaction and print result</p>
|
||||
<fieldset>
|
||||
<legend>Group 1 </legend>
|
||||
<label class="form-label" for="test-node-servers">Node Server for tests</label>
|
||||
<% if(node_servers.size() == 0) { %>
|
||||
<a href="<%= getBaseUrl() %>/nodes"><span class="link-title">Edit Node-Servers</span></a>
|
||||
<% } %>
|
||||
<select name="test-node-servers" id="test-node-servers">
|
||||
<% for(auto it = node_servers.begin(); it != node_servers.end(); it++) {
|
||||
auto model = (*it)->getModel();
|
||||
%>
|
||||
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!node_server.isNull() && node_server->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getUrlWithPort() %>, group: <%= model->getGroupId() %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
<label class="form-label" for="test-hedera-topic">Hedera Topic for tests</label>
|
||||
<% if(hedera_topics.size() == 0) { %>
|
||||
<a href="<%= getBaseUrl() %>/topic"><span class="link-title">Edit Hedera-Topics</span></a>
|
||||
<% } %>
|
||||
<select name="test-hedera-topic" id="test-hedera-topic">
|
||||
<% 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;
|
||||
}
|
||||
%>
|
||||
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!hedera_topic.isNull() && hedera_topic->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getName() %>, group: <%= model->getGroupId() %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Group 2 </legend>
|
||||
<label class="form-label" for="test-node-servers2">Node Server for tests</label>
|
||||
<% if(node_servers.size() == 0) { %>
|
||||
<a href="<%= getBaseUrl() %>/nodes"><span class="link-title">Edit Node-Servers</span></a>
|
||||
<% } %>
|
||||
<select name="test-node-servers2" id="test-node-servers2">
|
||||
<% for(auto it = node_servers.begin(); it != node_servers.end(); it++) {
|
||||
auto model = (*it)->getModel();
|
||||
%>
|
||||
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!node_server2.isNull() && node_server2->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getUrlWithPort() %>, group: <%= model->getGroupId() %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
<label class="form-label" for="test-hedera-topic2">Hedera Topic for tests</label>
|
||||
<% if(hedera_topics.size() == 0) { %>
|
||||
<a href="<%= getBaseUrl() %>/topic"><span class="link-title">Edit Hedera-Topics</span></a>
|
||||
<% } %>
|
||||
<select name="test-hedera-topic2" id="test-hedera-topic2">
|
||||
<% 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;
|
||||
}
|
||||
%>
|
||||
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!hedera_topic2.isNull() && hedera_topic2->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getName() %>, group: <%= model->getGroupId() %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</fieldset>
|
||||
|
||||
<label class="form-label" for="test-timeout">Timeout waiting for hedera in seconds</label>
|
||||
<input name="test-timeout" id="test-timeout" type="number" value="<%= hedera_timeout %>"> seconds
|
||||
<label class="form-label" for="test-part-timeout">Timeout between transactions to prevent out-of-order</label>
|
||||
<input name="test-part-timeout" id="test-part-timeout" type="number" value="<%= sleep_ms_between_transactions %>"> ms
|
||||
<input class="center-form-submit form-button" type="submit" name="submit" value="Run 6-Test">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="gn-jsonrpc" class="tabcontent" <% if(PAGE_GET_TRANSACTION_RPC_CALL == page) { %> style="display:block" <% } %>>
|
||||
<div class="center-form-title">
|
||||
<h3>Test 4-Set (2 AddMember, Creation, Transfer)</</h3>
|
||||
</div>
|
||||
<div class="center-form-form">
|
||||
<form method="POST" action="<%= getBaseUrl() %>/adminNodeServerTest">
|
||||
<label class="form-label" for="test-node-servers">Node Server to call</label>
|
||||
<% if(node_servers.size() == 0) { %>
|
||||
<a href="<%= getBaseUrl() %>/nodes"><span class="link-title">Edit Node-Servers</span></a>
|
||||
<% } %>
|
||||
<select name="test-node-servers" id="test-node-servers">
|
||||
<% for(auto it = node_servers.begin(); it != node_servers.end(); it++) {
|
||||
auto model = (*it)->getModel();
|
||||
%>
|
||||
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(!node_server.isNull() && node_server->getModel()->getID() == model->getID()) {%>selected="selected"<% } %>><%= model->getUrlWithPort() %>, group: <%= model->getGroupId() %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
<input class="center-form-submit form-button" type="submit" name="submit" value="json-rpc getTransactions">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<% if(PAGE_RUN_4_SET_TEST == page && !hedera_topic.isNull() && !node_server.isNull()) { %>
|
||||
<ul>
|
||||
<li>
|
||||
<p>1. Create three new accounts and show user public keys for comparisation: </p>
|
||||
<%
|
||||
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";
|
||||
auto user_1 = controller::User::create("testEmail@google.de", "Max", "Mustermann", group_id);
|
||||
auto passphrase_1 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]);
|
||||
auto gradido_key_pair_1 = KeyPairEd25519::create(passphrase_1);
|
||||
user_1->setGradidoKeyPair(gradido_key_pair_1);
|
||||
user_1->login(password1);
|
||||
|
||||
std::string password2 = "uweia8saiSale,dsasA";
|
||||
auto user_2 = controller::User::create("testEmail2@google.de", "MJax", "Mustrermann", group_id);
|
||||
auto passphrase_2 = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[mnemonic_type]);
|
||||
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);
|
||||
%>
|
||||
<fieldset><legend><%= user_group->getModel()->getName() %></legend>
|
||||
<p>User 1: <%= user_1->getPublicHex() %></p>
|
||||
<p>User 2: <%= user_2->getPublicHex() %></p>
|
||||
</fieldset>
|
||||
<fieldset><legend><%= user_group2->getModel()->getName() %></legend>
|
||||
<p>User 3: <%= user_3->getPublicHex() %></p>
|
||||
</fieldset>
|
||||
<p>Time: <%= time2.string() %>
|
||||
</li>
|
||||
<li>
|
||||
<p>2. Send a add-member transaction to hedera topic with one signature (first user)</p>
|
||||
<%
|
||||
time2.reset();
|
||||
if(!steps[0]) { %>
|
||||
<p>skipped</p>
|
||||
<% } else {
|
||||
auto transaction1 = model::gradido::Transaction::createGroupMemberUpdate(user_1, user_group);
|
||||
transaction1->getTransactionBody()->getGroupMemberUpdate()->setMinSignatureCount(1);
|
||||
transaction1->sign(user_1);
|
||||
auto transaction1_json = transaction1->getTransactionAsJson(true);
|
||||
%>
|
||||
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction1_json) %></p>
|
||||
<% } %>
|
||||
<p>Time: <%= time2.string() %>
|
||||
</li>
|
||||
<li>
|
||||
<p>3. Send a add-member transaction to hedera topic with two signatures (first user and second user)</p>
|
||||
<%
|
||||
time2.reset();
|
||||
if(!steps[1]) { %>
|
||||
<p>skipped</p>
|
||||
<% } 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);
|
||||
%>
|
||||
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction2_json) %></p>
|
||||
<% } %>
|
||||
<p>Time: <%= time2.string() %>
|
||||
</li>
|
||||
<li>
|
||||
<p>4. Send a creation transaction to second user, signed by first user</p>
|
||||
<%
|
||||
time2.reset();
|
||||
if(!steps[2]) { %>
|
||||
<p>skipped</p>
|
||||
<% } else {
|
||||
auto transaction3 = model::gradido::Transaction::createCreation(user_2, 10000000, Poco::DateTime(), "Test Creation", model::gradido::BLOCKCHAIN_HEDERA);
|
||||
// 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);
|
||||
%>
|
||||
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction3_json) %></p>
|
||||
<% } %>
|
||||
<p>Time: <%= time2.string() %></p>
|
||||
</li>
|
||||
<li>
|
||||
<p>5. Send a transfer transaction from second user to first user signed by second user</p>
|
||||
<%
|
||||
time2.reset();
|
||||
if(!steps[3]) { %>
|
||||
<p>skipped</p>
|
||||
<% } 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", model::gradido::BLOCKCHAIN_HEDERA);
|
||||
// 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);
|
||||
transaction4->sign(user_2);
|
||||
auto transaction4_json = transaction4->getTransactionAsJson(true);
|
||||
%>
|
||||
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction4_json) %></p>
|
||||
<% } %>
|
||||
<p>Time: <%= time2.string() %></p>
|
||||
</li>
|
||||
<li>
|
||||
<p>6. Send a add-member transaction to hedera topic 2 with one signature (third user)</p>
|
||||
<%
|
||||
time2.reset();
|
||||
if(!steps[4]) { %>
|
||||
<p>skipped</p>
|
||||
<% } 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);
|
||||
%>
|
||||
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction5_json) %></p>
|
||||
<% } %>
|
||||
<p>Time: <%= time2.string() %></p>
|
||||
</li>
|
||||
<li>
|
||||
<p>7. Send a cross group transfer from second user to third user signed by second user</p>
|
||||
<%
|
||||
time2.reset();
|
||||
if(!steps[5]) { %>
|
||||
<p>skipped</p>
|
||||
<% } 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", model::gradido::BLOCKCHAIN_HEDERA, false);
|
||||
if(transaction6.isNull()) {
|
||||
%>
|
||||
<div class="alert alert-error" role="alert">
|
||||
<i class="material-icons-outlined">report_problem</i>
|
||||
<span>Error creating Transaction</span>
|
||||
</div>
|
||||
<%
|
||||
} else {
|
||||
Poco::Thread::sleep(sleep_ms_between_transactions);
|
||||
transaction6->sign(user_2);
|
||||
auto transaction6_json = transaction6->getTransactionAsJson(true);
|
||||
auto paired_transaction = transaction6->getPairedTransaction();
|
||||
%>
|
||||
<p><%= DataTypeConverter::replaceNewLineWithBr(transaction6_json) %></p>
|
||||
<% if(!paired_transaction.isNull()) {
|
||||
auto transaction6_2_json = paired_transaction->getTransactionAsJson(true);
|
||||
%><p><%= DataTypeConverter::replaceNewLineWithBr(transaction6_2_json) %></p>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<p>Time: <%= time2.string() %></p>
|
||||
</li>
|
||||
<li>
|
||||
<p>8. Wait <%= hedera_timeout %> seconds to give hedera time to process transactions</p>
|
||||
<% if(!steps[6]) { %>
|
||||
<p>skipped</p>
|
||||
<% } else {
|
||||
Poco::Thread::sleep(hedera_timeout * 1000);
|
||||
} %>
|
||||
</li>
|
||||
<li>
|
||||
<p>9. Ask choosen node for transaction and print result</p>
|
||||
<% time2.reset();
|
||||
if(!steps[7] || node_server.isNull()) {
|
||||
%><p>skipped</p>
|
||||
<% } else {
|
||||
auto node_server_model = node_server->getModel();
|
||||
JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort());
|
||||
Poco::JSON::Object params;
|
||||
params.set("groupAlias", user_group->getModel()->getAlias());
|
||||
params.set("lastKnownSequenceNumber", 0);
|
||||
auto gn_answear = jsonrpc.request("getTransactions", params);
|
||||
if(!gn_answear.isNull()) {
|
||||
std::stringstream ss;
|
||||
Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER);
|
||||
std::string answear_string = ss.str(); %>
|
||||
<%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><%
|
||||
}
|
||||
} %>
|
||||
<p>Time: <%= time2.string() %></p>
|
||||
</li>
|
||||
</ul>
|
||||
<% } else if(PAGE_GET_TRANSACTION_RPC_CALL == page && !node_server.isNull()) {
|
||||
Profiler time3;
|
||||
auto node_server_model = node_server->getModel();
|
||||
auto user_group = controller::Group::load(node_server_model->getGroupId());
|
||||
JsonRPCRequest jsonrpc(node_server_model->getUrl(), node_server_model->getPort());
|
||||
Poco::JSON::Object params;
|
||||
params.set("groupAlias", user_group->getModel()->getAlias());
|
||||
params.set("lastKnownSequenceNumber", 0);
|
||||
auto gn_answear = jsonrpc.request("getTransactions", params);
|
||||
if(!gn_answear.isNull()) {
|
||||
std::stringstream ss;
|
||||
Poco::JSON::Stringifier::stringify(gn_answear, ss, 4, -1, Poco::JSON_PRESERVE_KEY_ORDER);
|
||||
std::string answear_string = ss.str();%>
|
||||
<%= DataTypeConverter::replaceNewLineWithBr(answear_string) %><%
|
||||
}
|
||||
%>
|
||||
<p>Time: <%= time3.string() %></p>
|
||||
<% } %>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript" src="<%= ServerConfig::g_php_serverPath %>/js/tabs.js"></script>
|
||||
<%@ include file="include/footer.cpsp" %>
|
||||
@ -1,321 +0,0 @@
|
||||
<%@ page class="AdminTopicPage" %>
|
||||
<%@ page form="true" %>
|
||||
<%@ page baseClass="SessionHTTPRequestHandler" %>
|
||||
<%@ page ctorArg="Session*" %>
|
||||
<%@ header include="HTTPInterface/SessionHTTPRequestHandler.h" %>
|
||||
<%!
|
||||
#include "controller/HederaAccount.h"
|
||||
#include "controller/HederaTopic.h"
|
||||
#include "controller/Group.h"
|
||||
#include "SingletonManager/SessionManager.h"
|
||||
#include "ServerConfig.h"
|
||||
|
||||
#include "lib/DataTypeConverter.h"
|
||||
#include "lib/Profiler.h"
|
||||
#include "lib/Success.h"
|
||||
|
||||
#include "Poco/Timespan.h"
|
||||
#include "Poco/URI.h"
|
||||
%>
|
||||
<%%
|
||||
const char* pageName = "Topic";
|
||||
auto user = mSession->getNewUser();
|
||||
auto sm = SessionManager::getInstance();
|
||||
Profiler hedera_time;
|
||||
|
||||
std::string name = "";
|
||||
std::string topic_id_string = "";
|
||||
int auto_renew_account = 0;
|
||||
int auto_renew_period = 7890000; // 3 Monate
|
||||
|
||||
int group_id = 0;
|
||||
|
||||
Poco::URI uri(request.getURI());
|
||||
auto uri_query = uri.getQueryParameters();
|
||||
std::string action = "";
|
||||
Poco::AutoPtr<controller::HederaTopic> query_hedera_topic;
|
||||
|
||||
// parsing get query params
|
||||
if(uri_query.size() >= 2) {
|
||||
if(uri_query[0].first == "action") {
|
||||
action = uri_query[0].second;
|
||||
}
|
||||
if(uri_query[1].first == "topic_id") {
|
||||
std::string topic_id_from_query;
|
||||
int topic_id = 0;
|
||||
topic_id_from_query = uri_query[1].second;
|
||||
if(DataTypeConverter::strToInt(topic_id_from_query, topic_id) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting topic_id_from_query to int"));
|
||||
} else {
|
||||
auto hedera_topic = controller::HederaTopic::load(topic_id);
|
||||
if(hedera_topic.isNull()) {
|
||||
addError(new Error("Action", "hedera topic not found"));
|
||||
} else {
|
||||
query_hedera_topic = hedera_topic;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// actions
|
||||
if(!query_hedera_topic.isNull())
|
||||
{
|
||||
if(action == "getTopicInfos")
|
||||
{
|
||||
hedera_time.reset();
|
||||
if(query_hedera_topic->updateWithGetTopicInfos(user)) {
|
||||
addNotification(new ParamSuccess("Hedera", "hedera get topic infos success in ", hedera_time.string()));
|
||||
} else {
|
||||
addError(new ParamError("Hedera", "hedera get topic infos failed in ", hedera_time.string()));
|
||||
}
|
||||
getErrors(query_hedera_topic);
|
||||
}
|
||||
}
|
||||
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", "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"));
|
||||
}
|
||||
|
||||
if(!sm->isValid(auto_renew_account_string, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Topic", "auto renew account id not an integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(auto_renew_account_string, auto_renew_account) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int convert error", "Error converting auto renew account id to int"));
|
||||
}
|
||||
}
|
||||
|
||||
if(!sm->isValid(auto_renew_period_string, VALIDATE_ONLY_INTEGER)) {
|
||||
addError(new Error("Topic", "auto renew period not an integer"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(auto_renew_period_string, auto_renew_period) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
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"));
|
||||
} else {
|
||||
if(DataTypeConverter::strToInt(group_id_string, group_id) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int convert error", "Error converting group_id to int"));
|
||||
}
|
||||
}
|
||||
//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"));
|
||||
} else {
|
||||
auto payer = controller::HederaAccount::load(auto_renew_account);
|
||||
if(payer.isNull()) {
|
||||
addError(new Error("Payer", "payer account not found"));
|
||||
} else {
|
||||
auto hedera_task = hedera_topic->createTopic(payer, user);
|
||||
if(hedera_task.isNull()) {
|
||||
addError(new Error("Create Topic", "Failed"));
|
||||
getErrors(hedera_topic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID());
|
||||
//std::vector<Poco::AutoPtr<controller::HederaAccount>> hedera_accounts;
|
||||
|
||||
auto groups = controller::Group::listAll();
|
||||
std::map<int, int> group_indices;
|
||||
int count = 0;
|
||||
for(auto it = groups.begin(); it != groups.end(); it++) {
|
||||
group_indices.insert(std::pair<int, int>((*it)->getModel()->getID(), count));
|
||||
count++;
|
||||
}
|
||||
|
||||
auto hedera_topics = controller::HederaTopic::listAll();
|
||||
//std::vector<Poco::AutoPtr<controller::HederaTopic>> hedera_topics;
|
||||
|
||||
%><%@ include file="include/header_large.cpsp" %>
|
||||
|
||||
<style type="text/css">
|
||||
.center-form-form .input-40 {
|
||||
margin-left:0;
|
||||
width:40%;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
</style>
|
||||
<%= getErrorsHtml() %>
|
||||
<div class="content-container info-container">
|
||||
<h1>Topic Admin Page</h1>
|
||||
</div>
|
||||
<div class="center-form-container">
|
||||
<div class="content-list">
|
||||
<div class="content-list-title">
|
||||
<h2>Hedera Topics</h2>
|
||||
</div>
|
||||
<div class="content-list-table">
|
||||
<div class="row">
|
||||
<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>
|
||||
<div class="cell header-cell c4">Auto Renew Period</div>
|
||||
<div class="cell header-cell c3">Group ID</div>
|
||||
<div class="cell header-cell c3">Current Timeout</div>
|
||||
<div class="cell header-cell c2">Sequence Number</div>
|
||||
<div class="cell header-cell c3" title="Last Time Get update from Hedera">Last Updated</div>
|
||||
<div class="cell header-cell c5">Aktionen</div>
|
||||
</div>
|
||||
<% 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());
|
||||
std::string kabuto_url = "https://explorer.kabuto.sh/";//testnet/id/0.0.132132;
|
||||
|
||||
|
||||
auto auto_renew_account = (*it)->getAutoRenewAccount();
|
||||
auto renew_account_model = auto_renew_account->getModel();
|
||||
|
||||
if(renew_account_model->getNetworkType() == ServerConfig::HEDERA_TESTNET) {
|
||||
kabuto_url += "testnet/";
|
||||
} else if(renew_account_model->getNetworkType() == ServerConfig::HEDERA_MAINNET) {
|
||||
kabuto_url += "mainnet/";
|
||||
}
|
||||
kabuto_url += "id/";
|
||||
|
||||
std::string timeout_color = "success-color";
|
||||
if(hedera_topic_model->getCurrentTimeout() < Poco::DateTime()) {
|
||||
timeout_color = "alert-color";
|
||||
} else if((hedera_topic_model->getCurrentTimeout() - Poco::DateTime()) < Poco::Timespan(2,0,0,0,0)) {
|
||||
timeout_color = "orange-color";
|
||||
}
|
||||
std::string topic_hedera_id_string = "";
|
||||
auto topic_hedera_id = (*it)->getTopicHederaId();
|
||||
if(!topic_hedera_id.isNull()) {
|
||||
topic_hedera_id_string = topic_hedera_id->getModel()->toString();
|
||||
kabuto_url += topic_hedera_id_string;
|
||||
}
|
||||
|
||||
|
||||
%>
|
||||
<div class="row">
|
||||
<div class="cell c3"><a title="Hedera Block Explorer - Kabuto" target="_blank" href="<%= kabuto_url %>"><%= topic_hedera_id_string %></a></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>
|
||||
<div class="cell c4"><%= hedera_topic_model->getAutoRenewPeriodString() %></div>
|
||||
<div class="cell c3"><%= hedera_topic_model->getGroupId() %></div>
|
||||
<div class="cell c3 <%= timeout_color %>"><%= hedera_topic_model->getCurrentTimeoutString() %></div>
|
||||
<div class="cell c2"><%= hedera_topic_model->getSequenceNumber() %></div>
|
||||
<div class="cell c3"><%= hedera_topic_model->getUpdatedString() %></div>
|
||||
<div class="cell c5"><% if(!topic_hedera_id.isNull()) { %>
|
||||
<button class="form-button" title="Query on Hedera, cost some fees" onclick="window.location.href='<%= updateUrl %>'" >
|
||||
get topic infos
|
||||
</button>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</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>
|
||||
<div class="center-form-form">
|
||||
<form method="POST" action="<%= ServerConfig::g_serverPath %>/topic">
|
||||
<label class="form-label" for="topic-name">Name</label>
|
||||
<input type="text" class="form-control" id="topic-name" name="topic-name" value="<%= name %>">
|
||||
<label class="form-label" for="topic-auto-renew-account">Auto Renew Hedera Account</label>
|
||||
<select name="topic-auto-renew-account" id="topic-auto-renew-account">
|
||||
<% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) {
|
||||
auto model = (*it)->getModel();
|
||||
%>
|
||||
<option title="<%= model->toString() %>" value="<%= model->getID() %>" <% if(auto_renew_account == model->getID()) {%>selected="selected"<% } %>><%= (*it)->toShortSelectOptionName() %></option>
|
||||
<% } %>
|
||||
</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>
|
||||
<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>
|
||||
<% 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("Add Topic") %>">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%@ include file="include/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");
|
||||
span.innerHTML = '~ ' + getExactTimeDuration(input.value);
|
||||
input.addEventListener('keyup', function(e) {
|
||||
span.innerHTML = '~ ' + getExactTimeDuration(input.value);
|
||||
});
|
||||
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user