@@ -3365,8 +3365,73 @@ void MiningInterface::start_pplns_precompute()
33653365 auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(
33663366 std::chrono::steady_clock::now () - start_time).count ();
33673367
3368+ // Convert flat pre-computed entries to merged format with DOGE data
3369+ // Fetch current merged payouts once as a template for DOGE amounts
3370+ auto merged_template = rest_current_merged_payouts ();
3371+ if (merged_template.is_object () && !merged_template.empty ()) {
3372+ // Build DOGE lookup: addr → {symbol, address, amount_per_ltc_unit}
3373+ // For each address, compute DOGE/LTC ratio from the template
3374+ std::map<std::string, nlohmann::json> doge_info; // addr → merged array
3375+ for (auto & [addr, entry] : merged_template.items ()) {
3376+ if (entry.contains (" merged" ) && entry[" merged" ].is_array ()) {
3377+ doge_info[addr] = entry[" merged" ];
3378+ }
3379+ }
3380+ // Compute total LTC in template for proportion scaling
3381+ double template_ltc_total = 0 ;
3382+ for (auto & [addr, entry] : merged_template.items ()) {
3383+ if (entry.contains (" amount" ))
3384+ template_ltc_total += entry[" amount" ].get <double >();
3385+ }
3386+
3387+ std::lock_guard<std::mutex> lock (m_pplns_cache_mutex);
3388+ int upgraded = 0 ;
3389+ for (auto & [hash, pplns] : m_pplns_per_tip) {
3390+ // Skip entries already in merged format
3391+ if (pplns.empty ()) continue ;
3392+ auto first_val = pplns.begin ().value ();
3393+ if (first_val.is_object ()) continue ; // already merged format
3394+
3395+ // Convert flat {addr: ltc_amount} → merged {addr: {amount, merged:[]}}
3396+ double share_ltc_total = 0 ;
3397+ for (auto & [a, v] : pplns.items ()) {
3398+ if (v.is_number ()) share_ltc_total += v.get <double >();
3399+ }
3400+
3401+ nlohmann::json merged_pplns = nlohmann::json::object ();
3402+ for (auto & [addr, ltc_val] : pplns.items ()) {
3403+ double ltc_amt = ltc_val.is_number () ? ltc_val.get <double >() : 0 ;
3404+ double ltc_pct = share_ltc_total > 0 ? ltc_amt / share_ltc_total : 0 ;
3405+
3406+ nlohmann::json entry = {{" amount" , ltc_amt}, {" merged" , nlohmann::json::array ()}};
3407+
3408+ // Match DOGE data from template by address
3409+ auto dit = doge_info.find (addr);
3410+ if (dit != doge_info.end ()) {
3411+ // Use exact DOGE data for this address, scaled by LTC proportion
3412+ for (auto & m : dit->second ) {
3413+ double template_doge = m.value (" amount" , 0.0 );
3414+ // Scale: this share's LTC pct vs template LTC pct for this addr
3415+ double template_addr_ltc = 0 ;
3416+ if (merged_template.contains (addr) && merged_template[addr].contains (" amount" ))
3417+ template_addr_ltc = merged_template[addr][" amount" ].get <double >();
3418+ double scale = (template_addr_ltc > 0 ) ? (ltc_amt / template_addr_ltc) : 1.0 ;
3419+ entry[" merged" ].push_back ({
3420+ {" symbol" , m.value (" symbol" , " DOGE" )},
3421+ {" address" , m.value (" address" , " " )},
3422+ {" amount" , template_doge * scale}
3423+ });
3424+ }
3425+ }
3426+ merged_pplns[addr] = std::move (entry);
3427+ }
3428+ pplns = std::move (merged_pplns);
3429+ ++upgraded;
3430+ }
3431+ LOG_INFO << " [PPLNS-Cache] Upgraded " << upgraded << " entries to merged format with DOGE data" ;
3432+ }
3433+
33683434 m_pplns_precompute_done.store (true );
3369- // Invalidate window cache so next request includes all per-share PPLNS
33703435 invalidate_window_cache ();
33713436 LOG_INFO << " [PPLNS-Cache] Pre-computation complete: " << computed
33723437 << " snapshots in " << elapsed << " s (cache size: "
0 commit comments