Skip to content

Commit f8a1263

Browse files
committed
fix(bch): seed cold-start share-target floor on work-gen path, not share-create
The empty-sharechain cold-start seed for share_bits_ lived in build_connection_coinbase (the share-CREATE path), but that path only runs after core::StratumServer clears its is_pool_share gate, which is derived from pool_difficulty, itself derived from share_bits_. On an empty chain share_bits_==0 => pool_difficulty==0 => the gate never fires => no share is created => share_bits_ never advances: a deadlock the share-create seed cannot break because it sits behind the gate it opens. Relocate a floor-seed into cached_template() on the WORK-GEN path, which runs on every work poll independent of share creation. Seed both atomics to target_to_bits_upper_bound(PoolConfig::max_target()) -- the exact floor compute_share_target emits for max_bits on the genesis branch. Idempotent (fires only while unseeded). Verified on .198 regtest: pool_difficulty 0 -> 1 at cold start, is_pool_share gate now live from first work poll.
1 parent 8c82dbf commit f8a1263

1 file changed

Lines changed: 21 additions & 0 deletions

File tree

src/impl/bch/stratum/work_source.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <impl/bch/coin/mempool.hpp>
3232
#include <impl/bch/coin/merkle.hpp> // merkle_hash_pair (CTOR SHA256d)
3333
#include <impl/bch/coin/template_builder.hpp> // build_template + rpc::WorkData
34+
#include <impl/bch/config_pool.hpp> // PoolConfig::max_target (G2 cold-start floor)
3435

3536
#include <core/log.hpp>
3637
#include <btclibs/util/strencodings.h> // HexStr
@@ -222,6 +223,26 @@ BCHWorkSource::cached_template() const
222223
if (const char* e = std::getenv("BCH_DEMO_BLOCK_BITS"); e && *e)
223224
built->m_data["bits"] = std::string(e);
224225

226+
// [G2 cold-start] Seed the pool share-target floor on the WORK-GEN path.
227+
// build_connection_coinbase() also seeds share_bits_ from ref_hash_fn's
228+
// genesis max_bits, but that path runs only AFTER a share is created --
229+
// which core::StratumServer gates on pool_difficulty>0, itself derived
230+
// from share_bits_. On an empty sharechain share_bits_==0 => pool
231+
// difficulty==0 => the is_pool_share gate never fires => no share is
232+
// created => share_bits_ can never advance: a cold-start deadlock the
233+
// share-create seed cannot break because it sits behind the very gate it
234+
// needs to open. cached_template() runs on every work poll, BEFORE and
235+
// INDEPENDENT of share creation, so seeding the floor here bootstraps
236+
// pool_difficulty and lets the first real submission cross the gate.
237+
// Idempotent (fires only while unseeded); uses the exact floor
238+
// compute_share_target's genesis branch emits for max_bits.
239+
if (share_bits_.load(std::memory_order_relaxed) == 0) {
240+
const uint32_t floor_bits =
241+
chain::target_to_bits_upper_bound(bch::PoolConfig::max_target());
242+
share_bits_.store(floor_bits, std::memory_order_relaxed);
243+
share_max_bits_.store(floor_bits, std::memory_order_relaxed);
244+
}
245+
225246
auto sp = std::make_shared<const bch::coin::rpc::WorkData>(std::move(*built));
226247
std::lock_guard<std::mutex> lk(template_mutex_);
227248
template_cache_ = sp;

0 commit comments

Comments
 (0)