@@ -3502,18 +3502,31 @@ static RPCHelpMan generatetxohints()
35023502 }
35033503 CBlockIndex* curr{active_chain.Next (active_chain.Genesis ())};
35043504 uint64_t total_outputs_written{0 };
3505+ uint32_t running_index{};
3506+ std::set<COutPoint> spent_outpoints{};
35053507 while (curr) {
35063508 auto height{curr->nHeight };
35073509 if (height % 10000 == 0 ) {
35083510 LogDebug (BCLog::RPC, " Wrote hints up to height %s, total outputs written %d" , height, total_outputs_written);
35093511 }
3512+ if (height % 10 == 0 && height != 0 ) {
3513+ running_index = 0 ;
3514+ spent_outpoints.clear ();
3515+ }
35103516 FlatFilePos file_pos = curr->GetBlockPos ();
35113517 std::unique_ptr<CBlock> pblock = std::make_unique<CBlock>();
35123518 bool read = node.chainman ->m_blockman .ReadBlock (*pblock, file_pos, curr->GetBlockHash ());
35133519 if (!read) {
35143520 throw JSONRPCError (RPC_DATABASE_ERROR, " Block could not be read from disk." );
35153521 }
3516- uint32_t output_index{};
3522+ for (const auto & transaction : pblock->vtx ) {
3523+ if (transaction->IsCoinBase ()) {
3524+ continue ;
3525+ }
3526+ for (const auto & txin : transaction->vin ) {
3527+ spent_outpoints.insert (txin.prevout );
3528+ }
3529+ }
35173530 std::vector<uint32_t > unspent;
35183531 for (const auto & tx: pblock->vtx ) {
35193532 const Txid& txid = tx->GetHash ();
@@ -3522,10 +3535,13 @@ static RPCHelpMan generatetxohints()
35223535 continue ;
35233536 }
35243537 const COutPoint outpoint = COutPoint (txid, vout);
3538+ if (spent_outpoints.contains (outpoint)) {
3539+ continue ;
3540+ }
35253541 if (active_state.CoinsDB ().HaveCoin (outpoint)) {
3526- unspent.push_back (output_index );
3542+ unspent.push_back (running_index );
35273543 }
3528- ++output_index ;
3544+ ++running_index ;
35293545 ++total_outputs_written;
35303546 }
35313547 }
0 commit comments