merge with master

This commit is contained in:
einhorn_b 2021-06-04 10:42:01 +02:00
commit c8ea858ba5
121 changed files with 358 additions and 7966 deletions

8
.gitmodules vendored
View File

@ -15,16 +15,13 @@
[submodule "login_server/dependencies/spirit-po"]
path = login_server/dependencies/spirit-po
url = https://github.com/cbeck88/spirit-po.git
[submodule "login_server/dependencies/grpc"]
path = login_server/dependencies/grpc
url = https://github.com/grpc/grpc.git
[submodule "login_server/dependencies/poco"]
path = login_server/dependencies/poco
url = https://github.com/pocoproject/poco.git
[submodule "login_server/dependencies/cmake-modules"]
path = login_server/dependencies/cmake-modules
url = https://github.com/viaduck/cmake-modules.git
[submodule "community_server/src/protobuf"]
path = community_server/src/protobuf
url = https://github.com/gradido/gradido_protocol.git
@ -34,3 +31,6 @@
[submodule "login_server/src/proto"]
path = login_server/src/proto
url = https://github.com/gradido/gradido_protocol.git
[submodule "login_server/dependencies/protobuf"]
path = login_server/dependencies/protobuf
url = https://github.com/protocolbuffers/protobuf.git

View File

@ -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');

View File

@ -38,7 +38,7 @@ services:
- ./login_server/dependencies:/code/dependencies
- ./login_server/scripts:/code/scripts
- ./configs/login_server:/etc/grd_login
- login_build_alpine:/code/build
- login_build_3:/code/build
#########################################################
@ -100,4 +100,4 @@ services:
volumes:
frontend_node_modules:
login_build_alpine:
login_build_3:

View File

@ -38,9 +38,12 @@ with:
```json
{
"email": "max.musterman@gmail.de",
"username": "Maxilein",
"password": "123abcDE&"
}
```
`username` or `email` must be present!
If booth present, `email` will be used.
### Response
In case of success returns:
@ -50,6 +53,7 @@ In case of success returns:
"state":"success",
"user": {
"created": 1614782270,
"description": "",
"disabled": false,
"email": "max.musterman@gmail.de",
"email_checked": true,
@ -69,6 +73,7 @@ In case of success returns:
- `user`: contain user object
- `created`: timestamp on which account was created
- `description`: description of user for other user
- `disabled`: true if account was disabled, if disabled no login or coin transfer is possible
- `email`: email of user
- `email_checked`: true if user has successfully clicked on activation link in email
@ -96,7 +101,9 @@ with:
{
"email":"max.musterman@gmail.de",
"first_name":"Max",
"last_name":"Musterman" ,
"last_name":"Musterman",
"username": "Maxilein",
"description": "Tischler",
"emailType": 2,
"group_id": 1,
"password":"123abcDE&",
@ -104,6 +111,8 @@ with:
}
```
- `username`: (optional), mindestens 4 Zeichen, return error if already used
- `description`: (optional), mindestens 4 Zeichen
- `emailType`: control email-text sended with email verification code
- 2: default, if user has registered directly
- 5: if user was registered by an admin
@ -167,6 +176,8 @@ with:
"update": {
"User.first_name": "Max",
"User.last_name" : "Musterman",
"User.username" : "Maxilein",
"User.description" : "Tischler",
"User.disabled": 0,
"User.language": "de",
"User.password": "1234"
@ -237,6 +248,8 @@ with:
"user.pubkeyhex",
"user.first_name",
"user.last_name",
"user.username",
"user.description",
"user.disabled",
"user.email_checked",
"user.language"
@ -271,6 +284,8 @@ Return only the fields which are defined in request
- `user.pubkeyhex`: public key of user in hex-format
- `user.first_name`: first name of user
- `user.last_name`: last name of user
- `user.username`: username of user (min 4 Character, unique per group)
- `user.description`: profil text for user
- `user.disabled`: User will be disabled if he wants a account delete but has transactions. Until transactions are saved in real blockchain, we need this data because the public key
is in db only saved in state_users so if we delete this entry, validating all transactions is no longer possible. Disabled User cannot login and cannot receive transactions.
- `email_checked`: If user has clicked on link in verification email (register), can only transfer gradidos if email_checked is 1
@ -298,6 +313,7 @@ In case of success returns:
"info":[],
"user": {
"created": 1614782270,
"description": "Tischler"
"disabled": false,
"email": "max.musterman@gmail.de",
"email_checked": true,

View File

@ -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,28 @@ 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" )
set(PROTOC_BIN_PATH "build/dependencies/protobuf/cmake/bin")
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "${PROTOC_BIN_PATH}/Debug" )
find_program(PROTOBUF_PROTOC_EXECUTABLE protoc PATHS "${PROTOC_BIN_PATH}/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 +83,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 +158,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 +174,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 +187,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 +208,6 @@ if(MSVC)
endif()
add_executable(Gradido_LoginServer ${LOCAL_SRCS})
############################## config and add mariadb ###################################
@ -314,11 +255,11 @@ ENDIF()
target_link_libraries(Gradido_LoginServer ${GRPC_LIBS})
if(WIN32)
target_link_libraries(Gradido_LoginServer mariadbclient ${CONAN_LIBS})
target_link_libraries(Gradido_LoginServer mariadbclient libprotobuf ${CONAN_LIBS})
#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 +0,0 @@
Subproject commit 7d7e4567625db7cfebf8969a225948097a3f9f89

@ -0,0 +1 @@
Subproject commit 0b8d13a1d4cd9be16ed8a2230577aa9c296aa1ca

View File

@ -5,15 +5,9 @@ fi
if [ ! -d "../src/cpp/proto/gradido" ] ; then
mkdir ../src/cpp/proto/gradido
fi
PROTOC_PATH=build/bin
CPP_PLUGIN_PATH=build/bin
$PROTOC_PATH/protoc.exe --cpp_out=../src/cpp/proto --proto_path=../src/proto ../src/proto/gradido/*.proto
PROTOC_PATH=../build/dependencies/protobuf/cmake/bin/Debug
$PROTOC_PATH/protoc.exe --cpp_out=../build/proto/gradido --proto_path=../src/proto ../src/proto/gradido/*.proto
if [ ! -d "./src/cpp/proto/hedera" ] ; then
mkdir ./src/cpp/proto/hedera
fi
GOOGLE_PROTOBUF_INCLUDES=../dependencies/grpc/third_party/protobuf/src
$PROTOC_PATH/protoc.exe --plugin=protoc-gen-grpc=$CPP_PLUGIN_PATH/grpc_cpp_plugin.exe --cpp_out=../src/cpp/proto/hedera --grpc_out=../src/cpp/proto/hedera --proto_path=$GOOGLE_PROTOBUF_INCLUDES --proto_path=../src/proto/hedera/hedera-protobuf/src/main/proto ../src/proto/hedera/hedera-protobuf/src/main/proto/*.proto

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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',

View File

@ -4,6 +4,7 @@ CREATE TABLE `users` (
`first_name` varchar(150) NOT NULL,
`last_name` varchar(255) DEFAULT '',
`username` varchar(255) DEFAULT '',
`description` text DEFAULT '',
`password` bigint unsigned DEFAULT '0',
`pubkey` binary(32) DEFAULT NULL,
`privkey` binary(80) DEFAULT NULL,

View File

@ -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();

View File

@ -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);

View File

@ -15,6 +15,8 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params)
std::string first_name;
std::string last_name;
std::string password;
std::string username;
std::string description;
bool login_after_register = false;
int emailType;
int group_id = 1;
@ -36,18 +38,27 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params)
paramJsonObject->get("first_name").convert(first_name);
paramJsonObject->get("last_name").convert(last_name);
paramJsonObject->get("emailType").convert(emailType);
auto group_id_obj = paramJsonObject->get("group_id");
auto username_obj = paramJsonObject->get("username");
auto description_obj = paramJsonObject->get("description");
if(!group_id_obj.isEmpty()) {
group_id_obj.convert(group_id);
}
if (!username_obj.isEmpty()) {
username_obj.convert(username);
}
if (!description_obj.isEmpty()) {
description_obj.convert(description);
}
if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_PASSWORD_REQUESTS)) {
paramJsonObject->get("password").convert(password);
}
if (!paramJsonObject->isNull("login_after_register")) {
paramJsonObject->get("login_after_register").convert(login_after_register);
}
}
catch (Poco::Exception& ex) {
return stateError("json exception", ex.displayText());
@ -85,6 +96,15 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params)
group_was_not_set = true;
}
user = controller::User::create(email, first_name, last_name, group_id);
if (username.size() > 3) {
if (user->isUsernameAlreadyUsed(username)) {
return stateError("username already in use");
}
user->getModel()->setUsername(username);
}
if (description.size() > 3) {
user->getModel()->setDescription(description);
}
auto userModel = user->getModel();
Session* session = nullptr;

View File

@ -121,6 +121,12 @@ Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params)
else if (parameterString == "user.last_name") {
jsonUser.set("last_name", user_model->getLastName());
}
else if (parameterString == "user.username") {
jsonUser.set("username", user_model->getUsername());
}
else if (parameterString == "user.description") {
jsonUser.set("description", user_model->getDescription());
}
else if (parameterString == "user.disabled") {
jsonUser.set("disabled", user_model->isDisabled());
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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_

View File

@ -21,6 +21,7 @@ Poco::JSON::Object* JsonUnsecureLogin::handle(Poco::Dynamic::Var params)
// incoming
std::string email;
std::string username;
std::string password;
// if is json object
@ -32,8 +33,17 @@ Poco::JSON::Object* JsonUnsecureLogin::handle(Poco::Dynamic::Var params)
/// not available for the given type.
/// Throws InvalidAccessException if Var is empty.
try {
paramJsonObject->get("email").convert(email);
//paramJsonObject->get("email").convert(email);
paramJsonObject->get("password").convert(password);
auto email_obj = paramJsonObject->get("email");
auto username_obj = paramJsonObject->get("username");
if (!email_obj.isEmpty()) {
email_obj.convert(email);
}
if (!username_obj.isEmpty()) {
username_obj.convert(username);
}
}
catch (Poco::Exception& ex) {
return stateError("json exception", ex.displayText());
@ -43,13 +53,24 @@ Poco::JSON::Object* JsonUnsecureLogin::handle(Poco::Dynamic::Var params)
return stateError("parameter format unknown");
}
if (!email.size() || !sm->isValid(email, VALIDATE_EMAIL)) {
return stateError("invalid or empty email");
if (!email.size() && !username.size()) {
return stateError("no email or username given");
}
auto user = controller::User::create();
if (1 != user->load(email)) {
return stateError("user with email not found", email);
if (email.size()) {
if (!sm->isValid(email, VALIDATE_EMAIL)) {
return stateError("invalid email");
}
if (1 != user->load(email)) {
return stateError("user with email not found", email);
}
}
else if (username.size() > 0) {
if (1 != user->load(username)) {
return stateError("user with username not found", username);
}
email = user->getModel()->getEmail();
}
NotificationList pwd_errors;

View File

@ -86,6 +86,32 @@ Poco::JSON::Object* JsonUpdateUserInfos::handle(Poco::Dynamic::Var params)
extractet_values++;
}
}
else if ("User.username" == name && value.size() > 3) {
if (!value.isString()) {
jsonErrorsArray.add("User.username isn't a string");
}
else {
auto new_username = value.toString();
if (user_model->getUsername() != new_username) {
if (user->isUsernameAlreadyUsed(new_username)) {
jsonErrorsArray.add("username already used");
}
else {
user_model->setUsername(new_username);
extractet_values++;
}
}
}
}
else if ("User.description" == name && value.size() > 3) {
if (!value.isString()) {
jsonErrorsArray.add("description isn't a string");
}
else {
user_model->setDescription(value.toString());
extractet_values++;
}
}
else if ("User.disabled" == name) {
if (value.isBoolean()) {
bool disabled;

View File

@ -21,7 +21,6 @@
#include "Poco/DateTimeFormatter.h"
#include "Poco/Environment.h"
#include "model/table/HederaAccount.h"
using Poco::Net::SSLManager;
@ -62,9 +61,6 @@ 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>
@ -157,36 +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;
}
const char* mnemonicTypeToString(Mnemonic_Types type)
{
/*
MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER,
MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES,
MNEMONIC_BIP0039_SORTED_ORDER
*/
switch(type) {
case MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER: return "german random order";
case MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES: return "german random order fixed cases";
case MNEMONIC_BIP0039_SORTED_ORDER: return "BIP 0039 sorted";
}
return "<unknown>";
}
bool loadMnemonicWordLists()
{
@ -265,14 +231,6 @@ namespace ServerConfig {
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
@ -299,7 +257,6 @@ namespace ServerConfig {
g_AllowUnsecureFlags = (AllowUnsecure)(g_AllowUnsecureFlags | UNSECURE_ALLOW_ALL_PASSWORDS);
}
g_HederaDefaultTimeout = cfg.getInt("hedera.default_timeout", 5);
g_gRPCRelayServerFullURL = cfg.getString("grpc.server", "");

View File

@ -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,9 +77,6 @@ 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();
@ -102,7 +84,6 @@ namespace ServerConfig {
bool initEMailAccount(const Poco::Util::LayeredConfiguration& cfg);
bool initSSLClientContext();
const char* mnemonicTypeToString(Mnemonic_Types type);
void writeToFile(std::istream& datas, std::string fileName);

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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_
//

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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;
@ -106,6 +105,12 @@ namespace controller {
}
bool User::isUsernameAlreadyUsed(const std::string& username)
{
auto db = getModel();
return db->loadFromDB({ "username", "group_id" }, username, db->getGroupId(), model::table::MYSQL_CONDITION_AND) > 0;
}
int User::load(const unsigned char* pubkey_array)
{
Poco::Data::BLOB pubkey(pubkey_array, 32);
@ -117,6 +122,14 @@ namespace controller {
Poco::Data::BLOB email_hash(*emailHash, crypto_generichash_BYTES);
return getModel()->loadFromDB("email_hash", email_hash);
}
size_t User::load(const std::string& emailOrUsername)
{
auto model = getModel();
if (1 == model->loadFromDB("email", emailOrUsername)) {
return 1;
}
return model->loadFromDB("username", emailOrUsername);
}
Poco::AutoPtr<User> User::sload(int user_id)
{
auto db = new model::table::User();
@ -127,7 +140,7 @@ namespace controller {
auto user = new User(db);
return Poco::AutoPtr<User>(user);
}
void User::reload()
{
getModel()->loadFromDB("id", getModel()->getID());
@ -147,15 +160,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 +198,7 @@ namespace controller {
return 2;
}
auto observer = SingletonTaskObserver::getInstance();
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
assert(mPassword.isNull());
@ -201,7 +214,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 +225,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 +260,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 +298,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 +314,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 +371,7 @@ namespace controller {
continue;
}
auto key_pair = user_backup->createGradidoKeyPair();
if (key_pair->isTheSame(user_model->getPublicKey())) {
if (createdKeyPair) {
*createdKeyPair = key_pair;
@ -425,7 +438,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 +512,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 +566,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()

View File

@ -47,6 +47,8 @@ namespace controller {
static std::vector<User*> search(const std::string& searchString, const std::string& accountState = "all");
bool isUsernameAlreadyUsed(const std::string& username);
//! \brief go through whole db and search users with email_checked = false and schedule resend 7 days after email_opt_in created date
//!
//! Should be only called by server start, later it aren't necessary, because register function schedule resend tasks by himself.
@ -68,7 +70,7 @@ namespace controller {
//! \return 0 matching entry found
int tryLoadPassphraseUserBackup(KeyPairEd25519** createdKeyPair = nullptr);
inline size_t load(const std::string& email) { return getModel()->loadFromDB("email", email); }
size_t load(const std::string& emailOrUsername);
//! \brief try to load user from db via user_id
//! \return count of found rows, should be 1 or 0
inline size_t load(int user_id) { return getModel()->loadFromDB("id", user_id); }

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -7,6 +7,12 @@ Error::Error(const char* functionName, const char* message)
}
Error::Error(const char* functionName, const std::string& message)
: Notification(functionName, message)
{
}
Error::~Error()
{

View File

@ -19,6 +19,7 @@ class Error : public Notification
{
public:
Error(const char* functionName, const char* message);
Error(const char* functionName, const std::string& message);
~Error();
const char* getFunctionName() { return mFunctionName.data(); }
@ -39,6 +40,8 @@ public:
: Error(functionName, message), mParam(param) {}
ParamError(const char* functionName, const char* message, const std::string& param)
: Error(functionName, message), mParam(param) {}
ParamError(const char* functionName, const std::string& message, const std::string& param)
: Error(functionName, message), mParam(param) {}
ParamError(const char* functioName, const char* message, int param)
: Error(functioName, message) {

View File

@ -4,4 +4,10 @@ Notification::Notification(const char* functionName, const char* message)
: mFunctionName(functionName), mMessage(message)
{
}
Notification::Notification(const char* functionName, const std::string& message)
: mFunctionName(functionName), mMessage(message)
{
}

View File

@ -7,6 +7,7 @@ class Notification
{
public:
Notification(const char* functionName, const char* message);
Notification(const char* functionName, const std::string& message);
const char* getFunctionName() { return mFunctionName.data(); }
const char* getMessage() { return mMessage.data(); }

View File

@ -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

View File

@ -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&uuml;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&uuml;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;

View File

@ -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;
};

View File

@ -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);
@ -484,9 +356,10 @@ namespace model {
}
}
UniLib::controller::TaskPtr transaction_send_task(new SendTransactionTask(Poco::AutoPtr<Transaction>(this, true)));
transaction_send_task->scheduleTask(transaction_send_task);
return true;
//UniLib::controller::TaskPtr transaction_send_task(new SendTransactionTask(Poco::AutoPtr<Transaction>(this, true)));
//transaction_send_task->scheduleTask(transaction_send_task);
return 1 == runSendTransaction();
//return true;
}
return false;
}
@ -637,15 +510,14 @@ namespace model {
auto pt = PendingTasksManager::getInstance();
pt->reportErrorToCommunityServer(Poco::AutoPtr<Transaction>(this, true), error_name, error_description);
addError(new ParamError(function_name, error_name, error_description));
}
return -1;
}
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 +526,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";
@ -832,6 +565,10 @@ namespace model {
if (!json_request.errorCount()) {
finishSuccess();
}
else {
getErrors(&json_request);
return -1;
}
return 1;
}

View File

@ -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;

View File

@ -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 {
}
}
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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();
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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());
}
}
}

View File

@ -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

View File

@ -1,15 +0,0 @@
#include "TransactionGetReceipt.h"
namespace model {
namespace hedera {
TransactionGetReceipt::TransactionGetReceipt()
{
}
TransactionGetReceipt::~TransactionGetReceipt()
{
}
}
}

View File

@ -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

View File

@ -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()
{
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

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

View File

@ -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

View File

@ -1,18 +0,0 @@
#include "TransactionResponse.h"
namespace model {
namespace hedera {
TransactionResponse::TransactionResponse()
{
}
TransactionResponse::~TransactionResponse()
{
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

Some files were not shown because too many files have changed in this diff Show More