Skip to content
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

feat: get last bitcoin fees from sweep tables (#809) #810

Open
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

cylewitruk
Copy link
Member

@cylewitruk cylewitruk commented Nov 10, 2024

Description

Closes: #809

Changes

Removes the BitcoinInteract::get_last_fees() method (described in #541) and replaces it with logic to retrieve the Fees from the latest sweep transaction package (described in #809).

Testing Information

RBF tests updated to use the sweep_transactions method.

Checklist:

  • I have performed a self-review of my code
  • My changes generate no new warnings
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

@cylewitruk cylewitruk added the sbtc signer binary The sBTC Bootstrap Signer. label Nov 10, 2024
@cylewitruk cylewitruk added this to the sBTC: Deposit ready milestone Nov 10, 2024
@cylewitruk cylewitruk self-assigned this Nov 10, 2024
@cylewitruk cylewitruk linked an issue Nov 10, 2024 that may be closed by this pull request
1 task
Copy link
Contributor

@djordon djordon left a comment

Choose a reason for hiding this comment

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

This looks okay, but I don't think the query does what we want (or we need to change our usage).

signer/migrations/0003__create_tables.sql Outdated Show resolved Hide resolved
signer/src/message.rs Outdated Show resolved Hide resolved
signer/src/message.rs Outdated Show resolved Hide resolved
signer/tests/integration/rbf.rs Outdated Show resolved Hide resolved
signer/migrations/0003__create_tables.sql Show resolved Hide resolved
signer/src/storage/postgres.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@djordon djordon left a comment

Choose a reason for hiding this comment

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

I think there is only one issue with the last_fee part in the coordinator. Looks good otherwise.

signer/src/storage/mod.rs Outdated Show resolved Hide resolved
signer/src/transaction_coordinator.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@djordon djordon left a comment

Choose a reason for hiding this comment

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

Looks good ✅ 🚢. We should check if the integration tests in the transaction_coordinator run in CI.

signer/src/transaction_coordinator.rs Outdated Show resolved Hide resolved
/// This test asserts that the `get_btc_state` function returns the correct
/// `SignerBtcState` when there are no sweep transactions available, i.e.
/// the `last_fees` field should be `None`.
#[cfg_attr(not(feature = "integration-tests"), ignore)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this test run in CI? I would think that it doesn't, but I'm not sure. If not, then I think there are others that we need to move. And I've made this mistaken in some tests as well 😞.

Copy link
Member Author

Choose a reason for hiding this comment

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

@djordon hmm, I'm not sure of the best approach. Here we're testing get_btc_state() which is private, so it needs to be here, but otoh it also needs postgres, so it needs to be run as an integration-test. Should I just make it public and move the test, or do you have a better suggestion?

Copy link
Member Author

Choose a reason for hiding this comment

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

Moved the tests in 2b22025 and verified they run in CI

@djordon
Copy link
Contributor

djordon commented Nov 12, 2024

I decided to go and check myself and I didn't find those tests in the CI output logs. Also, we should have CI explicitly output which tests were ignored.

signer/src/network/in_memory2.rs Outdated Show resolved Hide resolved
signer/src/storage/in_memory.rs Outdated Show resolved Hide resolved
signer/src/storage/model.rs Outdated Show resolved Hide resolved
signer/src/storage/model.rs Outdated Show resolved Hide resolved
signer/src/storage/postgres.rs Show resolved Hide resolved
signer/src/storage/postgres.rs Outdated Show resolved Hide resolved
@djordon
Copy link
Contributor

djordon commented Nov 12, 2024

@djordon hmm, I'm not sure of the best approach. Here we're testing get_btc_state() which is private, so it needs to be here, but otoh it also needs postgres, so it needs to be run as an integration-test. Should I just make it public and move the test, or do you have a better suggestion?

Yeah I'd make it public.

Comment on lines +97 to +101
let total: u64 = self
.iter()
.map(|tx| tx.fee)
.try_fold(0u64, |acc, fee| acc.checked_add(fee))
.ok_or(Error::ArithmeticOverflow)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm, these fees cannot add up to anything more than u64::MAX, even if we added up all bitcoins (measured in sats).

Copy link
Member Author

@cylewitruk cylewitruk Nov 13, 2024

Choose a reason for hiding this comment

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

Nope, but the code otherwise is technically not panic-safe, which is what we've been striving for.

Same argument could be made for the vsize-- we should realistically never have transactions larger than a handful of vKb, and it would take a crazy number (u32::MAX+1) of transactions holding u32::MAX, but the code can still panic.

Comment on lines +105 to +107
if total_size == 0 {
return Err(Error::DivideByZero);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This can only happen if the vector is empty, so we could just return zero.

Copy link
Member Author

@cylewitruk cylewitruk Nov 13, 2024

Choose a reason for hiding this comment

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

I don't think zero is what we want -- compute_transaction_fee() matches on an Option<> and None would not be the same as Fees::ZERO.

But I changed the signature and added a check and return Ok(None) if it's empty as I could describe that mode in the trait description and it matches its use (basis for calculation is missing). We did this check manually before in the coordinator, so it's essentially just moved here.

The DivideByZero remains because you could still have a bug elsewhere i.e. when pulling these out of the database which defaults vsize to zero (i.e. the code still has a panic-able path otherwise).

Copy link
Collaborator

@matteojug matteojug left a comment

Choose a reason for hiding this comment

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

LGTM, but I think you should revert the changes in generated code (make lint should do the trick).

signer/src/storage/postgres.rs Show resolved Hide resolved
@cylewitruk
Copy link
Member Author

@matteojug yeah, crap, those generated files snuck in on me. make lint did indeed seem to resolve it 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sbtc signer binary The sBTC Bootstrap Signer.
Projects
Status: In Review
3 participants