diff --git a/src/batchproof_container.cpp b/src/batchproof_container.cpp index e6cadd5890..16fad9fdf5 100644 --- a/src/batchproof_container.cpp +++ b/src/batchproof_container.cpp @@ -69,64 +69,55 @@ void BatchProofContainer::add(lelantus::JoinSplit* joinSplit, void BatchProofContainer::removeSigma(const sigma::spend_info_container& spendSerials) { for (auto& spendSerial : spendSerials) { - bool foundAtSigma = false; for (auto& itr :sigmaProofs) { if (itr.first.first == spendSerial.second.denomination && itr.first.second.first == spendSerial.second.coinGroupId) { auto& vProofs = itr.second; for (auto dataItr = vProofs.begin(); dataItr != vProofs.end(); dataItr++) { if (dataItr->coinSerialNumber == spendSerial.first) { vProofs.erase(dataItr); - foundAtSigma = true; break; } } } } - if (!foundAtSigma) { - int64_t denom; - sigma::DenominationToInteger(spendSerial.second.denomination, denom); - int id = denom / 1000 + spendSerial.second.coinGroupId; - // afterFixes bool with the pair of set id is considered separate set identifiers, so try to find in one set, if not found try also in another - std::pair, bool> key1 = std::make_pair(std::make_pair(id, false), true); - std::pair, bool> key2 = std::make_pair(std::make_pair(id, true), true); - std::vector* vProofs; - if (lelantusSigmaProofs.count(key1) > 0) - vProofs = &lelantusSigmaProofs[key1]; - else if (lelantusSigmaProofs.count(key2) > 0) - vProofs = &lelantusSigmaProofs[key2]; - else - continue; - for (auto dataItr = vProofs->begin(); dataItr != vProofs->end(); dataItr++) { - if (dataItr->serialNumber == spendSerial.first) { - vProofs->erase(dataItr); - break; - } - } - } } } void BatchProofContainer::removeLelantus(std::unordered_map spentSerials) { for (auto& spendSerial : spentSerials) { + + int id = spendSerial.second; + int coinGroupId = id % (CENT / 1000); + int64_t intDenom = (id - coinGroupId); + intDenom *= 1000; + sigma::CoinDenomination denomination; + bool isSigmaToLela = false; + if (sigma::IntegerToDenomination(intDenom, denomination)) + isSigmaToLela = true; + // afterFixes bool with the pair of set id is considered separate set identifiers, so try to find in one set, if not found try also in another - std::pair, bool> key1 = std::make_pair(std::make_pair(spendSerial.second, false), true); - std::pair, bool> key2 = std::make_pair(std::make_pair(spendSerial.second, true), true); + std::pair, bool> key1 = std::make_pair(std::make_pair(id, false), isSigmaToLela); + std::pair, bool> key2 = std::make_pair(std::make_pair(id, true), isSigmaToLela); std::vector* vProofs; - if (lelantusSigmaProofs.count(key1) > 0) + if (lelantusSigmaProofs.count(key1) > 0) { vProofs = &lelantusSigmaProofs[key1]; - else if (lelantusSigmaProofs.count(key2) > 0) - vProofs = &lelantusSigmaProofs[key2]; - else - continue; + erase(vProofs, spendSerial.first); + } - for (auto dataItr = vProofs->begin(); dataItr != vProofs->end(); dataItr++) { - if (dataItr->serialNumber == spendSerial.first) { - vProofs->erase(dataItr); - break; - } + if (lelantusSigmaProofs.count(key2) > 0) { + vProofs = &lelantusSigmaProofs[key2]; + erase(vProofs, spendSerial.first); } } } +void BatchProofContainer::erase(std::vector* vProofs, const Scalar& serial) { + vProofs->erase(std::remove_if(vProofs->begin(), + vProofs->end(), + [serial](LelantusSigmaProofData& proof){return proof.serialNumber == serial;}), + vProofs->end()); + +} + void BatchProofContainer::batch_sigma() { for (const auto& itr : sigmaProofs) { std::vector anonymity_set; diff --git a/src/batchproof_container.h b/src/batchproof_container.h index e6fd45f654..c6a4863ca4 100644 --- a/src/batchproof_container.h +++ b/src/batchproof_container.h @@ -12,27 +12,6 @@ class BatchProofContainer { public: static BatchProofContainer* get_instance(); - void init(); - - void finalize(); - - void add(sigma::CoinSpend* spend, - bool fPadding, - int group_id, - size_t setSize, - bool fStartSigmaBlacklist); - - void add(lelantus::JoinSplit* joinSplit, - const std::map& setSizes, - const Scalar& challenge, - bool fStartLelantusBlacklist); - - void removeSigma(const sigma::spend_info_container& spendSerials); - void removeLelantus(std::unordered_map spentSerials); - - void batch_sigma(); - void batch_lelantus(); - struct SigmaProofData { SigmaProofData() : sigmaProof(0, 0), coinSerialNumber(uint64_t(0)), fPadding(0), anonymitySetSize(0) {} SigmaProofData(const sigma::SigmaPlusProof& sigmaProof_, @@ -66,6 +45,28 @@ class BatchProofContainer { size_t anonymitySetSize; }; + void init(); + + void finalize(); + + void add(sigma::CoinSpend* spend, + bool fPadding, + int group_id, + size_t setSize, + bool fStartSigmaBlacklist); + + void add(lelantus::JoinSplit* joinSplit, + const std::map& setSizes, + const Scalar& challenge, + bool fStartLelantusBlacklist); + + void removeSigma(const sigma::spend_info_container& spendSerials); + void removeLelantus(std::unordered_map spentSerials); + void erase(std::vector* vProofs, const Scalar& serial); + + void batch_sigma(); + void batch_lelantus(); + public: bool fCollectProofs = 0; diff --git a/src/lelantus.cpp b/src/lelantus.cpp index 1181be6012..19413112a1 100644 --- a/src/lelantus.cpp +++ b/src/lelantus.cpp @@ -498,12 +498,14 @@ bool CheckLelantusJoinSplitTransaction( } BatchProofContainer* batchProofContainer = BatchProofContainer::get_instance(); + bool useBatching = batchProofContainer->fCollectProofs && !isVerifyDB && !isCheckWallet && lelantusTxInfo && !lelantusTxInfo->fInfoIsComplete; + Scalar challenge; // if we are collecting proofs, skip verification and collect proofs - passVerify = joinsplit->Verify(anonymity_sets, anonymity_set_hashes, Cout, Vout, txHashForMetadata, challenge, batchProofContainer->fCollectProofs); + passVerify = joinsplit->Verify(anonymity_sets, anonymity_set_hashes, Cout, Vout, txHashForMetadata, challenge, useBatching); // add proofs into container - if(batchProofContainer->fCollectProofs) { + if(useBatching) { std::map idAndSizes; for(auto itr : anonymity_sets) diff --git a/src/validation.cpp b/src/validation.cpp index 875d2db914..8767f806f4 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3193,7 +3193,6 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara for (CTransactionRef tx : block.vtx) { CheckTransaction(*tx, state, false, tx->GetHash(), false, pindexDelete->pprev->nHeight, false, false, block.sigmaTxInfo.get(), block.lelantusTxInfo.get()); - if(GetBoolArg("-batching", true)) { if (tx->IsLelantusJoinSplit()) { const CTxIn &txin = tx->vin[0]; @@ -3213,22 +3212,8 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara continue; } - if (joinsplit->isSigmaToLelantus()) { - for (size_t i = 0; i < serials.size(); i++) { - int coinGroupId = ids[i] % (CENT / 1000); - int64_t intDenom = (ids[i] - coinGroupId); - intDenom *= 1000; - sigma::CoinDenomination denomination; - if (!sigma::IntegerToDenomination(intDenom, denomination)) - lelantusSerialsToRemove.insert(std::make_pair(serials[i], ids[i])); - else - sigmaSerialsToRemove.insert(std::make_pair( - serials[i], sigma::CSpendCoinInfo::make(denomination, coinGroupId))); - } - } else { - for (size_t i = 0; i < serials.size(); i++) { - lelantusSerialsToRemove.insert(std::make_pair(serials[i], ids[i])); - } + for (size_t i = 0; i < serials.size(); i++) { + lelantusSerialsToRemove.insert(std::make_pair(serials[i], ids[i])); } } else if (tx->IsSigmaSpend()) { for (const CTxIn &txin : tx->vin) { @@ -3266,6 +3251,16 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara sigma::DisconnectTipSigma(block, pindexDelete); lelantus::DisconnectTipLelantus(block, pindexDelete); + + BatchProofContainer* batchProofContainer = BatchProofContainer::get_instance(); + if (sigmaSerialsToRemove.size() > 0) { + batchProofContainer->removeSigma(sigmaSerialsToRemove); + } + + if (lelantusSerialsToRemove.size() > 0) { + batchProofContainer->removeLelantus(lelantusSerialsToRemove); + } + // Roll back MTP state MTPState::GetMTPState()->SetLastBlock(pindexDelete->pprev, chainparams.GetConsensus()); @@ -3312,15 +3307,6 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara // Update chainActive and related variables. UpdateTip(pindexDelete->pprev, chainparams); - BatchProofContainer* batchProofContainer = BatchProofContainer::get_instance(); - if (sigmaSerialsToRemove.size() > 0) { - batchProofContainer->removeSigma(sigmaSerialsToRemove); - } - - if (lelantusSerialsToRemove.size() > 0) { - batchProofContainer->removeLelantus(lelantusSerialsToRemove); - } - #ifdef ENABLE_WALLET // update mint/spend wallet if (!GetBoolArg("-disablewallet", false) && pwalletMain->zwallet) {