diff --git a/src/impl/bch/pool_entrypoint.hpp b/src/impl/bch/pool_entrypoint.hpp index 82e15f1dd..85832574f 100644 --- a/src/impl/bch/pool_entrypoint.hpp +++ b/src/impl/bch/pool_entrypoint.hpp @@ -191,11 +191,11 @@ inline void standup_pool_run(boost::asio::io_context& ioc, -> core::stratum::RefHashResult { core::stratum::RefHashResult result; - result.share_version = 35; + result.share_version = 36; // v36-native BCH sharechain (was 35, verify-preimage fix) result.desired_version = 36; bch::RefHashParams p; - p.share_version = 35; + p.share_version = 36; // v36-native genesis default (was 35) p.prev_share = prev_share_hash; p.coinbase_scriptSig = scriptSig; p.share_nonce = 0; @@ -505,7 +505,7 @@ inline void standup_pool_run(boost::asio::io_context& ioc, // reconstruction is byte-exact; fall back to the prev-tip version // (cold start: v35 voting v36) when ref_hash_fn produced no frozen // data (bits == 0). - int64_t create_ver = 35; + int64_t create_ver = 36; // author V36 from genesis (was 35): empty-chain V35 hash_link cannot carry this coinbase if (job.frozen_ref.bits != 0) { create_ver = job.frozen_ref.share_version; } else if (!job.prev_share_hash.IsNull() && diff --git a/src/impl/bch/share_check.hpp b/src/impl/bch/share_check.hpp index f4e4403f7..b1bea105c 100644 --- a/src/impl/bch/share_check.hpp +++ b/src/impl/bch/share_check.hpp @@ -170,6 +170,19 @@ inline HashLinkType prefix_to_hash_link_v35( const std::vector& const_ending) { auto v36_link = prefix_to_hash_link(prefix, const_ending); + // FAIL-LOUD (v36 verify-preimage): a V35 HashLinkType (FixedStrType(0)) has + // NO extra_data field, so any coinbase whose trailing partial SHA-256 block + // exceeds the const_ending tail (bufsize > len(const_ending)) leaves residual + // bytes a V35 hash_link cannot carry. Silently dropping them makes + // check_hash_link recompute a DIFFERENT coinbase txid than the author + // committed, so the share fails verify against a v36 peer. This is exactly + // the case the oracle's V36 hash_link (variable-length extra_data) exists + // for: such a coinbase MUST be authored at V36. Refuse to forge an + // unrepresentable V35 hash_link rather than emit a mismatching preimage. + if (!v36_link.m_extra_data.m_data.empty()) + throw std::runtime_error( + "prefix_to_hash_link_v35: coinbase requires V36 hash_link " + "(extra_data non-empty; V35 FixedStrType(0) cannot represent it)"); HashLinkType result; result.m_state = v36_link.m_state; result.m_length = v36_link.m_length;