Skip to content

Commit d552857

Browse files
committed
UTXO warm restart: skip re-processing + smart bootstrap range
- Add height guard (height > utxo->get_best_height()) before connect_block() for both LTC and DOGE full-block handlers, preventing double-processing of blocks already in UTXO LevelDB - Rewrite bootstrap to request only blocks from utxo_best+1 to tip, skipping the full 288/1440 window on warm restart - Log "UTXO warm restart: no bootstrap needed" when fully caught up - Add analytics_id to README configuration reference
1 parent ced327b commit d552857

2 files changed

Lines changed: 31 additions & 12 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ complete examples with all options documented.
281281
| `--payout-window` | `payout_window_seconds` | 86400 | PPLNS window (seconds) |
282282
| `--storage-save-interval` | `storage_save_interval` | 300 | Sharechain save interval |
283283
| `--dashboard-dir` | `dashboard_dir` | web-static | Static dashboard directory |
284+
| `--analytics-id` | `analytics_id` | -- | Google Analytics measurement ID (e.g. `G-XXXXXXXXXX`); injected into dashboard HTML `</head>` |
284285
| `--coinbase-text` | `coinbase_text` | /c2pool/ | Custom coinbase scriptSig text |
285286
| `--message-blob-hex` | -- | -- | V36 authority message blob |
286287
| `--doge-testnet4alpha` | -- | false | Use DOGE testnet4alpha |

src/c2pool/c2pool_refactored.cpp

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,7 +1768,8 @@ int main(int argc, char* argv[]) {
17681768

17691769
// Step 1: Update UTXO set (BEFORE mempool cleanup)
17701770
// Connect block: spend inputs, add outputs, save undo data
1771-
if (utxo && utxo_db) {
1771+
// Skip blocks already processed (warm restart: UTXO persists in LevelDB)
1772+
if (utxo && utxo_db && height > utxo->get_best_height()) {
17721773
auto txid_fn = [](const ltc::coin::MutableTransaction& tx) {
17731774
return ltc::coin::compute_txid(tx);
17741775
};
@@ -1801,22 +1802,32 @@ int main(int argc, char* argv[]) {
18011802
// Reference: litecoin/src/validation.h MIN_BLOCKS_TO_KEEP = 288
18021803
// Only fire once, and only when header chain has synced
18031804
// (height > keep_depth ensures we're at tip, not genesis).
1805+
// On warm restart, UTXO best_height is already within range
1806+
// — skip bootstrap to avoid re-downloading blocks already processed.
18041807
static bool ltc_bootstrap_done = false;
18051808
constexpr uint32_t LTC_KEEP = core::coin::LTC_MIN_BLOCKS_TO_KEEP;
18061809
if (!ltc_bootstrap_done && chain && bcaster && height > LTC_KEEP) {
18071810
ltc_bootstrap_done = true;
1811+
// Only request blocks we haven't processed yet
1812+
uint32_t utxo_best = utxo->get_best_height();
1813+
uint32_t start_from = (utxo_best > 0 && utxo_best >= height - LTC_KEEP)
1814+
? utxo_best + 1 : height - LTC_KEEP;
18081815
int requested = 0;
1809-
for (uint32_t bi = 1; bi <= LTC_KEEP && bi <= height; ++bi) {
1810-
auto entry = chain->get_header_by_height(height - bi);
1816+
for (uint32_t h = start_from; h < height; ++h) {
1817+
auto entry = chain->get_header_by_height(h);
18111818
if (entry) {
18121819
bcaster->request_full_block(entry->block_hash);
18131820
++requested;
18141821
}
18151822
}
18161823
if (requested > 0)
18171824
LOG_INFO << "[EMB-LTC] Bootstrap: requested " << requested
1818-
<< " historical blocks (MIN_BLOCKS_TO_KEEP="
1819-
<< LTC_KEEP << ")";
1825+
<< " blocks (utxo_best=" << utxo_best
1826+
<< " tip=" << height
1827+
<< " MIN_BLOCKS_TO_KEEP=" << LTC_KEEP << ")";
1828+
else
1829+
LOG_INFO << "[EMB-LTC] UTXO warm restart: best_height="
1830+
<< utxo_best << " — no bootstrap needed";
18201831
}
18211832
}
18221833

@@ -3881,7 +3892,8 @@ int main(int argc, char* argv[]) {
38813892
<< " from=" << peer;
38823893

38833894
// UTXO connect (before mempool cleanup)
3884-
if (utxo && utxo_db) {
3895+
// Skip blocks already processed (warm restart)
3896+
if (utxo && utxo_db && height > utxo->get_best_height()) {
38853897
// DOGE: txid = hash of full serialization (no witness stripping)
38863898
auto txid_fn = [](const ltc::coin::MutableTransaction& tx) {
38873899
return ltc::coin::compute_txid(tx);
@@ -3912,21 +3924,27 @@ int main(int argc, char* argv[]) {
39123924
// Bootstrap: seed UTXO with MIN_BLOCKS_TO_KEEP (1440) blocks.
39133925
// Matches dogecoind pruned node safety depth.
39143926
// Reference: dogecoin/src/validation.h MIN_BLOCKS_TO_KEEP = 1440
3915-
// Only fire once, and only when header chain has synced
3916-
// (height > keep_depth ensures we're at tip, not genesis).
3927+
// On warm restart, skip blocks already in UTXO LevelDB.
39173928
static bool doge_bootstrap_done = false;
39183929
constexpr uint32_t DOGE_KEEP = core::coin::DOGE_MIN_BLOCKS_TO_KEEP;
39193930
if (!doge_bootstrap_done && chain && height > DOGE_KEEP) {
39203931
doge_bootstrap_done = true;
3932+
uint32_t utxo_best = utxo->get_best_height();
3933+
uint32_t start_from = (utxo_best > 0 && utxo_best >= height - DOGE_KEEP)
3934+
? utxo_best + 1 : height - DOGE_KEEP;
39213935
int req = 0;
3922-
for (uint32_t bi = 1; bi <= DOGE_KEEP && bi <= height; ++bi) {
3923-
auto e = chain->get_header_by_height(height - bi);
3936+
for (uint32_t h = start_from; h < height; ++h) {
3937+
auto e = chain->get_header_by_height(h);
39243938
if (e) { bcaster_ptr->request_full_block(e->block_hash); ++req; }
39253939
}
39263940
if (req > 0)
39273941
LOG_INFO << "[EMB-DOGE] Bootstrap: requested " << req
3928-
<< " historical blocks (MIN_BLOCKS_TO_KEEP="
3929-
<< DOGE_KEEP << ")";
3942+
<< " blocks (utxo_best=" << utxo_best
3943+
<< " tip=" << height
3944+
<< " MIN_BLOCKS_TO_KEEP=" << DOGE_KEEP << ")";
3945+
else
3946+
LOG_INFO << "[EMB-DOGE] UTXO warm restart: best_height="
3947+
<< utxo_best << " — no bootstrap needed";
39303948
}
39313949
}
39323950
if (pool) {

0 commit comments

Comments
 (0)