{
 "number": 36466,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/36466",
 "title": "policy: make unstructured Taproot annexes standard",
 "author": "RobinLinus",
 "author_association": "FIRST_TIME_CONTRIBUTOR",
 "created_at": "2026-10-08T07:23:31Z",
 "updated_at": "2026-10-31T09:50:20Z",
 "description_hash": "78af74d344719a19",
 "age_days": 24,
 "draft": false,
 "labels": [
  "TX fees and policy"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
 "head_ref": "policy-unstructured-annex",
 "head_repo": "RobinLinus/bitcoin",
 "head_history": [],
 "additions": 273,
 "deletions": 28,
 "changed_files": 5,
 "commit_count": 4,
 "size_bucket": "M",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "ack": [
     {
      "login": "petertodd",
      "url": "https://github.com/bitcoin/bitcoin/pull/36466#issuecomment-6129681032"
     }
    ],
    "concept_ack": [
     {
      "login": "Rob1Ham",
      "url": "https://github.com/bitcoin/bitcoin/pull/36466#issuecomment-6390126363"
     }
    ]
   },
   "conflicts": []
  }
 },
 "acks_parsed": {
  "petertodd": {
   "kind": "ack",
   "hash": "b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
   "t": "2026-10-12T17:55:36Z",
   "stale": false
  },
  "Rob1Ham": {
   "kind": "ack",
   "hash": null,
   "t": "2026-10-24T22:07:00Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 2,
  "stale_ack": 0,
  "concept_ack": 0,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "Rob1Ham",
   "petertodd",
   "sipa"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-10-22T03:39:05Z",
  "last_reviewer_activity": "2026-10-24T22:07:00Z",
  "last_reviewer": "Rob1Ham",
  "author_silent_days": 10,
  "waiting_on_author_days": 8,
  "days_since_update": 1
 },
 "refs": {
  "mentioned": [
   27926
  ],
  "depends_on": [
   27926
  ],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 27926,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "policy: make unstructured annex standard"
   }
  ],
  "conflicts": []
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "src/policy/policy.cpp"
 ],
 "body": "Make Taproot annexes standard for key and script paths:\n\n- `0x50`: marker-only opt-in.\n- `0x50 0x00 <data>`: arbitrary data; other prefixes remain nonstandard.\n- All non-P2A inputs must carry an annex, or none may. P2A witnesses must be empty.\n\nNo annex-specific size limit; the existing 400,000 WU standard transaction limit applies.\n\nThis opt-in rule protects transactions that do not opt in. It does not prevent annex inflation by opted-in participants. Consensus and witness replacement are unchanged.\n\nBuilds on #27926 and [Libre Relay](https://github.com/petertodd/bitcoin/commit/04c8e449a34e74e048bf5751d13592a22763ff7e).\n\nValidation: full build, 17 transaction unit tests, full `feature_taproot.py`, and `git diff --check` passed.\n\nAI-assisted implementation and tests.",
 "commits": [
  {
   "sha": "aa85bd97d1e2fca0a022b0dc75e87d0c88c435fb",
   "date": "2026-10-08T07:10:43Z",
   "message": "policy: allow unstructured Taproot annexes\n\nPermit marker-only annexes and annexes whose first byte after the\n0x50 marker is 0x00, reserving other prefixes for future semantics.\nAnnex weight remains subject to MAX_STANDARD_TX_WEIGHT without an\nadditional per-input limit.\n\nRequire all transaction inputs to carry an annex if any does. This\nprevents unilateral introduction of an annex into transactions with\nparticipants who did not opt in; it does not prevent witness inflation\namong participants who opted in.\n\nCover key and script paths, mixed input types, reserved prefixes,\nscript stack limits, and the transaction weight boundary. Update the\nTaproot functional tests to exercise standard unstructured annexes.\n\nBuilds on the all-input opt-in approach in bitcoin/bitcoin#27926 and\nthe Libre Relay implementation."
  },
  {
   "sha": "2506b64ff5d0f2175154cba64eb881433a491523",
   "date": "2026-10-08T07:29:29Z",
   "message": "test: name AddCoins arguments in annex policy test"
  },
  {
   "sha": "bb6ccd0adaf1124a2df7447e5f6889fd50e11fbf",
   "date": "2026-10-08T10:42:37Z",
   "message": "policy: exempt P2A inputs from annex opt-in\n\nExclude native P2A inputs from the all-input annex requirement while retaining their empty-witness policy. Other inputs must still opt in together.\n\nCover mixed spends, input ordering, multiple anchors, wrapped and unknown witness programs, and witness stuffing in unit and functional tests."
  },
  {
   "sha": "b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
   "date": "2026-10-08T17:11:52Z",
   "message": "policy: clarify annex opt-in and prefix rationale"
  }
 ],
 "timeline": [
  {
   "t": "2026-10-08T10:07:16Z",
   "kind": "comment",
   "who": "petertodd",
   "assoc": "CONTRIBUTOR",
   "text": "[quoted text omitted]\n\nWe should exclude spends of P2A outputs here, as they can't contain an annex.",
   "id": "c:6057525720",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#issuecomment-6057525720",
   "hash": "a93a3e463f18d203",
   "edited": null
  },
  {
   "t": "2026-10-08T10:52:34Z",
   "kind": "comment",
   "who": "RobinLinus",
   "assoc": "NONE",
   "text": "@petertodd Thanks, fixed in bb6ccd0. Native P2A inputs are exempt; their witnesses must remain empty.",
   "id": "c:6058269299",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#issuecomment-6058269299",
   "hash": "cdb19671a065bd9b",
   "edited": null
  },
  {
   "t": "2026-10-08T11:00:15Z",
   "kind": "review_comment",
   "who": "petertodd",
   "assoc": "CONTRIBUTOR",
   "path": "src/policy/policy.cpp",
   "commit": "b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
   "in_reply_to": null,
   "text": "You should re-add the \"witness stuffing detected\" comment here to explain what this line is doing.",
   "id": "rc:4218079081",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#discussion_r4218079081",
   "hash": "ad0bd6d4beda7ea4",
   "edited": null
  },
  {
   "t": "2026-10-08T11:00:56Z",
   "kind": "review_comment",
   "who": "petertodd",
   "assoc": "CONTRIBUTOR",
   "path": "src/policy/policy.cpp",
   "commit": "b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
   "in_reply_to": null,
   "text": "...and the comment about P2A inputs and the annex probably makes more sense here.",
   "id": "rc:4218085007",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#discussion_r4218085007",
   "hash": "f5125d612aee2192",
   "edited": null
  },
  {
   "t": "2026-10-08T11:03:14Z",
   "kind": "review_comment",
   "who": "petertodd",
   "assoc": "CONTRIBUTOR",
   "path": "src/policy/policy.cpp",
   "commit": "b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
   "in_reply_to": null,
   "text": "I'm confused by this fragment. It doesn't look like it's related to the annex stuff at all. Rather it's just skipping further checks if scriptWitness is empty.",
   "id": "rc:4218105149",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#discussion_r4218105149",
   "hash": "9008a99b0a4cc443",
   "edited": null
  },
  {
   "t": "2026-10-08T11:04:13Z",
   "kind": "review_comment",
   "who": "petertodd",
   "assoc": "CONTRIBUTOR",
   "path": "src/policy/policy.cpp",
   "commit": "bb6ccd0adaf1124a2df7447e5f6889fd50e11fbf",
   "in_reply_to": null,
   "text": "It'd be more clear to say that \"Annexes must be zero-length, or start with the unstructured data prefix, 0x00\"",
   "id": "rc:4218113901",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#discussion_r4218113901",
   "hash": "4cf1e5fdd62e7787",
   "edited": null
  },
  {
   "t": "2026-10-08T11:07:26Z",
   "kind": "review_comment",
   "who": "petertodd",
   "assoc": "CONTRIBUTOR",
   "path": "src/policy/policy.cpp",
   "commit": "b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
   "in_reply_to": null,
   "text": "We should explain why the unstructured marker is being used here: 0x00 is reserved, so that future consensus-related usage of the annex can use a different prefix (quite possibly an entire encoding scheme).",
   "id": "rc:4218142203",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#discussion_r4218142203",
   "hash": "089d6c431a901700",
   "edited": null
  },
  {
   "t": "2026-10-08T11:09:24Z",
   "kind": "review_comment",
   "who": "petertodd",
   "assoc": "CONTRIBUTOR",
   "path": "src/policy/policy.cpp",
   "commit": "b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
   "in_reply_to": null,
   "text": "You should use the term \"transaction pinning attack\" here, so people have something to google.",
   "id": "rc:4218158417",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#discussion_r4218158417",
   "hash": "c250d5701ab84267",
   "edited": null
  },
  {
   "t": "2026-10-08T18:15:36Z",
   "kind": "comment",
   "who": "RobinLinus",
   "assoc": "NONE",
   "text": "@petertodd Thanks, addressed in b4179ad. The empty-witness check moved below P2A handling so anchors are counted before the early `continue`.",
   "id": "c:6066221892",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#issuecomment-6066221892",
   "hash": "b5f29f6be688d294",
   "edited": null
  },
  {
   "t": "2026-10-12T17:55:36Z",
   "kind": "comment",
   "who": "petertodd",
   "assoc": "CONTRIBUTOR",
   "text": "utACK b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
   "id": "c:6129681032",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#issuecomment-6129681032",
   "hash": "de7d7e51aaae4800",
   "edited": null
  },
  {
   "t": "2026-10-20T10:24:26Z",
   "kind": "comment",
   "who": "sipa",
   "assoc": "MEMBER",
   "text": "What is the purpose of this? I was imagining that annex standardness would be added at the same time consensus-relevant meaning would be given to annexes.\n\nOf course, if there were active use of annexes on the network it would be useful to accommodate relay, but as of now I don't see the point.",
   "id": "c:6288789786",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#issuecomment-6288789786",
   "hash": "557024007fd8e1ab",
   "edited": null
  },
  {
   "t": "2026-10-22T03:39:05Z",
   "kind": "comment",
   "who": "RobinLinus",
   "assoc": "NONE",
   "text": "@sipa The motivation is data availability for metaprotocols, including a range of shielded protocols such as [Shielded CSV](https://github.com/ShieldedCSV/ShieldedCSV).\n\nAnnexes would let these protocols publish data directly in a Taproot key-path spend, avoiding the script-path commitment and reveal required by inscription-style encoding.\n\nThe motivation for enabling relay now is to support these applications. They need data availability independently of future consensus semantics for the annex; the proposed `0x00` prefix distinguishes this unstructured use from future extensions.\n\nStandard relay would also let these applications reach miners through the public P2P network, reducing the incentive to build private mempools or depend on arrangements with individual mining pools.",
   "id": "c:6332088999",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#issuecomment-6332088999",
   "hash": "7ba4744ae213d7d9",
   "edited": "2026-10-22T07:06:16Z"
  },
  {
   "t": "2026-10-24T22:07:00Z",
   "kind": "comment",
   "who": "Rob1Ham",
   "assoc": "CONTRIBUTOR",
   "text": "ACK",
   "id": "c:6390126363",
   "url": "https://github.com/bitcoin/bitcoin/pull/36466#issuecomment-6390126363",
   "hash": "a2f1a6d79bfb0fe6",
   "edited": null
  }
 ],
 "labels_log": [
  {
   "t": "2026-10-08T07:23:35Z",
   "action": "labeled",
   "label": "TX fees and policy",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-09T13:45:43Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-09T17:12:46Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-10-10T08:39:21Z",
   "kind": "ready_for_review",
   "who": "RobinLinus"
  }
 ],
 "text_chars": 4318,
 "text_tokens_estimate": 1079,
 "changed_paths": [
  "src/policy/policy.cpp",
  "src/policy/policy.h",
  "src/script/interpreter.cpp",
  "src/test/transaction_tests.cpp",
  "test/functional/feature_taproot.py"
 ],
 "files": [
  {
   "path": "src/policy/policy.cpp",
   "add": 25,
   "del": 11
  },
  {
   "path": "src/policy/policy.h",
   "add": 2,
   "del": 1
  },
  {
   "path": "src/script/interpreter.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/transaction_tests.cpp",
   "add": 152,
   "del": 0
  },
  {
   "path": "test/functional/feature_taproot.py",
   "add": 93,
   "del": 15
  }
 ],
 "test_lines": 260,
 "git": {
  "head": "b4179ad2fb6154a4e93f46389cca00b6926fbd2f",
  "head_matches_backup": true,
  "base": "db0bde16b910f43e37252d4172d97f01653ae0f1",
  "patch_id": "78bc1ddd768a3479",
  "commits": [
   {
    "sha": "aa85bd97d1",
    "subject": "policy: allow unstructured Taproot annexes",
    "files": 5,
    "add": 188,
    "del": 21
   },
   {
    "sha": "2506b64ff5",
    "subject": "test: name AddCoins arguments in annex policy test",
    "files": 1,
    "add": 1,
    "del": 1
   },
   {
    "sha": "bb6ccd0ada",
    "subject": "policy: exempt P2A inputs from annex opt-in",
    "files": 3,
    "add": 93,
    "del": 18
   },
   {
    "sha": "b4179ad2fb",
    "subject": "policy: clarify annex opt-in and prefix rationale",
    "files": 1,
    "add": 12,
    "del": 9
   }
  ],
  "patch_truncated": false
 },
 "patch_id": "78bc1ddd768a3479",
 "input_hash": "76a54fc0d5359c57",
 "extracted_at": "2026-11-02T01:09:49+00:00"
}