From 9752ee48d919bf2faccc2e23ec3daf179c608b3e Mon Sep 17 00:00:00 2001 From: RockSteady Date: Mon, 1 Jan 2018 01:16:49 -0600 Subject: [PATCH] v0.2.2 --- .gitattributes | 2 + .gitignore | 8 ++++ include/IWallet.h | 14 ------ src/CryptoNoteConfig.h | 5 +- src/CryptoNoteCore/Core.cpp | 14 +++++- src/CryptoNoteCore/Core.h | 2 +- src/CryptoNoteCore/Currency.cpp | 2 + src/CryptoNoteCore/Currency.h | 3 ++ src/CryptoNoteCore/SwappedMap.h | 1 + .../TransactionValidationErrors.h | 2 + .../CryptoNoteProtocolHandler.cpp | 18 +++++-- src/Daemon/Daemon.cpp | 6 +++ .../PaymentServiceJsonRpcMessages.cpp | 26 ---------- .../PaymentServiceJsonRpcMessages.h | 34 ------------- .../PaymentServiceJsonRpcServer.cpp | 5 -- src/PaymentGate/PaymentServiceJsonRpcServer.h | 1 - src/PaymentGate/WalletService.cpp | 48 ++----------------- src/PaymentGate/WalletService.h | 1 - src/Platform/OSX/System/Context.c | 2 +- src/Platform/OSX/System/Context.h | 2 +- src/Rpc/RpcServer.cpp | 42 +++++++++++----- src/SimpleWallet/SimpleWallet.cpp | 4 +- src/Transfers/SynchronizationState.cpp | 3 ++ src/Wallet/WalletGreen.cpp | 29 ----------- src/Wallet/WalletGreen.h | 1 - src/crypto/crypto.cpp | 23 +++++++-- src/crypto/crypto.h | 6 +++ tests/UnitTests/TestWalletService.cpp | 1 - 28 files changed, 118 insertions(+), 187 deletions(-) create mode 100755 .gitattributes create mode 100755 .gitignore diff --git a/.gitattributes b/.gitattributes new file mode 100755 index 0000000000..6afd357c2c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +.git* export-ignore +/CMakeLists.txt export-subst \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000000..0b1472706b --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/build +/tags +.idea +.ycm_extra_conf.py +.ycm_extra_conf.pyc +Release +Debug diff --git a/include/IWallet.h b/include/IWallet.h index 6c2059a7c2..c3eff473b8 100755 --- a/include/IWallet.h +++ b/include/IWallet.h @@ -72,19 +72,6 @@ struct WalletEvent { }; }; -struct WalletOutput { - // output info - uint8_t type; - uint64_t amount; - uint32_t globalOutputIndex; - uint32_t outputInTransaction; - - // transaction info - std::string transactionHash; - std::string transactionPublicKey; - std::string outputKey; // Type: Key -}; - struct WalletTransaction { WalletTransactionState state; uint64_t timestamp; @@ -164,7 +151,6 @@ class IWallet { virtual std::string createAddress(const Crypto::SecretKey& spendSecretKey) = 0; virtual std::string createAddress(const Crypto::PublicKey& spendPublicKey) = 0; virtual std::vector createAddressList(const std::vector& spendSecretKeys) = 0; - virtual std::vector getAddressOutputs(const std::string& address) const = 0; virtual void deleteAddress(const std::string& address) = 0; virtual uint64_t getActualBalance() const = 0; diff --git a/src/CryptoNoteConfig.h b/src/CryptoNoteConfig.h index 0e16695bfc..4ddaac5374 100755 --- a/src/CryptoNoteConfig.h +++ b/src/CryptoNoteConfig.h @@ -120,7 +120,7 @@ const uint64_t P2P_DEFAULT_INVOKE_TIMEOUT = 60 * 2 * 1000; // const size_t P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT = 5000; // 5 seconds const char P2P_STAT_TRUSTED_PUB_KEY[] = ""; -const char* const SEED_NODES[] = { "104.236.227.176:11897", "104.236.55.84:11897", "163.172.147.52:11897", "51.15.138.214:11897", "51.15.137.77" }; +const char* const SEED_NODES[] = { "104.236.227.176:11897", "104.236.55.84:11897", "163.172.147.52:11897", "51.15.138.214:11897", "51.15.137.77:11897" }; struct CheckpointData { @@ -128,7 +128,8 @@ struct CheckpointData { const char* blockId; }; -const std::initializer_list CHECKPOINTS = { }; +const std::initializer_list CHECKPOINTS = { {50000, "dd40ba6a33e7c6ff84927d510881e285eba9a17cbde43da587aa6cc41883b852"} + }; } // CryptoNote diff --git a/src/CryptoNoteCore/Core.cpp b/src/CryptoNoteCore/Core.cpp index 80d7505dbb..d3774d472c 100755 --- a/src/CryptoNoteCore/Core.cpp +++ b/src/CryptoNoteCore/Core.cpp @@ -1200,7 +1200,7 @@ std::error_code Core::validateTransaction(const CachedTransaction& cachedTransac IBlockchainCache* cache, uint64_t& fee, uint32_t blockIndex) { // TransactionValidatorState currentState; const auto& transaction = cachedTransaction.getTransaction(); - auto error = validateSemantic(transaction, fee); +auto error = validateSemantic(transaction, fee, blockIndex); if (error != error::TransactionValidationError::VALIDATION_SUCCESS) { return error; } @@ -1257,7 +1257,7 @@ std::error_code Core::validateTransaction(const CachedTransaction& cachedTransac return error::TransactionValidationError::VALIDATION_SUCCESS; } -std::error_code Core::validateSemantic(const Transaction& transaction, uint64_t& fee) { +std::error_code Core::validateSemantic(const Transaction& transaction, uint64_t& fee, uint32_t blockIndex) { if (transaction.inputs.empty()) { return error::TransactionValidationError::EMPTY_INPUTS; } @@ -1283,6 +1283,11 @@ std::error_code Core::validateSemantic(const Transaction& transaction, uint64_t& summaryOutputAmount += output.amount; } + // parameters used for the additional key_image check + static const Crypto::KeyImage Z = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; + static const Crypto::KeyImage I = { {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; + static const Crypto::KeyImage L = { {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 } }; + uint64_t summaryInputAmount = 0; std::unordered_set ki; std::set> outputsUsage; @@ -1301,6 +1306,11 @@ std::error_code Core::validateSemantic(const Transaction& transaction, uint64_t& // outputIndexes are packed here, first is absolute, others are offsets to previous, // so first can be zero, others can't + // Fix discovered by Monero Lab and suggested by "fluffypony" (bitcointalk.org) + if (!(scalarmultKey(in.keyImage, L) == I) && blockIndex > parameters::KEY_IMAGE_CHECKING_BLOCK_INDEX) { + return error::TransactionValidationError::INPUT_INVALID_DOMAIN_KEYIMAGES; + } + if (std::find(++std::begin(in.outputIndexes), std::end(in.outputIndexes), 0) != std::end(in.outputIndexes)) { return error::TransactionValidationError::INPUT_IDENTICAL_OUTPUT_INDEXES; } diff --git a/src/CryptoNoteCore/Core.h b/src/CryptoNoteCore/Core.h index ed5cd88595..6fec4bad48 100755 --- a/src/CryptoNoteCore/Core.h +++ b/src/CryptoNoteCore/Core.h @@ -142,7 +142,7 @@ class Core : public ICore, public ICoreInformation { void throwIfNotInitialized() const; bool extractTransactions(const std::vector& rawTransactions, std::vector& transactions, uint64_t& cumulativeSize); - std::error_code validateSemantic(const Transaction& transaction, uint64_t& fee); + std::error_code validateSemantic(const Transaction& transaction, uint64_t& fee, uint32_t blockIndex); std::error_code validateTransaction(const CachedTransaction& transaction, TransactionValidatorState& state, IBlockchainCache* cache, uint64_t& fee, uint32_t blockIndex); uint32_t findBlockchainSupplement(const std::vector& remoteBlockIds) const; diff --git a/src/CryptoNoteCore/Currency.cpp b/src/CryptoNoteCore/Currency.cpp index dc02bec31c..cdbf093302 100755 --- a/src/CryptoNoteCore/Currency.cpp +++ b/src/CryptoNoteCore/Currency.cpp @@ -533,6 +533,7 @@ m_moneySupply(currency.m_moneySupply), m_emissionSpeedFactor(currency.m_emissionSpeedFactor), m_rewardBlocksWindow(currency.m_rewardBlocksWindow), m_blockGrantedFullRewardZone(currency.m_blockGrantedFullRewardZone), +m_isBlockexplorer(currency.m_isBlockexplorer), m_minerTxBlobReservedSize(currency.m_minerTxBlobReservedSize), m_numberOfDecimalPlaces(currency.m_numberOfDecimalPlaces), m_coin(currency.m_coin), @@ -620,6 +621,7 @@ genesisBlockReward(parameters::GENESIS_BLOCK_REWARD); blockIndexesFileName(parameters::CRYPTONOTE_BLOCKINDEXES_FILENAME); txPoolFileName(parameters::CRYPTONOTE_POOLDATA_FILENAME); + isBlockexplorer(false); testnet(false); } diff --git a/src/CryptoNoteCore/Currency.h b/src/CryptoNoteCore/Currency.h index 70c5ae1bc1..218c0dc804 100755 --- a/src/CryptoNoteCore/Currency.h +++ b/src/CryptoNoteCore/Currency.h @@ -91,6 +91,7 @@ class Currency { const std::string& blockIndexesFileName() const { return m_blockIndexesFileName; } const std::string& txPoolFileName() const { return m_txPoolFileName; } + bool isBlockexplorer() const { return m_isBlockexplorer; } bool isTestnet() const { return m_testnet; } const BlockTemplate& genesisBlock() const { return cachedGenesisBlock->getBlock(); } @@ -192,6 +193,7 @@ class Currency { static const std::vector PRETTY_AMOUNTS; bool m_testnet; + bool m_isBlockexplorer; BlockTemplate genesisBlockTemplate; std::unique_ptr cachedGenesisBlock; @@ -267,6 +269,7 @@ class CurrencyBuilder : boost::noncopyable { CurrencyBuilder& blockIndexesFileName(const std::string& val) { m_currency.m_blockIndexesFileName = val; return *this; } CurrencyBuilder& txPoolFileName(const std::string& val) { m_currency.m_txPoolFileName = val; return *this; } + CurrencyBuilder& isBlockexplorer(const bool val) { m_currency.m_isBlockexplorer = val; return *this; } CurrencyBuilder& testnet(bool val) { m_currency.m_testnet = val; return *this; } private: diff --git a/src/CryptoNoteCore/SwappedMap.h b/src/CryptoNoteCore/SwappedMap.h index 3b90b4e5e1..a830cdc9ff 100755 --- a/src/CryptoNoteCore/SwappedMap.h +++ b/src/CryptoNoteCore/SwappedMap.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/src/CryptoNoteCore/TransactionValidationErrors.h b/src/CryptoNoteCore/TransactionValidationErrors.h index 90b1685127..9996157143 100755 --- a/src/CryptoNoteCore/TransactionValidationErrors.h +++ b/src/CryptoNoteCore/TransactionValidationErrors.h @@ -28,6 +28,7 @@ enum class TransactionValidationError { EMPTY_INPUTS, INPUT_UNKNOWN_TYPE, INPUT_EMPTY_OUTPUT_USAGE, + INPUT_INVALID_DOMAIN_KEYIMAGES, INPUT_IDENTICAL_KEYIMAGES, INPUT_IDENTICAL_OUTPUT_INDEXES, INPUT_KEYIMAGE_ALREADY_SPENT, @@ -69,6 +70,7 @@ class TransactionValidationErrorCategory : public std::error_category { case TransactionValidationError::EMPTY_INPUTS: return "Transaction has no inputs"; case TransactionValidationError::INPUT_UNKNOWN_TYPE: return "Transaction has input with unknown type"; case TransactionValidationError::INPUT_EMPTY_OUTPUT_USAGE: return "Transaction's input uses empty output"; + case TransactionValidationError::INPUT_INVALID_DOMAIN_KEYIMAGES: return "Transaction uses key image not in the valid domain"; case TransactionValidationError::INPUT_IDENTICAL_KEYIMAGES: return "Transaction has identical key images"; case TransactionValidationError::INPUT_IDENTICAL_OUTPUT_INDEXES: return "Transaction has identical output indexes"; case TransactionValidationError::INPUT_KEYIMAGE_ALREADY_SPENT: return "Transaction uses spent key image"; diff --git a/src/CryptoNoteProtocol/CryptoNoteProtocolHandler.cpp b/src/CryptoNoteProtocol/CryptoNoteProtocolHandler.cpp index b539244721..a2fb65597c 100755 --- a/src/CryptoNoteProtocol/CryptoNoteProtocolHandler.cpp +++ b/src/CryptoNoteProtocol/CryptoNoteProtocolHandler.cpp @@ -136,7 +136,7 @@ CryptoNoteProtocolHandler::CryptoNoteProtocolHandler(const Currency& currency, S m_observedHeight(0), m_peersCount(0), logger(log, "protocol") { - + if (!m_p2p) { m_p2p = &m_p2p_stub; } @@ -181,7 +181,7 @@ void CryptoNoteProtocolHandler::onConnectionClosed(CryptoNoteConnectionContext& void CryptoNoteProtocolHandler::stop() { m_stop = true; } - + bool CryptoNoteProtocolHandler::start_sync(CryptoNoteConnectionContext& context) { logger(Logging::TRACE) << context << "Starting synchronization"; @@ -356,7 +356,7 @@ int CryptoNoteProtocolHandler::handle_notify_new_transactions(int command, NOTIF for (auto tx_blob_it = arg.txs.begin(); tx_blob_it != arg.txs.end();) { if (!m_core.addTransactionToPool(*tx_blob_it)) { - logger(Logging::INFO) << context << "Tx verification failed"; + logger(Logging::DEBUGGING) << context << "Tx verification failed"; tx_blob_it = arg.txs.erase(tx_blob_it); } else { ++tx_blob_it; @@ -564,7 +564,7 @@ bool CryptoNoteProtocolHandler::request_missing_objects(CryptoNoteConnectionCont << "\r\nm_last_response_height=" << context.m_last_response_height << "\r\nm_remote_blockchain_height=" << context.m_remote_blockchain_height << "\r\nm_needed_objects.size()=" << context.m_needed_objects.size() - << "\r\nm_requested_objects.size()=" << context.m_requested_objects.size() + << "\r\nm_requested_objects.size()=" << context.m_requested_objects.size() << "\r\non connection [" << context << "]"; return false; } @@ -689,7 +689,12 @@ void CryptoNoteProtocolHandler::updateObservedHeight(uint32_t peerHeight, const std::lock_guard lock(m_observedHeightMutex); uint32_t height = m_observedHeight; - if (peerHeight > context.m_remote_blockchain_height) { + if (context.m_remote_blockchain_height != 0 && context.m_last_response_height <= context.m_remote_blockchain_height - 1) { + m_observedHeight = context.m_remote_blockchain_height - 1; + if (m_observedHeight != height) { + updated = true; + } + } else if (peerHeight > context.m_remote_blockchain_height) { m_observedHeight = std::max(m_observedHeight, peerHeight); if (m_observedHeight != height) { updated = true; @@ -719,6 +724,9 @@ void CryptoNoteProtocolHandler::recalculateMaxObservedHeight(const CryptoNoteCon }); m_observedHeight = std::max(peerHeight, m_core.getTopBlockIndex() + 1); + if (context.m_state == CryptoNoteConnectionContext::state_normal) { + m_observedHeight = m_core.getTopBlockIndex(); + } } uint32_t CryptoNoteProtocolHandler::getObservedHeight() const { diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp index b1c0f90843..609d6e0f24 100755 --- a/src/Daemon/Daemon.cpp +++ b/src/Daemon/Daemon.cpp @@ -67,6 +67,7 @@ namespace const command_line::arg_descriptor arg_console = {"no-console", "Disable daemon console commands"}; const command_line::arg_descriptor arg_print_genesis_tx = { "print-genesis-tx", "Prints genesis' block tx hex to insert it to config and exits" }; const command_line::arg_descriptor> arg_genesis_block_reward_address = { "genesis-block-reward-address", "" }; + const command_line::arg_descriptor arg_blockexplorer_on = {"enable_blockexplorer", "Enable blockchain explorer RPC", false}; const command_line::arg_descriptor> arg_enable_cors = { "enable-cors", "Adds header 'Access-Control-Allow-Origin' to the daemon's RPC responses. Uses the value as domain. Use * for all" }; const command_line::arg_descriptor arg_testnet_on = {"testnet", "Used to deploy test nets. Checkpoints and hardcoded seeds are ignored, " "network id is changed. Use it with --data-dir flag. The wallet must be launched with --testnet flag.", false}; @@ -77,6 +78,8 @@ void print_genesis_tx_hex(const po::variables_map& vm, LoggerManager& logManager std::vector targets; auto genesis_block_reward_addresses = command_line::get_arg(vm, arg_genesis_block_reward_address); CryptoNote::CurrencyBuilder currencyBuilder(logManager); +bool blockexplorer_mode = command_line::get_arg(vm, arg_blockexplorer_on); +currencyBuilder.isBlockexplorer(blockexplorer_mode); CryptoNote::Currency currency = currencyBuilder.currency(); for (const auto& address_string : genesis_block_reward_addresses) { CryptoNote::AccountPublicAddress address; @@ -149,6 +152,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_cmd_sett, arg_console); command_line::add_arg(desc_cmd_sett, arg_testnet_on); command_line::add_arg(desc_cmd_sett, arg_enable_cors); + command_line::add_arg(desc_cmd_sett, arg_blockexplorer_on); command_line::add_arg(desc_cmd_sett, arg_print_genesis_tx); command_line::add_arg(desc_cmd_sett, arg_genesis_block_reward_address); @@ -227,6 +231,8 @@ command_line::add_arg(desc_cmd_sett, arg_print_genesis_tx); //create objects and link them CryptoNote::CurrencyBuilder currencyBuilder(logManager); +bool blockexplorer_mode = command_line::get_arg(vm, arg_blockexplorer_on); +currencyBuilder.isBlockexplorer(blockexplorer_mode); currencyBuilder.testnet(testnet_mode); try { currencyBuilder.currency(); diff --git a/src/PaymentGate/PaymentServiceJsonRpcMessages.cpp b/src/PaymentGate/PaymentServiceJsonRpcMessages.cpp index 8f1466cb29..d2531c1e77 100755 --- a/src/PaymentGate/PaymentServiceJsonRpcMessages.cpp +++ b/src/PaymentGate/PaymentServiceJsonRpcMessages.cpp @@ -313,32 +313,6 @@ void SendDelayedTransaction::Request::serialize(CryptoNote::ISerializer& seriali void SendDelayedTransaction::Response::serialize(CryptoNote::ISerializer& serializer) { } -void GetUnspendOuts::Request::serialize(CryptoNote::ISerializer& serializer) { - if (!serializer(address, "address")) { - throw RequestSerializationError(); - } - - serializer(viewKey, "viewKey"); - serializer(amount, "amount"); - serializer(mixIn, "mixIn"); - serializer(useDust, "useDust"); - serializer(dustThreshold, "dustThreshold"); -} - -void GetUnspendOuts::Response::serialize(CryptoNote::ISerializer& serializer) { - serializer(outputs, "outputs"); -} - -void TransactionOutputInformationSerialized::serialize(CryptoNote::ISerializer& serializer) { - serializer(type, "type"); - serializer(amount, "amount"); - serializer(globalOutputIndex, "globalOutputIndex"); - serializer(outputInTransaction, "outputInTransaction"); - serializer(transactionHash, "transactionHash"); - serializer(transactionPublicKey, "transactionPublicKey"); - serializer(outputKey, "outputKey"); -} - void SendFusionTransaction::Request::serialize(CryptoNote::ISerializer& serializer) { if (!serializer(threshold, "threshold")) { throw RequestSerializationError(); diff --git a/src/PaymentGate/PaymentServiceJsonRpcMessages.h b/src/PaymentGate/PaymentServiceJsonRpcMessages.h index ee23826a32..92bc9a9d09 100755 --- a/src/PaymentGate/PaymentServiceJsonRpcMessages.h +++ b/src/PaymentGate/PaymentServiceJsonRpcMessages.h @@ -378,40 +378,6 @@ struct SendDelayedTransaction { }; }; -struct TransactionOutputInformationSerialized { - // output info - uint8_t type; - uint64_t amount; - uint32_t globalOutputIndex; - uint32_t outputInTransaction; - - // transaction info - std::string transactionHash; - std::string transactionPublicKey; - std::string outputKey; // Type: Key - - void serialize(CryptoNote::ISerializer& serializer); -}; - -struct GetUnspendOuts { - struct Request { - std::string address; - std::string viewKey; - uint64_t amount; - uint32_t mixIn; - bool useDust; - uint64_t dustThreshold; - - void serialize(CryptoNote::ISerializer& serializer); - }; - - struct Response { - std::vector outputs; - - void serialize(CryptoNote::ISerializer& serializer); - }; -}; - struct SendFusionTransaction { struct Request { uint64_t threshold; diff --git a/src/PaymentGate/PaymentServiceJsonRpcServer.cpp b/src/PaymentGate/PaymentServiceJsonRpcServer.cpp index 840e9dc088..324cbd1aaf 100755 --- a/src/PaymentGate/PaymentServiceJsonRpcServer.cpp +++ b/src/PaymentGate/PaymentServiceJsonRpcServer.cpp @@ -53,7 +53,6 @@ PaymentServiceJsonRpcServer::PaymentServiceJsonRpcServer(System::Dispatcher& sys handlers.emplace("getViewKey", jsonHandler(std::bind(&PaymentServiceJsonRpcServer::handleGetViewKey, this, std::placeholders::_1, std::placeholders::_2))); handlers.emplace("getStatus", jsonHandler(std::bind(&PaymentServiceJsonRpcServer::handleGetStatus, this, std::placeholders::_1, std::placeholders::_2))); handlers.emplace("getAddresses", jsonHandler(std::bind(&PaymentServiceJsonRpcServer::handleGetAddresses, this, std::placeholders::_1, std::placeholders::_2))); - handlers.emplace("getUnspendOuts", jsonHandler(std::bind(&PaymentServiceJsonRpcServer::handleGetUnspendOuts, this, std::placeholders::_1, std::placeholders::_2))); handlers.emplace("sendFusionTransaction", jsonHandler(std::bind(&PaymentServiceJsonRpcServer::handleSendFusionTransaction, this, std::placeholders::_1, std::placeholders::_2))); handlers.emplace("estimateFusion", jsonHandler(std::bind(&PaymentServiceJsonRpcServer::handleEstimateFusion, this, std::placeholders::_1, std::placeholders::_2))); } @@ -203,10 +202,6 @@ std::error_code PaymentServiceJsonRpcServer::handleGetAddresses(const GetAddress return service.getAddresses(response.addresses); } -std::error_code PaymentServiceJsonRpcServer::handleGetUnspendOuts(const GetUnspendOuts::Request& request, GetUnspendOuts::Response& response) { - return service.getUnspendOuts(request, response.outputs); -} - std::error_code PaymentServiceJsonRpcServer::handleSendFusionTransaction(const SendFusionTransaction::Request& request, SendFusionTransaction::Response& response) { return service.sendFusionTransaction(request.threshold, request.anonymity, request.addresses, request.destinationAddress, response.transactionHash); } diff --git a/src/PaymentGate/PaymentServiceJsonRpcServer.h b/src/PaymentGate/PaymentServiceJsonRpcServer.h index d3f02e9a00..49b47dbd12 100755 --- a/src/PaymentGate/PaymentServiceJsonRpcServer.h +++ b/src/PaymentGate/PaymentServiceJsonRpcServer.h @@ -93,7 +93,6 @@ class PaymentServiceJsonRpcServer : public CryptoNote::JsonRpcServer { std::error_code handleGetStatus(const GetStatus::Request& request, GetStatus::Response& response); std::error_code handleGetAddresses(const GetAddresses::Request& request, GetAddresses::Response& response); - std::error_code handleGetUnspendOuts(const GetUnspendOuts::Request& request, GetUnspendOuts::Response& response); std::error_code handleSendFusionTransaction(const SendFusionTransaction::Request& request, SendFusionTransaction::Response& response); std::error_code handleEstimateFusion(const EstimateFusion::Request& request, EstimateFusion::Response& response); }; diff --git a/src/PaymentGate/WalletService.cpp b/src/PaymentGate/WalletService.cpp index 92f85dafdc..910fc82c96 100755 --- a/src/PaymentGate/WalletService.cpp +++ b/src/PaymentGate/WalletService.cpp @@ -194,7 +194,9 @@ std::vector filterTransactions( } } - result.push_back(std::move(item)); + if (!block.transactions.empty()) { + result.push_back(std::move(item)); + } } return result; @@ -228,28 +230,6 @@ PaymentService::TransactionRpcInfo convertTransactionWithTransfersToTransactionR return transactionInfo; } -std::vector convertWalletOutputsToTransactionOutputInformationSerialized( - const std::vector& outputs) { - - std::vector rpcOutputs; - rpcOutputs.reserve(outputs.size()); - for (const auto& output: outputs) { - PaymentService::TransactionOutputInformationSerialized rpcOutput; - - rpcOutput.type = output.type; - rpcOutput.amount = output.amount; - rpcOutput.globalOutputIndex = output.globalOutputIndex; - rpcOutput.outputInTransaction = output.outputInTransaction; - rpcOutput.transactionHash = output.transactionHash; - rpcOutput.transactionPublicKey = output.transactionPublicKey; - rpcOutput.outputKey = output.outputKey; - - rpcOutputs.push_back(std::move(rpcOutput)); - } - - return rpcOutputs; -} - std::vector convertTransactionsInBlockInfoToTransactionsInBlockRpcInfo( const std::vector& blocks) { @@ -1022,28 +1002,6 @@ std::error_code WalletService::getUnconfirmedTransactionHashes(const std::vector return std::error_code(); } -std::error_code WalletService::getUnspendOuts(const GetUnspendOuts::Request& request, std::vector& outputs) { - try { - System::EventLock lk(readyEvent); - - if (!CryptoNote::validateAddress(request.address, currency)) { - logger(Logging::WARNING, Logging::BRIGHT_YELLOW) << "Can't validate address " << request.address; - throw std::system_error(make_error_code(CryptoNote::error::BAD_ADDRESS)); - } - - auto outs = wallet.getAddressOutputs(request.address); - - outputs = convertWalletOutputsToTransactionOutputInformationSerialized(outs); - - logger(Logging::DEBUGGING) << "Got unspend outs for address " << request.address; - } catch (std::exception& x) { - logger(Logging::WARNING, Logging::BRIGHT_YELLOW) << "Error while getting unspend outs: " << x.what(); - return make_error_code(CryptoNote::error::INTERNAL_WALLET_ERROR); - } - - return std::error_code(); -} - std::error_code WalletService::getStatus(uint32_t& blockCount, uint32_t& knownBlockCount, std::string& lastBlockHash, uint32_t& peerCount) { try { System::EventLock lk(readyEvent); diff --git a/src/PaymentGate/WalletService.h b/src/PaymentGate/WalletService.h index c9a46a9337..362494459e 100755 --- a/src/PaymentGate/WalletService.h +++ b/src/PaymentGate/WalletService.h @@ -89,7 +89,6 @@ class WalletService { std::error_code sendDelayedTransaction(const std::string& transactionHash); std::error_code getUnconfirmedTransactionHashes(const std::vector& addresses, std::vector& transactionHashes); std::error_code getStatus(uint32_t& blockCount, uint32_t& knownBlockCount, std::string& lastBlockHash, uint32_t& peerCount); - std::error_code getUnspendOuts(const GetUnspendOuts::Request& request, std::vector& outputs); std::error_code sendFusionTransaction(uint64_t threshold, uint32_t anonymity, const std::vector& addresses, const std::string& destinationAddress, std::string& transactionHash); std::error_code estimateFusion(uint64_t threshold, const std::vector& addresses, uint32_t& fusionReadyCount, uint32_t& totalOutputCount); diff --git a/src/Platform/OSX/System/Context.c b/src/Platform/OSX/System/Context.c index a8030348d0..2698697a5d 100755 --- a/src/Platform/OSX/System/Context.c +++ b/src/Platform/OSX/System/Context.c @@ -16,7 +16,7 @@ // along with Bytecoin. If not, see . #include -#include "context.h" +#include "Context.h" void makecontext(uctx *ucp, void (*func)(void), intptr_t arg) diff --git a/src/Platform/OSX/System/Context.h b/src/Platform/OSX/System/Context.h index e02c49415e..bfff4c010e 100755 --- a/src/Platform/OSX/System/Context.h +++ b/src/Platform/OSX/System/Context.h @@ -29,7 +29,7 @@ typedef struct mcontext mctx; typedef struct ucontext uctx; extern int swapcontext(uctx*, const uctx*); -extern void makecontext(uctx*, void(*)(), intptr_t); +extern void makecontext(uctx*, void(*)(void), intptr_t); extern int getmcontext(mctx*); extern void setmcontext(const mctx*); diff --git a/src/Rpc/RpcServer.cpp b/src/Rpc/RpcServer.cpp index 83831c0b9f..4e6b55ae0a 100755 --- a/src/Rpc/RpcServer.cpp +++ b/src/Rpc/RpcServer.cpp @@ -104,9 +104,9 @@ RpcServer::HandlerFunction jsonMethod(bool (RpcServer::*handler)(typename Comman } - + std::unordered_map> RpcServer::s_handlers = { - + // binary handlers { "/getblocks.bin", { binMethod(&RpcServer::on_get_blocks), false } }, { "/queryblocks.bin", { binMethod(&RpcServer::on_query_blocks), false } }, @@ -496,7 +496,7 @@ bool RpcServer::on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMM logger(DEBUGGING) << "transaction " << transactionHash << " came in on_send_raw_tx"; if (!m_core.addTransactionToPool(transactions.back())) { - logger(INFO) << "[on_send_raw_tx]: tx verification failed"; + logger(DEBUGGING) << "[on_send_raw_tx]: tx verification failed"; res.status = "Failed"; return true; } @@ -523,16 +523,21 @@ bool RpcServer::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMM // JSON RPC methods //------------------------------------------------------------------------------------------------------------------------------ bool RpcServer::f_on_blocks_list_json(const F_COMMAND_RPC_GET_BLOCKS_LIST::request& req, F_COMMAND_RPC_GET_BLOCKS_LIST::response& res) { + // check if blockchain explorer RPC is enabled + if (m_core.getCurrency().isBlockexplorer() == false) { + return false; + } + if (m_core.getTopBlockIndex() + 1 <= req.height) { throw JsonRpc::JsonRpcError{ CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT, - std::string("To big height: ") + std::to_string(req.height) + ", current blockchain height = " + std::to_string(m_core.getTopBlockIndex() + 1) }; + std::string("To big height: ") + std::to_string(req.height) + ", current blockchain height = " + std::to_string(m_core.getTopBlockIndex()) }; } uint32_t print_blocks_count = 30; uint32_t last_height = req.height - print_blocks_count; if (req.height <= print_blocks_count) { last_height = 0; - } + } for (uint32_t i = req.height; i >= last_height; i--) { Hash block_hash = m_core.getBlockHashByIndex(static_cast(i)); @@ -562,6 +567,11 @@ bool RpcServer::f_on_blocks_list_json(const F_COMMAND_RPC_GET_BLOCKS_LIST::reque } bool RpcServer::f_on_block_json(const F_COMMAND_RPC_GET_BLOCK_DETAILS::request& req, F_COMMAND_RPC_GET_BLOCK_DETAILS::response& res) { + // check if blockchain explorer RPC is enabled + if (m_core.getCurrency().isBlockexplorer() == false) { + return false; + } + Hash hash; try { @@ -655,6 +665,11 @@ bool RpcServer::f_on_block_json(const F_COMMAND_RPC_GET_BLOCK_DETAILS::request& } bool RpcServer::f_on_transaction_json(const F_COMMAND_RPC_GET_TRANSACTION_DETAILS::request& req, F_COMMAND_RPC_GET_TRANSACTION_DETAILS::response& res) { + // check if blockchain explorer RPC is enabled + if (m_core.getCurrency().isBlockexplorer() == false) { + return false; + } + Hash hash; if (!parse_hash256(req.hash, hash)) { @@ -734,6 +749,11 @@ bool RpcServer::f_on_transaction_json(const F_COMMAND_RPC_GET_TRANSACTION_DETAIL bool RpcServer::f_on_transactions_pool_json(const F_COMMAND_RPC_GET_POOL::request& req, F_COMMAND_RPC_GET_POOL::response& res) { + // check if blockchain explorer RPC is enabled + if (m_core.getCurrency().isBlockexplorer() == false) { + return false; + } + auto pool = m_core.getPoolTransactions(); for (const Transaction tx : pool) { f_transaction_short_response transaction_short; @@ -778,7 +798,7 @@ bool RpcServer::on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, CO uint32_t h = static_cast(req[0]); Crypto::Hash blockId = m_core.getBlockHashByIndex(h - 1); if (blockId == NULL_HASH) { - throw JsonRpc::JsonRpcError{ + throw JsonRpc::JsonRpcError{ CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT, std::string("Too big height: ") + std::to_string(h) + ", current blockchain height = " + std::to_string(m_core.getTopBlockIndex() + 1) }; @@ -937,7 +957,7 @@ void RpcServer::fill_block_header_response(const BlockTemplate& blk, bool orphan } bool RpcServer::on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res) { - auto topBlock = m_core.getBlockByHash(m_core.getTopBlockHash()); + auto topBlock = m_core.getBlockByHash(m_core.getTopBlockHash()); fill_block_header_response(topBlock, false, m_core.getTopBlockIndex(), m_core.getTopBlockHash(), res.block_header); res.status = CORE_RPC_STATUS_OK; return true; @@ -967,15 +987,15 @@ bool RpcServer::on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_B } bool RpcServer::on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res) { - if (m_core.getTopBlockIndex() + 1 < req.height) { + if (m_core.getTopBlockIndex() < req.height) { throw JsonRpc::JsonRpcError{ CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT, - std::string("To big height: ") + std::to_string(req.height) + ", current blockchain height = " + std::to_string(m_core.getTopBlockIndex() + 1) }; + std::string("To big height: ") + std::to_string(req.height) + ", current blockchain height = " + std::to_string(m_core.getTopBlockIndex()) }; } - uint32_t index = static_cast(req.height) - 1; +uint32_t index = static_cast(req.height); auto block = m_core.getBlockByIndex(index); CachedBlock cachedBlock(block); - assert(cachedBlock.getBlockIndex() == req.height - 1); +assert(cachedBlock.getBlockIndex() == req.height); fill_block_header_response(block, false, index, cachedBlock.getBlockHash(), res.block_header); res.status = CORE_RPC_STATUS_OK; return true; diff --git a/src/SimpleWallet/SimpleWallet.cpp b/src/SimpleWallet/SimpleWallet.cpp index f6dbfcefca..b98f5af922 100755 --- a/src/SimpleWallet/SimpleWallet.cpp +++ b/src/SimpleWallet/SimpleWallet.cpp @@ -467,8 +467,8 @@ simple_wallet::simple_wallet(System::Dispatcher& dispatcher, const CryptoNote::C m_refresh_progress_reporter(*this), m_initResultPromise(nullptr), m_walletSynchronized(false) { - m_consoleHandler.setHandler("start_mining", boost::bind(&simple_wallet::start_mining, this, _1), "start_mining [] - Start mining in daemon"); - m_consoleHandler.setHandler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, _1), "Stop mining in daemon"); + //m_consoleHandler.setHandler("start_mining", boost::bind(&simple_wallet::start_mining, this, _1), "start_mining [] - Start mining in daemon"); + //m_consoleHandler.setHandler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, _1), "Stop mining in daemon"); //m_consoleHandler.setHandler("refresh", boost::bind(&simple_wallet::refresh, this, _1), "Resynchronize transactions and balance"); m_consoleHandler.setHandler("export_keys", boost::bind(&simple_wallet::export_keys, this, _1), "Show the secret keys of the openned wallet"); m_consoleHandler.setHandler("balance", boost::bind(&simple_wallet::show_balance, this, _1), "Show current wallet balance"); diff --git a/src/Transfers/SynchronizationState.cpp b/src/Transfers/SynchronizationState.cpp index d62864a7c3..b2344bde20 100755 --- a/src/Transfers/SynchronizationState.cpp +++ b/src/Transfers/SynchronizationState.cpp @@ -96,6 +96,9 @@ void SynchronizationState::detach(uint32_t height) { void SynchronizationState::addBlocks(const Crypto::Hash* blockHashes, uint32_t height, uint32_t count) { assert(blockHashes); auto size = m_blockchain.size(); + // Dummy fix for simplewallet or walletd when sync + if (height == 0) + height = 1; assert( size == height); m_blockchain.insert(m_blockchain.end(), blockHashes, blockHashes + count); } diff --git a/src/Wallet/WalletGreen.cpp b/src/Wallet/WalletGreen.cpp index 6eb9a26683..3f38df8ca8 100755 --- a/src/Wallet/WalletGreen.cpp +++ b/src/Wallet/WalletGreen.cpp @@ -1110,35 +1110,6 @@ std::string WalletGreen::addWallet(const Crypto::PublicKey& spendPublicKey, cons } } -std::vector WalletGreen::getAddressOutputs(const std::string& address) const { - throwIfNotInitialized(); - throwIfStopped(); - - std::vector outputs; - - const auto& wallet = getWalletRecord(address); - - ITransfersContainer* container = wallet.container; - WalletOuts outs; - container->getOutputs(outs.outs, ITransfersContainer::IncludeKeyUnlocked); - - for (const auto& out: outs.outs) { - WalletOutput output; - - output.type = uint8_t(out.type); - output.amount = out.amount; - - output.globalOutputIndex = out.globalOutputIndex; - output.outputInTransaction = out.outputInTransaction; - output.transactionHash = Common::podToHex(out.transactionHash); - output.transactionPublicKey = Common::podToHex(out.transactionPublicKey); - output.outputKey = Common::podToHex(out.outputKey); - - outputs.push_back(output); - } - - return outputs; -} void WalletGreen::deleteAddress(const std::string& address) { throwIfNotInitialized(); throwIfStopped(); diff --git a/src/Wallet/WalletGreen.h b/src/Wallet/WalletGreen.h index f8002fda43..6e35597204 100755 --- a/src/Wallet/WalletGreen.h +++ b/src/Wallet/WalletGreen.h @@ -61,7 +61,6 @@ class WalletGreen : public IWallet, virtual std::string createAddress(const Crypto::SecretKey& spendSecretKey) override; virtual std::string createAddress(const Crypto::PublicKey& spendPublicKey) override; virtual std::vector createAddressList(const std::vector& spendSecretKeys) override; - virtual std::vector getAddressOutputs(const std::string& address) const override; virtual void deleteAddress(const std::string& address) override; virtual uint64_t getActualBalance() const override; diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index 78cef9edc9..b9f09ecefd 100755 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -298,6 +298,17 @@ namespace Crypto { ge_p1p1_to_p3(&res, &point2); } + KeyImage crypto_ops::scalarmultKey(const KeyImage & P, const KeyImage & a) { + ge_p3 A; + ge_p2 R; +// maybe use assert instead? + ge_frombytes_vartime(&A, reinterpret_cast(&P)); + ge_scalarmult(&R, reinterpret_cast(&a), &A); + KeyImage aP; + ge_tobytes(reinterpret_cast(&aP), &R); + return aP; + } + void crypto_ops::hash_data_to_ec(const uint8_t* data, std::size_t len, PublicKey& key) { Hash h; ge_p2 point; @@ -327,16 +338,17 @@ namespace Crypto { #ifdef _MSC_VER #pragma warning(disable: 4200) #endif - + struct ec_point_pair { + EllipticCurvePoint a, b; + }; struct rs_comm { Hash h; - struct { - EllipticCurvePoint a, b; - } ab[]; + struct ec_point_pair ab[]; + }; static inline size_t rs_comm_size(size_t pubs_count) { - return sizeof(rs_comm) + pubs_count * sizeof(rs_comm().ab[0]); + return sizeof(rs_comm) + pubs_count * sizeof(ec_point_pair); } void crypto_ops::generate_ring_signature(const Hash &prefix_hash, const KeyImage &image, @@ -444,3 +456,4 @@ namespace Crypto { return sc_isnonzero(reinterpret_cast(&h)) == 0; } } + diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 006170afdd..b0a8b29f81 100755 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -82,6 +82,8 @@ struct EllipticCurveScalar { friend bool check_signature(const Hash &, const PublicKey &, const Signature &); static void generate_key_image(const PublicKey &, const SecretKey &, KeyImage &); friend void generate_key_image(const PublicKey &, const SecretKey &, KeyImage &); + static KeyImage scalarmultKey(const KeyImage & P, const KeyImage & a); + friend KeyImage scalarmultKey(const KeyImage & P, const KeyImage & a); static void hash_data_to_ec(const uint8_t*, std::size_t, PublicKey&); friend void hash_data_to_ec(const uint8_t*, std::size_t, PublicKey&); static void generate_ring_signature(const Hash &, const KeyImage &, @@ -219,6 +221,10 @@ struct EllipticCurveScalar { crypto_ops::generate_key_image(pub, sec, image); } + inline KeyImage scalarmultKey(const KeyImage & P, const KeyImage & a) { + return crypto_ops::scalarmultKey(P, a); + } + inline void hash_data_to_ec(const uint8_t* data, std::size_t len, PublicKey& key) { crypto_ops::hash_data_to_ec(data, len, key); } diff --git a/tests/UnitTests/TestWalletService.cpp b/tests/UnitTests/TestWalletService.cpp index 71565b2184..6c21315f88 100755 --- a/tests/UnitTests/TestWalletService.cpp +++ b/tests/UnitTests/TestWalletService.cpp @@ -71,7 +71,6 @@ struct IWalletBaseStub : public CryptoNote::IWallet, public CryptoNote::IFusionM virtual std::string createAddress(const Crypto::SecretKey& spendSecretKey) override { return ""; } virtual std::string createAddress(const Crypto::PublicKey& spendPublicKey) override { return ""; } virtual std::vector createAddressList(const std::vector& spendSecretKeys) override { return std::vector(); } - virtual std::vector getAddressOutputs(const std::string& address) const override { return {}; } virtual void deleteAddress(const std::string& address) override { } virtual uint64_t getActualBalance() const override { return 0; }