|
| 1 | +#!/usr/bin/env bash |
| 2 | +# G3b — BCH genuine Upgrade9 (CashTokens) activation gate (CI required-gate entrypoint). |
| 3 | +# Companion to G3a (bch_g3a_regtest_block_production.sh): where G3a proves a |
| 4 | +# POPULATED block is produced, G3b proves the feature is GENUINELY ACTIVATED at a |
| 5 | +# boundary — accepted after the activation height, and IMPOSSIBLE before it — not |
| 6 | +# merely always-on regtest convenience. |
| 7 | +# |
| 8 | +# The activation boundary splits across two layers, and this gate covers both: |
| 9 | +# |
| 10 | +# Default arm (CI-runner, network-free) — the POOL-SIDE activation semantics, via |
| 11 | +# the c2pool-bch in-process CHECK-harnesses: |
| 12 | +# bch_g2_ratchet_gate_kat_test : the 60%-by-WORK share-version SWITCH ratchet |
| 13 | +# — the pool activates the new version only |
| 14 | +# once the work-weighted supermajority crosses, |
| 15 | +# never on a flat count (the genuine switch). |
| 16 | +# bch_cashtokens_transparency_test : the Upgrade9 feature itself — CashTokens |
| 17 | +# FT/NFT genesis+transfer carried transparently |
| 18 | +# through the template once active. |
| 19 | +# bch_coinbase_author_kat_test : the version-gated donation author — sv<36 |
| 20 | +# forrestv P2PK vs sv>=36 combined P2SH — a |
| 21 | +# second activation boundary keyed to share |
| 22 | +# version, byte-pinned. |
| 23 | +# Optional live arm (opt-in when BCH_UPGRADE9_HEIGHT points at a running isolated |
| 24 | +# regtest BCHN started with -upgrade9activationheight=<N>, N>0): drives |
| 25 | +# scripts/bch_g3b_genuine_activation_regtest.py for the CONSENSUS-SIDE boundary — |
| 26 | +# a CashToken FT-genesis tx HARD-REJECTED pre-activation ("txn-tokens-before- |
| 27 | +# activation") and the SAME signed tx ACCEPTED into the won block post-activation. |
| 28 | +# The reject-at-height>0 is impossible under default always-on regtest, so observing |
| 29 | +# it proves the override took effect and activation is real. |
| 30 | +# |
| 31 | +# Deterministic: exit 0 = pass; nonzero = failure / hollow run. Fenced: tests/gates/ |
| 32 | +# entrypoint over existing COIN_BCH targets — no consensus / shared-base / build.yml / |
| 33 | +# CMake / other-coin surface. |
| 34 | +set -euo pipefail |
| 35 | + |
| 36 | +GATE="G3b bch-genuine-activation" |
| 37 | +TEST_REGEX='^bch_(g2_ratchet_gate_kat_test|cashtokens_transparency_test|coinbase_author_kat_test)$' |
| 38 | +TARGETS=(bch_g2_ratchet_gate_kat_test bch_cashtokens_transparency_test \ |
| 39 | + bch_coinbase_author_kat_test) |
| 40 | + |
| 41 | +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" |
| 42 | +# COIN_BCH targets compile ONLY under -DCOIN_BCH=ON, so default to the CI build_bch |
| 43 | +# tree; override BUILD_DIR to reuse a warm cache. |
| 44 | +BUILD_DIR="${BUILD_DIR:-$REPO_ROOT/build_bch}" |
| 45 | + |
| 46 | +# 1. Ensure the targets exist (configure+build only if the CI cache is cold). |
| 47 | +if [ ! -f "$BUILD_DIR/CMakeCache.txt" ]; then |
| 48 | + echo "[$GATE] no build dir at $BUILD_DIR — configuring (conan + cmake -DCOIN_BCH=ON)" |
| 49 | + conan install "$REPO_ROOT" --build=missing --output-folder="$BUILD_DIR" --settings=build_type=Release |
| 50 | + cmake -S "$REPO_ROOT" -B "$BUILD_DIR" \ |
| 51 | + -DCMAKE_TOOLCHAIN_FILE="$BUILD_DIR/conan_toolchain.cmake" \ |
| 52 | + -DCMAKE_BUILD_TYPE=Release \ |
| 53 | + -DCOIN_BCH=ON |
| 54 | +fi |
| 55 | +cmake --build "$BUILD_DIR" --target "${TARGETS[@]}" -j"$(nproc)" |
| 56 | + |
| 57 | +# 2. Run from build/ and capture (false-green trap: wrong CWD prints |
| 58 | +# "No tests were found!!!" and EXITS 0). |
| 59 | +set +e |
| 60 | +OUT="$(cd "$BUILD_DIR" && ctest -R "$TEST_REGEX" --output-on-failure 2>&1)" |
| 61 | +RC=$? |
| 62 | +set -e |
| 63 | +echo "$OUT" |
| 64 | + |
| 65 | +# 3. False-green guard: demand a positive test count actually ran, and that the |
| 66 | +# full expected set matched (a partial regex miss must not read as green). |
| 67 | +if grep -q "No tests were found" <<<"$OUT"; then |
| 68 | + echo "[$GATE] FAIL — hollow run: 0 tests matched $TEST_REGEX" >&2 |
| 69 | + exit 1 |
| 70 | +fi |
| 71 | +N="$(grep -oE 'out of [0-9]+' <<<"$OUT" | grep -oE '[0-9]+' | tail -1)" |
| 72 | +if [ -z "${N:-}" ] || [ "$N" -lt "${#TARGETS[@]}" ]; then |
| 73 | + echo "[$GATE] FAIL — expected ${#TARGETS[@]} tests, matched ${N:-0}" >&2 |
| 74 | + exit 1 |
| 75 | +fi |
| 76 | +if [ "$RC" -ne 0 ]; then |
| 77 | + echo "[$GATE] FAIL — ctest exit $RC ($N tests)" >&2 |
| 78 | + exit "$RC" |
| 79 | +fi |
| 80 | +echo "[$GATE] PASS (CI arm) — $N ratchet-switch / CashTokens-transparency / version-gated-author activation assertions green" |
| 81 | + |
| 82 | +# 4. Optional live regtest arm — only when an isolated BCHN with a >0 activation |
| 83 | +# override is wired in via env. |
| 84 | +if [ -n "${BCH_UPGRADE9_HEIGHT:-}" ]; then |
| 85 | + echo "[$GATE] live arm: driving scripts/bch_g3b_genuine_activation_regtest.py (override height=$BCH_UPGRADE9_HEIGHT)" |
| 86 | + python3 "$REPO_ROOT/scripts/bch_g3b_genuine_activation_regtest.py" |
| 87 | + echo "[$GATE] PASS (live arm) — pre-activation HARD-REJECT + post-activation ACCEPT proven on isolated regtest BCHN" |
| 88 | +else |
| 89 | + echo "[$GATE] live regtest arm SKIPPED (set BCH_UPGRADE9_HEIGHT + start BCHN with -upgrade9activationheight=<N> to enable)" |
| 90 | +fi |
0 commit comments