#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::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(hedera_topic); } std::vector> HederaTopic::listAll() { auto db = new model::table::HederaTopic(); std::vector topic_list; // throw an unresolved external symbol error topic_list = db->loadAllFromDB(); std::vector> resultVector; resultVector.reserve(topic_list.size()); for (auto it = topic_list.begin(); it != topic_list.end(); it++) { Poco::AutoPtr topic_ptr(new HederaTopic(new model::table::HederaTopic(*it))); resultVector.push_back(topic_ptr); } return resultVector; } Poco::AutoPtr HederaTopic::load(int id) { auto db = new model::table::HederaTopic; if (1 == db->loadFromDB("id", id)) { return new HederaTopic(db); } return nullptr; } Poco::AutoPtr HederaTopic::getTopicHederaId() { if (mTopicHederaId.isNull()) { mTopicHederaId = HederaId::load(getModel()->getTopicHederaId()); } return mTopicHederaId; } Poco::AutoPtr HederaTopic::getAutoRenewAccount() { if (mAutoRenewAccount.isNull()) { mAutoRenewAccount = HederaAccount::load(getModel()->getAutoRenewAccountId()); } return mAutoRenewAccount; } bool HederaTopic::getTopicInfosFromHedera(Poco::AutoPtr topicHederaId, Poco::AutoPtr 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) { 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::loadFromHedera(Poco::AutoPtr hederaId, Poco::UInt32 groupId, Poco::AutoPtr 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(hedera_topic); } Poco::AutoPtr HederaTopic::createTopic(Poco::AutoPtr operatorAccount, Poco::AutoPtr 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 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 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; } } }