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

Fast construction of Transaction when reading from the chain db #5078

Merged

Conversation

andiflabs
Copy link
Contributor

Summary

Transactions that contains mints involve parsing assets, which in turn involve parsing public addresses of the owner for those assets. Parsing a public address is currently an expensive operation, because it involves elliptic curve point multiplications.

Transactions containing mints are therefore harmful for the performance of wallet scans.

To improve the performance of wallet scans, this commit:

  • introduces a new PublicAddress::new_unchecked (in Rust) constructor that speeds up construction of public addresses from trusted input;
  • adds a skipValidation parameter to Transaction (in TypeScript) to allow using the "unchecked" variants of constructors;
  • changes the chain db deserializer to read transactions using skipValidation: true.

Note that, while the goal of this commit is to improve wallet scan performance, the impact of this commit is actually broader: it impacts all reads from the chain db. This is good for performance, but may be a concern for security and stability. The assumption is that if something is stored in the chain db, then it was previously validated and therefore it can be trusted.

Testing Plan

Documentation

N/A

Breaking Change

N/A

@andiflabs andiflabs requested a review from a team as a code owner June 26, 2024 02:45
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-notes-during-scan branch from e9cd83a to 6107b89 Compare June 26, 2024 16:53
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-transactions-from-chain-db branch from cda90fb to 6a9d58f Compare June 26, 2024 16:54
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-notes-during-scan branch from 6107b89 to 9ada9d8 Compare June 26, 2024 17:21
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-transactions-from-chain-db branch from 6a9d58f to c5bf574 Compare June 26, 2024 17:21
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-notes-during-scan branch from 9ada9d8 to f22f92c Compare June 28, 2024 00:33
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-transactions-from-chain-db branch from c5bf574 to 94f12e5 Compare June 28, 2024 00:34
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-notes-during-scan branch from f22f92c to bf4472f Compare June 28, 2024 20:43
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-transactions-from-chain-db branch from 94f12e5 to 10cd266 Compare June 28, 2024 20:44
Base automatically changed from andrea/fast-construction-of-notes-during-scan to staging June 28, 2024 21:04
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-transactions-from-chain-db branch 2 times, most recently from d8dffe5 to 3e9976f Compare July 8, 2024 20:26
@andiflabs andiflabs changed the base branch from staging to andrea/rm-types-jest July 8, 2024 20:26
@andiflabs andiflabs force-pushed the andrea/rm-types-jest branch from 8a381ed to 6679059 Compare July 9, 2024 16:35
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-transactions-from-chain-db branch from 3e9976f to 1839dab Compare July 9, 2024 16:35
@andiflabs andiflabs force-pushed the andrea/rm-types-jest branch from 6679059 to 8d1f93e Compare July 10, 2024 23:55
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-transactions-from-chain-db branch from 1839dab to 5bc24e7 Compare July 10, 2024 23:57
Copy link
Contributor

@hughy hughy 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 good to me 👍

I wonder if it's possible, or desirable, to enforce that we only skip validation when deserializing from stored values.

I think it may be hard to have a general rule like that for skipping validation, but I do wonder about how we can ensure that validation always happens somewhere.

* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { Transaction } from '../../primitives/transaction'

function areTransactionsEqual(a: unknown, b: unknown): boolean | undefined {
Copy link
Contributor

Choose a reason for hiding this comment

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

is this used as part of these changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, implicitly, whenever you call expect(...).toEqual on something that has a transaction in it

@andiflabs
Copy link
Contributor Author

This looks good to me 👍

I wonder if it's possible, or desirable, to enforce that we only skip validation when deserializing from stored values.

I think it may be hard to have a general rule like that for skipping validation, but I do wonder about how we can ensure that validation always happens somewhere.

Yes, I think it's both possible and desiderable. This could even be done using types, so that mistakes would be caught at build time.

@andiflabs andiflabs force-pushed the andrea/rm-types-jest branch from 8d1f93e to 8c16d8d Compare July 11, 2024 16:49
Transactions that contains mints involve parsing assets, which in turn
involve parsing public addresses of the owner for those assets. Parsing
a public address is currently an expensive operation, because it
involves elliptic curve point multiplications.

Transactions containing mints are therefore harmful for the performance
of wallet scans.

To improve the performance of wallet scans, this commit:
- introduces a new `PublicAddress::new_unchecked` (in Rust) constructor
  that speeds up construction of public addresses from trusted input;
- adds a `skipValidation` parameter to `Transaction` (in TypeScript) to
  allow using the "unchecked" variants of constructors;
- changes the chain db deserializer to read transactions using
  `skipValidation: true`.

Note that, while the goal of this commit is to improve wallet scan
performance, the impact of this commit is actually broader: it impacts
all reads from the chain db. This is good for performance, but may be a
concern for security and stability. The assumption is that if something
is stored in the chain db, then it was previously validated and
therefore it can be trusted.
@andiflabs andiflabs force-pushed the andrea/fast-construction-of-transactions-from-chain-db branch from 5bc24e7 to bcbaa5f Compare July 11, 2024 16:50
Base automatically changed from andrea/rm-types-jest to staging July 11, 2024 22:17
@andiflabs andiflabs merged commit 02e4cae into staging Jul 11, 2024
13 of 14 checks passed
@andiflabs andiflabs deleted the andrea/fast-construction-of-transactions-from-chain-db branch July 11, 2024 22:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants