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

Store the last sync time and block height #459

Merged
merged 6 commits into from
Nov 10, 2021

Conversation

afilini
Copy link
Member

@afilini afilini commented Oct 26, 2021

Description

Update the Database trait to allow storing the block height and timestamp of the last sync of a Wallet. This will allow having a rough estimation of the "current" height, even in parts of the code that don't have network access (tx creation, computing the balance, etc), at least in non-airgapped wallets that are periodically synced.

After this is ready I'm planning to work on a PR to close #413, essentially making BDK aware of what can be spent and what is still not "mature" (initially only for coinbase UTXOs which are trivial, later on ideally also for any UTXO that has a timelock, which is a lot trickier).

Closes #455.

Notes to the reviewers

Opening this in draft mode, since it includes some commits from #454.

Random open points:

  1. I was thinking about renaming ConfirmationTime because that name doesn't really make sense in this context, but I couldn't come up with a decent alternative. I'm open to suggestions if you have any.
  2. I'm not sure what I've done with the sqlite database is ideal, let me know if you think I could use a better structure. Initially I used to add an entry in the table for every sync, and then I would only return the latest one. That seemed pretty inefficient, considering that I was storing stuff that were by definition never read, so I changed it to the current structure.. but this feels more NoSQL-like so I still don't know which one I like best.

Checklists

All Submissions:

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

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

Bugfixes:

  • This pull request breaks the existing API
  • I'm linking the issue being fixed by this PR

@afilini afilini changed the title Feat/store sync time Store the last sync time and block height Oct 26, 2021
@notmandatory
Copy link
Member

notmandatory commented Oct 27, 2021

My rename suggestion for ConfirmationTime is simply Confirmationand then the field would be TransactionDetails.confirmation.

@notmandatory
Copy link
Member

It looks like this PR has come commits that are already in master, can it be rebased to simplify the history?
Don't need:
a348dbd
548e43d
548e43d
548e43d

@LLFourn
Copy link
Contributor

LLFourn commented Oct 28, 2021

Can we think about getting rid of the block height request in Wallet::new after this and just using the one from the database.

@afilini afilini force-pushed the feat/store-sync-time branch from b47ef60 to ca41644 Compare October 28, 2021 12:31
@afilini
Copy link
Member Author

afilini commented Oct 28, 2021

Can we think about getting rid of the block height request in Wallet::new after this and just using the one from the database.

Yup, that would be great. With that you would only need the network to sync, everything else would work offline as well, which is reasonable

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.

LGTM -- one thing I'd like you to consider changing.

@@ -82,6 +82,13 @@ macro_rules! impl_batch_operations {
Ok(())
}

fn set_last_sync_time(&mut self, ct: ConfirmationTime) -> Result<(), Error> {
Copy link
Contributor

Choose a reason for hiding this comment

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

So I'm working towards adding different types of syncs. e.g. only sync addresses given out (no stop-gap). Maybe only sync addresses given out recently or only sync external keychain etc.

Could we leave the door open to that by making a SyncTime struct which has the blocktime (whose type is unfortunately called ConfirmationTime) as a field? It wouldn't hurt to add the local time to it. It's possible we'd want more metadata about a sync in the future and it'd make it easier from a DB updating point of view to serialize it in this way.

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried implementing this but I got stuck because we don't have a way to get the tip hash with the current Blockchain trait.

Since I would have to make a breaking change to the trait I'm thinking I might as well split it up like you described during our last call.

I'm not sure if we should hold this PR until that's ready or just go ahead and merge it without block_hash and add that later on.

Copy link
Contributor

@LLFourn LLFourn Nov 4, 2021

Choose a reason for hiding this comment

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

I think merge without that now and follow up with a PR that adds Option<BlockHash> to the struct. I still think that we don't want to add this to BlockTime but rather a struct like SyncTime that contains a BlockTime. Also SyncTime should probably contain the UTC time that the sync was finished (in this PR).

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah in my local branch I had a separate structure that contained the BlockTime and the block hash.

I will add just the UTC time for now, we'll add the block hash in a following PR

Copy link
Contributor

Choose a reason for hiding this comment

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

You might consider adding a field for it in the sqlite table otherwise we have to do a table update and I'm not sure we have a db upgrade plan yet :S?

@artfuldev
Copy link
Contributor

Regarding ConfirmationTime, I think we can just use something like BlockInfo which has a few details from:
image

Currently, we use the height and timestamp as an indication of confirmation and last sync "time". Maybe we add hash next. And we can refer to it in a confirmed transaction as block: BlockInfo / while syncing as last_synced: BlockInfo.

@afilini afilini force-pushed the feat/store-sync-time branch 3 times, most recently from 8486b60 to 8dfe72f Compare November 8, 2021 09:38
@notmandatory
Copy link
Member

Looks like it needs a rebase to fix the CHANGELOG then is ready to go.

@afilini
Copy link
Member Author

afilini commented Nov 10, 2021

Done!

@afilini afilini force-pushed the feat/store-sync-time branch from 8dfe72f to 5830226 Compare November 10, 2021 11:30
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.

ACK 5830226

@notmandatory notmandatory merged commit 5830226 into bitcoindevkit:master Nov 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Save the latest block height in the database BDK will select coinbase inputs that are not matured yet
4 participants