From 509699cb09a28d883e80520dc3ba1f26053e7ddf Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 25 Feb 2023 09:45:37 +0100 Subject: [PATCH 01/30] Fix available balance --- src/Wallet/WalletGreen.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index 3cf062eae..15610cceb 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -3674,7 +3674,7 @@ namespace cn bool updated = false; /* First get the available and pending balances from the container */ - uint64_t actual = container->balance(ITransfersContainer::IncludeAllUnlocked); + uint64_t actual = container->balance(ITransfersContainer::IncludeKeyUnlocked); uint64_t pending = container->balance(ITransfersContainer::IncludeKeyNotUnlocked); /* Now update the overall balance (getBalance without parameters) */ @@ -3683,7 +3683,7 @@ namespace cn m_actualBalance += actual - it->actualBalance; updated = true; } - else + else if (it->actualBalance > actual) { m_actualBalance -= it->actualBalance - actual; updated = true; @@ -3694,7 +3694,7 @@ namespace cn m_pendingBalance += pending - it->pendingBalance; updated = true; } - else + else if (it->pendingBalance > pending) { m_pendingBalance -= it->pendingBalance - pending; updated = true; @@ -3706,15 +3706,13 @@ namespace cn container->getOutputs(transfers2, ITransfersContainer::IncludeTypeDeposit | ITransfersContainer::IncludeStateLocked | ITransfersContainer::IncludeStateSoftLocked); std::vector heights2; - for (auto transfer2 : transfers2) + for (const auto &transfer2 : transfers2) { crypto::Hash hash2 = transfer2.transactionHash; TransactionInformation info2; - bool ok2 = container->getTransactionInformation(hash2, info2, NULL, NULL); - if (ok2) + if (container->getTransactionInformation(hash2, info2, nullptr, nullptr)) { heights2.push_back(info2.blockHeight); - updated = true; } } uint64_t locked = calculateDepositsAmount(transfers2, m_currency, heights2); @@ -3725,13 +3723,14 @@ namespace cn container->getOutputs(transfers, ITransfersContainer::IncludeTypeDeposit | ITransfersContainer::IncludeStateUnlocked); std::vector heights; - for (auto transfer : transfers) + for (const auto &transfer : transfers) { crypto::Hash hash = transfer.transactionHash; TransactionInformation info; - bool ok = container->getTransactionInformation(hash, info, NULL, NULL); - assert(ok); - heights.push_back(info.blockHeight); + if (container->getTransactionInformation(hash, info, nullptr, nullptr)) + { + heights.push_back(info.blockHeight); + } } uint64_t unlocked = calculateDepositsAmount(transfers, m_currency, heights); @@ -3741,7 +3740,7 @@ namespace cn m_lockedDepositBalance += locked - it->lockedDepositBalance; updated = true; } - else + else if (it->lockedDepositBalance > locked) { m_lockedDepositBalance -= it->lockedDepositBalance - locked; updated = true; @@ -3752,7 +3751,7 @@ namespace cn m_unlockedDepositBalance += unlocked - it->unlockedDepositBalance; updated = true; } - else + else if (it->unlockedDepositBalance > unlocked) { m_unlockedDepositBalance -= it->unlockedDepositBalance - unlocked; updated = true; From e54a3ec3c6b79b3c77a1e54e9d6c9a280075e2a1 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 8 Jan 2023 19:44:33 +0100 Subject: [PATCH 02/30] Fix daemon-address usage --- src/Common/CommandLine.h | 6 ++++++ src/ConcealWallet/ConcealWallet.cpp | 6 +++--- src/ConcealWallet/Const.h | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Common/CommandLine.h b/src/Common/CommandLine.h index 4998c8335..2ae9b6122 100644 --- a/src/Common/CommandLine.h +++ b/src/Common/CommandLine.h @@ -159,6 +159,12 @@ namespace command_line return !value.empty(); } + template + bool has_arg_2(const boost::program_options::variables_map &vm, const arg_descriptor &arg) + { + auto value = vm[arg.name]; + return !value.empty() && !value.defaulted(); + } template T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor& arg) diff --git a/src/ConcealWallet/ConcealWallet.cpp b/src/ConcealWallet/ConcealWallet.cpp index 6b116604f..161c0e8c5 100644 --- a/src/ConcealWallet/ConcealWallet.cpp +++ b/src/ConcealWallet/ConcealWallet.cpp @@ -415,12 +415,12 @@ bool key_import = true; //---------------------------------------------------------------------------------------------------- bool conceal_wallet::init(const boost::program_options::variables_map& vm) { - handle_command_line(vm); - - if (!m_daemon_address.empty() && (!m_daemon_host.empty() || 0 != m_daemon_port)) { + if (command_line::has_arg_2(vm, arg_daemon_address) && (command_line::has_arg_2(vm, arg_daemon_host) || command_line::has_arg_2(vm, arg_daemon_port))) + { fail_msg_writer() << "you can't specify daemon host or port several times"; return false; } + handle_command_line(vm); if (m_daemon_host.empty()) { diff --git a/src/ConcealWallet/Const.h b/src/ConcealWallet/Const.h index cd2d6e55d..0fe899680 100644 --- a/src/ConcealWallet/Const.h +++ b/src/ConcealWallet/Const.h @@ -11,7 +11,7 @@ namespace { const command_line::arg_descriptor arg_daemon_address = { "daemon-address", "Use daemon instance at :", "" }; const command_line::arg_descriptor arg_daemon_host = { "daemon-host", "Use daemon instance at host instead of localhost", "" }; const command_line::arg_descriptor arg_password = { "password", "Wallet password", "", true }; - const command_line::arg_descriptor arg_daemon_port = { "daemon-port", "Use daemon instance at port instead of default", 0 }; + const command_line::arg_descriptor arg_daemon_port = { "daemon-port", "Use daemon instance at port instead of default", cn::RPC_DEFAULT_PORT }; const command_line::arg_descriptor arg_log_level = { "set_log", "", logging::INFO, true }; const command_line::arg_descriptor arg_testnet = { "testnet", "Used to deploy test nets. The daemon must be launched with --testnet flag", false }; const command_line::arg_descriptor< std::vector > arg_command = { "command", "" }; From d0ab5a913cfc8e2e6b36d0aabb42bead46600d20 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 1 Apr 2023 16:56:34 +0200 Subject: [PATCH 03/30] Migrate concealwallet to walletgreen --- include/ITransfersSynchronizer.h | 10 +- include/IWallet.h | 15 + src/ConcealWallet/ClientHelper.cpp | 95 ++-- src/ConcealWallet/ClientHelper.h | 20 +- src/ConcealWallet/ConcealWallet.cpp | 707 ++++++++++---------------- src/ConcealWallet/ConcealWallet.h | 33 +- src/ConcealWallet/TransferCmd.cpp | 17 +- src/ConcealWallet/TransferCmd.h | 12 +- src/ConcealWallet/main.cpp | 8 +- src/NodeRpcProxy/NodeRpcProxy.h | 98 ++-- src/PaymentGate/NodeFactory.cpp | 28 +- src/PaymentGate/WalletService.cpp | 37 -- src/Wallet/WalletGreen.cpp | 405 +++++++++++++-- src/Wallet/WalletGreen.h | 28 +- src/Wallet/WalletIndices.h | 2 + src/Wallet/WalletUtils.cpp | 42 ++ src/Wallet/WalletUtils.h | 2 + tests/UnitTests/TestWalletService.cpp | 10 + 18 files changed, 869 insertions(+), 700 deletions(-) diff --git a/include/ITransfersSynchronizer.h b/include/ITransfersSynchronizer.h index 5b7bf6873..c703c29d3 100644 --- a/include/ITransfersSynchronizer.h +++ b/include/ITransfersSynchronizer.h @@ -31,6 +31,7 @@ class ITransfersSubscription; class ITransfersObserver { public: + virtual ~ITransfersObserver() = default; virtual void onError(ITransfersSubscription* object, uint32_t height, std::error_code ec) { } @@ -53,7 +54,7 @@ class ITransfersObserver { class ITransfersSubscription : public IObservable < ITransfersObserver > { public: - virtual ~ITransfersSubscription() {} + virtual ~ITransfersSubscription() = default; virtual AccountPublicAddress getAddress() = 0; virtual ITransfersContainer& getContainer() = 0; @@ -61,17 +62,18 @@ class ITransfersSubscription : public IObservable < ITransfersObserver > { class ITransfersSynchronizerObserver { public: + virtual ~ITransfersSynchronizerObserver() = default; virtual void onBlocksAdded(const crypto::PublicKey& viewPublicKey, const std::vector& blockHashes) {} virtual void onBlockchainDetach(const crypto::PublicKey& viewPublicKey, uint32_t blockIndex) {} - virtual void onTransactionDeleteBegin(const crypto::PublicKey& viewPublicKey, crypto::Hash transactionHash) {} - virtual void onTransactionDeleteEnd(const crypto::PublicKey& viewPublicKey, crypto::Hash transactionHash) {} + virtual void onTransactionDeleteBegin(const crypto::PublicKey &viewPublicKey, const crypto::Hash &transactionHash) {} + virtual void onTransactionDeleteEnd(const crypto::PublicKey &viewPublicKey, const crypto::Hash &transactionHash) {} virtual void onTransactionUpdated(const crypto::PublicKey& viewPublicKey, const crypto::Hash& transactionHash, const std::vector& containers) {} }; class ITransfersSynchronizer : public IStreamSerializable { public: - virtual ~ITransfersSynchronizer() {} + virtual ~ITransfersSynchronizer() = default; virtual ITransfersSubscription& addSubscription(const AccountSubscription& acc) = 0; virtual bool removeSubscription(const AccountPublicAddress& acc) = 0; diff --git a/include/IWallet.h b/include/IWallet.h index 8a899a028..3d285a7bf 100644 --- a/include/IWallet.h +++ b/include/IWallet.h @@ -171,6 +171,12 @@ struct DepositsInBlockInfo std::vector deposits; }; +struct PaymentIdTransactions +{ + crypto::Hash paymentId; + std::vector transactions; +}; + class IWallet { public: @@ -181,6 +187,7 @@ class IWallet virtual void withdrawDeposit(DepositId depositId, std::string &transactionHash) = 0; virtual Deposit getDeposit(size_t depositIndex) const = 0; virtual void initializeWithViewKey(const std::string& path, const std::string& password, const crypto::SecretKey& viewSecretKey) = 0; + virtual void generateNewWallet(const std::string &path, const std::string &password) = 0; virtual void load(const std::string& path, const std::string& password, std::string& extra) = 0; virtual void load(const std::string& path, const std::string& password) = 0; virtual void shutdown() = 0; @@ -210,6 +217,8 @@ class IWallet virtual uint64_t getActualBalance(const std::string &address) const = 0; virtual uint64_t getPendingBalance() const = 0; virtual uint64_t getPendingBalance(const std::string &address) const = 0; + virtual uint64_t getDustBalance() const = 0; + virtual uint64_t getDustBalance(const std::string &address) const = 0; virtual uint64_t getLockedDepositBalance() const = 0; virtual uint64_t getLockedDepositBalance(const std::string &address) const = 0; @@ -239,6 +248,12 @@ class IWallet virtual void commitTransaction(size_t transactionId) = 0; virtual void rollbackUncommitedTransaction(size_t transactionId) = 0; + virtual std::string getReserveProof(const std::string &address, const uint64_t &reserve, const std::string &message) = 0; + virtual bool getTxProof(const crypto::Hash &transactionHash, const cn::AccountPublicAddress &address, const crypto::SecretKey &tx_key, std::string &signature) = 0; + virtual crypto::SecretKey getTransactionDeterministicSecretKey(crypto::Hash &transactionHash) const = 0; + virtual size_t createOptimizationTransaction(const std::string &address) = 0; + virtual std::vector getTransactionsByPaymentIds(const std::vector &paymentIds) = 0; + virtual void start() = 0; virtual void stop() = 0; diff --git a/src/ConcealWallet/ClientHelper.cpp b/src/ConcealWallet/ClientHelper.cpp index 081908330..14e39d194 100644 --- a/src/ConcealWallet/ClientHelper.cpp +++ b/src/ConcealWallet/ClientHelper.cpp @@ -47,7 +47,7 @@ namespace cn if (deposit.locked) status_str = "Locked"; - else if (deposit.spendingTransactionId == cn::WALLET_LEGACY_INVALID_TRANSACTION_ID) + else if (deposit.spendingTransactionId == cn::WALLET_INVALID_TRANSACTION_ID) status_str = "Unlocked"; else status_str = "Withdrawn"; @@ -65,17 +65,17 @@ namespace cn return deposit.spendingTransactionId; } - std::string client_helper::deposit_unlock_height(const cn::Deposit &deposit, const cn::WalletLegacyTransaction &txInfo) const + std::string client_helper::deposit_unlock_height(const cn::Deposit &deposit, const uint32_t &blockHeight) const { std::string unlock_str = ""; - if (txInfo.blockHeight > cn::parameters::CRYPTONOTE_MAX_BLOCK_NUMBER) + if (blockHeight > cn::parameters::CRYPTONOTE_MAX_BLOCK_NUMBER) { unlock_str = "Please wait."; } else { - unlock_str = std::to_string(txInfo.blockHeight + deposit_term(deposit)); + unlock_str = std::to_string(blockHeight + deposit_term(deposit)); } bool bad_unlock2 = unlock_str == "0"; @@ -87,19 +87,18 @@ namespace cn return unlock_str; } - std::string client_helper::deposit_height(const cn::WalletLegacyTransaction &txInfo) const + std::string client_helper::deposit_height(const uint32_t &blockHeight) const { std::string height_str = ""; - uint64_t deposit_height = txInfo.blockHeight; - bool bad_unlock = deposit_height > cn::parameters::CRYPTONOTE_MAX_BLOCK_NUMBER; + bool bad_unlock = blockHeight > cn::parameters::CRYPTONOTE_MAX_BLOCK_NUMBER; if (bad_unlock) { height_str = "Please wait."; } else { - height_str = std::to_string(deposit_height); + height_str = std::to_string(blockHeight); } bool bad_unlock2 = height_str == "0"; @@ -111,7 +110,7 @@ namespace cn return height_str; } - std::string client_helper::get_deposit_info(const cn::Deposit &deposit, cn::DepositId did, const Currency ¤cy, const cn::WalletLegacyTransaction &txInfo) const + std::string client_helper::get_deposit_info(const cn::Deposit &deposit, cn::DepositId did, const Currency ¤cy, const uint32_t &blockHeight) const { std::stringstream full_info; @@ -119,7 +118,7 @@ namespace cn std::setw(8) << makeCenteredString(8, std::to_string(did)) << " | " << std::setw(20) << makeCenteredString(20, deposit_amount(deposit, currency)) << " | " << std::setw(20) << makeCenteredString(20, deposit_interest(deposit, currency)) << " | " << - std::setw(16) << makeCenteredString(16, deposit_unlock_height(deposit, txInfo)) << " | " << + std::setw(16) << makeCenteredString(16, deposit_unlock_height(deposit, blockHeight)) << " | " << std::setw(12) << makeCenteredString(12, deposit_status(deposit)); std::string as_str = full_info.str(); @@ -127,15 +126,15 @@ namespace cn return as_str; } - std::string client_helper::get_full_deposit_info(const cn::Deposit &deposit, cn::DepositId did, const Currency ¤cy, const cn::WalletLegacyTransaction &txInfo) const + std::string client_helper::get_full_deposit_info(const cn::Deposit &deposit, cn::DepositId did, const Currency ¤cy, const uint32_t &blockHeight) const { std::stringstream full_info; full_info << "ID: " << std::to_string(did) << "\n" << "Amount: " << deposit_amount(deposit, currency) << "\n" << "Interest: " << deposit_interest(deposit, currency) << "\n" - << "Height: " << deposit_height(txInfo) << "\n" - << "Unlock Height: " << deposit_unlock_height(deposit, txInfo) << "\n" + << "Height: " << deposit_height(blockHeight) << "\n" + << "Unlock Height: " << deposit_unlock_height(deposit, blockHeight) << "\n" << "Status: " << deposit_status(deposit) << "\n"; std::string as_str = full_info.str(); @@ -143,7 +142,7 @@ namespace cn return as_str; } - std::string client_helper::list_deposit_item(const WalletLegacyTransaction& txInfo, Deposit deposit, std::string listed_deposit, DepositId id, const Currency ¤cy) + std::string client_helper::list_deposit_item(const WalletTransaction& txInfo, const Deposit& deposit, std::string listed_deposit, DepositId id, const Currency ¤cy) const { std::string format_amount = currency.formatAmount(deposit.amount); std::string format_interest = currency.formatAmount(deposit.interest); @@ -152,8 +151,8 @@ namespace cn std::stringstream ss_id(makeCenteredString(8, std::to_string(id))); std::stringstream ss_amount(makeCenteredString(20, format_amount)); std::stringstream ss_interest(makeCenteredString(20, format_interest)); - std::stringstream ss_height(makeCenteredString(16, deposit_height(txInfo))); - std::stringstream ss_unlockheight(makeCenteredString(16, deposit_unlock_height(deposit, txInfo))); + std::stringstream ss_height(makeCenteredString(16, deposit_height(txInfo.blockHeight))); + std::stringstream ss_unlockheight(makeCenteredString(16, deposit_unlock_height(deposit, txInfo.blockHeight))); std::stringstream ss_status(makeCenteredString(12, deposit_status(deposit))); ss_id >> std::setw(8); @@ -169,7 +168,7 @@ namespace cn return listed_deposit; } - std::string client_helper::list_tx_item(const WalletLegacyTransaction& txInfo, std::string listed_tx, const Currency ¤cy) + std::string client_helper::list_tx_item(const WalletTransaction& txInfo, std::string listed_tx, const Currency ¤cy) const { std::vector extraVec = asBinaryArray(txInfo.extra); @@ -212,7 +211,7 @@ namespace cn return listed_tx; } - bool client_helper::confirm_deposit(uint64_t term, uint64_t amount, bool is_testnet, const Currency& currency, logging::LoggerRef logger) + bool client_helper::confirm_deposit(uint32_t term, uint64_t amount, bool is_testnet, const Currency ¤cy, const logging::LoggerRef &logger) const { uint64_t interest = currency.calculateInterestV3(amount, term); uint64_t min_term = is_testnet ? parameters::TESTNET_DEPOSIT_MIN_TERM_V3 : parameters::DEPOSIT_MIN_TERM_V3; @@ -244,7 +243,7 @@ namespace cn return false; } - JsonValue client_helper::buildLoggerConfiguration(logging::Level level, const std::string& logfile) + JsonValue client_helper::buildLoggerConfiguration(logging::Level level, const std::string& logfile) const { using common::JsonValue; @@ -354,9 +353,9 @@ namespace cn if (initError) throw std::runtime_error("failed to load wallet: " + initError.message()); - logger(logging::INFO) << "Saving wallet..."; - save_wallet(*wallet, walletFileName, logger); - logger(logging::INFO, logging::BRIGHT_GREEN) << "Saving successful"; + // logger(logging::INFO) << "Saving wallet..."; + // save_wallet(*wallet, walletFileName, logger); + // logger(logging::INFO, logging::BRIGHT_GREEN) << "Saving successful"; return walletFileName; } @@ -389,9 +388,9 @@ namespace cn throw std::runtime_error("failed to load wallet: " + initError.message()); } - logger(logging::INFO) << "Saving wallet..."; - save_wallet(*wallet, walletFileName, logger); - logger(logging::INFO, logging::BRIGHT_GREEN) << "Saved successful"; + // logger(logging::INFO) << "Saving wallet..."; + // save_wallet(*wallet, walletFileName, logger); + // logger(logging::INFO, logging::BRIGHT_GREEN) << "Saved successful"; return walletFileName; } @@ -401,43 +400,21 @@ namespace cn } } - void client_helper::save_wallet(cn::IWalletLegacy& wallet, const std::string& walletFilename, logging::LoggerRef& logger) - { - logger(logging::INFO) << "Saving wallet..."; - - try - { - cn::WalletHelper::storeWallet(wallet, walletFilename); - logger(logging::INFO, logging::BRIGHT_GREEN) << "Saved successful"; - } - catch (std::exception& e) - { - logger(logging::ERROR, logging::BRIGHT_RED) << "Failed to store wallet: " << e.what(); - throw std::runtime_error("error saving wallet file '" + walletFilename + "'"); - } - } - - std::stringstream client_helper::balances(std::unique_ptr& wallet, const Currency& currency) + std::stringstream client_helper::balances(const cn::IWallet &wallet, const Currency ¤cy) const { std::stringstream balances; - - uint64_t full_balance = wallet->actualBalance() + wallet->pendingBalance() + wallet->actualDepositBalance() + wallet->pendingDepositBalance(); - std::string full_balance_text = "Total Balance: " + currency.formatAmount(full_balance) + "\n"; - - uint64_t non_deposit_unlocked_balance = wallet->actualBalance(); - std::string non_deposit_unlocked_balance_text = "Available: " + currency.formatAmount(non_deposit_unlocked_balance) + "\n"; - - uint64_t non_deposit_locked_balance = wallet->pendingBalance(); - std::string non_deposit_locked_balance_text = "Locked: " + currency.formatAmount(non_deposit_locked_balance) + "\n"; - - uint64_t deposit_unlocked_balance = wallet->actualDepositBalance(); - std::string deposit_locked_balance_text = "Unlocked Balance: " + currency.formatAmount(deposit_unlocked_balance) + "\n"; - - uint64_t deposit_locked_balance = wallet->pendingDepositBalance(); - std::string deposit_unlocked_balance_text = "Locked Deposits: " + currency.formatAmount(deposit_locked_balance) + "\n"; - balances << full_balance_text << non_deposit_unlocked_balance_text << non_deposit_locked_balance_text - << deposit_unlocked_balance_text << deposit_locked_balance_text; + uint64_t actualBalance = wallet.getActualBalance(); + uint64_t pendingBalance = wallet.getPendingBalance(); + uint64_t unlockedDepositBalance = wallet.getUnlockedDepositBalance(); + uint64_t lockedDepositBalance = wallet.getLockedDepositBalance(); + + uint64_t totalBalance = actualBalance + pendingBalance + unlockedDepositBalance + lockedDepositBalance; + balances << "Total Balance: " + currency.formatAmount(totalBalance) << std::endl + << "Available: " + currency.formatAmount(actualBalance) << std::endl + << "Locked: " + currency.formatAmount(pendingBalance) << std::endl + << "Unlocked Balance: " + currency.formatAmount(unlockedDepositBalance) << std::endl + << "Locked Deposits: " + currency.formatAmount(lockedDepositBalance); return balances; } diff --git a/src/ConcealWallet/ClientHelper.h b/src/ConcealWallet/ClientHelper.h index c94af5daf..26e057150 100644 --- a/src/ConcealWallet/ClientHelper.h +++ b/src/ConcealWallet/ClientHelper.h @@ -55,42 +55,42 @@ namespace cn /** * @return - returns unlock height from transaction blockheight + deposit term **/ - std::string deposit_unlock_height(const cn::Deposit &deposit, const cn::WalletLegacyTransaction &txInfo) const; + std::string deposit_unlock_height(const cn::Deposit &deposit, const uint32_t &blockHeight) const; /** * @return - returns deposit height **/ - std::string deposit_height(const cn::WalletLegacyTransaction &txInfo) const; + std::string deposit_height(const uint32_t &blockHeight) const; /** * @return - returns deposit info string for client output **/ - std::string get_deposit_info(const cn::Deposit &deposit, cn::DepositId did, const Currency ¤cy, const cn::WalletLegacyTransaction &txInfo) const; + std::string get_deposit_info(const cn::Deposit &deposit, cn::DepositId did, const Currency ¤cy, const uint32_t &blockHeight) const; /** * @return - returns full deposit info string for client output **/ - std::string get_full_deposit_info(const cn::Deposit &deposit, cn::DepositId did, const Currency ¤cy, const cn::WalletLegacyTransaction &txInfo) const; + std::string get_full_deposit_info(const cn::Deposit &deposit, cn::DepositId did, const Currency ¤cy, const uint32_t &blockHeight) const; /** * @return - returns deposit info string for file output **/ - std::string list_deposit_item(const WalletLegacyTransaction& txInfo, const Deposit deposit, std::string listed_deposit, DepositId id, const Currency ¤cy); + std::string list_deposit_item(const WalletTransaction& txInfo, const Deposit& deposit, std::string listed_deposit, DepositId id, const Currency ¤cy) const; /** * @return - returns transaction info string for file output **/ - std::string list_tx_item(const WalletLegacyTransaction& txInfo, std::string listed_tx, const Currency ¤cy); + std::string list_tx_item(const WalletTransaction& txInfo, std::string listed_tx, const Currency ¤cy) const; /** * @return - returns false if user rejects deposit */ - bool confirm_deposit(uint64_t term, uint64_t amount, bool is_testnet, const Currency& currency, logging::LoggerRef logger); + bool confirm_deposit(uint32_t term, uint64_t amount, bool is_testnet, const Currency& currency, const logging::LoggerRef& logger) const; /** * @return - returns logging config for file and client output */ - JsonValue buildLoggerConfiguration(logging::Level level, const std::string& logfile); + JsonValue buildLoggerConfiguration(logging::Level level, const std::string& logfile) const; /** * @return - returns a formatted url address @@ -101,11 +101,9 @@ namespace cn std::string tryToOpenWalletOrLoadKeysOrThrow(logging::LoggerRef& logger, std::unique_ptr& wallet, const std::string& walletFile, const std::string& password); - void save_wallet(cn::IWalletLegacy& wallet, const std::string& walletFilename, logging::LoggerRef& logger); - /** * @return - Displays all balances (main + deposits) */ - std::stringstream balances(std::unique_ptr& wallet, const Currency& currency); + std::stringstream balances(const cn::IWallet &wallet, const Currency ¤cy) const; }; } \ No newline at end of file diff --git a/src/ConcealWallet/ConcealWallet.cpp b/src/ConcealWallet/ConcealWallet.cpp index 161c0e8c5..92d44cdf1 100644 --- a/src/ConcealWallet/ConcealWallet.cpp +++ b/src/ConcealWallet/ConcealWallet.cpp @@ -42,9 +42,7 @@ #include "Wallet/WalletRpcServer.h" #include "Wallet/WalletUtils.h" -#include "WalletLegacy/WalletLegacy.h" #include "Wallet/LegacyKeysImporter.h" -#include "WalletLegacy/WalletHelper.h" #include "version.h" @@ -101,7 +99,7 @@ void printListDepositsHeader(LoggerRef& logger) { logger(INFO) << std::string(header.size(), '='); } -void printListTransfersItem(LoggerRef& logger, const WalletLegacyTransaction& txInfo, IWalletLegacy& wallet, const Currency& currency) { +void printListTransfersItem(LoggerRef& logger, const WalletTransaction& txInfo, IWallet& wallet, const Currency& currency, size_t transactionIndex) { std::vector extraVec = common::asBinaryArray(txInfo.extra); crypto::Hash paymentId; @@ -134,12 +132,14 @@ void printListTransfersItem(LoggerRef& logger, const WalletLegacyTransaction& tx logger(INFO, rowColor) << "payment ID: " << paymentIdStr; } - if (txInfo.totalAmount < 0) { - if (txInfo.transferCount > 0) { + if (txInfo.totalAmount < 0) + { + if (wallet.getTransactionTransferCount(transactionIndex) > 0) + { logger(INFO, rowColor) << "transfers:"; - for (TransferId id = txInfo.firstTransferId; id < txInfo.firstTransferId + txInfo.transferCount; ++id) { - WalletLegacyTransfer tr; - wallet.getTransfer(id, tr); + for (size_t id = 0; id < wallet.getTransactionTransferCount(transactionIndex); ++id) + { + WalletTransfer tr = wallet.getTransactionTransfer(transactionIndex, id); logger(INFO, rowColor) << tr.address << " " << std::setw(TOTAL_AMOUNT_MAX_WIDTH) << currency.formatAmount(tr.amount); } } @@ -216,7 +216,7 @@ bool splitUrlToHostAndUri(const std::string& aliasUrl, std::string& host, std::s return true; } -bool askAliasesTransfersConfirmation(const std::map>& aliases, const Currency& currency) { +bool askAliasesTransfersConfirmation(const std::map>& aliases, const Currency& currency) { std::cout << "Would you like to send money to the following addresses?" << std::endl; for (const auto& kv: aliases) { @@ -287,13 +287,15 @@ bool conceal_wallet::extended_help(const std::vector &args/* = std: return true; } -bool conceal_wallet::exit(const std::vector &args) { - m_consoleHandler.requestStop(); +bool conceal_wallet::exit(const std::vector &args) +{ + stop(); return true; } conceal_wallet::conceal_wallet(platform_system::Dispatcher& dispatcher, const cn::Currency& currency, logging::LoggerManager& log) : m_dispatcher(dispatcher), + m_stopEvent(m_dispatcher), m_daemon_port(0), m_currency(currency), logManager(log), @@ -384,9 +386,10 @@ std::string conceal_wallet::wallet_menu(bool do_ext) /* This function shows the number of outputs in the wallet that are below the dust threshold */ -bool conceal_wallet::show_dust(const std::vector& args) { - logger(INFO, BRIGHT_WHITE) << "Dust outputs: " << m_wallet->dustBalance() << std::endl; - return true; +bool conceal_wallet::show_dust(const std::vector &) +{ + logger(INFO, BRIGHT_WHITE) << "Dust outputs: " << m_wallet->getDustBalance(); + return true; } //---------------------------------------------------------------------------------------------------- @@ -546,18 +549,9 @@ bool conceal_wallet::init(const boost::program_options::variables_map& vm) { } this->m_node.reset(new NodeRpcProxy(m_daemon_host, m_daemon_port)); - - std::promise errorPromise; - std::future f_error = errorPromise.get_future(); - auto callback = [&errorPromise](std::error_code e) {errorPromise.set_value(e); }; - - m_node->addObserver(static_cast(this)); - m_node->init(callback); - auto error = f_error.get(); - if (error) { - fail_msg_writer() << "failed to init NodeRPCProxy: " << error.message(); - return false; - } + NodeInitObserver initObserver; + m_node->init(std::bind(&NodeInitObserver::initCompleted, &initObserver, std::placeholders::_1)); + initObserver.waitForInitEnd(); if (!m_generate_new.empty()) { std::string walletAddressFile = prepareWalletAddressFilename(m_generate_new); @@ -572,7 +566,8 @@ bool conceal_wallet::init(const boost::program_options::variables_map& vm) { return false; } - if (!writeAddressFile(walletAddressFile, m_wallet->getAddress())) { + if (!writeAddressFile(walletAddressFile, m_wallet->getAddress(0))) + { logger(WARNING, BRIGHT_RED) << "Couldn't write wallet address file: " + walletAddressFile; } } else if (!m_import_new.empty()) { @@ -641,45 +636,42 @@ bool conceal_wallet::init(const boost::program_options::variables_map& vm) { return false; } - if (!writeAddressFile(walletAddressFile, m_wallet->getAddress())) { + if (!writeAddressFile(walletAddressFile, m_wallet->getAddress(0))) + { logger(WARNING, BRIGHT_RED) << "Couldn't write wallet address file: " + walletAddressFile; } - } else { - m_wallet.reset(new WalletLegacy(m_currency, *m_node, logManager, m_testnet)); + } else { + m_wallet.reset(new WalletGreen(m_dispatcher, m_currency, *m_node, logManager)); - try { - m_wallet_file = m_chelper.tryToOpenWalletOrLoadKeysOrThrow(logger, m_wallet, m_wallet_file_arg, pwd_container.password()); - } catch (const std::exception& e) { + try + { + m_wallet->load(m_wallet_file_arg, pwd_container.password()); + m_wallet_file = m_wallet_file_arg; + success_msg_writer(true) << "Wallet loaded"; + } + catch (const std::exception &e) + { fail_msg_writer() << "failed to load wallet: " << e.what(); return false; } - m_wallet->addObserver(this); - m_node->addObserver(static_cast(this)); - - std::string tmp_str = m_wallet_file; - m_frmt_wallet_file = tmp_str.erase(tmp_str.size() - 7); - - logger(INFO, BRIGHT_WHITE) << "Opened wallet: " << m_wallet->getAddress(); - success_msg_writer() << "**********************************************************************\n" << "Use \"help\" command to see the list of available commands.\n" << "**********************************************************************"; } - + m_wallet->addObserver(this); return true; } //---------------------------------------------------------------------------------------------------- -bool conceal_wallet::deinit() { +bool conceal_wallet::deinit() +{ m_wallet->removeObserver(this); - m_node->removeObserver(static_cast(this)); - m_node->removeObserver(static_cast(this)); - if (!m_wallet.get()) + { return true; - + } return close_wallet(); } //---------------------------------------------------------------------------------------------------- @@ -703,34 +695,19 @@ void conceal_wallet::handle_command_line(const boost::program_options::variables bool conceal_wallet::new_wallet(const std::string &wallet_file, const std::string& password) { m_wallet_file = wallet_file; - m_wallet.reset(new WalletLegacy(m_currency, *m_node, logManager, m_testnet)); - m_node->addObserver(static_cast(this)); - m_wallet->addObserver(this); + m_wallet.reset(new WalletGreen(m_dispatcher, m_currency, *m_node, logManager)); try { - m_initResultPromise.reset(new std::promise()); - std::future f_initError = m_initResultPromise->get_future(); - m_wallet->initAndGenerate(password); - auto initError = f_initError.get(); - m_initResultPromise.reset(nullptr); - if (initError) { - fail_msg_writer() << "failed to generate new wallet: " << initError.message(); - return false; - } - - m_chelper.save_wallet(*m_wallet, m_wallet_file, logger); - - AccountKeys keys; - m_wallet->getAccountKeys(keys); - - std::string secretKeysData = std::string(reinterpret_cast(&keys.spendSecretKey), sizeof(keys.spendSecretKey)) + std::string(reinterpret_cast(&keys.viewSecretKey), sizeof(keys.viewSecretKey)); - std::string guiKeys = tools::base_58::encode_addr(cn::parameters::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, secretKeysData); + m_wallet->generateNewWallet(wallet_file, password); + KeyPair viewKey = m_wallet->getViewKey(); + KeyPair spendKey = m_wallet->getAddressSpendKey(0); + logger(INFO, BRIGHT_GREEN) << "ConcealWallet is an open-source, client-side, free wallet which allow you to send and receive CCX instantly on the blockchain. You are in control of your funds & your keys. When you generate a new wallet, login, send, receive or deposit $CCX everything happens locally. Your seed is never transmitted, received or stored. That's why its imperative to write, print or save your seed somewhere safe. The backup of keys is your responsibility. If you lose your seed, your account can not be recovered. The Conceal Team doesn't take any responsibility for lost funds due to nonexistent/missing/lost private keys." << std::endl << std::endl; - std::cout << "Wallet Address: " << m_wallet->getAddress() << std::endl; - std::cout << "Private spend key: " << common::podToHex(keys.spendSecretKey) << std::endl; - std::cout << "Private view key: " << common::podToHex(keys.viewSecretKey) << std::endl; - std::cout << "Mnemonic Seed: " << mnemonics::privateKeyToMnemonic(keys.spendSecretKey) << std::endl; + std::cout << "Wallet Address: " << m_wallet->getAddress(0) << std::endl; + std::cout << "Private spend key: " << common::podToHex(spendKey.secretKey) << std::endl; + std::cout << "Private view key: " << common::podToHex(viewKey.secretKey) << std::endl; + std::cout << "Mnemonic Seed: " << mnemonics::privateKeyToMnemonic(spendKey.secretKey) << std::endl; } catch (const std::exception& e) { fail_msg_writer() << "failed to generate new wallet: " << e.what(); @@ -748,39 +725,16 @@ bool conceal_wallet::new_wallet(const std::string &wallet_file, const std::strin return true; } //---------------------------------------------------------------------------------------------------- -bool conceal_wallet::new_wallet(crypto::SecretKey &secret_key, crypto::SecretKey &view_key, const std::string &wallet_file, const std::string& password) { +bool conceal_wallet::new_wallet(const crypto::SecretKey &secret_key, const crypto::SecretKey &view_key, const std::string &wallet_file, const std::string& password) { m_wallet_file = wallet_file; - m_wallet.reset(new WalletLegacy(m_currency, *m_node.get(), logManager, m_testnet)); - m_node->addObserver(static_cast(this)); - m_wallet->addObserver(this); + m_wallet.reset(new WalletGreen(m_dispatcher, m_currency, *m_node, logManager)); try { - m_initResultPromise.reset(new std::promise()); - std::future f_initError = m_initResultPromise->get_future(); - - AccountKeys wallet_keys; - wallet_keys.spendSecretKey = secret_key; - wallet_keys.viewSecretKey = view_key; - crypto::secret_key_to_public_key(wallet_keys.spendSecretKey, wallet_keys.address.spendPublicKey); - crypto::secret_key_to_public_key(wallet_keys.viewSecretKey, wallet_keys.address.viewPublicKey); - - m_wallet->initWithKeys(wallet_keys, password); - auto initError = f_initError.get(); - m_initResultPromise.reset(nullptr); - if (initError) { - fail_msg_writer() << "failed to generate new wallet: " << initError.message(); - return false; - } - - m_chelper.save_wallet(*m_wallet, m_wallet_file, logger); - - AccountKeys keys; - m_wallet->getAccountKeys(keys); - - logger(INFO, BRIGHT_WHITE) << - "Imported wallet: " << m_wallet->getAddress() << std::endl; + m_wallet->initializeWithViewKey(wallet_file, password, view_key); + std::string address = m_wallet->createAddress(secret_key); + logger(INFO, BRIGHT_WHITE) << "Imported wallet: " << address << std::endl; } catch (const std::exception& e) { @@ -802,7 +756,7 @@ bool conceal_wallet::new_wallet(crypto::SecretKey &secret_key, crypto::SecretKey //---------------------------------------------------------------------------------------------------- bool conceal_wallet::close_wallet() { - m_chelper.save_wallet(*m_wallet, m_wallet_file, logger); + m_wallet->save(); logger(logging::INFO, logging::BRIGHT_GREEN) << "Closing wallet..."; m_wallet->removeObserver(this); @@ -812,25 +766,27 @@ bool conceal_wallet::close_wallet() } //---------------------------------------------------------------------------------------------------- -bool conceal_wallet::save(const std::vector &args) +bool conceal_wallet::save(const std::vector &) { - m_chelper.save_wallet(*m_wallet, m_wallet_file, logger); + m_wallet->save(); return true; } -bool conceal_wallet::reset(const std::vector &args) { +bool conceal_wallet::reset(const std::vector &) +{ + m_wallet->removeObserver(this); { std::unique_lock lock(m_walletSynchronizedMutex); m_walletSynchronized = false; } - m_wallet->reset(); + m_wallet->reset(0); + m_wallet->addObserver(this); success_msg_writer(true) << "Reset completed successfully."; std::unique_lock lock(m_walletSynchronizedMutex); - while (!m_walletSynchronized) { - m_walletSynchronizedCV.wait(lock); - } + m_walletSynchronizedCV.wait(lock, [this] + { return m_walletSynchronized; }); std::cout << std::endl; @@ -852,13 +808,13 @@ bool conceal_wallet::get_reserve_proof(const std::vector &args) return true; } } else { - reserve = m_wallet->actualBalance(); + reserve = m_wallet->getActualBalance(); } try { - const std::string sig_str = m_wallet->getReserveProof(reserve, args.size() == 2 ? args[1] : ""); + const std::string sig_str = m_wallet->getReserveProof(m_wallet->getAddress(0), reserve, args.size() == 2 ? args[1] : ""); - //logger(INFO, BRIGHT_WHITE) << "\n\n" << sig_str << "\n\n" << std::endl; + logger(INFO, BRIGHT_WHITE) << "\n\n" << sig_str << "\n\n" << std::endl; const std::string filename = "balance_proof_" + args[0] + "_CCX.txt"; boost::system::error_code ec; @@ -904,104 +860,67 @@ bool conceal_wallet::get_tx_proof(const std::vector &args) } std::string sig_str; - crypto::SecretKey tx_key, tx_key2; - bool r = m_wallet->get_tx_key(txid, tx_key); + crypto::SecretKey tx_key = m_wallet->getTransactionDeterministicSecretKey(txid); + bool r = tx_key != NULL_SECRET_KEY; + crypto::SecretKey tx_key2; - if (args.size() == 3) { + if (args.size() == 3) + { crypto::Hash tx_key_hash; size_t size; - if (!common::fromHex(args[2], &tx_key_hash, sizeof(tx_key_hash), size) || size != sizeof(tx_key_hash)) { + if (!common::fromHex(args[2], &tx_key_hash, sizeof(tx_key_hash), size) || size != sizeof(tx_key_hash)) + { fail_msg_writer() << "failed to parse tx_key"; return true; } - tx_key2 = *(struct crypto::SecretKey *) &tx_key_hash; + tx_key2 = *(struct crypto::SecretKey *)&tx_key_hash; - if (r) { - if (args.size() == 3 && tx_key != tx_key2) { - fail_msg_writer() << "Tx secret key was found for the given txid, but you've also provided another tx secret key which doesn't match the found one."; - return true; - } - } - tx_key = tx_key2; - } else { - if (!r) { - fail_msg_writer() << "Tx secret key wasn't found in the wallet file. Provide it as the optional third parameter if you have it elsewhere."; + if (r && args.size() == 3 && tx_key != tx_key2) + { + fail_msg_writer() << "Tx secret key was found for the given txid, but you've also provided another tx secret key which doesn't match the found one."; return true; } + + tx_key = tx_key2; + } + else if (!r) + { + fail_msg_writer() << "Tx secret key wasn't found in the wallet file. Provide it as the optional third parameter if you have it elsewhere."; + return true; } - if (m_wallet->getTxProof(txid, address, tx_key, sig_str)) { + if (m_wallet->getTxProof(txid, address, tx_key, sig_str)) + { success_msg_writer() << "Signature: " << sig_str << std::endl; } return true; } -//---------------------------------------------------------------------------------------------------- -void conceal_wallet::initCompleted(std::error_code result) { - if (m_initResultPromise.get() != nullptr) { - m_initResultPromise->set_value(result); - } -} -//---------------------------------------------------------------------------------------------------- -void conceal_wallet::connectionStatusUpdated(bool connected) { - if (connected) { - logger(INFO, GREEN) << "Wallet connected to daemon."; - } else { - printConnectionError(); - } -} -//---------------------------------------------------------------------------------------------------- -void conceal_wallet::externalTransactionCreated(cn::TransactionId transactionId) { - WalletLegacyTransaction txInfo; - m_wallet->getTransaction(transactionId, txInfo); - - std::stringstream logPrefix; - if (txInfo.blockHeight == WALLET_LEGACY_UNCONFIRMED_TRANSACTION_HEIGHT) { - logPrefix << "Unconfirmed"; - } else { - logPrefix << "Height " << txInfo.blockHeight << ','; - } - - if (txInfo.totalAmount >= 0) { - logger(INFO, GREEN) << - logPrefix.str() << " transaction " << common::podToHex(txInfo.hash) << - ", received " << m_currency.formatAmount(txInfo.totalAmount); - } else { - logger(INFO, MAGENTA) << - logPrefix.str() << " transaction " << common::podToHex(txInfo.hash) << - ", spent " << m_currency.formatAmount(static_cast(-txInfo.totalAmount)); - } - - if (txInfo.blockHeight == WALLET_LEGACY_UNCONFIRMED_TRANSACTION_HEIGHT) { - m_refresh_progress_reporter.update(m_node->getLastLocalBlockHeight(), true); - } else { - m_refresh_progress_reporter.update(txInfo.blockHeight, true); - } -} -//---------------------------------------------------------------------------------------------------- -void conceal_wallet::synchronizationCompleted(std::error_code result) { +void conceal_wallet::synchronizationCompleted(std::error_code result) +{ std::unique_lock lock(m_walletSynchronizedMutex); m_walletSynchronized = true; m_walletSynchronizedCV.notify_one(); } -void conceal_wallet::synchronizationProgressUpdated(uint32_t current, uint32_t total) { +void conceal_wallet::synchronizationProgressUpdated(uint32_t processedBlockCount, uint32_t totalBlockCount) +{ std::unique_lock lock(m_walletSynchronizedMutex); - if (!m_walletSynchronized) { - m_refresh_progress_reporter.update(current, false); + if (!m_walletSynchronized) + { + m_refresh_progress_reporter.update(processedBlockCount, false); } } -bool conceal_wallet::show_balance(const std::vector& args/* = std::vector()*/) +bool conceal_wallet::show_balance(const std::vector &args) { if (!args.empty()) { logger(ERROR) << "Usage: balance"; return true; } - - std::stringstream balances = m_chelper.balances(m_wallet, m_currency); + std::stringstream balances = m_chelper.balances(*m_wallet, m_currency); logger(INFO) << balances.str(); return true; @@ -1015,13 +934,12 @@ bool conceal_wallet::sign_message(const std::vector& args) return true; } - AccountKeys keys; - m_wallet->getAccountKeys(keys); + KeyPair keys = m_wallet->getAddressSpendKey(0); crypto::Hash message_hash; crypto::Signature sig; crypto::cn_fast_hash(args[0].data(), args[0].size(), message_hash); - crypto::generate_signature(message_hash, keys.address.spendPublicKey, keys.spendSecretKey, sig); + crypto::generate_signature(message_hash, keys.publicKey, keys.secretKey, sig); success_msg_writer() << "Sig" << tools::base_58::encode(std::string(reinterpret_cast(&sig))); @@ -1070,7 +988,7 @@ bool conceal_wallet::verify_signature(const std::vector& args) /* CREATE INTEGRATED ADDRESS */ /* take a payment Id as an argument and generate an integrated wallet address */ -bool conceal_wallet::create_integrated(const std::vector& args/* = std::vector()*/) +bool conceal_wallet::create_integrated(const std::vector& args) { /* check if there is a payment id */ @@ -1089,7 +1007,7 @@ bool conceal_wallet::create_integrated(const std::vector& args/* = return true; } - std::string address = m_wallet->getAddress(); + std::string address = m_wallet->getAddress(0); uint64_t prefix; cn::AccountPublicAddress addr; @@ -1116,48 +1034,32 @@ bool conceal_wallet::create_integrated(const std::vector& args/* = /* ---------------------------------------------------------------------------------------- */ - -bool conceal_wallet::export_keys(const std::vector& args/* = std::vector()*/) { - AccountKeys keys; - m_wallet->getAccountKeys(keys); - - std::string secretKeysData = std::string(reinterpret_cast(&keys.spendSecretKey), sizeof(keys.spendSecretKey)) + std::string(reinterpret_cast(&keys.viewSecretKey), sizeof(keys.viewSecretKey)); - std::string guiKeys = tools::base_58::encode_addr(cn::parameters::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, secretKeysData); - - logger(INFO, BRIGHT_GREEN) << std::endl << "ConcealWallet is an open-source, client-side, free wallet which allow you to send and receive CCX instantly on the blockchain. You are in control of your funds & your keys. When you generate a new wallet, login, send, receive or deposit $CCX everything happens locally. Your seed is never transmitted, received or stored. That's why its imperative to write, print or save your seed somewhere safe. The backup of keys is your responsibility. If you lose your seed, your account can not be recovered. The Conceal Team doesn't take any responsibility for lost funds due to nonexistent/missing/lost private keys." << std::endl << std::endl; - - std::cout << "Private spend key: " << common::podToHex(keys.spendSecretKey) << std::endl; - std::cout << "Private view key: " << common::podToHex(keys.viewSecretKey) << std::endl; - - crypto::PublicKey unused_dummy_variable; - crypto::SecretKey deterministic_private_view_key; - - AccountBase::generateViewFromSpend(keys.spendSecretKey, deterministic_private_view_key, unused_dummy_variable); - - bool deterministic_private_keys = deterministic_private_view_key == keys.viewSecretKey; - - /* dont show a mnemonic seed if it is an old non-deterministic wallet */ - if (deterministic_private_keys) { - std::cout << "Mnemonic seed: " << mnemonics::privateKeyToMnemonic(keys.spendSecretKey) << std::endl << std::endl; - } - +bool conceal_wallet::export_keys(const std::vector &) +{ + std::cout << get_wallet_keys(); return true; } //---------------------------------------------------------------------------------------------------- -bool conceal_wallet::show_incoming_transfers(const std::vector& args) { +bool conceal_wallet::show_incoming_transfers(const std::vector &) +{ bool hasTransfers = false; size_t transactionsCount = m_wallet->getTransactionCount(); - for (size_t trantransactionNumber = 0; trantransactionNumber < transactionsCount; ++trantransactionNumber) { - WalletLegacyTransaction txInfo; - m_wallet->getTransaction(trantransactionNumber, txInfo); - if (txInfo.totalAmount < 0) continue; + for (size_t trantransactionNumber = 0; trantransactionNumber < transactionsCount; ++trantransactionNumber) + { + WalletTransaction txInfo = m_wallet->getTransaction(trantransactionNumber); + if (txInfo.totalAmount < 0) + { + continue; + } hasTransfers = true; logger(INFO) << " amount \t tx id"; - logger(INFO, GREEN) << - std::setw(21) << m_currency.formatAmount(txInfo.totalAmount) << '\t' << common::podToHex(txInfo.hash); + logger(INFO, GREEN) << std::setw(21) << m_currency.formatAmount(txInfo.totalAmount) << '\t' << common::podToHex(txInfo.hash); } - if (!hasTransfers) success_msg_writer() << "No incoming transfers"; + if (!hasTransfers) + { + success_msg_writer() << "No incoming transfers"; + } return true; } @@ -1166,8 +1068,6 @@ bool conceal_wallet::listTransfers(const std::vector& args) { bool haveBlockHeight = false; std::string blockHeightString = ""; uint32_t blockHeight = 0; - WalletLegacyTransaction txInfo; - /* get block height from arguments */ if (args.empty()) @@ -1180,11 +1080,11 @@ bool conceal_wallet::listTransfers(const std::vector& args) { } size_t transactionsCount = m_wallet->getTransactionCount(); - for (size_t trantransactionNumber = 0; trantransactionNumber < transactionsCount; ++trantransactionNumber) + for (size_t transactionIndex = 0; transactionIndex < transactionsCount; ++transactionIndex) { - m_wallet->getTransaction(trantransactionNumber, txInfo); - if (txInfo.state != WalletLegacyTransactionState::Active || txInfo.blockHeight == WALLET_LEGACY_UNCONFIRMED_TRANSACTION_HEIGHT) { + WalletTransaction transaction = m_wallet->getTransaction(transactionIndex); + if (transaction.state != WalletTransactionState::SUCCEEDED || transaction.blockHeight == WALLET_UNCONFIRMED_TRANSACTION_HEIGHT) { continue; } @@ -1194,10 +1094,10 @@ bool conceal_wallet::listTransfers(const std::vector& args) { } if (haveBlockHeight == false) { - printListTransfersItem(logger, txInfo, *m_wallet, m_currency); + printListTransfersItem(logger, transaction, *m_wallet, m_currency, transactionIndex); } else { - if (txInfo.blockHeight >= blockHeight) { - printListTransfersItem(logger, txInfo, *m_wallet, m_currency); + if (transaction.blockHeight >= blockHeight) { + printListTransfersItem(logger, transaction, *m_wallet, m_currency, transactionIndex); } @@ -1238,8 +1138,8 @@ bool conceal_wallet::show_payments(const std::vector &args) { auto payments = m_wallet->getTransactionsByPaymentIds(paymentIds); - for (auto& payment : payments) { - for (auto& transaction : payment.transactions) { + for (const auto& payment : payments) { + for (const auto& transaction : payment.transactions) { success_msg_writer(true) << common::podToHex(payment.paymentId) << '\t' << common::podToHex(transaction.hash) << '\t' << @@ -1269,59 +1169,45 @@ bool conceal_wallet::show_blockchain_height(const std::vector& args return true; } //---------------------------------------------------------------------------------------------------- -bool conceal_wallet::show_num_unlocked_outputs(const std::vector& args) { - try { +bool conceal_wallet::show_num_unlocked_outputs(const std::vector &) +{ + try + { std::vector unlocked_outputs = m_wallet->getUnspentOutputs(); success_msg_writer() << "Count: " << unlocked_outputs.size(); - for (const auto& out : unlocked_outputs) { + for (const auto &out : unlocked_outputs) + { success_msg_writer() << "Key: " << out.transactionPublicKey << " amount: " << m_currency.formatAmount(out.amount); } - } catch (std::exception &e) { + } + catch (std::exception &e) + { fail_msg_writer() << "failed to get outputs: " << e.what(); } - return true; } //---------------------------------------------------------------------------------------------------- bool conceal_wallet::optimize_outputs(const std::vector& args) { - try { - cn::WalletHelper::SendCompleteResultObserver sent; - WalletHelper::IWalletRemoveObserverGuard removeGuard(*m_wallet, sent); - - std::vector transfers; - std::vector messages; - std::string extraString; - uint64_t fee = cn::parameters::MINIMUM_FEE_V2; - uint64_t mixIn = 0; - uint64_t unlockTimestamp = 0; - uint64_t ttl = 0; - crypto::SecretKey transactionSK; - cn::TransactionId tx = m_wallet->sendTransaction(transactionSK, transfers, fee, extraString, mixIn, unlockTimestamp, messages, ttl); - if (tx == WALLET_LEGACY_INVALID_TRANSACTION_ID) { + try + { + cn::TransactionId tx = m_wallet->createOptimizationTransaction(m_wallet->getAddress(0)); + if (tx == WALLET_INVALID_TRANSACTION_ID) + { fail_msg_writer() << "Can't send money"; - return true; - } - - std::error_code sendError = sent.wait(tx); - removeGuard.removeObserver(); - - if (sendError) { - fail_msg_writer() << sendError.message(); - return true; + return false; } - - cn::WalletLegacyTransaction txInfo; - m_wallet->getTransaction(tx, txInfo); + cn::WalletTransaction txInfo = m_wallet->getTransaction(tx); success_msg_writer(true) << "Money successfully sent, transaction " << common::podToHex(txInfo.hash); - success_msg_writer(true) << "Transaction secret key " << common::podToHex(transactionSK); - - m_chelper.save_wallet(*m_wallet, m_wallet_file, logger); - } catch (const std::system_error& e) { + } + catch (const std::system_error &e) + { fail_msg_writer() << e.what(); - } catch (const std::exception& e) { + return false; + } + catch (const std::exception &e) + { fail_msg_writer() << e.what(); - } catch (...) { - fail_msg_writer() << "unknown error"; + return false; } return true; @@ -1335,56 +1221,17 @@ bool conceal_wallet::optimize_all_outputs(const std::vector& args) uint64_t num_unlocked_outputs = 0; try { - num_unlocked_outputs = m_wallet->getNumUnlockedOutputs(); + num_unlocked_outputs = m_wallet->getUnspentOutputsCount(); success_msg_writer() << "Total outputs: " << num_unlocked_outputs; } catch (std::exception &e) { fail_msg_writer() << "failed to get outputs: " << e.what(); } - uint64_t remainder = num_unlocked_outputs % 100; - uint64_t rounds = (num_unlocked_outputs - remainder) / 100; - success_msg_writer() << "Total optimization rounds: " << rounds; - for(uint64_t a = 1; a < rounds; a = a + 1 ) { - - try { - cn::WalletHelper::SendCompleteResultObserver sent; - WalletHelper::IWalletRemoveObserverGuard removeGuard(*m_wallet, sent); - - std::vector transfers; - std::vector messages; - std::string extraString; - uint64_t fee = cn::parameters::MINIMUM_FEE_V2; - uint64_t mixIn = 0; - uint64_t unlockTimestamp = 0; - uint64_t ttl = 0; - crypto::SecretKey transactionSK; - cn::TransactionId tx = m_wallet->sendTransaction(transactionSK, transfers, fee, extraString, mixIn, unlockTimestamp, messages, ttl); - if (tx == WALLET_LEGACY_INVALID_TRANSACTION_ID) { - fail_msg_writer() << "Can't send money"; - return true; - } - - std::error_code sendError = sent.wait(tx); - removeGuard.removeObserver(); - - if (sendError) { - fail_msg_writer() << sendError.message(); - return true; - } - - cn::WalletLegacyTransaction txInfo; - m_wallet->getTransaction(tx, txInfo); - success_msg_writer(true) << a << ". Optimization transaction successfully sent, transaction " << common::podToHex(txInfo.hash); - - m_chelper.save_wallet(*m_wallet, m_wallet_file, logger); - } catch (const std::system_error& e) { - fail_msg_writer() << e.what(); - } catch (const std::exception& e) { - fail_msg_writer() << e.what(); - } catch (...) { - fail_msg_writer() << "unknown error"; - } + bool success = true; + while (success && m_wallet->getUnspentOutputsCount() > 100) + { + success = optimize_outputs({}); } return true; } @@ -1482,16 +1329,18 @@ bool conceal_wallet::transfer(const std::vector &args) { } for (auto& kv: cmd.aliases) { - std::copy(std::move_iterator::iterator>(kv.second.begin()), - std::move_iterator::iterator>(kv.second.end()), + std::copy(std::move_iterator::iterator>(kv.second.begin()), + std::move_iterator::iterator>(kv.second.end()), std::back_inserter(cmd.dsts)); } } - std::vector messages; - for (auto dst : cmd.dsts) { - for (auto msg : cmd.messages) { - messages.emplace_back(TransactionMessage{ msg, dst.address }); + std::vector messages; + for (const auto &dst : cmd.dsts) + { + for (const auto &msg : cmd.messages) + { + messages.emplace_back(WalletMessage{dst.address, msg}); } } @@ -1505,9 +1354,6 @@ bool conceal_wallet::transfer(const std::vector &args) { std::string extraString; std::copy(cmd.extra.begin(), cmd.extra.end(), std::back_inserter(extraString)); - WalletHelper::IWalletRemoveObserverGuard removeGuard(*m_wallet, sent); - - /* set static mixin of 4*/ cmd.fake_outs_count = cn::parameters::MINIMUM_MIXIN; /* force minimum fee */ @@ -1515,27 +1361,19 @@ bool conceal_wallet::transfer(const std::vector &args) { cmd.fee = cn::parameters::MINIMUM_FEE_V2; } - crypto::SecretKey transactionSK; - cn::TransactionId tx = m_wallet->sendTransaction(transactionSK, cmd.dsts, cmd.fee, extraString, cmd.fake_outs_count, 0, messages, ttl); - if (tx == WALLET_LEGACY_INVALID_TRANSACTION_ID) { - fail_msg_writer() << "Can't send money"; - return true; - } + cn::TransactionParameters sendParams; + sendParams.destinations = cmd.dsts; + sendParams.messages = messages; + sendParams.extra = extraString; + sendParams.unlockTimestamp = ttl; + sendParams.changeDestination = m_wallet->getAddress(0); - std::error_code sendError = sent.wait(tx); - removeGuard.removeObserver(); - - if (sendError) { - fail_msg_writer() << sendError.message(); - return true; - } + crypto::SecretKey transactionSK; + size_t transactionId = m_wallet->transfer(sendParams, transactionSK); - cn::WalletLegacyTransaction txInfo; - m_wallet->getTransaction(tx, txInfo); + cn::WalletTransaction txInfo = m_wallet->getTransaction(transactionId); success_msg_writer(true) << "Money successfully sent, transaction hash: " << common::podToHex(txInfo.hash); - success_msg_writer(true) << "Transaction secret key " << common::podToHex(transactionSK); - - m_chelper.save_wallet(*m_wallet, m_wallet_file, logger); + success_msg_writer(true) << "Transaction secret key " << common::podToHex(transactionSK); } catch (const std::system_error& e) { fail_msg_writer() << e.what(); } catch (const std::exception& e) { @@ -1547,27 +1385,35 @@ bool conceal_wallet::transfer(const std::vector &args) { return true; } //---------------------------------------------------------------------------------------------------- -bool conceal_wallet::run() { +bool conceal_wallet::run() +{ { std::unique_lock lock(m_walletSynchronizedMutex); - while (!m_walletSynchronized) { - m_walletSynchronizedCV.wait(lock); + while (!m_walletSynchronized) + { + m_walletSynchronizedCV.wait(lock, [this] + { return m_walletSynchronized; }); } } std::cout << std::endl; - std::string addr_start = m_wallet->getAddress().substr(0, 10); - m_consoleHandler.start(false, "[" + addr_start + "]: ", common::console::Color::BrightYellow); + std::string addr_start = m_wallet->getAddress(0).substr(0, 10); + m_consoleHandler.start(true, "[" + addr_start + "]: ", common::console::Color::BrightYellow); + m_stopEvent.wait(); return true; } //---------------------------------------------------------------------------------------------------- -void conceal_wallet::stop() { +void conceal_wallet::stop() +{ + m_dispatcher.remoteSpawn([this] + { m_stopEvent.set(); }); m_consoleHandler.requestStop(); } //---------------------------------------------------------------------------------------------------- -bool conceal_wallet::print_address(const std::vector &args/* = std::vector()*/) { - success_msg_writer() << m_wallet->getAddress(); +bool conceal_wallet::print_address(const std::vector &) +{ + success_msg_writer() << m_wallet->getAddress(0); return true; } //---------------------------------------------------------------------------------------------------- @@ -1579,40 +1425,51 @@ void conceal_wallet::printConnectionError() const { fail_msg_writer() << "wallet failed to connect to daemon (" << m_daemon_address << ")."; } -bool conceal_wallet::save_keys_to_file(const std::vector& args) +std::string conceal_wallet::get_wallet_keys() const { - if (!args.empty()) - { - logger(ERROR) << "Usage: \"export_keys\""; - return true; - } + KeyPair viewKey = m_wallet->getViewKey(); + KeyPair spendKey = m_wallet->getAddressSpendKey(0); + std::stringstream stream; - std::string formatted_wal_str = m_frmt_wallet_file + "_conceal_backup.txt"; - std::ofstream backup_file(formatted_wal_str); + stream << std::endl + << "ConcealWallet is an open-source, client-side, free wallet which allow you to send and receive CCX instantly on the blockchain. You are in control of your funds & your keys. When you generate a new wallet, login, send, receive or deposit $CCX everything happens locally. Your seed is never transmitted, received or stored. That's why its imperative to write, print or save your seed somewhere safe. The backup of keys is your responsibility. If you lose your seed, your account can not be recovered. The Conceal Team doesn't take any responsibility for lost funds due to nonexistent/missing/lost private keys." << std::endl + << std::endl; - AccountKeys keys; - m_wallet->getAccountKeys(keys); - - std::string priv_key = "\t\tConceal Keys Backup\n\n"; - priv_key += "Wallet file name: " + m_wallet_file + "\n"; - priv_key += "Private spend key: " + common::podToHex(keys.spendSecretKey) + "\n"; - priv_key += "Private view key: " + common::podToHex(keys.viewSecretKey) + "\n"; + stream << "Private spend key: " << common::podToHex(spendKey.secretKey) << std::endl; + stream << "Private view key: " << common::podToHex(viewKey.secretKey) << std::endl; crypto::PublicKey unused_dummy_variable; crypto::SecretKey deterministic_private_view_key; - AccountBase::generateViewFromSpend(keys.spendSecretKey, deterministic_private_view_key, unused_dummy_variable); - bool deterministic_private_keys = deterministic_private_view_key == keys.viewSecretKey; + AccountBase::generateViewFromSpend(spendKey.secretKey, deterministic_private_view_key, unused_dummy_variable); + + bool deterministic_private_keys = deterministic_private_view_key == viewKey.secretKey; /* dont show a mnemonic seed if it is an old non-deterministic wallet */ - if (deterministic_private_keys) { - std::cout << "Mnemonic seed: " << mnemonics::privateKeyToMnemonic(keys.spendSecretKey) << std::endl << std::endl; + if (deterministic_private_keys) + { + stream << "Mnemonic seed: " << mnemonics::privateKeyToMnemonic(spendKey.secretKey) << std::endl + << std::endl; } + return stream.str(); +} - backup_file << priv_key; +bool conceal_wallet::save_keys_to_file(const std::vector& args) +{ + if (!args.empty()) + { + logger(ERROR) << "Usage: \"save_keys\""; + return true; + } + + std::string backup_filename = common::RemoveExtension(m_wallet_file) + "_conceal_backup.txt"; + std::ofstream backup_file(backup_filename); + + backup_file << "Conceal Keys Backup" << std::endl + << get_wallet_keys(); logger(INFO, BRIGHT_GREEN) << "Wallet keys have been saved to the current folder where \"concealwallet\" is located as \"" - << formatted_wal_str << "."; + << backup_filename << "\"."; return true; } @@ -1651,8 +1508,8 @@ bool conceal_wallet::save_all_txs_to_file(const std::vector &args) logger(INFO) << "Preparing file and transactions..."; /* create filename and file */ - std::string formatted_wal_str = m_frmt_wallet_file + "_conceal_transactions.txt"; - std::ofstream tx_file(formatted_wal_str); + std::string tx_filename = common::RemoveExtension(m_wallet_file) + "_conceal_transactions.txt"; + std::ofstream tx_file(tx_filename); /* create header for listed txs */ std::string header = common::makeCenteredString(32, "timestamp (UTC)") + " | "; @@ -1672,17 +1529,16 @@ bool conceal_wallet::save_all_txs_to_file(const std::vector &args) /* create line from string */ std::string listed_tx; - /* get tx struct */ - WalletLegacyTransaction txInfo; - /* go through tx ids for the amount of transactions in wallet */ for (TransactionId i = 0; i < tx_count; ++i) { + /* get tx struct */ + WalletTransaction txInfo; /* get tx to list from i */ - m_wallet->getTransaction(i, txInfo); + txInfo = m_wallet->getTransaction(i); /* check tx state */ - if (txInfo.state != WalletLegacyTransactionState::Active || txInfo.blockHeight == WALLET_LEGACY_UNCONFIRMED_TRANSACTION_HEIGHT) { + if (txInfo.state != WalletTransactionState::SUCCEEDED || txInfo.blockHeight == WALLET_LEGACY_UNCONFIRMED_TRANSACTION_HEIGHT) { continue; } @@ -1693,18 +1549,18 @@ bool conceal_wallet::save_all_txs_to_file(const std::vector &args) tx_file << formatted_item_tx; /* tell user about progress */ - logger(INFO) << "Transaction: " << i << " was pushed to " << formatted_wal_str; + logger(INFO) << "Transaction: " << i << " was pushed to " << tx_filename; } /* tell user job complete */ logger(INFO, BRIGHT_GREEN) << "All transactions have been saved to the current folder where \"concealwallet\" is located as \"" - << formatted_wal_str << "\"."; + << tx_filename << "\"."; /* if user uses "save_txs_to_file true" then we go through the deposits */ if (include_deposits == true) { /* get total deposits in wallet */ - size_t deposit_count = m_wallet->getDepositCount(); + size_t deposit_count = m_wallet->getWalletDepositCount(); /* check wallet txs before doing work */ if (deposit_count == 0) { @@ -1737,11 +1593,11 @@ bool conceal_wallet::save_all_txs_to_file(const std::vector &args) for (DepositId id = 0; id < deposit_count; ++id) { /* get deposit info from id and store it to deposit */ - Deposit deposit = m_wallet->get_deposit(id); - cn::WalletLegacyTransaction txInfo; + Deposit deposit = m_wallet->getDeposit(id); + cn::WalletTransaction txInfo; /* get deposit info and use its transaction in the chain */ - m_wallet->getTransaction(deposit.creatingTransactionId, txInfo); + txInfo = m_wallet->getTransaction(deposit.creatingTransactionId); /* grab deposit info */ std::string formatted_item_d = m_chelper.list_deposit_item(txInfo, deposit, listed_deposit, id, m_currency); @@ -1750,20 +1606,20 @@ bool conceal_wallet::save_all_txs_to_file(const std::vector &args) tx_file << formatted_item_d; /* tell user about progress */ - logger(INFO) << "Deposit: " << id << " was pushed to " << formatted_wal_str; + logger(INFO) << "Deposit: " << id << " was pushed to " << tx_filename; } /* tell user job complete */ logger(INFO, BRIGHT_GREEN) << "All deposits have been saved to the end of the file current folder where \"concealwallet\" is located as \"" - << formatted_wal_str << "\"."; + << tx_filename << "\"."; } return true; } -bool conceal_wallet::list_deposits(const std::vector &args) +bool conceal_wallet::list_deposits(const std::vector &) { - bool haveDeposits = m_wallet->getDepositCount() > 0; + bool haveDeposits = m_wallet->getWalletDepositCount() > 0; if (!haveDeposits) { @@ -1774,14 +1630,13 @@ bool conceal_wallet::list_deposits(const std::vector &args) printListDepositsHeader(logger); /* go through deposits ids for the amount of deposits in wallet */ - for (DepositId id = 0; id < m_wallet->getDepositCount(); ++id) + for (DepositId id = 0; id < m_wallet->getWalletDepositCount(); ++id) { /* get deposit info from id and store it to deposit */ - Deposit deposit = m_wallet->get_deposit(id); - cn::WalletLegacyTransaction txInfo; - m_wallet->getTransaction(deposit.creatingTransactionId, txInfo); + Deposit deposit = m_wallet->getDeposit(id); + cn::WalletTransaction txInfo = m_wallet->getTransaction(deposit.creatingTransactionId); - logger(INFO) << m_chelper.get_deposit_info(deposit, id, m_currency, txInfo); + logger(INFO) << m_chelper.get_deposit_info(deposit, id, m_currency, txInfo.blockHeight); } return true; @@ -1803,7 +1658,7 @@ bool conceal_wallet::deposit(const std::vector &args) **/ uint64_t min_term = m_currency.depositMinTermV3(); uint64_t max_term = m_currency.depositMaxTermV3(); - uint64_t deposit_term = boost::lexical_cast(args[0]) * min_term; + uint64_t deposit_term = boost::lexical_cast(args[0]) * min_term; /* Now validate the deposit term and the amount */ if (deposit_term < min_term) @@ -1841,38 +1696,12 @@ bool conceal_wallet::deposit(const std::vector &args) return true; } + std::string address = m_wallet->getAddress(0); + std::string tx_hash; logger(INFO) << "Creating deposit..."; - /* Use defaults for fee + mix in */ - uint64_t deposit_fee = cn::parameters::MINIMUM_FEE_V2; - uint64_t deposit_mix_in = cn::parameters::MINIMUM_MIXIN; - - cn::WalletHelper::SendCompleteResultObserver sent; - WalletHelper::IWalletRemoveObserverGuard removeGuard(*m_wallet, sent); - - cn::TransactionId tx = m_wallet->deposit(deposit_term, deposit_amount, deposit_fee, deposit_mix_in); - - if (tx == WALLET_LEGACY_INVALID_DEPOSIT_ID) - { - fail_msg_writer() << "Can't deposit money"; - return true; - } - - std::error_code sendError = sent.wait(tx); - removeGuard.removeObserver(); - - if (sendError) - { - fail_msg_writer() << sendError.message(); - return true; - } - - cn::WalletLegacyTransaction d_info; - m_wallet->getTransaction(tx, d_info); - success_msg_writer(true) << "Money successfully sent, transaction hash: " << common::podToHex(d_info.hash) - << "\n\tID: " << d_info.firstDepositId; - - m_chelper.save_wallet(*m_wallet, m_wallet_file, logger); + m_wallet->createDeposit(deposit_amount, deposit_term, address, address, tx_hash); + success_msg_writer(true) << "Money successfully sent, transaction hash: " << tx_hash; } catch (const std::system_error& e) { @@ -1900,44 +1729,20 @@ bool conceal_wallet::withdraw(const std::vector &args) try { - if (m_wallet->getDepositCount() == 0) + if (m_wallet->getWalletDepositCount() == 0) { logger(ERROR) << "No deposits have been made in this wallet."; return true; } uint64_t deposit_id = boost::lexical_cast(args[0]); - uint64_t deposit_fee = cn::parameters::MINIMUM_FEE_V2; - - cn::WalletHelper::SendCompleteResultObserver sent; - WalletHelper::IWalletRemoveObserverGuard removeGuard(*m_wallet, sent); - - cn::TransactionId tx = m_wallet->withdrawDeposit(deposit_id, deposit_fee); - - if (tx == WALLET_LEGACY_INVALID_DEPOSIT_ID) - { - fail_msg_writer() << "Can't withdraw money"; - return true; - } - - std::error_code sendError = sent.wait(tx); - removeGuard.removeObserver(); - - if (sendError) - { - fail_msg_writer() << sendError.message(); - return true; - } - - cn::WalletLegacyTransaction d_info; - m_wallet->getTransaction(tx, d_info); - success_msg_writer(true) << "Money successfully sent, transaction hash: " << common::podToHex(d_info.hash); - - m_chelper.save_wallet(*m_wallet, m_wallet_file, logger); + std::string tx_hash; + m_wallet->withdrawDeposit(deposit_id, tx_hash); + success_msg_writer(true) << "Money successfully sent, transaction hash: " << tx_hash; } catch (std::exception &e) { - fail_msg_writer() << "failed to withdraw deposit: " << e.what(); + fail_msg_writer() << "Failed to withdraw deposit: " << e.what(); } return true; @@ -1950,18 +1755,20 @@ bool conceal_wallet::deposit_info(const std::vector &args) logger(ERROR) << "Usage: withdraw "; return true; } - uint64_t deposit_id = boost::lexical_cast(args[0]); cn::Deposit deposit; - if (!m_wallet->getDeposit(deposit_id, deposit)) + try + { + deposit = m_wallet->getDeposit(deposit_id); + } + catch (const std::exception &e) { - logger(ERROR, BRIGHT_RED) << "Error: Invalid deposit id: " << deposit_id; + logger(ERROR, BRIGHT_RED) << "Error: " << e.what(); return false; } - cn::WalletLegacyTransaction txInfo; - m_wallet->getTransaction(deposit.creatingTransactionId, txInfo); + cn::WalletTransaction txInfo = m_wallet->getTransaction(deposit.creatingTransactionId); - logger(INFO) << m_chelper.get_full_deposit_info(deposit, deposit_id, m_currency, txInfo); + logger(INFO) << m_chelper.get_full_deposit_info(deposit, deposit_id, m_currency, txInfo.blockHeight); return true; } diff --git a/src/ConcealWallet/ConcealWallet.h b/src/ConcealWallet/ConcealWallet.h index 02aedb0c2..bb5e2847e 100644 --- a/src/ConcealWallet/ConcealWallet.h +++ b/src/ConcealWallet/ConcealWallet.h @@ -14,7 +14,7 @@ #include -#include "IWalletLegacy.h" +#include "Wallet/WalletGreen.h" #include "PasswordContainer.h" #include "ClientHelper.h" @@ -35,7 +35,7 @@ namespace cn /************************************************************************/ /* */ /************************************************************************/ - class conceal_wallet : public cn::INodeObserver, public cn::IWalletLegacyObserver, public cn::INodeRpcProxyObserver { + class conceal_wallet : public IBlockchainSynchronizerObserver { public: conceal_wallet(platform_system::Dispatcher& dispatcher, const cn::Currency& currency, logging::LoggerManager& log); @@ -55,7 +55,7 @@ namespace cn private: - logging::LoggerMessage success_msg_writer(bool color = false) { + logging::LoggerMessage success_msg_writer(bool color = false) const{ return logger(logging::INFO, color ? logging::GREEN : logging::DEFAULT); } @@ -70,7 +70,7 @@ namespace cn bool run_console_handler(); bool new_wallet(const std::string &wallet_file, const std::string& password); - bool new_wallet(crypto::SecretKey &secret_key, crypto::SecretKey &view_key, const std::string &wallet_file, const std::string& password); + bool new_wallet(const crypto::SecretKey &secret_key, const crypto::SecretKey &view_key, const std::string &wallet_file, const std::string& password); bool open_wallet(const std::string &wallet_file, const std::string& password); bool close_wallet(); @@ -111,28 +111,18 @@ namespace cn std::string resolveAlias(const std::string& aliasUrl); void printConnectionError() const; + std::string get_wallet_keys() const; - //---------------- IWalletLegacyObserver ------------------------- - virtual void initCompleted(std::error_code result) override; - virtual void externalTransactionCreated(cn::TransactionId transactionId) override; - virtual void synchronizationCompleted(std::error_code result) override; - virtual void synchronizationProgressUpdated(uint32_t current, uint32_t total) override; - //---------------------------------------------------------- - - //----------------- INodeRpcProxyObserver -------------------------- - virtual void connectionStatusUpdated(bool connected) override; - //---------------------------------------------------------- + void synchronizationCompleted(std::error_code result) override; + void synchronizationProgressUpdated(uint32_t processedBlockCount, uint32_t totalBlockCount) override; friend class refresh_progress_reporter_t; class refresh_progress_reporter_t { public: - refresh_progress_reporter_t(cn::conceal_wallet& conceal_wallet) + explicit refresh_progress_reporter_t(cn::conceal_wallet& conceal_wallet) : m_conceal_wallet(conceal_wallet) - , m_blockchain_height(0) - , m_blockchain_height_update_time() - , m_print_time() { } @@ -159,14 +149,12 @@ namespace cn m_blockchain_height_update_time = std::chrono::system_clock::now(); } - private: cn::conceal_wallet& m_conceal_wallet; - uint64_t m_blockchain_height; + uint64_t m_blockchain_height = 0; std::chrono::system_clock::time_point m_blockchain_height_update_time; std::chrono::system_clock::time_point m_print_time; }; - private: std::string m_wallet_file_arg; std::string m_generate_new; std::string m_import_new; @@ -185,11 +173,12 @@ namespace cn const cn::Currency& m_currency; logging::LoggerManager& logManager; platform_system::Dispatcher& m_dispatcher; + platform_system::Event m_stopEvent; logging::LoggerRef logger; cn::client_helper m_chelper; std::unique_ptr m_node; - std::unique_ptr m_wallet; + std::unique_ptr m_wallet; refresh_progress_reporter_t m_refresh_progress_reporter; bool m_walletSynchronized; diff --git a/src/ConcealWallet/TransferCmd.cpp b/src/ConcealWallet/TransferCmd.cpp index 5f6ea3a28..14b2ce0e0 100644 --- a/src/ConcealWallet/TransferCmd.cpp +++ b/src/ConcealWallet/TransferCmd.cpp @@ -9,19 +9,20 @@ #include "Common/StringTools.h" #include "CryptoNoteCore/CryptoNoteTools.h" #include "CryptoNoteCore/CryptoNoteBasicImpl.h" +#include "CryptoNoteCore/TransactionExtra.h" +#include "CryptoNoteCore/CryptoNoteFormatUtils.h" using namespace logging; namespace cn { - transfer_cmd::transfer_cmd(const cn::Currency& currency, std::string remote_fee_address) : + transfer_cmd::transfer_cmd(const cn::Currency& currency, const std::string& remote_fee_address) : m_currency(currency), - m_remote_address(remote_fee_address), - fake_outs_count(0), - fee(currency.minimumFeeV2()) { + fee(currency.minimumFeeV2()), + m_remote_address(remote_fee_address) { } - bool transfer_cmd::parseTx(LoggerRef& logger, const std::vector &args) + bool transfer_cmd::parseTx(const LoggerRef& logger, const std::vector &args) { ArgumentReader::const_iterator> ar(args.begin(), args.end()); @@ -89,8 +90,8 @@ namespace cn arg = address; } - WalletLegacyTransfer destination; - WalletLegacyTransfer feeDestination; + WalletOrder destination; + WalletOrder feeDestination; cn::TransactionDestinationEntry de; std::string aliasUrl; @@ -115,7 +116,7 @@ namespace cn } else { - aliases[aliasUrl].emplace_back(WalletLegacyTransfer{"", static_cast(de.amount)}); + aliases[aliasUrl].emplace_back(WalletOrder{"", de.amount}); } /* Remote node transactions fees are 10000 X */ diff --git a/src/ConcealWallet/TransferCmd.h b/src/ConcealWallet/TransferCmd.h index cb49042b7..026fa926f 100644 --- a/src/ConcealWallet/TransferCmd.h +++ b/src/ConcealWallet/TransferCmd.h @@ -5,8 +5,8 @@ #pragma once +#include "IWallet.h" #include "CryptoNoteCore/Currency.h" -#include "WalletLegacy/WalletLegacy.h" #include "Common/StringTools.h" #include @@ -19,18 +19,18 @@ namespace cn { public: const cn::Currency& m_currency; - size_t fake_outs_count; - std::vector dsts; + size_t fake_outs_count = 0; + std::vector dsts; std::vector extra; uint64_t fee; - std::map> aliases; + std::map> aliases; std::vector messages; uint64_t ttl = 0; std::string m_remote_address; - transfer_cmd(const cn::Currency& currency, std::string remote_fee_address); + transfer_cmd(const cn::Currency& currency, const std::string& remote_fee_address); - bool parseTx(LoggerRef& logger, const std::vector &args); + bool parseTx(const LoggerRef& logger, const std::vector &args); }; template diff --git a/src/ConcealWallet/main.cpp b/src/ConcealWallet/main.cpp index 55b8f7590..417aa1ffd 100644 --- a/src/ConcealWallet/main.cpp +++ b/src/ConcealWallet/main.cpp @@ -89,7 +89,7 @@ int main(int argc, char* argv[]) return 1; //set up logging options - Level logLevel = DEBUGGING; + Level logLevel = INFO; if (command_line::has_arg(vm, arg_log_level)) logLevel = static_cast(command_line::get_arg(vm, arg_log_level)); @@ -166,8 +166,8 @@ int main(int argc, char* argv[]) { walletFileName = m_chelper.tryToOpenWalletOrLoadKeysOrThrow(logger, wallet, wallet_file, wallet_password); - std::stringstream balances = m_chelper.balances(wallet, currency); - logger(INFO) << balances.str(); + // std::stringstream balances = m_chelper.balances(wallet, currency); + // logger(INFO) << balances.str(); logger(INFO, BRIGHT_GREEN) << "Loaded ok"; } @@ -195,7 +195,7 @@ int main(int argc, char* argv[]) logger(INFO) << "Stopped wallet rpc server"; logger(logging::INFO) << "Saving wallet..."; - m_chelper.save_wallet(*wallet, walletFileName, logger); + // m_chelper.save_wallet(*wallet, walletFileName, logger); logger(logging::INFO, logging::BRIGHT_GREEN) << "Saving successful"; } else diff --git a/src/NodeRpcProxy/NodeRpcProxy.h b/src/NodeRpcProxy/NodeRpcProxy.h index 4e724fc73..9ba9ca419 100644 --- a/src/NodeRpcProxy/NodeRpcProxy.h +++ b/src/NodeRpcProxy/NodeRpcProxy.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "Common/ObserverManager.h" #include "INode.h" @@ -29,47 +30,75 @@ class HttpClient; class INodeRpcProxyObserver { public: - virtual ~INodeRpcProxyObserver() {} + virtual ~INodeRpcProxyObserver() = default; virtual void connectionStatusUpdated(bool connected) {} }; +class NodeInitObserver +{ +public: + NodeInitObserver() + { + initFuture = initPromise.get_future(); + } + + void initCompleted(std::error_code result) + { + initPromise.set_value(result); + } + + void waitForInitEnd() + { + std::error_code ec = initFuture.get(); + if (ec) + { + throw std::system_error(ec); + } + return; + } + +private: + std::promise initPromise; + std::future initFuture; +}; + class NodeRpcProxy : public cn::INode { public: NodeRpcProxy(const std::string& nodeHost, unsigned short nodePort); - virtual ~NodeRpcProxy(); + ~NodeRpcProxy() override; - virtual bool addObserver(cn::INodeObserver* observer) override; - virtual bool removeObserver(cn::INodeObserver* observer) override; + bool addObserver(cn::INodeObserver* observer) override; + bool removeObserver(cn::INodeObserver* observer) override; virtual bool addObserver(cn::INodeRpcProxyObserver* observer); virtual bool removeObserver(cn::INodeRpcProxyObserver* observer); - virtual void init(const Callback& callback) override; - virtual bool shutdown() override; - - virtual size_t getPeerCount() const override; - virtual uint32_t getLastLocalBlockHeight() const override; - virtual uint32_t getLastKnownBlockHeight() const override; - virtual uint32_t getLocalBlockCount() const override; - virtual uint32_t getKnownBlockCount() const override; - virtual uint64_t getLastLocalBlockTimestamp() const override; - - virtual void relayTransaction(const cn::Transaction& transaction, const Callback& callback) override; - virtual void getRandomOutsByAmounts(std::vector&& amounts, uint64_t outsCount, std::vector& result, const Callback& callback) override; - virtual void getNewBlocks(std::vector&& knownBlockIds, std::vector& newBlocks, uint32_t& startHeight, const Callback& callback) override; - virtual void getTransactionOutsGlobalIndices(const crypto::Hash& transactionHash, std::vector& outsGlobalIndices, const Callback& callback) override; - virtual void queryBlocks(std::vector&& knownBlockIds, uint64_t timestamp, std::vector& newBlocks, uint32_t& startHeight, const Callback& callback) override; - virtual void getPoolSymmetricDifference(std::vector&& knownPoolTxIds, crypto::Hash knownBlockId, bool& isBcActual, + void init(const Callback& callback) override; + bool shutdown() override; + + size_t getPeerCount() const override; + uint32_t getLastLocalBlockHeight() const override; + uint32_t getLastKnownBlockHeight() const override; + uint32_t getLocalBlockCount() const override; + uint32_t getKnownBlockCount() const override; + uint64_t getLastLocalBlockTimestamp() const override; + + void relayTransaction(const cn::Transaction& transaction, const Callback& callback) override; + void getRandomOutsByAmounts(std::vector&& amounts, uint64_t outsCount, std::vector& result, const Callback& callback) override; + void getNewBlocks(std::vector&& knownBlockIds, std::vector& newBlocks, uint32_t& startHeight, const Callback& callback) override; + void getTransactionOutsGlobalIndices(const crypto::Hash& transactionHash, std::vector& outsGlobalIndices, const Callback& callback) override; + void queryBlocks(std::vector&& knownBlockIds, uint64_t timestamp, std::vector& newBlocks, uint32_t& startHeight, const Callback& callback) override; + void getPoolSymmetricDifference(std::vector&& knownPoolTxIds, crypto::Hash knownBlockId, bool& isBcActual, std::vector>& newTxs, std::vector& deletedTxIds, const Callback& callback) override; - virtual void getMultisignatureOutputByGlobalIndex(uint64_t amount, uint32_t gindex, MultisignatureOutput& out, const Callback& callback) override; - virtual void getBlocks(const std::vector& blockHeights, std::vector>& blocks, const Callback& callback) override; + void getMultisignatureOutputByGlobalIndex(uint64_t amount, uint32_t gindex, MultisignatureOutput& out, const Callback& callback) override; + void getBlocks(const std::vector& blockHeights, std::vector>& blocks, const Callback& callback) override; - virtual void getBlocks(const std::vector& blockHashes, std::vector& blocks, const Callback& callback) override; - virtual void getBlocks(uint64_t timestampBegin, uint64_t timestampEnd, uint32_t blocksNumberLimit, std::vector& blocks, uint32_t& blocksNumberWithinTimestamps, const Callback& callback) override; - virtual void getTransactions(const std::vector& transactionHashes, std::vector& transactions, const Callback& callback) override; - virtual void getTransactionsByPaymentId(const crypto::Hash& paymentId, std::vector& transactions, const Callback& callback) override; - virtual void getPoolTransactions(uint64_t timestampBegin, uint64_t timestampEnd, uint32_t transactionsNumberLimit, std::vector& transactions, uint64_t& transactionsNumberWithinTimestamps, const Callback& callback) override; - virtual void isSynchronized(bool& syncStatus, const Callback& callback) override; + void getBlocks(const std::vector& blockHashes, std::vector& blocks, const Callback& callback) override; + void getBlocks(uint64_t timestampBegin, uint64_t timestampEnd, uint32_t blocksNumberLimit, std::vector& blocks, uint32_t& blocksNumberWithinTimestamps, const Callback& callback) override; + void getTransactions(const std::vector& transactionHashes, std::vector& transactions, const Callback& callback) override; + void getTransactionsByPaymentId(const crypto::Hash& paymentId, std::vector& transactions, const Callback& callback) override; + void getPoolTransactions(uint64_t timestampBegin, uint64_t timestampEnd, uint32_t transactionsNumberLimit, std::vector& transactions, uint64_t& transactionsNumberWithinTimestamps, const Callback& callback) override; + void isSynchronized(bool& syncStatus, const Callback& callback) override; unsigned int rpcTimeout() const { return m_rpcTimeout; } void rpcTimeout(unsigned int val) { m_rpcTimeout = val; } @@ -98,16 +127,16 @@ class NodeRpcProxy : public cn::INode { std::vector& newBlocks, uint32_t& startHeight); std::error_code doGetPoolSymmetricDifference(std::vector&& knownPoolTxIds, crypto::Hash knownBlockId, bool& isBcActual, std::vector>& newTxs, std::vector& deletedTxIds); - virtual void getTransaction(const crypto::Hash &transactionHash, cn::Transaction &transaction, const Callback &callback) override; + void getTransaction(const crypto::Hash &transactionHash, cn::Transaction &transaction, const Callback &callback) override; std::error_code doGetTransaction(const crypto::Hash &transactionHash, cn::Transaction &transaction); - void scheduleRequest(std::function&& procedure, const Callback& callback); -template - std::error_code binaryCommand(const std::string& url, const Request& req, Response& res); + void scheduleRequest(std::function &&procedure, const Callback &callback); + template + std::error_code binaryCommand(const std::string &url, const Request &req, Response &res); template - std::error_code jsonCommand(const std::string& url, const Request& req, Response& res); + std::error_code jsonCommand(const std::string &url, const Request &req, Response &res); template - std::error_code jsonRpcCommand(const std::string& method, const Request& req, Response& res); + std::error_code jsonRpcCommand(const std::string &method, const Request &req, Response &res); enum State { STATE_NOT_INITIALIZED, @@ -115,7 +144,6 @@ template STATE_INITIALIZED }; -private: State m_state = STATE_NOT_INITIALIZED; std::mutex m_mutex; std::condition_variable m_cv_initialized; diff --git a/src/PaymentGate/NodeFactory.cpp b/src/PaymentGate/NodeFactory.cpp index b99629362..925a09517 100644 --- a/src/PaymentGate/NodeFactory.cpp +++ b/src/PaymentGate/NodeFactory.cpp @@ -77,30 +77,6 @@ class NodeRpcStub: public cn::INode { }; - -class NodeInitObserver { -public: - NodeInitObserver() { - initFuture = initPromise.get_future(); - } - - void initCompleted(std::error_code result) { - initPromise.set_value(result); - } - - void waitForInitEnd() { - std::error_code ec = initFuture.get(); - if (ec) { - throw std::system_error(ec); - } - return; - } - -private: - std::promise initPromise; - std::future initFuture; -}; - NodeFactory::NodeFactory() = default; NodeFactory::~NodeFactory() = default; @@ -108,8 +84,8 @@ NodeFactory::~NodeFactory() = default; cn::INode* NodeFactory::createNode(const std::string& daemonAddress, uint16_t daemonPort) { std::unique_ptr node(new cn::NodeRpcProxy(daemonAddress, daemonPort)); - NodeInitObserver initObserver; - node->init(std::bind(&NodeInitObserver::initCompleted, &initObserver, std::placeholders::_1)); + cn::NodeInitObserver initObserver; + node->init(std::bind(&cn::NodeInitObserver::initCompleted, &initObserver, std::placeholders::_1)); initObserver.waitForInitEnd(); return node.release(); diff --git a/src/PaymentGate/WalletService.cpp b/src/PaymentGate/WalletService.cpp index 97ce49086..9f580f322 100644 --- a/src/PaymentGate/WalletService.cpp +++ b/src/PaymentGate/WalletService.cpp @@ -34,7 +34,6 @@ #include "NodeFactory.h" #include "Wallet/WalletGreen.h" -#include "Wallet/LegacyKeysImporter.h" #include "Wallet/WalletErrors.h" #include "Wallet/WalletUtils.h" #include "WalletServiceErrorCategory.h" @@ -385,28 +384,6 @@ namespace payment_service } // namespace - void createWalletFile(std::fstream &walletFile, const std::string &filename) - { - boost::filesystem::path pathToWalletFile(filename); - boost::filesystem::path directory = pathToWalletFile.parent_path(); - if (!directory.empty() && !tools::directoryExists(directory.string())) - { - throw std::runtime_error("Directory does not exist: " + directory.string()); - } - - walletFile.open(filename.c_str(), std::fstream::in | std::fstream::out | std::fstream::binary); - if (walletFile) - { - walletFile.close(); - throw std::runtime_error("Wallet file already exists"); - } - - walletFile.open(filename.c_str(), std::fstream::out); - walletFile.close(); - - walletFile.open(filename.c_str(), std::fstream::in | std::fstream::out | std::fstream::binary); - } - void saveWallet(cn::IWallet &wallet, std::fstream &walletFile, bool saveDetailed = true, bool saveCache = true) { wallet.save(); @@ -517,20 +494,6 @@ namespace payment_service log(logging::INFO) << "Wallet is saved"; } // namespace payment_service - void importLegacyKeys(const std::string &legacyKeysFile, const WalletConfiguration &conf) - { - std::stringstream archive; - - cn::importLegacyKeys(legacyKeysFile, conf.walletPassword, archive); - - std::fstream walletFile; - createWalletFile(walletFile, conf.walletFile); - - archive.flush(); - walletFile << archive.rdbuf(); - walletFile.flush(); - } - WalletService::WalletService( const cn::Currency ¤cy, platform_system::Dispatcher &sys, diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index 15610cceb..ca976e522 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -21,6 +21,7 @@ #include "ITransaction.h" +#include "Common/Base58.h" #include "Common/ScopeExit.h" #include "Common/ShuffleGenerator.h" #include "Common/StdInputStream.h" @@ -422,7 +423,7 @@ namespace cn auto getTransactionCompleted = std::promise(); auto getTransactionWaitFuture = getTransactionCompleted.get_future(); cn::Transaction tx; - m_node.getTransaction(std::move(transactionHash), std::ref(tx), + m_node.getTransaction(transactionHash, std::ref(tx), [&getTransactionCompleted](std::error_code ec) { auto detachedPromise = std::move(getTransactionCompleted); detachedPromise.set_value(ec); @@ -756,6 +757,21 @@ namespace cn m_logger(INFO, BRIGHT_WHITE) << "Container initialized with view secret key, public view key " << common::podToHex(viewPublicKey); } + void WalletGreen::generateNewWallet(const std::string &path, const std::string &password) + { + crypto::SecretKey viewSecretKey; + cn::KeyPair spendKey; + + crypto::generate_keys(spendKey.publicKey, spendKey.secretKey); + + crypto::PublicKey viewPublicKey; + + cn::AccountBase::generateViewFromSpend(spendKey.secretKey, viewSecretKey, viewPublicKey); + + initializeWithViewKey(path, password, viewSecretKey); + createAddress(spendKey.secretKey); + } + void WalletGreen::shutdown() { throwIfNotInitialized(); @@ -1831,6 +1847,49 @@ namespace cn return wallet.pendingBalance; } + uint64_t WalletGreen::getDustBalance() const + { + throwIfNotInitialized(); + throwIfStopped(); + + const auto &walletsIndex = m_walletsContainer.get(); + uint64_t money = 0; + for (const auto &wallet : walletsIndex) + { + const ITransfersContainer *container = wallet.container; + std::vector outputs; + container->getOutputs(outputs, ITransfersContainer::IncludeKeyUnlocked); + for (const auto &output : outputs) + { + if (output.amount < m_currency.defaultDustThreshold()) + { + money += output.amount; + } + } + } + return money; + } + + uint64_t WalletGreen::getDustBalance(const std::string &address) const + { + throwIfNotInitialized(); + throwIfStopped(); + + const auto &wallet = getWalletRecord(address); + uint64_t money = 0; + const ITransfersContainer *container = wallet.container; + std::vector outputs; + container->getOutputs(outputs, ITransfersContainer::IncludeKeyUnlocked); + for (const auto &output : outputs) + { + if (output.amount < m_currency.defaultDustThreshold()) + { + money += output.amount; + } + } + return money; + } + size_t WalletGreen::getTransactionCount() const { throwIfNotInitialized(); @@ -1862,7 +1921,15 @@ namespace cn throw std::system_error(make_error_code(cn::error::DEPOSIT_DOESNOT_EXIST)); } - return m_deposits.get()[depositIndex]; + Deposit deposit = m_deposits.get()[depositIndex]; + + uint32_t knownBlockHeight = m_node.getLastKnownBlockHeight(); + if (knownBlockHeight > deposit.unlockHeight) + { + deposit.locked = false; + } + + return deposit; } size_t WalletGreen::getTransactionTransferCount(size_t transactionIndex) const @@ -2702,15 +2769,16 @@ namespace cn void WalletGreen::sendTransaction(const cn::Transaction &cryptoNoteTransaction) { - platform_system::Event completion(m_dispatcher); std::error_code ec; - throwIfStopped(); - m_node.relayTransaction(cryptoNoteTransaction, [&ec, &completion, this](std::error_code error) { - ec = error; - this->m_dispatcher.remoteSpawn(std::bind(asyncRequestCompletion, std::ref(completion))); - }); - completion.wait(); + auto relayTransactionCompleted = std::promise(); + auto relayTransactionWaitFuture = relayTransactionCompleted.get_future(); + m_node.relayTransaction(cryptoNoteTransaction, [&ec, &relayTransactionCompleted, this](std::error_code error) + { + auto detachedPromise = std::move(relayTransactionCompleted); + detachedPromise.set_value(ec); + }); + ec = relayTransactionWaitFuture.get(); if (ec) { @@ -2807,17 +2875,18 @@ namespace cn amounts.push_back(out.out.amount); } - platform_system::Event requestFinished(m_dispatcher); std::error_code mixinError; throwIfStopped(); - m_node.getRandomOutsByAmounts(std::move(amounts), mixIn, mixinResult, [&requestFinished, &mixinError, this](std::error_code ec) { - mixinError = ec; - this->m_dispatcher.remoteSpawn(std::bind(asyncRequestCompletion, std::ref(requestFinished))); - }); + auto getRandomOutsByAmountsCompleted = std::promise(); + auto getRandomOutsByAmountsWaitFuture = getRandomOutsByAmountsCompleted.get_future(); - requestFinished.wait(); + m_node.getRandomOutsByAmounts(std::move(amounts), mixIn, mixinResult, [&getRandomOutsByAmountsCompleted, &mixinError, this](std::error_code ec) { + auto detachedPromise = std::move(getRandomOutsByAmountsCompleted); + detachedPromise.set_value(ec); + }); + mixinError = getRandomOutsByAmountsWaitFuture.get(); checkIfEnoughMixins(mixinResult, mixIn); @@ -3282,23 +3351,23 @@ namespace cn blockHeightIndex.erase(std::next(blockHeightIndex.begin(), blockIndex), blockHeightIndex.end()); } - void WalletGreen::onTransactionDeleteBegin(const crypto::PublicKey &viewPublicKey, crypto::Hash transactionHash) + void WalletGreen::onTransactionDeleteBegin(const crypto::PublicKey &viewPublicKey, const crypto::Hash &transactionHash) { m_dispatcher.remoteSpawn([=]() { transactionDeleteBegin(transactionHash); }); } // TODO remove - void WalletGreen::transactionDeleteBegin(crypto::Hash /*transactionHash*/) + void WalletGreen::transactionDeleteBegin(const crypto::Hash& /*transactionHash*/) { } - void WalletGreen::onTransactionDeleteEnd(const crypto::PublicKey &viewPublicKey, crypto::Hash transactionHash) + void WalletGreen::onTransactionDeleteEnd(const crypto::PublicKey &viewPublicKey, const crypto::Hash &transactionHash) { m_dispatcher.remoteSpawn([=]() { transactionDeleteEnd(transactionHash); }); } // TODO remove - void WalletGreen::transactionDeleteEnd(crypto::Hash transactionHash) + void WalletGreen::transactionDeleteEnd(const crypto::Hash &transactionHash) { } @@ -3414,6 +3483,184 @@ namespace cn return id; } + std::vector WalletGreen::getUnspentOutputs() + { + std::vector unspentOutputs; + const auto &walletsIndex = m_walletsContainer.get(); + + std::vector walletOuts; + for (const auto &wallet : walletsIndex) + { + const ITransfersContainer *container = wallet.container; + + std::vector outputs; + container->getOutputs(outputs, ITransfersContainer::IncludeKeyUnlocked); + unspentOutputs.insert(unspentOutputs.end(), outputs.begin(), outputs.end()); + } + return unspentOutputs; + } + + size_t WalletGreen::getUnspentOutputsCount() + { + + return getUnspentOutputs().size(); + } + + std::string WalletGreen::getReserveProof(const std::string &address, const uint64_t &reserve, const std::string &message) + { + const WalletRecord& wallet = getWalletRecord(address); + const AccountKeys& keys = makeAccountKeys(wallet); + + if (keys.spendSecretKey == NULL_SECRET_KEY) + { + throw std::runtime_error("Reserve proof can only be generated by a full wallet"); + } + uint64_t actualBalance = getActualBalance(); + if (actualBalance == 0) + { + throw std::runtime_error("Zero balance"); + } + + if (actualBalance < reserve) + { + throw std::runtime_error("Not enough balance for the requested minimum reserve amount"); + } + + // determine which outputs to include in the proof + std::vector selected_transfers; + wallet.container->getOutputs(selected_transfers, ITransfersContainer::IncludeKeyUnlocked); + + // minimize the number of outputs included in the proof, by only picking the N largest outputs that can cover the requested min reserve amount + auto compareTransactionOutputInformationByAmount = [](const TransactionOutputInformation &a, const TransactionOutputInformation &b) + { return a.amount < b.amount; }; + std::sort(selected_transfers.begin(), selected_transfers.end(), compareTransactionOutputInformationByAmount); + while (selected_transfers.size() >= 2 && selected_transfers[1].amount >= reserve) + { + selected_transfers.erase(selected_transfers.begin()); + } + size_t sz = 0; + uint64_t total = 0; + while (total < reserve) + { + total += selected_transfers[sz].amount; + ++sz; + } + selected_transfers.resize(sz); + + // compute signature prefix hash + std::string prefix_data = message; + prefix_data.append((const char *)&keys.address, sizeof(cn::AccountPublicAddress)); + + std::vector kimages; + cn::KeyPair ephemeral; + + for (const auto &td : selected_transfers) + { + // derive ephemeral secret key + crypto::KeyImage ki; + const bool r = cn::generate_key_image_helper(keys, td.transactionPublicKey, td.outputInTransaction, ephemeral, ki); + if (!r) + { + throw std::runtime_error("Failed to generate key image"); + } + // now we can insert key image + prefix_data.append((const char *)&ki, sizeof(crypto::PublicKey)); + kimages.push_back(ki); + } + + crypto::Hash prefix_hash; + crypto::cn_fast_hash(prefix_data.data(), prefix_data.size(), prefix_hash); + + // generate proof entries + std::vector proofs(selected_transfers.size()); + + for (size_t i = 0; i < selected_transfers.size(); ++i) + { + const TransactionOutputInformation &td = selected_transfers[i]; + reserve_proof_entry &proof = proofs[i]; + proof.key_image = kimages[i]; + proof.txid = td.transactionHash; + proof.index_in_tx = td.outputInTransaction; + + auto txPubKey = td.transactionPublicKey; + + for (int i = 0; i < 2; ++i) + { + crypto::KeyImage sk = crypto::scalarmultKey(*reinterpret_cast(&txPubKey), *reinterpret_cast(&keys.viewSecretKey)); + proof.shared_secret = *reinterpret_cast(&sk); + + crypto::KeyDerivation derivation; + if (!crypto::generate_key_derivation(proof.shared_secret, keys.viewSecretKey, derivation)) + { + throw std::runtime_error("Failed to generate key derivation"); + } + } + + // generate signature for shared secret + crypto::generate_tx_proof(prefix_hash, keys.address.viewPublicKey, txPubKey, proof.shared_secret, keys.viewSecretKey, proof.shared_secret_sig); + + // derive ephemeral secret key + crypto::KeyImage ki; + cn::KeyPair ephemeral; + + const bool r = cn::generate_key_image_helper(keys, td.transactionPublicKey, td.outputInTransaction, ephemeral, ki); + if (!r) + { + throw std::runtime_error("Failed to generate key image"); + } + + if (ephemeral.publicKey != td.outputKey) + { + throw std::runtime_error("Derived public key doesn't agree with the stored one"); + } + + // generate signature for key image + const std::vector &pubs = {&ephemeral.publicKey}; + + crypto::generate_ring_signature(prefix_hash, proof.key_image, &pubs[0], 1, ephemeral.secretKey, 0, &proof.key_image_sig); + } + // generate signature for the spend key that received those outputs + crypto::Signature signature; + crypto::generate_signature(prefix_hash, keys.address.spendPublicKey, keys.spendSecretKey, signature); + + // serialize & encode + reserve_proof p; + p.proofs.assign(proofs.begin(), proofs.end()); + memcpy(&p.signature, &signature, sizeof(signature)); + + BinaryArray ba = toBinaryArray(p); + std::string ret = common::toHex(ba); + + ret = "ReserveProofV1" + tools::base_58::encode(ret); + + return ret; + } + + bool WalletGreen::getTxProof(const crypto::Hash &transactionHash, const cn::AccountPublicAddress &address, const crypto::SecretKey &tx_key, std::string &signature) + { + const crypto::KeyImage p = *reinterpret_cast(&address.viewPublicKey); + const crypto::KeyImage k = *reinterpret_cast(&tx_key); + crypto::KeyImage pk = crypto::scalarmultKey(p, k); + crypto::PublicKey R; + crypto::PublicKey rA = reinterpret_cast(pk); + crypto::secret_key_to_public_key(tx_key, R); + crypto::Signature sig; + try + { + crypto::generate_tx_proof(transactionHash, R, address.viewPublicKey, rA, tx_key, sig); + } + catch (std::runtime_error) + { + return false; + } + + signature = std::string("ProofV1") + + tools::base_58::encode(std::string((const char *)&rA, sizeof(crypto::PublicKey))) + + tools::base_58::encode(std::string((const char *)&sig, sizeof(crypto::Signature))); + + return true; + } + /* Process transactions, this covers both new transactions AND confirmed transactions */ void WalletGreen::transactionUpdated( TransactionInformation transactionInfo, @@ -3642,11 +3889,12 @@ namespace cn void WalletGreen::addUnconfirmedTransaction(const ITransactionReader &transaction) { - platform_system::RemoteContext context(m_dispatcher, [this, &transaction] { - return m_blockchainSynchronizer.addUnconfirmedTransaction(transaction).get(); - }); + auto addUnconfirmedTransactionCompleted = std::promise(); + auto addUnconfirmedTransactionWaitFuture = addUnconfirmedTransactionCompleted.get_future(); + + addUnconfirmedTransactionWaitFuture = m_blockchainSynchronizer.addUnconfirmedTransaction(transaction); - auto ec = context.get(); + std::error_code ec = addUnconfirmedTransactionWaitFuture.get(); if (ec) { throw std::system_error(ec, "Failed to add unconfirmed transaction"); @@ -3899,7 +4147,7 @@ namespace cn return WALLET_INVALID_TRANSACTION_ID; } - typedef cn::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount outs_for_amount; + using outs_for_amount = cn::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount; std::vector mixinResult; if (mixin != 0) { @@ -3914,7 +4162,6 @@ namespace cn std::unique_ptr fusionTransaction; size_t transactionSize; int round = 0; - uint64_t transactionAmount; do { if (round != 0) @@ -3927,8 +4174,6 @@ namespace cn return amount + input.out.amount; }); - transactionAmount = inputsAmount; - ReceiverAmounts decomposedOutputs = decomposeFusionOutputs(destination, inputsAmount); assert(decomposedOutputs.amounts.size() <= MAX_FUSION_OUTPUT_COUNT); @@ -3938,13 +4183,16 @@ namespace cn transactionSize = getTransactionSize(*fusionTransaction); ++round; - } while ((transactionSize > m_currency.fusionTxMaxSize()) && (fusionInputs.size() >= m_currency.fusionTxMinInputCount())); + } while (transactionSize > m_currency.fusionTxMaxSize() && fusionInputs.size() >= m_currency.fusionTxMinInputCount()); if (fusionInputs.size() < m_currency.fusionTxMinInputCount()) { throw std::system_error(make_error_code(error::MINIMUM_INPUT_COUNT)); } - + if (fusionTransaction->getOutputCount() == 0) + { + throw std::system_error(make_error_code(error::WRONG_AMOUNT)); + } id = validateSaveAndSendTransaction(*fusionTransaction, {}, true, true); return id; } @@ -3953,9 +4201,11 @@ namespace cn { WalletGreen::ReceiverAmounts outputs; outputs.receiver = address; - - decomposeAmount(inputsAmount, 0, outputs.amounts); - std::sort(outputs.amounts.begin(), outputs.amounts.end()); + if (inputsAmount > m_currency.minimumFeeV2()) + { + decomposeAmount(inputsAmount - m_currency.minimumFeeV2(), 0, outputs.amounts); + std::sort(outputs.amounts.begin(), outputs.amounts.end()); + } return outputs; } @@ -4037,6 +4287,35 @@ namespace cn } } + size_t WalletGreen::createOptimizationTransaction(const std::string &address) + { + if (getUnspentOutputsCount() < 100) + { + throw std::system_error(make_error_code(error::NOTHING_TO_OPTIMIZE)); + return WALLET_INVALID_TRANSACTION_ID; + } + + uint64_t balance = getActualBalance(address); + uint64_t threshold = 100; + bool fusionReady = false; + while (threshold <= balance && !fusionReady) + { + EstimateResult estimation = estimate(threshold, {address}); + if (estimation.fusionReadyCount > 50) + { + fusionReady = true; + break; + } + threshold *= 10; + } + if (fusionReady) + { + return createFusionTransaction(threshold, cn::parameters::MINIMUM_MIXIN, {address}, address); + } + throw std::system_error(make_error_code(error::NOTHING_TO_OPTIMIZE)); + return WALLET_INVALID_TRANSACTION_ID; + } + void WalletGreen::validateChangeDestination(const std::vector &sourceAddresses, const std::string &changeDestination, bool isFusion) const { std::string message; @@ -4541,4 +4820,66 @@ namespace cn shutdown(); } + bool canInsertTransactionToIndex(const WalletTransaction &transaction) + { + return transaction.state == WalletTransactionState::SUCCEEDED && transaction.blockHeight != WALLET_UNCONFIRMED_TRANSACTION_HEIGHT && + transaction.totalAmount > 0 && !transaction.extra.empty(); + } + + void WalletGreen::pushToPaymentsIndex(const crypto::Hash &paymentId, size_t txId) + { + m_paymentIds[paymentId].push_back(txId); + } + + void WalletGreen::buildPaymentIds() + { + size_t begin = 0; + size_t end = getTransactionCount(); + std::vector extra; + for (auto txId = begin; txId != end; ++txId) + { + const WalletTransaction& tx = getTransaction(txId); + PaymentId paymentId; + extra.insert(extra.begin(), tx.extra.begin(), tx.extra.end()); + if (canInsertTransactionToIndex(tx) && getPaymentIdFromTxExtra(extra, paymentId)) + { + pushToPaymentsIndex(paymentId, txId); + } + extra.clear(); + } + } + + std::vector WalletGreen::getTransactionsByPaymentIds(const std::vector &paymentIds) + { + buildPaymentIds(); + std::vector payments(paymentIds.size()); + auto payment = payments.begin(); + for (auto &key : paymentIds) + { + payment->paymentId = key; + auto it = m_paymentIds.find(key); + if (it != m_paymentIds.end()) + { + std::transform(it->second.begin(), it->second.end(), std::back_inserter(payment->transactions), + [this](size_t txId) + { + return getTransaction(txId); + }); + } + + ++payment; + } + return payments; + } + + void WalletGreen::addObserver(IBlockchainSynchronizerObserver *observer) + { + m_blockchainSynchronizer.addObserver(observer); + } + + void WalletGreen::removeObserver(IBlockchainSynchronizerObserver *observer) + { + m_blockchainSynchronizer.removeObserver(observer); + } + } //namespace cn diff --git a/src/Wallet/WalletGreen.h b/src/Wallet/WalletGreen.h index 3ee8bcec7..a1e9b0fb8 100644 --- a/src/Wallet/WalletGreen.h +++ b/src/Wallet/WalletGreen.h @@ -42,6 +42,7 @@ class WalletGreen : public IWallet, void initialize(const std::string& path, const std::string& password) override; void initializeWithViewKey(const std::string& path, const std::string& password, const crypto::SecretKey& viewSecretKey) override; + void generateNewWallet(const std::string &path, const std::string &password) override; void load(const std::string& path, const std::string& password, std::string& extra) override; void load(const std::string& path, const std::string& password) override; void shutdown() override; @@ -74,6 +75,8 @@ class WalletGreen : public IWallet, uint64_t getLockedDepositBalance(const std::string &address) const override; uint64_t getUnlockedDepositBalance() const override; uint64_t getUnlockedDepositBalance(const std::string &address) const override; + uint64_t getDustBalance() const override; + uint64_t getDustBalance(const std::string &address) const override; size_t getTransactionCount() const override; WalletTransaction getTransaction(size_t transactionIndex) const override; @@ -114,6 +117,17 @@ class WalletGreen : public IWallet, TransactionId creatingTransactionId, const Currency ¤cy, uint32_t height); + std::vector getUnspentOutputs(); + size_t getUnspentOutputsCount(); + std::string getReserveProof(const std::string &address, const uint64_t &reserve, const std::string &message) override; + bool getTxProof(const crypto::Hash &transactionHash, const cn::AccountPublicAddress &address, const crypto::SecretKey &tx_key, std::string &signature) override; + crypto::SecretKey getTransactionDeterministicSecretKey(crypto::Hash &transactionHash) const override; + size_t createOptimizationTransaction(const std::string &address) override; + std::vector getTransactionsByPaymentIds(const std::vector &paymentIds) override; + + void addObserver(IBlockchainSynchronizerObserver *observer); + void removeObserver(IBlockchainSynchronizerObserver *observer); + protected: struct NewAddressData { @@ -142,7 +156,6 @@ class WalletGreen : public IWallet, void initWithKeys(const std::string& path, const std::string& password, const crypto::PublicKey& viewPublicKey, const crypto::SecretKey& viewSecretKey); std::string doCreateAddress(const crypto::PublicKey &spendPublicKey, const crypto::SecretKey &spendSecretKey, uint64_t creationTimestamp); std::vector doCreateAddressList(const std::vector &addressDataList); - crypto::SecretKey getTransactionDeterministicSecretKey(crypto::Hash &transactionHash) const; uint64_t scanHeightToTimestamp(const uint32_t scanHeight); uint64_t getCurrentTimestampAdjusted(); @@ -218,11 +231,11 @@ class WalletGreen : public IWallet, void onBlockchainDetach(const crypto::PublicKey &viewPublicKey, uint32_t blockIndex) override; void blocksRollback(uint32_t blockIndex); - void onTransactionDeleteBegin(const crypto::PublicKey &viewPublicKey, crypto::Hash transactionHash) override; - void transactionDeleteBegin(crypto::Hash transactionHash); + void onTransactionDeleteBegin(const crypto::PublicKey &viewPublicKey, const crypto::Hash &transactionHash) override; + void transactionDeleteBegin(const crypto::Hash &transactionHash); - void onTransactionDeleteEnd(const crypto::PublicKey &viewPublicKey, crypto::Hash transactionHash) override; - void transactionDeleteEnd(crypto::Hash transactionHash); + void onTransactionDeleteEnd(const crypto::PublicKey &viewPublicKey, const crypto::Hash &transactionHash) override; + void transactionDeleteEnd(const crypto::Hash &transactionHash); std::vector pickWalletsWithMoney() const; WalletOuts pickWallet(const std::string &address) const; @@ -338,7 +351,7 @@ class WalletGreen : public IWallet, std::vector pickRandomFusionInputs(const std::vector &addresses, uint64_t threshold, size_t minInputCount, size_t maxInputCount); - static ReceiverAmounts decomposeFusionOutputs(const AccountPublicAddress &address, uint64_t inputsAmount); + ReceiverAmounts decomposeFusionOutputs(const AccountPublicAddress &address, uint64_t inputsAmount); enum class WalletState { @@ -370,6 +383,8 @@ class WalletGreen : public IWallet, void deleteContainerFromUnlockTransactionJobs(const ITransfersContainer *container); std::vector deleteTransfersForAddress(const std::string &address, std::vector &deletedTransactions); void deleteFromUncommitedTransactions(const std::vector &deletedTransactions); + void pushToPaymentsIndex(const crypto::Hash &paymentId, size_t txId); + void buildPaymentIds(); private: platform_system::Dispatcher &m_dispatcher; @@ -413,6 +428,7 @@ class WalletGreen : public IWallet, uint32_t m_transactionSoftLockTime; BlockHashesContainer m_blockchain; + WalletPaymentIds m_paymentIds; }; } //namespace cn diff --git a/src/Wallet/WalletIndices.h b/src/Wallet/WalletIndices.h index 246cb878d..67399172c 100644 --- a/src/Wallet/WalletIndices.h +++ b/src/Wallet/WalletIndices.h @@ -140,5 +140,7 @@ struct EncryptedWalletRecord { boost::multi_index::tag, boost::multi_index::identity>>> BlockHashesContainer; + + using WalletPaymentIds = std::unordered_map, boost::hash>; } // namespace cn diff --git a/src/Wallet/WalletUtils.cpp b/src/Wallet/WalletUtils.cpp index e0ae5dc3f..3c5544cb4 100644 --- a/src/Wallet/WalletUtils.cpp +++ b/src/Wallet/WalletUtils.cpp @@ -7,9 +7,16 @@ #include "WalletUtils.h" +#include + +#include + +#include "Common/Util.h" #include "CryptoNote.h" #include "crypto/crypto.h" #include "Wallet/WalletErrors.h" +#include "Wallet/LegacyKeysImporter.h" + namespace cn { @@ -26,4 +33,39 @@ void throwIfKeysMissmatch(const crypto::SecretKey& secretKey, const crypto::Publ } } + void importLegacyKeys(const std::string &legacyKeysFile, const std::string &filename, const std::string &password) + { + std::stringstream archive; + + cn::importLegacyKeys(legacyKeysFile, password, archive); + + std::fstream walletFile; + createWalletFile(walletFile, filename); + + archive.flush(); + walletFile << archive.rdbuf(); + walletFile.flush(); + } + + void createWalletFile(std::fstream &walletFile, const std::string &filename) + { + boost::filesystem::path pathToWalletFile(filename); + boost::filesystem::path directory = pathToWalletFile.parent_path(); + if (!directory.empty() && !tools::directoryExists(directory.string())) + { + throw std::runtime_error("Directory does not exist: " + directory.string()); + } + + walletFile.open(filename.c_str(), std::fstream::in | std::fstream::out | std::fstream::binary); + if (walletFile) + { + walletFile.close(); + throw std::runtime_error("Wallet file already exists"); + } + + walletFile.open(filename.c_str(), std::fstream::out); + walletFile.close(); + + walletFile.open(filename.c_str(), std::fstream::in | std::fstream::out | std::fstream::binary); + } } diff --git a/src/Wallet/WalletUtils.h b/src/Wallet/WalletUtils.h index 0caac4399..756f6dac9 100644 --- a/src/Wallet/WalletUtils.h +++ b/src/Wallet/WalletUtils.h @@ -15,4 +15,6 @@ namespace cn { bool validateAddress(const std::string& address, const cn::Currency& currency); void throwIfKeysMissmatch(const crypto::SecretKey& secretKey, const crypto::PublicKey& expectedPublicKey, const std::string& message = ""); +void importLegacyKeys(const std::string &legacyKeysFile, const std::string &filename, const std::string &password); +void createWalletFile(std::fstream &walletFile, const std::string &filename); } diff --git a/tests/UnitTests/TestWalletService.cpp b/tests/UnitTests/TestWalletService.cpp index 74c64be98..27c410335 100644 --- a/tests/UnitTests/TestWalletService.cpp +++ b/tests/UnitTests/TestWalletService.cpp @@ -42,6 +42,7 @@ struct IWalletBaseStub : public cn::IWallet, public cn::IFusionManager { virtual void initialize(const std::string& path, const std::string& password) override { } virtual void initializeWithViewKey(const std::string& path, const std::string& password, const crypto::SecretKey& viewSecretKey) override { } + virtual void generateNewWallet(const std::string &path, const std::string &password) override { }; virtual void load(const std::string& path, const std::string& password) override { } virtual void shutdown() override { } @@ -62,6 +63,8 @@ struct IWalletBaseStub : public cn::IWallet, public cn::IFusionManager { virtual uint64_t getActualBalance(const std::string& address) const override { return 0; } virtual uint64_t getPendingBalance() const override { return 0; } virtual uint64_t getPendingBalance(const std::string& address) const override { return 0; } + virtual uint64_t getDustBalance() const override { return 0; }; + virtual uint64_t getDustBalance(const std::string &address) const override { return 0; } virtual size_t getTransactionCount() const override { return 0; } virtual WalletTransaction getTransaction(size_t transactionIndex) const override { return WalletTransaction(); } @@ -82,6 +85,13 @@ struct IWalletBaseStub : public cn::IWallet, public cn::IFusionManager { virtual void commitTransaction(size_t transactionId) override { } virtual void rollbackUncommitedTransaction(size_t transactionId) override { } + virtual std::string getReserveProof(const std::string &address, const uint64_t &reserve, const std::string &message) override { return ""; } + virtual bool getTxProof(const crypto::Hash &transactionHash, const cn::AccountPublicAddress &address, const crypto::SecretKey &tx_key, std::string &signature) override { return true; } + + virtual crypto::SecretKey getTransactionDeterministicSecretKey(crypto::Hash &transactionHash) const { return cn::NULL_SECRET_KEY; } + virtual size_t createOptimizationTransaction(const std::string &address) {return 0; }; + virtual std::vector getTransactionsByPaymentIds(const std::vector &paymentIds) { return std::vector{}; }; + virtual void start() override { m_stopped = false; } virtual void stop() override { m_stopped = true; m_eventOccurred.set(); } From 5668b5056c7d6b8b74e89f3a4a5449e0deee853d Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 1 Apr 2023 17:42:51 +0200 Subject: [PATCH 04/30] Migrate concealwallet to walletgreen --- include/IWallet.h | 8 ++++++++ src/ConcealWallet/ConcealWallet.cpp | 1 + src/ConcealWallet/ConcealWallet.h | 6 ++++-- src/Wallet/WalletGreen.h | 8 ++++---- tests/UnitTests/TestWalletService.cpp | 6 ++++++ 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/IWallet.h b/include/IWallet.h index 3d285a7bf..19de73502 100644 --- a/include/IWallet.h +++ b/include/IWallet.h @@ -177,6 +177,9 @@ struct PaymentIdTransactions std::vector transactions; }; +class TransactionOutputInformation; +class IBlockchainSynchronizerObserver; + class IWallet { public: @@ -248,12 +251,17 @@ class IWallet virtual void commitTransaction(size_t transactionId) = 0; virtual void rollbackUncommitedTransaction(size_t transactionId) = 0; + virtual std::vector getUnspentOutputs() = 0; + virtual size_t getUnspentOutputsCount() = 0; virtual std::string getReserveProof(const std::string &address, const uint64_t &reserve, const std::string &message) = 0; virtual bool getTxProof(const crypto::Hash &transactionHash, const cn::AccountPublicAddress &address, const crypto::SecretKey &tx_key, std::string &signature) = 0; virtual crypto::SecretKey getTransactionDeterministicSecretKey(crypto::Hash &transactionHash) const = 0; virtual size_t createOptimizationTransaction(const std::string &address) = 0; virtual std::vector getTransactionsByPaymentIds(const std::vector &paymentIds) = 0; + virtual void addObserver(IBlockchainSynchronizerObserver *observer) = 0; + virtual void removeObserver(IBlockchainSynchronizerObserver *observer) = 0; + virtual void start() = 0; virtual void stop() = 0; diff --git a/src/ConcealWallet/ConcealWallet.cpp b/src/ConcealWallet/ConcealWallet.cpp index 92d44cdf1..f8b53fe04 100644 --- a/src/ConcealWallet/ConcealWallet.cpp +++ b/src/ConcealWallet/ConcealWallet.cpp @@ -40,6 +40,7 @@ #include "Rpc/HttpClient.h" #include "CryptoNoteCore/CryptoNoteTools.h" +#include "Wallet/WalletGreen.h" #include "Wallet/WalletRpcServer.h" #include "Wallet/WalletUtils.h" #include "Wallet/LegacyKeysImporter.h" diff --git a/src/ConcealWallet/ConcealWallet.h b/src/ConcealWallet/ConcealWallet.h index bb5e2847e..c5253d2d7 100644 --- a/src/ConcealWallet/ConcealWallet.h +++ b/src/ConcealWallet/ConcealWallet.h @@ -14,7 +14,7 @@ #include -#include "Wallet/WalletGreen.h" +#include "IWallet.h" #include "PasswordContainer.h" #include "ClientHelper.h" @@ -23,10 +23,12 @@ #include "CryptoNoteCore/Currency.h" #include "NodeRpcProxy/NodeRpcProxy.h" #include "WalletLegacy/WalletHelper.h" +#include "Transfers/IBlockchainSynchronizer.h" #include #include +#include #include #include @@ -178,7 +180,7 @@ namespace cn cn::client_helper m_chelper; std::unique_ptr m_node; - std::unique_ptr m_wallet; + std::unique_ptr m_wallet; refresh_progress_reporter_t m_refresh_progress_reporter; bool m_walletSynchronized; diff --git a/src/Wallet/WalletGreen.h b/src/Wallet/WalletGreen.h index a1e9b0fb8..b65508006 100644 --- a/src/Wallet/WalletGreen.h +++ b/src/Wallet/WalletGreen.h @@ -117,16 +117,16 @@ class WalletGreen : public IWallet, TransactionId creatingTransactionId, const Currency ¤cy, uint32_t height); - std::vector getUnspentOutputs(); - size_t getUnspentOutputsCount(); + std::vector getUnspentOutputs() override; + size_t getUnspentOutputsCount() override; std::string getReserveProof(const std::string &address, const uint64_t &reserve, const std::string &message) override; bool getTxProof(const crypto::Hash &transactionHash, const cn::AccountPublicAddress &address, const crypto::SecretKey &tx_key, std::string &signature) override; crypto::SecretKey getTransactionDeterministicSecretKey(crypto::Hash &transactionHash) const override; size_t createOptimizationTransaction(const std::string &address) override; std::vector getTransactionsByPaymentIds(const std::vector &paymentIds) override; - void addObserver(IBlockchainSynchronizerObserver *observer); - void removeObserver(IBlockchainSynchronizerObserver *observer); + void addObserver(IBlockchainSynchronizerObserver *observer) override; + void removeObserver(IBlockchainSynchronizerObserver *observer) override; protected: struct NewAddressData diff --git a/tests/UnitTests/TestWalletService.cpp b/tests/UnitTests/TestWalletService.cpp index 27c410335..4b3041350 100644 --- a/tests/UnitTests/TestWalletService.cpp +++ b/tests/UnitTests/TestWalletService.cpp @@ -20,6 +20,7 @@ #include "PaymentGate/WalletServiceErrorCategory.h" #include "INodeStubs.h" #include "Wallet/WalletErrors.h" +#include "ITransfersContainer.h" using namespace cn; using namespace payment_service; @@ -85,6 +86,8 @@ struct IWalletBaseStub : public cn::IWallet, public cn::IFusionManager { virtual void commitTransaction(size_t transactionId) override { } virtual void rollbackUncommitedTransaction(size_t transactionId) override { } + std::vector getUnspentOutputs() override { return std::vector{}; }; + size_t getUnspentOutputsCount() override { return 0; }; virtual std::string getReserveProof(const std::string &address, const uint64_t &reserve, const std::string &message) override { return ""; } virtual bool getTxProof(const crypto::Hash &transactionHash, const cn::AccountPublicAddress &address, const crypto::SecretKey &tx_key, std::string &signature) override { return true; } @@ -92,6 +95,9 @@ struct IWalletBaseStub : public cn::IWallet, public cn::IFusionManager { virtual size_t createOptimizationTransaction(const std::string &address) {return 0; }; virtual std::vector getTransactionsByPaymentIds(const std::vector &paymentIds) { return std::vector{}; }; + virtual void addObserver(IBlockchainSynchronizerObserver *observer) override{}; + virtual void removeObserver(IBlockchainSynchronizerObserver *observer) override{}; + virtual void start() override { m_stopped = false; } virtual void stop() override { m_stopped = true; m_eventOccurred.set(); } From b5f9481e2c7465e495352adcbc85b02c3cf89c4a Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 2 Apr 2023 19:28:58 +0200 Subject: [PATCH 05/30] Observable wallet --- include/IWallet.h | 31 +++++++-- src/ConcealWallet/ConcealWallet.cpp | 53 ++++++++++++++++ src/ConcealWallet/ConcealWallet.h | 17 ++++- src/Transfers/IObservableImpl.h | 4 +- src/Wallet/WalletGreen.cpp | 91 +++++++++++++-------------- src/Wallet/WalletGreen.h | 11 +++- tests/UnitTests/TestWalletService.cpp | 4 +- 7 files changed, 150 insertions(+), 61 deletions(-) diff --git a/include/IWallet.h b/include/IWallet.h index 19de73502..d975060b5 100644 --- a/include/IWallet.h +++ b/include/IWallet.h @@ -13,11 +13,13 @@ #include #include "CryptoNote.h" #include "CryptoNoteConfig.h" +#include "IObservable.h" namespace cn { -typedef size_t DepositId; +using DepositId = size_t; +using TransactionId = size_t; const size_t WALLET_INVALID_TRANSACTION_ID = std::numeric_limits::max(); const size_t WALLET_INVALID_TRANSFER_ID = std::numeric_limits::max(); @@ -180,7 +182,29 @@ struct PaymentIdTransactions class TransactionOutputInformation; class IBlockchainSynchronizerObserver; -class IWallet +class IWalletObserver +{ +public: + virtual ~IWalletObserver() = default; + + virtual void initCompleted(std::error_code result) = 0; + virtual void saveCompleted(std::error_code result) = 0; + virtual void synchronizationProgressUpdated(uint32_t current, uint32_t total) = 0; + virtual void synchronizationCompleted(std::error_code result) = 0; + virtual void actualBalanceUpdated(uint64_t balance) = 0; + virtual void pendingBalanceUpdated(uint64_t balance) = 0; + virtual void actualDepositBalanceUpdated(uint64_t balance) = 0; + virtual void pendingDepositBalanceUpdated(uint64_t balance) = 0; + virtual void actualInvestmentBalanceUpdated(uint64_t balance) = 0; + virtual void pendingInvestmentBalanceUpdated(uint64_t balance) = 0; + virtual void externalTransactionCreated(TransactionId transactionId) = 0; + virtual void sendTransactionCompleted(TransactionId transactionId, std::error_code result) = 0; + virtual void transactionUpdated(TransactionId transactionId) = 0; + virtual void depositUpdated(DepositId depositId) = 0; + virtual void depositsUpdated(const std::vector &depositIds) = 0; +}; + +class IWallet : public IObservable { public: virtual ~IWallet() = default; @@ -259,9 +283,6 @@ class IWallet virtual size_t createOptimizationTransaction(const std::string &address) = 0; virtual std::vector getTransactionsByPaymentIds(const std::vector &paymentIds) = 0; - virtual void addObserver(IBlockchainSynchronizerObserver *observer) = 0; - virtual void removeObserver(IBlockchainSynchronizerObserver *observer) = 0; - virtual void start() = 0; virtual void stop() = 0; diff --git a/src/ConcealWallet/ConcealWallet.cpp b/src/ConcealWallet/ConcealWallet.cpp index f8b53fe04..06f7bb1cd 100644 --- a/src/ConcealWallet/ConcealWallet.cpp +++ b/src/ConcealWallet/ConcealWallet.cpp @@ -1793,4 +1793,57 @@ bool conceal_wallet::check_address(const std::vector &args) logger(INFO) << "The wallet " << addr << " seems to be valid, please still be cautious still."; return true; +} + +void conceal_wallet::initCompleted(std::error_code result) +{ + // Nothing to do here +} +void conceal_wallet::saveCompleted(std::error_code result) +{ + // Nothing to do here +} +void conceal_wallet::actualBalanceUpdated(uint64_t balance) +{ + // Nothing to do here +} +void conceal_wallet::pendingBalanceUpdated(uint64_t balance) +{ + // Nothing to do here +} +void conceal_wallet::actualDepositBalanceUpdated(uint64_t balance) +{ + // Nothing to do here +} +void conceal_wallet::pendingDepositBalanceUpdated(uint64_t balance) +{ + // Nothing to do here +} +void conceal_wallet::actualInvestmentBalanceUpdated(uint64_t balance) +{ + // Nothing to do here +} +void conceal_wallet::pendingInvestmentBalanceUpdated(uint64_t balance) +{ + // Nothing to do here +} +void conceal_wallet::externalTransactionCreated(TransactionId transactionId) +{ + // Nothing to do here +} +void conceal_wallet::sendTransactionCompleted(TransactionId transactionId, std::error_code result) +{ + // Nothing to do here +} +void conceal_wallet::transactionUpdated(TransactionId transactionId) +{ + // Nothing to do here +} +void conceal_wallet::depositUpdated(DepositId depositId) +{ + // Nothing to do here +} +void conceal_wallet::depositsUpdated(const std::vector &depositIds) +{ + // Nothing to do here } \ No newline at end of file diff --git a/src/ConcealWallet/ConcealWallet.h b/src/ConcealWallet/ConcealWallet.h index c5253d2d7..ae3f87d07 100644 --- a/src/ConcealWallet/ConcealWallet.h +++ b/src/ConcealWallet/ConcealWallet.h @@ -37,7 +37,7 @@ namespace cn /************************************************************************/ /* */ /************************************************************************/ - class conceal_wallet : public IBlockchainSynchronizerObserver { + class conceal_wallet : public IWalletObserver { public: conceal_wallet(platform_system::Dispatcher& dispatcher, const cn::Currency& currency, logging::LoggerManager& log); @@ -115,8 +115,21 @@ namespace cn void printConnectionError() const; std::string get_wallet_keys() const; + void initCompleted(std::error_code result) override; + void saveCompleted(std::error_code result) override; + void synchronizationProgressUpdated(uint32_t current, uint32_t total) override; void synchronizationCompleted(std::error_code result) override; - void synchronizationProgressUpdated(uint32_t processedBlockCount, uint32_t totalBlockCount) override; + void actualBalanceUpdated(uint64_t balance) override; + void pendingBalanceUpdated(uint64_t balance) override; + void actualDepositBalanceUpdated(uint64_t balance) override; + void pendingDepositBalanceUpdated(uint64_t balance) override; + void actualInvestmentBalanceUpdated(uint64_t balance) override; + void pendingInvestmentBalanceUpdated(uint64_t balance) override; + void externalTransactionCreated(TransactionId transactionId) override; + void sendTransactionCompleted(TransactionId transactionId, std::error_code result) override; + void transactionUpdated(TransactionId transactionId) override; + void depositUpdated(DepositId depositId) override; + void depositsUpdated(const std::vector &depositIds) override; friend class refresh_progress_reporter_t; diff --git a/src/Transfers/IObservableImpl.h b/src/Transfers/IObservableImpl.h index fd94aa2d4..43b7ba772 100644 --- a/src/Transfers/IObservableImpl.h +++ b/src/Transfers/IObservableImpl.h @@ -15,11 +15,11 @@ template class IObservableImpl : public Base { public: - virtual void addObserver(Observer* observer) override { + void addObserver(Observer* observer) override { m_observerManager.add(observer); } - virtual void removeObserver(Observer* observer) override { + void removeObserver(Observer* observer) override { m_observerManager.remove(observer); } diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index ca976e522..37ba81c77 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -137,49 +137,6 @@ namespace } } - cn::WalletEvent makeTransactionUpdatedEvent(size_t id) - { - cn::WalletEvent event; - event.type = cn::WalletEventType::TRANSACTION_UPDATED; - event.transactionUpdated.transactionIndex = id; - - return event; - } - - cn::WalletEvent makeTransactionCreatedEvent(size_t id) - { - cn::WalletEvent event; - event.type = cn::WalletEventType::TRANSACTION_CREATED; - event.transactionCreated.transactionIndex = id; - - return event; - } - - cn::WalletEvent makeMoneyUnlockedEvent() - { - cn::WalletEvent event; - event.type = cn::WalletEventType::BALANCE_UNLOCKED; - - return event; - } - - cn::WalletEvent makeSyncProgressUpdatedEvent(uint32_t current, uint32_t total) - { - cn::WalletEvent event; - event.type = cn::WalletEventType::SYNC_PROGRESS_UPDATED; - event.synchronizationProgressUpdated.processedBlockCount = current; - event.synchronizationProgressUpdated.totalBlockCount = total; - return event; - } - - cn::WalletEvent makeSyncCompletedEvent() - { - cn::WalletEvent event; - event.type = cn::WalletEventType::SYNC_COMPLETED; - - return event; - } - size_t getTransactionSize(const ITransactionReader &transaction) { return transaction.getTransactionData().size(); @@ -943,12 +900,14 @@ namespace cn catch (const std::exception &e) { m_logger(ERROR, BRIGHT_RED) << "Failed to save container: " << e.what(); + m_observerManager.notify(&IWalletObserver::saveCompleted, make_error_code(cn::error::INTERNAL_WALLET_ERROR)); startBlockchainSynchronizer(); throw; } startBlockchainSynchronizer(); m_logger(INFO, BRIGHT_WHITE) << "Container saved"; + m_observerManager.notify(&IWalletObserver::saveCompleted, std::error_code()); } void WalletGreen::copyContainerStorageKeys(ContainerStorage &src, const chacha8_key &srcKey, ContainerStorage &dst, const chacha8_key &dstKey) @@ -3285,6 +3244,7 @@ namespace cn void WalletGreen::synchronizationCompleted(std::error_code result) { + m_observerManager.notify(&IWalletObserver::synchronizationCompleted, result); m_dispatcher.remoteSpawn([this]() { onSynchronizationCompleted(); }); } @@ -4025,6 +3985,10 @@ namespace cn << m_currency.formatAmount(m_pendingBalance) << ", locked deposits " << m_currency.formatAmount(m_lockedDepositBalance) << ",unlocked deposits " << m_currency.formatAmount(m_unlockedDepositBalance); + m_observerManager.notify(&IWalletObserver::actualBalanceUpdated, actual); + m_observerManager.notify(&IWalletObserver::pendingBalanceUpdated, pending); + m_observerManager.notify(&IWalletObserver::actualDepositBalanceUpdated, locked); + m_observerManager.notify(&IWalletObserver::pendingDepositBalanceUpdated, unlocked); } } @@ -4872,14 +4836,47 @@ namespace cn return payments; } - void WalletGreen::addObserver(IBlockchainSynchronizerObserver *observer) + cn::WalletEvent WalletGreen::makeTransactionUpdatedEvent(size_t id) { - m_blockchainSynchronizer.addObserver(observer); + cn::WalletEvent event; + event.type = cn::WalletEventType::TRANSACTION_UPDATED; + event.transactionUpdated.transactionIndex = id; + m_observerManager.notify(&IWalletObserver::transactionUpdated, id); + return event; } - void WalletGreen::removeObserver(IBlockchainSynchronizerObserver *observer) + cn::WalletEvent WalletGreen::makeTransactionCreatedEvent(size_t id) { - m_blockchainSynchronizer.removeObserver(observer); + cn::WalletEvent event; + event.type = cn::WalletEventType::TRANSACTION_CREATED; + event.transactionCreated.transactionIndex = id; + m_observerManager.notify(&IWalletObserver::sendTransactionCompleted, id, std::error_code()); + return event; + } + + cn::WalletEvent WalletGreen::makeMoneyUnlockedEvent() + { + cn::WalletEvent event; + event.type = cn::WalletEventType::BALANCE_UNLOCKED; + + return event; + } + + cn::WalletEvent WalletGreen::makeSyncProgressUpdatedEvent(uint32_t current, uint32_t total) + { + cn::WalletEvent event; + event.type = cn::WalletEventType::SYNC_PROGRESS_UPDATED; + event.synchronizationProgressUpdated.processedBlockCount = current; + event.synchronizationProgressUpdated.totalBlockCount = total; + m_observerManager.notify(&IWalletObserver::synchronizationProgressUpdated, current, total); + return event; + } + + cn::WalletEvent WalletGreen::makeSyncCompletedEvent() + { + cn::WalletEvent event; + event.type = cn::WalletEventType::SYNC_COMPLETED; + return event; } } //namespace cn diff --git a/src/Wallet/WalletGreen.h b/src/Wallet/WalletGreen.h index b65508006..854d4f188 100644 --- a/src/Wallet/WalletGreen.h +++ b/src/Wallet/WalletGreen.h @@ -20,11 +20,12 @@ #include #include "Transfers/TransfersSynchronizer.h" #include "Transfers/BlockchainSynchronizer.h" +#include "Transfers/IObservableImpl.h" namespace cn { -class WalletGreen : public IWallet, +class WalletGreen : public IObservableImpl, public ITransfersObserver, public IBlockchainSynchronizerObserver, public ITransfersSynchronizerObserver, @@ -125,8 +126,6 @@ class WalletGreen : public IWallet, size_t createOptimizationTransaction(const std::string &address) override; std::vector getTransactionsByPaymentIds(const std::vector &paymentIds) override; - void addObserver(IBlockchainSynchronizerObserver *observer) override; - void removeObserver(IBlockchainSynchronizerObserver *observer) override; protected: struct NewAddressData @@ -386,6 +385,12 @@ class WalletGreen : public IWallet, void pushToPaymentsIndex(const crypto::Hash &paymentId, size_t txId); void buildPaymentIds(); + cn::WalletEvent makeTransactionUpdatedEvent(size_t id); + cn::WalletEvent makeTransactionCreatedEvent(size_t id); + cn::WalletEvent makeMoneyUnlockedEvent(); + cn::WalletEvent makeSyncProgressUpdatedEvent(uint32_t current, uint32_t total); + cn::WalletEvent makeSyncCompletedEvent(); + private: platform_system::Dispatcher &m_dispatcher; const Currency &m_currency; diff --git a/tests/UnitTests/TestWalletService.cpp b/tests/UnitTests/TestWalletService.cpp index 4b3041350..326a3601d 100644 --- a/tests/UnitTests/TestWalletService.cpp +++ b/tests/UnitTests/TestWalletService.cpp @@ -95,8 +95,8 @@ struct IWalletBaseStub : public cn::IWallet, public cn::IFusionManager { virtual size_t createOptimizationTransaction(const std::string &address) {return 0; }; virtual std::vector getTransactionsByPaymentIds(const std::vector &paymentIds) { return std::vector{}; }; - virtual void addObserver(IBlockchainSynchronizerObserver *observer) override{}; - virtual void removeObserver(IBlockchainSynchronizerObserver *observer) override{}; + virtual void addObserver(IWalletObserver *observer) override{}; + virtual void removeObserver(IWalletObserver *observer) override{}; virtual void start() override { m_stopped = false; } virtual void stop() override { m_stopped = true; m_eventOccurred.set(); } From f27c97df395cdf4f303d898b0bbb3119190e9260 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 8 Apr 2023 10:17:46 +0200 Subject: [PATCH 06/30] Format timestamp as string --- src/Common/StringTools.cpp | 15 +++++++++- src/Common/StringTools.h | 2 ++ src/ConcealWallet/ClientHelper.cpp | 15 +--------- src/ConcealWallet/ConcealWallet.cpp | 15 +--------- src/CryptoNoteCore/TransactionPool.cpp | 38 ++------------------------ src/CryptoNoteCore/UpgradeDetector.h | 16 ++--------- 6 files changed, 22 insertions(+), 79 deletions(-) diff --git a/src/Common/StringTools.cpp b/src/Common/StringTools.cpp index 34375b760..accf28829 100644 --- a/src/Common/StringTools.cpp +++ b/src/Common/StringTools.cpp @@ -7,6 +7,7 @@ #include "StringTools.h" #include +#include namespace common { @@ -348,5 +349,17 @@ std::string makeCenteredString(size_t width, const std::string& text) { return std::string(offset, ' ') + text + std::string(width - text.size() - offset, ' '); } - +std::string formatTimestamp(time_t timestamp) +{ + std::string buffer(32, '\0'); + struct tm time_info; +#ifdef _WIN32 + gmtime_s(&time_info, ×tamp); +#else + gmtime_r(×tamp, &time_info); +#endif + std::strftime(&buffer[0], buffer.size(), "%c", &time_info); + buffer += " UTC"; + return buffer; +} } diff --git a/src/Common/StringTools.h b/src/Common/StringTools.h index 89ff42111..47aadec32 100644 --- a/src/Common/StringTools.h +++ b/src/Common/StringTools.h @@ -108,4 +108,6 @@ std::string timeIntervalToString(uint64_t intervalInSeconds); std::string makeCenteredString(size_t width, const std::string& text); +std::string formatTimestamp(time_t timestamp); + } \ No newline at end of file diff --git a/src/ConcealWallet/ClientHelper.cpp b/src/ConcealWallet/ClientHelper.cpp index 14e39d194..4f594d81e 100644 --- a/src/ConcealWallet/ClientHelper.cpp +++ b/src/ConcealWallet/ClientHelper.cpp @@ -3,7 +3,6 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include #include #include #include @@ -175,19 +174,7 @@ namespace cn crypto::Hash paymentId; std::string paymentIdStr = (cn::getPaymentIdFromTxExtra(extraVec, paymentId) && paymentId != NULL_HASH ? podToHex(paymentId) : ""); - char timeString[32 + 1]; - time_t timestamp = static_cast(txInfo.timestamp); - struct tm time; -#ifdef _WIN32 - gmtime_s(&time, ×tamp); -#else - gmtime_r(×tamp, &time); -#endif - - if (!std::strftime(timeString, sizeof(timeString), "%c", &time)) - { - throw std::runtime_error("time buffer is too small"); - } + std::string timeString = formatTimestamp(static_cast(txInfo.timestamp)); std::string format_amount = currency.formatAmount(txInfo.totalAmount); diff --git a/src/ConcealWallet/ConcealWallet.cpp b/src/ConcealWallet/ConcealWallet.cpp index 06f7bb1cd..36982953d 100644 --- a/src/ConcealWallet/ConcealWallet.cpp +++ b/src/ConcealWallet/ConcealWallet.cpp @@ -9,7 +9,6 @@ #include "TransferCmd.h" #include "Const.h" -#include #include #include #include @@ -106,19 +105,7 @@ void printListTransfersItem(LoggerRef& logger, const WalletTransaction& txInfo, crypto::Hash paymentId; std::string paymentIdStr = (getPaymentIdFromTxExtra(extraVec, paymentId) && paymentId != NULL_HASH ? common::podToHex(paymentId) : ""); - char timeString[TIMESTAMP_MAX_WIDTH + 1]; - time_t timestamp = static_cast(txInfo.timestamp); - struct tm time; -#ifdef _WIN32 - gmtime_s(&time, ×tamp); -#else - gmtime_r(×tamp, &time); -#endif - - if (!std::strftime(timeString, sizeof(timeString), "%c", &time)) - { - throw std::runtime_error("time buffer is too small"); - } + std::string timeString = formatTimestamp(static_cast(txInfo.timestamp)); std::string rowColor = txInfo.totalAmount < 0 ? MAGENTA : GREEN; logger(INFO, rowColor) diff --git a/src/CryptoNoteCore/TransactionPool.cpp b/src/CryptoNoteCore/TransactionPool.cpp index ea75c48e7..d5beffd82 100644 --- a/src/CryptoNoteCore/TransactionPool.cpp +++ b/src/CryptoNoteCore/TransactionPool.cpp @@ -8,7 +8,6 @@ #include "TransactionPool.h" #include -#include #include #include @@ -451,45 +450,12 @@ namespace cn ss << "blobSize: " << txd.blobSize << std::endl << "fee: " << m_currency.formatAmount(txd.fee) << std::endl - << "received: "; - - char receivedTimeStr[32]; - struct tm receivedTimeTm; -#ifdef _WIN32 - gmtime_s(&receivedTimeTm, &txd.receiveTime); -#else - gmtime_r(&txd.receiveTime, &receivedTimeTm); -#endif - if (std::strftime(receivedTimeStr, sizeof(receivedTimeStr), "%c", &receivedTimeTm)) - { - ss << receivedTimeStr << " UTC"; - } - else - { - ss << "unable to get time"; - } - ss << std::endl; + << "received: " << common::formatTimestamp(txd.receiveTime) << std::endl; auto ttlIt = m_ttlIndex.find(txd.id); if (ttlIt != m_ttlIndex.end()) { - char ttlTimeStr[32]; - struct tm ttlTimeTm; - time_t timestamp = reinterpret_cast(&ttlIt->second); -#ifdef _WIN32 - gmtime_s(&ttlTimeTm, ×tamp); -#else - gmtime_r(×tamp, &ttlTimeTm); -#endif - if (std::strftime(ttlTimeStr, sizeof(ttlTimeStr), "%c", &ttlTimeTm)) - { - ss << "TTL: " << ttlTimeStr << " UTC"; - } - else - { - ss << "TTL failed"; - } - ss << std::endl; + ss << "TTL: " << common::formatTimestamp(static_cast(ttlIt->second)) << std::endl; } } return ss.str(); diff --git a/src/CryptoNoteCore/UpgradeDetector.h b/src/CryptoNoteCore/UpgradeDetector.h index 9c432da59..4ebd1b57e 100644 --- a/src/CryptoNoteCore/UpgradeDetector.h +++ b/src/CryptoNoteCore/UpgradeDetector.h @@ -9,7 +9,6 @@ #include #include -#include #include "Common/StringTools.h" #include "CryptoNoteCore/CryptoNoteBasicImpl.h" @@ -126,21 +125,10 @@ namespace cn { if (m_blockchain.size() % (60 * 60 / m_currency.difficultyTarget()) == 0) { auto interval = m_currency.difficultyTarget() * (upgradeHeight() - m_blockchain.size() + 2); - char upgradeTimeStr[32]; - struct tm upgradeTimeTm; time_t upgradeTimestamp = time(nullptr) + static_cast(interval); -#ifdef _WIN32 - gmtime_s(&upgradeTimeTm, &upgradeTimestamp); -#else - gmtime_r(&upgradeTimestamp, &upgradeTimeTm); -#endif - if (!std::strftime(upgradeTimeStr, sizeof(upgradeTimeStr), "%c", &upgradeTimeTm)) - { - throw std::runtime_error("time buffer is too small"); - } - + std::string upgradeTime = common::formatTimestamp(upgradeTimestamp); logger(logging::TRACE, logging::BRIGHT_GREEN) << "###### UPGRADE is going to happen after block index " << upgradeHeight() << " at about " << - upgradeTimeStr << " UTC" << " (in " << common::timeIntervalToString(interval) << ")! Current last block index " << (m_blockchain.size() - 1) << + upgradeTime << " (in " << common::timeIntervalToString(interval) << ")! Current last block index " << (m_blockchain.size() - 1) << ", hash " << get_block_hash(m_blockchain.back().bl); } } else if (m_blockchain.size() == upgradeHeight() + 1) { From c5b35b891795ffac6d75451e5b517e7fc2a20ffb Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 9 Apr 2023 14:47:03 +0200 Subject: [PATCH 07/30] Include system_error --- include/IWallet.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/IWallet.h b/include/IWallet.h index 4183bb112..02a2586b7 100644 --- a/include/IWallet.h +++ b/include/IWallet.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include "CryptoNote.h" From 52ae8391c66824218a6085a8248f0496cb7a0058 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 9 Apr 2023 16:07:37 +0200 Subject: [PATCH 08/30] Fix WalletGreen warnings --- include/IWallet.h | 2 +- src/Wallet/WalletGreen.cpp | 231 +++++++++++--------------- src/Wallet/WalletGreen.h | 44 ++--- src/Wallet/WalletSerializationV1.cpp | 2 +- src/Wallet/WalletSerializationV1.h | 2 +- tests/UnitTests/TestWalletService.cpp | 2 +- 6 files changed, 122 insertions(+), 161 deletions(-) diff --git a/include/IWallet.h b/include/IWallet.h index 02a2586b7..867e60838 100644 --- a/include/IWallet.h +++ b/include/IWallet.h @@ -211,7 +211,7 @@ class IWallet : public IObservable virtual ~IWallet() = default; virtual void initialize(const std::string& path, const std::string& password) = 0; - virtual void createDeposit(uint64_t amount, uint64_t term, std::string sourceAddress, std::string destinationAddress, std::string &transactionHash) = 0; + virtual void createDeposit(uint64_t amount, uint32_t term, std::string sourceAddress, std::string destinationAddress, std::string &transactionHash) = 0; virtual void withdrawDeposit(DepositId depositId, std::string &transactionHash) = 0; virtual Deposit getDeposit(size_t depositIndex) const = 0; virtual void initializeWithViewKey(const std::string& path, const std::string& password, const crypto::SecretKey& viewSecretKey) = 0; diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index 010757ef8..97cf7bf97 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -54,8 +54,8 @@ namespace decompose_amount_into_digits( amount, dustThreshold, - [&](uint64_t chunk) { amounts.push_back(chunk); }, - [&](uint64_t dust) { amounts.push_back(dust); }); + [&amounts](uint64_t chunk) { amounts.push_back(chunk); }, + [&amounts](uint64_t dust) { amounts.push_back(dust); }); return amounts; } @@ -63,10 +63,10 @@ namespace uint64_t calculateDepositsAmount( const std::vector &transfers, const cn::Currency ¤cy, - const std::vector heights) + const std::vector &heights) { int index = 0; - return std::accumulate(transfers.begin(), transfers.end(), static_cast(0), [¤cy, &index, heights](uint64_t sum, const cn::TransactionOutputInformation &deposit) { + return std::accumulate(transfers.begin(), transfers.end(), static_cast(0), [¤cy, &index, &heights](uint64_t sum, const cn::TransactionOutputInformation &deposit) { return sum + deposit.amount + currency.calculateInterest(deposit.amount, deposit.term, heights[index++]); }); } @@ -104,9 +104,9 @@ namespace } //to supress warning - uint64_t uamount = static_cast(transfer.amount); - neededMoney += uamount; - if (neededMoney < uamount) + auto amount = static_cast(transfer.amount); + neededMoney += amount; + if (neededMoney < amount) { throw std::system_error(make_error_code(cn::error::SUM_OVERFLOW)); } @@ -121,10 +121,10 @@ namespace return neededMoney; } - void checkIfEnoughMixins(std::vector &mixinResult, uint64_t mixIn) + void checkIfEnoughMixins(std::vector &mixinResult, uint64_t mixIn) { auto notEnoughIt = std::find_if(mixinResult.begin(), mixinResult.end(), - [mixIn](const cn::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount &ofa) { return ofa.outs.size() < mixIn; }); + [mixIn](const outs_for_amount &ofa) { return ofa.outs.size() < mixIn; }); if (mixIn == 0 && mixinResult.empty()) { @@ -233,17 +233,10 @@ namespace cn m_currency(currency), m_node(node), m_logger(logger, "WalletGreen"), - m_stopped(false), - m_blockchainSynchronizerStarted(false), m_blockchainSynchronizer(node, currency.genesisBlockHash()), m_synchronizer(currency, logger, m_blockchainSynchronizer, node), m_eventOccurred(m_dispatcher), m_readyEvent(m_dispatcher), - m_state(WalletState::NOT_INITIALIZED), - m_actualBalance(0), - m_pendingBalance(0), - m_lockedDepositBalance(0), - m_unlockedDepositBalance(0), m_transactionSoftLockTime(transactionSoftLockTime) { m_upperTransactionSizeLimit = m_currency.transactionMaxSize(); @@ -305,7 +298,7 @@ namespace cn std::vector selectedTransfers; const auto &wallet = getWalletRecord(address); - ITransfersContainer *container = wallet.container; + const ITransfersContainer *container = wallet.container; AccountKeys account = makeAccountKeys(wallet); ITransfersContainer::TransferState state; TransactionOutputInformation transfer; @@ -367,7 +360,7 @@ namespace cn } transactionHash = common::podToHex(transaction->getTransactionHash()); - size_t id = validateSaveAndSendTransaction(*transaction, {}, false, true); + validateSaveAndSendTransaction(*transaction, {}, false, true); } crypto::SecretKey WalletGreen::getTransactionDeterministicSecretKey(crypto::Hash &transactionHash) const @@ -401,7 +394,7 @@ namespace cn return txKey; } - std::vector WalletGreen::prepareMultisignatureInputs(const std::vector &selectedTransfers) + std::vector WalletGreen::prepareMultisignatureInputs(const std::vector &selectedTransfers) const { std::vector inputs; inputs.reserve(selectedTransfers.size()); @@ -413,7 +406,7 @@ namespace cn MultisignatureInput input; input.amount = output.amount; - input.signatureCount = output.requiredSignatures; + input.signatureCount = static_cast(output.requiredSignatures); input.outputIndex = output.globalOutputIndex; input.term = output.term; @@ -425,7 +418,7 @@ namespace cn void WalletGreen::createDeposit( uint64_t amount, - uint64_t term, + uint32_t term, std::string sourceAddress, std::string destinationAddress, std::string &transactionHash) @@ -467,7 +460,7 @@ namespace cn std::vector selectedTransfers; uint64_t foundMoney = selectTransfers(neededMoney, m_currency.defaultDustThreshold(), - std::move(wallets), + wallets, selectedTransfers); /* Do we have enough funds */ @@ -480,27 +473,18 @@ namespace cn which includes the term, and then after that the change outputs */ /* Add the deposit outputs to the transaction */ - auto depositIndex = transaction->addOutput( + transaction->addOutput( neededMoney - fee, {destAddr}, 1, term); /* Let's add the change outputs to the transaction */ - - std::vector amounts; - - /* Breakdown the change into specific amounts */ - decompose_amount_into_digits( - foundMoney - neededMoney, - m_currency.defaultDustThreshold(), - [&](uint64_t chunk) { amounts.push_back(chunk); }, - [&](uint64_t dust) { amounts.push_back(dust); }); - std::vector decomposedChange = amounts; + std::vector decomposedChange = split(foundMoney - neededMoney, m_currency.defaultDustThreshold()); /* Now pair each of those amounts to the change address which in the case of a deposit is the source address */ - typedef std::pair AmountToAddress; + using AmountToAddress = std::pair; std::vector amountsToAddresses; for (const auto &output : decomposedChange) { @@ -555,7 +539,6 @@ namespace cn /* Prepare the inputs */ /* Get additional inputs for the mixin */ - typedef cn::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount outs_for_amount; std::vector mixinResult; requestMixinOuts(selectedTransfers, cn::parameters::MINIMUM_MIXIN, mixinResult); std::vector keysInfo; @@ -570,14 +553,14 @@ namespace cn /* Now sign the inputs so we can proceed with the transaction */ size_t i = 0; - for (auto &input : keysInfo) + for (const auto &input : keysInfo) { transaction->signInputKey(i++, input.keyInfo, input.ephKeys); } /* Return the transaction hash */ transactionHash = common::podToHex(transaction->getTransactionHash()); - size_t id = validateSaveAndSendTransaction(*transaction, {}, false, true); + validateSaveAndSendTransaction(*transaction, {}, false, true); } void WalletGreen::validateOrders(const std::vector &orders) const @@ -739,13 +722,13 @@ namespace cn void WalletGreen::initBlockchain(const crypto::PublicKey &viewPublicKey) { - std::vector blockchain = m_synchronizer.getViewKeyKnownBlocks(m_viewPublicKey); + std::vector blockchain = m_synchronizer.getViewKeyKnownBlocks(viewPublicKey); m_blockchain.insert(m_blockchain.end(), blockchain.begin(), blockchain.end()); } void WalletGreen::deleteOrphanTransactions(const std::unordered_set &deletedKeys) { - for (auto spendPublicKey : deletedKeys) + for (const auto &spendPublicKey : deletedKeys) { AccountPublicAddress deletedAccountAddress; deletedAccountAddress.spendPublicKey = spendPublicKey; @@ -857,7 +840,7 @@ namespace cn ContainerStorage newStorage(path, common::FileMappedVectorOpenMode::CREATE, sizeof(ContainerStoragePrefix)); ContainerStoragePrefix *prefix = reinterpret_cast(newStorage.prefix()); - prefix->version = static_cast(WalletSerializerV2::SERIALIZATION_VERSION); + prefix->version = WalletSerializerV2::SERIALIZATION_VERSION; prefix->nextIv = crypto::rand(); crypto::cn_context cnContext; @@ -910,7 +893,7 @@ namespace cn m_observerManager.notify(&IWalletObserver::saveCompleted, std::error_code()); } - void WalletGreen::copyContainerStorageKeys(ContainerStorage &src, const chacha8_key &srcKey, ContainerStorage &dst, const chacha8_key &dstKey) + void WalletGreen::copyContainerStorageKeys(const ContainerStorage &src, const chacha8_key &srcKey, ContainerStorage &dst, const chacha8_key &dstKey) const { dst.reserve(src.size()); @@ -920,9 +903,7 @@ namespace cn dst.flush(); }); - size_t counter = 0; - - for (auto &encryptedSpendKeys : src) + for (const auto &encryptedSpendKeys : src) { crypto::PublicKey publicKey; crypto::SecretKey secretKey; @@ -940,7 +921,7 @@ namespace cn void WalletGreen::copyContainerStoragePrefix(ContainerStorage &src, const chacha8_key &srcKey, ContainerStorage &dst, const chacha8_key &dstKey) { - ContainerStoragePrefix *srcPrefix = reinterpret_cast(src.prefix()); + const ContainerStoragePrefix *srcPrefix = reinterpret_cast(src.prefix()); ContainerStoragePrefix *dstPrefix = reinterpret_cast(dst.prefix()); dstPrefix->version = srcPrefix->version; dstPrefix->nextIv = crypto::randomChachaIV(); @@ -1045,7 +1026,7 @@ namespace cn prefix->nextIv = crypto::randomChachaIV(); uint64_t creationTimestamp = time(nullptr); prefix->encryptedViewKeys = encryptKeyPair(m_viewPublicKey, m_viewSecretKey, creationTimestamp); - for (auto spendKeys : m_walletsContainer.get()) + for (const auto &spendKeys : m_walletsContainer.get()) { m_containerStorage.push_back(encryptKeyPair(spendKeys.spendPublicKey, spendKeys.spendSecretKey, spendKeys.creationTimestamp)); incNextIv(); @@ -1126,7 +1107,7 @@ namespace cn { m_containerStorage.open(path, FileMappedVectorOpenMode::OPEN, sizeof(ContainerStoragePrefix)); - ContainerStoragePrefix *prefix = reinterpret_cast(m_containerStorage.prefix()); + const ContainerStoragePrefix *prefix = reinterpret_cast(m_containerStorage.prefix()); assert(prefix->version >= WalletSerializerV2::MIN_VERSION); uint64_t creationTimestamp; @@ -1266,16 +1247,16 @@ namespace cn { std::vector subscriptionList; m_synchronizer.getSubscriptions(subscriptionList); - for (auto &addr : subscriptionList) + for (const auto &addr : subscriptionList) { auto sub = m_synchronizer.getSubscription(addr); if (sub != nullptr) { std::vector allTransfers; - ITransfersContainer *container = &sub->getContainer(); + const ITransfersContainer *container = &sub->getContainer(); container->getOutputs(allTransfers, ITransfersContainer::IncludeAll); m_logger(INFO, BRIGHT_WHITE) << "Known Transfers " << allTransfers.size(); - for (auto &o : allTransfers) + for (const auto &o : allTransfers) { if (o.type != transaction_types::OutputType::Invalid) { @@ -1386,10 +1367,8 @@ namespace cn auto &subscription = m_synchronizer.addSubscription(sub); bool r = index.modify(it, [&subscription](WalletRecord &rec) { rec.container = &subscription.getContainer(); }); + (void)r; assert(r); - if (r) - { - }; subscription.addObserver(this); } } @@ -1399,7 +1378,7 @@ namespace cn std::vector subscriptionList; m_synchronizer.getSubscriptions(subscriptionList); - for (auto &subscription : subscriptionList) + for (const auto &subscription : subscriptionList) { m_synchronizer.removeSubscription(subscription); } @@ -1499,7 +1478,7 @@ namespace cn { KeyPair spendKey; crypto::generate_keys(spendKey.publicKey, spendKey.secretKey); - uint64_t creationTimestamp = static_cast(time(nullptr)); + auto creationTimestamp = static_cast(time(nullptr)); return doCreateAddress(spendKey.publicKey, spendKey.secretKey, creationTimestamp); } @@ -1511,7 +1490,7 @@ namespace cn { throw std::system_error(make_error_code(cn::error::KEY_GENERATION_ERROR)); } - uint64_t creationTimestamp = static_cast(time(nullptr)); + auto creationTimestamp = static_cast(time(nullptr)); return doCreateAddress(spendPublicKey, spendSecretKey, creationTimestamp); } @@ -1521,7 +1500,7 @@ namespace cn { throw std::system_error(make_error_code(error::WRONG_PARAMETERS), "Wrong public key format"); } - uint64_t creationTimestamp = static_cast(time(nullptr)); + auto creationTimestamp = static_cast(time(nullptr)); return doCreateAddress(spendPublicKey, NULL_SECRET_KEY, creationTimestamp); } @@ -1959,14 +1938,13 @@ namespace cn preparedTransaction.neededMoney = countNeededMoney(preparedTransaction.destinations, fee); std::vector selectedTransfers; - uint64_t foundMoney = selectTransfers(preparedTransaction.neededMoney, m_currency.defaultDustThreshold(), std::move(wallets), selectedTransfers); + uint64_t foundMoney = selectTransfers(preparedTransaction.neededMoney, m_currency.defaultDustThreshold(), wallets, selectedTransfers); if (foundMoney < preparedTransaction.neededMoney) { throw std::system_error(make_error_code(error::WRONG_AMOUNT), "Not enough money"); } - typedef cn::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount outs_for_amount; std::vector mixinResult; if (mixIn != 0) @@ -2048,13 +2026,8 @@ namespace cn size_t WalletGreen::makeTransaction(const TransactionParameters &sendingTransaction) { size_t id = WALLET_INVALID_TRANSACTION_ID; - tools::ScopeExit releaseContext([this, &id] { + tools::ScopeExit releaseContext([this] { m_dispatcher.yield(); - - if (id != WALLET_INVALID_TRANSACTION_ID) - { - auto &tx = m_transactions[id]; - } }); platform_system::EventLock lk(m_readyEvent); @@ -2228,7 +2201,7 @@ namespace cn updated = true; } }); - + (void)r; assert(r); return updated; @@ -2292,7 +2265,7 @@ namespace cn updated = true; } }); - + (void)r; assert(r); return updated; @@ -2330,7 +2303,7 @@ namespace cn return txId; } - uint64_t WalletGreen::scanHeightToTimestamp(const uint32_t scanHeight) + uint64_t WalletGreen::scanHeightToTimestamp(const uint32_t scanHeight) const { if (scanHeight == 0) { @@ -2355,7 +2328,7 @@ namespace cn return timestamp; } - uint64_t WalletGreen::getCurrentTimestampAdjusted() + uint64_t WalletGreen::getCurrentTimestampAdjusted() const { /* Get the current time as a unix timestamp */ std::time_t time = std::time(nullptr); @@ -2658,7 +2631,7 @@ namespace cn bool eraseOutputTransfers) { - return eraseTransfers(transactionId, firstTransferIdx, [this, &knownAddresses, eraseOutputTransfers](bool isOutput, const std::string &transferAddress) { + return eraseTransfers(transactionId, firstTransferIdx, [&knownAddresses, eraseOutputTransfers](bool isOutput, const std::string &transferAddress) { return eraseOutputTransfers == isOutput && knownAddresses.count(transferAddress) == 0; }); } @@ -2732,7 +2705,7 @@ namespace cn throwIfStopped(); auto relayTransactionCompleted = std::promise(); auto relayTransactionWaitFuture = relayTransactionCompleted.get_future(); - m_node.relayTransaction(cryptoNoteTransaction, [&ec, &relayTransactionCompleted, this](std::error_code error) + m_node.relayTransaction(cryptoNoteTransaction, [&ec, &relayTransactionCompleted](std::error_code) { auto detachedPromise = std::move(relayTransactionCompleted); detachedPromise.set_value(ec); @@ -2825,7 +2798,7 @@ namespace cn void WalletGreen::requestMixinOuts( const std::vector &selectedTransfers, uint64_t mixIn, - std::vector &mixinResult) + std::vector &mixinResult) { std::vector amounts; @@ -2841,7 +2814,7 @@ namespace cn auto getRandomOutsByAmountsCompleted = std::promise(); auto getRandomOutsByAmountsWaitFuture = getRandomOutsByAmountsCompleted.get_future(); - m_node.getRandomOutsByAmounts(std::move(amounts), mixIn, mixinResult, [&getRandomOutsByAmountsCompleted, &mixinError, this](std::error_code ec) { + m_node.getRandomOutsByAmounts(std::move(amounts), mixIn, mixinResult, [&getRandomOutsByAmountsCompleted](std::error_code ec) { auto detachedPromise = std::move(getRandomOutsByAmountsCompleted); detachedPromise.set_value(ec); }); @@ -2858,27 +2831,27 @@ namespace cn uint64_t WalletGreen::selectTransfers( uint64_t neededMoney, uint64_t dustThreshold, - std::vector &&wallets, - std::vector &selectedTransfers) + const std::vector &wallets, + std::vector &selectedTransfers) const { uint64_t foundMoney = 0; - typedef std::pair OutputData; + using OutputData = std::pair; std::vector walletOuts; std::unordered_map> buckets; - for (auto walletIt = wallets.begin(); walletIt != wallets.end(); ++walletIt) + for (const auto &wallet : wallets) { - for (auto outIt = walletIt->outs.begin(); outIt != walletIt->outs.end(); ++outIt) + for (const auto &out : wallet.outs) { - int numberOfDigits = floor(log10(outIt->amount)) + 1; + auto numberOfDigits = static_cast(floor(log10(out.amount)) + 1); - if (outIt->amount > dustThreshold) + if (out.amount > dustThreshold) { buckets[numberOfDigits].emplace_back( std::piecewise_construct, - std::forward_as_tuple(walletIt->wallet), - std::forward_as_tuple(*outIt)); + std::forward_as_tuple(wallet.wallet), + std::forward_as_tuple(out)); } } } @@ -2926,14 +2899,14 @@ namespace cn continue; } - ITransfersContainer *container = wallet.container; + const ITransfersContainer *container = wallet.container; WalletOuts outs; container->getOutputs(outs.outs, ITransfersContainer::IncludeKeyUnlocked); outs.wallet = const_cast(&wallet); walletOuts.push_back(std::move(outs)); - }; + } return walletOuts; } @@ -2942,7 +2915,7 @@ namespace cn { const auto &wallet = getWalletRecord(address); - ITransfersContainer *container = wallet.container; + const ITransfersContainer *container = wallet.container; WalletOuts outs; container->getOutputs(outs.outs, ITransfersContainer::IncludeKeyUnlocked); outs.wallet = const_cast(&wallet); @@ -2969,7 +2942,7 @@ namespace cn std::vector WalletGreen::splitDestinations(const std::vector &destinations, uint64_t dustThreshold, - const cn::Currency ¤cy) + const cn::Currency ¤cy) const { std::vector decomposedOutputs; @@ -2986,7 +2959,7 @@ namespace cn cn::WalletGreen::ReceiverAmounts WalletGreen::splitAmount( uint64_t amount, const AccountPublicAddress &destination, - uint64_t dustThreshold) + uint64_t dustThreshold) const { ReceiverAmounts receiverAmounts; @@ -2998,12 +2971,12 @@ namespace cn void WalletGreen::prepareInputs( const std::vector &selectedTransfers, - std::vector &mixinResult, + std::vector &mixinResult, uint64_t mixIn, - std::vector &keysInfo) + std::vector &keysInfo) const { - typedef cn::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry; + using out_entry = cn::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry; size_t i = 0; for (const auto &input : selectedTransfers) @@ -3015,9 +2988,8 @@ namespace cn { std::sort(mixinResult[i].outs.begin(), mixinResult[i].outs.end(), [](const out_entry &a, const out_entry &b) { return a.global_amount_index < b.global_amount_index; }); - for (auto &fakeOut : mixinResult[i].outs) + for (const auto &fakeOut : mixinResult[i].outs) { - if (input.out.globalOutputIndex == fakeOut.global_amount_index) { continue; @@ -3025,10 +2997,12 @@ namespace cn transaction_types::GlobalOutput globalOutput; globalOutput.outputIndex = static_cast(fakeOut.global_amount_index); - globalOutput.targetKey = reinterpret_cast(fakeOut.out_key); + globalOutput.targetKey = fakeOut.out_key; keyInfo.outputs.push_back(std::move(globalOutput)); if (keyInfo.outputs.size() >= mixIn) + { break; + } } } @@ -3039,7 +3013,7 @@ namespace cn transaction_types::GlobalOutput realOutput; realOutput.outputIndex = input.out.globalOutputIndex; - realOutput.targetKey = reinterpret_cast(input.out.outputKey); + realOutput.targetKey = input.out.outputKey; auto insertedIn = keyInfo.outputs.insert(insertIn, realOutput); @@ -3089,7 +3063,7 @@ namespace cn auto heightIt = m_blockchain.project(it); - uint32_t blockIndex = static_cast(std::distance(m_blockchain.get().begin(), heightIt)); + auto blockIndex = static_cast(std::distance(m_blockchain.get().begin(), heightIt)); return getTransactionsInBlocks(blockIndex, count); } @@ -3107,7 +3081,7 @@ namespace cn auto heightIt = m_blockchain.project(it); - uint32_t blockIndex = static_cast(std::distance(m_blockchain.get().begin(), heightIt)); + auto blockIndex = static_cast(std::distance(m_blockchain.get().begin(), heightIt)); return getDepositsInBlocks(blockIndex, count); } @@ -3149,7 +3123,7 @@ namespace cn throwIfNotInitialized(); throwIfStopped(); - uint32_t blockCount = static_cast(m_blockchain.size()); + auto blockCount = static_cast(m_blockchain.size()); assert(blockCount != 0); return blockCount; @@ -3235,6 +3209,7 @@ namespace cn void WalletGreen::onError(ITransfersSubscription *object, uint32_t height, std::error_code ec) { + // Do nothing } void WalletGreen::synchronizationProgressUpdated(uint32_t processedBlockCount, uint32_t totalBlockCount) @@ -3313,7 +3288,7 @@ namespace cn void WalletGreen::onTransactionDeleteBegin(const crypto::PublicKey &viewPublicKey, const crypto::Hash &transactionHash) { - m_dispatcher.remoteSpawn([=]() { transactionDeleteBegin(transactionHash); }); + m_dispatcher.remoteSpawn([this, &transactionHash]() { transactionDeleteBegin(transactionHash); }); } // TODO remove @@ -3323,7 +3298,7 @@ namespace cn void WalletGreen::onTransactionDeleteEnd(const crypto::PublicKey &viewPublicKey, const crypto::Hash &transactionHash) { - m_dispatcher.remoteSpawn([=]() { transactionDeleteEnd(transactionHash); }); + m_dispatcher.remoteSpawn([this, &transactionHash]() { transactionDeleteEnd(transactionHash); }); } // TODO remove @@ -3370,9 +3345,7 @@ namespace cn // transaction uint64_t outputsAmount; bool found = container->getTransactionInformation(transactionHash, info, &inputsAmount, &outputsAmount); - if (found) - { - } + (void)found; assert(found); ContainerAmounts containerAmounts; @@ -3542,7 +3515,7 @@ namespace cn proof.txid = td.transactionHash; proof.index_in_tx = td.outputInTransaction; - auto txPubKey = td.transactionPublicKey; + const auto& txPubKey = td.transactionPublicKey; for (int i = 0; i < 2; ++i) { @@ -3609,7 +3582,7 @@ namespace cn { crypto::generate_tx_proof(transactionHash, R, address.viewPublicKey, rA, tx_key, sig); } - catch (std::runtime_error) + catch (std::runtime_error&) { return false; } @@ -3657,7 +3630,7 @@ namespace cn m_fusionTxsCache.emplace(transactionId, isFusionTransaction(*it)); } - for (auto containerAmounts : containerAmountsList) + for (const auto& containerAmounts : containerAmountsList) { auto newDepositOuts = containerAmounts.container->getTransactionOutputs(transactionInfo.transactionHash, ITransfersContainer::IncludeTypeDeposit | ITransfersContainer::IncludeStateAll); auto spentDepositOutputs = containerAmounts.container->getTransactionInputs(transactionInfo.transactionHash, ITransfersContainer::IncludeTypeDeposit); @@ -3665,7 +3638,7 @@ namespace cn std::vector updatedDepositIds; /* Check for new deposits in this transaction, and create them */ - for (size_t i = 0; i < newDepositOuts.size(); i++) + for (const auto& depositOutput: newDepositOuts) { /* We only add confirmed deposit entries, so this condition prevents the same deposit in the deposit index during creation and during confirmation */ @@ -3673,14 +3646,14 @@ namespace cn { continue; } - auto id = insertNewDeposit(newDepositOuts[i], transactionId, m_currency, transactionInfo.blockHeight); + auto id = insertNewDeposit(depositOutput, transactionId, m_currency, transactionInfo.blockHeight); updatedDepositIds.push_back(id); } /* Now check for any deposit withdrawals in the transactions */ - for (size_t i = 0; i < spentDepositOutputs.size(); i++) + for (const auto& depositOutput: spentDepositOutputs) { - auto depositId = getDepositId(spentDepositOutputs[i].transactionHash); + auto depositId = getDepositId(depositOutput.transactionHash); assert(depositId != WALLET_INVALID_DEPOSIT_ID); if (depositId == WALLET_INVALID_DEPOSIT_ID) { @@ -4065,13 +4038,8 @@ namespace cn { size_t id = WALLET_INVALID_TRANSACTION_ID; - tools::ScopeExit releaseContext([this, &id] { + tools::ScopeExit releaseContext([this] { m_dispatcher.yield(); - - if (id != WALLET_INVALID_TRANSACTION_ID) - { - auto &tx = m_transactions[id]; - } }); platform_system::EventLock lk(m_readyEvent); @@ -4111,7 +4079,6 @@ namespace cn return WALLET_INVALID_TRANSACTION_ID; } - using outs_for_amount = cn::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount; std::vector mixinResult; if (mixin != 0) { @@ -4161,7 +4128,7 @@ namespace cn return id; } - WalletGreen::ReceiverAmounts WalletGreen::decomposeFusionOutputs(const AccountPublicAddress &address, uint64_t inputsAmount) + WalletGreen::ReceiverAmounts WalletGreen::decomposeFusionOutputs(const AccountPublicAddress &address, uint64_t inputsAmount) const { WalletGreen::ReceiverAmounts outputs; outputs.receiver = address; @@ -4337,9 +4304,9 @@ namespace cn auto walletOuts = sourceAddresses.empty() ? pickWalletsWithMoney() : pickWallets(sourceAddresses); std::array::digits10 + 1> bucketSizes; bucketSizes.fill(0); - for (size_t walletIndex = 0; walletIndex < walletOuts.size(); ++walletIndex) + for (const auto &wallet : walletOuts) { - for (auto &out : walletOuts[walletIndex].outs) + for (const auto &out : wallet.outs) { uint8_t powerOfTen = 0; if (m_currency.isAmountApplicableInFusionTransactionInput(out.amount, threshold, powerOfTen, m_node.getLastKnownBlockHeight())) @@ -4349,7 +4316,7 @@ namespace cn } } - result.totalOutputCount += walletOuts[walletIndex].outs.size(); + result.totalOutputCount += wallet.outs.size(); } for (auto bucketSize : bucketSizes) @@ -4364,21 +4331,21 @@ namespace cn } std::vector WalletGreen::pickRandomFusionInputs(const std::vector &addresses, - uint64_t threshold, size_t minInputCount, size_t maxInputCount) + uint64_t threshold, size_t minInputCount, size_t maxInputCount) const { std::vector allFusionReadyOuts; auto walletOuts = addresses.empty() ? pickWalletsWithMoney() : pickWallets(addresses); std::array::digits10 + 1> bucketSizes; bucketSizes.fill(0); - for (size_t walletIndex = 0; walletIndex < walletOuts.size(); ++walletIndex) + for (auto &walletOut : walletOuts) { - for (auto &out : walletOuts[walletIndex].outs) + for (auto &out : walletOut.outs) { uint8_t powerOfTen = 0; if (m_currency.isAmountApplicableInFusionTransactionInput(out.amount, threshold, powerOfTen, m_node.getLastKnownBlockHeight())) { - allFusionReadyOuts.push_back({std::move(out), walletOuts[walletIndex].wallet}); + allFusionReadyOuts.push_back({std::move(out), walletOut.wallet}); assert(powerOfTen < std::numeric_limits::digits10 + 1); bucketSizes[powerOfTen]++; } @@ -4415,11 +4382,11 @@ namespace cn uint64_t upperBound = selectedBucket == std::numeric_limits::digits10 ? UINT64_MAX : lowerBound * 10; std::vector selectedOuts; selectedOuts.reserve(bucketSizes[selectedBucket]); - for (size_t outIndex = 0; outIndex < allFusionReadyOuts.size(); ++outIndex) + for (auto& output: allFusionReadyOuts) { - if (allFusionReadyOuts[outIndex].out.amount >= lowerBound && allFusionReadyOuts[outIndex].out.amount < upperBound) + if (output.out.amount >= lowerBound && output.out.amount < upperBound) { - selectedOuts.push_back(std::move(allFusionReadyOuts[outIndex])); + selectedOuts.push_back(std::move(output)); } } @@ -4459,7 +4426,7 @@ namespace cn } auto &blockHeightIndex = m_deposits.get(); - uint32_t stopIndex = static_cast(std::min(m_blockchain.size(), blockIndex + count)); + auto stopIndex = static_cast(std::min(m_blockchain.size(), blockIndex + count)); for (uint32_t height = blockIndex; height < stopIndex; ++height) { @@ -4495,7 +4462,7 @@ namespace cn } auto &blockHeightIndex = m_transactions.get(); - uint32_t stopIndex = static_cast(std::min(m_blockchain.size(), blockIndex + count)); + auto stopIndex = static_cast(std::min(m_blockchain.size(), blockIndex + count)); for (uint32_t height = blockIndex; height < stopIndex; ++height) { @@ -4586,12 +4553,6 @@ namespace cn } } - void WalletGreen::getViewKeyKnownBlocks(const crypto::PublicKey &viewPublicKey) - { - std::vector blockchain = m_synchronizer.getViewKeyKnownBlocks(m_viewPublicKey); - m_blockchain.insert(m_blockchain.end(), blockchain.begin(), blockchain.end()); - } - ///pre: changeDestinationAddress belongs to current container ///pre: source address belongs to current container cn::AccountPublicAddress WalletGreen::getChangeDestination(const std::string &changeDestinationAddress, const std::vector &sourceAddresses) const diff --git a/src/Wallet/WalletGreen.h b/src/Wallet/WalletGreen.h index 424766ec3..be031daca 100644 --- a/src/Wallet/WalletGreen.h +++ b/src/Wallet/WalletGreen.h @@ -24,6 +24,7 @@ namespace cn { + using outs_for_amount= cn::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount; class WalletGreen : public IObservableImpl, public ITransfersObserver, @@ -36,9 +37,9 @@ class WalletGreen : public IObservableImpl, ~WalletGreen() override; /* Deposit related functions */ - void createDeposit(uint64_t amount, uint64_t term, std::string sourceAddress, std::string destinationAddress, std::string &transactionHash) override; + void createDeposit(uint64_t amount, uint32_t term, std::string sourceAddress, std::string destinationAddress, std::string &transactionHash) override; void withdrawDeposit(DepositId depositId, std::string &transactionHash) override; - std::vector prepareMultisignatureInputs(const std::vector &selectedTransfers); + std::vector prepareMultisignatureInputs(const std::vector &selectedTransfers) const; void initialize(const std::string& path, const std::string& password) override; @@ -156,8 +157,8 @@ class WalletGreen : public IObservableImpl, std::string doCreateAddress(const crypto::PublicKey &spendPublicKey, const crypto::SecretKey &spendSecretKey, uint64_t creationTimestamp); std::vector doCreateAddressList(const std::vector &addressDataList); - uint64_t scanHeightToTimestamp(const uint32_t scanHeight); - uint64_t getCurrentTimestampAdjusted(); + uint64_t scanHeightToTimestamp(const uint32_t scanHeight) const; + uint64_t getCurrentTimestampAdjusted() const; struct InputInfo { @@ -284,21 +285,21 @@ class WalletGreen : public IObservableImpl, void requestMixinOuts(const std::vector &selectedTransfers, uint64_t mixIn, - std::vector &mixinResult); + std::vector &mixinResult); void prepareInputs(const std::vector &selectedTransfers, - std::vector &mixinResult, + std::vector &mixinResult, uint64_t mixIn, - std::vector &keysInfo); + std::vector &keysInfo) const; uint64_t selectTransfers(uint64_t needeMoney, uint64_t dustThreshold, - std::vector &&wallets, - std::vector &selectedTransfers); + const std::vector &wallets, + std::vector &selectedTransfers) const; std::vector splitDestinations(const std::vector &destinations, - uint64_t dustThreshold, const Currency ¤cy); - ReceiverAmounts splitAmount(uint64_t amount, const AccountPublicAddress &destination, uint64_t dustThreshold); + uint64_t dustThreshold, const Currency ¤cy) const; + ReceiverAmounts splitAmount(uint64_t amount, const AccountPublicAddress &destination, uint64_t dustThreshold) const; std::unique_ptr makeTransaction(const std::vector &decomposedOutputs, std::vector &keysInfo, const std::vector &messages, const std::string &extra, uint64_t unlockTimestamp, crypto::SecretKey &transactionSK); @@ -337,7 +338,7 @@ class WalletGreen : public IObservableImpl, static void encryptAndSaveContainerData(ContainerStorage& storage, const crypto::chacha8_key& key, const void* containerData, size_t containerDataSize); void loadWalletCache(std::unordered_set& addedKeys, std::unordered_set& deletedKeys, std::string& extra); - void copyContainerStorageKeys(ContainerStorage& src, const crypto::chacha8_key& srcKey, ContainerStorage& dst, const crypto::chacha8_key& dstKey); + void copyContainerStorageKeys(const ContainerStorage& src, const crypto::chacha8_key& srcKey, ContainerStorage& dst, const crypto::chacha8_key& dstKey) const; static void copyContainerStoragePrefix(ContainerStorage& src, const crypto::chacha8_key& srcKey, ContainerStorage& dst, const crypto::chacha8_key& dstKey); void deleteOrphanTransactions(const std::unordered_set &deletedKeys); @@ -348,9 +349,9 @@ class WalletGreen : public IObservableImpl, void subscribeWallets(); std::vector pickRandomFusionInputs(const std::vector &addresses, - uint64_t threshold, size_t minInputCount, size_t maxInputCount); + uint64_t threshold, size_t minInputCount, size_t maxInputCount) const; - ReceiverAmounts decomposeFusionOutputs(const AccountPublicAddress &address, uint64_t inputsAmount); + ReceiverAmounts decomposeFusionOutputs(const AccountPublicAddress &address, uint64_t inputsAmount) const; enum class WalletState { @@ -375,7 +376,6 @@ class WalletGreen : public IObservableImpl, std::vector getTransactionTransfers(const WalletTransaction &transaction) const; void filterOutTransactions(WalletTransactions &transactions, WalletTransfers &transfers, std::function &&pred) const; void initBlockchain(const crypto::PublicKey& viewPublicKey); - void getViewKeyKnownBlocks(const crypto::PublicKey &viewPublicKey); cn::AccountPublicAddress getChangeDestination(const std::string &changeDestinationAddress, const std::vector &sourceAddresses) const; bool isMyAddress(const std::string &address) const; @@ -396,7 +396,7 @@ class WalletGreen : public IObservableImpl, const Currency &m_currency; INode &m_node; mutable logging::LoggerRef m_logger; - bool m_stopped; + bool m_stopped = false; WalletDeposits m_deposits; WalletsContainer m_walletsContainer; ContainerStorage m_containerStorage; @@ -406,7 +406,7 @@ class WalletGreen : public IObservableImpl, mutable std::unordered_map m_fusionTxsCache; // txIndex -> isFusion UncommitedTransactions m_uncommitedTransactions; - bool m_blockchainSynchronizerStarted; + bool m_blockchainSynchronizerStarted = false; BlockchainSynchronizer m_blockchainSynchronizer; TransfersSyncronizer m_synchronizer; @@ -414,7 +414,7 @@ class WalletGreen : public IObservableImpl, std::queue m_events; mutable platform_system::Event m_readyEvent; - WalletState m_state; + WalletState m_state = WalletState::NOT_INITIALIZED; std::string m_password; crypto::chacha8_key m_key; @@ -424,10 +424,10 @@ class WalletGreen : public IObservableImpl, crypto::PublicKey m_viewPublicKey; crypto::SecretKey m_viewSecretKey; - uint64_t m_actualBalance; - uint64_t m_pendingBalance; - uint64_t m_lockedDepositBalance; - uint64_t m_unlockedDepositBalance; + uint64_t m_actualBalance = 0; + uint64_t m_pendingBalance = 0; + uint64_t m_lockedDepositBalance = 0; + uint64_t m_unlockedDepositBalance = 0; uint64_t m_upperTransactionSizeLimit; uint32_t m_transactionSoftLockTime; diff --git a/src/Wallet/WalletSerializationV1.cpp b/src/Wallet/WalletSerializationV1.cpp index 07496ea78..333014797 100644 --- a/src/Wallet/WalletSerializationV1.cpp +++ b/src/Wallet/WalletSerializationV1.cpp @@ -264,7 +264,7 @@ cn::WalletTransfer convert(const cn::WalletLegacyTransfer& tr) { namespace cn { -const uint32_t WalletSerializer::SERIALIZATION_VERSION = 5; +const uint8_t WalletSerializer::SERIALIZATION_VERSION = 5; void CryptoContext::incIv() { uint64_t * i = reinterpret_cast(&iv.data[0]); diff --git a/src/Wallet/WalletSerializationV1.h b/src/Wallet/WalletSerializationV1.h index 9513f9391..b35806d52 100644 --- a/src/Wallet/WalletSerializationV1.h +++ b/src/Wallet/WalletSerializationV1.h @@ -48,7 +48,7 @@ class WalletSerializer void load(const crypto::chacha8_key &key, common::IInputStream &source); private: - static const uint32_t SERIALIZATION_VERSION; + static const uint8_t SERIALIZATION_VERSION; void loadWallet(common::IInputStream &source, const crypto::chacha8_key &key, uint32_t version); void loadWalletV1(common::IInputStream &source, const crypto::chacha8_key &key); diff --git a/tests/UnitTests/TestWalletService.cpp b/tests/UnitTests/TestWalletService.cpp index 277837ce3..392bcc31e 100644 --- a/tests/UnitTests/TestWalletService.cpp +++ b/tests/UnitTests/TestWalletService.cpp @@ -101,7 +101,7 @@ struct IWalletBaseStub : public cn::IWallet, public cn::IFusionManager { virtual void start() override { m_stopped = false; } virtual void stop() override { m_stopped = true; m_eventOccurred.set(); } - void createDeposit(uint64_t amount, uint64_t term, std::string sourceAddress, std::string destinationAddress, std::string &transactionHash) override {} + void createDeposit(uint64_t amount, uint32_t term, std::string sourceAddress, std::string destinationAddress, std::string &transactionHash) override {} void withdrawDeposit(DepositId depositId, std::string &transactionHash) override{}; Deposit getDeposit(size_t depositIndex) const override { From 080f889cea03aa0a1925d45b047114eb744d2712 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 9 Apr 2023 16:41:09 +0200 Subject: [PATCH 09/30] Remove WalletGreen message duplication --- src/Wallet/WalletGreen.cpp | 43 ++++---------------------------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index 97cf7bf97..e7b6ca07f 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -335,24 +335,6 @@ namespace cn crypto::SecretKey transactionSK; transaction->getTransactionSecretKey(transactionSK); - /* Add the transaction extra */ - std::vector messages; - crypto::PublicKey publicKey = transaction->getTransactionPublicKey(); - cn::KeyPair kp = {publicKey, transactionSK}; - for (size_t i = 0; i < messages.size(); ++i) - { - cn::AccountPublicAddress addressBin; - if (!m_currency.parseAccountAddressString(messages[i].address, addressBin)) - continue; - cn::tx_extra_message tag; - if (!tag.encrypt(i, messages[i].message, &addressBin, kp)) - continue; - BinaryArray ba; - toBinaryArray(tag, ba); - ba.insert(ba.begin(), TX_EXTRA_MESSAGE_TAG); - transaction->appendExtra(ba); - } - assert(inputs.size() == selectedTransfers.size()); for (size_t i = 0; i < inputs.size(); ++i) { @@ -518,24 +500,6 @@ namespace cn transaction->getTransactionSecretKey(transactionSK); transaction->setUnlockTime(0); - /* Add the transaction extra */ - std::vector messages; - crypto::PublicKey publicKey = transaction->getTransactionPublicKey(); - cn::KeyPair kp = {publicKey, transactionSK}; - for (size_t i = 0; i < messages.size(); ++i) - { - cn::AccountPublicAddress addressBin; - if (!m_currency.parseAccountAddressString(messages[i].address, addressBin)) - continue; - cn::tx_extra_message tag; - if (!tag.encrypt(i, messages[i].message, &addressBin, kp)) - continue; - BinaryArray ba; - toBinaryArray(tag, ba); - ba.insert(ba.begin(), TX_EXTRA_MESSAGE_TAG); - transaction->appendExtra(ba); - } - /* Prepare the inputs */ /* Get additional inputs for the mixin */ @@ -2677,9 +2641,10 @@ namespace cn if (!tag.encrypt(i, messages[i].message, &addressBin, kp)) continue; BinaryArray ba; - toBinaryArray(tag, ba); - ba.insert(ba.begin(), TX_EXTRA_MESSAGE_TAG); - tx->appendExtra(ba); + if (cn::append_message_to_extra(ba, tag)) + { + tx->appendExtra(ba); + } } for (const auto &amountToAddress : amountsToAddresses) From 17ca1389f83146a5457740d17a1fb2cd0bbbf031 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 9 Apr 2023 18:45:20 +0200 Subject: [PATCH 10/30] Remove WalletGreen transaction duplication --- src/Wallet/WalletGreen.cpp | 55 ++++++++------------------------------ src/Wallet/WalletGreen.h | 4 +-- 2 files changed, 13 insertions(+), 46 deletions(-) diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index e7b6ca07f..fa5fbdfda 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -1871,9 +1871,8 @@ namespace cn size_t WalletGreen::transfer(const TransactionParameters &transactionParameters, crypto::SecretKey &transactionSK) { - tools::ScopeExit releaseContext([this] { - m_dispatcher.yield(); - }); + tools::ScopeExit releaseContext([this] + { m_dispatcher.yield(); }); platform_system::EventLock lk(m_readyEvent); @@ -1881,11 +1880,11 @@ namespace cn throwIfTrackingMode(); throwIfStopped(); - return doTransfer(transactionParameters, transactionSK); + return doTransfer(transactionParameters, transactionSK, true); } void WalletGreen::prepareTransaction( - std::vector &&wallets, + const std::vector &wallets, const std::vector &orders, const std::vector &messages, uint64_t fee, @@ -1955,7 +1954,7 @@ namespace cn validateOrders(transactionParameters.destinations); } - size_t WalletGreen::doTransfer(const TransactionParameters &transactionParameters, crypto::SecretKey &transactionSK) + size_t WalletGreen::doTransfer(const TransactionParameters &transactionParameters, crypto::SecretKey &transactionSK, bool send) { validateTransactionParameters(transactionParameters); cn::AccountPublicAddress changeDestination = getChangeDestination(transactionParameters.changeDestination, transactionParameters.sourceAddresses); @@ -1972,7 +1971,7 @@ namespace cn PreparedTransaction preparedTransaction; prepareTransaction( - std::move(wallets), + wallets, transactionParameters.destinations, transactionParameters.messages, transactionParameters.fee, @@ -1984,53 +1983,21 @@ namespace cn preparedTransaction, transactionSK); - return validateSaveAndSendTransaction(*preparedTransaction.transaction, preparedTransaction.destinations, false, true); + return validateSaveAndSendTransaction(*preparedTransaction.transaction, preparedTransaction.destinations, false, send); } size_t WalletGreen::makeTransaction(const TransactionParameters &sendingTransaction) { - size_t id = WALLET_INVALID_TRANSACTION_ID; - tools::ScopeExit releaseContext([this] { - m_dispatcher.yield(); - }); + tools::ScopeExit releaseContext([this] + { m_dispatcher.yield(); }); platform_system::EventLock lk(m_readyEvent); throwIfNotInitialized(); throwIfTrackingMode(); throwIfStopped(); - - validateTransactionParameters(sendingTransaction); - cn::AccountPublicAddress changeDestination = getChangeDestination(sendingTransaction.changeDestination, sendingTransaction.sourceAddresses); - m_logger(DEBUGGING) << "Change address " << m_currency.accountAddressAsString(changeDestination); - - std::vector wallets; - if (!sendingTransaction.sourceAddresses.empty()) - { - wallets = pickWallets(sendingTransaction.sourceAddresses); - } - else - { - wallets = pickWalletsWithMoney(); - } - - PreparedTransaction preparedTransaction; crypto::SecretKey txSecretKey; - prepareTransaction( - std::move(wallets), - sendingTransaction.destinations, - sendingTransaction.messages, - sendingTransaction.fee, - sendingTransaction.mixIn, - sendingTransaction.extra, - sendingTransaction.unlockTimestamp, - sendingTransaction.donation, - changeDestination, - preparedTransaction, - txSecretKey); - - id = validateSaveAndSendTransaction(*preparedTransaction.transaction, preparedTransaction.destinations, false, false); - return id; + return doTransfer(sendingTransaction, txSecretKey, false); } void WalletGreen::commitTransaction(size_t transactionId) @@ -4669,7 +4636,7 @@ namespace cn PreparedTransaction preparedTransaction; crypto::SecretKey txSecretKey; prepareTransaction( - std::move(wallets), + wallets, sendingTransaction.destinations, sendingTransaction.messages, sendingTransaction.fee, diff --git a/src/Wallet/WalletGreen.h b/src/Wallet/WalletGreen.h index be031daca..1ddf36d5f 100644 --- a/src/Wallet/WalletGreen.h +++ b/src/Wallet/WalletGreen.h @@ -264,7 +264,7 @@ class WalletGreen : public IObservableImpl, uint64_t changeAmount; }; - void prepareTransaction(std::vector &&wallets, + void prepareTransaction(const std::vector &wallets, const std::vector &orders, const std::vector &messages, uint64_t fee, @@ -281,7 +281,7 @@ class WalletGreen : public IObservableImpl, void validateOrders(const std::vector &orders) const; void validateTransactionParameters(const TransactionParameters &transactionParameters) const; - size_t doTransfer(const TransactionParameters &transactionParameters, crypto::SecretKey &transactionSK); + size_t doTransfer(const TransactionParameters &transactionParameters, crypto::SecretKey &transactionSK, bool send); void requestMixinOuts(const std::vector &selectedTransfers, uint64_t mixIn, From 2691680d0409b79812fbca15d077ed64df3fc571 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 15 Apr 2023 14:28:04 +0200 Subject: [PATCH 11/30] Fix promise --- src/Wallet/WalletGreen.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index fa5fbdfda..44f503625 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -2633,16 +2633,15 @@ namespace cn void WalletGreen::sendTransaction(const cn::Transaction &cryptoNoteTransaction) { - std::error_code ec; throwIfStopped(); auto relayTransactionCompleted = std::promise(); auto relayTransactionWaitFuture = relayTransactionCompleted.get_future(); - m_node.relayTransaction(cryptoNoteTransaction, [&ec, &relayTransactionCompleted](std::error_code) + m_node.relayTransaction(cryptoNoteTransaction, [&relayTransactionCompleted](std::error_code ec) { auto detachedPromise = std::move(relayTransactionCompleted); detachedPromise.set_value(ec); }); - ec = relayTransactionWaitFuture.get(); + std::error_code ec = relayTransactionWaitFuture.get(); if (ec) { @@ -2739,24 +2738,22 @@ namespace cn amounts.push_back(out.out.amount); } - std::error_code mixinError; - throwIfStopped(); auto getRandomOutsByAmountsCompleted = std::promise(); auto getRandomOutsByAmountsWaitFuture = getRandomOutsByAmountsCompleted.get_future(); m_node.getRandomOutsByAmounts(std::move(amounts), mixIn, mixinResult, [&getRandomOutsByAmountsCompleted](std::error_code ec) { - auto detachedPromise = std::move(getRandomOutsByAmountsCompleted); + auto detachedPromise = std::move(getRandomOutsByAmountsCompleted); detachedPromise.set_value(ec); }); - mixinError = getRandomOutsByAmountsWaitFuture.get(); + std::error_code ec = getRandomOutsByAmountsWaitFuture.get(); checkIfEnoughMixins(mixinResult, mixIn); - if (mixinError) + if (ec) { - throw std::system_error(mixinError); + throw std::system_error(ec); } } From 8edffedb9b594a70b00206b1ff6ad7be5458ba33 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 15 Apr 2023 15:22:17 +0200 Subject: [PATCH 12/30] Add messages to WalletTransaction --- include/IWallet.h | 1 + src/Wallet/WalletGreen.cpp | 26 +++++++++++++++++++++++++- src/Wallet/WalletGreen.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/IWallet.h b/include/IWallet.h index 867e60838..7a3c488ca 100644 --- a/include/IWallet.h +++ b/include/IWallet.h @@ -107,6 +107,7 @@ struct WalletTransaction size_t firstDepositId = WALLET_INVALID_DEPOSIT_ID; size_t depositCount = 0; bool isBase; + std::vector messages; }; enum class WalletTransferType : uint8_t diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index 44f503625..c8d7e3dfc 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -1810,7 +1810,23 @@ namespace cn throw std::system_error(make_error_code(cn::error::INDEX_OUT_OF_RANGE)); } - return m_transactions.get()[transactionIndex]; + WalletTransaction transaction = m_transactions.get()[transactionIndex]; + transaction.messages = getMessagesFromExtra(transaction.extra); + return transaction; + } + + std::vector WalletGreen::getMessagesFromExtra(const std::string &extra) const + { + std::vector messages; + std::vector extraBin = common::asBinaryArray(extra); + crypto::PublicKey publicKey = cn::getTransactionPublicKeyFromExtra(extraBin); + for (size_t i = 0; i < getAddressCount(); ++i) + { + crypto::SecretKey secretKey = getAddressSpendKey(getAddress(i)).secretKey; + std::vector m = cn::get_messages_from_extra(extraBin, publicKey, &secretKey); + messages.insert(std::end(messages), std::begin(m), std::end(m)); + } + return messages; } Deposit WalletGreen::getDeposit(size_t depositIndex) const @@ -2195,6 +2211,12 @@ namespace cn transaction.isBase = isBase; updated = true; } + + if (transaction.messages != info.messages) + { + transaction.messages = info.messages; + updated = true; + } }); (void)r; assert(r); @@ -2227,6 +2249,7 @@ namespace cn tx.extra.assign(reinterpret_cast(info.extra.data()), info.extra.size()); tx.totalAmount = txBalance; tx.creationTime = info.timestamp; + tx.messages = info.messages; size_t txId = index.size(); index.push_back(std::move(tx)); @@ -2973,6 +2996,7 @@ namespace cn WalletTransactionWithTransfers walletTransaction; walletTransaction.transaction = *it; + walletTransaction.transaction.messages = getMessagesFromExtra(it->extra); walletTransaction.transfers = getTransactionTransfers(*it); return walletTransaction; diff --git a/src/Wallet/WalletGreen.h b/src/Wallet/WalletGreen.h index 1ddf36d5f..313dee48c 100644 --- a/src/Wallet/WalletGreen.h +++ b/src/Wallet/WalletGreen.h @@ -384,6 +384,7 @@ class WalletGreen : public IObservableImpl, void deleteFromUncommitedTransactions(const std::vector &deletedTransactions); void pushToPaymentsIndex(const crypto::Hash &paymentId, size_t txId); void buildPaymentIds(); + std::vector getMessagesFromExtra(const std::string &extra) const; cn::WalletEvent makeTransactionUpdatedEvent(size_t id); cn::WalletEvent makeTransactionCreatedEvent(size_t id); From a2f8ed393fbfa8dc80b1f7121df4a353b5788b77 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 22 Apr 2023 16:07:55 +0200 Subject: [PATCH 13/30] Add ttl to WalletGreen --- include/IWallet.h | 1 + src/ConcealWallet/ConcealWallet.cpp | 2 +- src/Wallet/WalletGreen.cpp | 21 +++++++++++++++++---- src/Wallet/WalletGreen.h | 3 ++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/include/IWallet.h b/include/IWallet.h index 7a3c488ca..c44727fab 100644 --- a/include/IWallet.h +++ b/include/IWallet.h @@ -155,6 +155,7 @@ struct TransactionParameters uint64_t unlockTimestamp = 0; DonationSettings donation; std::string changeDestination; + uint64_t ttl = 0; }; struct WalletTransactionWithTransfers diff --git a/src/ConcealWallet/ConcealWallet.cpp b/src/ConcealWallet/ConcealWallet.cpp index 3a4d7c58f..7e0fec321 100644 --- a/src/ConcealWallet/ConcealWallet.cpp +++ b/src/ConcealWallet/ConcealWallet.cpp @@ -1353,7 +1353,7 @@ bool conceal_wallet::transfer(const std::vector &args) { sendParams.destinations = cmd.dsts; sendParams.messages = messages; sendParams.extra = extraString; - sendParams.unlockTimestamp = ttl; + sendParams.ttl = ttl; sendParams.changeDestination = m_wallet->getAddress(0); crypto::SecretKey transactionSK; diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index c8d7e3dfc..854841f02 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -1909,10 +1909,14 @@ namespace cn uint64_t unlockTimestamp, const DonationSettings &donation, const cn::AccountPublicAddress &changeDestination, + uint64_t ttl, PreparedTransaction &preparedTransaction, crypto::SecretKey &transactionSK) { - + if (ttl != 0) + { + fee = 0; + } preparedTransaction.destinations = convertOrdersToTransfers(orders); preparedTransaction.neededMoney = countNeededMoney(preparedTransaction.destinations, fee); @@ -1950,7 +1954,7 @@ namespace cn decomposedOutputs.emplace_back(std::move(splittedChange)); } - preparedTransaction.transaction = makeTransaction(decomposedOutputs, keysInfo, messages, extra, unlockTimestamp, transactionSK); + preparedTransaction.transaction = makeTransaction(decomposedOutputs, keysInfo, messages, extra, unlockTimestamp, ttl, transactionSK); } void WalletGreen::validateTransactionParameters(const TransactionParameters &transactionParameters) const @@ -1996,6 +2000,7 @@ namespace cn transactionParameters.unlockTimestamp, transactionParameters.donation, changeDestination, + transactionParameters.ttl, preparedTransaction, transactionSK); @@ -2591,7 +2596,7 @@ namespace cn } std::unique_ptr WalletGreen::makeTransaction(const std::vector &decomposedOutputs, - std::vector &keysInfo, const std::vector &messages, const std::string &extra, uint64_t unlockTimestamp, crypto::SecretKey &transactionSK) + std::vector &keysInfo, const std::vector &messages, const std::string &extra, uint64_t unlockTimestamp, uint64_t ttl, crypto::SecretKey &transactionSK) { std::unique_ptr tx = createTransaction(); @@ -2637,6 +2642,13 @@ namespace cn } } + if (ttl != 0) + { + BinaryArray ba; + cn::appendTTLToExtra(ba, ttl); + tx->appendExtra(ba); + } + for (const auto &amountToAddress : amountsToAddresses) { tx->addOutput(amountToAddress.second, *amountToAddress.first); @@ -4063,7 +4075,7 @@ namespace cn crypto::SecretKey txkey; std::vector messages; - fusionTransaction = makeTransaction(std::vector{decomposedOutputs}, keysInfo, messages, "", 0, txkey); + fusionTransaction = makeTransaction(std::vector{decomposedOutputs}, keysInfo, messages, "", 0, 0, txkey); transactionSize = getTransactionSize(*fusionTransaction); ++round; @@ -4666,6 +4678,7 @@ namespace cn sendingTransaction.unlockTimestamp, sendingTransaction.donation, changeDestination, + sendingTransaction.ttl, preparedTransaction, txSecretKey); diff --git a/src/Wallet/WalletGreen.h b/src/Wallet/WalletGreen.h index 313dee48c..66d3aaa84 100644 --- a/src/Wallet/WalletGreen.h +++ b/src/Wallet/WalletGreen.h @@ -273,6 +273,7 @@ class WalletGreen : public IObservableImpl, uint64_t unlockTimestamp, const DonationSettings &donation, const cn::AccountPublicAddress &changeDestinationAddress, + uint64_t ttl, PreparedTransaction &preparedTransaction, crypto::SecretKey &transactionSK); void validateAddresses(const std::vector &addresses) const; @@ -302,7 +303,7 @@ class WalletGreen : public IObservableImpl, ReceiverAmounts splitAmount(uint64_t amount, const AccountPublicAddress &destination, uint64_t dustThreshold) const; std::unique_ptr makeTransaction(const std::vector &decomposedOutputs, - std::vector &keysInfo, const std::vector &messages, const std::string &extra, uint64_t unlockTimestamp, crypto::SecretKey &transactionSK); + std::vector &keysInfo, const std::vector &messages, const std::string &extra, uint64_t unlockTimestamp, uint64_t ttl, crypto::SecretKey &transactionSK); void sendTransaction(const cn::Transaction &cryptoNoteTransaction); size_t validateSaveAndSendTransaction(const ITransactionReader &transaction, const std::vector &destinations, bool isFusion, bool send); From 442f39aec09c489008140b4773bc1a689cf9c319 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Tue, 19 Sep 2023 21:33:00 +0200 Subject: [PATCH 14/30] Update release build flags --- .github/workflows/macOS.yml | 2 +- .github/workflows/ubuntu20.yml | 2 +- .github/workflows/ubuntu22.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macOS.yml b/.github/workflows/macOS.yml index 5d909ad6a..1ebe5381e 100644 --- a/.github/workflows/macOS.yml +++ b/.github/workflows/macOS.yml @@ -21,7 +21,7 @@ jobs: brew install gcc boost mkdir "$build_folder" cd "$build_folder" - cmake -DCMAKE_C_FLAGS="-mmacosx-version-min=10.12" -DCMAKE_CXX_FLAGS="-mmacosx-version-min=10.12" -DSTATIC=ON .. + cmake -DCMAKE_C_FLAGS="-mmacosx-version-min=10.12" -DCMAKE_CXX_FLAGS="-mmacosx-version-min=10.12" -DCMAKE_BUILD_TYPE=Release -DSTATIC=ON .. make -j2 mkdir "$release_name" exeFiles=() diff --git a/.github/workflows/ubuntu20.yml b/.github/workflows/ubuntu20.yml index b0b1e7180..b98e61922 100644 --- a/.github/workflows/ubuntu20.yml +++ b/.github/workflows/ubuntu20.yml @@ -27,7 +27,7 @@ jobs: release_name=ccx-cli-ubuntu-2004-v"$ccx_version" mkdir -p "$build_folder" cd "$build_folder" - cmake ../.. + cmake ../.. -DCMAKE_BUILD_TYPE=Release -DSTATIC=ON make -j2 mkdir -p "$release_name/$ccx_ver_folder" exeFiles=() diff --git a/.github/workflows/ubuntu22.yml b/.github/workflows/ubuntu22.yml index eeabb3b98..8afaf9980 100644 --- a/.github/workflows/ubuntu22.yml +++ b/.github/workflows/ubuntu22.yml @@ -27,7 +27,7 @@ jobs: release_name=ccx-cli-ubuntu-2204-v"$ccx_version" mkdir -p "$build_folder" cd "$build_folder" - cmake ../.. + cmake ../.. -DCMAKE_BUILD_TYPE=Release -DSTATIC=ON make -j2 mkdir -p "$release_name/$ccx_ver_folder" exeFiles=() From e3b5621b28e5b09325cf18cc70c07a1a9a38801b Mon Sep 17 00:00:00 2001 From: AxVultis Date: Wed, 20 Sep 2023 21:14:31 +0200 Subject: [PATCH 15/30] Update Boost --- .github/workflows/check.yml | 5 ++--- .github/workflows/windows.yml | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 90350287f..556f6fbc7 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -13,7 +13,7 @@ jobs: name: Windows runs-on: windows-2019 env: - BOOST_ROOT: C:/local/boost_1_72_0 + BOOST_ROOT: C:/local/boost_1_83_0 steps: - uses: actions/checkout@master @@ -32,8 +32,7 @@ jobs: - name: Install dependencies shell: powershell run: | - echo "${env:BOOST_ROOT}" - $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.72.0/boost_1_72_0-msvc-14.2-64.exe" + $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.2-64.exe" (New-Object System.Net.WebClient).DownloadFile($Url, "$env:TEMP\boost.exe") Start-Process -Wait -FilePath "$env:TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=${env:BOOST_ROOT}" diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index eec013f2d..6e2a387c4 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -10,7 +10,7 @@ jobs: name: Windows runs-on: windows-2019 env: - BOOST_ROOT: C:/local/boost_1_72_0 + BOOST_ROOT: C:/local/boost_1_83_0 steps: - uses: actions/checkout@master @@ -20,8 +20,7 @@ jobs: - name: Install Boost shell: powershell run: | - echo "${env:BOOST_ROOT}" - $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.72.0/boost_1_72_0-msvc-14.2-64.exe" + $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.2-64.exe" (New-Object System.Net.WebClient).DownloadFile($Url, "$env:TEMP\boost.exe") Start-Process -Wait -FilePath "$env:TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=${env:BOOST_ROOT}" From 49a9a16bc4d52092ff0eeee941931c643d59c692 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Wed, 20 Sep 2023 21:46:46 +0200 Subject: [PATCH 16/30] Update windows runners to windows-2022 --- .github/workflows/check.yml | 8 ++++---- .github/workflows/windows.yml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 556f6fbc7..389656c36 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -11,7 +11,7 @@ on: jobs: build-windows: name: Windows - runs-on: windows-2019 + runs-on: windows-2022 env: BOOST_ROOT: C:/local/boost_1_83_0 steps: @@ -32,7 +32,7 @@ jobs: - name: Install dependencies shell: powershell run: | - $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.2-64.exe" + $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.3-64.exe" (New-Object System.Net.WebClient).DownloadFile($Url, "$env:TEMP\boost.exe") Start-Process -Wait -FilePath "$env:TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=${env:BOOST_ROOT}" @@ -42,7 +42,7 @@ jobs: run: | mkdir build cd build - cmake .. -G "Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON + cmake .. -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON msbuild concealX.sln /p:Configuration=Release /m:2 - name: Prepare release @@ -90,7 +90,7 @@ jobs: build-mingw: name: MinGW - runs-on: windows-2019 + runs-on: windows-2022 steps: - uses: msys2/setup-msys2@v2 with: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6e2a387c4..1551c8308 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -8,7 +8,7 @@ on: jobs: build-windows: name: Windows - runs-on: windows-2019 + runs-on: windows-2022 env: BOOST_ROOT: C:/local/boost_1_83_0 steps: @@ -20,7 +20,7 @@ jobs: - name: Install Boost shell: powershell run: | - $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.2-64.exe" + $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.3-64.exe" (New-Object System.Net.WebClient).DownloadFile($Url, "$env:TEMP\boost.exe") Start-Process -Wait -FilePath "$env:TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=${env:BOOST_ROOT}" @@ -33,7 +33,7 @@ jobs: $release_name = "ccx-cli-win64-v$ccx_version" mkdir "$build_folder" cd "$build_folder" - cmake -G "Visual Studio 16 2019" .. + cmake -G "Visual Studio 17 2022" .. msbuild concealX.sln /p:Configuration=Release /m cd src\Release Compress-Archive -Path *.exe -DestinationPath "$release_name.zip" From a05e78e9d1ce1a190880c272ef4b500cf24304f3 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 23 Sep 2023 16:50:54 +0200 Subject: [PATCH 17/30] Cache Boost --- .github/workflows/check.yml | 10 +++++++++- .github/workflows/windows.yml | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 389656c36..2e2ddbd6a 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -29,7 +29,15 @@ jobs: - name: Install msbuild uses: microsoft/setup-msbuild@v1.1.3 - - name: Install dependencies + - name: Restore Boost + uses: actions/cache@v3 + id: restore-boost + with: + path: ${{env.BOOST_ROOT}} + key: boost_1_83_0-msvc-14.3-64 + + - name: Install Boost + if: steps.restore-boost.outputs.cache-hit != 'true' shell: powershell run: | $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.3-64.exe" diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1551c8308..c575e31df 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -17,7 +17,15 @@ jobs: - name: Setup msbuild uses: microsoft/setup-msbuild@v1.1.3 + - name: Restore Boost + uses: actions/cache@v3 + id: restore-boost + with: + path: ${{env.BOOST_ROOT}} + key: boost_1_83_0-msvc-14.3-64 + - name: Install Boost + if: steps.restore-boost.outputs.cache-hit != 'true' shell: powershell run: | $Url = "https://sourceforge.net/projects/boost/files/boost-binaries/1.83.0/boost_1_83_0-msvc-14.3-64.exe" From 7598cc3ce02223ecb2639c65d440a4e018a8749e Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 23 Sep 2023 17:03:33 +0200 Subject: [PATCH 18/30] Update miniupnpc to version 2.2.5 https://github.com/miniupnp/miniupnp/releases/tag/miniupnpc_2_2_5 --- external/miniupnpc/CMakeLists.txt | 27 +++++++++++++++-- external/miniupnpc/Changelog.txt | 14 ++++++++- external/miniupnpc/LICENSE | 40 ++++++++++++++------------ external/miniupnpc/README | 2 +- external/miniupnpc/VERSION | 2 +- external/miniupnpc/include/miniupnpc.h | 4 +-- external/miniupnpc/src/upnpc.c | 38 ++++++++++++++---------- external/miniupnpc/src/upnperrors.c | 22 ++++++++++++-- 8 files changed, 106 insertions(+), 43 deletions(-) diff --git a/external/miniupnpc/CMakeLists.txt b/external/miniupnpc/CMakeLists.txt index d7742dcf4..65eb89d08 100644 --- a/external/miniupnpc/CMakeLists.txt +++ b/external/miniupnpc/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12 FATAL_ERROR) project (miniupnpc - VERSION 2.2.4 + VERSION 2.2.5 DESCRIPTION "UPnP IGD client lightweight library" HOMEPAGE_URL https://miniupnp.tuxfamily.org/ LANGUAGES C) @@ -36,6 +36,9 @@ if (NOT WIN32) # add_definitions (-D_POSIX_C_SOURCE=200112L) target_compile_definitions(miniupnpc-private INTERFACE _XOPEN_SOURCE=600) endif () + if (CMAKE_SYSTEM_NAME STREQUAL "NetBSD") + target_compile_definitions(miniupnpc-private INTERFACE _NETBSD_SOURCE) + endif () else () target_compile_definitions(miniupnpc-private INTERFACE _WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends endif () @@ -133,6 +136,10 @@ if (UPNPC_BUILD_STATIC) add_executable (upnpc-static src/upnpc.c) target_link_libraries (upnpc-static PRIVATE libminiupnpc-static) target_include_directories(upnpc-static PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + if (NOT UPNPC_NO_INSTALL) + install (TARGETS upnpc-static + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif() endif () endif () @@ -170,11 +177,19 @@ if (UPNPC_BUILD_SHARED) add_executable (upnpc-shared src/upnpc.c) target_link_libraries (upnpc-shared PRIVATE libminiupnpc-shared) target_include_directories(upnpc-shared PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + if (NOT UPNPC_NO_INSTALL) + install (TARGETS upnpc-shared + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif() endif () add_executable (listdevices src/listdevices.c) target_link_libraries (listdevices PRIVATE libminiupnpc-shared) target_include_directories(listdevices PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + if (NOT UPNPC_NO_INSTALL) + install (TARGETS listdevices + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif() endif () if (UPNPC_BUILD_TESTS) @@ -270,7 +285,7 @@ if (NOT UPNPC_NO_INSTALL) include/miniupnpctypes.h include/portlistingparse.h include/miniupnpc_declspec.h - DESTINATION include/miniupnpc + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/miniupnpc ) install(FILES miniupnpc-config.cmake @@ -280,6 +295,14 @@ if (NOT UPNPC_NO_INSTALL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/miniupnpc.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) + + install(FILES man3/miniupnpc.3 + DESTINATION ${CMAKE_INSTALL_MANDIR}/man3 + ) + + install(FILES external-ip.sh + TYPE BIN + ) endif() # vim: ts=2:sw=2:expandtab diff --git a/external/miniupnpc/Changelog.txt b/external/miniupnpc/Changelog.txt index 486356ec9..1e79adb9e 100644 --- a/external/miniupnpc/Changelog.txt +++ b/external/miniupnpc/Changelog.txt @@ -1,6 +1,18 @@ -$Id: Changelog.txt,v 1.254 2022/10/21 21:13:12 nanard Exp $ +$Id: Changelog.txt,v 1.257 2023/06/11 23:25:45 nanard Exp $ miniUPnP client Changelog. +VERSION 2.2.5 : released 2023/06/12 + +2023/06/05: + GetListOfPortMappings NewStartPort 0 => 1 + +2023/05/30: + CheckPinholeWorking is optional + add 60x errors from UPnP Device Architecture + +2023/01/04: + cmake: install binaries, man pages and external-ip.sh + VERSION 2.2.4 : released 2022/10/21 2022/02/20: diff --git a/external/miniupnpc/LICENSE b/external/miniupnpc/LICENSE index a16dc2d7d..6eff8d268 100644 --- a/external/miniupnpc/LICENSE +++ b/external/miniupnpc/LICENSE @@ -1,27 +1,29 @@ -MiniUPnPc -Copyright (c) 2005-2021, Thomas BERNARD +BSD 3-Clause License + +Copyright (c) 2005-2023, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/external/miniupnpc/README b/external/miniupnpc/README index f87155030..aa8ad2024 100644 --- a/external/miniupnpc/README +++ b/external/miniupnpc/README @@ -2,7 +2,7 @@ Project: miniupnp Project web page: http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ github: https://github.com/miniupnp/miniupnp Author: Thomas Bernard -Copyright (c) 2005-2021 Thomas Bernard +Copyright (c) 2005-2023 Thomas Bernard This software is subject to the conditions detailed in the LICENSE file provided within this distribution. diff --git a/external/miniupnpc/VERSION b/external/miniupnpc/VERSION index 530cdd91a..21bb5e156 100644 --- a/external/miniupnpc/VERSION +++ b/external/miniupnpc/VERSION @@ -1 +1 @@ -2.2.4 +2.2.5 diff --git a/external/miniupnpc/include/miniupnpc.h b/external/miniupnpc/include/miniupnpc.h index 75fb8b702..721819583 100644 --- a/external/miniupnpc/include/miniupnpc.h +++ b/external/miniupnpc/include/miniupnpc.h @@ -1,4 +1,4 @@ -/* $Id: miniupnpc.h,v 1.61 2022/10/21 21:15:02 nanard Exp $ */ +/* $Id: miniupnpc.h,v 1.62 2023/06/11 23:25:46 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project: miniupnp * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ @@ -20,7 +20,7 @@ #define UPNPDISCOVER_MEMORY_ERROR (-102) /* versions : */ -#define MINIUPNPC_VERSION "2.2.4" +#define MINIUPNPC_VERSION "2.2.5" #define MINIUPNPC_API_VERSION 17 /* Source port: diff --git a/external/miniupnpc/src/upnpc.c b/external/miniupnpc/src/upnpc.c index 991e26677..23bb27830 100644 --- a/external/miniupnpc/src/upnpc.c +++ b/external/miniupnpc/src/upnpc.c @@ -1,7 +1,7 @@ -/* $Id: upnpc.c,v 1.131 2022/02/19 23:22:54 nanard Exp $ */ +/* $Id: upnpc.c,v 1.134 2023/06/11 23:23:10 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2022 Thomas Bernard + * Copyright (c) 2005-2023 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -135,7 +135,7 @@ static void ListRedirections(struct UPNPUrls * urls, struct IGDdatas * data) { int r; - int i = 0; + unsigned short i = 0; char index[6]; char intClient[40]; char intPort[6]; @@ -150,7 +150,7 @@ static void ListRedirections(struct UPNPUrls * urls, printf("PortMappingNumberOfEntries : %u\n", num);*/ printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); do { - snprintf(index, 6, "%d", i); + snprintf(index, 6, "%hu", i); rHost[0] = '\0'; enabled[0] = '\0'; duration[0] = '\0'; desc[0] = '\0'; extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; @@ -162,20 +162,19 @@ static void ListRedirections(struct UPNPUrls * urls, rHost, duration); if(r==0) /* - printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" + printf("%02hu - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" " desc='%s' rHost='%s'\n", i, protocol, extPort, intClient, intPort, enabled, duration, desc, rHost); */ - printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n", + printf("%2hu %s %5s->%s:%-5s '%s' '%s' %s\n", i, protocol, extPort, intClient, intPort, desc, rHost, duration); else printf("GetGenericPortMappingEntry() returned %d (%s)\n", r, strupnperror(r)); - i++; - } while(r == 0 && i < 65536); + } while(r == 0 && i++ < 65535); } static void NewListRedirections(struct UPNPUrls * urls, @@ -189,7 +188,7 @@ static void NewListRedirections(struct UPNPUrls * urls, memset(&pdata, 0, sizeof(struct PortMappingParserData)); r = UPNP_GetListOfPortMappings(urls->controlURL, data->first.servicetype, - "0", + "1", "65535", "TCP", "1000", @@ -215,7 +214,7 @@ static void NewListRedirections(struct UPNPUrls * urls, } r = UPNP_GetListOfPortMappings(urls->controlURL, data->first.servicetype, - "0", + "1", "65535", "UDP", "1000", @@ -466,11 +465,20 @@ static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data, fprintf(stderr, "Wrong arguments\n"); return; } + /* CheckPinholeWorking is an Optional Action, error 602 should be + * returned if it is not implemented */ r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - if(isWorking || r==709) + if(r==UPNPCOMMAND_SUCCESS) + printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); + else + printf("CheckPinholeWorking(%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r)); + /* 702 FirewallDisabled Firewall is disabled and this action is disabled + * 703 InboundPinholeNotAllowed Creation of inbound pinholes by UPnP CPs + * are not allowed and this action is disabled + * 704 NoSuchEntry There is no pinhole with the specified UniqueID. + * 709 NoTrafficReceived No traffic corresponding to this pinhole has + * been received by the gateway. */ + if(isWorking || (r!=702 && r!=703 && r!=704)) { r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time); printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time); @@ -583,7 +591,7 @@ int main(int argc, char ** argv) } #endif printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); - printf(" (c) 2005-2022 Thomas Bernard.\n"); + printf(" (c) 2005-2023 Thomas Bernard.\n"); printf("Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/\n" "for more information.\n"); /* command line processing */ diff --git a/external/miniupnpc/src/upnperrors.c b/external/miniupnpc/src/upnperrors.c index 4496e8622..eec403738 100644 --- a/external/miniupnpc/src/upnperrors.c +++ b/external/miniupnpc/src/upnperrors.c @@ -1,8 +1,8 @@ -/* $Id: upnperrors.c,v 1.10 2019/08/24 08:49:53 nanard Exp $ */ +/* $Id: upnperrors.c,v 1.11 2023/05/29 21:59:15 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp * Author : Thomas BERNARD - * copyright (c) 2007-2019 Thomas Bernard + * copyright (c) 2007-2023 Thomas Bernard * All Right reserved. * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * This software is subjet to the conditions detailed in the @@ -47,6 +47,24 @@ const char * strupnperror(int err) case 501: s = "Action Failed"; break; + case 600: + s = "Argument Value Invalid"; + break; + case 601: + s = "Argument Value Out of Range"; + break; + case 602: + s = "Optional Action Not Implemented"; + break; + case 603: + s = "Out of Memory"; + break; + case 604: + s = "Human Intervention Required"; + break; + case 605: + s = "String Argument Too Long"; + break; case 606: s = "Action not authorized"; break; From 954479ad2565b770cc078849abc3b3bbf54760c4 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 23 Sep 2023 17:29:28 +0200 Subject: [PATCH 19/30] Update parallel_hashmap to version 1.3.11 https://github.com/greg7mdp/parallel-hashmap/releases/tag/v1.3.11 --- external/parallel_hashmap/LICENSE | 202 +++++++++++++++++++++ external/parallel_hashmap/btree.h | 35 ++-- external/parallel_hashmap/conanfile.py | 2 +- external/parallel_hashmap/phmap.h | 190 ++++++++++--------- external/parallel_hashmap/phmap_base.h | 129 ++++++------- external/parallel_hashmap/phmap_bits.h | 4 +- external/parallel_hashmap/phmap_config.h | 31 +--- external/parallel_hashmap/phmap_fwd_decl.h | 32 ++++ external/parallel_hashmap/phmap_utils.h | 8 - 9 files changed, 412 insertions(+), 221 deletions(-) create mode 100644 external/parallel_hashmap/LICENSE diff --git a/external/parallel_hashmap/LICENSE b/external/parallel_hashmap/LICENSE new file mode 100644 index 000000000..62589edd1 --- /dev/null +++ b/external/parallel_hashmap/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/external/parallel_hashmap/btree.h b/external/parallel_hashmap/btree.h index 8aee516a2..5304e42ee 100644 --- a/external/parallel_hashmap/btree.h +++ b/external/parallel_hashmap/btree.h @@ -60,6 +60,7 @@ #include #include #include +#include #include "phmap_fwd_decl.h" #include "phmap_base.h" @@ -76,14 +77,6 @@ namespace phmap { - // Defined and documented later on in this file. - template - struct is_trivially_destructible; - - // Defined and documented later on in this file. - template - struct is_trivially_move_assignable; - namespace type_traits_internal { // Silence MSVC warnings about the destructor being defined as deleted. @@ -107,25 +100,25 @@ namespace phmap { : std::integral_constant< bool, std::is_move_constructible< type_traits_internal::SingleMemberUnion>::value && - phmap::is_trivially_destructible::value> {}; + std::is_trivially_destructible::value> {}; template struct IsTriviallyCopyConstructibleObject : std::integral_constant< bool, std::is_copy_constructible< type_traits_internal::SingleMemberUnion>::value && - phmap::is_trivially_destructible::value> {}; + std::is_trivially_destructible::value> {}; template struct IsTriviallyMoveAssignableReference : std::false_type {}; template struct IsTriviallyMoveAssignableReference - : phmap::is_trivially_move_assignable::type {}; + : std::is_trivially_move_assignable::type {}; template struct IsTriviallyMoveAssignableReference - : phmap::is_trivially_move_assignable::type {}; + : std::is_trivially_move_assignable::type {}; } // namespace type_traits_internal @@ -155,10 +148,10 @@ namespace phmap { public: static constexpr bool kValue = - (__has_trivial_copy(ExtentsRemoved) || !kIsCopyOrMoveConstructible) && - (__has_trivial_assign(ExtentsRemoved) || !kIsCopyOrMoveAssignable) && + (std::is_trivially_copyable::value || !kIsCopyOrMoveConstructible) && + (std::is_trivially_copy_assignable::value || !kIsCopyOrMoveAssignable) && (kIsCopyOrMoveConstructible || kIsCopyOrMoveAssignable) && - is_trivially_destructible::value && + std::is_trivially_destructible::value && // We need to check for this explicitly because otherwise we'll say // references are trivial copyable when compiled by MSVC. !std::is_reference::value; @@ -744,13 +737,13 @@ namespace priv { StringBtreeDefaultLess(std::less) {} // NOLINT StringBtreeDefaultLess(phmap::Less) {} // NOLINT - phmap::weak_ordering operator()(std::string_view lhs, - std::string_view rhs) const { + phmap::weak_ordering operator()(const std::string_view &lhs, + const std::string_view &rhs) const { return compare_internal::compare_result_as_ordering(lhs.compare(rhs)); } #else - phmap::weak_ordering operator()(std::string lhs, - std::string rhs) const { + phmap::weak_ordering operator()(const std::string &lhs, + const std::string &rhs) const { return compare_internal::compare_result_as_ordering(lhs.compare(rhs)); } #endif @@ -770,8 +763,8 @@ namespace priv { return compare_internal::compare_result_as_ordering(rhs.compare(lhs)); } #else - phmap::weak_ordering operator()(std::string lhs, - std::string rhs) const { + phmap::weak_ordering operator()(const std::string &lhs, + const std::string &rhs) const { return compare_internal::compare_result_as_ordering(rhs.compare(lhs)); } #endif diff --git a/external/parallel_hashmap/conanfile.py b/external/parallel_hashmap/conanfile.py index 421124732..f3099f13f 100644 --- a/external/parallel_hashmap/conanfile.py +++ b/external/parallel_hashmap/conanfile.py @@ -6,7 +6,7 @@ class SparseppConan(ConanFile): name = "parallel_hashmap" - version = "1.36" + version = "1.3.11" description = "A header-only, very fast and memory-friendly hash map" url = "https://github.com/greg7mdp/parallel-hashmap/blob/master/parallel_hashmap/conanfile.py" diff --git a/external/parallel_hashmap/phmap.h b/external/parallel_hashmap/phmap.h index 17fc20133..37f0f7c14 100644 --- a/external/parallel_hashmap/phmap.h +++ b/external/parallel_hashmap/phmap.h @@ -1,6 +1,5 @@ #if !defined(phmap_h_guard_) #define phmap_h_guard_ -#define PHMAP_BIDIRECTIONAL 0 // --------------------------------------------------------------------------- // Copyright (c) 2019, Gregory Popovitch - greg7mdp@gmail.com @@ -136,6 +135,7 @@ void SwapAlloc(AllocType& lhs, AllocType& rhs, using std::swap; swap(lhs, rhs); } + template void SwapAlloc(AllocType& /*lhs*/, AllocType& /*rhs*/, std::false_type /* propagate_on_container_swap */) {} @@ -193,14 +193,19 @@ struct IsDecomposable< // TODO(alkis): Switch to std::is_nothrow_swappable when gcc/clang supports it. // -------------------------------------------------------------------------- template -constexpr bool IsNoThrowSwappable() { +constexpr bool IsNoThrowSwappable(std::true_type = {} /* is_swappable */) { using std::swap; return noexcept(swap(std::declval(), std::declval())); } +template +constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) { + return false; +} + // -------------------------------------------------------------------------- template -int TrailingZeros(T x) { +uint32_t TrailingZeros(T x) { PHMAP_IF_CONSTEXPR(sizeof(T) == 8) return base_internal::CountTrailingZerosNonZero64(static_cast(x)); else @@ -209,7 +214,7 @@ int TrailingZeros(T x) { // -------------------------------------------------------------------------- template -int LeadingZeros(T x) { +uint32_t LeadingZeros(T x) { PHMAP_IF_CONSTEXPR(sizeof(T) == 8) return base_internal::CountLeadingZeros64(static_cast(x)); else @@ -352,7 +357,7 @@ inline size_t H1(size_t hashval, const ctrl_t* ) { #endif -inline h2_t H2(size_t hashval) { return (ctrl_t)(hashval & 0x7F); } +inline h2_t H2(size_t hashval) { return (h2_t)(ctrl_t)(hashval & 0x7F); } inline bool IsEmpty(ctrl_t c) { return c == kEmpty; } inline bool IsFull(ctrl_t c) { return c >= static_cast(0); } @@ -958,7 +963,7 @@ class raw_hash_set return tmp; } -#if PHMAP_BIDIRECTIONAL +#if 0 // PHMAP_BIDIRECTIONAL // PRECONDITION: not a begin() iterator. iterator& operator--() { assert(ctrl_); @@ -1185,10 +1190,10 @@ class raw_hash_set size_(phmap::exchange(that.size_, 0)), capacity_(phmap::exchange(that.capacity_, 0)), infoz_(phmap::exchange(that.infoz_, HashtablezInfoHandle())), - // Hash, equality and allocator are copied instead of moved because - // `that` must be left valid. If Hash is std::function, moving it - // would create a nullptr functor that cannot be called. - settings_(that.settings_) { + // Hash, equality and allocator are copied instead of moved because + // `that` must be left valid. If Hash is std::function, moving it + // would create a nullptr functor that cannot be called. + settings_(std::move(that.settings_)) { // growth_left was copied above, reset the one from `that`. that.growth_left() = 0; } @@ -1243,7 +1248,7 @@ class raw_hash_set } iterator end() { -#if PHMAP_BIDIRECTIONAL +#if 0 // PHMAP_BIDIRECTIONAL return iterator_at(capacity_); #else return {ctrl_ + capacity_}; @@ -1451,7 +1456,7 @@ class raw_hash_set template ::value, int>::type = 0> std::pair emplace(Args&&... args) { - typename std::aligned_storage::type + typename phmap::aligned_storage::type raw; slot_type* slot = reinterpret_cast(&raw); @@ -1462,7 +1467,7 @@ class raw_hash_set template ::value, int>::type = 0> std::pair emplace_with_hash(size_t hashval, Args&&... args) { - typename std::aligned_storage::type raw; + typename phmap::aligned_storage::type raw; slot_type* slot = reinterpret_cast(&raw); PolicyTraits::construct(&alloc_ref(), slot, std::forward(args)...); @@ -1521,13 +1526,28 @@ class raw_hash_set slot_type** slot_; }; + // Extension API: support for lazy emplace. + // Looks up key in the table. If found, returns the iterator to the element. + // Otherwise calls f with one argument of type raw_hash_set::constructor. f + // MUST call raw_hash_set::constructor with arguments as if a + // raw_hash_set::value_type is constructed, otherwise the behavior is + // undefined. + // + // For example: + // + // std::unordered_set s; + // // Makes ArenaStr even if "abc" is in the map. + // s.insert(ArenaString(&arena, "abc")); + // + // flat_hash_set s; + // // Makes ArenaStr only if "abc" is not in the map. + // s.lazy_emplace("abc", [&](const constructor& ctor) { + // ctor(&arena, "abc"); + // }); + // ----------------------------------------------------- template iterator lazy_emplace(const key_arg& key, F&& f) { - auto res = find_or_prepare_insert(key); - if (res.second) { - lazy_emplace_at(res.first, std::forward(f)); - } - return iterator_at(res.first); + return lazy_emplace_with_hash(key, this->hash(key), std::forward(f)); } template @@ -1535,6 +1555,7 @@ class raw_hash_set auto res = find_or_prepare_insert(key, hashval); if (res.second) { lazy_emplace_at(res.first, std::forward(f)); + this->set_ctrl(res.first, H2(hashval)); } return iterator_at(res.first); } @@ -1549,9 +1570,10 @@ class raw_hash_set template void emplace_single_with_hash(const key_arg& key, size_t hashval, F&& f) { auto res = find_or_prepare_insert(key, hashval); - if (res.second) + if (res.second) { lazy_emplace_at(res.first, std::forward(f)); - else + this->set_ctrl(res.first, H2(hashval)); + } else _erase(iterator_at(res.first)); } @@ -1648,7 +1670,7 @@ class raw_hash_set void swap(raw_hash_set& that) noexcept( IsNoThrowSwappable() && IsNoThrowSwappable() && (!AllocTraits::propagate_on_container_swap::value || - IsNoThrowSwappable())) { + IsNoThrowSwappable(typename AllocTraits::propagate_on_container_swap{}))) { using std::swap; swap(ctrl_, that.ctrl_); swap(slots_, that.slots_); @@ -1658,12 +1680,7 @@ class raw_hash_set swap(hash_ref(), that.hash_ref()); swap(eq_ref(), that.eq_ref()); swap(infoz_, that.infoz_); - if (AllocTraits::propagate_on_container_swap::value) { - swap(alloc_ref(), that.alloc_ref()); - } else { - // If the allocators do not compare equal it is officially undefined - // behavior. We choose to do nothing. - } + SwapAlloc(alloc_ref(), that.alloc_ref(), typename AllocTraits::propagate_on_container_swap{}); } #if !defined(PHMAP_NON_DETERMINISTIC) @@ -1888,6 +1905,7 @@ class raw_hash_set auto res = find_or_prepare_insert(key, hashval); if (res.second) { emplace_at(res.first, std::forward(args)...); + this->set_ctrl(res.first, H2(hashval)); } return {iterator_at(res.first), res.second}; } @@ -1915,9 +1933,11 @@ class raw_hash_set { template std::pair operator()(const K& key, Args&&...) && { - auto res = s.find_or_prepare_insert(key); + size_t hashval = s.hash(key); + auto res = s.find_or_prepare_insert(key, hashval); if (res.second) { PolicyTraits::transfer(&s.alloc_ref(), s.slots_ + res.first, &slot); + s.set_ctrl(res.first, H2(hashval)); } else if (do_destroy) { PolicyTraits::destroy(&s.alloc_ref(), &slot); } @@ -1936,6 +1956,7 @@ class raw_hash_set auto res = s.find_or_prepare_insert(key, hashval); if (res.second) { PolicyTraits::transfer(&s.alloc_ref(), s.slots_ + res.first, &slot); + s.set_ctrl(res.first, H2(hashval)); } else if (do_destroy) { PolicyTraits::destroy(&s.alloc_ref(), &slot); } @@ -2054,7 +2075,7 @@ class raw_hash_set // mark target as FULL // repeat procedure for current slot with moved from element (target) ConvertDeletedToEmptyAndFullToDeleted(ctrl_, capacity_); - typename std::aligned_storage::type + typename phmap::aligned_storage::type raw; slot_type* slot = reinterpret_cast(&raw); for (size_t i = 0; i != capacity_; ++i) { @@ -2187,11 +2208,6 @@ class raw_hash_set return {prepare_insert(hashval), true}; } - template - std::pair find_or_prepare_insert(const K& key) { - return find_or_prepare_insert(key, this->hash(key)); - } - size_t prepare_insert(size_t hashval) PHMAP_ATTRIBUTE_NOINLINE { auto target = find_first_non_full(hashval); if (PHMAP_PREDICT_FALSE(growth_left() == 0 && @@ -2201,7 +2217,7 @@ class raw_hash_set } ++size_; growth_left() -= IsEmpty(ctrl_[target.offset]); - set_ctrl(target.offset, H2(hashval)); + // set_ctrl(target.offset, H2(hashval)); infoz_.RecordInsert(hashval, target.probe_length); return target.offset; } @@ -2218,15 +2234,35 @@ class raw_hash_set void emplace_at(size_t i, Args&&... args) { PolicyTraits::construct(&alloc_ref(), slots_ + i, std::forward(args)...); - + +#ifdef PHMAP_CHECK_CONSTRUCTED_VALUE + // this check can be costly, so do it only when requested assert(PolicyTraits::apply(FindElement{*this}, *iterator_at(i)) == iterator_at(i) && "constructed value does not match the lookup key"); +#endif } iterator iterator_at(size_t i) { return {ctrl_ + i, slots_ + i}; } const_iterator iterator_at(size_t i) const { return {ctrl_ + i, slots_ + i}; } +protected: + // Sets the control byte, and if `i < Group::kWidth`, set the cloned byte at + // the end too. + void set_ctrl(size_t i, ctrl_t h) { + assert(i < capacity_); + + if (IsFull(h)) { + SanitizerUnpoisonObject(slots_ + i); + } else { + SanitizerPoisonObject(slots_ + i); + } + + ctrl_[i] = h; + ctrl_[((i - Group::kWidth) & capacity_) + 1 + + ((Group::kWidth - 1) & capacity_)] = h; + } + private: friend struct RawHashSetTestOnlyAccess; @@ -2245,22 +2281,6 @@ class raw_hash_set growth_left() = CapacityToGrowth(capacity) - size_; } - // Sets the control byte, and if `i < Group::kWidth`, set the cloned byte at - // the end too. - void set_ctrl(size_t i, ctrl_t h) { - assert(i < capacity_); - - if (IsFull(h)) { - SanitizerUnpoisonObject(slots_ + i); - } else { - SanitizerPoisonObject(slots_ + i); - } - - ctrl_[i] = h; - ctrl_[((i - Group::kWidth) & capacity_) + 1 + - ((Group::kWidth - 1) & capacity_)] = h; - } - size_t& growth_left() { return settings_.template get<0>(); } template private: template std::pair insert_or_assign_impl(K&& k, V&& v) { - auto res = this->find_or_prepare_insert(k); - if (res.second) + size_t hashval = this->hash(k); + auto res = this->find_or_prepare_insert(k, hashval); + if (res.second) { this->emplace_at(res.first, std::forward(k), std::forward(v)); - else + this->set_ctrl(res.first, H2(hashval)); + } else Policy::value(&*this->iterator_at(res.first)) = std::forward(v); return {this->iterator_at(res.first), res.second}; } template std::pair try_emplace_impl(K&& k, Args&&... args) { - auto res = this->find_or_prepare_insert(k); - if (res.second) + size_t hashval = this->hash(k); + auto res = this->find_or_prepare_insert(k, hashval); + if (res.second) { this->emplace_at(res.first, std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)); + this->set_ctrl(res.first, H2(hashval)); + } return {this->iterator_at(res.first), res.second}; } }; @@ -2728,7 +2753,7 @@ class parallel_hash_set std::is_nothrow_default_constructible::value&& std::is_nothrow_default_constructible::value) {} -#if (__cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402)) && (defined(_MSC_VER) || defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 6)) +#if (__cplusplus >= 201703L || _MSVC_LANG >= 201402) && (defined(_MSC_VER) || defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 6)) explicit parallel_hash_set(size_t bucket_cnt, const hasher& hash_param = hasher(), const key_equal& eq = key_equal(), @@ -3085,7 +3110,7 @@ class parallel_hash_set template ::value, int>::type = 0> std::pair emplace_with_hash(size_t hashval, Args&&... args) { - typename std::aligned_storage::type raw; + typename phmap::aligned_storage::type raw; slot_type* slot = reinterpret_cast(&raw); PolicyTraits::construct(&alloc_ref(), slot, std::forward(args)...); @@ -3158,7 +3183,7 @@ class parallel_hash_set template ::value, int>::type = 0> std::pair emplace(Args&&... args) { - typename std::aligned_storage::type raw; + typename phmap::aligned_storage::type raw; slot_type* slot = reinterpret_cast(&raw); size_t hashval = this->hash(PolicyTraits::key(slot)); @@ -3292,12 +3317,14 @@ class parallel_hash_set // --------------------------------------------------------------------------------------- template bool lazy_emplace_l(const key_arg& key, FExists&& fExists, FEmplace&& fEmplace) { + size_t hashval = this->hash(key); typename Lockable::UniqueLock m; - auto res = this->find_or_prepare_insert(key, m); + auto res = this->find_or_prepare_insert_with_hash(hashval, key, m); Inner* inner = std::get<0>(res); - if (std::get<2>(res)) + if (std::get<2>(res)) { inner->set_.lazy_emplace_at(std::get<1>(res), std::forward(fEmplace)); - else { + inner->set_.set_ctrl(std::get<1>(res), H2(hashval)); + } else { auto it = this->iterator_at(inner, inner->set_.iterator_at(std::get<1>(res))); std::forward(fExists)(const_cast(*it)); // in case of the set, non "key" part of value_type can be changed } @@ -3483,7 +3510,7 @@ class parallel_hash_set void swap(parallel_hash_set& that) noexcept(IsNoThrowSwappable() && (!AllocTraits::propagate_on_container_swap::value || - IsNoThrowSwappable())) + IsNoThrowSwappable(typename AllocTraits::propagate_on_container_swap{}))) { using std::swap; using Lockable2 = phmap::LockableImpl; @@ -3976,14 +4003,16 @@ class parallel_hash_map : public parallel_hash_set bool try_emplace_l(K&& k, F&& f, Args&&... args) { + size_t hashval = this->hash(k); typename Lockable::UniqueLock m; - auto res = this->find_or_prepare_insert(k, m); + auto res = this->find_or_prepare_insert_with_hash(hashval, k, m); typename Base::Inner *inner = std::get<0>(res); - if (std::get<2>(res)) + if (std::get<2>(res)) { inner->set_.emplace_at(std::get<1>(res), std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)); - else { + inner->set_.set_ctrl(std::get<1>(res), H2(hashval)); + } else { auto it = this->iterator_at(inner, inner->set_.iterator_at(std::get<1>(res))); std::forward(f)(const_cast(*it)); // in case of the set, non "key" part of value_type can be changed } @@ -4006,12 +4035,14 @@ class parallel_hash_map : public parallel_hash_set std::pair insert_or_assign_impl(K&& k, V&& v) { + size_t hashval = this->hash(k); typename Lockable::UniqueLock m; - auto res = this->find_or_prepare_insert(k, m); + auto res = this->find_or_prepare_insert_with_hash(hashval, k, m); typename Base::Inner *inner = std::get<0>(res); - if (std::get<2>(res)) + if (std::get<2>(res)) { inner->set_.emplace_at(std::get<1>(res), std::forward(k), std::forward(v)); - else + inner->set_.set_ctrl(std::get<1>(res), H2(hashval)); + } else Policy::value(&*inner->set_.iterator_at(std::get<1>(res))) = std::forward(v); return {this->iterator_at(inner, inner->set_.iterator_at(std::get<1>(res))), std::get<2>(res)}; @@ -4019,15 +4050,8 @@ class parallel_hash_map : public parallel_hash_set std::pair try_emplace_impl(K&& k, Args&&... args) { - typename Lockable::UniqueLock m; - auto res = this->find_or_prepare_insert(k, m); - typename Base::Inner *inner = std::get<0>(res); - if (std::get<2>(res)) - inner->set_.emplace_at(std::get<1>(res), std::piecewise_construct, - std::forward_as_tuple(std::forward(k)), - std::forward_as_tuple(std::forward(args)...)); - return {this->iterator_at(inner, inner->set_.iterator_at(std::get<1>(res))), - std::get<2>(res)}; + return try_emplace_impl_with_hash(this->hash(k), std::forward(k), + std::forward(args)...); } template @@ -4035,10 +4059,12 @@ class parallel_hash_map : public parallel_hash_setfind_or_prepare_insert_with_hash(hashval, k, m); typename Base::Inner *inner = std::get<0>(res); - if (std::get<2>(res)) + if (std::get<2>(res)) { inner->set_.emplace_at(std::get<1>(res), std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)); + inner->set_.set_ctrl(std::get<1>(res), H2(hashval)); + } return {this->iterator_at(inner, inner->set_.iterator_at(std::get<1>(res))), std::get<2>(res)}; } @@ -4698,7 +4724,7 @@ class flat_hash_map : public phmap::priv::raw_hash_map< // hashing function and equality operator. // * Contains a `capacity()` member function indicating the number of element // slots (open, deleted, and empty) within the hash set. -// * Returns `void` from the `erase(iterator)` overload. +// * Returns `void` from the `_erase(iterator)` overload. // ----------------------------------------------------------------------------- template // default values in phmap_fwd_decl.h class node_hash_set @@ -4763,7 +4789,7 @@ class node_hash_set // hashing function and equality operator. // * Contains a `capacity()` member function indicating the number of element // slots (open, deleted, and empty) within the hash map. -// * Returns `void` from the `erase(iterator)` overload. +// * Returns `void` from the `_erase(iterator)` overload. // ----------------------------------------------------------------------------- template // default values in phmap_fwd_decl.h class node_hash_map diff --git a/external/parallel_hashmap/phmap_base.h b/external/parallel_hashmap/phmap_base.h index 2a2f38049..28676d5d4 100644 --- a/external/parallel_hashmap/phmap_base.h +++ b/external/parallel_hashmap/phmap_base.h @@ -96,19 +96,6 @@ struct VoidTImpl { using type = void; }; -// This trick to retrieve a default alignment is necessary for our -// implementation of aligned_storage_t to be consistent with any implementation -// of std::aligned_storage. -// --------------------------------------------------------------------------- -template > -struct default_alignment_of_aligned_storage; - -template -struct default_alignment_of_aligned_storage> { - static constexpr size_t value = Align; -}; - // NOTE: The `is_detected` family of templates here differ from the library // fundamentals specification in that for library fundamentals, `Op` is // evaluated as soon as the type `is_detected` undergoes @@ -236,29 +223,6 @@ struct disjunction<> : std::false_type {}; template struct negation : std::integral_constant {}; -template -struct is_trivially_destructible - : std::integral_constant::value> {}; - -template -struct is_trivially_default_constructible - : std::integral_constant::value && - is_trivially_destructible::value> {}; - -template -struct is_trivially_copy_constructible - : std::integral_constant::value && - is_trivially_destructible::value> {}; - -template -struct is_trivially_copy_assignable - : std::integral_constant< - bool, __has_trivial_assign(typename std::remove_reference::type) && - phmap::is_copy_assignable::value> {}; - // ----------------------------------------------------------------------------- // C++14 "_t" trait aliases // ----------------------------------------------------------------------------- @@ -308,9 +272,15 @@ using remove_extent_t = typename std::remove_extent::type; template using remove_all_extents_t = typename std::remove_all_extents::type; -template ::value> -using aligned_storage_t = typename std::aligned_storage::type; +template +struct aligned_storage { + struct type { + alignas(Align) unsigned char data[Len]; + }; +}; + +template< std::size_t Len, std::size_t Align> +using aligned_storage_t = typename aligned_storage::type; template using decay_t = typename std::decay::type; @@ -652,83 +622,85 @@ namespace phmap { namespace base_internal { namespace { -template + #ifdef PHMAP_HAVE_EXCEPTIONS -[[noreturn]] void Throw(const T& error) { - throw error; -} + #define PHMAP_THROW_IMPL(e) throw e #else -[[noreturn]] void Throw(const T&) { - std::abort(); -} + #define PHMAP_THROW_IMPL(e) std::abort() #endif } // namespace static inline void ThrowStdLogicError(const std::string& what_arg) { - Throw(std::logic_error(what_arg)); + PHMAP_THROW_IMPL(std::logic_error(what_arg)); } static inline void ThrowStdLogicError(const char* what_arg) { - Throw(std::logic_error(what_arg)); + PHMAP_THROW_IMPL(std::logic_error(what_arg)); } static inline void ThrowStdInvalidArgument(const std::string& what_arg) { - Throw(std::invalid_argument(what_arg)); + PHMAP_THROW_IMPL(std::invalid_argument(what_arg)); } static inline void ThrowStdInvalidArgument(const char* what_arg) { - Throw(std::invalid_argument(what_arg)); + PHMAP_THROW_IMPL(std::invalid_argument(what_arg)); } static inline void ThrowStdDomainError(const std::string& what_arg) { - Throw(std::domain_error(what_arg)); + PHMAP_THROW_IMPL(std::domain_error(what_arg)); } static inline void ThrowStdDomainError(const char* what_arg) { - Throw(std::domain_error(what_arg)); + PHMAP_THROW_IMPL(std::domain_error(what_arg)); } static inline void ThrowStdLengthError(const std::string& what_arg) { - Throw(std::length_error(what_arg)); + PHMAP_THROW_IMPL(std::length_error(what_arg)); } static inline void ThrowStdLengthError(const char* what_arg) { - Throw(std::length_error(what_arg)); + PHMAP_THROW_IMPL(std::length_error(what_arg)); } static inline void ThrowStdOutOfRange(const std::string& what_arg) { - Throw(std::out_of_range(what_arg)); + PHMAP_THROW_IMPL(std::out_of_range(what_arg)); } static inline void ThrowStdOutOfRange(const char* what_arg) { - Throw(std::out_of_range(what_arg)); + PHMAP_THROW_IMPL(std::out_of_range(what_arg)); } static inline void ThrowStdRuntimeError(const std::string& what_arg) { - Throw(std::runtime_error(what_arg)); + PHMAP_THROW_IMPL(std::runtime_error(what_arg)); } static inline void ThrowStdRuntimeError(const char* what_arg) { - Throw(std::runtime_error(what_arg)); + PHMAP_THROW_IMPL(std::runtime_error(what_arg)); } static inline void ThrowStdRangeError(const std::string& what_arg) { - Throw(std::range_error(what_arg)); + PHMAP_THROW_IMPL(std::range_error(what_arg)); } static inline void ThrowStdRangeError(const char* what_arg) { - Throw(std::range_error(what_arg)); + PHMAP_THROW_IMPL(std::range_error(what_arg)); } static inline void ThrowStdOverflowError(const std::string& what_arg) { - Throw(std::overflow_error(what_arg)); + PHMAP_THROW_IMPL(std::overflow_error(what_arg)); } + static inline void ThrowStdOverflowError(const char* what_arg) { - Throw(std::overflow_error(what_arg)); + PHMAP_THROW_IMPL(std::overflow_error(what_arg)); } static inline void ThrowStdUnderflowError(const std::string& what_arg) { - Throw(std::underflow_error(what_arg)); + PHMAP_THROW_IMPL(std::underflow_error(what_arg)); } + static inline void ThrowStdUnderflowError(const char* what_arg) { - Throw(std::underflow_error(what_arg)); + PHMAP_THROW_IMPL(std::underflow_error(what_arg)); +} + +static inline void ThrowStdBadFunctionCall() { + PHMAP_THROW_IMPL(std::bad_function_call()); +} + +static inline void ThrowStdBadAlloc() { + PHMAP_THROW_IMPL(std::bad_alloc()); } - -static inline void ThrowStdBadFunctionCall() { Throw(std::bad_function_call()); } - -static inline void ThrowStdBadAlloc() { Throw(std::bad_alloc()); } } // namespace base_internal } // namespace phmap @@ -1815,9 +1787,10 @@ class optional_data_base : public optional_data_dtor_base // Also, we should be checking is_trivially_copyable here, which is not // supported now, so we use is_trivially_* traits instead. template ::value&& - phmap::is_trivially_copy_assignable::type>::value&& std::is_trivially_destructible::value> + bool unused = + std::is_trivially_copy_constructible::value && + std::is_trivially_copy_assignable::type>::value && + std::is_trivially_destructible::value> class optional_data; // Trivially copyable types @@ -2074,7 +2047,7 @@ class optional : private optional_internal::optional_data, optional(const optional& src) = default; // Move constructor, standard semantics - optional(optional&& src) = default; + optional(optional&& src) noexcept = default; // Constructs a non-empty `optional` direct-initialized value of type `T` from // the arguments `std::forward(args)...` within the `optional`. @@ -2214,7 +2187,7 @@ class optional : private optional_internal::optional_data, optional& operator=(const optional& src) = default; // Move assignment operator, standard semantics - optional& operator=(optional&& src) = default; + optional& operator=(optional&& src) noexcept = default; // Value assignment operators template < @@ -4792,7 +4765,7 @@ class LockableBaseImpl DoNothing(mutex_type&, phmap::try_to_lock_t) {} template explicit DoNothing(T&&) {} DoNothing& operator=(const DoNothing&) { return *this; } - DoNothing& operator=(DoNothing&&) { return *this; } + DoNothing& operator=(DoNothing&&) noexcept { return *this; } void swap(DoNothing &) {} bool owns_lock() const noexcept { return true; } }; @@ -4823,13 +4796,13 @@ class LockableBaseImpl m_->try_lock(); } - WriteLock(WriteLock &&o) : + WriteLock(WriteLock &&o) noexcept : m_(std::move(o.m_)), locked_(std::move(o.locked_)) { o.locked_ = false; o.m_ = nullptr; } - WriteLock& operator=(WriteLock&& other) { + WriteLock& operator=(WriteLock&& other) noexcept { WriteLock temp(std::move(other)); swap(temp); return *this; @@ -4901,13 +4874,13 @@ class LockableBaseImpl m_->try_lock_shared(); } - ReadLock(ReadLock &&o) : + ReadLock(ReadLock &&o) noexcept : m_(std::move(o.m_)), locked_(std::move(o.locked_)) { o.locked_ = false; o.m_ = nullptr; } - ReadLock& operator=(ReadLock&& other) { + ReadLock& operator=(ReadLock&& other) noexcept { ReadLock temp(std::move(other)); swap(temp); return *this; diff --git a/external/parallel_hashmap/phmap_bits.h b/external/parallel_hashmap/phmap_bits.h index d37ede358..314e91d53 100644 --- a/external/parallel_hashmap/phmap_bits.h +++ b/external/parallel_hashmap/phmap_bits.h @@ -270,7 +270,7 @@ inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } namespace phmap { namespace base_internal { -PHMAP_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) { +PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountLeadingZeros64Slow(uint64_t n) { int zeroes = 60; if (n >> 32) zeroes -= 32, n >>= 32; if (n >> 16) zeroes -= 16, n >>= 16; @@ -279,7 +279,7 @@ PHMAP_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) { return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes; } -PHMAP_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n) { +PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountLeadingZeros64(uint64_t n) { #if defined(_MSC_VER) && defined(_M_X64) // MSVC does not have __buitin_clzll. Use _BitScanReverse64. unsigned long result = 0; // NOLINT(runtime/int) diff --git a/external/parallel_hashmap/phmap_config.h b/external/parallel_hashmap/phmap_config.h index 18434f6bd..744de1825 100644 --- a/external/parallel_hashmap/phmap_config.h +++ b/external/parallel_hashmap/phmap_config.h @@ -36,7 +36,7 @@ #define PHMAP_VERSION_MAJOR 1 #define PHMAP_VERSION_MINOR 3 -#define PHMAP_VERSION_PATCH 8 +#define PHMAP_VERSION_PATCH 11 // Included for the __GLIBC__ macro (or similar macros on other systems). #include @@ -148,33 +148,6 @@ #define PHMAP_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) 0 #endif -// ---------------------------------------------------------------- -// Checks whether `std::is_trivially_destructible` is supported. -// ---------------------------------------------------------------- -#ifdef PHMAP_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE - #error PHMAP_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set -#elif defined(_LIBCPP_VERSION) || defined(_MSC_VER) || \ - (!defined(__clang__) && defined(__GNUC__) && defined(__GLIBCXX__) && PHMAP_INTERNAL_HAVE_MIN_GNUC_VERSION(4, 8)) - #define PHMAP_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 -#endif - -// -------------------------------------------------------------- -// Checks whether `std::is_trivially_default_constructible` is -// supported. -// -------------------------------------------------------------- -#if defined(PHMAP_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) - #error PHMAP_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set -#elif defined(PHMAP_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) - #error PHMAP_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set -#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ - (!defined(__clang__) && defined(__GNUC__) && \ - PHMAP_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 1) && \ - (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \ - (defined(_MSC_VER) && !defined(__NVCC__)) - #define PHMAP_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 - #define PHMAP_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 -#endif - // ------------------------------------------------------------------- // Checks whether C++11's `thread_local` storage duration specifier is // supported. @@ -340,7 +313,7 @@ #endif #endif -#if PHMAP_HAVE_CC17 +#if PHMAP_HAVE_CC17 && (!defined(__has_include) || __has_include()) #define PHMAP_HAVE_SHARED_MUTEX 1 #endif diff --git a/external/parallel_hashmap/phmap_fwd_decl.h b/external/parallel_hashmap/phmap_fwd_decl.h index a7719c494..c625be1d2 100644 --- a/external/parallel_hashmap/phmap_fwd_decl.h +++ b/external/parallel_hashmap/phmap_fwd_decl.h @@ -20,6 +20,7 @@ #include #include +#include #if defined(PHMAP_USE_ABSL_HASH) && !defined(ABSL_HASH_HASH_H_) namespace absl { template struct Hash; }; @@ -127,6 +128,37 @@ namespace phmap { class Mutex = phmap::NullMutex> // use std::mutex to enable internal locks class parallel_node_hash_map; + // ----------------------------------------------------------------------------- + // phmap::parallel_*_hash_* using std::mutex by default + // ----------------------------------------------------------------------------- + template , + class Eq = phmap::priv::hash_default_eq, + class Alloc = phmap::priv::Allocator, + size_t N = 4> + using parallel_flat_hash_set_m = parallel_flat_hash_set; + + template , + class Eq = phmap::priv::hash_default_eq, + class Alloc = phmap::priv::Allocator>, + size_t N = 4> + using parallel_flat_hash_map_m = parallel_flat_hash_map; + + template , + class Eq = phmap::priv::hash_default_eq, + class Alloc = phmap::priv::Allocator, + size_t N = 4> + using parallel_node_hash_set_m = parallel_node_hash_set; + + template , + class Eq = phmap::priv::hash_default_eq, + class Alloc = phmap::priv::Allocator>, + size_t N = 4> + using parallel_node_hash_map_m = parallel_node_hash_map; + // ------------- forward declarations for btree containers ---------------------------------- template , typename Alloc = phmap::Allocator> diff --git a/external/parallel_hashmap/phmap_utils.h b/external/parallel_hashmap/phmap_utils.h index dcf1cb779..b87e0ee22 100644 --- a/external/parallel_hashmap/phmap_utils.h +++ b/external/parallel_hashmap/phmap_utils.h @@ -293,7 +293,6 @@ template struct Combiner { H operator()(H h1, size_t k1) { -#if 1 // Copyright 2005-2014 Daniel James. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -310,9 +309,6 @@ template struct Combiner h1 = h1*5+0xe6546b64; return h1; -#else - return h1 ^ (k1 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2)); -#endif } }; @@ -320,7 +316,6 @@ template struct Combiner { H operator()(H h, size_t k) { -#if 1 // Copyright 2005-2014 Daniel James. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -339,9 +334,6 @@ template struct Combiner h += 0xe6546b64; return h; -#else - return h ^ (k + size_t(0xc6a4a7935bd1e995) + (h << 6) + (h >> 2)); -#endif } }; From e12c9058d77b2d053a45dc619f52006c91deece8 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 15 Oct 2023 11:18:59 +0200 Subject: [PATCH 20/30] Update RPC server --- src/Rpc/CoreRpcServerCommandsDefinitions.h | 88 +++++++-------- src/Rpc/HttpServer.cpp | 2 +- src/Rpc/RpcServer.cpp | 120 +++++++-------------- src/Rpc/RpcServer.h | 10 +- 4 files changed, 88 insertions(+), 132 deletions(-) diff --git a/src/Rpc/CoreRpcServerCommandsDefinitions.h b/src/Rpc/CoreRpcServerCommandsDefinitions.h index b053643a7..cf3778bfb 100644 --- a/src/Rpc/CoreRpcServerCommandsDefinitions.h +++ b/src/Rpc/CoreRpcServerCommandsDefinitions.h @@ -16,11 +16,11 @@ namespace cn { //----------------------------------------------- -#define CORE_RPC_STATUS_OK "OK" -#define CORE_RPC_STATUS_BUSY "BUSY" +const std::string CORE_RPC_STATUS_OK = "OK"; +const std::string CORE_RPC_STATUS_BUSY = "BUSY"; struct EMPTY_STRUCT { - void serialize(ISerializer &s) {} + void serialize(const ISerializer &) const {/* Nothing to serialize*/} }; struct STATUS_STRUCT { @@ -32,10 +32,10 @@ struct STATUS_STRUCT { }; struct COMMAND_RPC_GET_HEIGHT { - typedef EMPTY_STRUCT request; + using request = EMPTY_STRUCT; struct response { - uint64_t height; + uint32_t height; std::string status; void serialize(ISerializer &s) { @@ -141,7 +141,7 @@ struct COMMAND_RPC_GET_POOL_CHANGES { struct COMMAND_RPC_GET_ALT_BLOCKS_LIST { - typedef EMPTY_STRUCT request; + using request = EMPTY_STRUCT; struct response { @@ -254,7 +254,7 @@ struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response { std::string status; void serialize(ISerializer &s) { - KV_MEMBER(outs); + KV_MEMBER(outs) KV_MEMBER(status) } }; @@ -264,25 +264,25 @@ struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response_json { std::string status; void serialize(ISerializer &s) { - KV_MEMBER(outs); + KV_MEMBER(outs) KV_MEMBER(status) } }; struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS { - typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_request request; - typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response response; + using request = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_request; + using response = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response; - typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_out_entry out_entry; - typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_outs_for_amount outs_for_amount; + using out_entry = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_out_entry; + using outs_for_amount = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_outs_for_amount; }; struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_JSON { - typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_request request; - typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response_json response; + using request = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_request; + using response = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response_json; - typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_out_entry_json out_entry; - typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_outs_for_amount_json outs_for_amount; + using out_entry = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_out_entry_json; + using outs_for_amount = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_outs_for_amount_json; }; //----------------------------------------------- @@ -290,7 +290,7 @@ struct COMMAND_RPC_SEND_RAW_TX { struct request { std::string tx_as_hex; - request() {} + request() = default; explicit request(const Transaction &); void serialize(ISerializer &s) { @@ -328,14 +328,14 @@ struct COMMAND_RPC_START_MINING { }; //----------------------------------------------- struct COMMAND_RPC_GET_INFO { - typedef EMPTY_STRUCT request; + using request = EMPTY_STRUCT; struct response { std::string status; std::string version; std::string fee_address; std::string top_block_hash; - uint64_t height; + uint32_t height; uint64_t difficulty; uint64_t tx_count; uint64_t tx_pool_size; @@ -381,7 +381,7 @@ struct COMMAND_RPC_GET_INFO { //----------------------------------------------- struct COMMAND_RPC_GET_PEER_LIST { - typedef EMPTY_STRUCT request; + using request = EMPTY_STRUCT; struct response { std::vector peers; @@ -396,19 +396,19 @@ struct COMMAND_RPC_GET_PEER_LIST { //----------------------------------------------- struct COMMAND_RPC_STOP_MINING { - typedef EMPTY_STRUCT request; - typedef STATUS_STRUCT response; + using request = EMPTY_STRUCT; + using response = STATUS_STRUCT; }; //----------------------------------------------- struct COMMAND_RPC_STOP_DAEMON { - typedef EMPTY_STRUCT request; - typedef STATUS_STRUCT response; + using request = EMPTY_STRUCT; + using response = STATUS_STRUCT; }; // struct COMMAND_RPC_GETBLOCKCOUNT { - typedef std::vector request; + using request = std::vector; struct response { uint64_t count; @@ -422,7 +422,7 @@ struct COMMAND_RPC_GETBLOCKCOUNT { }; struct COMMAND_RPC_GET_FEE_ADDRESS { - typedef EMPTY_STRUCT request; + using request = EMPTY_STRUCT; struct response { std::string fee_address; @@ -438,8 +438,8 @@ struct COMMAND_RPC_GET_FEE_ADDRESS { struct COMMAND_RPC_GETBLOCKHASH { - typedef std::vector request; - typedef std::string response; + using request = std::vector; + using response = std::string; }; struct COMMAND_RPC_GETBLOCKTEMPLATE { @@ -471,7 +471,7 @@ struct COMMAND_RPC_GETBLOCKTEMPLATE { }; struct COMMAND_RPC_GET_CURRENCY_ID { - typedef EMPTY_STRUCT request; + using request = EMPTY_STRUCT; struct response { std::string currency_id_blob; @@ -483,8 +483,8 @@ struct COMMAND_RPC_GET_CURRENCY_ID { }; struct COMMAND_RPC_SUBMITBLOCK { - typedef std::vector request; - typedef STATUS_STRUCT response; + using request = std::vector; + using response = STATUS_STRUCT; }; struct block_header_response { @@ -494,7 +494,7 @@ struct block_header_response { std::string prev_hash; uint32_t nonce; bool orphan_status; - uint64_t height; + uint32_t height; uint64_t depth; uint64_t deposits; std::string hash; @@ -585,7 +585,7 @@ struct f_block_details_response { std::string prev_hash; uint32_t nonce; bool orphan_status; - uint64_t height; + uint32_t height; uint64_t depth; std::string hash; difficulty_type difficulty; @@ -686,8 +686,8 @@ struct currency_core { struct COMMAND_RPC_GET_LAST_BLOCK_HEADER { - typedef EMPTY_STRUCT request; - typedef BLOCK_HEADER_RESPONSE response; + using request = EMPTY_STRUCT; + using response = BLOCK_HEADER_RESPONSE; }; struct COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH { @@ -699,26 +699,26 @@ struct COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH { } }; - typedef BLOCK_HEADER_RESPONSE response; + using response = BLOCK_HEADER_RESPONSE; }; struct COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT { struct request { - uint64_t height; + uint32_t height; void serialize(ISerializer &s) { KV_MEMBER(height) } }; - typedef BLOCK_HEADER_RESPONSE response; + using response = BLOCK_HEADER_RESPONSE; }; struct F_COMMAND_RPC_GET_BLOCKS_LIST { struct request { - uint64_t height; + uint32_t height; void serialize(ISerializer &s) { KV_MEMBER(height) @@ -781,7 +781,7 @@ struct F_COMMAND_RPC_GET_TRANSACTION_DETAILS { }; struct F_COMMAND_RPC_GET_POOL { - typedef EMPTY_STRUCT request; + using request = EMPTY_STRUCT; struct response { std::vector transactions; //transactions blobs as hex @@ -795,7 +795,7 @@ struct F_COMMAND_RPC_GET_POOL { }; struct F_COMMAND_RPC_GET_BLOCKCHAIN_SETTINGS { - typedef EMPTY_STRUCT request; + using request = EMPTY_STRUCT; struct response { currency_base_coin base_coin; currency_core core; @@ -903,7 +903,7 @@ struct COMMAND_RPC_GET_BLOCK_TIMESTAMP_BY_HEIGHT { struct request { - uint64_t height; + uint32_t height; void serialize(ISerializer &s) { @@ -928,7 +928,7 @@ struct COMMAND_RPC_GET_BLOCK_DETAILS_BY_HEIGHT { struct request { - uint64_t height; + uint32_t height; void serialize(ISerializer &s) { @@ -998,7 +998,7 @@ struct COMMAND_RPC_GET_TRANSACTIONS_WITH_OUTPUT_GLOBAL_INDEXES { }; struct COMMAND_RPC_GET_RAW_TRANSACTIONS_POOL { - typedef EMPTY_STRUCT request; + using request = EMPTY_STRUCT; struct response { std::vector transactions; diff --git a/src/Rpc/HttpServer.cpp b/src/Rpc/HttpServer.cpp index a3e7709e8..f6608bf62 100644 --- a/src/Rpc/HttpServer.cpp +++ b/src/Rpc/HttpServer.cpp @@ -98,7 +98,7 @@ void HttpServer::acceptLoop() { HttpRequest req; HttpResponse resp; resp.addHeader("Access-Control-Allow-Origin", "*"); - resp.addHeader("content-type", "application/json"); + resp.addHeader("Content-Type", "application/json"); parser.receiveRequest(stream, req); if (authenticate(req)) { diff --git a/src/Rpc/RpcServer.cpp b/src/Rpc/RpcServer.cpp index 82ae8078f..fcd1a5aab 100644 --- a/src/Rpc/RpcServer.cpp +++ b/src/Rpc/RpcServer.cpp @@ -118,7 +118,7 @@ RpcServer::RpcServer(platform_system::Dispatcher& dispatcher, logging::ILogger& } void RpcServer::processRequest(const HttpRequest& request, HttpResponse& response) { - auto url = request.getUrl(); + const auto& url = request.getUrl(); auto it = s_handlers.find(url); if (it == s_handlers.end()) { @@ -203,12 +203,12 @@ bool RpcServer::isCoreReady() { return m_core.currency().isTestnet() || m_p2p.get_payload_object().isSynchronized(); } -bool RpcServer::enableCors(const std::string domain) { +bool RpcServer::enableCors(const std::string& domain) { m_cors_domain = domain; return true; } -std::string RpcServer::getCorsDomain() { +std::string RpcServer::getCorsDomain() const { return m_cors_domain; } @@ -275,7 +275,7 @@ bool RpcServer::on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request &req, CO throw JsonRpc::JsonRpcError{CORE_RPC_ERROR_CODE_WRONG_PARAM, "Wrong parameters, expected height"}; } - uint32_t h = static_cast(req[0]); + uint32_t h = req[0]; crypto::Hash blockId = m_core.getBlockIdByHeight(h); if (blockId == NULL_HASH) { @@ -323,12 +323,12 @@ bool RpcServer::fill_f_block_details_response(const crypto::Hash &hash, f_block_ block.hash = common::podToHex(hash); block.orphan_status = is_orphaned; block.depth = m_core.get_current_blockchain_height() - block.height - 1; - m_core.getBlockDifficulty(static_cast(block.height), block.difficulty); + m_core.getBlockDifficulty(block_height, block.difficulty); block.reward = block_header.reward; std::vector blocksSizes; - if (!m_core.getBackwardBlocksSizes(block.height, blocksSizes, parameters::CRYPTONOTE_REWARD_BLOCKS_WINDOW)) + if (!m_core.getBackwardBlocksSizes(block_height, blocksSizes, parameters::CRYPTONOTE_REWARD_BLOCKS_WINDOW)) { return false; } @@ -352,29 +352,26 @@ bool RpcServer::fill_f_block_details_response(const crypto::Hash &hash, f_block_ } block.alreadyGeneratedCoins = std::to_string(alreadyGeneratedCoins); - if (!m_core.getGeneratedTransactionsNumber(block.height, block.alreadyGeneratedTransactions)) + if (!m_core.getGeneratedTransactionsNumber(block_height, block.alreadyGeneratedTransactions)) { return false; } uint64_t prevBlockGeneratedCoins = 0; - if (block.height > 0) + if (block.height > 0 && !m_core.getAlreadyGeneratedCoins(blk.previousBlockHash, prevBlockGeneratedCoins)) { - if (!m_core.getAlreadyGeneratedCoins(blk.previousBlockHash, prevBlockGeneratedCoins)) - { - return false; - } + return false; } uint64_t maxReward = 0; uint64_t currentReward = 0; int64_t emissionChange = 0; block.effectiveSizeMedian = std::max(block.sizeMedian, m_core.currency().blockGrantedFullRewardZone()); - if (!m_core.getBlockReward(block.sizeMedian, 0, prevBlockGeneratedCoins, 0, block.height, maxReward, emissionChange)) + if (!m_core.getBlockReward(block.sizeMedian, 0, prevBlockGeneratedCoins, 0, block_height, maxReward, emissionChange)) { return false; } - if (!m_core.getBlockReward(block.sizeMedian, block.transactionsCumulativeSize, prevBlockGeneratedCoins, 0, block.height, currentReward, emissionChange)) + if (!m_core.getBlockReward(block.sizeMedian, block.transactionsCumulativeSize, prevBlockGeneratedCoins, 0, block_height, currentReward, emissionChange)) { return false; } @@ -415,7 +412,7 @@ bool RpcServer::fill_f_block_details_response(const crypto::Hash &hash, f_block_ uint64_t amount_out = get_outs_money_amount(tx); transaction_short.hash = common::podToHex(getObjectHash(tx)); - transaction_short.fee = m_core.currency().getTransactionFee(tx, static_cast(block.height)); + transaction_short.fee = m_core.currency().getTransactionFee(tx, block.height); transaction_short.amount_out = amount_out; transaction_short.size = getObjectBinarySize(tx); block.transactions.push_back(transaction_short); @@ -469,7 +466,7 @@ bool RpcServer::on_get_txs_with_output_global_indexes(const COMMAND_RPC_GET_TRAN } uint32_t upperBound = std::min(range[1], m_core.get_current_blockchain_height()); - for (size_t i = 0; i < (upperBound - range[0]); i++) { + for (uint32_t i = 0; i < (upperBound - range[0]); i++) { heights.push_back(range[0] + i); } } @@ -548,7 +545,7 @@ bool RpcServer::on_get_txs_with_output_global_indexes(const COMMAND_RPC_GET_TRAN return true; } -bool RpcServer::on_get_transactions_pool_raw(const COMMAND_RPC_GET_RAW_TRANSACTIONS_POOL::request& req, COMMAND_RPC_GET_RAW_TRANSACTIONS_POOL::response& res) { +bool RpcServer::on_get_transactions_pool_raw(const COMMAND_RPC_GET_RAW_TRANSACTIONS_POOL::request&, COMMAND_RPC_GET_RAW_TRANSACTIONS_POOL::response& res) { auto pool = m_core.getMemoryPool(); for (const auto& txd : pool) { @@ -865,7 +862,7 @@ bool RpcServer::setViewKey(const std::string& view_key) { return true; } -bool RpcServer::on_get_fee_address(const COMMAND_RPC_GET_FEE_ADDRESS::request& req, COMMAND_RPC_GET_FEE_ADDRESS::response& res) { +bool RpcServer::on_get_fee_address(const COMMAND_RPC_GET_FEE_ADDRESS::request&, COMMAND_RPC_GET_FEE_ADDRESS::response& res) { if (m_fee_address.empty()) { res.status = CORE_RPC_STATUS_OK; return false; @@ -912,8 +909,8 @@ bool RpcServer::on_get_random_outs_json(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR for (size_t i = 0; i < outs.size(); ++i) { COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_JSON::outs_for_amount out; out.amount = bin.outs[i].amount; - for (auto& o : outs[i].outs) { - out.outs.push_back(static_cast(o)); + for (const auto& o : outs[i].outs) { + out.outs.push_back(static_cast(o)); } res.outs.push_back(out); } @@ -927,11 +924,11 @@ bool RpcServer::onGetPoolChanges(const COMMAND_RPC_GET_POOL_CHANGES::request& re rsp.status = CORE_RPC_STATUS_OK; std::vector addedTransactions; rsp.isTailBlockActual = m_core.getPoolChanges(req.tailBlockId, req.knownTxsIds, addedTransactions, rsp.deletedTxsIds); - for (auto& tx : addedTransactions) { + for (const auto& tx : addedTransactions) { BinaryArray txBlob; if (!toBinaryArray(tx, txBlob)) { rsp.status = "Internal error"; - break;; + break; } rsp.addedTxs.emplace_back(std::move(txBlob)); @@ -952,7 +949,7 @@ bool RpcServer::onGetPoolChangesLite(const COMMAND_RPC_GET_POOL_CHANGES_LITE::re // -bool RpcServer::on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_LIST::response& res) { +bool RpcServer::on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request&, COMMAND_RPC_GET_PEER_LIST::response& res) { std::list pl_wite; std::list pl_gray; m_p2p.getPeerlistManager().get_peerlist_full(pl_gray, pl_wite); @@ -965,7 +962,7 @@ bool RpcServer::on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request& req, return true; } -bool RpcServer::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res) { +bool RpcServer::on_get_info(const COMMAND_RPC_GET_INFO::request&, COMMAND_RPC_GET_INFO::response& res) { res.height = m_core.get_current_blockchain_height(); res.difficulty = m_core.getNextBlockDifficulty(); res.tx_count = m_core.get_blockchain_total_transactions() - res.height; //without coinbase @@ -1008,13 +1005,13 @@ bool RpcServer::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RP res.block_minor_version = block_header.minor_version; res.last_block_timestamp = block_header.timestamp; res.last_block_reward = block_header.reward; - m_core.getBlockDifficulty(static_cast(last_block_height), res.last_block_difficulty); + m_core.getBlockDifficulty(last_block_height, res.last_block_difficulty); res.connections = m_p2p.get_payload_object().all_connections(); return true; } -bool RpcServer::on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res) { +bool RpcServer::on_get_height(const COMMAND_RPC_GET_HEIGHT::request&, COMMAND_RPC_GET_HEIGHT::response& res) { res.height = m_core.get_current_blockchain_height(); res.status = CORE_RPC_STATUS_OK; return true; @@ -1039,7 +1036,7 @@ bool RpcServer::on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& std::list txs; m_core.getTransactions(vh, txs, missed_txs); - for (auto& tx : txs) { + for (const auto& tx : txs) { res.txs_as_hex.push_back(toHex(toBinaryArray(tx))); } @@ -1089,18 +1086,6 @@ bool RpcServer::on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMM return true; } - /* check tx for node fee - - if (!m_fee_address.empty() && m_view_key != NULL_SECRET_KEY) { - if (!remotenode_check_incoming_tx(tx_blob)) { - logger(INFO) << "Transaction not relayed due to lack of remote node fee"; - res.status = "Not relayed due to lack of node fee"; - return true; - } - } - - */ - NOTIFY_NEW_TRANSACTIONS::request r; r.txs.push_back(asString(tx_blob)); m_core.get_protocol()->relay_transactions(r); @@ -1115,7 +1100,7 @@ bool RpcServer::on_start_mining(const COMMAND_RPC_START_MINING::request& req, CO return true; } - if (!m_core.get_miner().start(adr, static_cast(req.threads_count))) { + if (!m_core.get_miner().start(adr, req.threads_count)) { res.status = "Failed, mining not started"; return true; } @@ -1124,36 +1109,7 @@ bool RpcServer::on_start_mining(const COMMAND_RPC_START_MINING::request& req, CO return true; } -/* - -bool RpcServer::remotenode_check_incoming_tx(const BinaryArray& tx_blob) { - crypto::Hash tx_hash = NULL_HASH; - crypto::Hash tx_prefixt_hash = NULL_HASH; - Transaction tx; - if (!parseAndValidateTransactionFromBinaryArray(tx_blob, tx, tx_hash, tx_prefixt_hash)) { - logger(INFO) << "Could not parse tx from blob"; - return false; - } - cn::TransactionPrefix transaction = *static_cast(&tx); - - std::vector out; - uint64_t amount; - - if (!cn::findOutputsToAccount(transaction, m_fee_acc, m_view_key, out, amount)) { - logger(INFO) << "Could not find outputs to remote node fee address"; - return false; - } - - if (amount != 0) { - logger(INFO) << "Node received relayed transaction fee: " << m_core.currency().formatAmount(amount) << " CCX"; - return true; - } - return false; -} - -*/ - -bool RpcServer::on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res) { +bool RpcServer::on_stop_mining(const COMMAND_RPC_STOP_MINING::request&, COMMAND_RPC_STOP_MINING::response& res) { if (!m_core.get_miner().stop()) { res.status = "Failed, mining not stopped"; return true; @@ -1162,7 +1118,7 @@ bool RpcServer::on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMM return true; } -bool RpcServer::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res) { +bool RpcServer::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request&, COMMAND_RPC_STOP_DAEMON::response& res) { if (m_core.currency().isTestnet()) { m_p2p.sendStopSignal(); res.status = CORE_RPC_STATUS_OK; @@ -1189,7 +1145,7 @@ bool RpcServer::f_on_blocks_list_json(const F_COMMAND_RPC_GET_BLOCKS_LIST::reque } for (uint32_t i = req.height; i >= last_height; i--) { - Hash block_hash = m_core.getBlockIdByHeight(static_cast(i)); + Hash block_hash = m_core.getBlockIdByHeight(i); Block blk; if (!m_core.getBlockByHash(block_hash, blk)) { throw JsonRpc::JsonRpcError{ CORE_RPC_ERROR_CODE_INTERNAL_ERROR, @@ -1205,7 +1161,7 @@ bool RpcServer::f_on_blocks_list_json(const F_COMMAND_RPC_GET_BLOCKS_LIST::reque block_short.cumul_size = blokBlobSize + tx_cumulative_block_size - minerTxBlobSize; block_short.timestamp = blk.timestamp; block_short.height = i; - m_core.getBlockDifficulty(static_cast(block_short.height), block_short.difficulty); + m_core.getBlockDifficulty(block_short.height, block_short.difficulty); block_short.hash = common::podToHex(block_hash); block_short.tx_count = blk.transactionHashes.size() + 1; @@ -1315,7 +1271,7 @@ bool RpcServer::f_on_transaction_json(const F_COMMAND_RPC_GET_TRANSACTION_DETAIL return true; } -bool RpcServer::f_getMixin(const Transaction& transaction, uint64_t& mixin) { +bool RpcServer::f_getMixin(const Transaction& transaction, uint64_t& mixin) const { mixin = 0; for (const TransactionInput& txin : transaction.inputs) { if (txin.type() != typeid(KeyInput)) { @@ -1329,7 +1285,7 @@ bool RpcServer::f_getMixin(const Transaction& transaction, uint64_t& mixin) { return true; } -bool RpcServer::f_on_transactions_pool_json(const F_COMMAND_RPC_GET_POOL::request& req, F_COMMAND_RPC_GET_POOL::response& res) { +bool RpcServer::f_on_transactions_pool_json(const F_COMMAND_RPC_GET_POOL::request&, F_COMMAND_RPC_GET_POOL::response& res) { auto pool = m_core.getPoolTransactions(); auto height = m_core.get_current_blockchain_height(); for (const Transaction tx : pool) { @@ -1347,7 +1303,7 @@ bool RpcServer::f_on_transactions_pool_json(const F_COMMAND_RPC_GET_POOL::reques return true; } -bool RpcServer::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res) { +bool RpcServer::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request&, COMMAND_RPC_GETBLOCKCOUNT::response& res) { res.count = m_core.get_current_blockchain_height(); res.status = CORE_RPC_STATUS_OK; return true; @@ -1456,7 +1412,7 @@ namespace { } } -bool RpcServer::on_alt_blocks_list_json(const COMMAND_RPC_GET_ALT_BLOCKS_LIST::request &req, COMMAND_RPC_GET_ALT_BLOCKS_LIST::response &res) +bool RpcServer::on_alt_blocks_list_json(const COMMAND_RPC_GET_ALT_BLOCKS_LIST::request &, COMMAND_RPC_GET_ALT_BLOCKS_LIST::response &res) { std::list alt_blocks; @@ -1471,7 +1427,7 @@ bool RpcServer::on_alt_blocks_list_json(const COMMAND_RPC_GET_ALT_BLOCKS_LIST::r size_t blokBlobSize = getObjectBinarySize(b); size_t minerTxBlobSize = getObjectBinarySize(b.baseTransaction); difficulty_type blockDiff; - m_core.getBlockDifficulty(static_cast(block_height), blockDiff); + m_core.getBlockDifficulty(block_height, blockDiff); block_short_response block_short; block_short.timestamp = b.timestamp; @@ -1489,7 +1445,7 @@ bool RpcServer::on_alt_blocks_list_json(const COMMAND_RPC_GET_ALT_BLOCKS_LIST::r return true; } -void RpcServer::fill_block_header_response(const Block& blk, bool orphan_status, uint64_t height, const Hash& hash, block_header_response& responce) { +void RpcServer::fill_block_header_response(const Block& blk, bool orphan_status, uint32_t height, const Hash& hash, block_header_response& responce) { responce.major_version = blk.majorVersion; responce.minor_version = blk.minorVersion; responce.timestamp = blk.timestamp; @@ -1500,11 +1456,11 @@ void RpcServer::fill_block_header_response(const Block& blk, bool orphan_status, responce.deposits = m_core.depositAmountAtHeight(height); responce.depth = m_core.get_current_blockchain_height() - height - 1; responce.hash = common::podToHex(hash); - m_core.getBlockDifficulty(static_cast(height), responce.difficulty); + m_core.getBlockDifficulty(height, responce.difficulty); responce.reward = get_block_reward(blk); } -bool RpcServer::on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res) { +bool RpcServer::on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request&, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res) { uint32_t last_block_height; Hash last_block_hash; @@ -1559,7 +1515,7 @@ bool RpcServer::on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER std::string("To big height: ") + std::to_string(req.height) + ", current blockchain height = " + std::to_string(m_core.get_current_blockchain_height()) }; } - Hash block_hash = m_core.getBlockIdByHeight(static_cast(req.height)); + Hash block_hash = m_core.getBlockIdByHeight(req.height); Block blk; if (!m_core.getBlockByHash(block_hash, blk)) { throw JsonRpc::JsonRpcError{ CORE_RPC_ERROR_CODE_INTERNAL_ERROR, diff --git a/src/Rpc/RpcServer.h b/src/Rpc/RpcServer.h index fc0c746b0..5b19edce2 100644 --- a/src/Rpc/RpcServer.h +++ b/src/Rpc/RpcServer.h @@ -30,8 +30,8 @@ class RpcServer : public HttpServer { bool k_on_check_tx_proof(const K_COMMAND_RPC_CHECK_TX_PROOF::request& req, K_COMMAND_RPC_CHECK_TX_PROOF::response& res); bool k_on_check_reserve_proof(const K_COMMAND_RPC_CHECK_RESERVE_PROOF::request& req, K_COMMAND_RPC_CHECK_RESERVE_PROOF::response& res); bool remotenode_check_incoming_tx(const BinaryArray& tx_blob); - bool enableCors(const std::string domain); - std::string getCorsDomain(); + bool enableCors(const std::string& domain); + std::string getCorsDomain() const; private: @@ -44,7 +44,7 @@ class RpcServer : public HttpServer { typedef void (RpcServer::*HandlerPtr)(const HttpRequest& request, HttpResponse& response); static std::unordered_map> s_handlers; - virtual void processRequest(const HttpRequest& request, HttpResponse& response) override; + void processRequest(const HttpRequest& request, HttpResponse& response) override; bool processJsonRpcRequest(const HttpRequest& request, HttpResponse& response); bool isCoreReady(); @@ -84,13 +84,13 @@ class RpcServer : public HttpServer { bool on_get_block_details_by_height(const COMMAND_RPC_GET_BLOCK_DETAILS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_DETAILS_BY_HEIGHT::response& res); bool on_get_transactions_pool_raw(const COMMAND_RPC_GET_RAW_TRANSACTIONS_POOL::request& req, COMMAND_RPC_GET_RAW_TRANSACTIONS_POOL::response& res); - void fill_block_header_response(const Block& blk, bool orphan_status, uint64_t height, const crypto::Hash& hash, block_header_response& responce); + void fill_block_header_response(const Block& blk, bool orphan_status, uint32_t height, const crypto::Hash& hash, block_header_response& responce); bool f_on_blocks_list_json(const F_COMMAND_RPC_GET_BLOCKS_LIST::request& req, F_COMMAND_RPC_GET_BLOCKS_LIST::response& res); bool f_on_block_json(const F_COMMAND_RPC_GET_BLOCK_DETAILS::request& req, F_COMMAND_RPC_GET_BLOCK_DETAILS::response& res); bool f_on_transaction_json(const F_COMMAND_RPC_GET_TRANSACTION_DETAILS::request& req, F_COMMAND_RPC_GET_TRANSACTION_DETAILS::response& res); bool f_on_transactions_pool_json(const F_COMMAND_RPC_GET_POOL::request& req, F_COMMAND_RPC_GET_POOL::response& res); - bool f_getMixin(const Transaction& transaction, uint64_t& mixin); + bool f_getMixin(const Transaction& transaction, uint64_t& mixin) const; bool fill_f_block_details_response(const crypto::Hash& hash, f_block_details_response& block); From 3b30e7985e43076c156e1c4270c071a0c1b98e7c Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 22 Oct 2023 13:47:22 +0200 Subject: [PATCH 21/30] Add OpenAPI documentation --- docs/rpc/openapi/check_reserve_proof.yaml | 103 +++ docs/rpc/openapi/check_tx_proof.yaml | 168 +++++ docs/rpc/openapi/f_block_json.yaml | 200 ++++++ docs/rpc/openapi/f_blocks_list_json.yaml | 307 ++++++++ docs/rpc/openapi/f_on_transactions_pool.yaml | 106 +++ docs/rpc/openapi/f_transaction_json.yaml | 302 ++++++++ docs/rpc/openapi/getalblockslist.yaml | 115 +++ docs/rpc/openapi/getblockbyheight.yaml | 200 ++++++ docs/rpc/openapi/getblockcount.yaml | 87 +++ docs/rpc/openapi/getblockhash.yaml | 84 +++ docs/rpc/openapi/getblockheaderbyhash.yaml | 141 ++++ docs/rpc/openapi/getblockheaderbyheight.yaml | 141 ++++ docs/rpc/openapi/getblocktemplate.yaml | 107 +++ docs/rpc/openapi/getblocktimestamp.yaml | 91 +++ docs/rpc/openapi/getcurrencyid.yaml | 83 +++ docs/rpc/openapi/getlastblockheader.yaml | 137 ++++ docs/rpc/openapi/getrawtransactionpool.yaml | 291 ++++++++ .../openapi/getrawtransactionsbyheight.yaml | 293 ++++++++ docs/rpc/openapi/json_methods.yaml | 664 ++++++++++++++++++ docs/rpc/openapi/submitblock.yaml | 83 +++ 20 files changed, 3703 insertions(+) create mode 100644 docs/rpc/openapi/check_reserve_proof.yaml create mode 100644 docs/rpc/openapi/check_tx_proof.yaml create mode 100644 docs/rpc/openapi/f_block_json.yaml create mode 100644 docs/rpc/openapi/f_blocks_list_json.yaml create mode 100644 docs/rpc/openapi/f_on_transactions_pool.yaml create mode 100644 docs/rpc/openapi/f_transaction_json.yaml create mode 100644 docs/rpc/openapi/getalblockslist.yaml create mode 100644 docs/rpc/openapi/getblockbyheight.yaml create mode 100644 docs/rpc/openapi/getblockcount.yaml create mode 100644 docs/rpc/openapi/getblockhash.yaml create mode 100644 docs/rpc/openapi/getblockheaderbyhash.yaml create mode 100644 docs/rpc/openapi/getblockheaderbyheight.yaml create mode 100644 docs/rpc/openapi/getblocktemplate.yaml create mode 100644 docs/rpc/openapi/getblocktimestamp.yaml create mode 100644 docs/rpc/openapi/getcurrencyid.yaml create mode 100644 docs/rpc/openapi/getlastblockheader.yaml create mode 100644 docs/rpc/openapi/getrawtransactionpool.yaml create mode 100644 docs/rpc/openapi/getrawtransactionsbyheight.yaml create mode 100644 docs/rpc/openapi/json_methods.yaml create mode 100644 docs/rpc/openapi/submitblock.yaml diff --git a/docs/rpc/openapi/check_reserve_proof.yaml b/docs/rpc/openapi/check_reserve_proof.yaml new file mode 100644 index 000000000..eea71997d --- /dev/null +++ b/docs/rpc/openapi/check_reserve_proof.yaml @@ -0,0 +1,103 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Check Reserve Proof + description: Check the reserve proof using JSON-RPC. + operationId: checkReserveProof + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/CheckReserveProofRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/CheckReserveProofResponse" + +components: + schemas: + CheckReserveProofRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["check_reserve_proof"] + params: + $ref: "#/components/schemas/CheckReserveProofParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + CheckReserveProofParams: + type: object + properties: + address: + type: string + description: The address for the reserve proof. + example: ccx7WVMV8EEEQE7GcN9xME6zAK8ZonvqYgA3694nXk97ZsxUGmD5chx48ze9hrhZ4V81bQ7xMMHLkFbB9HtPEcqq3edGYYnahU + message: + type: string + description: The message for the reserve proof. + example: concealrpc + signature: + type: string + description: The signature for the reserve proof. + example: ReserveProofV194Xs6wZjz4d9u2nsjVtDekA4oqmKtfihoAGFfsMP3aEYHRrsmWdFvdyHRYtWk4rwYYHvmUvAAbebGHdDqw45farP9mJPG9EVEMTHG9nMLUZW1JAGT3BdtffbzJ6SMwkj3ZCN9Ztq7bALP1694iTbpS9Jva9jNMjLjBP4EAbjQTMSvJsc9ZrdEa2rYQB9jShDok8BnJA6hnmoHrk7N9Ru5E9i61yS9w3FrKr2s8FA6fZPisMYZxHHtus4JJ8vW9mM3EHCvHqB9tzeJJbxYueA6ZPm37JCob9Pvnjo5we4JAa2Tk8XP2jZ9GF2gQLrm8eAGSeN8UCAex9GCPofkZoDQHFtoPpu7CjPAGFcUUfmL66A6hmNUYkgDzA4oqGfubEnY96VmHUpFVigAQSpZpLNpif9G83LKWayswAGNFQPV5dhyHFyBFqvbQg39vxroHMtfxtARzVsqpbLE89u5PBLfsS2QJ6WjpYMcDp89GCp7vCGsmA9tzcPJrqK3AJ6UaKcXL376A6kPkKu46E8Hnot1APNWj79G3cndVx9CqAZqUq7jNuWn9ZfdKzuCpRE9mLfDhs81uz9jJMgf9BhKaHxZBQYD9hwxAQKoERs6MQ694VCpyYB5T5HbN9NqktiRTHG9mGGaAzom9EGi7m3MiHF9ZredMP5gHSHTXZv3TttcuHxZBtdaViHe9PtbMRy327K9Zfck9rzEF19Q3QgATkkDvHRpEnn1o8dp9mE4NdXDRfzHbXKDPgWbpHHkxBTJroJ8AHHpUuLK4z6RA535eBU9ykk2Jva4Q + + CheckReserveProofResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/CheckReserveProofResult" + id: + type: string + example: "1" + + CheckReserveProofResult: + type: object + properties: + good: + type: boolean + description: Whether the reserve proof is valid or not. + example: true + total: + type: integer + description: The total amount in the reserve proof. + example: 200000000 + spent: + type: integer + description: The spent amount from the reserve proof. + example: 0 diff --git a/docs/rpc/openapi/check_tx_proof.yaml b/docs/rpc/openapi/check_tx_proof.yaml new file mode 100644 index 000000000..d520c900d --- /dev/null +++ b/docs/rpc/openapi/check_tx_proof.yaml @@ -0,0 +1,168 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Check Transaction Proof + description: Check the transaction proof using JSON-RPC. + operationId: checkTransactionProof + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/CheckTxProofRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/CheckTxProofResponse" + +components: + schemas: + CheckTxProofRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["check_tx_proof"] + params: + $ref: "#/components/schemas/CheckTxProofParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + CheckTxProofParams: + type: object + properties: + tx_id: + type: string + description: The transaction ID. + example: f16dbf513d5d056316450b7a75888eb8efb89db06ce835e348ba47cd58621d4e + dest_address: + type: string + description: The destination address. + example: ccx7WVMV8EEEQE7GcN9xME6zAK8ZonvqYgA3694nXk97ZsxUGmD5chx48ze9hrhZ4V81bQ7xMMHLkFbB9HtPEcqq3edGYYnahU + signature: + type: string + description: The transaction signature. + example: ProofV1f9UnC8p5CguFpjZ4WoqYCRW26NCJJHFTuBoD74jhMWVbSkL5vZ3gtcnY2H12HLa27uF2ndPtUU6axKX8cHiJwJmKQsuLDCNDyvr36yGfeUSM8jCW5stQk8aLGcfAcAV3wAzE + + CheckTxProofResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/CheckTxProofResult" + id: + type: string + example: "1" + + CheckTxProofResult: + type: object + properties: + signature_valid: + type: boolean + description: Whether the signature is valid or not. + example: true + received_amount: + type: integer + description: The received amount. + example: 200000000 + outputs: + type: array + items: + $ref: "#/components/schemas/TransactionOutput" + description: The transaction outputs. + confirmations: + type: integer + description: The number of confirmations. + example: 12 + status: + type: string + description: The status of the operation + example: OK + + TransactionOutput: + type: object + properties: + amount: + type: integer + description: The amount for the transaction output. + example: 200000000 + target: + $ref: "#/components/schemas/TransactionOutputTarget" + + TransactionOutputTarget: + type: object + oneOf: + - $ref: "#/components/schemas/KeyOutput" + - $ref: "#/components/schemas/MultisignatureOutput" + discriminator: + propertyName: type + mapping: + "02": "#/components/schemas/KeyOutput" + "03": "#/components/schemas/MultisignatureOutput" + + KeyOutput: + type: object + properties: + type: + type: string + enum: ["02"] + data: + type: object + description: The public key for the key output. + properties: + key: + type: string + example: 9e32c015362a892ea40d02148b453f774f6ce8e2036acda96255cefda6bf2ba3 + + MultisignatureOutput: + type: object + properties: + type: + type: string + enum: ["03"] + data: + type: object + properties: + keys: + type: array + items: + type: string + description: The public keys for the multisignature output. + required_signatures: + type: integer + description: The required signature count for the multisignature output. + term: + type: integer + description: The term for the multisignature output. diff --git a/docs/rpc/openapi/f_block_json.yaml b/docs/rpc/openapi/f_block_json.yaml new file mode 100644 index 000000000..2945c123b --- /dev/null +++ b/docs/rpc/openapi/f_block_json.yaml @@ -0,0 +1,200 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + - name: blockchain-indexes + description: Mandatory blockchain indexes + +paths: + /json_rpc: + post: + summary: Get Block Details + description: Retrieve details of a block using JSON-RPC. + operationId: getBlockDetails + tags: ["JSON-RPC", "blockchain-indexes"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockResponse" + +components: + schemas: + GetBlockRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["f_block_json"] + params: + $ref: "#/components/schemas/GetBlockParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + GetBlockParams: + type: object + properties: + hash: + type: string + description: The hash of the block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + + GetBlockResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetBlockResult" + id: + type: string + example: "1" + + GetBlockResult: + type: object + properties: + block: + $ref: "#/components/schemas/BlockDetails" + description: Block details for the specified hash + status: + type: string + description: The status of the operation + example: OK + + BlockDetails: + type: object + properties: + major_version: + type: integer + description: The major version of the block. + example: 8 + minor_version: + type: integer + description: The minor version of the block. + example: 0 + timestamp: + type: integer + description: The timestamp of the block. + example: 1633510598 + prev_hash: + type: string + description: The hash of the previous block. + example: 09371a62201ba2393b2e250bc101e9e772e8bbab3b02ebddcdd3e35e5dd17c4c + nonce: + type: integer + description: The nonce of the block. + example: 3425989702 + orphan_status: + type: boolean + description: Whether the block is an orphan. + example: false + height: + type: integer + description: The height of the block. + example: height + depth: + type: integer + description: The depth of the block. + example: 123456 + hash: + type: string + description: The hash of the block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + difficulty: + type: integer + description: The difficulty of the block. + example: 74 + reward: + type: integer + description: The reward of the block. + example: 6000000 + blockSize: + type: integer + description: The size of the block. + example: 123 + sizeMedian: + type: integer + description: The median size of the block. + example: 79 + effectiveSizeMedian: + type: integer + description: The effective median size of the block. + example: 100000 + transactionsCumulativeSize: + type: integer + description: The cumulative size of transactions in the block. + example: 79 + alreadyGeneratedCoins: + type: string + description: The already generated coins. + example: "12073996950581" + alreadyGeneratedTransactions: + type: integer + description: The already generated transactions. + example: 12464 + baseReward: + type: integer + description: The base reward. + example: 6000000 + penalty: + type: number + description: The penalty. + example: 0.0 + totalFeeAmount: + type: integer + description: The total fee amount. + example: 0 + transactions: + type: array + items: + $ref: "#/components/schemas/TransactionShort" + + TransactionShort: + type: object + properties: + hash: + type: string + description: The hash of the transaction. + example: d1a55fc4ca4bdc80383d836a5e10e0218cd2ecfa4905f847101b7bdb11531493 + fee: + type: integer + description: The fee of the transaction. + example: 0 + amount_out: + type: integer + description: The amount out in the transaction. + example: 6000000 + size: + type: integer + description: The size of the transaction. + example: 79 diff --git a/docs/rpc/openapi/f_blocks_list_json.yaml b/docs/rpc/openapi/f_blocks_list_json.yaml new file mode 100644 index 000000000..beb923598 --- /dev/null +++ b/docs/rpc/openapi/f_blocks_list_json.yaml @@ -0,0 +1,307 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Blocks List + description: Retrieve the list of the 30 blocks preceding a given block height, and the block at the given height using JSON-RPC. + operationId: getBlocksList + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlocksListRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlocksListResponse" + +components: + schemas: + GetBlocksListRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["f_blocks_list_json"] + params: + $ref: "#/components/schemas/getBlocksListParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + getBlocksListParams: + type: object + properties: + height: + type: integer + description: The height of the block. + example: 12345 + + GetBlocksListResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetBlocksListResult" + id: + type: string + example: "1" + + GetBlocksListResult: + type: object + properties: + blocks: + type: array + items: + $ref: "#/components/schemas/BlockShort" + example: + - timestamp: 1633510598 + height: 12345 + difficulty: 74 + hash: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633510318 + height: 12344 + difficulty: 78 + hash: 09371a62201ba2393b2e250bc101e9e772e8bbab3b02ebddcdd3e35e5dd17c4c + tx_count: 1 + cumul_size: 123 + - timestamp: 1633510013 + height: 12343 + difficulty: 77 + hash: d61e4bab173f2d737156e4cb9b11755f71f300de9fa6076e134f43f15d14f6e0 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633509936 + height: 12342 + difficulty: 77 + hash: 66b916b3013b373b605f6b98539d15b962af2561d383ba2a48299b4151ec3e5b + tx_count: 1 + cumul_size: 123 + - timestamp: 1633509810 + height: 12341 + difficulty: 79 + hash: c2e3cc90f927898c49120513c3ca8f6423e526abae8f1aacfe5295a25d6a411d + tx_count: 1 + cumul_size: 123 + - timestamp: 1633509619 + height: 12340 + difficulty: 77 + hash: a2dd421ffb515ffcf647a0a875b2c82a3e5a47e6e40ac8de9fb58a6bcf18b38d + tx_count: 1 + cumul_size: 123 + - timestamp: 1633509605 + height: 12339 + difficulty: 78 + hash: d50ede088718dcb5c233fee4d21d01a6e673947fa794daf634e02f3c617981a7 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633509405 + height: 12338 + difficulty: 77 + hash: d17fb668c9e9434cd207b44af4b7de6840f5c356f36b6a3d61b22535bf0aaac3 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633509347 + height: 12337 + difficulty: 77 + hash: d42b8a4529297e7932a6b9bac70eb84c350955c77028d92280c5eca64cbfbdf5 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633509228 + height: 12336 + difficulty: 78 + hash: e75cc640981a1d1099f721f81962a78eda964708e3c240207140ad6f94f61935 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633509081 + height: 12335 + difficulty: 79 + hash: ed90940618bfdc63dd769260bed5c58bc5d04e5776b131c7c0c5442576fe3ad3 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633508878 + height: 12334 + difficulty: 79 + hash: e6c668531bdd470435f1b697867b8a03b215f85b708495917b5be93365afbd07 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633508815 + height: 12333 + difficulty: 76 + hash: dc38fd26025d9c4c54c37728be9766e11ebabaef99394bf01b80230b04f94775 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633508808 + height: 12332 + difficulty: 77 + hash: 3da2b11ee70eaaa99034f0dcebca8769d4d693e7f4022a2fbbf58f3ec25e6ff7 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633508703 + height: 12331 + difficulty: 79 + hash: 4331bdc9c4b8aa2228607c484d604fca8ca35bc5b671d0c7bda41876a9e9bf0d + tx_count: 1 + cumul_size: 123 + - timestamp: 1633508416 + height: 12330 + difficulty: 84 + hash: c28b448a3de849e16c3e45a145a5f56db4c26966b117e95dd4807b00ff83033d + tx_count: 1 + cumul_size: 123 + - timestamp: 1633508071 + height: 12329 + difficulty: 83 + hash: a91b363ef1d16648599732f5012ad30a7231be5a4332aeba38295516a9dfb608 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633507957 + height: 12328 + difficulty: 86 + hash: 4fdc4c7f29f212fbfff15cc8f054e5b48a0f2e74217cca1eb81de0e6cde45679 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633507761 + height: 12327 + difficulty: 86 + hash: d695c0c6b692c223f83af58f8ad0966a10467c982e4cd5acd46f43df8f8f14b6 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633507619 + height: 12326 + difficulty: 85 + hash: 9f1e241340ca746089032437e59899c215aabc0e2c36d0326a991d7e555567a2 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633507556 + height: 12325 + difficulty: 85 + hash: 2b0df5c7e0f321357aa1c86dea7f36359d4d4da611fa387cfe4d748697f465d1 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633507407 + height: 12324 + difficulty: 84 + hash: 9f1fba9cab2d67c03d18e9f184e4dd598b2b2bcc384d25836fb0b5e57ad387b2 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633507358 + height: 12323 + difficulty: 86 + hash: 623ae4899650e00733ba8a175843ab1af48f366d0776d7f501d674d76f6c8418 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633507186 + height: 12322 + difficulty: 86 + hash: b7079f58b17cc2680744b54051b28894c23fb981bbc563fe52d263dfc916863e + tx_count: 1 + cumul_size: 123 + - timestamp: 1633507039 + height: 12321 + difficulty: 86 + hash: 92de5201d785528d230a0903c9e3cd8d3be090c99091802879a81f094cbd37cd + tx_count: 1 + cumul_size: 123 + - timestamp: 1633506906 + height: 12320 + difficulty: 85 + hash: 86b2c086c048fefe7a0a2af887e1270834f9466371040a6b568c5b4da9fbe03f + tx_count: 1 + cumul_size: 123 + - timestamp: 1633506878 + height: 12319 + difficulty: 89 + hash: 609a7a544146d7045dde332aa319d46e330c4af26e4056065732ad29fafa2ed7 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633506550 + height: 12318 + difficulty: 88 + hash: 334e2a2517cb0940fecc2d404e4b5c0caae26c54790051dd1cb13dfac7b1c6e8 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633506499 + height: 12317 + difficulty: 86 + hash: b94010e3064c25a20468af4bffb76771b2e69e69159a6e805fd165ea53445308 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633506457 + height: 12316 + difficulty: 84 + hash: 4dab830162ff197b06d1750c2364e068eecdca275b37b8ba3cdb58b9200466b6 + tx_count: 1 + cumul_size: 123 + - timestamp: 1633506450 + height: 12315 + difficulty: 86 + hash: 8c4707306735750c41d66a2714a4027b9744fbf0a8658deb46800302f0d03c33 + tx_count: 1 + cumul_size: 123 + + status: + type: string + description: The status of the operation + example: OK + + BlockShort: + type: object + properties: + timestamp: + type: integer + description: The timestamp of the block. + example: 1633510598 + height: + type: integer + description: The height of the block. + example: 12345 + difficulty: + type: integer + description: The difficulty of the block. + example: 74 + hash: + type: string + description: The hash of the block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + tx_count: + type: integer + description: The number of transactions in the block. + example: 1 + cumul_size: + type: integer + description: The cumulative size of the block. + example: 123 diff --git a/docs/rpc/openapi/f_on_transactions_pool.yaml b/docs/rpc/openapi/f_on_transactions_pool.yaml new file mode 100644 index 000000000..40148f651 --- /dev/null +++ b/docs/rpc/openapi/f_on_transactions_pool.yaml @@ -0,0 +1,106 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Transactions from the Pool + description: Retrieve transactions from the transaction pool using JSON-RPC. + operationId: getTransactionsFromPool + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionsFromPoolRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionsFromPoolResponse" + +components: + schemas: + GetTransactionsFromPoolRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["f_on_transactions_pool_json"] + params: + $ref: "#/components/schemas/EmptyParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + EmptyParams: + type: object + additionalProperties: false + + GetTransactionsFromPoolResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetTransactionsFromPoolResult" + id: + type: string + example: "1" + + GetTransactionsFromPoolResult: + type: object + properties: + transactions: + type: array + items: + $ref: "#/components/schemas/TransactionShort" + status: + type: string + example: OK + + TransactionShort: + type: object + properties: + hash: + type: string + description: The hash of the transaction. + example: 030e1d9fb2a672c8ac99d0d684f7189221e2ae1143fe69e1524fdd3b0db8cbff + fee: + type: integer + description: The fee for the transaction. + example: 1000 + amount_out: + type: integer + description: The amount out for the transaction. + example: 6000000 + size: + type: integer + description: The size of the transaction. + example: 2170 diff --git a/docs/rpc/openapi/f_transaction_json.yaml b/docs/rpc/openapi/f_transaction_json.yaml new file mode 100644 index 000000000..222cbfaca --- /dev/null +++ b/docs/rpc/openapi/f_transaction_json.yaml @@ -0,0 +1,302 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Transaction + description: Retrieve transaction using JSON-RPC. + operationId: getTransaction + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionResponse" + +components: + schemas: + GetTransactionRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["f_transaction_json"] + params: + $ref: "#/components/schemas/GetTransactionParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + GetTransactionParams: + type: object + properties: + hash: + type: string + description: The hash of the transaction. + example: d1a55fc4ca4bdc80383d836a5e10e0218cd2ecfa4905f847101b7bdb11531493 + + GetTransactionResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetTransactionResult" + id: + type: string + example: "1" + + GetTransactionResult: + type: object + properties: + tx: + $ref: "#/components/schemas/Transaction" + txDetails: + $ref: "#/components/schemas/TransactionDetails" + block: + $ref: "#/components/schemas/BlockShort" + status: + type: string + description: The status of the operation + example: OK + + Transaction: + type: object + properties: + version: + type: integer + description: The version of the transaction. + example: 1 + unlock_time: + type: integer + description: The unlock time of the transaction. + example: 12345 + vin: + type: array + items: + $ref: "#/components/schemas/TransactionInput" + vout: + type: array + items: + $ref: "#/components/schemas/TransactionOutput" + extra: + type: string + example: 012b7c0e7d977e81fd2cbfa9b26d0ef7dd99da38d65ee18f856c52731358bd611d + "": + type: string + description: The transaction signature + example: 620a3ed1b6fdccfb694316a08609fc424f3c2af9cc44c1a02243c5c793c37300830f89a052ba3cfd2fd7d346dc7bd3d4e193a5c3f44b93524911dd5fa308b501 + + TransactionInput: + type: object + oneOf: + - $ref: "#/components/schemas/BaseInput" + - $ref: "#/components/schemas/KeyInput" + - $ref: "#/components/schemas/MultisignatureInput" + discriminator: + propertyName: type + mapping: + "ff": "#/components/schemas/BaseInput" + "02": "#/components/schemas/KeyInput" + "03": "#/components/schemas/MultisignatureInput" + + BaseInput: + type: object + properties: + type: + type: string + enum: ["ff"] + value: + type: object + properties: + height: + type: integer + description: The block index. + example: 12345 + + KeyInput: + type: object + properties: + type: + type: string + enum: ["02"] + value: + type: object + properties: + amount: + type: integer + description: The amount for the key input. + key_offsets: + type: array + items: + type: integer + description: The output indexes for the key input. + k_image: + type: object + description: The key image for the key input. + + MultisignatureInput: + type: object + properties: + type: + type: string + enum: ["03"] + value: + type: object + properties: + amount: + type: integer + description: The amount for the multisignature input. + signatures: + type: integer + description: The signature count for the multisignature input. + outputIndex: + type: integer + description: The output index for the multisignature input. + term: + type: integer + description: The term for the multisignature input. + + TransactionOutput: + type: object + properties: + amount: + type: integer + description: The amount for the transaction output. + example: 6000000 + target: + $ref: "#/components/schemas/TransactionOutputTarget" + + TransactionOutputTarget: + type: object + oneOf: + - $ref: "#/components/schemas/KeyOutput" + - $ref: "#/components/schemas/MultisignatureOutput" + discriminator: + propertyName: type + mapping: + "02": "#/components/schemas/KeyOutput" + "03": "#/components/schemas/MultisignatureOutput" + + KeyOutput: + type: object + properties: + type: + type: string + enum: ["02"] + data: + type: object + description: The public key for the key output. + properties: + key: + type: string + example: 477bddc9954a47aef3d3dc20a071e1955200fcc01a4cf43db7235eafc8da19b4 + + MultisignatureOutput: + type: object + properties: + type: + type: string + enum: ["03"] + data: + type: object + properties: + keys: + type: array + items: + type: string + description: The public keys for the multisignature output. + required_signatures: + type: integer + description: The required signature count for the multisignature output. + term: + type: integer + description: The term for the multisignature output. + + TransactionDetails: + type: object + properties: + hash: + type: string + description: The hash of the transaction. + example: d1a55fc4ca4bdc80383d836a5e10e0218cd2ecfa4905f847101b7bdb11531493 + size: + type: integer + description: The size of the transaction. + example: 79 + paymentId: + type: string + description: The payment ID of the transaction. + example: "" + mixin: + type: integer + description: The mixin of the transaction. + example: 0 + fee: + type: integer + description: The fee of the transaction. + example: 0 + amount_out: + type: integer + description: The amount out in the transaction. + example: 6000000 + + BlockShort: + type: object + properties: + timestamp: + type: integer + description: The timestamp of the block. + example: 1633510598 + height: + type: integer + description: The height of the block. + example: 12345 + difficulty: + type: integer + description: The difficulty of the block. + example: 74 + hash: + type: string + description: The hash of the block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + tx_count: + type: integer + description: The number of transactions in the block. + example: 1 + cumul_size: + type: integer + description: The cumulative size of the block. + example: 123 diff --git a/docs/rpc/openapi/getalblockslist.yaml b/docs/rpc/openapi/getalblockslist.yaml new file mode 100644 index 000000000..767da822c --- /dev/null +++ b/docs/rpc/openapi/getalblockslist.yaml @@ -0,0 +1,115 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Alternative Blocks List + description: Retrieve a list of alternative blocks using JSON-RPC. + operationId: getAltBlocksList + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetAltBlocksListRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetAltBlocksListResponse" + +components: + schemas: + GetAltBlocksListRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getaltblockslist"] + params: + $ref: "#/components/schemas/EmptyParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + EmptyParams: + type: object + additionalProperties: false + + GetAltBlocksListResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetAltBlocksListResult" + id: + type: string + example: "1" + + GetAltBlocksListResult: + type: object + properties: + alt_blocks: + type: array + items: + $ref: "#/components/schemas/BlockShort" + status: + type: string + description: The status of the operation + example: OK + + BlockShort: + type: object + properties: + timestamp: + type: integer + description: The timestamp of the block. + example: 1683611541 + height: + type: integer + description: The height of the block. + example: 428207 + hash: + type: string + description: The hash of the block. + example: c0a685377857a23ea789b796ffe1fce1eb8fa93fe3cf2b725a8a07a985785072 + transactions_count: + type: integer + description: The number of transactions in the block. + example: 1 + cumulative_size: + type: integer + description: The cumulative size of the block. + example: 44 + difficulty: + type: integer + description: The difficulty type of the block. + example: 341 diff --git a/docs/rpc/openapi/getblockbyheight.yaml b/docs/rpc/openapi/getblockbyheight.yaml new file mode 100644 index 000000000..b7450aed7 --- /dev/null +++ b/docs/rpc/openapi/getblockbyheight.yaml @@ -0,0 +1,200 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + - name: blockchain-indexes + description: Mandatory blockchain indexes + +paths: + /json_rpc: + post: + summary: Get Block by Height + description: Get block details by height using JSON-RPC. + operationId: getBlockByHeight + tags: ["JSON-RPC", "blockchain-indexes"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockByHeightRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockByHeightResponse" + +components: + schemas: + GetBlockByHeightRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getblockbyheight"] + params: + $ref: "#/components/schemas/GetBlockByHeightParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + GetBlockByHeightParams: + type: object + properties: + height: + type: integer + description: The block height to retrieve. + example: 12345 + + GetBlockByHeightResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetBlockByHeightResult" + id: + type: string + example: "1" + + GetBlockByHeightResult: + type: object + properties: + block: + $ref: "#/components/schemas/BlockDetails" + description: Block details for the specified height. + status: + type: string + description: The status of the operation + example: OK + + BlockDetails: + type: object + properties: + major_version: + type: integer + description: The major version of the block. + example: 8 + minor_version: + type: integer + description: The minor version of the block. + example: 0 + timestamp: + type: integer + description: The timestamp of the block. + example: 1633510598 + prev_hash: + type: string + description: The hash of the previous block. + example: 09371a62201ba2393b2e250bc101e9e772e8bbab3b02ebddcdd3e35e5dd17c4c + nonce: + type: integer + description: The nonce of the block. + example: 3425989702 + orphan_status: + type: boolean + description: Whether the block is an orphan. + example: false + height: + type: integer + description: The height of the block. + example: height + depth: + type: integer + description: The depth of the block. + example: 123456 + hash: + type: string + description: The hash of the block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + difficulty: + type: integer + description: The difficulty of the block. + example: 74 + reward: + type: integer + description: The reward of the block. + example: 6000000 + blockSize: + type: integer + description: The size of the block. + example: 123 + sizeMedian: + type: integer + description: The median size of the block. + example: 79 + effectiveSizeMedian: + type: integer + description: The effective median size of the block. + example: 100000 + transactionsCumulativeSize: + type: integer + description: The cumulative size of transactions in the block. + example: 79 + alreadyGeneratedCoins: + type: string + description: The already generated coins. + example: "12073996950581" + alreadyGeneratedTransactions: + type: integer + description: The already generated transactions. + example: 12464 + baseReward: + type: integer + description: The base reward. + example: 6000000 + penalty: + type: number + description: The penalty. + example: 0.0 + totalFeeAmount: + type: integer + description: The total fee amount. + example: 0 + transactions: + type: array + items: + $ref: "#/components/schemas/TransactionShort" + + TransactionShort: + type: object + properties: + hash: + type: string + description: The hash of the transaction. + example: d1a55fc4ca4bdc80383d836a5e10e0218cd2ecfa4905f847101b7bdb11531493 + fee: + type: integer + description: The fee of the transaction. + example: 0 + amount_out: + type: integer + description: The amount out in the transaction. + example: 6000000 + size: + type: integer + description: The size of the transaction. + example: 79 diff --git a/docs/rpc/openapi/getblockcount.yaml b/docs/rpc/openapi/getblockcount.yaml new file mode 100644 index 000000000..a37166cd4 --- /dev/null +++ b/docs/rpc/openapi/getblockcount.yaml @@ -0,0 +1,87 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Block Count + description: Get the current block count using JSON-RPC. + operationId: getBlockCount + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockCountRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockCountResponse" + +components: + schemas: + GetBlockCountRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getblockcount"] + params: + $ref: "#/components/schemas/EmptyParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + EmptyParams: + type: object + additionalProperties: false + + GetBlockCountResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetBlockCountResult" + id: + type: string + example: "1" + + GetBlockCountResult: + type: object + properties: + count: + type: integer + description: The current block count. + example: 12345 + status: + type: string + description: The status of the operation + example: OK diff --git a/docs/rpc/openapi/getblockhash.yaml b/docs/rpc/openapi/getblockhash.yaml new file mode 100644 index 000000000..b4c49912b --- /dev/null +++ b/docs/rpc/openapi/getblockhash.yaml @@ -0,0 +1,84 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Block Hash + description: Get the block hash using JSON-RPC. + operationId: getBlockHash + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockHashRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockHashResponse" + +components: + schemas: + GetBlockHashRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getblockhash", "on_getblockhash"] + params: + $ref: "#/components/schemas/GetBlockHashParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + GetBlockHashParams: + type: array + items: + type: integer + description: An array of block heights. + example: + - 12345 + + GetBlockHashResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetBlockHashResult" + id: + type: string + example: "1" + + GetBlockHashResult: + type: string + description: The block hash for the specified block height. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 diff --git a/docs/rpc/openapi/getblockheaderbyhash.yaml b/docs/rpc/openapi/getblockheaderbyhash.yaml new file mode 100644 index 000000000..1d01b8b5f --- /dev/null +++ b/docs/rpc/openapi/getblockheaderbyhash.yaml @@ -0,0 +1,141 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Block Header by Hash + description: Retrieve the block header by hash using JSON-RPC. + operationId: getBlockHeaderByHash + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockHeaderByHashRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockHeaderByHashResponse" + +components: + schemas: + GetBlockHeaderByHashRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getblockheaderbyhash"] + params: + $ref: "#/components/schemas/GetBlockHeaderByHashParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + GetBlockHeaderByHashParams: + type: object + properties: + hash: + type: string + description: The hash of the block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + + GetBlockHeaderByHashResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetBlockHeaderByHashResult" + id: + type: string + example: "1" + + GetBlockHeaderByHashResult: + type: object + properties: + block_header: + $ref: "#/components/schemas/BlockHeader" + status: + type: string + description: The status of the operation + example: OK + + BlockHeader: + type: object + properties: + major_version: + type: integer + description: The major version of the block. + example: 8 + minor_version: + type: integer + description: The minor version of the block. + example: 0 + timestamp: + type: integer + description: The timestamp of the block. + example: 1633510598 + prev_hash: + type: string + description: The hash of the previous block. + example: 09371a62201ba2393b2e250bc101e9e772e8bbab3b02ebddcdd3e35e5dd17c4c + nonce: + type: integer + description: The nonce of the block. + example: 3425989702 + orphan_status: + type: boolean + description: Whether the block is an orphan. + example: false + height: + type: integer + description: The height of the block. + example: 12345 + depth: + type: integer + description: The depth of the block. + example: 123456 + deposits: + type: integer + description: The deposits of the block. + example: 30000000 + hash: + type: string + description: The hash of the block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + difficulty: + type: integer + description: The difficulty of the block. + example: 74 + reward: + type: integer + description: The reward of the block. + example: 6000000 diff --git a/docs/rpc/openapi/getblockheaderbyheight.yaml b/docs/rpc/openapi/getblockheaderbyheight.yaml new file mode 100644 index 000000000..e0ded1467 --- /dev/null +++ b/docs/rpc/openapi/getblockheaderbyheight.yaml @@ -0,0 +1,141 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Block Header by Height + description: Retrieve the block header by height using JSON-RPC. + operationId: getBlockHeaderByHeight + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockHeaderByHeightRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockHeaderByHeightResponse" + +components: + schemas: + GetBlockHeaderByHeightRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getblockheaderbyheight"] + params: + $ref: "#/components/schemas/GetBlockHeaderByHeightParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + GetBlockHeaderByHeightParams: + type: object + properties: + height: + type: integer + description: The height of the block. + example: 12345 + + GetBlockHeaderByHeightResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetBlockHeaderByHeightResult" + id: + type: string + example: "1" + + GetBlockHeaderByHeightResult: + type: object + properties: + block_header: + $ref: "#/components/schemas/BlockHeader" + status: + type: string + description: The status of the operation + example: OK + + BlockHeader: + type: object + properties: + major_version: + type: integer + description: The major version of the block. + example: 8 + minor_version: + type: integer + description: The minor version of the block. + example: 0 + timestamp: + type: integer + description: The timestamp of the block. + example: 1633510598 + prev_hash: + type: string + description: The hash of the previous block. + example: 09371a62201ba2393b2e250bc101e9e772e8bbab3b02ebddcdd3e35e5dd17c4c + nonce: + type: integer + description: The nonce of the block. + example: 3425989702 + orphan_status: + type: boolean + description: Whether the block is an orphan. + example: false + height: + type: integer + description: The height of the block. + example: 12345 + depth: + type: integer + description: The depth of the block. + example: 123456 + deposits: + type: integer + description: The deposits of the block. + example: 30000000 + hash: + type: string + description: The hash of the block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + difficulty: + type: integer + description: The difficulty of the block. + example: 74 + reward: + type: integer + description: The reward of the block. + example: 6000000 diff --git a/docs/rpc/openapi/getblocktemplate.yaml b/docs/rpc/openapi/getblocktemplate.yaml new file mode 100644 index 000000000..a6e3a5945 --- /dev/null +++ b/docs/rpc/openapi/getblocktemplate.yaml @@ -0,0 +1,107 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Block Template + description: Get block template using JSON-RPC. + operationId: getBlockTemplate + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockTemplateRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockTemplateResponse" + +components: + schemas: + GetBlockTemplateRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getblocktemplate"] + params: + $ref: "#/components/schemas/GetBlockTemplateParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + GetBlockTemplateParams: + type: object + properties: + reserve_size: + type: integer + description: The reserve size (max 255 bytes). + example: 0 + wallet_address: + type: string + description: The wallet address. + example: ccx7WVMV8EEEQE7GcN9xME6zAK8ZonvqYgA3694nXk97ZsxUGmD5chx48ze9hrhZ4V81bQ7xMMHLkFbB9HtPEcqq3edGYYnahU + + GetBlockTemplateResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetBlockTemplateResult" + id: + type: string + example: "1" + + GetBlockTemplateResult: + type: object + properties: + difficulty: + type: integer + description: The difficulty for the block. + example: 252 + height: + type: integer + description: The height of the block. + example: 12346 + reserved_offset: + type: integer + description: The reserved offset. + example: 0 + blocktemplate_blob: + type: string + description: The block template blob. + example: 080099a58ca906061a5e877a9e84ea6e01772f86520005f3c04a6da967cdc6c785d5b19169d4a30000000001bfed2001ffb5ed2001809bee0202c068049f8cadf2da104eacf2a1f453521dfc4cc8b10ef29ee2105c362dcaae3b21014a6555f52174a84758e77b6aa92970df88d33c39ee2e2cb84cec6507a87cf84200 + status: + type: string + description: The status of the operation + example: OK diff --git a/docs/rpc/openapi/getblocktimestamp.yaml b/docs/rpc/openapi/getblocktimestamp.yaml new file mode 100644 index 000000000..dde8c7a30 --- /dev/null +++ b/docs/rpc/openapi/getblocktimestamp.yaml @@ -0,0 +1,91 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Block Timestamp by Height + description: Retrieve the timestamp of a block by height using JSON-RPC. + operationId: getBlockTimestampByHeight + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockTimestampByHeightRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetBlockTimestampByHeightResponse" + +components: + schemas: + GetBlockTimestampByHeightRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getblocktimestamp"] + params: + $ref: "#/components/schemas/GetBlockTimestampByHeightParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + GetBlockTimestampByHeightParams: + type: object + properties: + height: + type: integer + description: The height of the block. + example: 12345 + + GetBlockTimestampByHeightResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetBlockTimestampByHeightResult" + id: + type: string + example: "1" + + GetBlockTimestampByHeightResult: + type: object + properties: + timestamp: + type: integer + description: The timestamp of the block. + example: 1633510598 + status: + type: string + description: The status of the operation + example: OK diff --git a/docs/rpc/openapi/getcurrencyid.yaml b/docs/rpc/openapi/getcurrencyid.yaml new file mode 100644 index 000000000..943bc4841 --- /dev/null +++ b/docs/rpc/openapi/getcurrencyid.yaml @@ -0,0 +1,83 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Currency ID + description: Get currency ID using JSON-RPC. + operationId: getCurrencyId + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetCurrencyIdRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetCurrencyIdResponse" + +components: + schemas: + GetCurrencyIdRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getcurrencyid"] + params: + $ref: "#/components/schemas/EmptyParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + EmptyParams: + type: object + additionalProperties: false + + GetCurrencyIdResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetCurrencyIdResult" + id: + type: string + example: "1" + + GetCurrencyIdResult: + type: object + properties: + currency_id_blob: + type: string + description: The currency ID blob. + example: 850ac16022f4dddab624fad3f9049dba80592c8ea51a5dff19fefeb386e536b1 diff --git a/docs/rpc/openapi/getlastblockheader.yaml b/docs/rpc/openapi/getlastblockheader.yaml new file mode 100644 index 000000000..a334e615a --- /dev/null +++ b/docs/rpc/openapi/getlastblockheader.yaml @@ -0,0 +1,137 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Last Block Header + description: Retrieve the header of the last block using JSON-RPC. + operationId: getLastBlockHeader + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetLastBlockHeaderRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetLastBlockHeaderResponse" + +components: + schemas: + GetLastBlockHeaderRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getlastblockheader"] + params: + $ref: "#/components/schemas/EmptyParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + EmptyParams: + type: object + additionalProperties: false + + GetLastBlockHeaderResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetLastBlockHeaderResult" + id: + type: string + example: "1" + + GetLastBlockHeaderResult: + type: object + properties: + block_header: + $ref: "#/components/schemas/BlockHeader" + status: + type: string + description: The status of the operation + example: OK + + BlockHeader: + type: object + properties: + major_version: + type: integer + description: The major version of the block. + example: 8 + minor_version: + type: integer + description: The minor version of the block. + example: 0 + timestamp: + type: integer + description: The timestamp of the block. + example: 1633510598 + prev_hash: + type: string + description: The hash of the previous block. + example: 09371a62201ba2393b2e250bc101e9e772e8bbab3b02ebddcdd3e35e5dd17c4c + nonce: + type: integer + description: The nonce of the block. + example: 3425989702 + orphan_status: + type: boolean + description: Whether the block is an orphan. + example: false + height: + type: integer + description: The height of the block. + example: 12345 + depth: + type: integer + description: The depth of the block. + example: 123456 + deposits: + type: integer + description: The deposits of the block. + example: 30000000 + hash: + type: string + description: The hash of the block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + difficulty: + type: integer + description: The difficulty of the block. + example: 74 + reward: + type: integer + description: The reward of the block. + example: 6000000 diff --git a/docs/rpc/openapi/getrawtransactionpool.yaml b/docs/rpc/openapi/getrawtransactionpool.yaml new file mode 100644 index 000000000..213d8a2a5 --- /dev/null +++ b/docs/rpc/openapi/getrawtransactionpool.yaml @@ -0,0 +1,291 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Raw Transactions from Pool + description: Get raw transactions from the transaction pool using JSON-RPC. + operationId: getRawTransactionsPool + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetRawTransactionsPoolRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetRawTransactionsPoolResponse" + +components: + schemas: + GetRawTransactionsPoolRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getrawtransactionspool"] + params: + $ref: "#/components/schemas/EmptyParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + EmptyParams: + type: object + additionalProperties: false + + GetRawTransactionsPoolResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetRawTransactionsPoolResult" + id: + type: string + example: "1" + + GetRawTransactionsPoolResult: + type: object + properties: + transactions: + type: array + items: + $ref: "#/components/schemas/TxWithOutputGlobalIndexes" + description: List of raw transactions from the transaction pool. + status: + type: string + description: The status of the operation + example: OK + + TxWithOutputGlobalIndexes: + type: object + properties: + transaction: + $ref: "#/components/schemas/TransactionPrefix" + description: The transaction prefix. + hash: + type: string + description: The hash of the transaction. + example: 030e1d9fb2a672c8ac99d0d684f7189221e2ae1143fe69e1524fdd3b0db8cbff + block_hash: + type: string + description: The hash of the block containing the transaction. + example: "0000000000000000000000000000000000000000000000000000000000000000" + height: + type: integer + description: The height of the block containing the transaction. + example: 0 + fee: + type: integer + description: The fee of the transaction. + example: 1000 + timestamp: + type: integer + description: The timestamp of the transaction. + example: 1633510598 + output_indexes: + type: array + items: + type: integer + description: List of output indexes. + example: [] + + TransactionPrefix: + type: object + properties: + version: + type: integer + description: The version of the transaction. + example: 1 + unlock_time: + type: integer + description: The unlock time of the transaction. + example: 0 + vin: + type: array + items: + $ref: "#/components/schemas/TransactionInput" + description: The transaction inputs. + vout: + type: array + items: + $ref: "#/components/schemas/TransactionOutput" + description: The transaction outputs. + extra: + type: array + items: + type: integer + description: Additional transaction data. + example: 02210067c35be8114117cd58031e9115d9c7692e675950e60369d54f05ea0b1b7d1b8301b68ebe0733f70a44044676a9f75ed7deacf4df00a81ddd78dd22420a15d0675e + + TransactionInput: + type: object + oneOf: + - $ref: "#/components/schemas/BaseInput" + - $ref: "#/components/schemas/KeyInput" + - $ref: "#/components/schemas/MultisignatureInput" + discriminator: + propertyName: type + mapping: + "ff": "#/components/schemas/BaseInput" + "02": "#/components/schemas/KeyInput" + "03": "#/components/schemas/MultisignatureInput" + + BaseInput: + type: object + properties: + type: + type: string + enum: ["ff"] + value: + type: object + properties: + height: + type: integer + description: The block index. + + KeyInput: + type: object + properties: + type: + type: string + enum: ["02"] + value: + type: object + properties: + amount: + type: integer + description: The amount for the key input. + example: 6000000 + key_offsets: + type: array + items: + type: integer + description: The output indexes for the key input. + example: + - 8328 + - 15424 + - 155100 + - 65645 + - 2834 + - 46125 + k_image: + type: object + description: The key image for the key input. + example: b0de5d7bb9355f0796d2177dddedf10e1a2889f70692e7b2af33a4461bf23864 + + MultisignatureInput: + type: object + properties: + type: + type: string + enum: ["03"] + value: + type: object + properties: + amount: + type: integer + description: The amount for the multisignature input. + example: 5000000 + signatures: + type: integer + description: The signature count for the multisignature input. + example: 1 + outputIndex: + type: integer + description: The output index for the multisignature input. + example: 0 + term: + type: integer + description: The term for the multisignature input. + example: 21900 + + TransactionOutput: + type: object + properties: + amount: + type: integer + description: The amount for the transaction output. + example: 6000000 + target: + $ref: "#/components/schemas/TransactionOutputTarget" + + TransactionOutputTarget: + type: object + oneOf: + - $ref: "#/components/schemas/KeyOutput" + - $ref: "#/components/schemas/MultisignatureOutput" + discriminator: + propertyName: type + mapping: + "02": "#/components/schemas/KeyOutput" + "03": "#/components/schemas/MultisignatureOutput" + + KeyOutput: + type: object + properties: + type: + type: string + enum: ["02"] + data: + type: object + description: The public key for the key output. + properties: + key: + type: string + example: 477bddc9954a47aef3d3dc20a071e1955200fcc01a4cf43db7235eafc8da19b4 + + MultisignatureOutput: + type: object + properties: + type: + type: string + enum: ["03"] + data: + type: object + properties: + keys: + type: array + items: + type: string + description: The public keys for the multisignature output. + example: + - c9b8d92eb3aba2d3519741f2c5b314099e232d027dcbce10ba1d5d595b615b34 + required_signatures: + type: integer + description: The required signature count for the multisignature output. + example: 1 + term: + type: integer + description: The term for the multisignature output. + example: 21900 diff --git a/docs/rpc/openapi/getrawtransactionsbyheight.yaml b/docs/rpc/openapi/getrawtransactionsbyheight.yaml new file mode 100644 index 000000000..47b869c2d --- /dev/null +++ b/docs/rpc/openapi/getrawtransactionsbyheight.yaml @@ -0,0 +1,293 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Get Raw Transactions by Heights + description: Get raw transactions by block heights using JSON-RPC. + operationId: getRawTransactionsByHeights + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionsByHeightsRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionsByHeightsResponse" + +components: + schemas: + GetTransactionsByHeightsRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["getrawtransactionsbyheights"] + params: + $ref: "#/components/schemas/GetTransactionsByHeightsParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + GetTransactionsByHeightsParams: + type: object + properties: + heights: + type: array + items: + type: integer + description: List of block heights to retrieve transactions for. + example: + - 12345 + - 12355 + include_miner_txs: + type: boolean + description: Flag to include miner transactions. + example: true + range: + type: boolean + description: Flag to indicate if the heights are provided as a range. + example: false + + GetTransactionsByHeightsResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/GetTransactionsByHeightsResult" + id: + type: string + example: "1" + + GetTransactionsByHeightsResult: + type: object + properties: + transactions: + type: array + items: + $ref: "#/components/schemas/TxWithOutputGlobalIndexes" + description: List of raw transactions. + missed_txs: + type: array + items: + type: string + description: List of missed transactions. + example: [] + status: + type: string + description: The status of the operation + example: OK + + TxWithOutputGlobalIndexes: + type: object + properties: + transaction: + $ref: "#/components/schemas/TransactionPrefix" + description: The transaction prefix. + hash: + type: string + description: The hash of the transaction. + example: d1a55fc4ca4bdc80383d836a5e10e0218cd2ecfa4905f847101b7bdb11531493 + block_hash: + type: string + description: The hash of the block containing the transaction. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + height: + type: integer + description: The height of the block containing the transaction. + example: 12345 + fee: + type: integer + description: The fee of the transaction. + example: 0 + timestamp: + type: integer + description: The timestamp of the transaction. + example: 1633510598 + output_indexes: + type: array + items: + type: integer + description: List of output indexes. + example: + - 12269 + + TransactionPrefix: + type: object + properties: + version: + type: integer + description: The version of the transaction. + example: 1 + unlock_time: + type: integer + description: The unlock time of the transaction. + example: 12345 + vin: + type: array + items: + $ref: "#/components/schemas/TransactionInput" + vout: + type: array + items: + $ref: "#/components/schemas/TransactionOutput" + extra: + type: string + example: 012b7c0e7d977e81fd2cbfa9b26d0ef7dd99da38d65ee18f856c52731358bd611d + + TransactionInput: + type: object + oneOf: + - $ref: "#/components/schemas/BaseInput" + - $ref: "#/components/schemas/KeyInput" + - $ref: "#/components/schemas/MultisignatureInput" + discriminator: + propertyName: type + mapping: + "ff": "#/components/schemas/BaseInput" + "02": "#/components/schemas/KeyInput" + "03": "#/components/schemas/MultisignatureInput" + + BaseInput: + type: object + properties: + type: + type: string + enum: ["ff"] + value: + type: object + properties: + height: + type: integer + description: The block index. + example: 12345 + + KeyInput: + type: object + properties: + type: + type: string + enum: ["02"] + value: + type: object + properties: + amount: + type: integer + description: The amount for the key input. + key_offsets: + type: array + items: + type: integer + description: The output indexes for the key input. + k_image: + type: object + description: The key image for the key input. + + MultisignatureInput: + type: object + properties: + type: + type: string + enum: ["03"] + value: + type: object + properties: + amount: + type: integer + description: The amount for the multisignature input. + signatures: + type: integer + description: The signature count for the multisignature input. + outputIndex: + type: integer + description: The output index for the multisignature input. + term: + type: integer + description: The term for the multisignature input. + + TransactionOutput: + type: object + properties: + amount: + type: integer + description: The amount for the transaction output. + example: 6000000 + target: + $ref: "#/components/schemas/TransactionOutputTarget" + + TransactionOutputTarget: + type: object + oneOf: + - $ref: "#/components/schemas/KeyOutput" + - $ref: "#/components/schemas/MultisignatureOutput" + discriminator: + propertyName: type + mapping: + "02": "#/components/schemas/KeyOutput" + "03": "#/components/schemas/MultisignatureOutput" + + KeyOutput: + type: object + properties: + type: + type: string + enum: ["02"] + data: + type: object + description: The public key for the key output. + properties: + key: + type: string + example: 477bddc9954a47aef3d3dc20a071e1955200fcc01a4cf43db7235eafc8da19b4 + + MultisignatureOutput: + type: object + properties: + type: + type: string + enum: ["03"] + data: + type: object + properties: + keys: + type: array + items: + type: string + description: The public keys for the multisignature output. + required_signatures: + type: integer + description: The required signature count for the multisignature output. + term: + type: integer + description: The term for the multisignature output. diff --git a/docs/rpc/openapi/json_methods.yaml b/docs/rpc/openapi/json_methods.yaml new file mode 100644 index 000000000..5dbead30d --- /dev/null +++ b/docs/rpc/openapi/json_methods.yaml @@ -0,0 +1,664 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON + +paths: + /getinfo: + get: + summary: Get Info + description: Get information about the Conceal Core node. + operationId: getInfo + tags: ["JSON"] + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetInfoResponse" + + /getheight: + get: + summary: Get Height + description: Get the current blockchain height. + operationId: getHeight + tags: ["JSON"] + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetHeightResponse" + + /feeaddress: + get: + summary: Get Fee Address + description: Get the fee address for transactions. + operationId: getFeeAddress + tags: ["JSON"] + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetFeeAddressResponse" + + /peers: + get: + summary: Get Peers + description: Get the list of peers. + operationId: getPeers + tags: ["JSON"] + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetPeersResponse" + + /getpeers: + get: + summary: Get Peers + description: Get the list of peers. + operationId: getPeersAlt + tags: ["JSON"] + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetPeersResponse" + + /getrawtransactionspool: + get: + summary: Get Raw Transactions Pool + description: Get the raw transactions from the transaction pool. + operationId: getRawTransactionsPool + tags: ["JSON"] + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetRawTransactionsPoolResult" + + /getrandom_outs: + post: + summary: Get Random Outputs for Amounts + description: Get random outputs for specified amounts. + operationId: getRandomOutputs + tags: ["JSON"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetRandomOutputsRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetRandomOutputsResponse" + + /gettransactions: + post: + summary: Get Transactions + description: Get transactions by their hashes. + operationId: getTransactions + tags: ["JSON"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionsRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionsResponse" + + /get_raw_transactions_by_heights: + post: + summary: Get Transactions by Heights + description: Get transactions for specified heights. + operationId: getTransactionsByHeights + tags: ["JSON"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionsByHeightsParams" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/GetTransactionsByHeightsResult" + + /sendrawtransaction: + post: + summary: Send Raw Transaction + description: Send a raw transaction in hex format. + operationId: sendRawTransaction + tags: ["JSON"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/SendRawTransactionRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/SendRawTransactionResponse" + +components: + schemas: + GetInfoResponse: + type: object + properties: + status: + type: string + description: The status of the operation + example: OK + version: + type: string + description: The version of Conceal Core. + example: "6.7.2" + fee_address: + type: string + description: The fee address. + example: ccx7WVMV8EEEQE7GcN9xME6zAK8ZonvqYgA3694nXk97ZsxUGmD5chx48ze9hrhZ4V81bQ7xMMHLkFbB9HtPEcqq3edGYYnahU + top_block_hash: + type: string + description: The hash of the top block. + example: 20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44 + height: + type: integer + description: The current block height. + example: 12346 + difficulty: + type: integer + description: The current difficulty. + example: 74 + tx_count: + type: integer + description: The total number of transactions. + example: 7890 + tx_pool_size: + type: integer + description: The size of the transaction pool. + example: 2 + alt_blocks_count: + type: integer + description: The number of alternative blocks. + example: 2 + outgoing_connections_count: + type: integer + description: The number of outgoing connections. + example: 2 + incoming_connections_count: + type: integer + description: The number of incoming connections. + example: 2 + white_peerlist_size: + type: integer + description: The size of the white peerlist. + example: 100 + grey_peerlist_size: + type: integer + description: The size of the grey peerlist. + example: 50 + block_major_version: + type: integer + description: The major version of the current block. + example: 8 + block_minor_version: + type: integer + description: The minor version of the current block. + example: 0 + last_known_block_index: + type: integer + description: The last known block index. + example: 12345 + full_deposit_amount: + type: integer + description: The full deposit amount. + example: 1000000 + last_block_reward: + type: integer + description: The reward for the last block. + example: 6000000 + last_block_timestamp: + type: integer + description: The timestamp of the last block. + example: 1633816200 + last_block_difficulty: + type: integer + description: The difficulty of the last block. + example: 71 + connections: + type: array + items: + type: string + description: List of connections. + example: + - "1.2.3.4" + - "5.6.7.8" + + GetHeightResponse: + type: object + properties: + height: + type: integer + description: The current blockchain height. + example: 12345 + status: + type: string + description: The status of the operation + example: OK + + GetFeeAddressResponse: + type: object + properties: + fee_address: + type: string + description: The fee address. + example: ccx7WVMV8EEEQE7GcN9xME6zAK8ZonvqYgA3694nXk97ZsxUGmD5chx48ze9hrhZ4V81bQ7xMMHLkFbB9HtPEcqq3edGYYnahU + status: + type: string + description: The status of the operation + example: OK + + GetPeersResponse: + type: object + properties: + peers: + type: array + items: + type: string + description: List of peers. + example: + - "1.2.3.4:5678" + - "9.8.7.6:5432" + status: + type: string + description: The status of the operation + example: OK + + GetRawTransactionsPoolResult: + type: object + properties: + transactions: + type: array + items: + $ref: "#/components/schemas/TxWithOutputGlobalIndexes" + description: List of raw transactions from the transaction pool. + status: + type: string + description: The status of the operation + example: OK + + TxWithOutputGlobalIndexes: + type: object + properties: + transaction: + $ref: "#/components/schemas/TransactionPrefix" + hash: + type: string + description: The hash of the transaction. + example: 030e1d9fb2a672c8ac99d0d684f7189221e2ae1143fe69e1524fdd3b0db8cbff + block_hash: + type: string + description: The hash of the block containing the transaction. + example: "0000000000000000000000000000000000000000000000000000000000000000" + height: + type: integer + description: The height of the block containing the transaction. + example: 0 + fee: + type: integer + description: The fee of the transaction. + example: 1000 + timestamp: + type: integer + description: The timestamp of the transaction. + example: 1633510598 + output_indexes: + type: array + items: + type: integer + description: List of output indexes. + example: [] + + TransactionPrefix: + type: object + properties: + version: + type: integer + description: The version of the transaction. + example: 1 + unlock_time: + type: integer + description: The unlock time of the transaction. + example: 0 + vin: + type: array + items: + $ref: "#/components/schemas/TransactionInput" + description: The transaction inputs. + vout: + type: array + items: + $ref: "#/components/schemas/TransactionOutput" + description: The transaction outputs. + extra: + type: string + description: Additional transaction data. + example: 02210067c35be8114117cd58031e9115d9c7692e675950e60369d54f05ea0b1b7d1b8301b68ebe0733f70a44044676a9f75ed7deacf4df00a81ddd78dd22420a15d0675e + + TransactionInput: + type: object + oneOf: + - $ref: "#/components/schemas/BaseInput" + - $ref: "#/components/schemas/KeyInput" + - $ref: "#/components/schemas/MultisignatureInput" + discriminator: + propertyName: type + mapping: + "ff": "#/components/schemas/BaseInput" + "02": "#/components/schemas/KeyInput" + "03": "#/components/schemas/MultisignatureInput" + + BaseInput: + type: object + properties: + type: + type: string + enum: ["ff"] + value: + type: object + properties: + height: + type: integer + description: The block index. + + KeyInput: + type: object + properties: + type: + type: string + enum: ["02"] + value: + type: object + properties: + amount: + type: integer + description: The amount for the key input. + example: 6000000 + key_offsets: + type: array + items: + type: integer + description: The output indexes for the key input. + example: + - 8328 + - 15424 + - 155100 + - 65645 + - 2834 + - 46125 + k_image: + type: object + description: The key image for the key input. + example: b0de5d7bb9355f0796d2177dddedf10e1a2889f70692e7b2af33a4461bf23864 + + MultisignatureInput: + type: object + properties: + type: + type: string + enum: ["03"] + value: + type: object + properties: + amount: + type: integer + description: The amount for the multisignature input. + example: 5000000 + signatures: + type: integer + description: The signature count for the multisignature input. + example: 1 + outputIndex: + type: integer + description: The output index for the multisignature input. + example: 0 + term: + type: integer + description: The term for the multisignature input. + example: 21900 + + TransactionOutput: + type: object + properties: + amount: + type: integer + description: The amount for the transaction output. + example: 6000000 + target: + $ref: "#/components/schemas/TransactionOutputTarget" + + TransactionOutputTarget: + type: object + oneOf: + - $ref: "#/components/schemas/KeyOutput" + - $ref: "#/components/schemas/MultisignatureOutput" + discriminator: + propertyName: type + mapping: + "02": "#/components/schemas/KeyOutput" + "03": "#/components/schemas/MultisignatureOutput" + + KeyOutput: + type: object + properties: + type: + type: string + enum: ["02"] + data: + type: object + description: The public key for the key output. + properties: + key: + type: string + example: 477bddc9954a47aef3d3dc20a071e1955200fcc01a4cf43db7235eafc8da19b4 + + MultisignatureOutput: + type: object + properties: + type: + type: string + enum: ["03"] + data: + type: object + properties: + keys: + type: array + items: + type: string + description: The public keys for the multisignature output. + example: + - c9b8d92eb3aba2d3519741f2c5b314099e232d027dcbce10ba1d5d595b615b34 + required_signatures: + type: integer + description: The required signature count for the multisignature output. + example: 1 + term: + type: integer + description: The term for the multisignature output. + example: 21900 + + GetRandomOutputsRequest: + type: object + properties: + amounts: + type: array + items: + type: integer + description: List of amounts for which to get random outputs. + example: + - 6000000 + outs_count: + type: integer + description: Number of random outputs to retrieve. + example: 5 + + GetRandomOutputsResponse: + type: object + properties: + outs: + type: array + items: + $ref: "#/components/schemas/RandomOutputsForAmount" + description: Random outputs for specified amounts. + status: + type: string + description: The status of the operation + example: OK + + RandomOutputsForAmount: + type: object + properties: + amount: + type: integer + description: The amount for which random outputs are provided. + example: 6000000 + outs: + type: array + items: + $ref: "#/components/schemas/RandomOutputEntry" + description: Random output entries for the specified amount. + + RandomOutputEntry: + type: object + properties: + global_index: + type: integer + description: Global amount index. + example: 8267 + public_key: + type: string + description: Public key for the output. + example: 3b99ff1afd669f63fd086610fc720fea80c0a507e70eca1a3157acc0ac9fde54 + + GetTransactionsRequest: + type: object + properties: + txs_hashes: + type: array + items: + type: string + description: List of transaction hashes to retrieve. + example: + - d1a55fc4ca4bdc80383d836a5e10e0218cd2ecfa4905f847101b7bdb11531493 + + GetTransactionsResponse: + type: object + properties: + txs_as_hex: + type: array + items: + type: string + description: Transactions blobs as hex. + example: + - 01c36001ffb96001809bee0202477bddc9954a47aef3d3dc20a071e1955200fcc01a4cf43db7235eafc8da19b421012b7c0e7d977e81fd2cbfa9b26d0ef7dd99da38d65ee18f856c52731358bd611d + missed_tx: + type: array + items: + type: string + description: Not found transactions. + example: [] + status: + type: string + description: The status of the operation + example: OK + + GetTransactionsByHeightsParams: + type: object + properties: + heights: + type: array + items: + type: integer + description: List of block heights to retrieve transactions for. + example: + - 12345 + - 12355 + include_miner_txs: + type: boolean + description: Flag to include miner transactions. + example: true + range: + type: boolean + description: Flag to indicate if the heights are provided as a range. + example: false + + GetTransactionsByHeightsResult: + type: object + properties: + transactions: + type: array + items: + $ref: "#/components/schemas/TxWithOutputGlobalIndexes" + description: List of raw transactions. + missed_txs: + type: array + items: + type: string + description: List of missed transactions. + example: [] + status: + type: string + description: The status of the operation + example: OK + + SendRawTransactionRequest: + type: object + properties: + tx_as_hex: + type: string + description: Raw transaction in hex format. + + SendRawTransactionResponse: + type: object + properties: + status: + type: string + description: The status of the operation + example: OK diff --git a/docs/rpc/openapi/submitblock.yaml b/docs/rpc/openapi/submitblock.yaml new file mode 100644 index 000000000..d18439050 --- /dev/null +++ b/docs/rpc/openapi/submitblock.yaml @@ -0,0 +1,83 @@ +openapi: 3.0.0 +info: + title: Conceal Core API Documentation + version: "6.7.2" + description: API documentation for Conceal Core + contact: + name: Conceal Help Desk + url: https://conceal.network/support + +servers: + - url: "http://localhost:16000" + description: Mainnet local node + - url: "http://localhost:16600" + description: Testnet local node + +tags: + - name: JSON-RPC + +paths: + /json_rpc: + post: + summary: Submit Block + description: Submit a new block using JSON-RPC. + operationId: submitBlock + tags: ["JSON-RPC"] + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/SubmitBlockRequest" + responses: + "200": + description: Successful response. + content: + application/json: + schema: + $ref: "#/components/schemas/SubmitBlockResponse" + +components: + schemas: + SubmitBlockRequest: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + method: + type: string + enum: ["submitblock"] + params: + $ref: "#/components/schemas/SubmitBlockParams" + id: + type: string + example: "1" + required: + - jsonrpc + - method + - params + - id + + SubmitBlockParams: + type: string + description: The block data. + + SubmitBlockResponse: + type: object + properties: + jsonrpc: + type: string + enum: ["2.0"] + result: + $ref: "#/components/schemas/SubmitBlockResult" + id: + type: string + example: "1" + + SubmitBlockResult: + type: object + properties: + status: + type: string + description: The status of the operation + example: OK From 74d400c42093e90564303d9721da183935d1ac45 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 22 Oct 2023 13:56:11 +0200 Subject: [PATCH 22/30] Add Redoc documentation --- docs/build_docs.bash | 55 +++ docs/rpc/check_reserve_proof.html | 380 +++++++++++++++++++ docs/rpc/check_tx_proof.html | 380 +++++++++++++++++++ docs/rpc/f_block_json.html | 392 +++++++++++++++++++ docs/rpc/f_blocks_list_json.html | 380 +++++++++++++++++++ docs/rpc/f_on_transactions_pool.html | 380 +++++++++++++++++++ docs/rpc/f_transaction_json.html | 380 +++++++++++++++++++ docs/rpc/getalblockslist.html | 380 +++++++++++++++++++ docs/rpc/getblockbyheight.html | 392 +++++++++++++++++++ docs/rpc/getblockcount.html | 380 +++++++++++++++++++ docs/rpc/getblockhash.html | 376 +++++++++++++++++++ docs/rpc/getblockheaderbyhash.html | 380 +++++++++++++++++++ docs/rpc/getblockheaderbyheight.html | 380 +++++++++++++++++++ docs/rpc/getblocktemplate.html | 380 +++++++++++++++++++ docs/rpc/getblocktimestamp.html | 380 +++++++++++++++++++ docs/rpc/getcurrencyid.html | 380 +++++++++++++++++++ docs/rpc/getlastblockheader.html | 380 +++++++++++++++++++ docs/rpc/getrawtransactionpool.html | 380 +++++++++++++++++++ docs/rpc/getrawtransactionsbyheight.html | 380 +++++++++++++++++++ docs/rpc/json_methods.html | 454 +++++++++++++++++++++++ docs/rpc/submitblock.html | 376 +++++++++++++++++++ 21 files changed, 7745 insertions(+) create mode 100644 docs/build_docs.bash create mode 100644 docs/rpc/check_reserve_proof.html create mode 100644 docs/rpc/check_tx_proof.html create mode 100644 docs/rpc/f_block_json.html create mode 100644 docs/rpc/f_blocks_list_json.html create mode 100644 docs/rpc/f_on_transactions_pool.html create mode 100644 docs/rpc/f_transaction_json.html create mode 100644 docs/rpc/getalblockslist.html create mode 100644 docs/rpc/getblockbyheight.html create mode 100644 docs/rpc/getblockcount.html create mode 100644 docs/rpc/getblockhash.html create mode 100644 docs/rpc/getblockheaderbyhash.html create mode 100644 docs/rpc/getblockheaderbyheight.html create mode 100644 docs/rpc/getblocktemplate.html create mode 100644 docs/rpc/getblocktimestamp.html create mode 100644 docs/rpc/getcurrencyid.html create mode 100644 docs/rpc/getlastblockheader.html create mode 100644 docs/rpc/getrawtransactionpool.html create mode 100644 docs/rpc/getrawtransactionsbyheight.html create mode 100644 docs/rpc/json_methods.html create mode 100644 docs/rpc/submitblock.html diff --git a/docs/build_docs.bash b/docs/build_docs.bash new file mode 100644 index 000000000..16392e605 --- /dev/null +++ b/docs/build_docs.bash @@ -0,0 +1,55 @@ +#!/bin/bash + +input_folder="" +output_folder="" + +display_help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " -i, --input INPUT_FOLDER Specify the input folder (default: chatgpt)" + echo " -o, --output OUTPUT_FOLDER Specify the output folder (default: docs)" + echo " -h, --help Display this help message" + exit 0 +} + +if [ $# -ne 4 ]; then + display_help +fi + +# Parse command-line arguments +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -i) + input_folder="$2" + shift + shift + ;; + -o) + output_folder="$2" + shift + shift + ;; + *) + display_help + ;; + esac +done + +if [ -z "$input_folder" ] || [ -z "$output_folder" ]; then + display_help +fi + +if [ ! -d "$input_folder" ]; then + echo "Input folder '$input_folder' does not exist." + exit 1 +fi + +mkdir -p "$output_folder" + +for yaml_file in "$input_folder"/*.yaml; do + if [[ -f "$yaml_file" ]]; then + filename=$(basename "$yaml_file" .yaml) + redocly build-docs "$yaml_file" -o "$output_folder/$filename.html" + fi +done diff --git a/docs/rpc/check_reserve_proof.html b/docs/rpc/check_reserve_proof.html new file mode 100644 index 000000000..ea9648a8e --- /dev/null +++ b/docs/rpc/check_reserve_proof.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Check Reserve Proof

Check the reserve proof using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "check_reserve_proof"
required
object (CheckReserveProofParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "check_reserve_proof",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/check_tx_proof.html b/docs/rpc/check_tx_proof.html new file mode 100644 index 000000000..a3d97a6c7 --- /dev/null +++ b/docs/rpc/check_tx_proof.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Check Transaction Proof

Check the transaction proof using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "check_tx_proof"
required
object (CheckTxProofParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "check_tx_proof",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/f_block_json.html b/docs/rpc/f_block_json.html new file mode 100644 index 000000000..cf9a33461 --- /dev/null +++ b/docs/rpc/f_block_json.html @@ -0,0 +1,392 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Block Details

Retrieve details of a block using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "f_block_json"
required
object (GetBlockParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "f_block_json",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}

blockchain-indexes

Mandatory blockchain indexes

+

Get Block Details

Retrieve details of a block using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "f_block_json"
required
object (GetBlockParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "f_block_json",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/f_blocks_list_json.html b/docs/rpc/f_blocks_list_json.html new file mode 100644 index 000000000..25e5b3e3c --- /dev/null +++ b/docs/rpc/f_blocks_list_json.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Blocks List

Retrieve the list of the 30 blocks preceding a given block height, and the block at the given height using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "f_blocks_list_json"
required
object (getBlocksListParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "f_blocks_list_json",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/f_on_transactions_pool.html b/docs/rpc/f_on_transactions_pool.html new file mode 100644 index 000000000..0512e5e72 --- /dev/null +++ b/docs/rpc/f_on_transactions_pool.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Transactions from the Pool

Retrieve transactions from the transaction pool using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "f_on_transactions_pool_json"
required
object (EmptyParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "f_on_transactions_pool_json",
  • "params": { },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/f_transaction_json.html b/docs/rpc/f_transaction_json.html new file mode 100644 index 000000000..30594f416 --- /dev/null +++ b/docs/rpc/f_transaction_json.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Transaction

Retrieve transaction using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "f_transaction_json"
required
object (GetTransactionParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "f_transaction_json",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getalblockslist.html b/docs/rpc/getalblockslist.html new file mode 100644 index 000000000..9427e7a98 --- /dev/null +++ b/docs/rpc/getalblockslist.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Alternative Blocks List

Retrieve a list of alternative blocks using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getaltblockslist"
required
object (EmptyParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getaltblockslist",
  • "params": { },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getblockbyheight.html b/docs/rpc/getblockbyheight.html new file mode 100644 index 000000000..376464824 --- /dev/null +++ b/docs/rpc/getblockbyheight.html @@ -0,0 +1,392 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Block by Height

Get block details by height using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getblockbyheight"
required
object (GetBlockByHeightParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getblockbyheight",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}

blockchain-indexes

Mandatory blockchain indexes

+

Get Block by Height

Get block details by height using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getblockbyheight"
required
object (GetBlockByHeightParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getblockbyheight",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getblockcount.html b/docs/rpc/getblockcount.html new file mode 100644 index 000000000..ccdfd6eea --- /dev/null +++ b/docs/rpc/getblockcount.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Block Count

Get the current block count using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getblockcount"
required
object (EmptyParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getblockcount",
  • "params": { },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getblockhash.html b/docs/rpc/getblockhash.html new file mode 100644 index 000000000..338bee17f --- /dev/null +++ b/docs/rpc/getblockhash.html @@ -0,0 +1,376 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Block Hash

Get the block hash using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Enum: "getblockhash" "on_getblockhash"
params
required
Array of integers (GetBlockHashParams)

An array of block heights.

+
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getblockhash",
  • "params": [
    ],
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": "20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44",
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getblockheaderbyhash.html b/docs/rpc/getblockheaderbyhash.html new file mode 100644 index 000000000..9873119b0 --- /dev/null +++ b/docs/rpc/getblockheaderbyhash.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Block Header by Hash

Retrieve the block header by hash using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getblockheaderbyhash"
required
object (GetBlockHeaderByHashParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getblockheaderbyhash",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getblockheaderbyheight.html b/docs/rpc/getblockheaderbyheight.html new file mode 100644 index 000000000..f95652760 --- /dev/null +++ b/docs/rpc/getblockheaderbyheight.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Block Header by Height

Retrieve the block header by height using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getblockheaderbyheight"
required
object (GetBlockHeaderByHeightParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getblockheaderbyheight",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getblocktemplate.html b/docs/rpc/getblocktemplate.html new file mode 100644 index 000000000..a81071abf --- /dev/null +++ b/docs/rpc/getblocktemplate.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Block Template

Get block template using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getblocktemplate"
required
object (GetBlockTemplateParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getblocktemplate",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getblocktimestamp.html b/docs/rpc/getblocktimestamp.html new file mode 100644 index 000000000..ba92a6215 --- /dev/null +++ b/docs/rpc/getblocktimestamp.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Block Timestamp by Height

Retrieve the timestamp of a block by height using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getblocktimestamp"
required
object (GetBlockTimestampByHeightParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getblocktimestamp",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getcurrencyid.html b/docs/rpc/getcurrencyid.html new file mode 100644 index 000000000..c80d9fdc3 --- /dev/null +++ b/docs/rpc/getcurrencyid.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Currency ID

Get currency ID using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getcurrencyid"
required
object (EmptyParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getcurrencyid",
  • "params": { },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getlastblockheader.html b/docs/rpc/getlastblockheader.html new file mode 100644 index 000000000..316051a96 --- /dev/null +++ b/docs/rpc/getlastblockheader.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Last Block Header

Retrieve the header of the last block using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getlastblockheader"
required
object (EmptyParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getlastblockheader",
  • "params": { },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getrawtransactionpool.html b/docs/rpc/getrawtransactionpool.html new file mode 100644 index 000000000..8c727f7a4 --- /dev/null +++ b/docs/rpc/getrawtransactionpool.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Raw Transactions from Pool

Get raw transactions from the transaction pool using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getrawtransactionspool"
required
object (EmptyParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getrawtransactionspool",
  • "params": { },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/getrawtransactionsbyheight.html b/docs/rpc/getrawtransactionsbyheight.html new file mode 100644 index 000000000..14e3c2c19 --- /dev/null +++ b/docs/rpc/getrawtransactionsbyheight.html @@ -0,0 +1,380 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Get Raw Transactions by Heights

Get raw transactions by block heights using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "getrawtransactionsbyheights"
required
object (GetTransactionsByHeightsParams)
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "getrawtransactionsbyheights",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + diff --git a/docs/rpc/json_methods.html b/docs/rpc/json_methods.html new file mode 100644 index 000000000..6e5b52e39 --- /dev/null +++ b/docs/rpc/json_methods.html @@ -0,0 +1,454 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON

Get Info

Get information about the Conceal Core node.

+

Responses

Response samples

Content type
application/json
{
  • "status": "OK",
  • "version": "6.7.2",
  • "fee_address": "ccx7WVMV8EEEQE7GcN9xME6zAK8ZonvqYgA3694nXk97ZsxUGmD5chx48ze9hrhZ4V81bQ7xMMHLkFbB9HtPEcqq3edGYYnahU",
  • "top_block_hash": "20e93738606e150ea3f2dd30b4b60fd9af2db05b6aecdd1201159a4e50455d44",
  • "height": 12346,
  • "difficulty": 74,
  • "tx_count": 7890,
  • "tx_pool_size": 2,
  • "alt_blocks_count": 2,
  • "outgoing_connections_count": 2,
  • "incoming_connections_count": 2,
  • "white_peerlist_size": 100,
  • "grey_peerlist_size": 50,
  • "block_major_version": 8,
  • "block_minor_version": 0,
  • "last_known_block_index": 12345,
  • "full_deposit_amount": 1000000,
  • "last_block_reward": 6000000,
  • "last_block_timestamp": 1633816200,
  • "last_block_difficulty": 71,
  • "connections": [
    ]
}

Get Height

Get the current blockchain height.

+

Responses

Response samples

Content type
application/json
{
  • "height": 12345,
  • "status": "OK"
}

Get Fee Address

Get the fee address for transactions.

+

Responses

Response samples

Content type
application/json
{
  • "fee_address": "ccx7WVMV8EEEQE7GcN9xME6zAK8ZonvqYgA3694nXk97ZsxUGmD5chx48ze9hrhZ4V81bQ7xMMHLkFbB9HtPEcqq3edGYYnahU",
  • "status": "OK"
}

Get Peers

Get the list of peers.

+

Responses

Response samples

Content type
application/json
{
  • "peers": [
    ],
  • "status": "OK"
}

Get Peers

Get the list of peers.

+

Responses

Response samples

Content type
application/json
{
  • "peers": [
    ],
  • "status": "OK"
}

Get Raw Transactions Pool

Get the raw transactions from the transaction pool.

+

Responses

Response samples

Content type
application/json
{
  • "transactions": [
    ],
  • "status": "OK"
}

Get Random Outputs for Amounts

Get random outputs for specified amounts.

+
Request Body schema: application/json
amounts
Array of integers

List of amounts for which to get random outputs.

+
outs_count
integer

Number of random outputs to retrieve.

+

Responses

Request samples

Content type
application/json
{
  • "amounts": [
    ],
  • "outs_count": 5
}

Response samples

Content type
application/json
{
  • "outs": [
    ],
  • "status": "OK"
}

Get Transactions

Get transactions by their hashes.

+
Request Body schema: application/json
txs_hashes
Array of strings

List of transaction hashes to retrieve.

+

Responses

Request samples

Content type
application/json
{
  • "txs_hashes": [
    ]
}

Response samples

Content type
application/json
{
  • "txs_as_hex": [
    ],
  • "missed_tx": [ ],
  • "status": "OK"
}

Get Transactions by Heights

Get transactions for specified heights.

+
Request Body schema: application/json
heights
Array of integers

List of block heights to retrieve transactions for.

+
include_miner_txs
boolean

Flag to include miner transactions.

+
range
boolean

Flag to indicate if the heights are provided as a range.

+

Responses

Request samples

Content type
application/json
{
  • "heights": [
    ],
  • "include_miner_txs": true,
  • "range": false
}

Response samples

Content type
application/json
{
  • "transactions": [
    ],
  • "missed_txs": [ ],
  • "status": "OK"
}

Send Raw Transaction

Send a raw transaction in hex format.

+
Request Body schema: application/json
tx_as_hex
string

Raw transaction in hex format.

+

Responses

Request samples

Content type
application/json
{
  • "tx_as_hex": "string"
}

Response samples

Content type
application/json
{
  • "status": "OK"
}
+ + + + diff --git a/docs/rpc/submitblock.html b/docs/rpc/submitblock.html new file mode 100644 index 000000000..d1e8df92d --- /dev/null +++ b/docs/rpc/submitblock.html @@ -0,0 +1,376 @@ + + + + + + Conceal Core API Documentation + + + + + + + + + +

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

API documentation for Conceal Core

+

JSON-RPC

Submit Block

Submit a new block using JSON-RPC.

+
Request Body schema: application/json
jsonrpc
required
string
Value: "2.0"
method
required
string
Value: "submitblock"
params
required
string (SubmitBlockParams)

The block data.

+
id
required
string

Responses

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "submitblock",
  • "params": "string",
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}
+ + + + From 8e2b0f68b2d2dcdd9cf08ad602bdc3328468cd55 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 22 Oct 2023 14:13:16 +0200 Subject: [PATCH 23/30] Update checkpoints --- src/CryptoNoteConfig.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/CryptoNoteConfig.h b/src/CryptoNoteConfig.h index 032f0e91e..0bbd7b9b9 100644 --- a/src/CryptoNoteConfig.h +++ b/src/CryptoNoteConfig.h @@ -365,7 +365,16 @@ namespace cn {1280000, "544b164dfc4e19221e23e427fe821c812dda2a41fe5eee1915065f99a3c707d2"}, {1290000, "7844314fdd7e70ed38def90377339e249108e328bb94820f070c6aa2a787abf9"}, {1300000, "68e1ce32210bc1cd41ea26e64382f39c5302bf251273cc6fd35d80a3c19df815"}, - {1310000, "64aab7bbc148131f11479e74bbbd74c67e6ee45312bd6e72f5b68d5d1d383e46"} + {1310000, "64aab7bbc148131f11479e74bbbd74c67e6ee45312bd6e72f5b68d5d1d383e46"}, + {1320000, "1e3d88026216db2a09b7771f5c36b6a9cf49086d259160b2ad4530155265c394"}, + {1330000, "2c05b06c4412738a06961406cea1d3b605afd0380a29ff306db6f1b820ce802f"}, + {1340000, "271352a6b9d8cdef191aaf3395d5b38d7e7bd1b270766aceec915d0e5d6eb9c4"}, + {1350000, "2911699e718b064a4820a860bff5b421ee122707cd4cc7bacebfcb70ed4ea8a5"}, + {1360000, "2635c819e25ea4d25be05adf7b515c09b14ff0bffd600921ab488d8597e1e35e"}, + {1370000, "a8e01900ca2289971a6f926c9bbd420a86c9213c287b8c207c4ee5accff27f10"}, + {1380000, "d6014404b60a7fd16372aacefb78132d417d8e08b5a6876851ab4862b167c84a"}, + {1390000, "30c3eb1c67b1ff52e84c7637131f6e0a950464c633e6e69bb27be7488a690462"}, + {1400000, "9668035887ed9f819382db025f852e57aa02fa8980b4c9043f0dd535ea4a1085"} }; const std::initializer_list TESTNET_CHECKPOINTS = { @@ -387,8 +396,11 @@ namespace cn {375000, "11858ed98655337da5f959194e96f4405a5811bb96afdb8ad1e450a62face3c8"}, {400000, "1de31d8d458e0b0355fd7ff14ab757e6991b1b66c5e63156849891118843bc26"}, {425000, "63c2ff4cb122d76acb4c8939996d2486fcf6d347f801ad2b3b7356ffab0f1b85"}, - {450000, "aa34be98d020af37faf6b78ffe51561a3c001b0322f726da75574e9c8c86dc7b"} -}; + {450000, "aa34be98d020af37faf6b78ffe51561a3c001b0322f726da75574e9c8c86dc7b"}, + {475000, "d6224b5f69024e101487da252b3efc75a8b035810eae32d51656e2dee42cc757"}, + {500000, "f0aa507fdd0cc13698381002ee962e5943db1ade6d20c27eaf8544a3d0dc8230"}, + {525000, "14c6a1f432d577861d0c6a510bffa18bf8c09629f3553d9d475d5a46421ec8fa"} + }; } // namespace cn From dd6854e04b8e580639e3a41e34d8445d5dc9b769 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 22 Oct 2023 15:31:09 +0200 Subject: [PATCH 24/30] Add paymentId to extra --- src/CryptoNoteCore/TransactionExtra.cpp | 9 +++++++++ src/CryptoNoteCore/TransactionExtra.h | 1 + src/PaymentGate/WalletService.cpp | 5 +---- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/CryptoNoteCore/TransactionExtra.cpp b/src/CryptoNoteCore/TransactionExtra.cpp index 43f092d62..9f8118139 100644 --- a/src/CryptoNoteCore/TransactionExtra.cpp +++ b/src/CryptoNoteCore/TransactionExtra.cpp @@ -357,6 +357,15 @@ namespace cn return true; } + bool addPaymentIdToExtra(const std::string &paymentId, std::string &extra) { + std::vector extraVector; + if (!createTxExtraWithPaymentId(paymentId, extraVector)) { + return false; + } + std::copy(extraVector.begin(), extraVector.end(), std::back_inserter(extra)); + return true; + } + #define TX_EXTRA_MESSAGE_CHECKSUM_SIZE 4 #pragma pack(push, 1) diff --git a/src/CryptoNoteCore/TransactionExtra.h b/src/CryptoNoteCore/TransactionExtra.h index 064bf7fd8..f9a950b5e 100644 --- a/src/CryptoNoteCore/TransactionExtra.h +++ b/src/CryptoNoteCore/TransactionExtra.h @@ -99,5 +99,6 @@ bool createTxExtraWithPaymentId(const std::string& paymentIdString, std::vector< //returns false if payment id is not found or parse error bool getPaymentIdFromTxExtra(const std::vector& extra, crypto::Hash& paymentId); bool parsePaymentId(const std::string& paymentIdString, crypto::Hash& paymentId); +bool addPaymentIdToExtra(const std::string &paymentId, std::string &extra); } diff --git a/src/PaymentGate/WalletService.cpp b/src/PaymentGate/WalletService.cpp index b9c61c06b..0b75f588a 100644 --- a/src/PaymentGate/WalletService.cpp +++ b/src/PaymentGate/WalletService.cpp @@ -183,13 +183,10 @@ namespace payment_service void addPaymentIdToExtra(const std::string &paymentId, std::string &extra) { - std::vector extraVector; - if (!cn::createTxExtraWithPaymentId(paymentId, extraVector)) + if (!cn::addPaymentIdToExtra(paymentId, extra)) { throw std::runtime_error("Couldn't add payment id to extra"); } - - std::copy(extraVector.begin(), extraVector.end(), std::back_inserter(extra)); } void validatePaymentId(const std::string &paymentId, const logging::LoggerRef& logger) From 195c5cbe69660a91bfa448ebb8c67d60db5ca5b9 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 19 Nov 2023 16:11:52 +0100 Subject: [PATCH 25/30] Update WalletGreen --- src/Wallet/WalletGreen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index 854841f02..de7a4808a 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -1259,6 +1259,7 @@ namespace cn m_state = WalletState::INITIALIZED; m_logger(INFO, BRIGHT_WHITE) << "Container loaded, view public key " << common::podToHex(m_viewPublicKey) << ", wallet count " << m_walletsContainer.size() << ", actual balance " << m_currency.formatAmount(m_actualBalance) << ", pending balance " << m_currency.formatAmount(m_pendingBalance); + m_observerManager.notify(&IWalletObserver::initCompleted, std::error_code()); } void WalletGreen::clearCaches(bool clearTransactions, bool clearCachedData) From 628a30521d7725d618396e639b527bf9d254526c Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 26 Nov 2023 16:38:45 +0100 Subject: [PATCH 26/30] Fix WalletGreen password change --- src/Common/FileMappedVector.h | 2 +- src/Wallet/WalletGreen.cpp | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Common/FileMappedVector.h b/src/Common/FileMappedVector.h index 0ae892f46..705dfc87a 100644 --- a/src/Common/FileMappedVector.h +++ b/src/Common/FileMappedVector.h @@ -759,7 +759,7 @@ void FileMappedVector::rename(const std::string& newPath) { template template void FileMappedVector::atomicUpdate(F&& func) { - atomicUpdate0(capacity(), prefixSize(), suffixSize(), std::forward(func)); + atomicUpdate0(capacity(), prefixSize(), suffixSize(), std::move(func)); } template diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index de7a4808a..c53070b82 100644 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -1368,7 +1368,30 @@ namespace cn throw std::system_error(make_error_code(error::WRONG_PASSWORD)); } + if (oldPassword == newPassword) + { + return; + } + + crypto::cn_context cnContext; + crypto::chacha8_key newKey; + crypto::generate_chacha8_key(cnContext, newPassword, newKey); + + m_containerStorage.atomicUpdate([this, newKey](ContainerStorage &newStorage) + { + copyContainerStoragePrefix(m_containerStorage, m_key, newStorage, newKey); + copyContainerStorageKeys(m_containerStorage, m_key, newStorage, newKey); + + if (m_containerStorage.suffixSize() > 0) { + BinaryArray containerData; + loadAndDecryptContainerData(m_containerStorage, m_key, containerData); + encryptAndSaveContainerData(newStorage, newKey, containerData.data(), containerData.size()); + } }); + + m_key = newKey; m_password = newPassword; + + m_logger(INFO, BRIGHT_WHITE) << "Container password changed"; } size_t WalletGreen::getAddressCount() const From 63ca10a9e5b5aac674cad3867d8c863b8a830669 Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sun, 26 Nov 2023 16:51:32 +0100 Subject: [PATCH 27/30] Update #include --- src/Mnemonics/CRC32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mnemonics/CRC32.h b/src/Mnemonics/CRC32.h index 07b5404ec..a72550f77 100644 --- a/src/Mnemonics/CRC32.h +++ b/src/Mnemonics/CRC32.h @@ -26,7 +26,7 @@ SOFTWARE. #pragma once #include - +#include #include namespace crc32 From 0eb1a26cd620759fa02ad635ba60ea474583eafe Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 24 Feb 2024 09:43:11 +0100 Subject: [PATCH 28/30] Update checkpoints --- src/CryptoNoteConfig.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/CryptoNoteConfig.h b/src/CryptoNoteConfig.h index 0bbd7b9b9..94ee5c69a 100644 --- a/src/CryptoNoteConfig.h +++ b/src/CryptoNoteConfig.h @@ -374,7 +374,16 @@ namespace cn {1370000, "a8e01900ca2289971a6f926c9bbd420a86c9213c287b8c207c4ee5accff27f10"}, {1380000, "d6014404b60a7fd16372aacefb78132d417d8e08b5a6876851ab4862b167c84a"}, {1390000, "30c3eb1c67b1ff52e84c7637131f6e0a950464c633e6e69bb27be7488a690462"}, - {1400000, "9668035887ed9f819382db025f852e57aa02fa8980b4c9043f0dd535ea4a1085"} + {1400000, "9668035887ed9f819382db025f852e57aa02fa8980b4c9043f0dd535ea4a1085"}, + {1410000, "a01f353bfe5b907f9b0ffa7e4226caca5d8a67e2bf4b39c13c93b63a4a7d4379"}, + {1420000, "930ad5850a8aeeb8ee38b08006bfea2e93474d97bf666b97df9ab9fbe84a79be"}, + {1430000, "8d1b006f9fa277196f62a98a501ecf91a81731d199463c23931181b4a28b694a"}, + {1440000, "b54921b7c396e66e1a15492289e33993a166f49675739f437257fbb760ee1035"}, + {1450000, "f8a2b95f394f6cd188363a20f585dadbfa0db707dd5fa2699604eb7ccab313a6"}, + {1460000, "6bd96b76bd2d3bc7ca320c089ffe21e64565432401cb94736d60d8f70cfb42f3"}, + {1470000, "7e2d26dd0b258ff826d6ff1e36fe6606206fca535ba0ed40e944ddb165da9dc0"}, + {1480000, "f4463eed0890245dca0ccf9fb3a9f101e110f1dc53ce1286ef47d56938faf007"}, + {1490000, "bc76acf39ea16ce02588798b93034208881bab6c6dd9dfc545a6fab51dfce886"} }; const std::initializer_list TESTNET_CHECKPOINTS = { @@ -399,7 +408,11 @@ namespace cn {450000, "aa34be98d020af37faf6b78ffe51561a3c001b0322f726da75574e9c8c86dc7b"}, {475000, "d6224b5f69024e101487da252b3efc75a8b035810eae32d51656e2dee42cc757"}, {500000, "f0aa507fdd0cc13698381002ee962e5943db1ade6d20c27eaf8544a3d0dc8230"}, - {525000, "14c6a1f432d577861d0c6a510bffa18bf8c09629f3553d9d475d5a46421ec8fa"} + {525000, "14c6a1f432d577861d0c6a510bffa18bf8c09629f3553d9d475d5a46421ec8fa"}, + {550000, "29699db2cc98d5e9aee8c3abcc0d64604d121692aae50f8bb7e642083ba8f7fc"}, + {575000, "f32d55598a3df5e83a28a1c0f67ecc836c7fc2d710be7656fddd3d07b0f3e88f"}, + {600000, "b44f8e1a1bcc9841a174f76ff04832e7090851dfd0a2e7ac9ce68990c5b21ca3"}, + {625000, "774e1129050fe4d09661ddf335f9b44922b1e44637bbfd30f44a89142e7bf8f9"} }; } // namespace cn From 504cd3ca5e712e6f1b3760a731181e2716a3972f Mon Sep 17 00:00:00 2001 From: AxVultis Date: Sat, 24 Feb 2024 11:29:05 +0100 Subject: [PATCH 29/30] Version 6.7.3 --- .gitignore | 3 +-- CMakeLists.txt | 2 +- docs/build_docs.bash | 4 ++-- docs/rpc/check_reserve_proof.html | 4 ++-- docs/rpc/check_tx_proof.html | 4 ++-- docs/rpc/f_block_json.html | 4 ++-- docs/rpc/f_blocks_list_json.html | 4 ++-- docs/rpc/f_on_transactions_pool.html | 4 ++-- docs/rpc/f_transaction_json.html | 4 ++-- docs/rpc/getalblockslist.html | 4 ++-- docs/rpc/getblockbyheight.html | 4 ++-- docs/rpc/getblockcount.html | 4 ++-- docs/rpc/getblockhash.html | 4 ++-- docs/rpc/getblockheaderbyhash.html | 4 ++-- docs/rpc/getblockheaderbyheight.html | 4 ++-- docs/rpc/getblocktemplate.html | 4 ++-- docs/rpc/getblocktimestamp.html | 4 ++-- docs/rpc/getcurrencyid.html | 4 ++-- docs/rpc/getlastblockheader.html | 4 ++-- docs/rpc/getrawtransactionpool.html | 4 ++-- docs/rpc/getrawtransactionsbyheight.html | 4 ++-- docs/rpc/json_methods.html | 4 ++-- docs/rpc/openapi/check_reserve_proof.yaml | 2 +- docs/rpc/openapi/check_tx_proof.yaml | 2 +- docs/rpc/openapi/f_block_json.yaml | 2 +- docs/rpc/openapi/f_blocks_list_json.yaml | 2 +- docs/rpc/openapi/f_on_transactions_pool.yaml | 2 +- docs/rpc/openapi/f_transaction_json.yaml | 2 +- docs/rpc/openapi/getalblockslist.yaml | 2 +- docs/rpc/openapi/getblockbyheight.yaml | 2 +- docs/rpc/openapi/getblockcount.yaml | 2 +- docs/rpc/openapi/getblockhash.yaml | 2 +- docs/rpc/openapi/getblockheaderbyhash.yaml | 2 +- docs/rpc/openapi/getblockheaderbyheight.yaml | 2 +- docs/rpc/openapi/getblocktemplate.yaml | 2 +- docs/rpc/openapi/getblocktimestamp.yaml | 2 +- docs/rpc/openapi/getcurrencyid.yaml | 2 +- docs/rpc/openapi/getlastblockheader.yaml | 2 +- docs/rpc/openapi/getrawtransactionpool.yaml | 2 +- docs/rpc/openapi/getrawtransactionsbyheight.yaml | 2 +- docs/rpc/openapi/json_methods.yaml | 2 +- docs/rpc/openapi/submitblock.yaml | 2 +- docs/rpc/submitblock.html | 4 ++-- 43 files changed, 64 insertions(+), 65 deletions(-) diff --git a/.gitignore b/.gitignore index 71689b542..6a8aeadc5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,5 +23,4 @@ compile_commands.json *.ipch *.bin *.json -*.json -*.json +cmake-build* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fbc3ec15..be68bd059 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.0) include(CheckCXXCompilerFlag) -set(VERSION "6.7.2") +set(VERSION "6.7.3") set(VERSION_BUILD_NO "Trebopala") # Packaged from main commits set(COMMIT 1db6e66) diff --git a/docs/build_docs.bash b/docs/build_docs.bash index 16392e605..267b97dee 100644 --- a/docs/build_docs.bash +++ b/docs/build_docs.bash @@ -6,8 +6,8 @@ output_folder="" display_help() { echo "Usage: $0 [OPTIONS]" echo "Options:" - echo " -i, --input INPUT_FOLDER Specify the input folder (default: chatgpt)" - echo " -o, --output OUTPUT_FOLDER Specify the output folder (default: docs)" + echo " -i, --input INPUT_FOLDER Specify the input folder (default: rpc/openapi)" + echo " -o, --output OUTPUT_FOLDER Specify the output folder (default: rpc)" echo " -h, --help Display this help message" exit 0 } diff --git a/docs/rpc/check_reserve_proof.html b/docs/rpc/check_reserve_proof.html index ea9648a8e..26c147b8f 100644 --- a/docs/rpc/check_reserve_proof.html +++ b/docs/rpc/check_reserve_proof.html @@ -357,7 +357,7 @@ 55.627 l 55.6165,55.627 -231.245496,231.24803 c -127.185,127.1864 -231.5279,231.248 -231.873,231.248 -0.3451,0 -104.688, -104.0616 -231.873,-231.248 z - " fill="currentColor">

Conceal Core API Documentation (6.7.2)

Download OpenAPI specification:Download

Conceal Core API Documentation (6.7.3)

Download OpenAPI specification:Download

API documentation for Conceal Core

JSON-RPC

Check Reserve Proof

Check the reserve proof using JSON-RPC.

@@ -369,7 +369,7 @@ " class="sc-iJCSeZ sc-cBornZ gJcGEt hchhAE">

Testnet local node

http://localhost:16600/json_rpc

Request samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "method": "check_reserve_proof",
  • "params": {
    },
  • "id": "1"
}

Response samples

Content type
application/json
{
  • "jsonrpc": "2.0",
  • "result": {
    },
  • "id": "1"
}