Skip to content

Commit ec5892e

Browse files
committed
dgb(g3a): populated-block regtest harness + round-trip assertions
Isolated digibyted regtest greenlight gate G3a: mine ONE block holding a diverse tx mix (P2PKH, P2SH 1-of-2, native P2WPKH/P2WSH, P2SH-P2WPKH, OP_RETURN) and HARD-FAIL assert that every output-script type and all SegWit witness data survive a full serialize->node->deserialize round-trip: A1 block is populated (coinbase + >=5 payload tx, not coinbase-only) A2 coinbase carries the segwit witness commitment (6a24aa21a9ed) A3 every witness-bearing tx has txid != wtxid (witness not stripped/lost) A4 types-in == types-survived-roundtrip across all 5 core script types Additive scripts/ only; no consensus/shared-base/build.yml/CMake surface.
1 parent 67e1cec commit ec5892e

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env bash
2+
# G3a — DGB v36 greenlight gate: produce a POPULATED regtest block with a
3+
# diverse transaction mix and HARD-FAIL assertions that every output-script
4+
# type and the SegWit witness data survive a full serialize->node->deserialize
5+
# round-trip. Isolated digibyted regtest only (off-prod); self-provisions coins.
6+
# Additive/fenced: no consensus, shared-base, build.yml or CMake surface.
7+
set -euo pipefail
8+
D="${DGB_SRC:-$HOME/Github/digibyte/src}"
9+
CLI="$D/digibyte-cli"
10+
J() { python3 -c 'import sys,json;print(json.load(sys.stdin)["'"$1"'"])'; }
11+
fail() { echo "ASSERT-FAIL: $*" >&2; exit 1; }
12+
13+
echo "=== G3a populated-block harness — chain=$($CLI getblockchaininfo | J chain) ==="
14+
[ "$($CLI getblockchaininfo | J chain)" = "regtest" ] || fail "refusing to run off regtest"
15+
16+
# --- 1. self-provision mature coins -----------------------------------------
17+
A_LEGACY=$($CLI getnewaddress "" legacy)
18+
$CLI generatetoaddress 130 "$A_LEGACY" >/dev/null
19+
echo "mined 130 -> spendable balance: $($CLI getbalance)"
20+
21+
# --- 2. one address per output-script type ----------------------------------
22+
A_P2PKH=$($CLI getnewaddress "" legacy) # pubkeyhash
23+
A_P2WPKH=$($CLI getnewaddress "" bech32) # witness_v0_keyhash (wallet-owned)
24+
A_P2SHWPKH=$($CLI getnewaddress "" p2sh-segwit) # scripthash, witness when spent (wallet-owned)
25+
K1=$($CLI getaddressinfo "$($CLI getnewaddress)" | J pubkey)
26+
K2=$($CLI getaddressinfo "$($CLI getnewaddress)" | J pubkey)
27+
A_MS_P2SH=$($CLI createmultisig 1 "[\"$K1\",\"$K2\"]" legacy | J address) # scripthash (1-of-2, donation shape)
28+
A_MS_P2WSH=$($CLI createmultisig 1 "[\"$K1\",\"$K2\"]" bech32 | J address) # witness_v0_scripthash
29+
30+
# --- 3. pre-seed wallet-owned SEGWIT utxos (spent in the block => witnesses) -
31+
$CLI sendmany "" "{\"$A_P2WPKH\":25,\"$A_P2SHWPKH\":25}" >/dev/null
32+
$CLI generatetoaddress 1 "$A_LEGACY" >/dev/null
33+
34+
pick_utxo() { # $1=address -> "txid vout"
35+
$CLI listunspent 1 9999999 "[\"$1\"]" | python3 -c 'import sys,json;u=json.load(sys.stdin)[0];print(u["txid"],u["vout"])'
36+
}
37+
38+
# --- 4. assemble the POPULATED block's mempool ------------------------------
39+
# T1: spend P2WPKH utxo -> native-segwit witness tx (txid != wtxid)
40+
read -r I1T I1V < <(pick_utxo "$A_P2WPKH")
41+
T1R=$($CLI createrawtransaction "[{\"txid\":\"$I1T\",\"vout\":$I1V}]" "{\"$A_P2PKH\":24.9}")
42+
T1=$($CLI sendrawtransaction "$($CLI signrawtransactionwithwallet "$T1R" | J hex)")
43+
# T5: spend P2SH-P2WPKH utxo -> wrapped-segwit witness tx (txid != wtxid)
44+
read -r I5T I5V < <(pick_utxo "$A_P2SHWPKH")
45+
T5R=$($CLI createrawtransaction "[{\"txid\":\"$I5T\",\"vout\":$I5V}]" "{\"$A_P2PKH\":24.9}")
46+
T5=$($CLI sendrawtransaction "$($CLI signrawtransactionwithwallet "$T5R" | J hex)")
47+
# T2: bare-funded raw tx -> P2SH 1-of-2 multisig output + OP_RETURN data carrier
48+
DATA=$(printf 'c2pool-dgb-g3a' | xxd -p)
49+
T2R=$($CLI createrawtransaction "[]" "{\"$A_MS_P2SH\":5,\"data\":\"$DATA\"}")
50+
T2F=$($CLI fundrawtransaction "$T2R" | J hex)
51+
T2=$($CLI sendrawtransaction "$($CLI signrawtransactionwithwallet "$T2F" | J hex)")
52+
# T3: native P2WSH output T4: native P2WPKH output
53+
T3=$($CLI sendtoaddress "$A_MS_P2WSH" 6)
54+
T4=$($CLI sendtoaddress "$A_P2WPKH" 7)
55+
echo "mempool: T1=$T1 T5=$T5 T2=$T2 T3=$T3 T4=$T4"
56+
57+
# --- 5. mine ONE block capturing the whole mempool = the deliverable block ---
58+
BLK=$($CLI generatetoaddress 1 "$A_LEGACY" | python3 -c 'import sys,json;print(json.load(sys.stdin)[0])')
59+
echo "=== deliverable populated block: $BLK ==="
60+
$CLI getblock "$BLK" 2 > /tmp/g3a_block.json
61+
62+
# --- 6. HARD-FAIL assertions ------------------------------------------------
63+
python3 - "$T1" "$T5" <<'PY'
64+
import json,sys
65+
b=json.load(open("/tmp/g3a_block.json")); txs=b["tx"]; T1,T5=sys.argv[1],sys.argv[2]
66+
def fail(m): print("ASSERT-FAIL:",m,file=sys.stderr); sys.exit(1)
67+
n=len(txs); print(f" block tx count = {n}")
68+
if n<6: fail(f"under-populated ({n} txs, want >=6)")
69+
print(" [PASS] A1 populated (coinbase + >=5 payload tx)")
70+
cb=txs[0]
71+
if not any(o["scriptPubKey"]["hex"].startswith("6a24aa21a9ed") for o in cb["vout"]):
72+
fail("coinbase missing segwit witness commitment")
73+
print(" [PASS] A2 coinbase witness-commitment present")
74+
seg=sum(1 for t in txs[1:] if any("txinwitness" in v for v in t["vin"]))
75+
for nm,need in (("T1",T1),("T5",T5)):
76+
tt=[t for t in txs if t["txid"]==need]
77+
if not tt: fail(f"witness tx {nm}={need} absent")
78+
if tt[0]["txid"]==tt[0]["hash"]: fail(f"{nm} txid==wtxid (witness lost)")
79+
print(f" [PASS] A3 {seg} witness tx(s); txid!=wtxid holds for T1,T5")
80+
want={"pubkeyhash","scripthash","witness_v0_keyhash","witness_v0_scripthash","nulldata"}
81+
got=set(o["scriptPubKey"].get("type") for t in txs for o in t["vout"] if o["scriptPubKey"].get("type"))
82+
print(" output types survived round-trip:",sorted(got))
83+
miss=want-got
84+
if miss: fail(f"types lost on round-trip: {miss}")
85+
print(" [PASS] A4 all 5 core script types survived node serialize->deserialize")
86+
print("\nG3A RESULT: PASS — block %s height=%d txs=%d witness=%d types=%s"%(b["hash"],b["height"],n,seg,sorted(got)))
87+
PY
88+
echo "=== G3a complete (height $($CLI getblockcount)) ==="

0 commit comments

Comments
 (0)