@@ -1165,30 +1165,19 @@ int main(int argc, char* argv[]) {
11651165 // io_context needed for block verification timers in all modes
11661166 web_server.get_mining_interface ()->set_io_context (&ioc);
11671167
1168- // Wire live coin-daemon RPC so getblocktemplate/submitblock use real data
1169- if (!embedded_ltc) {
1170- web_server.set_coin_rpc (node_rpc.get (), &coin_node);
1171- } else if (embedded_broadcaster && embedded_chain) {
1172- // Wire embedded node + header-sync callback (now that web_server is alive)
1173- web_server.set_embedded_node (embedded_node.get ());
1174-
1175- // Wire block verification for embedded mode
1168+ // --- Layer +2: Persistent found block + THE checkpoint storage ---
1169+ // Runs in ALL modes (RPC and embedded). Uses dedicated LevelDB.
1170+ {
11761171 auto * mi = web_server.get_mining_interface ();
1177-
1178- // --- Layer +2: Persistent found block storage ---
1179- // Uses a dedicated LevelDB in the network data dir.
11801172 std::string net_label = settings->m_testnet ? " testnet" : " mainnet" ;
11811173 std::string fblk_db_path = std::string (getenv (" HOME" ) ? getenv (" HOME" ) : " ." ) +
11821174 " /.c2pool/" + net_label + " /found_blocks_db" ;
11831175 auto fblk_leveldb = std::make_shared<core::LevelDBStore>(
11841176 fblk_db_path, core::LevelDBOptions{});
1185- if (!fblk_leveldb->open ()) {
1186- LOG_WARNING << " [Pool] Failed to open found blocks LevelDB at " << fblk_db_path;
1187- } else {
1177+ if (fblk_leveldb->open ()) {
11881178 auto fblk_store = std::make_shared<c2pool::storage::FoundBlockStore>(*fblk_leveldb);
11891179 using MI = core::MiningInterface;
11901180 mi->set_found_block_persistence (
1191- // persist callback
11921181 [fblk_store, fblk_leveldb](const MI ::FoundBlock& blk) -> bool {
11931182 c2pool::storage::FoundBlockRecord rec;
11941183 rec.chain = blk.chain ;
@@ -1201,7 +1190,6 @@ int main(int argc, char* argv[]) {
12011190 rec.last_checked = static_cast <uint64_t >(std::time (nullptr ));
12021191 return fblk_store->store (rec);
12031192 },
1204- // load callback
12051193 [fblk_store, fblk_leveldb]() -> std::vector<MI ::FoundBlock> {
12061194 auto records = fblk_store->load_all ();
12071195 std::vector<MI ::FoundBlock> result;
@@ -1223,104 +1211,75 @@ int main(int argc, char* argv[]) {
12231211 mi->load_persisted_found_blocks ();
12241212 LOG_INFO << " [Pool] Found block persistence enabled at " << fblk_db_path;
12251213
1226- // --- THE checkpoint store (shares same LevelDB) ---
1214+ // THE checkpoint store (shares same LevelDB)
12271215 auto the_store = std::make_shared<c2pool::storage::TheCheckpointStore>(*fblk_leveldb);
1228-
1229- // Checkpoint creation: called on every found block
12301216 mi->set_checkpoint_fns (
1231- // latest verified checkpoint
12321217 [the_store]() -> nlohmann::json {
1233- // Try all chains
1234- for (const auto & chain : {" tLTC" , " LTC" , " DOGE" , " tDOGE" }) {
1235- auto cp = the_store->get_latest_verified (chain);
1236- if (cp.has_value ()) {
1237- return nlohmann::json{
1238- {" chain" , cp->chain },
1239- {" block_height" , cp->block_height },
1240- {" block_hash" , cp->block_hash },
1241- {" the_state_root" , cp->the_state_root .GetHex ()},
1242- {" sharechain_height" , cp->sharechain_height },
1243- {" miner_count" , cp->miner_count },
1244- {" hashrate_class" , cp->hashrate_class },
1245- {" timestamp" , cp->timestamp },
1246- {" status" , cp->status == 1 ? " verified" : " pending" }
1247- };
1248- }
1249- }
1250- // Fall back to latest any-status
12511218 for (const auto & chain : {" tLTC" , " LTC" , " DOGE" , " tDOGE" }) {
12521219 auto cp = the_store->get_latest (chain);
12531220 if (cp.has_value ()) {
12541221 return nlohmann::json{
1255- {" chain" , cp->chain },
1256- {" block_height" , cp->block_height },
1222+ {" chain" , cp->chain }, {" block_height" , cp->block_height },
12571223 {" block_hash" , cp->block_hash },
12581224 {" the_state_root" , cp->the_state_root .GetHex ()},
12591225 {" sharechain_height" , cp->sharechain_height },
12601226 {" miner_count" , cp->miner_count },
12611227 {" hashrate_class" , cp->hashrate_class },
12621228 {" timestamp" , cp->timestamp },
1263- {" status" , " pending" }
1229+ {" status" , cp-> status == 1 ? " verified " : " pending" }
12641230 };
12651231 }
12661232 }
1267- return nlohmann::json{{" error " , " no checkpoints found " }};
1233+ return nlohmann::json{{" status " , " no checkpoints" }};
12681234 },
1269- // all checkpoints
12701235 [the_store]() -> nlohmann::json {
12711236 auto all = the_store->load_all ();
12721237 nlohmann::json arr = nlohmann::json::array ();
12731238 for (const auto & cp : all) {
12741239 arr.push_back ({
1275- {" chain" , cp.chain },
1276- {" block_height" , cp.block_height },
1240+ {" chain" , cp.chain }, {" block_height" , cp.block_height },
12771241 {" block_hash" , cp.block_hash },
12781242 {" the_state_root" , cp.the_state_root .GetHex ()},
12791243 {" sharechain_height" , cp.sharechain_height },
12801244 {" miner_count" , cp.miner_count },
1281- {" hashrate_class" , cp.hashrate_class },
12821245 {" timestamp" , cp.timestamp },
12831246 {" status" , cp.status == 1 ? " verified" : (cp.status == 2 ? " mismatch" : " pending" )}
12841247 });
12851248 }
12861249 return arr;
12871250 },
1288- // verify callback (recompute state_root)
1289- [](const uint256& /* state_root*/ , uint32_t /* height*/ ) -> bool {
1290- // TODO: recompute from sharechain and compare
1291- return true ; // optimistic until V37
1292- },
1293- // create checkpoint on block found
1251+ [](const uint256&, uint32_t ) -> bool { return true ; },
12941252 [the_store, mi](const std::string& chain, uint64_t height,
12951253 const std::string& hash, uint64_t ts) {
12961254 c2pool::storage::TheCheckpoint cp;
1297- cp.chain = chain;
1298- cp.block_height = height;
1299- cp.block_hash = hash;
1300- cp.timestamp = ts;
1301- cp.status = 0 ; // pending
1302-
1303- // Capture current sharechain state from THE metadata
1304- // The state_root was already computed in refresh_work()
1305- // and embedded in the block. We store the same data here.
1255+ cp.chain = chain; cp.block_height = height;
1256+ cp.block_hash = hash; cp.timestamp = ts; cp.status = 0 ;
13061257 auto work = mi->get_current_work ();
1307- if (!work.the_state_root .IsNull ())
1308- cp.the_state_root = work.the_state_root ;
1309-
1258+ cp.the_state_root = work.the_state_root ;
13101259 cp.sharechain_height = work.sharechain_height ;
13111260 cp.miner_count = work.miner_count ;
13121261 cp.hashrate_class = c2pool::TheMetadata::encode_hashrate (work.pool_hashrate );
1313-
13141262 the_store->store (cp);
1315- LOG_INFO << " [THE] Checkpoint created: chain=" << chain
1316- << " height=" << height
1263+ LOG_INFO << " [THE] Checkpoint: " << chain << " height=" << height
13171264 << " miners=" << cp.miner_count
1318- << " hashrate_class=" << (int )cp.hashrate_class
1319- << " state_root=" << cp.the_state_root .GetHex ().substr (0 , 16 ) << " ..." ;
1265+ << " root=" << cp.the_state_root .GetHex ().substr (0 , 16 ) << " ..." ;
13201266 }
13211267 );
1322- LOG_INFO << " [THE] Checkpoint store enabled (" << the_store->count () << " existing checkpoints)" ;
1268+ LOG_INFO << " [THE] Checkpoint store: " << the_store->count () << " existing" ;
1269+ } else {
1270+ LOG_WARNING << " [Pool] Failed to open found blocks LevelDB at " << fblk_db_path;
13231271 }
1272+ }
1273+
1274+ // Wire live coin-daemon RPC so getblocktemplate/submitblock use real data
1275+ if (!embedded_ltc) {
1276+ web_server.set_coin_rpc (node_rpc.get (), &coin_node);
1277+ } else if (embedded_broadcaster && embedded_chain) {
1278+ // Wire embedded node + header-sync callback (now that web_server is alive)
1279+ web_server.set_embedded_node (embedded_node.get ());
1280+
1281+ // Wire block verification for embedded mode
1282+ auto * mi = web_server.get_mining_interface ();
13241283 mi->set_block_verify_fn (
13251284 [chain = embedded_chain.get ()](const std::string& hash_hex) -> int {
13261285 uint256 h;
0 commit comments