From 692d226b8f9b659d4c8acc192af57746446ac20e Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Sun, 18 Aug 2024 21:02:31 -0700 Subject: [PATCH 1/9] skip trial decryption for fresh wallets --- packages/query/src/block-processor.ts | 15 +++++++++++---- packages/types/src/block-processor.ts | 2 +- packages/types/src/servers.ts | 2 +- packages/wasm/crate/src/view_server.rs | 14 +++++++++++--- packages/wasm/src/view-server.ts | 6 +++--- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index 0efa41ec25..760707731e 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -100,8 +100,8 @@ export class BlockProcessor implements BlockProcessorInterface { // If sync() is called multiple times concurrently, they'll all wait for // the same promise rather than each starting their own sync process. - public sync = (): Promise => - (this.syncPromise ??= backOff(() => this.syncAndStore(), { + public sync = (isFreshWallet?: boolean, walletCreationBlockHeight?: number): Promise => + (this.syncPromise ??= backOff(() => this.syncAndStore(isFreshWallet, walletCreationBlockHeight), { delayFirstAttempt: false, startingDelay: 5_000, // 5 seconds numOfAttempts: Infinity, @@ -125,7 +125,7 @@ export class BlockProcessor implements BlockProcessorInterface { this.numeraires = numeraires; } - private async syncAndStore() { + private async syncAndStore(isFreshWallet?: boolean, walletCreationBlockHeight?: number) { // start at next block, or genesis if height is undefined let currentHeight = (await this.indexedDb.getFullSyncHeight()) ?? -1n; @@ -169,6 +169,13 @@ export class BlockProcessor implements BlockProcessorInterface { throw new Error(`Unexpected block height: ${compactBlock.height} at ${currentHeight}`); } + // Set the skip_trial_decrypt flag + const skipTrialDecrypt = Boolean( + isFreshWallet && + walletCreationBlockHeight && + currentHeight < BigInt(walletCreationBlockHeight), + ); + if (compactBlock.appParametersUpdated) { await this.indexedDb.saveAppParams(await this.querier.app.appParams()); } @@ -194,7 +201,7 @@ export class BlockProcessor implements BlockProcessorInterface { // - decrypts new notes // - decrypts new swaps // - updates idb with advice - const scannerWantsFlush = await this.viewServer.scanBlock(compactBlock); + const scannerWantsFlush = await this.viewServer.scanBlock(compactBlock, skipTrialDecrypt); // flushing is slow, avoid it until // - wasm says diff --git a/packages/types/src/block-processor.ts b/packages/types/src/block-processor.ts index 3433e747b3..656a84bc04 100644 --- a/packages/types/src/block-processor.ts +++ b/packages/types/src/block-processor.ts @@ -1,7 +1,7 @@ import { AssetId } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb'; export interface BlockProcessorInterface { - sync(): Promise; + sync(isFreshWallet?: boolean, walletCreationBlockHeight?: number): Promise; stop(r?: string): void; setNumeraires(numeraires: AssetId[]): void; } diff --git a/packages/types/src/servers.ts b/packages/types/src/servers.ts index 0d5b299f9d..b90d50a846 100644 --- a/packages/types/src/servers.ts +++ b/packages/types/src/servers.ts @@ -3,7 +3,7 @@ import { CompactBlock } from '@penumbra-zone/protobuf/penumbra/core/component/co import { MerkleRoot } from '@penumbra-zone/protobuf/penumbra/crypto/tct/v1/tct_pb'; export interface ViewServerInterface { - scanBlock(compactBlock: CompactBlock): Promise; + scanBlock(compactBlock: CompactBlock, skipTrialDecrypt: boolean): Promise; flushUpdates(): ScanBlockResult; resetTreeToStored(): Promise; getSctRoot(): MerkleRoot; diff --git a/packages/wasm/crate/src/view_server.rs b/packages/wasm/crate/src/view_server.rs index 09a399d1e2..eb290e0f76 100644 --- a/packages/wasm/crate/src/view_server.rs +++ b/packages/wasm/crate/src/view_server.rs @@ -113,7 +113,11 @@ impl ViewServer { /// Use `flush_updates()` to get the scan results /// Returns: `bool` #[wasm_bindgen] - pub async fn scan_block(&mut self, compact_block: &[u8]) -> WasmResult { + pub async fn scan_block( + &mut self, + compact_block: &[u8], + skip_trial_decrypt: bool, + ) -> WasmResult { utils::set_panic_hook(); let block = CompactBlock::decode(compact_block)?; @@ -125,7 +129,9 @@ impl ViewServer { match state_payload { StatePayload::Note { note: payload, .. } => { - match payload.trial_decrypt(&self.fvk) { + match bool::then_some(!skip_trial_decrypt, payload.trial_decrypt(&self.fvk)) + .flatten() + { Some(note) => { let note_position = self.sct.insert(Keep, payload.note_commitment)?; @@ -161,7 +167,9 @@ impl ViewServer { } } StatePayload::Swap { swap: payload, .. } => { - match payload.trial_decrypt(&self.fvk) { + match bool::then_some(!skip_trial_decrypt, payload.trial_decrypt(&self.fvk)) + .flatten() + { Some(swap) => { let swap_position = self.sct.insert(Keep, payload.commitment)?; let batch_data = diff --git a/packages/wasm/src/view-server.ts b/packages/wasm/src/view-server.ts index a995557ae9..2d68347433 100644 --- a/packages/wasm/src/view-server.ts +++ b/packages/wasm/src/view-server.ts @@ -38,7 +38,7 @@ export class ViewServer implements ViewServerInterface { private readonly epochDuration: bigint, private readonly getStoredTree: () => Promise, private readonly idbConstants: IdbConstants, - ) {} + ) { } static async initialize({ fullViewingKey, @@ -58,9 +58,9 @@ export class ViewServer implements ViewServerInterface { // Decrypts blocks with viewing key for notes, swaps, and updates revealed for user // Makes update to internal state-commitment-tree as a side effect. // Should extract updates via this.flushUpdates(). - async scanBlock(compactBlock: CompactBlock): Promise { + async scanBlock(compactBlock: CompactBlock, skipTrialDecrypt: boolean): Promise { const res = compactBlock.toBinary(); - return this.wasmViewServer.scan_block(res); + return this.wasmViewServer.scan_block(res, skipTrialDecrypt); } // Resets the state of the wasmViewServer to the one set in storage From 1a42946cab558e65716bbb514d47c01ca43fb357 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Tue, 27 Aug 2024 15:30:45 -0700 Subject: [PATCH 2/9] add skip_trial_decrypt --- packages/query/src/block-processor.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index fa16c4c8d4..07367fe04b 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -145,7 +145,7 @@ export class BlockProcessor implements BlockProcessorInterface { * - query remote rpc to begin streaming at the next block * - iterate */ - private async syncAndStore(_isFreshWallet: boolean | undefined, _walletCreationBlockHeight: number | undefined) { + private async syncAndStore(isFreshWallet: boolean | undefined, walletCreationBlockHeight: number | undefined) { // start at next block, or genesis if height is undefined let currentHeight = (await this.indexedDb.getFullSyncHeight()) ?? -1n; @@ -171,7 +171,7 @@ export class BlockProcessor implements BlockProcessorInterface { // begin the chain with local genesis block if provided if (this.genesisBlock?.height === currentHeight + 1n) { currentHeight = this.genesisBlock.height; - await this.processBlock(this.genesisBlock, latestKnownBlockHeight); + await this.processBlock(this.genesisBlock, latestKnownBlockHeight, false); } } @@ -189,7 +189,16 @@ export class BlockProcessor implements BlockProcessorInterface { throw new Error(`Unexpected block height: ${compactBlock.height} at ${currentHeight}`); } - await this.processBlock(compactBlock, latestKnownBlockHeight); + + // Set the skip_trial_decrypt flag + const skipTrialDecrypt = Boolean( + isFreshWallet && + walletCreationBlockHeight && + currentHeight < BigInt(walletCreationBlockHeight), + ); + console.log("skipTrialDecrypt: ", skipTrialDecrypt) + + await this.processBlock(compactBlock, latestKnownBlockHeight, skipTrialDecrypt); // We only query Tendermint for the latest known block height once, when // the block processor starts running. Once we're caught up, though, the @@ -203,7 +212,7 @@ export class BlockProcessor implements BlockProcessorInterface { } // logic for processing a compact block - private async processBlock(compactBlock: CompactBlock, latestKnownBlockHeight: bigint) { + private async processBlock(compactBlock: CompactBlock, latestKnownBlockHeight: bigint, skipTrialDecrypt: boolean) { if (compactBlock.appParametersUpdated) { await this.indexedDb.saveAppParams(await this.querier.app.appParams()); } @@ -230,7 +239,7 @@ export class BlockProcessor implements BlockProcessorInterface { // - decrypts new notes // - decrypts new swaps // - updates idb with advice - const scannerWantsFlush = await this.viewServer.scanBlock(compactBlock, true); + const scannerWantsFlush = await this.viewServer.scanBlock(compactBlock, skipTrialDecrypt); // flushing is slow, avoid it until // - wasm says From 2160cf13e1cc69a92b567bd54aa3ab0e41c9fc45 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Wed, 28 Aug 2024 22:15:52 -0700 Subject: [PATCH 3/9] skip trial decryption until wallet creation height --- packages/query/src/block-processor.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index 07367fe04b..80df47e2a5 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -71,6 +71,7 @@ interface QueryClientProps { numeraires: AssetId[]; stakingAssetId: AssetId; genesisBlock: CompactBlock | undefined; + walletCreationBlockHeight: number; } const BLANK_TX_SOURCE = new CommitmentSource({ @@ -92,6 +93,7 @@ export class BlockProcessor implements BlockProcessorInterface { private readonly stakingAssetId: AssetId; private syncPromise: Promise | undefined; private genesisBlock: CompactBlock | undefined; + private walletCreationBlockHeight: number; constructor({ indexedDb, @@ -100,6 +102,7 @@ export class BlockProcessor implements BlockProcessorInterface { numeraires, stakingAssetId, genesisBlock, + walletCreationBlockHeight }: QueryClientProps) { this.indexedDb = indexedDb; this.viewServer = viewServer; @@ -107,12 +110,13 @@ export class BlockProcessor implements BlockProcessorInterface { this.numeraires = numeraires; this.stakingAssetId = stakingAssetId; this.genesisBlock = genesisBlock; + this.walletCreationBlockHeight = walletCreationBlockHeight; } // If sync() is called multiple times concurrently, they'll all wait for // the same promise rather than each starting their own sync process. - public sync = (isFreshWallet?: boolean, walletCreationBlockHeight?: number): Promise => - (this.syncPromise ??= backOff(() => this.syncAndStore(isFreshWallet, walletCreationBlockHeight), { + public sync = (): Promise => + (this.syncPromise ??= backOff(() => this.syncAndStore(), { delayFirstAttempt: false, startingDelay: 5_000, // 5 seconds numOfAttempts: Infinity, @@ -145,7 +149,7 @@ export class BlockProcessor implements BlockProcessorInterface { * - query remote rpc to begin streaming at the next block * - iterate */ - private async syncAndStore(isFreshWallet: boolean | undefined, walletCreationBlockHeight: number | undefined) { + private async syncAndStore() { // start at next block, or genesis if height is undefined let currentHeight = (await this.indexedDb.getFullSyncHeight()) ?? -1n; @@ -192,9 +196,8 @@ export class BlockProcessor implements BlockProcessorInterface { // Set the skip_trial_decrypt flag const skipTrialDecrypt = Boolean( - isFreshWallet && - walletCreationBlockHeight && - currentHeight < BigInt(walletCreationBlockHeight), + this.walletCreationBlockHeight && + currentHeight < BigInt(this.walletCreationBlockHeight), ); console.log("skipTrialDecrypt: ", skipTrialDecrypt) From 67d6cb03c30a596ed4743bfc63b2bc4f47f417fd Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Wed, 28 Aug 2024 22:35:47 -0700 Subject: [PATCH 4/9] linting --- packages/query/src/block-processor.ts | 14 ++++++++------ packages/wasm/src/view-server.ts | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index 80df47e2a5..7565365a76 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -102,7 +102,7 @@ export class BlockProcessor implements BlockProcessorInterface { numeraires, stakingAssetId, genesisBlock, - walletCreationBlockHeight + walletCreationBlockHeight, }: QueryClientProps) { this.indexedDb = indexedDb; this.viewServer = viewServer; @@ -193,13 +193,11 @@ export class BlockProcessor implements BlockProcessorInterface { throw new Error(`Unexpected block height: ${compactBlock.height} at ${currentHeight}`); } - // Set the skip_trial_decrypt flag const skipTrialDecrypt = Boolean( - this.walletCreationBlockHeight && - currentHeight < BigInt(this.walletCreationBlockHeight), + this.walletCreationBlockHeight && currentHeight < BigInt(this.walletCreationBlockHeight), ); - console.log("skipTrialDecrypt: ", skipTrialDecrypt) + console.log('skipTrialDecrypt: ', skipTrialDecrypt); await this.processBlock(compactBlock, latestKnownBlockHeight, skipTrialDecrypt); @@ -215,7 +213,11 @@ export class BlockProcessor implements BlockProcessorInterface { } // logic for processing a compact block - private async processBlock(compactBlock: CompactBlock, latestKnownBlockHeight: bigint, skipTrialDecrypt: boolean) { + private async processBlock( + compactBlock: CompactBlock, + latestKnownBlockHeight: bigint, + skipTrialDecrypt: boolean, + ) { if (compactBlock.appParametersUpdated) { await this.indexedDb.saveAppParams(await this.querier.app.appParams()); } diff --git a/packages/wasm/src/view-server.ts b/packages/wasm/src/view-server.ts index 2d68347433..31bc131a2d 100644 --- a/packages/wasm/src/view-server.ts +++ b/packages/wasm/src/view-server.ts @@ -38,7 +38,7 @@ export class ViewServer implements ViewServerInterface { private readonly epochDuration: bigint, private readonly getStoredTree: () => Promise, private readonly idbConstants: IdbConstants, - ) { } + ) {} static async initialize({ fullViewingKey, From 29c5b743f1b6c84c44fb0ba08eab4bba5aa16231 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Wed, 28 Aug 2024 22:37:00 -0700 Subject: [PATCH 5/9] remove log --- packages/query/src/block-processor.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index 7565365a76..5d5c82ae3c 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -197,7 +197,6 @@ export class BlockProcessor implements BlockProcessorInterface { const skipTrialDecrypt = Boolean( this.walletCreationBlockHeight && currentHeight < BigInt(this.walletCreationBlockHeight), ); - console.log('skipTrialDecrypt: ', skipTrialDecrypt); await this.processBlock(compactBlock, latestKnownBlockHeight, skipTrialDecrypt); From b81c8d9d283aff2f9008593aff34eddb04ccc48e Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Fri, 30 Aug 2024 23:47:33 -0700 Subject: [PATCH 6/9] gabe's suggestions --- packages/query/src/block-processor.ts | 43 ++++++++++---- .../src/helpers/skip-trial-decrypt.test.ts | 56 +++++++++++++++++++ packages/types/src/block-processor.ts | 2 +- packages/wasm/crate/src/view_server.rs | 14 +++-- 4 files changed, 96 insertions(+), 19 deletions(-) create mode 100644 packages/query/src/helpers/skip-trial-decrypt.test.ts diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index 5d5c82ae3c..1c5d6547ac 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -71,7 +71,13 @@ interface QueryClientProps { numeraires: AssetId[]; stakingAssetId: AssetId; genesisBlock: CompactBlock | undefined; - walletCreationBlockHeight: number; + walletCreationBlockHeight: bigint; +} + +interface ProcessBlockParams { + compactBlock: CompactBlock; + latestKnownBlockHeight: bigint; + skipTrialDecrypt?: boolean; } const BLANK_TX_SOURCE = new CommitmentSource({ @@ -92,8 +98,8 @@ export class BlockProcessor implements BlockProcessorInterface { private numeraires: AssetId[]; private readonly stakingAssetId: AssetId; private syncPromise: Promise | undefined; - private genesisBlock: CompactBlock | undefined; - private walletCreationBlockHeight: number; + private readonly genesisBlock: CompactBlock | undefined; + private readonly walletCreationBlockHeight: bigint; constructor({ indexedDb, @@ -175,7 +181,17 @@ export class BlockProcessor implements BlockProcessorInterface { // begin the chain with local genesis block if provided if (this.genesisBlock?.height === currentHeight + 1n) { currentHeight = this.genesisBlock.height; - await this.processBlock(this.genesisBlock, latestKnownBlockHeight, false); + + // Set the trial decryption flag for the genesis compact block + const skipTrialDecrypt = Boolean( + this.walletCreationBlockHeight && currentHeight < BigInt(this.walletCreationBlockHeight), + ); + + await this.processBlock({ + compactBlock: this.genesisBlock, + latestKnownBlockHeight: latestKnownBlockHeight, + skipTrialDecrypt: skipTrialDecrypt, + }); } } @@ -193,12 +209,16 @@ export class BlockProcessor implements BlockProcessorInterface { throw new Error(`Unexpected block height: ${compactBlock.height} at ${currentHeight}`); } - // Set the skip_trial_decrypt flag + // Set the trial decryption flag for all other compact blocks const skipTrialDecrypt = Boolean( this.walletCreationBlockHeight && currentHeight < BigInt(this.walletCreationBlockHeight), ); - await this.processBlock(compactBlock, latestKnownBlockHeight, skipTrialDecrypt); + await this.processBlock({ + compactBlock: compactBlock, + latestKnownBlockHeight: latestKnownBlockHeight, + skipTrialDecrypt: skipTrialDecrypt, + }); // We only query Tendermint for the latest known block height once, when // the block processor starts running. Once we're caught up, though, the @@ -212,11 +232,11 @@ export class BlockProcessor implements BlockProcessorInterface { } // logic for processing a compact block - private async processBlock( - compactBlock: CompactBlock, - latestKnownBlockHeight: bigint, - skipTrialDecrypt: boolean, - ) { + private async processBlock({ + compactBlock, + latestKnownBlockHeight, + skipTrialDecrypt = false, + }: ProcessBlockParams) { if (compactBlock.appParametersUpdated) { await this.indexedDb.saveAppParams(await this.querier.app.appParams()); } @@ -238,7 +258,6 @@ export class BlockProcessor implements BlockProcessorInterface { } } - // TODO: add logic for determining when to skip trial decryption // wasm view server scan // - decrypts new notes // - decrypts new swaps diff --git a/packages/query/src/helpers/skip-trial-decrypt.test.ts b/packages/query/src/helpers/skip-trial-decrypt.test.ts new file mode 100644 index 0000000000..5a2ba84288 --- /dev/null +++ b/packages/query/src/helpers/skip-trial-decrypt.test.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from 'vitest'; + +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ + +describe('skipTrialDecrypt()', () => { + it('should not skip trial decryption for genesis block when wallet creation block height is zero', () => { + const currentHeight = 0n; + const walletCreationBlockHeight = 0n; + + const skipTrialDecrypt = Boolean( + walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), + ); + + expect(skipTrialDecrypt).toBe(false); + }); + it('should skip trial decryption for genesis block when wallet creation block height is not zero', () => { + const currentHeight = 0n; + const walletCreationBlockHeight = 100n; + + const skipTrialDecrypt = Boolean( + walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), + ); + + expect(skipTrialDecrypt).toBe(true); + }); + it('should skip trial decryption for other blocks when wallet creation block height is not zero', () => { + const currentHeight = 1n; + const walletCreationBlockHeight = 100n; + + const skipTrialDecrypt = Boolean( + walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), + ); + + expect(skipTrialDecrypt).toBe(true); + }); + it('should not skip trial decryption when wallet creation block height equals current height', () => { + const currentHeight = 100n; + const walletCreationBlockHeight = 100n; + + const skipTrialDecrypt = Boolean( + walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), + ); + + expect(skipTrialDecrypt).toBe(false); + }); + it('should not skip trial decryption when wallet creation block height is greater than current height', () => { + const currentHeight = 200n; + const walletCreationBlockHeight = 100n; + + const skipTrialDecrypt = Boolean( + walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), + ); + + expect(skipTrialDecrypt).toBe(false); + }); +}); diff --git a/packages/types/src/block-processor.ts b/packages/types/src/block-processor.ts index 656a84bc04..3433e747b3 100644 --- a/packages/types/src/block-processor.ts +++ b/packages/types/src/block-processor.ts @@ -1,7 +1,7 @@ import { AssetId } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb'; export interface BlockProcessorInterface { - sync(isFreshWallet?: boolean, walletCreationBlockHeight?: number): Promise; + sync(): Promise; stop(r?: string): void; setNumeraires(numeraires: AssetId[]): void; } diff --git a/packages/wasm/crate/src/view_server.rs b/packages/wasm/crate/src/view_server.rs index eb290e0f76..90ffefaada 100644 --- a/packages/wasm/crate/src/view_server.rs +++ b/packages/wasm/crate/src/view_server.rs @@ -129,9 +129,10 @@ impl ViewServer { match state_payload { StatePayload::Note { note: payload, .. } => { - match bool::then_some(!skip_trial_decrypt, payload.trial_decrypt(&self.fvk)) - .flatten() - { + let note_opt = (!skip_trial_decrypt) + .then(|| payload.trial_decrypt(&self.fvk)) + .flatten(); + match note_opt { Some(note) => { let note_position = self.sct.insert(Keep, payload.note_commitment)?; @@ -167,9 +168,10 @@ impl ViewServer { } } StatePayload::Swap { swap: payload, .. } => { - match bool::then_some(!skip_trial_decrypt, payload.trial_decrypt(&self.fvk)) - .flatten() - { + let note_opt = (!skip_trial_decrypt) + .then(|| payload.trial_decrypt(&self.fvk)) + .flatten(); + match note_opt { Some(swap) => { let swap_position = self.sct.insert(Keep, payload.commitment)?; let batch_data = From 9540487bdfc1bb766d6d53c8873957044c0b497a Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Sat, 31 Aug 2024 21:47:05 -0700 Subject: [PATCH 7/9] change block height field to number --- packages/query/src/block-processor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index 1c5d6547ac..63cb7254db 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -71,7 +71,7 @@ interface QueryClientProps { numeraires: AssetId[]; stakingAssetId: AssetId; genesisBlock: CompactBlock | undefined; - walletCreationBlockHeight: bigint; + walletCreationBlockHeight: number; } interface ProcessBlockParams { @@ -99,7 +99,7 @@ export class BlockProcessor implements BlockProcessorInterface { private readonly stakingAssetId: AssetId; private syncPromise: Promise | undefined; private readonly genesisBlock: CompactBlock | undefined; - private readonly walletCreationBlockHeight: bigint; + private readonly walletCreationBlockHeight: number; constructor({ indexedDb, From 652c4bf1a7dad8dcbea4870cdc38f19445742b59 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Mon, 2 Sep 2024 00:26:12 -0700 Subject: [PATCH 8/9] changeset --- .changeset/rude-camels-attack.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/rude-camels-attack.md diff --git a/.changeset/rude-camels-attack.md b/.changeset/rude-camels-attack.md new file mode 100644 index 0000000000..672d4e28a3 --- /dev/null +++ b/.changeset/rude-camels-attack.md @@ -0,0 +1,7 @@ +--- +'@penumbra-zone/query': major +'@penumbra-zone/types': major +'@penumbra-zone/wasm': minor +--- + +fresh and existing wallets skip trial decryption From 288b0b3b0e1cd8828afca6a4889b499310dba67d Mon Sep 17 00:00:00 2001 From: Gabe Rodriguez Date: Tue, 3 Sep 2024 14:36:26 +0200 Subject: [PATCH 9/9] [pairing] review comments --- .changeset/rude-camels-attack.md | 2 +- packages/query/src/block-processor.ts | 19 +++++---- .../src/helpers/skip-trial-decrypt.test.ts | 41 +++++++++---------- .../query/src/helpers/skip-trial-decrypt.ts | 11 +++++ 4 files changed, 42 insertions(+), 31 deletions(-) create mode 100644 packages/query/src/helpers/skip-trial-decrypt.ts diff --git a/.changeset/rude-camels-attack.md b/.changeset/rude-camels-attack.md index 672d4e28a3..cfc9542828 100644 --- a/.changeset/rude-camels-attack.md +++ b/.changeset/rude-camels-attack.md @@ -1,7 +1,7 @@ --- '@penumbra-zone/query': major '@penumbra-zone/types': major -'@penumbra-zone/wasm': minor +'@penumbra-zone/wasm': major --- fresh and existing wallets skip trial decryption diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index 63cb7254db..b3d089e0d0 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -46,6 +46,7 @@ import { getAssetIdFromGasPrices } from '@penumbra-zone/getters/compact-block'; import { getSpendableNoteRecordCommitment } from '@penumbra-zone/getters/spendable-note-record'; import { getSwapRecordCommitment } from '@penumbra-zone/getters/swap-record'; import { CompactBlock } from '@penumbra-zone/protobuf/penumbra/core/component/compact_block/v1/compact_block_pb'; +import { shouldSkipTrialDecrypt } from './helpers/skip-trial-decrypt.js'; declare global { // eslint-disable-next-line no-var @@ -71,7 +72,7 @@ interface QueryClientProps { numeraires: AssetId[]; stakingAssetId: AssetId; genesisBlock: CompactBlock | undefined; - walletCreationBlockHeight: number; + walletCreationBlockHeight: number | undefined; } interface ProcessBlockParams { @@ -99,7 +100,7 @@ export class BlockProcessor implements BlockProcessorInterface { private readonly stakingAssetId: AssetId; private syncPromise: Promise | undefined; private readonly genesisBlock: CompactBlock | undefined; - private readonly walletCreationBlockHeight: number; + private readonly walletCreationBlockHeight: number | undefined; constructor({ indexedDb, @@ -183,14 +184,15 @@ export class BlockProcessor implements BlockProcessorInterface { currentHeight = this.genesisBlock.height; // Set the trial decryption flag for the genesis compact block - const skipTrialDecrypt = Boolean( - this.walletCreationBlockHeight && currentHeight < BigInt(this.walletCreationBlockHeight), + const skipTrialDecrypt = shouldSkipTrialDecrypt( + this.walletCreationBlockHeight, + currentHeight, ); await this.processBlock({ compactBlock: this.genesisBlock, latestKnownBlockHeight: latestKnownBlockHeight, - skipTrialDecrypt: skipTrialDecrypt, + skipTrialDecrypt, }); } } @@ -210,14 +212,15 @@ export class BlockProcessor implements BlockProcessorInterface { } // Set the trial decryption flag for all other compact blocks - const skipTrialDecrypt = Boolean( - this.walletCreationBlockHeight && currentHeight < BigInt(this.walletCreationBlockHeight), + const skipTrialDecrypt = shouldSkipTrialDecrypt( + this.walletCreationBlockHeight, + currentHeight, ); await this.processBlock({ compactBlock: compactBlock, latestKnownBlockHeight: latestKnownBlockHeight, - skipTrialDecrypt: skipTrialDecrypt, + skipTrialDecrypt, }); // We only query Tendermint for the latest known block height once, when diff --git a/packages/query/src/helpers/skip-trial-decrypt.test.ts b/packages/query/src/helpers/skip-trial-decrypt.test.ts index 5a2ba84288..d9d7c15f21 100644 --- a/packages/query/src/helpers/skip-trial-decrypt.test.ts +++ b/packages/query/src/helpers/skip-trial-decrypt.test.ts @@ -1,55 +1,52 @@ import { describe, expect, it } from 'vitest'; - -/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +import { shouldSkipTrialDecrypt } from './skip-trial-decrypt.js'; describe('skipTrialDecrypt()', () => { + it('should not skip trial decryption if walletCreationBlockHeight is undefined', () => { + const currentHeight = 0n; + const walletCreationBlockHeight = undefined; + + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); + + expect(skipTrialDecrypt).toBe(false); + }); it('should not skip trial decryption for genesis block when wallet creation block height is zero', () => { const currentHeight = 0n; - const walletCreationBlockHeight = 0n; + const walletCreationBlockHeight = 0; - const skipTrialDecrypt = Boolean( - walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), - ); + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); expect(skipTrialDecrypt).toBe(false); }); it('should skip trial decryption for genesis block when wallet creation block height is not zero', () => { const currentHeight = 0n; - const walletCreationBlockHeight = 100n; + const walletCreationBlockHeight = 100; - const skipTrialDecrypt = Boolean( - walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), - ); + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); expect(skipTrialDecrypt).toBe(true); }); it('should skip trial decryption for other blocks when wallet creation block height is not zero', () => { const currentHeight = 1n; - const walletCreationBlockHeight = 100n; + const walletCreationBlockHeight = 100; - const skipTrialDecrypt = Boolean( - walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), - ); + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); expect(skipTrialDecrypt).toBe(true); }); it('should not skip trial decryption when wallet creation block height equals current height', () => { const currentHeight = 100n; - const walletCreationBlockHeight = 100n; + const walletCreationBlockHeight = 100; - const skipTrialDecrypt = Boolean( - walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), - ); + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); expect(skipTrialDecrypt).toBe(false); }); it('should not skip trial decryption when wallet creation block height is greater than current height', () => { const currentHeight = 200n; - const walletCreationBlockHeight = 100n; + const walletCreationBlockHeight = 100; - const skipTrialDecrypt = Boolean( - walletCreationBlockHeight && currentHeight < BigInt(walletCreationBlockHeight), - ); + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); expect(skipTrialDecrypt).toBe(false); }); diff --git a/packages/query/src/helpers/skip-trial-decrypt.ts b/packages/query/src/helpers/skip-trial-decrypt.ts new file mode 100644 index 0000000000..895f3c2b72 --- /dev/null +++ b/packages/query/src/helpers/skip-trial-decrypt.ts @@ -0,0 +1,11 @@ +// Used to determine whether trial decryption should be skipped for this block +export const shouldSkipTrialDecrypt = ( + creationHeight: number | undefined, + currentHeight: bigint, +) => { + if (creationHeight === undefined || creationHeight === 0) { + return false; + } + + return currentHeight < BigInt(creationHeight); +};