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

Refactor verification logic #502

Merged
merged 12 commits into from
Feb 22, 2022

Conversation

rajarshimaitra
Copy link
Contributor

@rajarshimaitra rajarshimaitra commented Dec 16, 2021

Description

As discussed in #498 and also in team call,

  • default verification from wallet sync is removed
  • verify_tx refactored as an wallet API
  • in sync verification added for electrum and esplora backends, gated by verify flag.
  • verify flag is removed from TransactionDetails.

Notes to the reviewers

I haven't looked into comapct_filters to see how verification can fit there, but that will probably be required in future.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Wallet API change:

  • I've updated CHANGELOG.md

@rajarshimaitra rajarshimaitra force-pushed the verifcation-refactor branch 4 times, most recently from ff24805 to 426430d Compare December 18, 2021 17:30
@rajarshimaitra
Copy link
Contributor Author

Rebased.

Copy link
Contributor

@LLFourn LLFourn left a comment

Choose a reason for hiding this comment

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

utACK 426430d

Thanks for this @rajarshimaitra.
Looks like sqlite will need some extra care to get rid of the "verified" flag.

@rajarshimaitra rajarshimaitra force-pushed the verifcation-refactor branch 3 times, most recently from 15560d3 to 8f47dfb Compare January 2, 2022 14:14
@rajarshimaitra
Copy link
Contributor Author

Thanks @LLFourn for the look. Sqlite was tricky. But finally all checks seems to be passing.. 🥳

Changes since last review

src/blockchain/esplora/reqwest.rs Show resolved Hide resolved
/// `electrum` and `esplora` support (confed/unconfed) *any* transaction verification,
/// `rpc` supports (confed/unconfed) *in-wallet* transaction verification
/// `compact_filters` supports (unconfed) *any* transaction verification.
pub fn verify_tx(&self, tx: &Transaction) -> Result<(), VerifyError> {
Copy link
Contributor

Choose a reason for hiding this comment

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

After thinking about this further I really think we should remove this API for now.

If a user wants to verify a transaction it's unlikely they want to verify a transaction that's in the database. If it's in the database they can just check if it's in the database. If it is then it's verified (assuming you compiled with verification on).

If it's not in the database then it's really a blockchain specific thing in which case it should be a trait that is implemented on blockchains.

Copy link
Contributor Author

@rajarshimaitra rajarshimaitra Jan 11, 2022

Choose a reason for hiding this comment

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

I think I get what you are saying.

Even if its an inherent Blockchain thing, we don't want to force user with its impl in their custom backends. So one way to do that will be to create a default implementation for any Blockchain. This can then be feature gated and blanket implemented.

And the end result would look like wallet.blockchain.verify(), instead of current wallet.verify(). I am not sure if thats a big enough API win.

My envision of using the verify API is also mostly for non wallet transactions, because its a reasonable assumption that you trust your own DB. And they can enforce it at sync level with --verify feature flag for that purpose.

But there should be an easy way to verify non wallet txs. (Even random message verification at future). So the library needs the API somewhere.

So I think for this PR I will just let it be here. And we can make the move in future PR if we want.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@LLFourn Do you feel satisfied with this reasoning?

Copy link
Contributor

@LLFourn LLFourn Jan 26, 2022

Choose a reason for hiding this comment

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

@rajarshimaitra I'm not sure.

I've thought about this a lot and I think that transaction verification is a very context specific thing and I'm not sure this function fits any of those contexts. Do you have one in mind?

In what situations do you need to verify non-wallet transactions where you don't care about whether the transaction is actually valid but just if the inputs were to exist it passes the consensus rules. Don't you also want to check if the inputs has have been spent or otherwise exist or if the locktime on the tx has passed? Also note this function fails with backends without a transaction index. How are you meant to deal with this failure in the context where it is useful (which again I can't conceive of).

I can understand wanting to check a tx is valid without broadcasting it. Bitcoin core rpc has a call for this. With esplora it would be a matter of checking whether the inputs have been spent and using libconsensus. So I see this as a blockchain specific check which this function doesn't implement properly. It may fail depending on the backend which is odd because the backend it fails on (rpc) is the only one that has a call to do this thing properly (testmempoolaccept).

I don't think it's worth holding up this PR on this but if we are unsure about this function then it makes sense to me to leave it where it is. Why break the API only to break it again later on?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I guess I see what you mean. My initial use case was, if I build a transaction with a custom script P2SH and I create my custom witness to spend it, a easy way to check if the the witness works would be useful. Something like testmempoolaccept of core RPC.

I don't have any strong opinion on where this should be placed, and no solution for the case of non-txindex blockchains.

Currently its not breaking the wallet API. Using the lib with --verify flag will just open this extra function call on wallet, no other existing calls changes.

What do you suggest is the way forward with this PR?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I guess I see what you mean. My initial use case was, if I build a transaction with a custom script P2SH and I create my custom witness to spend it, a easy way to check if the the witness works would be useful. Something like testmempoolaccept of core RPC.

Wouldn't using libconsensus for the P2SH output be preferable in this case? testmempool would only be useful if you want to check the outputs actually exist at the same time and the network time allows for it etc. Another option is to use Interpreter from rust-miniscript.

Currently its not breaking the wallet API. Using the lib with --verify flag will just open this extra function call on wallet, no other existing calls changes.

It's breaking the API because it removes the existing function.

What do you suggest is the way forward with this PR?

I'd suggest the easiest way forward is to remove the changes related to the verify function from this PR and then make an issue or follow up PR where we can discuss whether this API is even a good idea or not. iirc @afilini introduced this function so his input is probably more useful than mine here.

@rajarshimaitra
Copy link
Contributor Author

@LLFourn as suggested moved verification logic to script_sync.

@notmandatory updated with rebase.

The default sync verification is removed from wallet module.
By default sync time verification only makes sense for `electrum` and
`esplora` backend as they are usually untrusted 3rd party services.

script verification for transaction is costly, so removing default
script verification optimizes performance.
Instead of verifying txs at sync time in every backend, its moved to
script_sync to by default be available to any backend.
@rajarshimaitra
Copy link
Contributor Author

@LLFourn updated with suggested changes..

Some weird test failure is happening in ureq compilation.. Not sure why..

@notmandatory
Copy link
Member

@rajarshimaitra I think the CI was failing due to some problem with the recent rust nightly used by those jobs.. I pinned the failing jobs to nightly-2022-01-25 and now they are passing.

The reason the Blockchain test-electrum and two Blockchain test-esplora tests are waiting is because the name changed with the new verify feature added, I can fix this in the github checks config prior to merging.

@rajarshimaitra
Copy link
Contributor Author

Thanks @notmandatory for looking into it.. Yup they seem like something to do with recent rust.

Copy link
Contributor

@LLFourn LLFourn left a comment

Choose a reason for hiding this comment

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

utACK 98a3b32.

LGTM thanks @rajarshimaitra

Copy link
Member

@notmandatory notmandatory left a comment

Choose a reason for hiding this comment

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

Overall looks good but I have a few changelog related comments. Some may be fixed with a rebase.

CHANGELOG.md Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
@rajarshimaitra
Copy link
Contributor Author

Thanks @notmandatory , I missed the changelog modification in last push.. Updated as suggested.

Copy link
Member

@afilini afilini left a comment

Choose a reason for hiding this comment

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

I like the concept and I think the code looks good. My only concern are the database changes that were made, I don't think those are backwards-compatible, especially in sqlite.

For sqlite I would just add another migration that removes the verified column.

For sled I don't think we have to do anything, because serde should ignore the extra fields when deserializing, but if you could check it (even manually, no need to add a test for this) it would be great.

@LLFourn
Copy link
Contributor

LLFourn commented Feb 21, 2022

utACK 02f2302 thanks for fixing that up @notmandatory

@notmandatory
Copy link
Member

notmandatory commented Feb 21, 2022

In 02f2302 I changed the MIGRATIONS to do a proper migration and remove the transaction_details.verified column rather than altering the original CREATE TABLE transaction_details ... statement. Since sqlite doesn't support ALTER TABLE DROP column I had to recreate the transaction_details table which seems to be the recommended way to do it.

I also used my PR version of bdk-cli to manually test sync and list_transaction before and after this PR change. With our without it works for key-value-db or sqlite. I still fixed the MIGRATIONS so it can be an example for the future changes.

@notmandatory
Copy link
Member

notmandatory commented Feb 21, 2022

I think all we need now is a rebase to pickup the pinned tokio version and CHANGELOG (:face_exhaling:) changes in master.

I removed my cherry-picked commits and added a merge commit from master at the end instead.

notmandatory added a commit to notmandatory/bdk that referenced this pull request Feb 22, 2022
86d36e5 Pin tokio version to ~1.14 (Steve Myers)
02f2302 Remove `verify` flag from `TransactionDetails` via new MIGRATIONS (Steve Myers)
662500f Update CHANGELOG (rajarshimaitra)
e6be550 [ci] Change test-readme-examples and Codecov jobs to use `nightly-2022-01-25` rust (Steve Myers)
1d7ea89 Refactor sync time verification (rajarshimaitra)
b05ee78 Remove verifcation flag from compact_filters (rajarshimaitra)
53c30b0 Add verification tests in CI (rajarshimaitra)
6a09075 Remove verify flag from sqlite DB (rajarshimaitra)
61a95d0 Update changelog (rajarshimaitra)
08f312a Remove `verify` flag from `TransactionDetails` (rajarshimaitra)
acbf0ae Add sync verification for `esplora` (rajarshimaitra)
4761155 Add sync verification in `electrum` (rajarshimaitra)
98a3b32 Remove sync verification (rajarshimaitra)

Pull request description:

  <!-- You can erase any parts of this template not applicable to your Pull Request. -->

  ### Description

  As discussed in bitcoindevkit#498 and also in team call,
   - default verification from wallet sync is removed
   - `verify_tx` refactored as an wallet API
   - in `sync` verification added for electrum and esplora backends, gated by `verify` flag.
   - `verify` flag is removed from `TransactionDetails`.

  ### Notes to the reviewers

  I haven't looked into `comapct_filters` to see how verification can fit there, but that will probably be required in future.

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  #### Wallet API change:

  * [x] I've updated `CHANGELOG.md`

Top commit has no ACKs.

Tree-SHA512: 82ac52f77e0fc1a011fc59d1ac70ad24b729e0287adf75fcb78af0f2b38eaeb187b2cabe959b63147ffb16d825711d58b87ad3292cbaa340dc6df2bfdcab5ab3
@notmandatory notmandatory merged commit 19f0287 into bitcoindevkit:master Feb 22, 2022
notmandatory added a commit to notmandatory/bdk that referenced this pull request Mar 9, 2022
0cc4700 Fix typo in CHANGELOG and doc in wallet/mod.rs (Steve Myers)
660faab Fix typo in CHANGELOG (LLFourn)
45767fc Remove max_addresses sync param (LLFourn)
fbb50ad apply doc suggestions from @notmandatory (Lloyd Fournier)
035307e [rpc] Filter out unrelated transactions (LLFourn)
c0e75fc Split get_tx into its own trait (LLFourn)
dcd90f8 Restore but depreciate new_offline (LLFourn)
410a513 Add SyncOptions as the second argument to Wallet::sync (LLFourn)
326bfe8 Remove Blockchain from wallet (LLFourn)

Pull request description:

  While trying to finish bitcoindevkit#490 I thought that it'd be better to try the idea of getting rid of a lot of the async macros and just having tow different traits for sync and async stuff. While trying to do that I felt that this needed to be done first.

  The goal of this change is to decouple the wallet from the blockchain trait. A wallet is something that keeps track of UTXOs and transactions (and can sign things). The only reason it should need to talk to the blockchain is if doing a `sync`. So we remove all superfluous calls to the blockchain and precisely define the requirements for the blockchain to be used to sync with two new traits: `WalletSync` and `GetHeight`.

  1. Stop requesting height when wallet is created
  2. `new_offline` is just `new` now.
  3. a `WalletSync + GetHeight` is now the first argument to `sync`.
  4. `SyncOptions` replaces the existing options to `sync` and allows for less friction when making breaking changes in the fuutre (no more noop_progress!).
  5. We `Box` the `Progress` now to avoid type parameters
  6. broadcast has been removed from `Wallet`. You just use the blockchain directly to broadcast now.

  ### Notes to the reviewers

  This needs bitcoindevkit#502 before it can be merged but can reviewed now.
  Be on the look up for stale documentation from this change.
  Our doc build looks broken because of ureq or something.

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing
  * [x] I've updated `CHANGELOG.md`

Top commit has no ACKs.

Tree-SHA512: a8f3e21e45359be642b1f30d4ac1ba74785439e1b770dbeab0a5a4b8aab1eef4bb6b855aea4382e289257bc890fa713ca832a8b6c9655f7a59e96d412b4da3e6
notmandatory added a commit to bitcoindevkit/bdk-cli that referenced this pull request May 11, 2022
…irectories

00454be Update CHANGELOG with new db features and wallet data directories (Steve Myers)
14106eb Prevent building with more than one database feature enabled (Steve Myers)
fac465e Fix clippy warning (Steve Myers)
d7471f6 Add key-value-db and sqlite-db features, separate wallet directories (Steve Myers)

Pull request description:

  ### Description

  - Add distinct `key-value-db` and `sqlite-db` features, keep default as `key-value-db`

  - Put cached wallet data in separate directories: `~/.bdk-bitcoin/<wallet_name>`
  - Put compact filter data in `<wallet_name>/compact_filters`
  - Depending on the db used put cached wallet data in: `<wallet_name>/wallet.sled/` or `<wallet_name>/wallet.sqlite`

  ### Notes to the reviewers

  This change will help test BDK with different databases, in particular for manually testing DB migrations such as in bitcoindevkit/bdk#502.

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk-cli/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  #### New Features:

  * [ ] I've added tests for the new feature
  * [x] I've added docs for the new feature
  * [x] I've updated `CHANGELOG.md`

Top commit has no ACKs.

Tree-SHA512: a2610448295b39674706ab48f36e4ccb92f7065489bca2b7e0be81a6bbc063844ce7ea3728bd1fffde97938a8ef84234ba5a6cee56aa0deca267bbd671ae692a
notmandatory added a commit to bitcoindevkit/rust-esplora-client that referenced this pull request Aug 2, 2022
1999d97aeb3d97ee24a9b59a2f1453a26943b595 Remove `verify` flag from `TransactionDetails` via new MIGRATIONS (Steve Myers)
0195bc0636d9a58013f0cbc3781d213b0cfc1509 Update CHANGELOG (rajarshimaitra)
4652bb8 Refactor sync time verification (rajarshimaitra)
b05ee78c7335f7e3a1593dc4ff7686e6f72ff5c0 Remove verifcation flag from compact_filters (rajarshimaitra)
53c30b0479c74dde17cd27f8eac7f540e492067d Add verification tests in CI (rajarshimaitra)
6a09075d1a87509e9117eab727132efdf8ea6e1d Remove verify flag from sqlite DB (rajarshimaitra)
61a95d0d15b9944e8b5d13db64ef6ffd9a8d6e29 Update changelog (rajarshimaitra)
08f312a82f889f6bf5dfedfaa565ac2cb59683ae Remove `verify` flag from `TransactionDetails` (rajarshimaitra)
6fa29fa Add sync verification for `esplora` (rajarshimaitra)
4761155707a819c4db437e71a36621a027d5302a Add sync verification in `electrum` (rajarshimaitra)
98a3b3282a0ff59bbdf900adc765f6912d1975c1 Remove sync verification (rajarshimaitra)

Pull request description:

  <!-- You can erase any parts of this template not applicable to your Pull Request. -->

  ### Description

  As discussed in bitcoindevkit/bdk#498 and also in team call,
   - default verification from wallet sync is removed
   - `verify_tx` refactored as an wallet API
   - in `sync` verification added for electrum and esplora backends, gated by `verify` flag.
   - `verify` flag is removed from `TransactionDetails`.

  ### Notes to the reviewers

  I haven't looked into `comapct_filters` to see how verification can fit there, but that will probably be required in future.

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  #### Wallet API change:

  * [x] I've updated `CHANGELOG.md`

Top commit has no ACKs.

Tree-SHA512: 72e307008a137468d96d5c2a6ec804b18fa52363606f3c978208ae5dc22973a7f0aa37488e9bb98dde88409a12d59cc5f00c675d2d408e57e661bf6210bee67b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants