diff --git a/src/libmw/src/node/CoinsViewCache.cpp b/src/libmw/src/node/CoinsViewCache.cpp index 9069f8a64d..b0ec06fa5c 100644 --- a/src/libmw/src/node/CoinsViewCache.cpp +++ b/src/libmw/src/node/CoinsViewCache.cpp @@ -23,7 +23,7 @@ UTXO::CPtr CoinsViewCache::GetUTXO(const mw::Hash& output_id) const noexcept std::vector actions = m_pUpdates->GetActions(output_id); for (const CoinAction& action : actions) { if (action.pUTXO != nullptr) { - // MW: TODO - Don't allow having more than one UTXO with output_id at a time + assert(pUTXO == nullptr); pUTXO = action.pUTXO; } else { assert(pUTXO != nullptr); @@ -44,15 +44,6 @@ mw::BlockUndo::CPtr CoinsViewCache::ApplyBlock(const mw::Block::CPtr& pBlock) BlindingFactor prev_offset = pPreviousHeader != nullptr ? pPreviousHeader->GetKernelOffset() : BlindingFactor(); KernelSumValidator::ValidateForBlock(pBlock->GetTxBody(), pBlock->GetKernelOffset(), prev_offset); - std::vector coinsSpent; - std::for_each( - pBlock->GetInputs().cbegin(), pBlock->GetInputs().cend(), - [this, &coinsSpent](const Input& input) { - UTXO spentUTXO = SpendUTXO(input.GetOutputID()); - coinsSpent.push_back(std::move(spentUTXO)); - } - ); - std::vector coinsAdded; std::for_each( pBlock->GetOutputs().cbegin(), pBlock->GetOutputs().cend(), @@ -62,6 +53,15 @@ mw::BlockUndo::CPtr CoinsViewCache::ApplyBlock(const mw::Block::CPtr& pBlock) } ); + std::vector coinsSpent; + std::for_each( + pBlock->GetInputs().cbegin(), pBlock->GetInputs().cend(), + [this, &coinsSpent](const Input& input) { + UTXO spentUTXO = SpendUTXO(input.GetOutputID()); + coinsSpent.push_back(std::move(spentUTXO)); + } + ); + auto pHeader = pBlock->GetHeader(); if (pHeader->GetOutputRoot() != GetOutputPMMR()->Root() || pHeader->GetNumTXOs() != GetOutputPMMR()->GetNumLeaves() @@ -202,10 +202,15 @@ bool CoinsViewCache::HasSpendInCache(const mw::Hash& output_id) const noexcept void CoinsViewCache::AddUTXO(const uint64_t header_height, const Output& output) { + UTXO::CPtr pUTXO = GetUTXO(output.GetOutputID()); + if (pUTXO != nullptr) {// && m_pLeafSet->Contains(pUTXO->GetLeafIndex())) { + ThrowValidation(EConsensusError::DUPLICATES); + } + mmr::LeafIndex leafIdx = m_pOutputPMMR->Add(output.GetOutputID()); m_pLeafSet->Add(leafIdx); - auto pUTXO = std::make_shared(header_height, std::move(leafIdx), output); + pUTXO = std::make_shared(header_height, std::move(leafIdx), output); m_pUpdates->AddUTXO(pUTXO); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5c177bca99..e136f76586 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1975,6 +1975,25 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc } if (!block.mweb_block.IsNull()) { + // MW: TODO - Pegouts? + mw::Coin mweb_coin; + for (const mw::Hash& output_id : block.mweb_block.GetOutputIDs()) { + if (mweb_wallet->RewindOutput(block.mweb_block.m_block, output_id, mweb_coin)) { + const CWalletTx* wtx = FindWalletTx(mweb_coin.output_id); + if (wtx) { + // MW: TODO - Update height + } else { + AddToWallet( + MakeTransactionRef(), + boost::make_optional(mweb_coin), + {CWalletTx::Status::CONFIRMED, block_height, block_hash, 0}, + nullptr, + false + ); + } + } + } + for (const mw::Hash& spent_id : block.mweb_block.GetSpentIDs()) { if (IsMine(CTxInput(spent_id))) { // MW: TODO - Check for zapped transactions with matching spent IDs @@ -1992,20 +2011,6 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc } } } - - mw::Coin mweb_coin; - for (const mw::Hash& output_id : block.mweb_block.GetOutputIDs()) { - if (mweb_wallet->RewindOutput(block.mweb_block.m_block, output_id, mweb_coin)) { - // MW: TODO - Check for zapped transactions with matching output IDs - AddToWallet( - MakeTransactionRef(), - boost::make_optional(mweb_coin), - {CWalletTx::Status::CONFIRMED, block_height, block_hash, 0}, - nullptr, - false - ); - } - } } // scan succeeded, record block as most recent successfully scanned