-
Notifications
You must be signed in to change notification settings - Fork 37.7k
policy: Add PayToAnchor(P2A), OP_1 <0x4e73>
as a standard output script for spending
#30352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utack 99e9d3c
OP_TRUE <0x4e73>
as a standard output scriptOP_TRUE <0x4e73>
as a standard output script for spending
OP_TRUE <0x4e73>
as a standard output script for spendingOP_TRUE <0x4e73>
as a standard output script for spending
Suggestion for adding corresponding Patchdiff --git a/test/functional/rpc_decodescript.py b/test/functional/rpc_decodescript.py
index f37e61ab50..a105b3d3b4 100755
--- a/test/functional/rpc_decodescript.py
+++ b/test/functional/rpc_decodescript.py
@@ -187,6 +187,16 @@ class DecodeScriptTest(BitcoinTestFramework):
assert_equal('1 ' + xonly_public_key, rpc_result['asm'])
assert 'segwit' not in rpc_result
+ self.log.info("- P2A (anchor)")
+ # 1 <4e73>
+ witprog_hex = '4e73'
+ rpc_result = self.nodes[0].decodescript('5102' + witprog_hex)
+ assert_equal('anchor', rpc_result['type'])
+ # in the disassembly, the witness program is shown as single decimal due to its small size
+ witprog_as_decimal = int.from_bytes(bytes.fromhex(witprog_hex), 'little')
+ assert_equal(f'1 {witprog_as_decimal}', rpc_result['asm'])
+ assert 'fees' in rpc_result['address']
+
def decoderawtransaction_asm_sighashtype(self):
"""Test decoding scripts via RPC command "decoderawtransaction". I assume that the witness program was chosen on purpose to contain "fees" in the bech32m encoded address and this was not just by accident? (could also test for the full address anyways) |
Concept NACK. This seems to encourage and promote spam. We should be doing the exact opposite. Curious why you say "creation was already standard" - I don't see why that would be the case. |
This proposal is merely a way of doing something that is already done - signed anchor outputs - in a more efficient way with less overall bytes consumed. The creating and spending of keyless anchor outputs is completely fixed, with no ability to encode any data. It has nothing to do with "spam".
Because we decided to make wallets and Bitcoin Core itself forward compatible with future tapscript versions. If this class of outputs was not standard, you'd have a big transition time before a new type of tapscript was actually usable for general purpose wallets. Concept ACK. |
src/script/interpreter.cpp
Outdated
@@ -1943,6 +1943,9 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, | |||
} | |||
return set_success(serror); | |||
} | |||
} else if (witversion == 1 && program.size() == 2 && program[0] == 0x4e && program[1] == 0x73) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5e7e767: Intentional to make p2sh-p2a spend standard as well? Would be good to have a test as documentation, so that reviewers know what to expect and don't have to guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was unintentional. Disallowed it and added coverage.
There is no situation where this would be preferable.
99e9d3c
to
b7deedf
Compare
@theStack took test coverage suggestion, and yes "fees" is intentional since it will be in any net's address @luke-jr I think @petertodd has stated what I would say. It's a pattern people can already do, and it's trivial and cheap to clean up. |
b7deedf
to
ee0f688
Compare
🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the Possibly this is due to a silent merge conflict (the changes in this pull request being Leave a comment here, if you need help tracking down a confusing failure. |
And at a reduced cost. Unless this proposal increases vsize to make it identical?
What is the 0x4e73 for? These outputs bloat the UTXO set, without sufficient value to incentivise cleanup later. The anchor idea is documented to address this by requiring they be spent before being accepted, but that isn't the case in this PR (unless I missed something).
I didn't notice this was a taproot output. In that case, my question is why that is the case. Shouldn't an output with just |
On July 8, 2024 8:42:50 PM GMT+02:00, Luke Dashjr ***@***.***> wrote:
>This proposal is merely a way of doing something that is already done - signed anchor outputs - in a more efficient way with less overall bytes consumed.
And at a reduced cost. Unless this proposal increases vsize to make it identical?
The cost reduction is a natural one, in line with the byte reduction.
> The creating and spending of keyless anchor outputs is completely fixed, with no ability to encode any data. It has nothing to do with "spam".
What is the 0x4e73 for?
Good question! Maybe that's not needed.
These outputs bloat the UTXO set, without sufficient value to incentivise cleanup later. The anchor idea is documented to address this by requiring they be spent before being accepted, but that isn't the case in this PR (unless I missed something).
They bloat the UTXO set no more than the alternative of keyed anchor outputs, which are already used by Lightning. Slightly less actually, as keyless anchor outputs are smaller.
The lower dust threshold for them is in line with the decrease in # of bytes necessary to spend them.
>>Curious why you say "creation was already standard" - I don't see why that would be the case.
>Because we decided to make wallets and Bitcoin Core itself forward compatible with future tapscript versions.
I didn't notice this was a taproot output. In that case, my question is why that is the case. Shouldn't an output with just `OP_TRUE` in scriptPubKey suffice for this use case?
A bare OP_True scriptPubKey leads to a malleable transaction because it isn't segwit. That's a serious problem for certain use cases.
IMO it would be reasonable to also allow a bare OP_True scriptPubKey for the usecases where that malleability isn't important. But it's reasonable to do both (and actually, I think we can do this with an entirely empty scriptPubKey, which is only (standardly) spendable via OP_True).
|
To be segwit, it needs to be a witness version + witness program(or p2sh nested segwit script). A witness program is 2 to 40 bytes long push. For this use-case we simply use size two. The specific bytes chosen are simply "cutesy" to spell "fees", as they cannot be 0 so something else has to be chosen and have an associated address. As far as I know this is the only proposed size 2 witness program use case so far.
If we want sub-dust(as defined per IsDust) the requirement would be this would be "ephemeral dust" #30239 . These are now conceptually distinct features. This PR simply uses the current dust calculations over all witness program types, which actually still penalizes it for assuming it has a P2WSH-like witness when it actually has no witness related data. Further penalizing can happen for further complication, but I'm unconvinced that this would be a net gain.
Indeed, bare OP_TRUE was my original proposal and could still be rolled out at any point. I think paying the 3 vbytes extra to get txid stability is a fair trade for the time being. Lack of txid stability is awful for reasoning about composability :( |
@achow101 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #29806 for the wallet intermittent unrelated test issue.
ee0f688
to
9f13705
Compare
IIUC these txs will not get relayed widely across the network until there is widespread adoption of |
@Christewart spends of these outputs will not propagate until some 10%+ of the network updates, correct. |
Worth mentioning this in the release notes as this feature is intended for time sensitive protocols. Perhaps putting the cart before the horse, but it is a potential foot gun. |
@Christewart done, since it would need a release note anyways |
…sactionwithkey` succeeds 5e87f30 test: check that keyless P2A 'signing' via `signrawtransactionwithkey` succeeds (Sebastian Falbesoner) Pull request description: This small PR adds a sanity check to verify that transactions with P2A inputs can be 'signed' successfully, using the non-wallet RPC `signrawtransactionwithkey`. Note that in the this flow, `SignStep` (which was also extended for the new `ANCHOR` output type in #30352) is never called, as signing is only tried if the locking script verification isn't successful already. See the review discussion #30352 (comment) ff. ACKs for top commit: instagibbs: ACK 5e87f30 tdb3: ACK 5e87f30 glozow: code review ACK 5e87f30 Tree-SHA512: dfea75b4bf8fa0b9c265ddd63dab36374c2430c31220f0c8eb1b53dd847c183f9e1c493a0173e2da317553a1d4cb1b35aa9ffde1268c430cc610368d23b9c942
2a3a242 test: check that P2A with witness data is still consensus-legal (Greg Sanders) 68bd86c test: P2A is a destination type with an address (Greg Sanders) Pull request description: Followups for #30352 Suggestions taken: #30352 (comment) #30352 (comment) ACKs for top commit: tdb3: ACK 2a3a242 glozow: ACK 2a3a242 theStack: ACK 2a3a242 Tree-SHA512: 5de865b2c300fa504dbdbd5879649a6fc328da052ad8bf9479e3fea0c49c516d824908a87523ec1fb30cc536bffe2e116dd523a9b66a07f81f93429e42879f14
58499b0 refactor: move `SignSignature` helpers to test utils (Sebastian Falbesoner) Pull request description: These helpers haven't been used in production code since segwit was merged more than eight years ago (see commit 605e847, PR #8149), so it seems appropriate to move them to the test utils module. As suggested by instagibbs, see #30352 (comment). ACKs for top commit: instagibbs: ACK 58499b0 pablomartin4btc: ACK 58499b0 Tree-SHA512: a52d3b92b477246f2ceb57c3690d0229a492b65a15dae331faeae9d96e5907f7fe1176edc1530243e0f088586984fd7ba435a0a2d2f2531c04d076fdf3f4095f
Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
f7ea6e5 Add support for pay to anchor outputs (Erik De Smedt) Pull request description: Add support for the newly created Pay2Anchor output-type which was introduced in bitcoin 28.0 See bitcoin/bitcoin#30352 ACKs for top commit: Kixunil: ACK f7ea6e5 apoelstra: ACK f7ea6e5; successfully ran local tests Tree-SHA512: cd3da860e81bd25e6fef72a9118b43d647af2339e9d226c124fa221f63d9c3149189480d40368d38900a999bf59a23fd5302025751ea1bebfea059b4fab21c0b
* Fix key/script spend detection in `Witness` The `taproot_control_block` did not properly detect whether it deals with script spend or key spend. As a result, if key spend with annex was used it'd return the first element (the signature) as if it was a control block. Further, the conditions identifying which kind of spend it was were repeated multiple times but behaved subtly differently making only `taproot_control_block` buggy but the other places confusing. To resolve these issues this change adds a `P2TrSpend` enum that represents a parsed witness and has a single method doing all the parsing. The other methods can then be trivially implemented by matching on that type. This way only one place needs to be verified and the parsing code is more readable since it uses one big `match` to handle all possibilities. The downside of this is a potential perf impact if the parsing code doesn't get inlined since the common parsing code has to shuffle around data that the caller is not intersted in. I don't think this will be a problem but if it will I suppose it will be solvable (e.g. by using `#[inline(always)]`). The enum also looks somewhat nice and perhaps downstream consumers could make use of it. This change does not expose it yet but is written such that after exposing it the API would be (mostly) idiomatic. Closes rust-bitcoin#4097 * Add a test case checking `taproot_control_block` The previous commit fixed a bug when `taproot_control_block` returned `Some` on key-spends. This adds a test case for it which succeeds when applied after the previous commit and fails if applied before it. * Add `taproot_leaf_script` methood to `Witness` We already have `tapscript` method on `Witness` which is broken because it doesn't check that the leaf script is a tapscript, however that behavior might have been intended by some consumers who want to inspect the script independent of the version. To resolve the confusion, we're going to add a new method that returns both the leaf script and, to avoid forgetting version check, also the leaf version. This doesn't touch the `tapscript` method yet to make backporting of this commit easier. It's also worth noting that leaf script is often used together with version. To make passing them around easier it'd be helpful to use a separate type. Thus this also adds a public POD type containing the script and the version. In anticipation of if being usable in different APIs it's also generic over the script type. Similarly to the `tapscript` method, this also only adds the type and doesn't change other functions to use it yet. Only the newly added `taproot_leaf_script` method uses it now. This is a part of rust-bitcoin#4073 * Add Timestamp newtype Bitcoin block headers have a timestamp. Currently we are using a `u32`. while this functions correctly it gives the compiler no chance to enforce type safety. Add a `Timestamp` newtype that is a thin wrapper around a `u32`. Document it and test the API surface in `api.rs`. * Fix `is_invalid_use_of_sighash_single()` incompatibility with Bitcoin Core * Add test for sighash_single_bug incompatility fix * Grab missing changelog We release `v0.32.4` and `v0.32.5` already but forgot to merge the changelog entries back into master. Grab the missing changelog entries from the `0.32.x` release branch. * Update input_string.rs * Update key.rs * Update transaction.rs * Update sighash.rs * chore: remove redundant words in CONTRIBUTING.md Signed-off-by: costcould <fliter@myyahoo.com> * Derive Copy for NumOpResult The `NumOpResult` type is way more ergonomic to use if it derives `Copy`. This restricts the `NumOpResult` to being `Copy` as well. This does restrict what we can include in the error type in the future. Derive Copy for `NumOpResult` and `NumOpResult`. * units: introduce impl_op_for_references and use it in three places This macro can generally handle a lot of different cases where we implement "the same trait but on references". We introduce it here and use it in two places. We will use it in many more, but I wanted to make the diff small on this commit, which introduces the actual macro code and might take a bit of reading to understand. You may want to use --color-moved-ws=allow-indentation-change to review this, and the next commit. The next set of changes will mechanically delete other macros that are made redundant by this. * units: allow multiple invocations in impl_op_for_references macro This is not too complicated a change to support and it will reduce the noise in the following commits a fair bit. * units: rearrange a bit of code to prep the next commit The next commit changes a lot of code, but almost entirely by moving and indenting it. We try to do the moves here ahead of time, so it the diff for the next commit will be just deletions and indentations. * units: replace a gazillion more macro calls with new macro Looks like a large diff but if you run git show --color-moved-ws=allow-indentation-change you will see that it's 100% moves (though moves of code into the reference macro). May be easier to just look at src/amount/result.rs after this; it's pretty short now. * units: extend op reference macro to handle generics and where clauses This is a bit ugly and requires that we put our where-clauses in parentheses because the macro_rules parser sucks, but it allows us to move the blanket-impls on NumOpResult into the macro. This commit moves one instance and updates the macro; the next commits will change the rest. * units: pull generic op impls on NumOpResult into macro * Add a few impls to the result macro Add a few missing impls to the `impl_op_for_references` macro. Includes a minor whitespace change so that traits are grouped together. * Macroise the NumOpResult tests Macroise the tests improving coverage along the way. Includes a TODO to remind us to do `Neg` more fully. * Hide relative locktime error internals As part of the 1.0 effort and forward maintainability hide the internals of the two error types in the `relative` locktime module. Doing so allows us to remove the `non_exhaustive` attribute. Add getters to get at the error innards. * primitives: Hide script error internals As part of the 1.0 effort and forward maintainability hide the internals of the two error types in the `script` module. Add getters to get at the invalid size. * Move taproot back to bitcoin crate I don't know what I was thinking when I move the taproot hash types to `primitives`. As correctly pointed out by Kix we agreed to only have blockdata in `primitives`. Move the taproot hash types back to `bitcoin::taproot` and remove the extension traits. * fuzz: add coverage for Display for Script * Policy: Relax MIN_STANDARD_TX_NONWITNESS_SIZE to 65 Align with Bitcoin Core's policy by reducing the minimum non-witness transaction size from 82 to 65 bytes. This change allows for more minimal transaction cases (e.g., 1 input with 1 OP_RETURN output), while still maintaining protection against CVE-2017-12842. Matches bitcoin/bitcoin#26398 * hashes: Remove Clone trait bound from Tag Implementors of the Tag trait had to use the #[derive(Clone)] attribute. This change eliminates this need by removing the Clone trait bound from the Tag trait. * Add support for pay to anchor outputs Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352 * Typo fix in: README.md Hi, I suggest some typo fix' for this doc: 1- "since these are needed to display hashes anway." Should be "since these are needed to display hashes anyway." (spelling error). 2- "bench mark" and "bench marks" Should be "benchmark" and "benchmarks" (incorrect spacing; "benchmark" is a single word). Thanks. * units: Improve code comment on macros We have two macros that are hidden because they are code de-duplication tools. However the output they produce is, and has to be, stable so that we can use them in `units` and `primitives` without inadvertently breaking semver in `primitives`. * chore: fix some typos in comments Signed-off-by: looklose <shishuaiqun@yeah.net> * Update mod.rs * Update serialized_signature.rs * Update message.rs * Update instruction.rs * Automated update to Github CI to rustc nightly-2025-02-28 * 2025-03-02 automated rustfmt nightly * update secp256k1 to 0.30.0 * Add tests for amount op int We aim to support three ops on amount types that use an integer for the right hand size. Prove that implement them. * Improve add/sub tests for amount types Add a few macros to test `Add` and `Sub` impls for both amount types, all combos of type and res (eg `Amount` and `NumOpResult<Amount>`), and all combos of references. * Add more add/sub tests Add units tests for various values including negative values. * Test amount ops that involve an integer From the amount types `Div`, `Mul`, and `Rem` can have an integer on one side. Test them - includes commented out test for one missing combo. * Add missing Mul impls for amount types Add and test missing `Mul` impls for both amount types. * Implement Div by amount for amount types It is semantically valid to divide an amount by another amount. The result of the operation is an integer. Note that we cannot implement `Div` by `NumOpResult` because there is no way to show the div by invalid case. Implement `Div` by amount for both amount types. * Add additional re-exports As we do for other types add two new alias' at the crate root of `primitives` and mirror it in `bitcoin`: - `BlockVersion` - `TransactionVersion` * Move opcodes back to bitcoin Duplicate `opcodes` in `bitcoin` and hide it in `primitives` so we do not have to commit to the API. We use opcodes in `impl fmt::Display for Script`. Close: rust-bitcoin#4144 * units: Remove unnecessary code comments These comments to not add much value - remove them. * Move Assign impls together Next patch will move all the impls of `Add` and `Sub` into a macro call. In order to make that patch smaller move the assign impls to be together below the add/sub impls. Code move only, no logic change. * Use impl_op_for_references for block height/interval We have a new macro for implementing ops with a bunch of reference combos. Lets use it for block `Height` and `Interval`. This patch is strictly additive. * Use impl_add/sub_assign for block interval We have a macro for implementing `AddAssign` and `SubAssign`. Use the macro, gets us an additional ref impl for both. * Improve docs crate headings I took a look at the rendered HMTL of `bitcoin`, `primitives`, `units`, `serde`, and `tokio` and picked a header style that I thought looked good. Use it for `primitives` and `units`. * hashes: Improve crate docs heading Use same for as the other crates and emphasise that this is a Bitcoin hashes crate. * io: Improve crate docs heading Use the same format as the other crates. * chacha20: Add a docs heading Like we do for the other crates add a heading to the crate docs. * chacha20: Add whitespace Mirror the other crates. Whitespace only. * Improve Weight rustdocs Do trivial improvement to rustdocs for the `Weight` type. * Make Weigth::from_kwu const The other two `Weight` constructors are const already. * Use uniform return statement in docs We have a bunch of 'Returns [`None`] if .. ' statements. Make the whole module uniform. * Manually update nightly version While trying to use the `macro_use_imports` lint I found that there is a bug in last weeks nightly. It has been fixed already so lets update. Update to todays nightly compiler. Doing so causes some new linter warnings, for now we just allow them. * Inline small functions Functions that just delegate or do trivial operations should be inline. Add `#[inline]` to all functions in `primitives` that fit the criteria. * fuzz: cover count_sigops{_legacy} for Script * fuzz: cover minimal_non_dust for Script * fuzz: move consume_random_bytes to a util file * Fix the release script that checks for TBD `release.sh` is missing `units`. Add `units` to the list of crates to check. Reorder the crates alphabetically. * Implement Rem for Weight `Weight` implements `Div` but not `Rem` Add `Rem` impl for `Weight` * Add a test for remainder A remainder operation has been implemented for `Weight`. Test the functionality of remainder with both a `Weight` and `u64` * bitcoin: Remove hash type re-exports The `{W}PubkeyHash` and `{W}ScriptHash` types are not likely to be used directly by consumers of the library because we have other function that return them and are more ergonomic to use. There is therefor no good reason to re-export them from the crate root. * Make `hex` in `internals` optional The `hex` crate is not always desirable - e.g. when the consumer wants to work with raw data only. We already had this optional in `hashes` but if `hashes` is going to depend on `internals` it would break this property. This change makes `hash` optional, since it's easy: there's just one struct that depends on it. * Bump GitHub Actions Artifacts to v4 v3 is deprecated and causes an automatic fail of fuzz workflow. Bump the version of `actions/upload-artifact` and `actions/download-artifact` to v4. * fuzz: add consume_u64 * fuzz: cover minimal_non_dust_custom for Script * ci: update Kani GitHub Actions runners to ubuntu-24.04 GitHub is deprecating the ubuntu-20.04 runner, with removal scheduled for 2025-04-01 (see: actions/runner-images#11101) This commit updates workflow files to use ubuntu-24.04 instead. * Don't panic in `PrivateKey::from_slice` During upgrade of `secp256k1` a number of function calls needed to be rewritten to not use `from_slice` but `from_byte_array`. Unfortunately, the conversions wasn't correct and caused panics on invalid inputs rather than errors. This fixes it simply by calling `try_into` on the entire slice and converting the error. * Add a test checking `PrivateKey::from_slice` This test checks the previous fix - if ordered before the previous commit it will fail. * Add `from_byte_array` to `PrivateKey`. Private keys have statically-known length of 32 bytes and we are migrating types with known lenths to use `from_byte_array` methods. This adds the method to `PrivateKey` as well and uses it to implement `from_slice`. * Deprecate `PrivateKey::from_slice` method Since arrays better convey the intention than slices when parsing fixed-sized bytes we're migrating to them. This deprecates the `from_slice` method similarly to how we do it elsewhere. * Kill mutants in primitives and units This kills 15 mutants found with the mutants workflow * Fix bug in PSBT `Deserialize` for `XOnlyPublicKey` During upgrade of `secp256k1` a number of function calls needed to be rewritten to not use `from_slice` but `from_byte_array`. Unfortunately, the conversion wasn't correct and caused panics on invalid inputs rather than errors. This fixes it simply by calling `try_into` on the entire slice and converting the error. * Add test checking `XOnlyPublicKey::deserialize` This test checks the previous fix - if ordered before the previous commit it will fail. * Minor: fix typo * ci: Update GitHub workflows to use ubuntu-24.04 instead of ubuntu-latest * primitives: Enable pedantic lints Enable all the pedantic lints and fix warnings. Notable items: - `enum_glob_used` import types with a single character alias - `doc_markdown`: add a whitelist that includes SegWit and OpenSSL * units: Prevent casting pub enums as ints A public enum with simple variants gets an automatic integer variant that can be cast by library consumers. This puts a unnecessary maintenance burden upon us because we cannot then add variants in the middle of others. Add a hidden variant to the single public non-error enum in `units`. * Add hash_again regression test Add a simple regression test prior to patching the `sha256::Hash::hash_again` function. * Add Hash type and finalize method to HashEngine Add an associated const `Hash` to the `HashEngine` trait. Also add a `finalize` method that converts the engine to the associated hash. For now just use the existent `from_engine` stuff. We can refactor later. * Bound HmacEngine on HashEngine We would like to do away with the `GeneralHash` trait. Currently we bound `Hmac` and `HmacEngine` on it but this is unnecessary now that we have added `HashEngine::finalize` and `HashEngine::Hash`. Bound the `HmacEngine` on `HashEngine` (which has an associated `Hash` type returned by `finilalize`). Bound `Hmac` type on `T::Hash` where `T` is `HashEngine`. Includes some minor shortening of local variable names around hmac engine usage. Note this means that `Hmac` no longer implements `GeneralHash`. * hashes: Add hash function to modules Add a standalone `hash` function that is a drop in replacement for `GeneralHash::hash`. Do not add it to `hmac` - this is in parity with the current code because `Hmac` does not implement `GeneralHash::hash`. Use the new function in `bitcoin` removing all occurrences of `GeneralHash` from `bitcoin`. In `hashes` replace usage of `GeneralHash::hash` with the new `hash` function. * hashes: Add hash_byte_chunks function to modules Add a standalone `hash_byte_chunks` function that is a drop in replacement for `GeneralHash::hash_byte_chunks`. Do not add it to `hmac` - this is in parity with the current code because `Hmac` does not implement `GeneralHash::hash_byte_chunks`. * io: Use function in place of GeneralHashExt We would like to remove the `GeneralHash` trait but we want to keep the `hash_reader` functionality. Add a stand alone function (when `hashes` is enabled) `hash_reader`. Remove the extension trait. * Remove unused trait import This import is not needed. Interesting that the linter does not catch it. * hashes: Remove the GeneralHash trait Now that we are able to unambiguously go from a hash engine to its associated hash type there is no longer any need for the `GeneralHash` trait. Please note that IMO this concept of a general hash type as opposed to one where one can hash arbitrary data still exists in the codebase - it is implicitly in the `hash_newtype` macro. Remove the `GeneralHash` trait. * Take spent closure by value in count_witness_sigops and count_p2sh_sigops This fixes issue rust-bitcoin#4141 Change count_witness_sigops and count_p2sh_sigops to take the spent closure by value instead of &mut - Changed both functions to accept S as a value (FnMut) instead of &mut S - Removes need to annotate &mut when calling the function * Replace uses of `chunks_exact` with `as_chunks` In the past we've been using `chunks_exact` because const generics were unstable but then, when they were stabilized we didn't use `as_chunks` (or `array_chunks`) since they were unstable. But the instability was only because Rust devs don't know how to handle `0` being passed in. The function is perfectly implementable on stable. (With a tiny, easy-to-understand `unsafe` block.) `core` doesn't want to make a decision for all other crates yet but we can make it for our own crates because we know that we simply never pass zero. (And even if we did, we could just change the decision.) It also turns out there's a hack to simulate `const {}` block in our MSRV, so we can make compilation fail early. This commit adds an extension trait to internals to provide the methods, so we no longer have to use `chunks_exact`. It also cleans up the code quite nicely. * Add fee_rate::serde re-export When we added the `fee_rate::serde` module we forgot to re-export it. This is needed so downstream can do specify serde attributes on struct fields. ```rust #[serde(with = "bitcoin::fee_rate::serde::as_sat_per_kwu")] rate: FeeRate, ``` * Fix some comments Signed-off-by: NinaLua <iturf@sina.cn> * Move module out of fuzz_target directory The new module `fuzz_utils` in the `fuzz_targets/` directory causes `verify-execution` to fail. Move the module to the `src/` directory. Create a `lib.rs` file. * Re-name Timestamp to BlockTime We just added a `Timestamp` type without knowing that there was a push by OpenTimestamps to also create a timestamp and that our new type may lead to confusion. Our timestamp is explicitly for the `time` field in a block so we can call it `BlockTime`. This name change makes the module name stale but we will change that in a following patch to ease review. * Rename timestamp module to time We just re-named `Timestamp` to `BlockTime`. We have a `units::block` module but it currently holds abstractions (`BlockHeight` and `BlockInterval`) that are not onchain abstractions and therefore somewhat different from the `BlockTime`. Instead of making `block` a block 'utils' module instead re-name the `timestamp` module to `time`. * Automated update to Github CI to rustc nightly-2025-03-06 * Remove warning section Since monadic handling has been introduced, panics have been replaced with return errors. Therefore this section is no longer applicable. * Replace underflow with overflow in doc comments The use of underflow is misleading. Adding one to MAX and subtracting one from MIN are both considered an overflow. * primitives: Feature gate import Feature gate the `Infallible` import. Found with `clippy`. * fix typos * docs: The quotation marks are incorrect. Signed-off-by: RiceChuan <lc582041246@gmail.com> * docs: Update README to replace use of mutagen with cargo-mutants * Remove references to cfg(mutate) from lint allow - no longer allowed Also fix incorrect spelling of honggfuzz * Add validation for private key format and master key constraints This commit adds additional validation checks when decoding extended private keys: 1. Verifies that byte 45 is zero as required by BIP-32 specification 2. For master keys (depth=0), ensures parent fingerprint is zero 3. For master keys (depth=0), ensures child number is zero These checks improve security by rejecting malformed keys that could potentially lead to unexpected behavior. Added corresponding error types and unit tests to verify each validation rule. * psbt: Use Amount::ZERO in unit test We have a const for this, use it. Internal change only. * Use den_ prefix for local Denomination variable Throughout the `amount::tests` module we use `sat` and `ssat` as aliases to amount constructors but in on test we use them as `Denomination` variables. To assist clarity and so we can introduce uniform usage of the constructor aliases change the variable names to use the `den_` prefix. Internal change only, no logic changes. * Use sat/ssat constructors throughout tests There is an as yet unresolved discussion about the unchecked amount constructor. In an effort to focus the amount of changes required later and also to make the `tests` module uniform use the `sat` and `ssat` constructor functions everywhere. Internal change only, no logic changes. * Use _unchecked in amount const types We are about to start enforcing the MAX_MONEY invariant. Doing so will change constructors to return an error type. In preparation use the `_unchecked` constructor for all the consts. Internal change only, no logic changes. * Enforce newtype sanity rules for amount types The unchecked-should-be-unsafe conversation is out of scope for this patch. We want to bite off small chunks so the constructors are left as they currently are - we are just doing the encapsulation here. This is in preparation for enforcing the MAX_MONEY invariant which is not currently enforced. As per the sanity rules policy outline in: rust-bitcoin#4090 For both amount types create a private `encapsulate` module that consists of exactly the type and a single constructor and a single getter. * Pick one - MAX or MAX_MONEY Just use MAX everywhere in this codebase. After discussion in PR consensus was to just use MAX throughout the codebase. ref: rust-bitcoin#4164 (comment) * Fix amount whole bitcoin constructors I royally botched the recent effort to make const amount constructors use a smaller type. I left in an unnecessary panic and forgot to do both of them. Note these function return values will change again very shortly when we start enforcing the MAX_MONEY invariant. However the 64 to 32 bit change is unrelated to that and is easier to review if done separately. Whole bitcoin can not in any sane environment be greater than 21,000,000 which fits in 32 bits so we can take a 32 bit integer in the whole bitcoin constructors without loss of utility. Doing so removes the potential panic. This is a breaking API change. We elect not to deprecate because we want to keep the same function names. * Remove panic in dust value functions Calculating the minimum non-dust fee currently panics if either the script is really big or the dust fee rate is really big. Harden the API by returning an `Option` instead of panicing. * Make mul weight by fee return NumOpResult Now that we have the `NumOpResult<Amount>` type that is used to show a math calculation returned a valid amount we can use it when multiplying weight and fee rates thus removing panics. * Remove deprecated amount methods When we enforce the MAX_MONEY invariant these functions would require the function signature changing - might as well just delete them. * feat: add MAX_BLOCK_SERIALIZED_SIZE existing in core * Update ecdsa-psbt.rs * test: add coverage for ServiceFlags::P2P_V2 * chore: add missing backquotes Signed-off-by: kevincatty <zhanshanmao@outlook.com> * Create test helper function to create a header Move the header creation to the helper function so it can be used in further tests. * Increase test coverage in block.rs Add tests to `primitive::block` module to increase test coverage. * Use impl_op_for_references macro in fee module This commit replaces the individual operator implementations in the fee module with the impl_op_for_references macro to handle reference operations. This removes the need to manually implement reference combinations for operands, simplifying the code and improving consistency. The change: - Replaces direct implementations of operators with macro usage - Adds tests to verify that reference operations work correctly - Maintains the same semantics as the original implementation * Enforce the MAX_MONEY invariant in amount types Enforcing the MAX_MONEY invariant is quite involved because it means multiple things: - Constructing amounts is now fallible - Converting from unsigned to signed is now infallible - Taking the absolute value is now infallible - Integer overflow is illuminated in various places Details: - Update from_sat to check the invariant - Fix all docs including examples - Use the unchecked constructor in test code - Comment any other use of the unchecked constructor - Deprecate unchecked_abs - Fail serde (using the horrible string error variant) - Try not to use the unchecked constructor in rustdocs, no need to encourage unsuspecting users to use it. - Use ? in rustdoc examples (required by Rust API guidlines) - Remove TryFrom<Amount> for SignedAmount because the conversion is now infallible. Add a From impl. - Fix the arbitrary impls - Maintain correct formatting - Remove private check_max function as its no longer needed * Automated update to Github CI to cargo-semver-checks version-0.40.0 * Automated update to Github CI to rustc nightly-2025-03-14 * 2025-03-16 automated rustfmt nightly * chore: spellchecker * Update sighash.rs * Update owned.rs * Enable getting the network kind from an address Users may wish to ask of an address 'what kind of address is this?' We have the `NetworkKind` struct that abstracts over the answer but currently no API to ask the question. The address may have been parsed or constructed and weather the network has been checked already is immaterial. Hence we add the function for both `NetworkChecked` and `NetworkUnchecked` addresses. Fix: rust-bitcoin#4247 * Increase test coverage in absolute.rs Modify existing tests and add new ones to increase test coverage in `locktime/absolute.rs`. * Increase test coverage in relative.rs Increase test coverage in `locktime/relative.rs` * units: Make from_int_btc_const take a 16 bit integer The `from_int_btc_const` constructors are specifically designed for easily creating amount types in const context but currently they return an error which is annoying to handle in const context. If we make the `whole_bitcoin` parameter a 16 bit integer this gives us a nicer const constructor with the downside that it can only create values upto a maximum of - unsigned: 65_536 - signed: 32_767 That is plenty high enough for most use cases. Then use the new `from_int_btc_const` in associated consts. Note that because `from_sat` checks max (and min) values we must define max and min from sats directly. * Add `Buf` suffix to `TaprootMerkleBranch` This type actually contains a `Vec` but we would prefer to have an unsized type. Rename it first so that we can reuse the name later. * Push `merkle_branch` module one level deeper. This moves the content of the module into `buf` submodule making future changes clearer. * Add `as_mut_slice` to `TaprootMerkleBranchBuf` `TaprootMerkleBranchBuf` already had `as_slice` method and `DerefMut` but was missing `as_slice_mut`, so this change adds it. * Introduce unsized `TaprootMerkleBranch` `TaprootMerkleBranchBuf` being a vec introduced intermediate allocation when creating or decoding `Witness`. However the representation on the wire is the same as in-memory (aside from `#[repr(transparent)]`) so this allocation wasn't really needed. This commit introduces `TaprootMerkleBranch` type which is unsized and can be used in place of `TaprootMerkleBranchBuf` within `ControlBlock`. Aside from removing the intermediate allocation, this improves the API a bit: the conversion from array to other type is no longer needed because it's performed by `ControlBlock` in its methods. Thus, consumers who have an array can simply set it as `merkle_branch` field and then encode the `ControlBlock` into witness. A convenience method is also provided to push the `ControlBlock` along with other parts at the end of the `Witness`. * Change `Deref::Target` of `TaprootMerkleBranchBuf` `TaprootMerkleBranchBuf` previously derefed to a slice which lost the information about length being valid. This commit changes the type which, while API-breaking, is not disruptive because the type has API very similar to slice. * Don't use references to `TaprootMerkleBranchBuf` The new unsized type is more flexible and so are the references to it. Just like we pass around `&str` instead of `&String` we should be passing `&TaprootMerkleBranch` instead of `&TaprootMerkleBranchBuf`. * amount: rename `from_int_btc_const` unctions to hungarian ones We have `from_int_btc_const` on both `Amount` and `SignedAmount` because the "real" `from_int_btc` is generic over the integer type it accepts, which means that it cannot be a constfn. But we do want a constfn. However, just because `from_int_btc_const` exists for the sake of constfn doesn't mean that that's what it *is*. So rename these methods to reflect what they *are*. * amount: add from_sat_i32 and from_sat_u32 methods for small constants We have a ton of calls to `from_sat_unchecked` for small constants which were clearly in range, e.g. in fee.rs. Add a new constfn for these cases. Don't bother making a generic Into<u32>/Into<u16> variant because there isn't an obvious name for it. There are 7 instances where we're using this method with values that are out of range, which we leave as from_sat_unchecked for now. * tests: replace Amount::from_sat_unchecked with from_sat.unwrap There are only 7 instances of this so just call .unwrap() on each one. * amount: stop using from_sat_unchecked in tests There is no need for this. It's a 2-line diff to change it. * amount: return i64 from parse_signed_to_satoshi This private function is used for string-parsing an amount. It returns a sign boolean and a u64, but its surrounding logic can be simplified if it just returns a i64 (which is OK now since the range of `Amount` fits into the range of i64). Along the way we eliminate some instances of from_sat_unchecked. Annoyingly we still need the bool to distinguish -0 from +0; when parsing Amount we reject -0 (and we have tests for this). This causes a couple error constructors to no longer be used outside of unit tests. May be worth looking at whether we need them, or whether we should be using them in parse_signed_to_satoshi. * amount: move MIN/MAX constants and constructors inside the privacy boundary It's conceptually a bit tortured to have an `Amount` type defined in a private module, with an _unchecked method allowing you to set values out of range, which needs to be used outside of the module to *define* the range and the constructors that check it. Move the constants and constructors inside the privacy module, where they can be written directly. This is easier to understand and eliminates a couple _unchecked calls. * amount: remove from_sat_unchecked Turns out we don't even need this. It is only used in one place now and we can just stick an .expect there. * Remove a bunch of `try_into().expect()` Previously we've used `try_into().expect()` because const generics were unavailable. Then they became available but we didn't realize we could already convert a bunch of code to not use panicking conversions. But we can (and could for a while). This adds an extension trait for arrays to provide basic non-panicking operations returning arrays, so they can be composed with other functions accepting arrays without any conversions. It also refactors a bunch of code to use the non-panicking constructs but it's certainly not all of it. That could be done later. This just aims at removing the ugliest offenders and demonstrate the usefulness of this approach. Aside from this, to avoid a bunch of duplicated work, this refactors BIP32 key parsing to use a common method where xpub and xpriv are encoded the same. Not doing this already led to a mistake where xpriv implemented some additional checks that were missing in xpub. Thus this change also indirectly fixes that bug. * Add official BIP32 test vectors for invalid keys These are defined in the BIP as invalid. The previous commit fixed a bug where invalid key was parsed as valid and this bug can be caught by these vectors. Therefore, if this commit is ordered before the last one the test will fail. * Use compute_merkle_root Remove manual implementation of merkle root calculation and just use the function we already have. Refactor only, no logic change. * Remove From<hash> for not-general-hash types The `hash_newtype` macro is explicitly designed to produce a hash that is not a general purpose hash type to try and prevent users hashing arbitrary stuff with it. E.g., `Txid` isn't meant to be just hash arbitrary data. However we provide a `From` impl that will convert any instance of the inner hash type into the new type. This kind of defeats the purpose. We provide `from_byte_array` and `to_byte_array` to allow folk to 'cast' from one hash type to another if they really want to and its ugly on purpose. Also, it is becoming apparent that we may be able to remove the `hashes` crate from the public API of `primitives` allowing us to stabalise `primitives` without stabalising `hashes`. For both these reasons remove the `From` impl from the `hash_newtype` macro. Note that deprecating doesn't seem to work so we just delete it. * Remove From<newtype> for $hash We provide the from/to_byte_array functions for casting between arrays. We shouldn't be supporting calls to `into` to quickly do the cast. We already removed the other direction, now remove this one. * Automated update to Github CI to rustc stable-1.85.1 * Add XOnlyPublicKey support for PSBT key retrieval and improve Taproot signing This commit enhances PSBT signing functionality by: 1. Added new KeyRequest::XOnlyPubkey variant to support direct retrieval using XOnly public keys 2. Implemented GetKey for HashMap<XOnlyPublicKey, PrivateKey> for more efficient Taproot key management 3. Modified HashMap<PublicKey, PrivateKey> implementation to handle XOnlyPublicKey requests by checking both even and odd parity variants These changes allow for more flexible key management in Taproot transactions. Specifically, wallet implementations can now store keys indexed by either PublicKey or XOnlyPublicKey and successfully sign PSBTs with Taproot inputs. Added tests for both implementations to verify correct behavior. Added test for odd parity key retrieval. Closes rust-bitcoin#4150 * Rename impl_try_from_array to impl_from_array * Make usage of Self and type uniform across both modules This commit standardizes the function signatures in the Amount and SignedAmount implementations by consistently using Self as the return type instead of the concrete type names. This makes the code more consistent, easier to maintain, and follows Rust's idiomatic practices. Changes: Replace all occurrences of -> Amount with -> Self in unsigned.rs Replace all occurrences of -> SignedAmount with -> Self in signed.rs Make similar replacements for Option/Result return types Use Self:: instead of the explicit type name for static method calls * Automated update to Github CI to rustc nightly-2025-03-21 * docs: fix LICENCE link * Add a bunch of missing conversions for `Witness` `Witness` was missing conversions from arrays (and variations) which was annoying when creating known-sized witnesses. These come up when spending statically-known inputs and in tests. * Impl `PartialEq` between `Witness` and containers Since `Witness` is semantically equivalent to `&[&[u8]]` they should also be comparable. However we only had the impl to compare `Witness` with itself. Being able to compare `Witness` with other containers is particularly needed in tests. * Don't access internalls of `Witness` in tests Accessing the internals of tested object is problematic because it makes changes to layout harder, it makes tests harder to read and it checks implementation details rather than semantics of the API (behvaior). We had such tests in `primitives::witness` so this changes them to use the newly added APIs instead. However, it still leaves `from_parts__unstable` which needs to be dealt with separately. * Simplify `Witness` construction in tests The `Witness`-related tests were constructing `Witness` in over-complicated way by serializing `Vec<Vec<u8>>` and then deserializing `Witness` even though they were not supposed to test serialization but Taproot accessor methods. This was difficult to understand and maintain. This change simplifies them to just construct the `Witness` from array of `Vec<u8>`s using the recently-added constructors. Note that we already have serialization tests written separately so we're not losing meaningful coverage here. --------- Signed-off-by: costcould <fliter@myyahoo.com> Signed-off-by: looklose <shishuaiqun@yeah.net> Signed-off-by: NinaLua <iturf@sina.cn> Signed-off-by: RiceChuan <lc582041246@gmail.com> Signed-off-by: kevincatty <zhanshanmao@outlook.com> Co-authored-by: merge-script <apoelstra@wpsoftware.net> Co-authored-by: Martin Habovstiak <martin.habovstiak@gmail.com> Co-authored-by: Tobin C. Harding <me@tobin.cc> Co-authored-by: Liu-Cheng Xu <xuliuchengxlc@gmail.com> Co-authored-by: leopardracer <136604165+leopardracer@users.noreply.github.com> Co-authored-by: costcould <fliter@myyahoo.com> Co-authored-by: Bruno Garcia <brunoely.gc@gmail.com> Co-authored-by: jrakibi <j.errakibi@gmail.com> Co-authored-by: ndungudedan <dnkibere@gmail.com> Co-authored-by: Erik De Smedt <contact@erikdesmedt.be> Co-authored-by: leonarddt05 <139609434+leonarddt05@users.noreply.github.com> Co-authored-by: looklose <shishuaiqun@yeah.net> Co-authored-by: kilavvy <140459108+kilavvy@users.noreply.github.com> Co-authored-by: Update Nightly Rustc Bot <bot@example.com> Co-authored-by: 19年梦醒 <3949379+getong@users.noreply.github.com> Co-authored-by: Jamil Lambert, PhD <Jamil.Lambert@proton.me> Co-authored-by: Erick Cestari <erickcestari03@gmail.com> Co-authored-by: Shing Him Ng <shinghim@protonmail.com> Co-authored-by: Peter Todd <pete@petertodd.org> Co-authored-by: NinaLua <iturf@sina.cn> Co-authored-by: yancy <github@yancy.lol> Co-authored-by: wgyt <wgythe@gmail.com> Co-authored-by: RiceChuan <lc582041246@gmail.com> Co-authored-by: AM <hones02_tunica@icloud.com> Co-authored-by: ChrisCho-H <c.hyunhum@gmail.com> Co-authored-by: planetBoy <140164174+Guayaba221@users.noreply.github.com> Co-authored-by: kevincatty <zhanshanmao@outlook.com> Co-authored-by: healthyyyoung <healthyoung@proton.me> Co-authored-by: jike <jike2021@proton.me>
…rd_tests` 8284229 refactor: deduplicate anchor witness program bytes (`0x4e,0x73`) (Sebastian Falbesoner) 41f2f05 test: add missing segwitv1 test cases to `script_standard_tests` (Sebastian Falbesoner) Pull request description: Currently we have two segwitv1 output script types that are considered standard: - `TxoutType::WITNESS_V1_TAPROOT` (P2TR): witness program has size 32 (introduced with taproot soft-fork) - `TxoutType::ANCHOR` (P2A): witness program is {0x4e, 0x7e} (introduced with #30352) This PR adds them to the script standardness unit tests where missing, i.e. for using them with the `ExtractDestination` and `GetScriptForDestination` functions. ACKs for top commit: rkrux: ACK 8284229 instagibbs: reACK 8284229 hodlinator: Code Review ACK 8284229 Tree-SHA512: d4a3b47fd31ba33f62d4367811e72a7f442c01b046b0a7217a66be0b9dea5c9041eebfe812c31839ec0f0b14c56948c7c016d3d2de79283583ad8e32c192c6ff
Manually backport PR rust-bitcoin#4111. Of note, here we put `new_p2a` on `ScriptBuf` instead of on the `script::Builder` because that seems to be where all the other `new_foo` methods are in this release. From the original patch: Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
Manually backport PR rust-bitcoin#4111. Of note, here we put `new_p2a` on `ScriptBuf` instead of on the `script::Builder` because that seems to be where all the other `new_foo` methods are in this release. Note the `WitnessProgram::p2a` is conditionally const on Rust `v1.61` because MSRV is only `v1.56.1`. From the original patch: Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
Manually backport PR rust-bitcoin#4111. Of note, here we put `new_p2a` on `ScriptBuf` instead of on the `script::Builder` because that seems to be where all the other `new_foo` methods are in this release. Note the `WitnessProgram::p2a` is conditionally const on Rust `v1.61` because MSRV is only `v1.56.1`. From the original patch: Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352
c2481e4 backport: Add support for pay to anchor outputs (Tobin C. Harding) Pull request description: Manually backport PR #4111. Of note, here we put `new_p2a` on `ScriptBuf` instead of on the `script::Builder` because that seems to be where all the other `new_foo` methods are in this release. From the original patch: Add support for the newly created Pay2Anchor output-type. See bitcoin/bitcoin#30352 ACKs for top commit: apoelstra: ACK c2481e4; successfully ran local tests Tree-SHA512: 016919914750adf6f8226acb4e6b36c0dcd8ce230df8cca13f19bcc97709caf07a076be367c76f9519a421fc93fdf73caa078ee65a85a750af7a9d9e6c757e75
This is a sub-feature taken out of the original proposal for ephemeral anchors #30239
This PR makes spending of
OP_1 <0x4e73>
(i.e.bc1pfeessrawgf
) standard. Creation of this output type is already standard.Any future witness output types are considered relay-standard to create, but not to spend. This preserves upgrade hooks, such as a completely new output type for a softfork such as BIP341. It also gives us a bit of room to use a new output type for policy uses.
This particular sized witness program has no other known use-cases (https://bitcoin.stackexchange.com/a/110664/17078), s it affords insufficient cryptographic security for a secure commitment to data, such as a script or a public key. This makes this type of output "keyless", or unauthenticated.
As a witness program, the
scriptSig
of the input MUST be blank, by BIP141. This helps ensure txid-stability of the spending transaction, which may be required for smart contracting wallets. If we do not use segwit, a miner can simply insert anOP_NOP
in thescriptSig
without effecting the result of program execution.An additional relay restriction is to disallow non-empty witness data, which an adversary may use to penalize the "honest" transactor when RBF'ing the transaction due to the incremental fee requirement of RBF rules.
The intended use-case for this output type is to "anchor" the transaction with a spending child to bring exogenous CPFP fees into the transaction package, encouraging the inclusion of the package in a block. The minimal size of creation and spending of this output makes it an attractive contrast to outputs like
p2sh(OP_TRUE)
andp2wsh(OP_TRUE)
whichare significantly larger in vbyte terms.
Combined with TRUC transactions which limits the size of child transactions significantly, this is an attractive option for presigned transactions that need to be fee-bumped after the fact.