From 761defde093bfb174cc71e043df67f10931d00af Mon Sep 17 00:00:00 2001 From: Aiwe Date: Thu, 4 Aug 2022 16:00:58 +0300 Subject: [PATCH] Remove Multisig implementation from Bytecoin/CryptoNote dev --- include/BlockchainExplorerData.h | 19 +- include/CryptoNote.h | 15 +- include/INode.h | 1 - include/ITransaction.h | 11 +- .../BlockchainExplorerDataBuilder.cpp | 11 -- src/CryptoNoteCore/Blockchain.cpp | 179 ------------------ src/CryptoNoteCore/Blockchain.h | 17 -- src/CryptoNoteCore/Core.cpp | 13 -- src/CryptoNoteCore/Core.h | 2 - src/CryptoNoteCore/CryptoNoteFormatUtils.cpp | 50 +---- .../CryptoNoteSerialization.cpp | 26 --- src/CryptoNoteCore/CryptoNoteSerialization.h | 2 - src/CryptoNoteCore/CryptoNoteTools.cpp | 4 - src/CryptoNoteCore/ICore.h | 3 - src/CryptoNoteCore/Transaction.cpp | 92 +-------- src/CryptoNoteCore/TransactionPool.cpp | 29 --- src/CryptoNoteCore/TransactionPrefixImpl.cpp | 23 +-- src/CryptoNoteCore/TransactionUtils.cpp | 22 +-- src/InProcessNode/InProcessNode.cpp | 25 --- src/InProcessNode/InProcessNode.h | 3 - src/NodeRpcProxy/NodeRpcProxy.cpp | 11 -- src/NodeRpcProxy/NodeRpcProxy.h | 1 - src/PaymentGate/NodeFactory.cpp | 3 - src/Rpc/RpcServer.cpp | 20 -- .../BlockchainExplorerDataSerialization.cpp | 17 +- .../BlockchainExplorerDataSerialization.h | 1 - src/Transfers/TransfersConsumer.cpp | 36 +--- src/Transfers/TransfersContainer.cpp | 54 +----- src/Transfers/TransfersContainer.h | 4 - 29 files changed, 20 insertions(+), 674 deletions(-) diff --git a/include/BlockchainExplorerData.h b/include/BlockchainExplorerData.h index 135b44c3de..d621a12537 100644 --- a/include/BlockchainExplorerData.h +++ b/include/BlockchainExplorerData.h @@ -39,18 +39,11 @@ struct TransactionOutputToKeyDetails { Crypto::PublicKey txOutKey; }; -struct TransactionOutputMultisignatureDetails { - std::vector keys; - uint32_t requiredSignatures; -}; - struct TransactionOutputDetails { uint64_t amount; uint32_t globalIndex; - boost::variant< - TransactionOutputToKeyDetails, - TransactionOutputMultisignatureDetails> output; + boost::variant output; }; struct TransactionOutputReferenceDetails { @@ -79,8 +72,7 @@ struct TransactionInputDetails { boost::variant< TransactionInputGenerateDetails, - TransactionInputToKeyDetails, - TransactionInputMultisignatureDetails> input; + TransactionInputToKeyDetails> input; }; struct TransactionExtraDetails { @@ -106,12 +98,7 @@ struct KeyInputDetails { std::vector outputs; }; -struct MultisignatureInputDetails { - MultisignatureInput input; - TransactionOutputReferenceDetails output; -}; - -typedef boost::variant transactionInputDetails2; +typedef boost::variant transactionInputDetails2; struct TransactionExtraDetails2 { std::vector padding; diff --git a/include/CryptoNote.h b/include/CryptoNote.h index 69dc1ba6a2..64ecc2e7c0 100644 --- a/include/CryptoNote.h +++ b/include/CryptoNote.h @@ -34,24 +34,13 @@ struct KeyInput { Crypto::KeyImage keyImage; }; -struct MultisignatureInput { - uint64_t amount; - uint8_t signatureCount; - uint32_t outputIndex; -}; - struct KeyOutput { Crypto::PublicKey key; }; -struct MultisignatureOutput { - std::vector keys; - uint8_t requiredSignatureCount; -}; - -typedef boost::variant TransactionInput; +typedef boost::variant TransactionInput; -typedef boost::variant TransactionOutputTarget; +typedef boost::variant TransactionOutputTarget; struct TransactionOutput { uint64_t amount; diff --git a/include/INode.h b/include/INode.h index 9cf51ce58c..3109471cfb 100644 --- a/include/INode.h +++ b/include/INode.h @@ -168,7 +168,6 @@ class INode { virtual void getTransactionOutsGlobalIndices(const Crypto::Hash& transactionHash, std::vector& outsGlobalIndices, const Callback& callback) = 0; virtual void queryBlocks(std::vector&& knownBlockIds, uint64_t timestamp, std::vector& newBlocks, uint32_t& startHeight, const Callback& callback) = 0; virtual void getPoolSymmetricDifference(std::vector&& knownPoolTxIds, Crypto::Hash knownBlockId, bool& isBcActual, std::vector>& newTxs, std::vector& deletedTxIds, const Callback& callback) = 0; - virtual void getMultisignatureOutputByGlobalIndex(uint64_t amount, uint32_t gindex, MultisignatureOutput& out, const Callback& callback) = 0; virtual void getBlocks(const std::vector& blockHeights, std::vector>& blocks, const Callback& callback) = 0; virtual void getBlocks(const std::vector& blockHashes, std::vector& blocks, const Callback& callback) = 0; virtual void getBlocks(uint64_t timestampBegin, uint64_t timestampEnd, uint32_t blocksNumberLimit, std::vector& blocks, uint32_t& blocksNumberWithinTimestamps, const Callback& callback) = 0; diff --git a/include/ITransaction.h b/include/ITransaction.h index 732ee83992..42e2a307e5 100644 --- a/include/ITransaction.h +++ b/include/ITransaction.h @@ -28,8 +28,8 @@ namespace CryptoNote { namespace TransactionTypes { - enum class InputType : uint8_t { Invalid, Key, Multisignature, Generating }; - enum class OutputType : uint8_t { Invalid, Key, Multisignature }; + enum class InputType : uint8_t { Invalid, Key, Generating }; + enum class OutputType : uint8_t { Invalid, Key }; struct GlobalOutput { Crypto::PublicKey targetKey; @@ -75,7 +75,6 @@ class ITransactionReader { virtual uint64_t getInputTotalAmount() const = 0; virtual TransactionTypes::InputType getInputType(size_t index) const = 0; virtual void getInput(size_t index, KeyInput& input) const = 0; - virtual void getInput(size_t index, MultisignatureInput& input) const = 0; virtual std::vector getInputs() const = 0; // outputs @@ -83,7 +82,6 @@ class ITransactionReader { virtual uint64_t getOutputTotalAmount() const = 0; virtual TransactionTypes::OutputType getOutputType(size_t index) const = 0; virtual void getOutput(size_t index, KeyOutput& output, uint64_t& amount) const = 0; - virtual void getOutput(size_t index, MultisignatureOutput& output, uint64_t& amount) const = 0; // signatures virtual size_t getRequiredSignaturesCount(size_t inputIndex) const = 0; @@ -118,21 +116,16 @@ class ITransactionWriter { // Inputs/Outputs virtual size_t addInput(const KeyInput& input) = 0; - virtual size_t addInput(const MultisignatureInput& input) = 0; virtual size_t addInput(const AccountKeys& senderKeys, const TransactionTypes::InputKeyInfo& info, KeyPair& ephKeys) = 0; virtual size_t addOutput(uint64_t amount, const AccountPublicAddress& to) = 0; - virtual size_t addOutput(uint64_t amount, const std::vector& to, uint32_t requiredSignatures) = 0; virtual size_t addOutput(uint64_t amount, const KeyOutput& out) = 0; - virtual size_t addOutput(uint64_t amount, const MultisignatureOutput& out) = 0; // transaction info virtual void setTransactionSecretKey(const Crypto::SecretKey& key) = 0; // signing virtual void signInputKey(size_t input, const TransactionTypes::InputKeyInfo& info, const KeyPair& ephKeys) = 0; - virtual void signInputMultisignature(size_t input, const Crypto::PublicKey& sourceTransactionKey, size_t outputIndex, const AccountKeys& accountKeys) = 0; - virtual void signInputMultisignature(size_t input, const KeyPair& ephemeralKeys) = 0; }; class ITransaction : diff --git a/src/BlockchainExplorer/BlockchainExplorerDataBuilder.cpp b/src/BlockchainExplorer/BlockchainExplorerDataBuilder.cpp index 419dd635c6..14b9c77bf9 100755 --- a/src/BlockchainExplorer/BlockchainExplorerDataBuilder.cpp +++ b/src/BlockchainExplorer/BlockchainExplorerDataBuilder.cpp @@ -314,17 +314,6 @@ bool BlockchainExplorerDataBuilder::fillTransactionDetails(const Transaction& tr txInToKeyDetails.outputs.push_back(d); } txInDetails = txInToKeyDetails; - } else if (txIn.type() == typeid(MultisignatureInput)) { - MultisignatureInputDetails txInMultisigDetails; - const MultisignatureInput& txInMultisig = boost::get(txIn); - txInMultisigDetails.input = txInMultisig; - std::pair outputReference; - if (!m_core.getMultisigOutputReference(txInMultisig, outputReference)) { - return false; - } - txInMultisigDetails.output.number = outputReference.second; - txInMultisigDetails.output.transactionHash = outputReference.first; - txInDetails = txInMultisigDetails; } else { return false; } diff --git a/src/CryptoNoteCore/Blockchain.cpp b/src/CryptoNoteCore/Blockchain.cpp index c8109e7787..ae2cf83c32 100644 --- a/src/CryptoNoteCore/Blockchain.cpp +++ b/src/CryptoNoteCore/Blockchain.cpp @@ -179,9 +179,6 @@ class BlockCacheSerializer { logger(INFO) << operation << "outputs..."; s(m_bs.m_outputs, "outputs"); - logger(INFO) << operation << "multi-signature outputs..."; - s(m_bs.m_multisignatureOutputs, "multisig_outputs"); - logger(INFO) << operation << "hashing blobs..."; s(m_bs.m_blobs, "hashing_blobs"); @@ -540,7 +537,6 @@ void Blockchain::rebuildCache() { m_transactionMap.clear(); m_spent_key_images.clear(); m_outputs.clear(); - m_multisignatureOutputs.clear(); m_blobs.clear(); m_blobs.reserve(m_blocks.size()); for (uint32_t b = 0; b < m_blocks.size(); ++b) { @@ -560,9 +556,6 @@ void Blockchain::rebuildCache() { for (auto& i : transaction.tx.inputs) { if (i.type() == typeid(KeyInput)) { m_spent_key_images.insert(std::make_pair(::boost::get(i).keyImage, b)); - } else if (i.type() == typeid(MultisignatureInput)) { - auto out = ::boost::get(i); - m_multisignatureOutputs[out.amount][out.outputIndex].isUsed = true; } } @@ -571,9 +564,6 @@ void Blockchain::rebuildCache() { const auto& out = transaction.tx.outputs[o]; if (out.target.type() == typeid(KeyOutput)) { m_outputs[out.amount].push_back(std::make_pair<>(transactionIndex, o)); - } else if (out.target.type() == typeid(MultisignatureOutput)) { - MultisignatureOutputUsage usage = { transactionIndex, o, false }; - m_multisignatureOutputs[out.amount].push_back(usage); } } } @@ -1817,28 +1807,6 @@ bool Blockchain::getTransactionOutputGlobalIndexes(const Crypto::Hash& tx_id, st return true; } -bool Blockchain::get_out_by_msig_gindex(uint64_t amount, uint64_t gindex, MultisignatureOutput& out) { - std::lock_guard lk(m_blockchain_lock); - auto it = m_multisignatureOutputs.find(amount); - if (it == m_multisignatureOutputs.end()) { - return false; - } - - if (it->second.size() <= gindex) { - return false; - } - - auto msigUsage = it->second[gindex]; - auto& targetOut = transactionByIndex(msigUsage.transactionIndex).tx.outputs[msigUsage.outputIndex].target; - if (targetOut.type() != typeid(MultisignatureOutput)) { - return false; - } - - out = boost::get(targetOut); - return true; -} - - bool Blockchain::checkTransactionInputs(const Transaction& tx, uint32_t& max_used_block_height, Crypto::Hash& max_used_block_id, BlockInfo* tail) { std::lock_guard lk(m_blockchain_lock); @@ -1898,13 +1866,6 @@ bool Blockchain::checkTransactionInputs(const Transaction& tx, const Crypto::Has } } - ++inputIndex; - } else if (txin.type() == typeid(MultisignatureInput)) { - if (!isInCheckpointZone(getCurrentBlockchainHeight())) { - if (!validateInput(::boost::get(txin), transactionHash, tx_prefix_hash, tx.signatures[inputIndex])) { - return false; - } - } ++inputIndex; } else { logger(INFO, BRIGHT_WHITE) << @@ -2429,13 +2390,6 @@ bool Blockchain::pushTransaction(BlockEntry& block, const Crypto::Hash& transact TransactionEntry& transaction = block.transactions[transactionIndex.transaction]; - if (!checkMultisignatureInputsDiff(transaction.tx)) { - logger(ERROR, BRIGHT_RED) << - "Double spending transaction was pushed to blockchain."; - m_transactionMap.erase(transactionHash); - return false; - } - for (size_t i = 0; i < transaction.tx.inputs.size(); ++i) { if (transaction.tx.inputs[i].type() == typeid(KeyInput)) { auto result = m_spent_key_images.insert(std::make_pair(::boost::get(transaction.tx.inputs[i]).keyImage, block.height)); @@ -2451,25 +2405,12 @@ bool Blockchain::pushTransaction(BlockEntry& block, const Crypto::Hash& transact } } - for (const auto& inv : transaction.tx.inputs) { - if (inv.type() == typeid(MultisignatureInput)) { - const MultisignatureInput& in = ::boost::get(inv); - auto& amountOutputs = m_multisignatureOutputs[in.amount]; - amountOutputs[in.outputIndex].isUsed = true; - } - } - transaction.m_global_output_indexes.resize(transaction.tx.outputs.size()); for (uint16_t output = 0; output < transaction.tx.outputs.size(); ++output) { if (transaction.tx.outputs[output].target.type() == typeid(KeyOutput)) { auto& amountOutputs = m_outputs[transaction.tx.outputs[output].amount]; transaction.m_global_output_indexes[output] = static_cast(amountOutputs.size()); amountOutputs.push_back(std::make_pair<>(transactionIndex, output)); - } else if (transaction.tx.outputs[output].target.type() == typeid(MultisignatureOutput)) { - auto& amountOutputs = m_multisignatureOutputs[transaction.tx.outputs[output].amount]; - transaction.m_global_output_indexes[output] = static_cast(amountOutputs.size()); - MultisignatureOutputUsage outputUsage = { transactionIndex, output, false }; - amountOutputs.push_back(outputUsage); } } @@ -2512,42 +2453,6 @@ void Blockchain::popTransaction(const Transaction& transaction, const Crypto::Ha if (amountOutputs->second.empty()) { m_outputs.erase(amountOutputs); } - } else if (output.target.type() == typeid(MultisignatureOutput)) { - auto amountOutputs = m_multisignatureOutputs.find(output.amount); - if (amountOutputs == m_multisignatureOutputs.end()) { - logger(ERROR, BRIGHT_RED) << - "Blockchain consistency broken - cannot find specific amount in outputs map."; - continue; - } - - if (amountOutputs->second.empty()) { - logger(ERROR, BRIGHT_RED) << - "Blockchain consistency broken - output array for specific amount is empty."; - continue; - } - - if (amountOutputs->second.back().isUsed) { - logger(ERROR, BRIGHT_RED) << - "Blockchain consistency broken - attempting to remove used output."; - continue; - } - - if (amountOutputs->second.back().transactionIndex.block != transactionIndex.block || amountOutputs->second.back().transactionIndex.transaction != transactionIndex.transaction) { - logger(ERROR, BRIGHT_RED) << - "Blockchain consistency broken - invalid transaction index."; - continue; - } - - if (amountOutputs->second.back().outputIndex != transaction.outputs.size() - 1 - outputIndex) { - logger(ERROR, BRIGHT_RED) << - "Blockchain consistency broken - invalid output index."; - continue; - } - - amountOutputs->second.pop_back(); - if (amountOutputs->second.empty()) { - m_multisignatureOutputs.erase(amountOutputs); - } } } @@ -2558,15 +2463,6 @@ void Blockchain::popTransaction(const Transaction& transaction, const Crypto::Ha logger(ERROR, BRIGHT_RED) << "Blockchain consistency broken - cannot find spent key."; } - } else if (input.type() == typeid(MultisignatureInput)) { - const MultisignatureInput& in = ::boost::get(input); - auto& amountOutputs = m_multisignatureOutputs[in.amount]; - if (!amountOutputs[in.outputIndex].isUsed) { - logger(ERROR, BRIGHT_RED) << - "Blockchain consistency broken - multisignature output not marked as used."; - } - - amountOutputs[in.outputIndex].isUsed = false; } } @@ -2587,63 +2483,6 @@ void Blockchain::popTransactions(const BlockEntry& block, const Crypto::Hash& mi popTransaction(block.bl.baseTransaction, minerTransactionHash); } -bool Blockchain::validateInput(const MultisignatureInput& input, const Crypto::Hash& transactionHash, const Crypto::Hash& transactionPrefixHash, const std::vector& transactionSignatures) { - assert(input.signatureCount == transactionSignatures.size()); - MultisignatureOutputsContainer::const_iterator amountOutputs = m_multisignatureOutputs.find(input.amount); - if (amountOutputs == m_multisignatureOutputs.end()) { - logger(DEBUGGING) << - "Transaction << " << transactionHash << " contains multisignature input with invalid amount."; - return false; - } - - if (input.outputIndex >= amountOutputs->second.size()) { - logger(DEBUGGING) << - "Transaction << " << transactionHash << " contains multisignature input with invalid outputIndex."; - return false; - } - - const MultisignatureOutputUsage& outputIndex = amountOutputs->second[input.outputIndex]; - if (outputIndex.isUsed) { - logger(DEBUGGING) << - "Transaction << " << transactionHash << " contains double spending multisignature input."; - return false; - } - - const Transaction& outputTransaction = m_blocks[outputIndex.transactionIndex.block].transactions[outputIndex.transactionIndex.transaction].tx; - if (!is_tx_spendtime_unlocked(outputTransaction.unlockTime)) { - logger(DEBUGGING) << - "Transaction << " << transactionHash << " contains multisignature input which points to a locked transaction."; - return false; - } - - assert(outputTransaction.outputs[outputIndex.outputIndex].amount == input.amount); - assert(outputTransaction.outputs[outputIndex.outputIndex].target.type() == typeid(MultisignatureOutput)); - const MultisignatureOutput& output = ::boost::get(outputTransaction.outputs[outputIndex.outputIndex].target); - if (input.signatureCount != output.requiredSignatureCount) { - logger(DEBUGGING) << - "Transaction << " << transactionHash << " contains multisignature input with invalid signature count."; - return false; - } - - size_t inputSignatureIndex = 0; - size_t outputKeyIndex = 0; - while (inputSignatureIndex < input.signatureCount) { - if (outputKeyIndex == output.keys.size()) { - logger(DEBUGGING) << - "Transaction << " << transactionHash << " contains multisignature input with invalid signatures."; - return false; - } - - if (Crypto::check_signature(transactionPrefixHash, output.keys[outputKeyIndex], transactionSignatures[inputSignatureIndex])) { - ++inputSignatureIndex; - } - - ++outputKeyIndex; - } - - return true; -} - bool Blockchain::checkCheckpoints(uint32_t& lastValidCheckpointHeight) { std::vector checkpointHeights = m_checkpoints.getCheckpointHeights(); for (const auto& checkpointHeight : checkpointHeights) { @@ -2775,24 +2614,6 @@ bool Blockchain::getBlockSize(const Crypto::Hash& hash, size_t& size) { return false; } -bool Blockchain::getMultisigOutputReference(const MultisignatureInput& txInMultisig, std::pair& outputReference) { - std::lock_guard lk(m_blockchain_lock); - MultisignatureOutputsContainer::const_iterator amountIter = m_multisignatureOutputs.find(txInMultisig.amount); - if (amountIter == m_multisignatureOutputs.end()) { - logger(DEBUGGING) << "Transaction contains multisignature input with invalid amount."; - return false; - } - if (amountIter->second.size() <= txInMultisig.outputIndex) { - logger(DEBUGGING) << "Transaction contains multisignature input with invalid outputIndex."; - return false; - } - const MultisignatureOutputUsage& outputIndex = amountIter->second[txInMultisig.outputIndex]; - const Transaction& outputTransaction = m_blocks[outputIndex.transactionIndex.block].transactions[outputIndex.transactionIndex.transaction].tx; - outputReference.first = getObjectHash(outputTransaction); - outputReference.second = outputIndex.outputIndex; - return true; -} - bool Blockchain::storeBlockchainIndices() { std::lock_guard lk(m_blockchain_lock); diff --git a/src/CryptoNoteCore/Blockchain.h b/src/CryptoNoteCore/Blockchain.h index f82c4a2c66..5ed2ff8e5d 100755 --- a/src/CryptoNoteCore/Blockchain.h +++ b/src/CryptoNoteCore/Blockchain.h @@ -111,7 +111,6 @@ namespace CryptoNote { bool getRandomOutsByAmount(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response& res); bool getBackwardBlocksSize(size_t from_height, std::vector& sz, size_t count); bool getTransactionOutputGlobalIndexes(const Crypto::Hash& tx_id, std::vector& indexs); - bool get_out_by_msig_gindex(uint64_t amount, uint64_t gindex, MultisignatureOutput& out); bool checkTransactionInputs(const Transaction& tx, uint32_t& pmax_used_block_height, Crypto::Hash& max_used_block_id, BlockInfo* tail = 0); uint64_t getCurrentCumulativeBlocksizeLimit(); uint64_t blockDifficulty(size_t i); @@ -120,7 +119,6 @@ namespace CryptoNote { bool getBlockContainingTransaction(const Crypto::Hash& txId, Crypto::Hash& blockId, uint32_t& blockHeight); bool getAlreadyGeneratedCoins(const Crypto::Hash& hash, uint64_t& generatedCoins); bool getBlockSize(const Crypto::Hash& hash, size_t& size); - bool getMultisigOutputReference(const MultisignatureInput& txInMultisig, std::pair& outputReference); bool getGeneratedTransactionsNumber(uint32_t height, uint64_t& generatedTransactions); bool getOrphanBlockIdsByHeight(uint32_t height, std::vector& blockHashes); bool getBlockIdsByTimestamp(uint64_t timestampBegin, uint64_t timestampEnd, uint32_t blocksNumberLimit, std::vector& hashes, uint32_t& blocksNumberWithinTimestamps); @@ -217,18 +215,6 @@ namespace CryptoNote { private: - struct MultisignatureOutputUsage { - TransactionIndex transactionIndex; - uint16_t outputIndex; - bool isUsed; - - void serialize(ISerializer& s) { - s(transactionIndex, "txindex"); - s(outputIndex, "outindex"); - s(isUsed, "used"); - } - }; - struct TransactionEntry { Transaction tx; std::vector m_global_output_indexes; @@ -260,7 +246,6 @@ namespace CryptoNote { typedef parallel_flat_hash_map key_images_container; typedef parallel_flat_hash_map blocks_ext_by_hash; typedef parallel_flat_hash_map>> outputs_container; //Crypto::Hash - tx hash, size_t - index of out in transaction - typedef parallel_flat_hash_map> MultisignatureOutputsContainer; typedef std::vector hashing_blobs_container; @@ -288,7 +273,6 @@ namespace CryptoNote { Blocks m_blocks; CryptoNote::BlockIndex m_blockIndex; TransactionMap m_transactionMap; - MultisignatureOutputsContainer m_multisignatureOutputs; hashing_blobs_container m_blobs; @@ -342,7 +326,6 @@ namespace CryptoNote { bool pushTransaction(BlockEntry& block, const Crypto::Hash& transactionHash, TransactionIndex transactionIndex); void popTransaction(const Transaction& transaction, const Crypto::Hash& transactionHash); void popTransactions(const BlockEntry& block, const Crypto::Hash& minerTransactionHash); - bool validateInput(const MultisignatureInput& input, const Crypto::Hash& transactionHash, const Crypto::Hash& transactionPrefixHash, const std::vector& transactionSignatures); bool checkCheckpoints(uint32_t& lastValidCheckpointHeight); void removeLastBlock(); bool checkUpgradeHeight(const UpgradeDetector& upgradeDetector); diff --git a/src/CryptoNoteCore/Core.cpp b/src/CryptoNoteCore/Core.cpp index eb20caf2b9..2d67c4f1fb 100755 --- a/src/CryptoNoteCore/Core.cpp +++ b/src/CryptoNoteCore/Core.cpp @@ -439,11 +439,6 @@ bool Core::check_tx_semantic(const Transaction& tx, const Crypto::Hash& txHash, return false; } - if (!checkMultisignatureInputsDiff(tx)) { - logger(ERROR) << "tx has a few multisignature inputs with identical output indexes"; - return false; - } - return true; } @@ -648,10 +643,6 @@ bool Core::get_tx_outputs_gindexs(const Crypto::Hash& tx_id, std::vectorpause(); } @@ -1112,10 +1103,6 @@ bool Core::getBlockContainingTx(const Crypto::Hash& txId, Crypto::Hash& blockId, return m_blockchain.getBlockContainingTransaction(txId, blockId, blockHeight); } -bool Core::getMultisigOutputReference(const MultisignatureInput& txInMultisig, std::pair& outputReference) { - return m_blockchain.getMultisigOutputReference(txInMultisig, outputReference); -} - bool Core::getGeneratedTransactionsNumber(uint32_t height, uint64_t& generatedTransactions) { return m_blockchain.getGeneratedTransactionsNumber(height, generatedTransactions); } diff --git a/src/CryptoNoteCore/Core.h b/src/CryptoNoteCore/Core.h index a96e3b83b2..304bf3a866 100755 --- a/src/CryptoNoteCore/Core.h +++ b/src/CryptoNoteCore/Core.h @@ -83,14 +83,12 @@ namespace CryptoNote { virtual bool getBlockCumulativeDifficulty(uint32_t height, difficulty_type& difficulty) override; virtual bool getBlockTimestamp(uint32_t height, uint64_t& timestamp) override; virtual bool getBlockContainingTx(const Crypto::Hash& txId, Crypto::Hash& blockId, uint32_t& blockHeight) override; - virtual bool getMultisigOutputReference(const MultisignatureInput& txInMultisig, std::pair& output_reference) override; virtual bool getGeneratedTransactionsNumber(uint32_t height, uint64_t& generatedTransactions) override; virtual bool getOrphanBlocksByHeight(uint32_t height, std::vector& blocks) override; virtual bool getBlocksByTimestamp(uint64_t timestampBegin, uint64_t timestampEnd, uint32_t blocksNumberLimit, std::vector& blocks, uint32_t& blocksNumberWithinTimestamps) override; virtual bool getPoolTransactionsByTimestamp(uint64_t timestampBegin, uint64_t timestampEnd, uint32_t transactionsNumberLimit, std::vector& transactions, uint64_t& transactionsNumberWithinTimestamps) override; virtual bool getTransactionsByPaymentId(const Crypto::Hash& paymentId, std::vector& transactions) override; virtual std::vector getTransactionHashesByPaymentId(const Crypto::Hash& paymentId) override; - virtual bool getOutByMSigGIndex(uint64_t amount, uint64_t gindex, MultisignatureOutput& out) override; virtual std::unique_ptr getBlock(const Crypto::Hash& blocksId) override; virtual bool handleIncomingTransaction(const Transaction& tx, const Crypto::Hash& txHash, size_t blobSize, tx_verification_context& tvc, bool keptByBlock, uint32_t height) override; virtual std::error_code executeLocked(const std::function& func) override; diff --git a/src/CryptoNoteCore/CryptoNoteFormatUtils.cpp b/src/CryptoNoteCore/CryptoNoteFormatUtils.cpp index 183ec7c8ff..37d8619b58 100644 --- a/src/CryptoNoteCore/CryptoNoteFormatUtils.cpp +++ b/src/CryptoNoteCore/CryptoNoteFormatUtils.cpp @@ -95,8 +95,6 @@ bool get_tx_fee(const Transaction& tx, uint64_t & fee) { for (const auto& in : tx.inputs) { if (in.type() == typeid(KeyInput)) { amount_in += boost::get(in).amount; - } else if (in.type() == typeid(MultisignatureInput)) { - amount_in += boost::get(in).amount; } } @@ -287,8 +285,6 @@ bool get_inputs_money_amount(const Transaction& tx, uint64_t& money) { if (in.type() == typeid(KeyInput)) { amount = boost::get(in).amount; - } else if (in.type() == typeid(MultisignatureInput)) { - amount = boost::get(in).amount; } money += amount; @@ -309,7 +305,7 @@ uint32_t get_block_height(const Block& b) { bool check_inputs_types_supported(const TransactionPrefix& tx) { for (const auto& in : tx.inputs) { - if (in.type() != typeid(KeyInput) && in.type() != typeid(MultisignatureInput)) { + if (in.type() != typeid(KeyInput)) { return false; } } @@ -343,31 +339,6 @@ bool check_outs_valid(const TransactionPrefix& tx, std::string* error) { return false; } keys_seen.insert(boost::get(out.target).key); - } else if (out.target.type() == typeid(MultisignatureOutput)) { - const MultisignatureOutput& multisignatureOutput = ::boost::get(out.target); - if (multisignatureOutput.requiredSignatureCount > multisignatureOutput.keys.size()) { - if (error) { - *error = "Multisignature output with invalid required signature count"; - } - return false; - } - for (const PublicKey& key : multisignatureOutput.keys) { - if (!check_key(key)) { - if (error) { - *error = "Multisignature output with invalid public key"; - } - return false; - } - - if (keys_seen.find(key) != keys_seen.end()) { - if (error) { - *error = "The same multisignature output target is present more than once"; - } - return false; - } - keys_seen.insert(key); - - } } else { if (error) { *error = "Output with invalid type"; @@ -379,19 +350,6 @@ bool check_outs_valid(const TransactionPrefix& tx, std::string* error) { return true; } -bool checkMultisignatureInputsDiff(const TransactionPrefix& tx) { - std::set> inputsUsage; - for (const auto& inv : tx.inputs) { - if (inv.type() == typeid(MultisignatureInput)) { - const MultisignatureInput& in = ::boost::get(inv); - if (!inputsUsage.insert(std::make_pair(in.amount, in.outputIndex)).second) { - return false; - } - } - } - return true; -} - bool check_money_overflow(const TransactionPrefix &tx) { return check_inputs_overflow(tx) && check_outs_overflow(tx); } @@ -404,8 +362,6 @@ bool check_inputs_overflow(const TransactionPrefix &tx) { if (in.type() == typeid(KeyInput)) { amount = boost::get(in).amount; - } else if (in.type() == typeid(MultisignatureInput)) { - amount = boost::get(in).amount; } if (money > amount + money) @@ -473,7 +429,7 @@ bool lookup_acc_outs(const AccountKeys& acc, const Transaction& tx, const Public generate_key_derivation(tx_pub_key, acc.viewSecretKey, derivation); for (const TransactionOutput& o : tx.outputs) { - assert(o.target.type() == typeid(KeyOutput) || o.target.type() == typeid(MultisignatureOutput)); + assert(o.target.type() == typeid(KeyOutput)); if (o.target.type() == typeid(KeyOutput)) { if (is_out_to_acc(acc, boost::get(o.target), derivation, keyIndex)) { outs.push_back(outputIndex); @@ -481,8 +437,6 @@ bool lookup_acc_outs(const AccountKeys& acc, const Transaction& tx, const Public } ++keyIndex; - } else if (o.target.type() == typeid(MultisignatureOutput)) { - keyIndex += boost::get(o.target).keys.size(); } ++outputIndex; diff --git a/src/CryptoNoteCore/CryptoNoteSerialization.cpp b/src/CryptoNoteCore/CryptoNoteSerialization.cpp index 4358ad3b43..d63e7d34a8 100644 --- a/src/CryptoNoteCore/CryptoNoteSerialization.cpp +++ b/src/CryptoNoteCore/CryptoNoteSerialization.cpp @@ -49,7 +49,6 @@ size_t getSignaturesCount(const TransactionInput& input) { struct txin_signature_size_visitor : public boost::static_visitor < size_t > { size_t operator()(const BaseInput& txin) const { return 0; } size_t operator()(const KeyInput& txin) const { return txin.outputIndexes.size(); } - size_t operator()(const MultisignatureInput& txin) const { return txin.signatureCount; } }; return boost::apply_visitor(txin_signature_size_visitor(), input); @@ -58,9 +57,7 @@ size_t getSignaturesCount(const TransactionInput& input) { struct BinaryVariantTagGetter: boost::static_visitor { uint8_t operator()(const CryptoNote::BaseInput) { return 0xff; } uint8_t operator()(const CryptoNote::KeyInput) { return 0x2; } - uint8_t operator()(const CryptoNote::MultisignatureInput) { return 0x3; } uint8_t operator()(const CryptoNote::KeyOutput) { return 0x2; } - uint8_t operator()(const CryptoNote::MultisignatureOutput) { return 0x3; } uint8_t operator()(const CryptoNote::Transaction) { return 0xcc; } uint8_t operator()(const CryptoNote::Block) { return 0xbb; } }; @@ -89,12 +86,6 @@ void getVariantValue(CryptoNote::ISerializer& serializer, uint8_t tag, CryptoNot in = v; break; } - case 0x3: { - CryptoNote::MultisignatureInput v; - serializer(v, "value"); - in = v; - break; - } default: throw std::runtime_error("Unknown variant tag"); } @@ -108,12 +99,6 @@ void getVariantValue(CryptoNote::ISerializer& serializer, uint8_t tag, CryptoNot out = v; break; } - case 0x3: { - CryptoNote::MultisignatureOutput v; - serializer(v, "data"); - out = v; - break; - } default: throw std::runtime_error("Unknown variant tag"); } @@ -270,12 +255,6 @@ void serialize(KeyInput& key, ISerializer& serializer) { serializer(key.keyImage, "k_image"); } -void serialize(MultisignatureInput& multisignature, ISerializer& serializer) { - serializer(multisignature.amount, "amount"); - serializer(multisignature.signatureCount, "signatures"); - serializer(multisignature.outputIndex, "outputIndex"); -} - void serialize(TransactionInputs & inputs, ISerializer & serializer) { serializer(inputs, "vin"); } @@ -305,11 +284,6 @@ void serialize(KeyOutput& key, ISerializer& serializer) { serializer(key.key, "key"); } -void serialize(MultisignatureOutput& multisignature, ISerializer& serializer) { - serializer(multisignature.keys, "keys"); - serializer(multisignature.requiredSignatureCount, "required_signatures"); -} - void serialize(ParentBlockSerializer& pbs, ISerializer& serializer) { serializer(pbs.m_parentBlock.majorVersion, "majorVersion"); diff --git a/src/CryptoNoteCore/CryptoNoteSerialization.h b/src/CryptoNoteCore/CryptoNoteSerialization.h index 0e5fad8af7..f8eac5d580 100755 --- a/src/CryptoNoteCore/CryptoNoteSerialization.h +++ b/src/CryptoNoteCore/CryptoNoteSerialization.h @@ -47,14 +47,12 @@ void serialize(TransactionOutput& in, ISerializer& serializer); void serialize(BaseInput& gen, ISerializer& serializer); void serialize(KeyInput& key, ISerializer& serializer); -void serialize(MultisignatureInput& multisignature, ISerializer& serializer); void serialize(TransactionInputs & inputs, ISerializer & serializer); void serialize(TransactionOutput& output, ISerializer& serializer); void serialize(TransactionOutputTarget& output, ISerializer& serializer); void serialize(KeyOutput& key, ISerializer& serializer); -void serialize(MultisignatureOutput& multisignature, ISerializer& serializer); void serialize(BlockHeader& header, ISerializer& serializer); void serialize(Block& block, ISerializer& serializer); diff --git a/src/CryptoNoteCore/CryptoNoteTools.cpp b/src/CryptoNoteCore/CryptoNoteTools.cpp index 91402a2fca..59a31026fc 100755 --- a/src/CryptoNoteCore/CryptoNoteTools.cpp +++ b/src/CryptoNoteCore/CryptoNoteTools.cpp @@ -48,8 +48,6 @@ uint64_t getInputAmount(const Transaction& transaction) { for (auto& input : transaction.inputs) { if (input.type() == typeid(KeyInput)) { amount += boost::get(input).amount; - } else if (input.type() == typeid(MultisignatureInput)) { - amount += boost::get(input).amount; } } @@ -63,8 +61,6 @@ std::vector getInputsAmounts(const Transaction& transaction) { for (auto& input: transaction.inputs) { if (input.type() == typeid(KeyInput)) { inputsAmounts.push_back(boost::get(input).amount); - } else if (input.type() == typeid(MultisignatureInput)) { - inputsAmounts.push_back(boost::get(input).amount); } } diff --git a/src/CryptoNoteCore/ICore.h b/src/CryptoNoteCore/ICore.h index 668fa963b3..6361e47518 100755 --- a/src/CryptoNoteCore/ICore.h +++ b/src/CryptoNoteCore/ICore.h @@ -48,7 +48,6 @@ struct BlockShortInfo; struct core_stat_info; struct i_cryptonote_protocol; struct Transaction; -struct MultisignatureInput; struct KeyInput; struct TransactionPrefixInfo; struct tx_verification_context; @@ -79,7 +78,6 @@ class ICore { uint32_t& totalBlockCount, uint32_t& startBlockIndex) = 0; virtual bool get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response& res) = 0; virtual bool get_tx_outputs_gindexs(const Crypto::Hash& tx_id, std::vector& indexs) = 0; - virtual bool getOutByMSigGIndex(uint64_t amount, uint64_t gindex, MultisignatureOutput& out) = 0; virtual i_cryptonote_protocol* get_protocol() = 0; virtual bool handle_incoming_tx(const BinaryArray& tx_blob, tx_verification_context& tvc, bool keeped_by_block) = 0; //Deprecated. Should be removed with CryptoNoteProtocolHandler. virtual std::vector getPoolTransactions() = 0; @@ -112,7 +110,6 @@ class ICore { virtual bool getBlockCumulativeDifficulty(uint32_t height, difficulty_type& difficulty) = 0; virtual bool getBlockTimestamp(uint32_t height, uint64_t& timestamp) = 0; virtual bool getBlockContainingTx(const Crypto::Hash& txId, Crypto::Hash& blockId, uint32_t& blockHeight) = 0; - virtual bool getMultisigOutputReference(const MultisignatureInput& txInMultisig, std::pair& outputReference) = 0; virtual bool getGeneratedTransactionsNumber(uint32_t height, uint64_t& generatedTransactions) = 0; virtual bool getOrphanBlocksByHeight(uint32_t height, std::vector& blocks) = 0; diff --git a/src/CryptoNoteCore/Transaction.cpp b/src/CryptoNoteCore/Transaction.cpp index 3fc3efa15c..f8fc68ca4a 100755 --- a/src/CryptoNoteCore/Transaction.cpp +++ b/src/CryptoNoteCore/Transaction.cpp @@ -70,7 +70,6 @@ namespace CryptoNote { virtual uint64_t getInputTotalAmount() const override; virtual TransactionTypes::InputType getInputType(size_t index) const override; virtual void getInput(size_t index, KeyInput& input) const override; - virtual void getInput(size_t index, MultisignatureInput& input) const override; virtual std::vector getInputs() const override; // outputs @@ -78,7 +77,6 @@ namespace CryptoNote { virtual uint64_t getOutputTotalAmount() const override; virtual TransactionTypes::OutputType getOutputType(size_t index) const override; virtual void getOutput(size_t index, KeyOutput& output, uint64_t& amount) const override; - virtual void getOutput(size_t index, MultisignatureOutput& output, uint64_t& amount) const override; virtual size_t getRequiredSignaturesCount(size_t index) const override; virtual bool findOutputsToAccount(const AccountPublicAddress& addr, const SecretKey& viewSecretKey, std::vector& outs, uint64_t& outputAmount) const override; @@ -102,18 +100,12 @@ namespace CryptoNote { // Inputs/Outputs virtual size_t addInput(const KeyInput& input) override; - virtual size_t addInput(const MultisignatureInput& input) override; virtual size_t addInput(const AccountKeys& senderKeys, const TransactionTypes::InputKeyInfo& info, KeyPair& ephKeys) override; virtual size_t addOutput(uint64_t amount, const AccountPublicAddress& to) override; - virtual size_t addOutput(uint64_t amount, const std::vector& to, uint32_t requiredSignatures) override; virtual size_t addOutput(uint64_t amount, const KeyOutput& out) override; - virtual size_t addOutput(uint64_t amount, const MultisignatureOutput& out) override; virtual void signInputKey(size_t input, const TransactionTypes::InputKeyInfo& info, const KeyPair& ephKeys) override; - virtual void signInputMultisignature(size_t input, const PublicKey& sourceTransactionKey, size_t outputIndex, const AccountKeys& accountKeys) override; - virtual void signInputMultisignature(size_t input, const KeyPair& ephemeralKeys) override; - // secret key virtual bool getTransactionSecretKey(SecretKey& key) const override; @@ -276,13 +268,6 @@ namespace CryptoNote { return addInput(input); } - size_t TransactionImpl::addInput(const MultisignatureInput& input) { - checkIfSigning(); - transaction.inputs.push_back(input); - invalidateHash(); - return transaction.inputs.size() - 1; - } - size_t TransactionImpl::addOutput(uint64_t amount, const AccountPublicAddress& to) { checkIfSigning(); @@ -295,26 +280,6 @@ namespace CryptoNote { return transaction.outputs.size() - 1; } - size_t TransactionImpl::addOutput(uint64_t amount, const std::vector& to, uint32_t requiredSignatures) { - checkIfSigning(); - - const auto& txKey = txSecretKey(); - size_t outputIndex = transaction.outputs.size(); - MultisignatureOutput outMsig; - outMsig.requiredSignatureCount = requiredSignatures; - outMsig.keys.resize(to.size()); - - for (size_t i = 0; i < to.size(); ++i) { - derivePublicKey(to[i], txKey, outputIndex, outMsig.keys[i]); - } - - TransactionOutput out = { amount, outMsig }; - transaction.outputs.emplace_back(out); - invalidateHash(); - - return outputIndex; - } - size_t TransactionImpl::addOutput(uint64_t amount, const KeyOutput& out) { checkIfSigning(); size_t outputIndex = transaction.outputs.size(); @@ -324,15 +289,6 @@ namespace CryptoNote { return outputIndex; } - size_t TransactionImpl::addOutput(uint64_t amount, const MultisignatureOutput& out) { - checkIfSigning(); - size_t outputIndex = transaction.outputs.size(); - TransactionOutput realOut = { amount, out }; - transaction.outputs.emplace_back(realOut); - invalidateHash(); - return outputIndex; - } - void TransactionImpl::signInputKey(size_t index, const TransactionTypes::InputKeyInfo& info, const KeyPair& ephKeys) { const auto& input = boost::get(getInputChecked(transaction, index, TransactionTypes::InputType::Key)); Hash prefixHash = getTransactionPrefixHash(); @@ -358,41 +314,6 @@ namespace CryptoNote { invalidateHash(); } - void TransactionImpl::signInputMultisignature(size_t index, const PublicKey& sourceTransactionKey, size_t outputIndex, const AccountKeys& accountKeys) { - KeyDerivation derivation; - PublicKey ephemeralPublicKey; - SecretKey ephemeralSecretKey; - - generate_key_derivation( - reinterpret_cast(sourceTransactionKey), - reinterpret_cast(accountKeys.viewSecretKey), - derivation); - - derive_public_key(derivation, outputIndex, - reinterpret_cast(accountKeys.address.spendPublicKey), ephemeralPublicKey); - derive_secret_key(derivation, outputIndex, - reinterpret_cast(accountKeys.spendSecretKey), ephemeralSecretKey); - - Signature signature; - auto txPrefixHash = getTransactionPrefixHash(); - - generate_signature(reinterpret_cast(txPrefixHash), - ephemeralPublicKey, ephemeralSecretKey, signature); - - getSignatures(index).push_back(signature); - invalidateHash(); - } - - void TransactionImpl::signInputMultisignature(size_t index, const KeyPair& ephemeralKeys) { - Signature signature; - auto txPrefixHash = getTransactionPrefixHash(); - - generate_signature(txPrefixHash, ephemeralKeys.publicKey, ephemeralKeys.secretKey, signature); - - getSignatures(index).push_back(signature); - invalidateHash(); - } - std::vector& TransactionImpl::getSignatures(size_t input) { // update signatures container size if needed if (transaction.signatures.size() < transaction.inputs.size()) { @@ -477,10 +398,6 @@ namespace CryptoNote { input = boost::get(getInputChecked(transaction, index, TransactionTypes::InputType::Key)); } - void TransactionImpl::getInput(size_t index, MultisignatureInput& input) const { - input = boost::get(getInputChecked(transaction, index, TransactionTypes::InputType::Multisignature)); - } - std::vector TransactionImpl::getInputs() const { return transaction.inputs; } @@ -504,12 +421,6 @@ namespace CryptoNote { amount = out.amount; } - void TransactionImpl::getOutput(size_t index, MultisignatureOutput& output, uint64_t& amount) const { - const auto& out = getOutputChecked(transaction, index, TransactionTypes::OutputType::Multisignature); - output = boost::get(out.target); - amount = out.amount; - } - bool TransactionImpl::findOutputsToAccount(const AccountPublicAddress& addr, const SecretKey& viewSecretKey, std::vector& out, uint64_t& amount) const { return ::CryptoNote::findOutputsToAccount(transaction, addr, viewSecretKey, out, amount); } @@ -522,8 +433,7 @@ namespace CryptoNote { return check_inputs_types_supported(transaction) && check_inputs_overflow(transaction) && - checkInputsKeyimagesDiff(transaction) && - checkMultisignatureInputsDiff(transaction); + checkInputsKeyimagesDiff(transaction); } bool TransactionImpl::validateOutputs() const { diff --git a/src/CryptoNoteCore/TransactionPool.cpp b/src/CryptoNoteCore/TransactionPool.cpp index 9df547abe7..5b6187234a 100644 --- a/src/CryptoNoteCore/TransactionPool.cpp +++ b/src/CryptoNoteCore/TransactionPool.cpp @@ -58,11 +58,6 @@ namespace CryptoNote { auto r = m_keyImages.insert(boost::get(in).keyImage); (void)r; //just to make compiler to shut up assert(r.second); - } else if (in.type() == typeid(MultisignatureInput)) { - const auto& msig = boost::get(in); - auto r = m_usedOutputs.insert(std::make_pair(msig.amount, msig.outputIndex)); - (void)r; //just to make compiler to shut up - assert(r.second); } } @@ -82,11 +77,6 @@ namespace CryptoNote { if (m_keyImages.count(boost::get(in).keyImage)) { return false; } - } else if (in.type() == typeid(MultisignatureInput)) { - const auto& msig = boost::get(in); - if (m_usedOutputs.count(std::make_pair(msig.amount, msig.outputIndex))) { - return false; - } } } return true; @@ -621,13 +611,6 @@ namespace CryptoNote { //it is now empty hash container for this key_image m_spent_key_images.erase(it); } - } else if (in.type() == typeid(MultisignatureInput)) { - if (!keptByBlock) { - const auto& msig = boost::get(in); - auto output = GlobalOutput(msig.amount, msig.outputIndex); - assert(m_spentOutputs.count(output)); - m_spentOutputs.erase(output); - } } } @@ -653,13 +636,6 @@ namespace CryptoNote { logger(ERROR, BRIGHT_RED) << "internal error: try to insert duplicate iterator in key_image set"; return false; } - } else if (in.type() == typeid(MultisignatureInput)) { - if (!keptByBlock) { - const auto& msig = boost::get(in); - auto r = m_spentOutputs.insert(GlobalOutput(msig.amount, msig.outputIndex)); - (void)r; - assert(r.second); - } } } @@ -674,11 +650,6 @@ namespace CryptoNote { if (m_spent_key_images.count(tokey_in.keyImage)) { return true; } - } else if (in.type() == typeid(MultisignatureInput)) { - const auto& msig = boost::get(in); - if (m_spentOutputs.count(GlobalOutput(msig.amount, msig.outputIndex))) { - return true; - } } } return false; diff --git a/src/CryptoNoteCore/TransactionPrefixImpl.cpp b/src/CryptoNoteCore/TransactionPrefixImpl.cpp index 1e83cf657c..b653125381 100755 --- a/src/CryptoNoteCore/TransactionPrefixImpl.cpp +++ b/src/CryptoNoteCore/TransactionPrefixImpl.cpp @@ -52,16 +52,14 @@ class TransactionPrefixImpl : public ITransactionReader { virtual uint64_t getInputTotalAmount() const override; virtual TransactionTypes::InputType getInputType(size_t index) const override; virtual void getInput(size_t index, KeyInput& input) const override; - virtual void getInput(size_t index, MultisignatureInput& input) const override; - virtual std::vector getInputs() const override; + virtual std::vector getInputs() const override; // outputs virtual size_t getOutputCount() const override; virtual uint64_t getOutputTotalAmount() const override; virtual TransactionTypes::OutputType getOutputType(size_t index) const override; virtual void getOutput(size_t index, KeyOutput& output, uint64_t& amount) const override; - virtual void getOutput(size_t index, MultisignatureOutput& output, uint64_t& amount) const override; - + // signatures virtual size_t getRequiredSignaturesCount(size_t inputIndex) const override; virtual bool findOutputsToAccount(const AccountPublicAddress& addr, const SecretKey& viewSecretKey, std::vector& outs, uint64_t& outputAmount) const override; @@ -162,10 +160,6 @@ void TransactionPrefixImpl::getInput(size_t index, KeyInput& input) const { input = boost::get(getInputChecked(m_txPrefix, index, TransactionTypes::InputType::Key)); } -void TransactionPrefixImpl::getInput(size_t index, MultisignatureInput& input) const { - input = boost::get(getInputChecked(m_txPrefix, index, TransactionTypes::InputType::Multisignature)); -} - std::vector TransactionPrefixImpl::getInputs() const { return m_txPrefix.inputs; } @@ -189,12 +183,6 @@ void TransactionPrefixImpl::getOutput(size_t index, KeyOutput& output, uint64_t& amount = out.amount; } -void TransactionPrefixImpl::getOutput(size_t index, MultisignatureOutput& output, uint64_t& amount) const { - const auto& out = getOutputChecked(m_txPrefix, index, TransactionTypes::OutputType::Multisignature); - output = boost::get(out.target); - amount = out.amount; -} - size_t TransactionPrefixImpl::getRequiredSignaturesCount(size_t inputIndex) const { return ::CryptoNote::getRequiredSignaturesCount(getInputChecked(m_txPrefix, inputIndex)); } @@ -205,14 +193,13 @@ bool TransactionPrefixImpl::findOutputsToAccount(const AccountPublicAddress& add bool TransactionPrefixImpl::validateInputs() const { return check_inputs_types_supported(m_txPrefix) && - check_inputs_overflow(m_txPrefix) && - checkInputsKeyimagesDiff(m_txPrefix) && - checkMultisignatureInputsDiff(m_txPrefix); + check_inputs_overflow(m_txPrefix) && + checkInputsKeyimagesDiff(m_txPrefix); } bool TransactionPrefixImpl::validateOutputs() const { return check_outs_valid(m_txPrefix) && - check_outs_overflow(m_txPrefix); + check_outs_overflow(m_txPrefix); } bool TransactionPrefixImpl::validateSignatures() const { diff --git a/src/CryptoNoteCore/TransactionUtils.cpp b/src/CryptoNoteCore/TransactionUtils.cpp index e24f1b00e3..e00d351347 100755 --- a/src/CryptoNoteCore/TransactionUtils.cpp +++ b/src/CryptoNoteCore/TransactionUtils.cpp @@ -45,9 +45,6 @@ size_t getRequiredSignaturesCount(const TransactionInput& in) { if (in.type() == typeid(KeyInput)) { return boost::get(in).outputIndexes.size(); } - if (in.type() == typeid(MultisignatureInput)) { - return boost::get(in).signatureCount; - } return 0; } @@ -55,9 +52,6 @@ uint64_t getTransactionInputAmount(const TransactionInput& in) { if (in.type() == typeid(KeyInput)) { return boost::get(in).amount; } - if (in.type() == typeid(MultisignatureInput)) { - return boost::get(in).amount; - } return 0; } @@ -65,9 +59,6 @@ TransactionTypes::InputType getTransactionInputType(const TransactionInput& in) if (in.type() == typeid(KeyInput)) { return TransactionTypes::InputType::Key; } - if (in.type() == typeid(MultisignatureInput)) { - return TransactionTypes::InputType::Multisignature; - } if (in.type() == typeid(BaseInput)) { return TransactionTypes::InputType::Generating; } @@ -95,9 +86,6 @@ TransactionTypes::OutputType getTransactionOutputType(const TransactionOutputTar if (out.type() == typeid(KeyOutput)) { return TransactionTypes::OutputType::Key; } - if (out.type() == typeid(MultisignatureOutput)) { - return TransactionTypes::OutputType::Multisignature; - } return TransactionTypes::OutputType::Invalid; } @@ -139,21 +127,13 @@ bool findOutputsToAccount(const CryptoNote::TransactionPrefix& transaction, cons generate_key_derivation(txPubKey, keys.viewSecretKey, derivation); for (const TransactionOutput& o : transaction.outputs) { - assert(o.target.type() == typeid(KeyOutput) || o.target.type() == typeid(MultisignatureOutput)); + assert(o.target.type() == typeid(KeyOutput)); if (o.target.type() == typeid(KeyOutput)) { if (is_out_to_acc(keys, boost::get(o.target), derivation, keyIndex)) { out.push_back(outputIndex); amount += o.amount; } ++keyIndex; - } else if (o.target.type() == typeid(MultisignatureOutput)) { - const auto& target = boost::get(o.target); - for (const auto& key : target.keys) { - if (isOutToKey(keys.address.spendPublicKey, key, derivation, static_cast(outputIndex))) { - out.push_back(outputIndex); - } - ++keyIndex; - } } ++outputIndex; } diff --git a/src/InProcessNode/InProcessNode.cpp b/src/InProcessNode/InProcessNode.cpp index 9f992ee885..86f50ca9a8 100644 --- a/src/InProcessNode/InProcessNode.cpp +++ b/src/InProcessNode/InProcessNode.cpp @@ -703,31 +703,6 @@ void InProcessNode::getPoolSymmetricDifferenceAsync(std::vector&& callback(ec); } -void InProcessNode::getMultisignatureOutputByGlobalIndex(uint64_t amount, uint32_t gindex, MultisignatureOutput& out, const Callback& callback) { - std::unique_lock lock(mutex); - if (state != INITIALIZED) { - lock.unlock(); - callback(make_error_code(CryptoNote::error::NOT_INITIALIZED)); - return; - } - - ioService.post([this, amount, gindex, &out, callback]() mutable { - this->getOutByMSigGIndexAsync(amount, gindex, out, callback); - }); -} - -void InProcessNode::getOutByMSigGIndexAsync(uint64_t amount, uint32_t gindex, MultisignatureOutput& out, const Callback& callback) { - std::error_code ec = std::error_code(); - bool result = core.getOutByMSigGIndex(amount, gindex, out); - if (!result) { - ec = make_error_code(std::errc::invalid_argument); - callback(ec); - return; - } - - callback(ec); -} - void InProcessNode::getBlockTimestamp(uint32_t height, uint64_t& timestamp, const Callback& callback) { std::unique_lock lock(mutex); if (state != INITIALIZED) { diff --git a/src/InProcessNode/InProcessNode.h b/src/InProcessNode/InProcessNode.h index f46dc4e23e..1035557eb9 100644 --- a/src/InProcessNode/InProcessNode.h +++ b/src/InProcessNode/InProcessNode.h @@ -85,7 +85,6 @@ class InProcessNode : public INode, public CryptoNote::ICryptoNoteProtocolObserv uint32_t& startHeight, const Callback& callback) override; virtual 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; virtual void getBlocks(const std::vector& blockHashes, std::vector& blocks, const Callback& callback) override; @@ -132,8 +131,6 @@ class InProcessNode : public INode, public CryptoNote::ICryptoNoteProtocolObserv void getPoolSymmetricDifferenceAsync(std::vector&& knownPoolTxIds, Crypto::Hash knownBlockId, bool& isBcActual, std::vector>& newTxs, std::vector& deletedTxIds, const Callback& callback); - void getOutByMSigGIndexAsync(uint64_t amount, uint32_t gindex, MultisignatureOutput& out, const Callback& callback); - void getBlocksAsync(const std::vector& blockHeights, std::vector>& blocks, const Callback& callback); std::error_code doGetBlocks(const std::vector& blockHeights, std::vector>& blocks); diff --git a/src/NodeRpcProxy/NodeRpcProxy.cpp b/src/NodeRpcProxy/NodeRpcProxy.cpp index 0a59859ac7..cac5443d54 100644 --- a/src/NodeRpcProxy/NodeRpcProxy.cpp +++ b/src/NodeRpcProxy/NodeRpcProxy.cpp @@ -548,17 +548,6 @@ void NodeRpcProxy::getPoolSymmetricDifference(std::vector&& knownP return this->doGetPoolSymmetricDifference(std::move(knownPoolTxIds), knownBlockId, isBcActual, newTxs, deletedTxIds); } , callback); } -void NodeRpcProxy::getMultisignatureOutputByGlobalIndex(uint64_t amount, uint32_t gindex, MultisignatureOutput& out, const Callback& callback) { - std::lock_guard lock(m_mutex); - if (m_state != STATE_INITIALIZED) { - callback(make_error_code(error::NOT_INITIALIZED)); - return; - } - - // TODO NOT IMPLEMENTED - callback(std::error_code()); -} - void NodeRpcProxy::getBlocks(const std::vector& blockHeights, std::vector>& blocks, const Callback& callback) { std::lock_guard lock(m_mutex); if (m_state != STATE_INITIALIZED) { diff --git a/src/NodeRpcProxy/NodeRpcProxy.h b/src/NodeRpcProxy/NodeRpcProxy.h index fa392f794d..e58297c4a7 100644 --- a/src/NodeRpcProxy/NodeRpcProxy.h +++ b/src/NodeRpcProxy/NodeRpcProxy.h @@ -88,7 +88,6 @@ class NodeRpcProxy : public CryptoNote::INode { 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, 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; 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; diff --git a/src/PaymentGate/NodeFactory.cpp b/src/PaymentGate/NodeFactory.cpp index cf88e3019d..db79c01ed3 100644 --- a/src/PaymentGate/NodeFactory.cpp +++ b/src/PaymentGate/NodeFactory.cpp @@ -101,9 +101,6 @@ class NodeRpcStub: public CryptoNote::INode { virtual void getTransactionsByPaymentId(const Crypto::Hash& paymentId, std::vector& transactions, const Callback& callback) override { callback(std::error_code()); } - virtual void getMultisignatureOutputByGlobalIndex(uint64_t amount, uint32_t gindex, CryptoNote::MultisignatureOutput& out, - const Callback& callback) override { callback(std::error_code()); } - void getBlockTimestamp(uint32_t height, uint64_t& timestamp, const Callback& callback) { callback(std::error_code()); } virtual void isSynchronized(bool& syncStatus, const Callback& callback) override { callback(std::error_code()); } diff --git a/src/Rpc/RpcServer.cpp b/src/Rpc/RpcServer.cpp index 563db40877..2a73f00284 100755 --- a/src/Rpc/RpcServer.cpp +++ b/src/Rpc/RpcServer.cpp @@ -1924,16 +1924,6 @@ bool RpcServer::on_get_explorer_tx_by_hash(const COMMAND_EXPLORER_GET_TRANSACTIO body.pop_back(); body += " \n"; } - else if (in.type() == typeid(MultisignatureInputDetails)) { - MultisignatureInputDetails m = boost::get(in); - body += m_core.currency().formatAmount(m.input.amount); - body += "\n multisig\n "; - body += "output index: " + std::to_string(m.input.outputIndex) + ", "; - body += "signature count: " + std::to_string(m.input.signatureCount) + ", "; - body += "output number: " + std::to_string(m.output.number) + ", "; - body += "output tx hash: " + Common::podToHex(m.output.transactionHash) + ""; - body += " \n"; - } body += " \n"; } body += "\n"; @@ -1959,16 +1949,6 @@ bool RpcServer::on_get_explorer_tx_by_hash(const COMMAND_EXPLORER_GET_TRANSACTIO KeyOutput ko = boost::get(o.output.target); body += Common::podToHex(ko); } - else if (o.output.target.type() == typeid(MultisignatureOutput)) { - body += "multisig\n"; - MultisignatureOutput mo = boost::get(o.output.target); - body += "keys: \n"; - for (const auto& k : mo.keys) { - body += Common::podToHex(k) + "\n"; - } - body += "required signature count: "; - body += std::to_string(mo.requiredSignatureCount); - } body += "\n "; body += std::to_string(o.globalIndex); body += " \n"; diff --git a/src/Serialization/BlockchainExplorerDataSerialization.cpp b/src/Serialization/BlockchainExplorerDataSerialization.cpp index fea11d6a19..81d11304ce 100644 --- a/src/Serialization/BlockchainExplorerDataSerialization.cpp +++ b/src/Serialization/BlockchainExplorerDataSerialization.cpp @@ -29,14 +29,13 @@ namespace CryptoNote { -enum class SerializationTag : uint8_t { Base = 0xff, Key = 0x2, Multisignature = 0x3, Transaction = 0xcc, Block = 0xbb }; +enum class SerializationTag : uint8_t { Base = 0xff, Key = 0x2, Transaction = 0xcc, Block = 0xbb }; namespace { struct BinaryVariantTagGetter: boost::static_visitor { uint8_t operator()(const CryptoNote::BaseInputDetails) { return static_cast(SerializationTag::Base); } uint8_t operator()(const CryptoNote::KeyInputDetails) { return static_cast(SerializationTag::Key); } - uint8_t operator()(const CryptoNote::MultisignatureInputDetails) { return static_cast(SerializationTag::Multisignature); } }; struct VariantSerializer : boost::static_visitor<> { @@ -50,8 +49,7 @@ struct VariantSerializer : boost::static_visitor<> { }; void getVariantValue(CryptoNote::ISerializer& serializer, uint8_t tag, boost::variant in) { + CryptoNote::KeyInputDetails> in) { switch (static_cast(tag)) { case SerializationTag::Base: { CryptoNote::BaseInputDetails v; @@ -65,12 +63,6 @@ void getVariantValue(CryptoNote::ISerializer& serializer, uint8_t tag, boost::va in = v; break; } - case SerializationTag::Multisignature: { - CryptoNote::MultisignatureInputDetails v; - serializer(v, "data"); - in = v; - break; - } default: throw std::runtime_error("Unknown variant tag"); } @@ -106,11 +98,6 @@ void serialize(KeyInputDetails& inputToKey, ISerializer& serializer) { serializer(inputToKey.outputs, "outputs"); } -void serialize(MultisignatureInputDetails& inputMultisig, ISerializer& serializer) { - serializer(inputMultisig.input, "input"); - serializer(inputMultisig.output, "output"); -} - void serialize(transactionInputDetails2& input, ISerializer& serializer) { if (serializer.type() == ISerializer::OUTPUT) { BinaryVariantTagGetter tagGetter; diff --git a/src/Serialization/BlockchainExplorerDataSerialization.h b/src/Serialization/BlockchainExplorerDataSerialization.h index 0aab201414..0a71f11dc3 100644 --- a/src/Serialization/BlockchainExplorerDataSerialization.h +++ b/src/Serialization/BlockchainExplorerDataSerialization.h @@ -29,7 +29,6 @@ void serialize(TransactionOutputReferenceDetails& outputReference, ISerializer& void serialize(BaseInputDetails& inputBase, ISerializer& serializer); void serialize(KeyInputDetails& inputToKey, ISerializer& serializer); -void serialize(MultisignatureInputDetails& inputMultisig, ISerializer& serializer); void serialize(transactionInputDetails2& input, ISerializer& serializer); void serialize(TransactionExtraDetails& extra, ISerializer& serializer); diff --git a/src/Transfers/TransfersConsumer.cpp b/src/Transfers/TransfersConsumer.cpp index b276e1d7f7..7daf46c284 100644 --- a/src/Transfers/TransfersConsumer.cpp +++ b/src/Transfers/TransfersConsumer.cpp @@ -89,17 +89,6 @@ void findMyOutputs( checkOutputKey(derivation, out.key, keyIndex, idx, spendKeys, outputs); ++keyIndex; - } else if (outType == TransactionTypes::OutputType::Multisignature) { - - uint64_t amount; - MultisignatureOutput out; - tx.getOutput(idx, out, amount); - - for (const auto& key : out.keys) { - checkOutputKey(derivation, key, idx, idx, spendKeys, outputs); - - ++keyIndex; - } } } } @@ -418,8 +407,7 @@ std::error_code TransfersConsumer::createTransfers( auto outType = tx.getOutputType(size_t(idx)); if ( - outType != TransactionTypes::OutputType::Key && - outType != TransactionTypes::OutputType::Multisignature) { + outType != TransactionTypes::OutputType::Key) { continue; } @@ -462,28 +450,6 @@ std::error_code TransfersConsumer::createTransfers( info.amount = amount; info.outputKey = out.key; - } else if (outType == TransactionTypes::OutputType::Multisignature) { - uint64_t amount; - MultisignatureOutput out; - tx.getOutput(idx, out, amount); - - for (const auto& key : out.keys) { - std::unordered_set::iterator it = transactions_hash_seen.find(txHash); - if (it == transactions_hash_seen.end()) { - std::unordered_set::iterator key_it = public_keys_seen.find(key); - if (key_it != public_keys_seen.end()) { - m_logger(ERROR, BRIGHT_RED) << "Failed to process transaction " << Common::podToHex(txHash) << ": duplicate multisignature output key is found"; - return std::error_code(); - } - if (std::find(temp_keys.begin(), temp_keys.end(), key) != temp_keys.end()) { - m_logger(ERROR, BRIGHT_RED) << "Failed to process transaction " << Common::podToHex(txHash) << ": the same multisignature output key is present more than once"; - return std::error_code(); - } - temp_keys.push_back(key); - } - } - info.amount = amount; - info.requiredSignatures = out.requiredSignatureCount; } transfers.push_back(info); diff --git a/src/Transfers/TransfersContainer.cpp b/src/Transfers/TransfersContainer.cpp index e82403242b..53ab99c713 100644 --- a/src/Transfers/TransfersContainer.cpp +++ b/src/Transfers/TransfersContainer.cpp @@ -111,9 +111,6 @@ SpentOutputDescriptor::SpentOutputDescriptor(const TransactionOutputInformationI m_globalOutputIndex(0) { if (m_type == TransactionTypes::OutputType::Key) { m_keyImage = &transactionInfo.keyImage; - } else if (m_type == TransactionTypes::OutputType::Multisignature) { - m_amount = transactionInfo.amount; - m_globalOutputIndex = transactionInfo.globalOutputIndex; } else { assert(false); } @@ -123,21 +120,11 @@ SpentOutputDescriptor::SpentOutputDescriptor(const KeyImage* keyImage) { assign(keyImage); } -SpentOutputDescriptor::SpentOutputDescriptor(uint64_t amount, uint32_t globalOutputIndex) { - assign(amount, globalOutputIndex); -} - void SpentOutputDescriptor::assign(const KeyImage* keyImage) { m_type = TransactionTypes::OutputType::Key; m_keyImage = keyImage; } -void SpentOutputDescriptor::assign(uint64_t amount, uint32_t globalOutputIndex) { - m_type = TransactionTypes::OutputType::Multisignature; - m_amount = amount; - m_globalOutputIndex = globalOutputIndex; -} - bool SpentOutputDescriptor::isValid() const { return m_type != TransactionTypes::OutputType::Invalid; } @@ -145,8 +132,6 @@ bool SpentOutputDescriptor::isValid() const { bool SpentOutputDescriptor::operator==(const SpentOutputDescriptor& other) const { if (m_type == TransactionTypes::OutputType::Key) { return other.m_type == m_type && *other.m_keyImage == *m_keyImage; - } else if (m_type == TransactionTypes::OutputType::Multisignature) { - return other.m_type == m_type && other.m_amount == m_amount && other.m_globalOutputIndex == m_globalOutputIndex; } else { assert(false); return false; @@ -157,10 +142,6 @@ size_t SpentOutputDescriptor::hash() const { if (m_type == TransactionTypes::OutputType::Key) { static_assert(sizeof(size_t) < sizeof(*m_keyImage), "sizeof(size_t) < sizeof(*m_keyImage)"); return *reinterpret_cast(m_keyImage->data); - } else if (m_type == TransactionTypes::OutputType::Multisignature) { - size_t hashValue = boost::hash_value(m_amount); - boost::hash_combine(hashValue, m_globalOutputIndex); - return hashValue; } else { assert(false); return 0; @@ -303,14 +284,6 @@ bool TransfersContainer::addTransactionOutputs(const TransactionBlockInfo& block ", key image " << info.keyImage; throw std::runtime_error(message); } - } else if (info.type == TransactionTypes::OutputType::Multisignature) { - SpentOutputDescriptor descriptor(transfer); - if (m_availableTransfers.get().count(descriptor) > 0 || - m_spentTransfers.get().count(descriptor) > 0) { - auto message = "Failed to add transaction output: multisignature output already exists"; - m_logger(ERROR, BRIGHT_RED) << message << ", amount " << m_currency.formatAmount(info.amount) << ", global index " << info.globalOutputIndex; - throw std::runtime_error(message); - } } auto result = m_availableTransfers.emplace(std::move(info)); @@ -402,19 +375,6 @@ bool TransfersContainer::addTransactionInputs(const TransactionBlockInfo& block, updateTransfersVisibility(input.keyImage); inputsAdded = true; - } else if (inputType == TransactionTypes::InputType::Multisignature) { - MultisignatureInput input; - tx.getInput(i, input); - - auto& outputDescriptorIndex = m_availableTransfers.get(); - auto availableOutputIt = outputDescriptorIndex.find(SpentOutputDescriptor(input.amount, input.outputIndex)); - if (availableOutputIt != outputDescriptorIndex.end()) { - copyToSpent(block, tx, i, *availableOutputIt); - // erase from available outputs - outputDescriptorIndex.erase(availableOutputIt); - - inputsAdded = true; - } } else { assert(inputType == TransactionTypes::InputType::Generating); } @@ -477,17 +437,6 @@ bool TransfersContainer::markTransactionConfirmed(const TransactionBlockInfo& bl transfer.transactionIndex = block.transactionIndex; transfer.globalOutputIndex = globalIndices[transfer.outputInTransaction]; - if (transfer.type == TransactionTypes::OutputType::Multisignature) { - SpentOutputDescriptor descriptor(transfer); - if (m_availableTransfers.get().count(descriptor) > 0 || - m_spentTransfers.get().count(descriptor) > 0) { - // This exception breaks TransfersContainer consistency - auto message = "Failed to confirm transaction: multisignature output already exists"; - m_logger(ERROR, BRIGHT_RED) << message << ", amount " << m_currency.formatAmount(transfer.amount) << ", global index " << transfer.globalOutputIndex; - throw std::runtime_error(message); - } - } - auto result = m_availableTransfers.emplace(std::move(transfer)); (void)result; // Disable unused warning assert(result.second); @@ -1023,8 +972,7 @@ bool TransfersContainer::isIncluded(TransactionTypes::OutputType type, uint32_t return // filter by type ( - ((flags & IncludeTypeKey) != 0 && type == TransactionTypes::OutputType::Key) || - ((flags & IncludeTypeMultisignature) != 0 && type == TransactionTypes::OutputType::Multisignature) + ((flags & IncludeTypeKey) != 0 && type == TransactionTypes::OutputType::Key) ) && // filter by state diff --git a/src/Transfers/TransfersContainer.h b/src/Transfers/TransfersContainer.h index 61056bd887..4ff31b41fe 100644 --- a/src/Transfers/TransfersContainer.h +++ b/src/Transfers/TransfersContainer.h @@ -47,10 +47,8 @@ class SpentOutputDescriptor { SpentOutputDescriptor(); SpentOutputDescriptor(const TransactionOutputInformationIn& transactionInfo); SpentOutputDescriptor(const Crypto::KeyImage* keyImage); - SpentOutputDescriptor(uint64_t amount, uint32_t globalOutputIndex); void assign(const Crypto::KeyImage* keyImage); - void assign(uint64_t amount, uint32_t globalOutputIndex); bool isValid() const; @@ -102,8 +100,6 @@ struct TransactionOutputInformationEx : public TransactionOutputInformationIn { if (type == TransactionTypes::OutputType::Key) { s(outputKey, ""); - } else if (type == TransactionTypes::OutputType::Multisignature) { - s(requiredSignatures, ""); } }