bitcoindevkit / bitcoindevkit/bdk-tx

Make output-metadata redaction opt-in and split into two composable functions

Open
#77 1 comment 0 reactions 0 assignees View on GitHub
api
Dominant language
Rust
Stars
13
Forks
17
Avg merge
17h 22m
Merged PRs (30d)
1

Description

`Finalizer::finalize` currently strips `bip32_derivation`, `tap_key_origins`, and `tap_internal_key` from every output when the PSBT is fully finalized (`finalizer.rs:139-146`). Two issues:

1. **Not spec-compliant by default.** BIP-174's finalizer role is defined over inputs only; output `PSBT_OUT_*` fields are normally retained until extraction. Bitcoin Core never touches outputs on finalize. Doing it silently diverges from both, and destroys metadata a downstream consumer may legitimately need (verifying change ownership, re-deriving addresses, registering change on a watch-only).

2. **Incomplete for policy privacy.** The current set removes wallet-linkage (key origins) but leaves `redeem_script` / `witness_script` / `tap_tree`, which expose an output's spending policy (multisig structure, full taproot tree). `tap_internal_key` sits between the two categories — it's a raw key, not a `KeySource` — so the split below assigns it to the key-origin function deliberately rather than leaving it ambiguous.

## Proposal

- Make `finalize` pure BIP-174 (inputs only; outputs untouched). Redaction becomes explicit opt-in.
- Add two standalone, composable functions (no `Finalizer`/plan dependency):
- `redact_output_key_origins` → clears `bip32_derivation`, `tap_key_origins`, `tap_internal_key` *(unlink output from wallet/xpub)*
- `redact_output_scripts` → clears `redeem_script`, `witness_script`, `tap_tree` *(hide spending policy)*
- Leave `proprietary` / `unknown` untouched (opaque, often load-bearing; mirrors input handling at `finalizer.rs:107-109`).

## Reasoning

- Two threat models, two field sets — callers pick what they need; calling both gives the full strip.
- Separate functions over a `finalize` parameter: redaction doesn't depend on the finalizer's plans, so coupling it to `finalize` is artificial. Distinct names make each function's leak-surface obvious.
- Opt-in default keeps us spec-compliant and Core-aligned; privacy is an explicit, deliberate step.

## Acceptance criteria

- [ ] `finalize` no longer modifies outputs.
- [ ] `redact_output_key_origins` and `redact_output_scripts` added.
- [ ] Doc comment at `finalizer.rs:20-22` updated; the "cleared after finalize" test (`finalizer.rs:300-304`) moved to exercise the new functions; preserve-by-default tests retained.

Contributor guide

Open the contributing guide

Research direction

Start by reading finalizer.rs:139-146 and the doc comment at :20-22, then inspect the test at :300-304 and the existing output-field handling. Done means finalize leaves outputs unchanged, the two opt-in redaction functions cover their specified fields, and preserve-by-default behavior remains tested.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
blockchain
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
66/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.