Skip to content

Conversation

@aagbotemi
Copy link
Collaborator

@aagbotemi aagbotemi commented May 6, 2025

This PR implements Anti-Fee-Sniping with randomization as discussed in issue #4

Notes to the reviewers

The implementation adds randomization to anti-fee-sniping behavior:

  1. Uses a 50/50 chance to choose between nLockTime and nSequence (when possible)
  2. Adds a 10% chance to set either value further back in time (by a random value between 0-99)
  3. Detects taproot inputs and their confirmation status

Changelog notice

Changed

  • CreatePsbtError::MissingFullTxForLegacyInput and CreatePsbtError::MissingFullTxForSegwitV0Input now wrap Input in Box (breaking change)

Added

  • PsbtParams::enable_anti_fee_sniping field for BIP326 anti-fee-sniping protection
  • CreatePsbtError::InvalidLockTime and CreatePsbtError::UnsupportedVersion error variants
  • Selection::create_psbt_with_rng method for custom RNG
  • I've signed all my commits
  • I ran cargo fmt and cargo clippy before committing
  • I've added docs for the new feature

Closes #4

@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch 2 times, most recently from 6a39ba9 to 94237e8 Compare May 19, 2025 02:58
@ValuedMammal
Copy link
Collaborator

Thanks @aagbotemi I'm still in the process of reviewing. I agree it would be nice to resolve the clippy error - my other suggestion would be to globally allow the lints in lib.rs for now and open an issue to fix them in a future PR, but in general I agree with your approach to simply Box the large enum variants.

@aagbotemi
Copy link
Collaborator Author

Thanks @aagbotemi I'm still in the process of reviewing.

Thank you @ValuedMammal. Clippy error and large enum variant error in the CI build has been fixed. For subsequent ones(if there is), I'll open another for it.

Copy link
Collaborator

@ValuedMammal ValuedMammal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some review notes

  • For imports, prefer alloc over std. This way we can actually support no-std.
  • I want to see a test of some kind that creates a PSBT with enable_anti_fee_sniping and checks the expected values of the locktime and/or sequence.

@notmandatory notmandatory added the enhancement New feature or request label May 28, 2025
@aagbotemi
Copy link
Collaborator Author

I have some review notes

Noted.
alloc is now preferred over std.
adding test to check enable_anti_fee_sniping

@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch 2 times, most recently from 42fe314 to cfe7b5b Compare May 29, 2025 23:21
@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from cfe7b5b to 9041b2f Compare May 30, 2025 22:33
@ValuedMammal
Copy link
Collaborator

We should also be able to remove the clippy allow attributes in lib.rs.

@aagbotemi
Copy link
Collaborator Author

We should also be able to remove the clippy allow attributes in lib.rs.

Alright, I will remove the clippy allow attributes in lib.rs

@ValuedMammal
Copy link
Collaborator

I'm still in favor of using Box on PlanOrPsbtInput and ScriptSource::Descriptor.

@aagbotemi
Copy link
Collaborator Author

I'm still in favor of using Box on PlanOrPsbtInput and ScriptSource::Descriptor.

Fixed! I've updated the code to use Box.

@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from 5506018 to 9fde5c1 Compare September 9, 2025 03:39
@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from ff19f53 to c4dd696 Compare October 20, 2025 14:30
@ValuedMammal
Copy link
Collaborator

In general I think the git history would be cleaner if we didn't merge with merge commits but instead rebase the commits in this PR.

@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch 2 times, most recently from cfa9826 to 4649e8d Compare October 26, 2025 21:56
@aagbotemi
Copy link
Collaborator Author

aagbotemi commented Oct 26, 2025

In general I think the git history would be cleaner if we didn't merge with merge commits but instead rebase the commits in this PR.

Alright, I've done the cleanup

@ValuedMammal
Copy link
Collaborator

Approach ACK.

@ValuedMammal ValuedMammal requested a review from nymius October 28, 2025 20:09
@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from 74d705d to 65a6eec Compare November 12, 2025 15:58
@ValuedMammal
Copy link
Collaborator

Sorry about the merge conflict.

@aagbotemi
Copy link
Collaborator Author

Sorry about the merge conflict.

Alright. I will rebase to resolve the conflict.

@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from 65a6eec to cd6e919 Compare November 14, 2025 21:27
@ValuedMammal ValuedMammal mentioned this pull request Nov 14, 2025
4 tasks
@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch 3 times, most recently from 3d7c798 to d3a378e Compare November 19, 2025 14:25
@aagbotemi
Copy link
Collaborator Author

aagbotemi commented Nov 19, 2025

Currently running cargo build​ is throwing error

error[E0433]: failed to resolve: could not find `rand` in `key`
   --> src/selection.rs:201:74
    |
201 | ...::bitcoin::key::rand::thread_rng())
    |                    ^^^^ could not find `rand` in `key`
    |
note: found an item that was configured out
   --> /home/abiodun/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitcoin-0.32.7/src/crypto/key.rs:29:20
    |
29  | pub use secp256k1::rand;
    |                    ^^^^
note: the item is gated behind the `rand-std` feature
   --> /home/abiodun/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitcoin-0.32.7/src/crypto/key.rs:28:7
    |
28  | #[cfg(feature = "rand-std")]
    |       ^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0433`.
error: could not compile `bdk_tx` (lib) due to 1 previous error

The solution I could think of is moving bitcoin from dev-dependencies​ to dependencies​. But it's a very big dependency.

EDIT: another solution is to add the rand crate, which is better (I would like to know if it's okay we want to add a new dependency)

@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from d3a378e to d9d165b Compare December 1, 2025 10:10
@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from d9d165b to 9e8c355 Compare December 1, 2025 18:00
@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from 9e8c355 to 88e798d Compare December 1, 2025 22:37
@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from 88e798d to ddf46bf Compare December 2, 2025 14:27
@ValuedMammal
Copy link
Collaborator

Looks good overall, not sure if any review comments are still unresolved.

@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from ddf46bf to ed9df3c Compare December 11, 2025 20:32
@aagbotemi aagbotemi requested a review from nymius January 12, 2026 07:56
Copy link
Collaborator

@ValuedMammal ValuedMammal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ed9df3c

  • You could make a note somewhere that this also includes an API breaking change in CreatePsbtError
  • Following up on the no-std discussion, we should have default features disabled for bdk_coin_select dependency, but I ran into an issue trying to implement it - bitcoindevkit/coin-select#36

Copy link
Contributor

@nymius nymius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ed9df3c

A little bit redundant now, but worth vouching for regardless.

To complement @ValuedMammal, I think is enough to change commit ed9df3c message from feat: enable random anti-fee sniping to feat!: enable random anti-fee sniping and comment about the rationale for the variant additions on the body of the commit message.

@aagbotemi
Copy link
Collaborator Author

make a note somewhere that this also includes an API breaking change in CreatePsbtError

Noted. Thank you.

Following up on the no-std discussion, we should have default features disabled for bdk_coin_select dependency, but I ran into an issue trying to implement it - bitcoindevkit/coin-select#36

no-std support is blocked by bdk_coin_select not having a no-std feature. I will fix it upstream.

change commit ed9df3c message from feat: enable random anti-fee sniping to feat!: enable random anti-fee sniping and comment about the rationale for the variant additions on the body of the commit message.

Thank you for the suggestion. I will fix it

@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch 3 times, most recently from 4190c17 to 58b7134 Compare January 15, 2026 10:08
@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from 58b7134 to 7047874 Compare January 15, 2026 10:11
BREAKING CHANGE:
- `CreatePsbtError::MissingFullTxForLegacyInput` and `CreatePsbtError::MissingFullTxForSegwitV0Input` now wrap `Input` in `Box`

Added new error variants to handle anti-fee-sniping specific failures:
- `InvalidLockTime` returns an error when the transaction locktime is time-based instead of height-based
- `UnsupportedVersion` returns an error when the transaction version is less than 2
@aagbotemi aagbotemi force-pushed the feature/anti-fee-sniping branch from 7047874 to 179860e Compare January 15, 2026 11:30
Copy link
Contributor

@nymius nymius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 179860e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feature request: Sequence based anti-fee-sniping BIP326

5 participants