-
Notifications
You must be signed in to change notification settings - Fork 10
feat: enable random anti-fee sniping #5
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
base: master
Are you sure you want to change the base?
feat: enable random anti-fee sniping #5
Conversation
6a39ba9 to
94237e8
Compare
|
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 |
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. |
ValuedMammal
left a comment
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.
I have some review notes
- For imports, prefer
allocoverstd. 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_snipingand checks the expected values of the locktime and/or sequence.
Noted. |
42fe314 to
cfe7b5b
Compare
cfe7b5b to
9041b2f
Compare
|
We should also be able to remove the clippy allow attributes in |
Alright, I will remove the clippy allow attributes in |
|
I'm still in favor of using |
Fixed! I've updated the code to use |
5506018 to
9fde5c1
Compare
ff19f53 to
c4dd696
Compare
|
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. |
cfa9826 to
4649e8d
Compare
Alright, I've done the cleanup |
|
Approach ACK. |
| Ok(()) | ||
| } | ||
|
|
||
| /// Returns true with probability 1/n. |
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.
I would add a comment explaining why we are using these functions and not rand::random_bool.
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.
The anti fee sniping implementation started from here. So, I have been using rand_core for the implementation since then. I can change to rand if we agree to use that.
cc: @ValuedMammal, we have access to using Rng trait using rand
src/utils.rs
Outdated
| } | ||
|
|
||
| /// Returns a random value in the range [0, end). | ||
| fn random_range(rng: &mut OsRng, end: u32) -> u32 { |
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.
Same here for rand::random_range. Also, I would mention here we are using unbiased methods to pick from the range.
782c3e3 to
0923128
Compare
src/utils.rs
Outdated
| // if random_probability(TEN_PERCENT_PROBABILITY_RANGE) { | ||
| // let random_offset = random_range(MAX_RANDOM_OFFSET); |
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.
nit: remove these comments.
src/utils.rs
Outdated
| || must_use_locktime | ||
| || taproot_inputs.is_empty() | ||
| || random_bool(FIFTY_PERCENT_PROBABILITY_RANGE); | ||
| // || random_probability(FIFTY_PERCENT_PROBABILITY_RANGE); |
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.
nit: remove this comment
| // - RBF is disabled, OR | ||
| // - Any input requires locktime (non-taproot, unconfirmed, or >65535 confirmations), OR | ||
| // - There are no taproot inputs, OR | ||
| // - Random 50/50 coin flip chose locktime |
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.
To make the example more dynamic I would set up all the conditions to make the example dependent of this 50/50 coin flip. Because I'm never hitting the sequence anti fee sniping branch below.
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.
Okay. I have fixed it.
examples/anti_fee_sniping.rs
Outdated
| if height_val >= min_expected && height_val <= max_expected { | ||
| println!("✓ Locktime is within expected range"); | ||
| } else { | ||
| println!("⚠ Locktime is outside expected range"); |
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.
Is this line reachable? I guess you want to show the feature is working, but if anti fee sniping works as intended, this is not going to ever happen. This isn't a test. Maybe showing the nLockTime or nSequence in a meaningful way is a better approach for the example.
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.
Thank you for the review. I have fixed it.
0923128 to
ccc615c
Compare
examples/anti_fee_sniping.rs
Outdated
|
|
||
| println!("nLockTime approach used: {} times", locktime_count); | ||
| println!("nSequence approach used: {} times", sequence_count); | ||
| println!("Both approaches provide anti-fee-sniping protection:"); |
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.
nit: this isn't providing new information, I recommend to remove it
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.
@aagbotemi sorry for the confusion here, but I was just referring to line 149 here, 147 and 148 were good
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.
Alright.
15d95a2 to
74d705d
Compare
|
|
||
| [dependencies] | ||
| miniscript = { version = "12", default-features = false } | ||
| bdk_coin_select = "0.4.0" |
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.
@ValuedMammal what do you think about rand as additional dependency? I don't want to fall in the slippery slope of adding new dependencies with each feature, but I wouldn't implement anti-fee sniping without rand, so, is anti-fee sniping something bdk-tx should ship by default? Should we consider adding it as a feature dependency?
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.
Ideally we want to support no-std, so my question is how are we providing a source of randomness for no-std environments.
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.
The approach we took for bdk_wallet is to depend on rand_core in order to have RngCore trait and essentially split the interface based on whether std feature is enabled. If std, then we have access to rand via bitcoin::secp256k1::rand. If no-std then the user can pass in something that implements RngCore.
/// Create PSBT.
#[cfg(feature = "std")]
pub fn create_psbt(&self, params: PsbtParams) -> Result<bitcoin::Psbt, CreatePsbtError> {
self.create_psbt_with_rng(params, &mut rand::thread_rng())
}
/// Create PSBT with `rng`.
pub fn create_psbt_with_rng(&self, params: PsbtParams, rng: &mut impl RngCore) -> Result<bitcoin::Psbt, CreatePsbtError> { ... }The other option is to feature-gate the enable_anti_fee_sniping option entirely but that seems a bit less useful.
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.
@aagbotemi could you adapt your code here and the current state of the PR to the above solution? Using feature gates
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.
Alright, will do that.
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.
I think you are missing the std implementation using rand full features.
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.
Looks good overall, not sure if any review comments are still unresolved.
@ValuedMammal I'm not sure we have fulfilled this requirement yet. Do you think we should roll a custom random range even if the user has std available?
74d705d to
65a6eec
Compare
|
Sorry about the merge conflict. |
Alright. I will rebase to resolve the conflict. |
65a6eec to
cd6e919
Compare
3d7c798 to
d3a378e
Compare
|
Currently running 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 errorThe solution I could think of is moving bitcoin from EDIT: another solution is to add the |
d3a378e to
d9d165b
Compare
d9d165b to
9e8c355
Compare
9e8c355 to
88e798d
Compare
88e798d to
ddf46bf
Compare
|
Looks good overall, not sure if any review comments are still unresolved. |
ddf46bf to
ed9df3c
Compare
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:
cargo fmtandcargo clippybefore committingCloses #4