From 5bb34f26a210fbcbfab176dda32a659e4cfd03e3 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 9 Nov 2020 18:45:34 +0100 Subject: [PATCH] work on hedera task for able to create topics --- src/cpp/controller/HederaRequest.cpp | 23 +++++++++- src/cpp/controller/HederaRequest.h | 2 + src/cpp/controller/HederaTopic.cpp | 44 +++++++++++++++++-- src/cpp/controller/HederaTopic.h | 9 ++-- src/cpp/model/hedera/ConsensusCreateTopic.cpp | 4 +- src/cpp/model/hedera/Query.cpp | 6 +-- src/cpp/model/hedera/QueryHeader.cpp | 29 +++++++++++- src/cpp/model/hedera/QueryHeader.h | 23 ++++++++-- src/cpp/model/hedera/Transaction.cpp | 5 +++ src/cpp/model/hedera/Transaction.h | 1 + .../model/hedera/TransactionGetReceipt.cpp | 15 +++++++ src/cpp/model/hedera/TransactionGetReceipt.h | 17 +++++++ .../hedera/TransactionGetReceiptQuery.cpp | 18 ++++++++ .../model/hedera/TransactionGetReceiptQuery.h | 29 ++++++++++++ src/cpp/model/table/PendingTask.h | 1 + src/cpp/tasks/HederaTask.cpp | 22 ++++++++++ src/cpp/tasks/HederaTask.h | 3 ++ 17 files changed, 234 insertions(+), 17 deletions(-) create mode 100644 src/cpp/model/hedera/TransactionGetReceipt.cpp create mode 100644 src/cpp/model/hedera/TransactionGetReceipt.h create mode 100644 src/cpp/model/hedera/TransactionGetReceiptQuery.cpp create mode 100644 src/cpp/model/hedera/TransactionGetReceiptQuery.h diff --git a/src/cpp/controller/HederaRequest.cpp b/src/cpp/controller/HederaRequest.cpp index 00c4d3717..6e901233a 100644 --- a/src/cpp/controller/HederaRequest.cpp +++ b/src/cpp/controller/HederaRequest.cpp @@ -83,6 +83,23 @@ HederaRequestReturn HederaRequest::request(model::hedera::Query* query, model::h return HEDERA_REQUEST_UNKNOWN_QUERY; } +HederaRequestReturn HederaRequest::request(model::hedera::TransactionGetReceiptQuery* query, model::hedera::Response* response) +{ + 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); + + auto proto_query = query->getProto(); + auto proto_response = response->getResponsePtr(); + grpc::Status status; + + auto stub = proto::CryptoService::NewStub(channel); + status = stub->getTransactionReceipts(&context, *proto_query, proto_response); +} + HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transaction, model::hedera::Response* response) { auto channel = grpc::CreateChannel(transaction->getConnectionString(), grpc::InsecureChannelCredentials()); @@ -106,7 +123,8 @@ HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transacti context.set_deadline(deadline); auto transaction_type = transaction->getType(); task->setTransactionId(transaction->getTransactionId()); - if (model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE == transaction_type) { + if (model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE == transaction_type || + model::hedera::TRANSACTION_CONSENSUS_CREATE_TOPIC == transaction_type) { auto stub = proto::ConsensusService::NewStub(channel); auto status = stub->submitMessage(&context, *transaction->getTransaction(), task->getTransactionResponse()->getProtoResponse()); @@ -119,7 +137,8 @@ HederaRequestReturn HederaRequest::request(model::hedera::Transaction* transacti return HEDERA_REQUEST_RETURN_ERROR; } } - addError(new ParamError("Hedera Request", "not implemnetet or unknown transaction type", transaction_type)); + + addError(new ParamError("Hedera Request", "not implementet or unknown transaction type", transaction_type)); return HEDERA_REQUEST_UNKNOWN_TRANSACTION; } diff --git a/src/cpp/controller/HederaRequest.h b/src/cpp/controller/HederaRequest.h index 22cffdcc9..59ffe2e3a 100644 --- a/src/cpp/controller/HederaRequest.h +++ b/src/cpp/controller/HederaRequest.h @@ -12,6 +12,7 @@ #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" @@ -36,6 +37,7 @@ public: ~HederaRequest(); HederaRequestReturn request(model::hedera::Query* query, model::hedera::Response* response, Poco::UInt64 fee = 0); + HederaRequestReturn request(model::hedera::TransactionGetReceiptQuery* query, model::hedera::Response* response); HederaRequestReturn request(model::hedera::Transaction* transaction, model::hedera::Response* response); //! //! \param task goes into HederaTaskManager and will be run after transaction diff --git a/src/cpp/controller/HederaTopic.cpp b/src/cpp/controller/HederaTopic.cpp index 5dad41814..686c5ea81 100644 --- a/src/cpp/controller/HederaTopic.cpp +++ b/src/cpp/controller/HederaTopic.cpp @@ -3,6 +3,9 @@ #include "HederaRequest.h" #include "../lib/Success.h" +#include "../model/hedera/ConsensusCreateTopic.h" +#include "../model/hedera/Transaction.h" + namespace controller { HederaTopic::HederaTopic(model::table::HederaTopic* dbModel) { @@ -64,10 +67,6 @@ namespace controller { return mAutoRenewAccount; } - Poco::UInt64 HederaTopic::hederaCreateTopic() - { - return 0; - } bool HederaTopic::updateWithGetTopicInfos(Poco::AutoPtr user) { @@ -124,4 +123,41 @@ namespace controller { return false; } + + Poco::AutoPtr HederaTopic::createTopic(Poco::AutoPtr operatorAccount, Poco::AutoPtr user) + { + static const char* function_name = "HederaTopic::createTopic"; + auto model = getModel(); + Poco::AutoPtr autoRenewAccountId(nullptr); + if (model->getAutoRenewAccountId()) { + autoRenewAccountId = controller::HederaId::load(model->getAutoRenewAccountId()); + } + model::hedera::ConsensusCreateTopic hederaCreateTopic(autoRenewAccountId, model->getAutoRenewPeriod()); + auto hederaTransactionBody = operatorAccount->createTransactionBody(); + hederaTransactionBody->setCreateTopic(hederaCreateTopic); + 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; + } + + Poco::AutoPtr receiptTask(new HederaTask(&hederaTransaction)); + HederaRequest request; + auto result = request.request(&hederaTransaction, receiptTask.get()); + if (HEDERA_REQUEST_RETURN_OK == result) { + if (proto::OK == receiptTask->getTransactionResponse()->getPrecheckCode()) { + + 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; + } + + } } \ No newline at end of file diff --git a/src/cpp/controller/HederaTopic.h b/src/cpp/controller/HederaTopic.h index cd08bbd0e..28f96d13f 100644 --- a/src/cpp/controller/HederaTopic.h +++ b/src/cpp/controller/HederaTopic.h @@ -15,6 +15,7 @@ #include "HederaId.h" #include "HederaAccount.h" +#include "../tasks/HederaTask.h" namespace controller { class HederaTopic : public TableControllerBase, public NotificationList @@ -26,16 +27,18 @@ namespace controller { static Poco::AutoPtr create(const std::string& name, int autoRenewAccountId, int autoRenewPeriod, int groupId); static std::vector> listAll(); static Poco::AutoPtr load(int id); - //! \brief hedera call to create a hedera topic - Poco::UInt64 hederaCreateTopic(); + + bool updateWithGetTopicInfos(Poco::AutoPtr user); + inline bool deleteFromDB() { return mDBModel->deleteFromDB(); } Poco::AutoPtr getTopicHederaId(); Poco::AutoPtr getAutoRenewAccount(); + //! \brief hedera call to create a hedera topic + Poco::AutoPtr createTopic(Poco::AutoPtr operatorAccount, Poco::AutoPtr user); - inline Poco::AutoPtr getModel() { return _getModel(); } diff --git a/src/cpp/model/hedera/ConsensusCreateTopic.cpp b/src/cpp/model/hedera/ConsensusCreateTopic.cpp index a20985593..b885db7c1 100644 --- a/src/cpp/model/hedera/ConsensusCreateTopic.cpp +++ b/src/cpp/model/hedera/ConsensusCreateTopic.cpp @@ -12,7 +12,9 @@ namespace model { auto_renew_period->set_seconds(autoRenewPeriod); auto auto_renew_account = mProtoCreateTopic->mutable_autorenewaccount(); - autoRenewHederaAccountId->copyToProtoAccountId(auto_renew_account); + if (!autoRenewHederaAccountId.isNull()) { + autoRenewHederaAccountId->copyToProtoAccountId(auto_renew_account); + } } ConsensusCreateTopic::~ConsensusCreateTopic() diff --git a/src/cpp/model/hedera/Query.cpp b/src/cpp/model/hedera/Query.cpp index 421266173..eb16dd332 100644 --- a/src/cpp/model/hedera/Query.cpp +++ b/src/cpp/model/hedera/Query.cpp @@ -67,10 +67,10 @@ namespace model { query->mTransactionBody = new TransactionBody(payerAccountId, connection); CryptoTransferTransaction crypto_transaction; - // 0.002809 Hashbars + // 0.003317 Hashbars // fee from https://www.hedera.com/fees - crypto_transaction.addSender(payerAccountId, 2809); - crypto_transaction.addReceiver(connection.hederaId, 2809); + crypto_transaction.addSender(payerAccountId, 3317); + crypto_transaction.addReceiver(connection.hederaId, 3317); query->mTransactionBody->setCryptoTransfer(crypto_transaction); return query; diff --git a/src/cpp/model/hedera/QueryHeader.cpp b/src/cpp/model/hedera/QueryHeader.cpp index c622841ec..cd85d2a86 100644 --- a/src/cpp/model/hedera/QueryHeader.cpp +++ b/src/cpp/model/hedera/QueryHeader.cpp @@ -1,8 +1,11 @@ #include "QueryHeader.h" +#include "Transaction.h" + namespace model { namespace hedera { - QueryHeader::QueryHeader(Transaction* paymentTransaction) + + QueryHeader::QueryHeader() { mProtoQueryHeader.set_responsetype(proto::ANSWER_ONLY); } @@ -12,5 +15,29 @@ namespace model { } + Poco::AutoPtr QueryHeader::createWithPaymentTransaction( + Poco::AutoPtr operatorAccount, + const controller::NodeServerConnection& connection, + Poco::AutoPtr keyHolder, + Poco::UInt32 cost + ) { + Poco::AutoPtr query_header(new QueryHeader); + auto proto_query_header = query_header->getProtoQueryHeader(); + auto payment_transaction = proto_query_header->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(keyHolder), &body); + transactionObj.resetPointer(); + + return query_header; + } + } } \ No newline at end of file diff --git a/src/cpp/model/hedera/QueryHeader.h b/src/cpp/model/hedera/QueryHeader.h index 47261e24a..a841284a6 100644 --- a/src/cpp/model/hedera/QueryHeader.h +++ b/src/cpp/model/hedera/QueryHeader.h @@ -4,20 +4,37 @@ #include "../proto/hedera/QueryHeader.pb.h" #include "Transaction.h" +#include "../../controller/User.h" +#include "../../controller/HederaAccount.h" + namespace model { namespace hedera { - class QueryHeader + class QueryHeader : public Poco::RefCountedObject { public: - QueryHeader(Transaction* paymentTransaction); ~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 createWithPaymentTransaction( + Poco::AutoPtr operatorAccount, + const controller::NodeServerConnection& connection, + Poco::AutoPtr keyHolder, + 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(); }; } } diff --git a/src/cpp/model/hedera/Transaction.cpp b/src/cpp/model/hedera/Transaction.cpp index 3d573bef2..e4d0f2bd5 100644 --- a/src/cpp/model/hedera/Transaction.cpp +++ b/src/cpp/model/hedera/Transaction.cpp @@ -7,6 +7,11 @@ namespace model { { mTransaction = new proto::Transaction; } + Transaction::Transaction(proto::Transaction* transaction) + : mTransaction(transaction) + { + + } Transaction::~Transaction() { diff --git a/src/cpp/model/hedera/Transaction.h b/src/cpp/model/hedera/Transaction.h index 5938a0f1e..de9704c86 100644 --- a/src/cpp/model/hedera/Transaction.h +++ b/src/cpp/model/hedera/Transaction.h @@ -20,6 +20,7 @@ namespace model { { public: Transaction(); + Transaction(proto::Transaction* transaction); ~Transaction(); bool sign(std::unique_ptr keyPairHedera, const TransactionBody* transactionBody); diff --git a/src/cpp/model/hedera/TransactionGetReceipt.cpp b/src/cpp/model/hedera/TransactionGetReceipt.cpp new file mode 100644 index 000000000..402dfd81d --- /dev/null +++ b/src/cpp/model/hedera/TransactionGetReceipt.cpp @@ -0,0 +1,15 @@ +#include "TransactionGetReceipt.h" + +namespace model { + namespace hedera { + TransactionGetReceipt::TransactionGetReceipt() + { + + } + + TransactionGetReceipt::~TransactionGetReceipt() + { + + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionGetReceipt.h b/src/cpp/model/hedera/TransactionGetReceipt.h new file mode 100644 index 000000000..e03623d58 --- /dev/null +++ b/src/cpp/model/hedera/TransactionGetReceipt.h @@ -0,0 +1,17 @@ +#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 \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionGetReceiptQuery.cpp b/src/cpp/model/hedera/TransactionGetReceiptQuery.cpp new file mode 100644 index 000000000..c8e2db73e --- /dev/null +++ b/src/cpp/model/hedera/TransactionGetReceiptQuery.cpp @@ -0,0 +1,18 @@ +#include "TransactionGetReceiptQuery.h" + +namespace model { + namespace hedera { + TransactionGetReceiptQuery::TransactionGetReceiptQuery(Poco::AutoPtr queryHeader, const Transaction* target) + : mQueryHeader(queryHeader) + { + mProtoReceiptQuery.set_allocated_header(queryHeader->getProtoQueryHeader()); + auto transaction_id = mProtoReceiptQuery.transactionid(); + transaction_id = target->getTransactionId(); + } + + TransactionGetReceiptQuery::~TransactionGetReceiptQuery() + { + + } + } +} \ No newline at end of file diff --git a/src/cpp/model/hedera/TransactionGetReceiptQuery.h b/src/cpp/model/hedera/TransactionGetReceiptQuery.h new file mode 100644 index 000000000..bf035a941 --- /dev/null +++ b/src/cpp/model/hedera/TransactionGetReceiptQuery.h @@ -0,0 +1,29 @@ +#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, const Transaction* target); + ~TransactionGetReceiptQuery(); + + proto::TransactionGetReceiptQuery* getProto() { return &mProtoReceiptQuery; } + + const std::string& getConnectionString() const { return mQueryHeader->getConnectionString(); } + + protected: + Poco::AutoPtr mQueryHeader; + proto::TransactionGetReceiptQuery mProtoReceiptQuery; + + }; + } +} + + + +#endif //GRADIDO_LOGIN_SERVER_MODEL_HEDERA_TRANSACTION_GET_RECEIPT_QUERY_H \ No newline at end of file diff --git a/src/cpp/model/table/PendingTask.h b/src/cpp/model/table/PendingTask.h index bee90e7a2..8d94ad7dc 100644 --- a/src/cpp/model/table/PendingTask.h +++ b/src/cpp/model/table/PendingTask.h @@ -18,6 +18,7 @@ namespace model { TASK_TYPE_HEDERA_TOPIC_CREATE = 20, TASK_TYPE_HEDERA_TOPIC_MESSAGE = 21, TASK_TYPE_HEDERA_ACCOUNT_CREATE = 25, + TASK_TYPE_HEDERA_ACCOUNT_TRANSFER = 26 }; diff --git a/src/cpp/tasks/HederaTask.cpp b/src/cpp/tasks/HederaTask.cpp index c9750a838..44d8fa584 100644 --- a/src/cpp/tasks/HederaTask.cpp +++ b/src/cpp/tasks/HederaTask.cpp @@ -13,6 +13,28 @@ HederaTask::HederaTask(const model::gradido::Transaction* transaction) hedera_task_model->setTaskType(model::table::TASK_TYPE_HEDERA_TOPIC_MESSAGE); } +HederaTask::HederaTask(const model::hedera::Transaction* transaction) +: controller::PendingTask(new model::table::PendingTask), mTransactionReceipt(nullptr) +{ + auto hedera_task_model = getModel(); + //auto gradido_task_model = transaction->getModel(); + //hedera_task_model->setUserId(gradido_task_model->getUserId()); + model::table::TaskType task_type; + auto transaction_type = transaction->getType(); + switch (transaction_type) { + case model::hedera::TRANSACTION_CONSENSUS_CREATE_TOPIC: + task_type = model::table::TASK_TYPE_HEDERA_TOPIC_CREATE; break; + case model::hedera::TRANSACTION_CONSENSUS_SUBMIT_MESSAGE: + task_type = model::table::TASK_TYPE_HEDERA_TOPIC_MESSAGE; break; + case model::hedera::TRANSACTION_CRYPTO_CREATE: + task_type = model::table::TASK_TYPE_HEDERA_ACCOUNT_CREATE; break; + case model::hedera::TRANSACTION_CRYPTO_TRANSFER: + task_type = model::table::TASK_TYPE_HEDERA_ACCOUNT_TRANSFER; break; + } + hedera_task_model->setTaskType(task_type); + +} + HederaTask::HederaTask(model::table::PendingTask* dbModel) : controller::PendingTask(dbModel), mTransactionReceipt(nullptr) { diff --git a/src/cpp/tasks/HederaTask.h b/src/cpp/tasks/HederaTask.h index a78cb394a..18f581e9d 100644 --- a/src/cpp/tasks/HederaTask.h +++ b/src/cpp/tasks/HederaTask.h @@ -3,12 +3,14 @@ #include "../model/hedera/TransactionResponse.h" #include "../model/hedera/TransactionReceipt.h" +#include "../model/hedera/Transaction.h" #include "../proto/hedera/BasicTypes.pb.h" #include "../proto/hedera/Duration.pb.h" #include "../model/gradido/Transaction.h" #include "../controller/PendingTask.h" +#include "../controller/HederaAccount.h" #include "Poco/Timestamp.h" @@ -27,6 +29,7 @@ class HederaTask : public controller::PendingTask, public NotificationList public: HederaTask(const model::gradido::Transaction* transaction); + HederaTask(const model::hedera::Transaction* transaction); HederaTask(model::table::PendingTask* dbModel); ~HederaTask();