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

zcash_client_sqlite should expose whether a note has been spent, and what block created it #1076

Open
AArnott opened this issue Dec 26, 2023 · 2 comments

Comments

@AArnott
Copy link
Contributor

AArnott commented Dec 26, 2023

Requirement

An app should be able to determine the block height for any note, and should be able to determine whether the note has been spent.

Use case

An account's birthday height needn't be so immutable. When an account is created in a wallet, the birthday height is typically given to the user as (tip - 100). But it may be a long while before the first incoming funds are received, making the birthday height perhaps needlessly far back in time, leading to longer than necessary account recovery times.

To address this, I split birthday height into 3 concepts:

  1. Original birthday height: this is the height the account was created with. This is what a wallet app shows to the user, as it matches what they entered or for a new account, matches what was originally displayed.
  2. (Optimized) birthday height: This is the block height of the first incoming transaction. Or it could be one block less than the first incoming transaction, if the assumption wallets make during account recovery is that the birthday height itself cannot possibly have an incoming transaction in it that's worth looking for. It might also be (tip - 100) if the tip is within 100 blocks of the first incoming transaction to guard against re-orgs. This can be promoted to the user as the suggested birthday height for purposes of future account recovery since it will typically require less scanning than the original birthday height.
  3. Rebirth height: This is the block containing the oldest unspent note. This will often be a much larger block height than the original birthday height and lead to far shorter account recovery times. It will provide access to the full balance of the account, but it will not reproduce the full account's history for the user to see.

Building up these three values requires that I can review all notes, determine their block heights, and determine whether they've been spent. Or an API could be added that simply gives me the above birthday heights, but I suspect exposing these two simple values on ReceivedSaplingNote (and the equivalent Orchard note) would unlock other use cases that I am not thinking about right now.
Of course, just exposing the necessary columns in the v_tx_outputs view would unblock this too, and allow for an efficient SQL query that would extract exactly the data necessary and nothing more.

The above all applies to incoming transparent funds as well as shielded notes.

@AArnott
Copy link
Contributor Author

AArnott commented Dec 26, 2023

I'll workaround this with the following sql (which depends on sql tables not considered to be public API for the crate):

SELECT
	(SELECT birthday_height FROM accounts WHERE account = :account_id) AS "Original birthday height",
	(SELECT MIN(mined_height) FROM v_transactions WHERE account_id = :account_id) AS "Block with first note",
	(SELECT MIN(t.block)
		FROM sapling_received_notes s
		INNER JOIN transactions t ON s.tx = t.id_tx
		WHERE s.account = :account_id AND s.spent IS NULL
	) AS "Block with first unspent note"

At the moment this only considers sapling. It obviously needs to support orchard (which sqlite doesn't yet anyway) and transparent (which the sqlite db seems suspiciously devoid of any data for).

@AArnott
Copy link
Contributor Author

AArnott commented Jan 8, 2024

The get_min_unspent_height function that is already in the crate nearly provides what I need for the rebirth height. The only issue is it doesn't allow for an account filter for the query. It would work only for a wallet-wide rebirth height.

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

No branches or pull requests

1 participant