Skip to content

Commit

Permalink
Await the synchronizer for user actions
Browse files Browse the repository at this point in the history
Some users are so fast they can request an address or attempt to send syncNetwork has finished initializing the synchronizer. We can await synchronizer creation instead of throwing an error.
  • Loading branch information
peachbits committed Oct 4, 2024
1 parent 6aa135c commit 2b5c579
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- changed: (Zcash/Piratechain) Await synchronizer initialization instead of throwing error in public methods
- fixed: (Zcash/Piratechain) Don't save sensitive initializer object to engine

## 4.26.0 (2024-10-03)
Expand Down
20 changes: 15 additions & 5 deletions src/piratechain/PiratechainEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ export class PiratechainEngine extends CurrencyEngine<
started: boolean
stopSyncing?: (value: number | PromiseLike<number>) => void
synchronizer?: PiratechainSynchronizer
synchronizerPromise: Promise<PiratechainSynchronizer>
synchronizerResolver!: (synchronizer: PiratechainSynchronizer) => void
lastUpdateFromSynchronizer?: number

constructor(
Expand All @@ -69,6 +71,9 @@ export class PiratechainEngine extends CurrencyEngine<
this.networkInfo = networkInfo
this.birthdayHeight = 0
this.makeSynchronizer = makeSynchronizer
this.synchronizerPromise = new Promise<PiratechainSynchronizer>(resolve => {
this.synchronizerResolver = resolve
})
this.queryMutex = false

this.started = false
Expand Down Expand Up @@ -295,12 +300,14 @@ export class PiratechainEngine extends CurrencyEngine<
this.birthdayHeight = piratechainPrivateKeys.birthdayHeight

try {
this.synchronizer = await this.makeSynchronizer({
this.synchronizerPromise = this.makeSynchronizer({
mnemonicSeed: piratechainPrivateKeys.mnemonic,
birthdayHeight: piratechainPrivateKeys.birthdayHeight,
alias: base16.stringify(base64.parse(this.walletId)),
...rpcNode
})
this.synchronizer = await this.synchronizerPromise
this.synchronizerResolver(this.synchronizer)
} catch (e) {
// The synchronizer cannot start if it isn't present.
if (
Expand All @@ -319,6 +326,9 @@ export class PiratechainEngine extends CurrencyEngine<
}

async killEngine(): Promise<void> {
this.synchronizerPromise = new Promise<PiratechainSynchronizer>(resolve => {
this.synchronizerResolver = resolve
})
this.started = false
if (this.stopSyncing != null) {
await this.stopSyncing(1000)
Expand Down Expand Up @@ -417,7 +427,6 @@ export class PiratechainEngine extends CurrencyEngine<
edgeTransaction: EdgeTransaction,
opts?: EdgeEnginePrivateKeyOptions
): Promise<EdgeTransaction> {
if (this.synchronizer == null) throw new Error('Synchronizer undefined')
const { memos } = edgeTransaction
const piratechainPrivateKeys = asPiratechainPrivateKeys(this.pluginId)(
opts?.privateKeys
Expand All @@ -441,7 +450,8 @@ export class PiratechainEngine extends CurrencyEngine<
}

try {
const signedTx = await this.synchronizer.sendToAddress(txParams)
const synchronizer = await this.synchronizerPromise
const signedTx = await synchronizer.sendToAddress(txParams)
edgeTransaction.txid = signedTx.txId
edgeTransaction.signedTx = signedTx.raw
edgeTransaction.date = Date.now() / 1000
Expand All @@ -455,8 +465,8 @@ export class PiratechainEngine extends CurrencyEngine<

async getFreshAddress(): Promise<EdgeFreshAddress> {
const getSynchronizerAddresses = async (): Promise<EdgeFreshAddress> => {
if (this.synchronizer == null) throw new Error('Synchronizer undefined')
const { saplingAddress } = await this.synchronizer.deriveUnifiedAddress()
const synchronizer = await this.synchronizerPromise
const { saplingAddress } = await synchronizer.deriveUnifiedAddress()
this.otherData.cachedAddress = saplingAddress
this.walletLocalDataDirty = true
return {
Expand Down
28 changes: 19 additions & 9 deletions src/zcash/ZcashEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export class ZcashEngine extends CurrencyEngine<
// Synchronizer management
stopSyncing?: (value: number | PromiseLike<number>) => void
synchronizer?: ZcashSynchronizer
synchronizerPromise: Promise<ZcashSynchronizer>
synchronizerResolver!: (synchronizer: ZcashSynchronizer) => void
autoshielding: {
createAutoshieldTx: boolean
threshold: string
Expand All @@ -75,6 +77,9 @@ export class ZcashEngine extends CurrencyEngine<
this.pluginId = this.currencyInfo.pluginId
this.networkInfo = networkInfo
this.makeSynchronizer = makeSynchronizer
this.synchronizerPromise = new Promise<ZcashSynchronizer>(resolve => {
this.synchronizerResolver = resolve
})
this.balances = {
transparentAvailableZatoshi: '0',
transparentTotalZatoshi: '0',
Expand Down Expand Up @@ -340,13 +345,15 @@ export class ZcashEngine extends CurrencyEngine<
if (this.synchronizer == null) {
const { rpcNode } = this.networkInfo

this.synchronizer = await this.makeSynchronizer({
this.synchronizerPromise = this.makeSynchronizer({
mnemonicSeed: zcashPrivateKeys.mnemonic,
birthdayHeight: zcashPrivateKeys.birthdayHeight,
alias: base16.stringify(base64.parse(this.walletId)),
newWallet: !this.otherData.isSdkInitializedOnDisk,
...rpcNode
})
this.synchronizer = await this.synchronizerPromise
this.synchronizerResolver(this.synchronizer)
this.initData()
this.initSubscriptions()
}
Expand Down Expand Up @@ -390,6 +397,9 @@ export class ZcashEngine extends CurrencyEngine<
}

async killEngine(): Promise<void> {
this.synchronizerPromise = new Promise<ZcashSynchronizer>(resolve => {
this.synchronizerResolver = resolve
})
await super.killEngine()
await this.restartSyncNetwork()
await this.synchronizer?.stop()
Expand Down Expand Up @@ -426,10 +436,10 @@ export class ZcashEngine extends CurrencyEngine<
if (publicAddress == null) {
throw new Error('makeSpend Missing publicAddress')
}
if (this.synchronizer == null) throw new Error('Synchronizer undefined')
const synchronizer = await this.synchronizerPromise
try {
// We anticipate this to fail and return an error message we cna parse the spendable amount from
await this.synchronizer.proposeTransfer({
await synchronizer.proposeTransfer({
toAddress: publicAddress,
zatoshi: this.availableZatoshi,
memo: memos[0]?.value ?? ''
Expand Down Expand Up @@ -457,8 +467,8 @@ export class ZcashEngine extends CurrencyEngine<
throw new InsufficientFundsError({ tokenId })
}

if (this.synchronizer == null) throw new Error('Synchronizer undefined')
const proposal = await this.synchronizer.proposeTransfer({
const synchronizer = await this.synchronizerPromise
const proposal = await synchronizer.proposeTransfer({
toAddress: publicAddress,
zatoshi: nativeAmount,
memo: memos[0]?.value ?? ''
Expand Down Expand Up @@ -517,7 +527,6 @@ export class ZcashEngine extends CurrencyEngine<
edgeTransaction: EdgeTransaction,
opts?: EdgeEnginePrivateKeyOptions
): Promise<EdgeTransaction> {
if (this.synchronizer == null) throw new Error('Synchronizer undefined')
const { proposalBase64 } = getOtherParams(edgeTransaction)
if (proposalBase64 == null) {
throw new Error('Missing proposalBase64 from makeSpend')
Expand All @@ -532,7 +541,8 @@ export class ZcashEngine extends CurrencyEngine<
}

try {
const txid = await this.synchronizer.createTransfer(txParams)
const synchronizer = await this.synchronizerPromise
const txid = await synchronizer.createTransfer(txParams)
edgeTransaction.txid = txid
edgeTransaction.date = Date.now() / 1000
this.warn(`SUCCESS broadcastTx\n${cleanTxLogs(edgeTransaction)}`)
Expand All @@ -545,8 +555,8 @@ export class ZcashEngine extends CurrencyEngine<

async getFreshAddress(): Promise<EdgeFreshAddress> {
const getSynchronizerAddresses = async (): Promise<EdgeFreshAddress> => {
if (this.synchronizer == null) throw new Error('Synchronizer undefined')
const { unifiedAddress } = await this.synchronizer.deriveUnifiedAddress()
const synchronizer = await this.synchronizerPromise
const { unifiedAddress } = await synchronizer.deriveUnifiedAddress()
this.otherData.cachedAddress = unifiedAddress
this.walletLocalDataDirty = true

Expand Down

0 comments on commit 2b5c579

Please sign in to comment.