@@ -3502,18 +3502,30 @@ static RPCHelpMan generatetxohints()
35023502 }
35033503 CBlockIndex* curr{active_chain.Next (active_chain.Genesis ())};
35043504 uint64_t total_outputs_written{0 };
3505+ std::set<COutPoint> spent_outpoints{};
35053506 while (curr) {
35063507 auto height{curr->nHeight };
35073508 if (height % 10000 == 0 ) {
35083509 LogDebug (BCLog::RPC, " Wrote hints up to height %s, total outputs written %d" , height, total_outputs_written);
35093510 }
3511+ if (height % 10 == 0 && height != 0 ) {
3512+ spent_outpoints.clear ();
3513+ }
35103514 FlatFilePos file_pos = curr->GetBlockPos ();
35113515 std::unique_ptr<CBlock> pblock = std::make_unique<CBlock>();
35123516 bool read = node.chainman ->m_blockman .ReadBlock (*pblock, file_pos, curr->GetBlockHash ());
35133517 if (!read) {
35143518 throw JSONRPCError (RPC_DATABASE_ERROR, " Block could not be read from disk." );
35153519 }
3516- uint32_t output_index{};
3520+ for (const auto & transaction : pblock->vtx ) {
3521+ if (transaction->IsCoinBase ()) {
3522+ continue ;
3523+ }
3524+ for (const auto & txin : transaction->vin ) {
3525+ spent_outpoints.insert (txin.prevout );
3526+ }
3527+ }
3528+ uint32_t running_index{};
35173529 std::vector<uint32_t > unspent;
35183530 for (const auto & tx: pblock->vtx ) {
35193531 const Txid& txid = tx->GetHash ();
@@ -3522,10 +3534,13 @@ static RPCHelpMan generatetxohints()
35223534 continue ;
35233535 }
35243536 const COutPoint outpoint = COutPoint (txid, vout);
3537+ if (spent_outpoints.contains (outpoint)) {
3538+ continue ;
3539+ }
35253540 if (active_state.CoinsDB ().HaveCoin (outpoint)) {
3526- unspent.push_back (output_index );
3541+ unspent.push_back (running_index );
35273542 }
3528- ++output_index ;
3543+ ++running_index ;
35293544 ++total_outputs_written;
35303545 }
35313546 }
0 commit comments