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

Nice-to-have data for the scanner to identify (or pass back to a consumer) in order of preference #48

Open
j-berman opened this issue Apr 29, 2024 · 6 comments

Comments

@j-berman
Copy link

j-berman commented Apr 29, 2024

I think the majority of these are useful for wallet users.

If all implemented, we would be able to easily maintain compatibility between the Seraphis lib and wallet2 (can import a Seraphis lib-based wallet into a complete and consistent wallet2-based wallet).

1) RCT / non-RCT status of enote

2) Tx fee

  • Answers "how much did I spend in fees" without re-consulting the chain

3) key_offsets of txs which include a received enote in their ring

  • Useful to track how often an enote is used in other rings.

3a) Legacy unscanned txs which include a received enote as a ring member

  • Useful for background syncing without the spend key (no need to re-query the daemon for key images to identify 0-change spends)

4) Coinbase boolean

  • Helpful for miners
  • Technically can be determined for RCT enotes if 1 is implemented (legacy RCT enotes with transparent amounts), not for pre-RCT

5) unlock_time on spend origin context

  • Useful when the user sends to another user with 0 change, and wants to know when the tx will unlock without re-consulting the chain (for historical record keeping purposes)

6) key_offsets for spent enotes

  • Useful to display the ring in the wallet UI

7) a tx's index in a block

  • Useful to have a clear-cut correct answer to is_older_than for pre-RCT enotes in the same block (Legacy Indexing Overhaul #42 (comment))
  • Useful to create a consistently ordered wallet2 m_transfers container from a Seraphis enote store

8) the legacy cryptonote::transcaction

  • wallet2-based wallets use the tx in a few ways beyond scanning:
  • I see 2 options here:
    1. refactor where the tx is used where necessary (includes requiring downstream consumers who currently lean on the wallet2 callbacks to refactor)
    2. the Seraphis lib scanner can pass the tx along per identified enote, which can also be used to knock out 1, 2, 4, 5, and 6 from above
    • I think refactoring where the tx is used is fine and more in line with the design goals of the Seraphis lib, but our lives would probably be easier if we passed the tx along per-identified enote.
@UkoeHB
Copy link
Owner

UkoeHB commented Apr 29, 2024

  1. unlock_time on spend origin context

This is already stored on the legacy enote records, are you suggesting to move it?

  1. a tx's index in a block

I'd be fine adding this to the origin context.

the Seraphis lib scanner can pass the tx along per identified enote, which can also be used to knock out 1, 2, 4, 5, and 6 from above

What do you think about temporarily caching the txs on scan, and then consumers of enote store events can query the cache for missing data (with a fallback to daemon requests)? The enote store is explicitly an EnoteStore, i.e. not a WalletData, because it is very focused on doing one thing (tracking enotes). I am very fearful that adding complexity to the enote store will overload it beyond the point of robustness/maintainability.

@j-berman
Copy link
Author

This is already stored on the legacy enote records, are you suggesting to move it?

Unless I'm missing something, I only see it stored on the received enote. If a user spends an enote, the only metadata they have for that spend is the spend context, which doesn't include the unlock time. Reiterating this would only be useful to know when a spent enote will unlock in a tx in which the user receives 0 enotes.

What do you think about temporarily caching the txs on scan

This is also what I had in mind for option ii -- I think it would be fine and save a lot of headache.

That would just leave number 3, which I think can be tackled at the same time as tackling porting background sync over

@UkoeHB
Copy link
Owner

UkoeHB commented Apr 29, 2024

Reiterating this would only be useful to know when a spent enote will unlock in a tx in which the user receives 0 enotes.

Oh I see, for reconstructing transaction histories when you sent a locked no-change tx. Then yes, this would need to be on the spent context.

That would just leave number 3, which I think can be tackled at the same time as tackling porting background sync over

If txs are cached on scan, then the cache can be post-scanned for key offsets. The main problem is properly tracking reorgs without reimplementing the scan machine. Maybe reorgs can be inferred from enote store block events.

@j-berman
Copy link
Author

j-berman commented Apr 29, 2024

If txs are cached on scan, then the cache can be post-scanned for key offsets.

I was thinking only caching txs that the scanner would need to return to the consumer -- otherwise memory would fill up on long scans.

Number 3 would require some additional logic to identify txs which include prior received enotes in the key_offsets to know which txs to cache while scanning.

Maybe reorgs can be inferred from enote store block events.

Was thinking this as well. The consumer would need to rely on events generally to keep its history in sync with the enote store.

@UkoeHB
Copy link
Owner

UkoeHB commented Apr 29, 2024

I was thinking only caching txs that the scanner would need to return to the consumer -- otherwise memory would fill up on long scans.

If events are consumed in another thread, and txs are cached by sending them via channel to another thread, then you can clean up the cache continuously.

I never got that far, but the idea was for the prod scanner to send enote store events in a channel along with a read-lock-handle to the enote store (a readable<EnoteStore>).

@j-berman
Copy link
Author

If events are consumed in another thread, and txs are cached by sending them via channel to another thread, then you can clean up the cache continuously.

That sounds like a solid approach to me. Just need to make sure to consume the txs after processing each tx's respective events to know which txs the wallet cares about, without needing to scan the txs.

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

2 participants