Skip to content

Commit a8e8a54

Browse files
authored
btc(test): G1 version_gate SSOT v36-activation boundary KAT (#376)
Pin the V36 share-format/consensus-revision boundary as a regression lock: is_v36_active() flips at exactly version 36 (35->false, 36->true), uniform cross-coin, with compile-time static_asserts for the if-constexpr gate sites. Second KAT guards the SCOPE invariant that coin-specific segwit activation (BTC 33) is NOT folded into the uniform v36 gate. Proves the v36-delta BOUNDARY only; full v35 byte-parity is closed separately by the canonical golden-hex vector (G0). Rides existing btc_share_test exe, no build.yml change. btc_share_test green locally (boundary 2/2, suite 8/8). Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
1 parent f9eaba3 commit a8e8a54

1 file changed

Lines changed: 44 additions & 1 deletion

File tree

src/impl/btc/test/share_test.cpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,47 @@ TEST(LTC_share_test, Init)
2424
std::cout << rshare.type << std::endl;
2525

2626
auto share = btc::load_share(rshare, NetService{"0.0.0.0", 0});
27-
}
27+
}
28+
#include <core/version_gate.hpp>
29+
30+
// G1 — version_gate SSOT boundary KAT (BTC reference adoption).
31+
// Proves the V36 share-format / consensus-revision boundary: is_v36_active()
32+
// flips at EXACTLY version 36, uniformly across coins, independent of any
33+
// per-coin segwit activation. This pins the v36-delta BOUNDARY only; full v35
34+
// byte-parity is closed separately by the canonical golden-hex vector (G0).
35+
TEST(BTC_version_gate, V36ActivationBoundary)
36+
{
37+
using core::version_gate::is_v36_active;
38+
using core::version_gate::V36_ACTIVATION_VERSION;
39+
40+
// Activation number is the uniform cross-coin 36 (no per-coin network state).
41+
EXPECT_EQ(V36_ACTIVATION_VERSION, 36u);
42+
43+
// Pre-v36 versions use the legacy sharechain encoding.
44+
EXPECT_FALSE(is_v36_active(0));
45+
EXPECT_FALSE(is_v36_active(17)); // ltc/bch segwit version — NOT a v36 gate
46+
EXPECT_FALSE(is_v36_active(33)); // BTC segwit version — NOT a v36 gate
47+
EXPECT_FALSE(is_v36_active(35)); // exactly one below the boundary
48+
49+
// v36 and above use the V36 encoding + V36 consensus semantics.
50+
EXPECT_TRUE(is_v36_active(36)); // exactly at the boundary
51+
EXPECT_TRUE(is_v36_active(37));
52+
EXPECT_TRUE(is_v36_active(1000));
53+
54+
// The flip is a single version step — no off-by-one at the boundary.
55+
EXPECT_NE(is_v36_active(35), is_v36_active(36));
56+
57+
// constexpr: serves `if constexpr` template gates as well as runtime checks.
58+
static_assert(!is_v36_active(35), "v35 must be pre-v36 at compile time");
59+
static_assert(is_v36_active(36), "v36 must activate at compile time");
60+
}
61+
62+
// SCOPE guard: segwit activation is coin-SPECIFIC and MUST NOT be folded into
63+
// the uniform v36 gate. BTC segwit=33 sits below 36, so a share can be
64+
// segwit-active yet pre-v36 — the two boundaries are independent by design.
65+
TEST(BTC_version_gate, SegwitNotFoldedIntoV36Gate)
66+
{
67+
static_assert(33u < core::version_gate::V36_ACTIVATION_VERSION,
68+
"BTC segwit version must remain below the v36 gate");
69+
EXPECT_FALSE(core::version_gate::is_v36_active(33));
70+
}

0 commit comments

Comments
 (0)