{
 "product": "scaling-war",
 "title": "The Scaling War",
 "version": "1",
 "blurb": "Bitcoin's governance history extracted from the block version field: every BIP9 signal, era-bounded, genesis to tip.",
 "publisher": "PARALLAX",
 "generated_utc": "2026-07-29T22:49:58Z",
 "produced_by": "self-hosted full archival Bitcoin node; no external data source",
 "source_provenance": {
  "built_utc": "2026-07-28T23:10:33Z",
  "source": "raw blk files at blocks, version = int32 LE at blk_offset+8",
  "script": "extract_versions.py",
  "coverage": "heights 0..960043, complete",
  "verification": "magic asserted at every offset; genesis==1; 24 heights vs bitcoin-cli getblockheader"
 },
 "tables": [
  {
   "name": "block_versions",
   "description": "The raw seam: height, block time, and the version field both as Bitcoin Core reports it and normalised to unsigned. Genesis to tip, certified 23/23 against Core's getblockheader. Use version_unsigned for any bit masking - the signed form inverts every high-bit test.",
   "sql": "\nSELECT b.height,\n       to_timestamp(b.ts) AS block_time,\n       bv.version,\n       CASE WHEN bv.version < 0 THEN bv.version + 4294967296\n            ELSE bv.version END AS version_unsigned\n  FROM hdr.block_headers b JOIN block_versions bv USING (height)\n ORDER BY b.height",
   "rows": 960044,
   "schema": [
    [
     "height",
     "BIGINT"
    ],
    [
     "block_time",
     "TIMESTAMP WITH TIME ZONE"
    ],
    [
     "version",
     "INTEGER"
    ],
    [
     "version_unsigned",
     "BIGINT"
    ]
   ],
   "columns": {
    "height": {
     "count": 960044,
     "xor": "5254929446705319127",
     "sum": "8856992630060971220900585"
    },
    "block_time": {
     "count": 960044,
     "xor": "13044504908103682925",
     "sum": "8860528930126789393720493"
    },
    "version": {
     "count": 960044,
     "xor": "8489458955218004235",
     "sum": "7997636765473072660101879"
    },
    "version_unsigned": {
     "count": 960044,
     "xor": "8489458955218004235",
     "sum": "7997636765473072660101879"
    }
   },
   "files": {
    "parquet": {
     "path": "data/block_versions.parquet",
     "bytes": 6722215,
     "sha256": "3a376127eef746c463e9b66cb14085710ebb550c75fb6153d9107f0f5650270f"
    },
    "csv": {
     "path": "data/block_versions.csv",
     "bytes": 41359259,
     "sha256": "289a995dc2ee3dff5267ea5590fc3bb54c4787efbaebf84e32285a3af1b05f4c"
    }
   }
  },
  {
   "name": "bip9_signalling_monthly",
   "description": "Monthly BIP9 signalling shares per bit - the series behind the CSV, SegWit and Taproot panels.",
   "sql": "SELECT * FROM a.bip9_signalling_monthly ORDER BY month",
   "rows": 211,
   "schema": [
    [
     "month",
     "VARCHAR"
    ],
    [
     "blocks",
     "BIGINT"
    ],
    [
     "csv_bit0_pct",
     "DOUBLE"
    ],
    [
     "segwit_bit1_pct",
     "DOUBLE"
    ],
    [
     "taproot_bit2_pct",
     "DOUBLE"
    ],
    [
     "rolled_pct",
     "DOUBLE"
    ]
   ],
   "columns": {
    "month": {
     "count": 211,
     "xor": "4852654139577619881",
     "sum": "1925283822886067687517"
    },
    "blocks": {
     "count": 211,
     "xor": "82013295867478845",
     "sum": "1826373831897907462753"
    },
    "csv_bit0_pct": {
     "count": 211,
     "xor": "10978416095405100202",
     "sum": "194863244078850682222"
    },
    "segwit_bit1_pct": {
     "count": 211,
     "xor": "10051101379922929066",
     "sum": "364620351471676318864"
    },
    "taproot_bit2_pct": {
     "count": 211,
     "xor": "8519597820713944205",
     "sum": "679087663238792938511"
    },
    "rolled_pct": {
     "count": 211,
     "xor": "7568920681905688269",
     "sum": "1070512072800341928791"
    }
   },
   "files": {
    "parquet": {
     "path": "data/bip9_signalling_monthly.parquet",
     "bytes": 3830,
     "sha256": "c7bb3761c325b50ab37d0f6b385b1fd45482ebc26a1a0f3a5437208c8d033770"
    },
    "csv": {
     "path": "data/bip9_signalling_monthly.csv",
     "bytes": 7024,
     "sha256": "e44259a04768d2150414f7c30350211c3c9ff02e303d3008b8240371310e298f"
    }
   }
  },
  {
   "name": "signal_blocks",
   "description": "EVERY era-bounded signalling block, one row per block per proposal. The era bound is the asset: bit 28 is Bitcoin Classic before 2018 and mining entropy after it.",
   "sql": "\nSELECT 'BIP101_XT' AS proposal, height, t AS block_time, uv AS version,\n       'exact version 0x20000007' AS era_rule\n  FROM v WHERE uv = 536870919\nUNION ALL\nSELECT 'BIP109_Classic', height, t, uv,\n       'BIP9 top bits 001 AND bit 28 AND before 2018-01-01 (bit 28 is inside BIP320)'\n  FROM v WHERE (uv & 3758096384) = 536870912\n           AND (uv & 268435456) <> 0\n           AND t < TIMESTAMP '2018-01-01'\nUNION ALL\nSELECT 'BIP68_112_113_CSV', height, t, uv, 'BIP9 top bits 001 AND bit 0'\n  FROM v WHERE (uv & 3758096384) = 536870912 AND (uv & 1) <> 0\nUNION ALL\nSELECT 'BIP141_SegWit', height, t, uv, 'BIP9 top bits 001 AND bit 1'\n  FROM v WHERE (uv & 3758096384) = 536870912 AND (uv & 2) <> 0\nUNION ALL\nSELECT 'BIP341_Taproot', height, t, uv, 'BIP9 top bits 001 AND bit 2'\n  FROM v WHERE (uv & 3758096384) = 536870912 AND (uv & 4) <> 0\nORDER BY proposal, height",
   "rows": 77597,
   "schema": [
    [
     "proposal",
     "VARCHAR"
    ],
    [
     "height",
     "BIGINT"
    ],
    [
     "block_time",
     "TIMESTAMP WITH TIME ZONE"
    ],
    [
     "version",
     "BIGINT"
    ],
    [
     "era_rule",
     "VARCHAR"
    ]
   ],
   "columns": {
    "proposal": {
     "count": 77597,
     "xor": "15048751770228419442",
     "sum": "642085802195026671922212"
    },
    "height": {
     "count": 77597,
     "xor": "1425223220152591398",
     "sum": "716358015963081035465252"
    },
    "block_time": {
     "count": 77597,
     "xor": "12046201524586520137",
     "sum": "715738278111219497167403"
    },
    "version": {
     "count": 77597,
     "xor": "4409735723799773626",
     "sum": "809188730014508222269420"
    },
    "era_rule": {
     "count": 77597,
     "xor": "15517719487908011110",
     "sum": "146295540953563341728564"
    }
   },
   "files": {
    "parquet": {
     "path": "data/signal_blocks.parquet",
     "bytes": 570966,
     "sha256": "d06e999a57ea92ee7f4a2a0e62f7a276555c3ecbaf291594b2e732dc7cfa094f"
    },
    "csv": {
     "path": "data/signal_blocks.csv",
     "bytes": 6549642,
     "sha256": "9316db5d93a5d33b97f4ee00f73e8662179cdff1a59b55168dacc006582e1a8e"
    }
   }
  },
  {
   "name": "version_rolling_by_year",
   "description": "Per year: share of blocks rolling the BIP320 mask, and how many distinct version values existed. The ballot box becoming a nonce.",
   "sql": "\nSELECT CAST(EXTRACT(YEAR FROM t) AS INT) AS year,\n       COUNT(*) AS blocks,\n       ROUND(100.0 * AVG(CASE WHEN (uv & 3758096384) = 536870912\n                               AND (uv & 536862720) <> 0 THEN 1.0 ELSE 0.0 END), 2) AS rolled_pct,\n       COUNT(DISTINCT uv) AS distinct_versions\n  FROM v GROUP BY 1 ORDER BY 1",
   "rows": 18,
   "schema": [
    [
     "year",
     "INTEGER"
    ],
    [
     "blocks",
     "BIGINT"
    ],
    [
     "rolled_pct",
     "DOUBLE"
    ],
    [
     "distinct_versions",
     "BIGINT"
    ]
   ],
   "columns": {
    "year": {
     "count": 18,
     "xor": "12230010746727250029",
     "sum": "133719674641882519955"
    },
    "blocks": {
     "count": 18,
     "xor": "12585947844856171957",
     "sum": "168760343531892918749"
    },
    "rolled_pct": {
     "count": 18,
     "xor": "14986829031867269152",
     "sum": "126121905395249236480"
    },
    "distinct_versions": {
     "count": 18,
     "xor": "4692551671784285088",
     "sum": "137596264087203508764"
    }
   },
   "files": {
    "parquet": {
     "path": "data/version_rolling_by_year.parquet",
     "bytes": 900,
     "sha256": "3d030a9c049714a683971572d52812c700d20c271894a0245ad277d2ebefd6dd"
    },
    "csv": {
     "path": "data/version_rolling_by_year.csv",
     "bytes": 394,
     "sha256": "d99e625f5a0758377db38ebce811b499bac326958a48113cc3e4bee4d300704a"
    }
   }
  }
 ],
 "figures": {
  "xt_blocks_ever": {
   "sql": "SELECT count(*) FROM signal_blocks WHERE proposal = 'BIP101_XT'",
   "value": "41"
  },
  "classic_blocks_era_bounded": {
   "sql": "SELECT count(*) FROM signal_blocks WHERE proposal = 'BIP109_Classic'",
   "value": "2176"
  },
  "classic_blocks_IF_ERA_BOUND_OMITTED": {
   "sql": "SELECT count(*) FROM block_versions WHERE (version_unsigned & 3758096384) = 536870912 AND (version_unsigned & 268435456) <> 0",
   "value": "64928"
  },
  "distinct_versions_2018": {
   "sql": "SELECT distinct_versions FROM version_rolling_by_year WHERE year = 2018",
   "value": "27"
  },
  "distinct_versions_2024": {
   "sql": "SELECT distinct_versions FROM version_rolling_by_year WHERE year = 2024",
   "value": "21754"
  },
  "blocks_total": {
   "sql": "SELECT count(*) FROM block_versions",
   "value": "960044"
  },
  "max_height": {
   "sql": "SELECT max(height) FROM block_versions",
   "value": "960043"
  }
 },
 "controls": {
  "classic_bit28_absent_in_2015": {
   "sql": "SELECT count(*) = 0 FROM block_versions WHERE (version_unsigned & 3758096384) = 536870912 AND (version_unsigned & 268435456) <> 0 AND EXTRACT(YEAR FROM block_time) = 2015",
   "expected": true,
   "observed": true,
   "passed": true,
   "why": "Bitcoin Classic did not exist in 2015, so its bit must be unset all year. This is the control that proves the era bound is doing real work rather than being decoration."
  },
  "taproot_silent_before_deployment": {
   "sql": "SELECT taproot_bit2_pct = 0 FROM bip9_signalling_monthly WHERE month = '2021-04'",
   "expected": true,
   "observed": true,
   "passed": true,
   "why": "April 2021, the month before Taproot signalling opened: 0 of 4,073 blocks. A signal that appears before its deployment window means the bit is being read wrong."
  },
  "versions_normalise_unsigned": {
   "sql": "SELECT count(*) = 0 FROM block_versions WHERE version_unsigned < 0",
   "expected": true,
   "observed": true,
   "passed": true,
   "why": "Versions are stored signed. If normalisation failed, every high-bit mask in this product would silently invert."
  },
  "seam_is_gapless": {
   "sql": "SELECT count(*) = max(height) + 1 FROM block_versions",
   "expected": true,
   "observed": true,
   "passed": true,
   "why": "One row per block from genesis with no holes. A gapped seam would under-count every signal without ever looking wrong."
  }
 },
 "root_algorithm": "sha256 of the canonical JSON encoding of this manifest with the 'root' key removed (sort_keys, separators (',',':'), ensure_ascii false, utf-8)",
 "root": "6a9e8c9543e1aae312c561333b6a1ab206a018ba40b657e37d23027c67a2bd98"
}