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

fix: When address is not enough, stop update localSavedBlockNumber #3052

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/neuron-wallet/src/block-sync-renderer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const resetSyncTask = async (startTask = true) => {

if (startTask) {
await WalletService.getInstance().maintainAddressesIfNecessary()
await TransactionPersistor.checkTxLock()
await CommonUtils.retry(3, 5000, TransactionPersistor.checkTxLock)
await CommonUtils.sleep(3000)
await createBlockSyncTask()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ export default class LightSynchronizer extends Synchronizer {
}

private async updateBlockStartNumber(blockNumber: number) {
if (this._needGenerateAddress || !this.pollingIndexer) {
logger.info('LightConnector:\twait for generating address')
return
}
const scripts = await this.lightRpc.getScripts()
await SyncProgressService.updateBlockNumber(
scripts.map(v => v.script.args),
Expand Down
4 changes: 4 additions & 0 deletions packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import LightSynchronizer from './light-synchronizer'
import { generateRPC } from '../../utils/ckb-rpc'
import { BUNDLED_LIGHT_CKB_URL } from '../../utils/const'
import { NetworkType } from '../../models/network'
import WalletService from '../../services/wallets'

export default class Queue {
#lockHashes: string[]
Expand Down Expand Up @@ -254,6 +255,9 @@ export default class Queue {
.map(addr => addr.walletId)
)
if (process.send) {
this.#indexerConnector!.needGenerateAddress = await WalletService.getInstance().checkNeedGenerateAddress([
...walletIds,
])
process.send({ channel: 'check-and-save-wallet-address', message: [...walletIds] })
} else {
throw new ShouldInChildProcess()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export abstract class Synchronizer {
protected addressesByWalletId: Map<string, AddressMeta[]> = new Map()
protected pollingIndexer: boolean = false
private indexerQueryQueue: QueueObject<LumosCellQuery> | undefined
protected _needGenerateAddress: boolean = false

abstract connect(): Promise<void>
abstract processTxsInNextBlockNumber(): Promise<void>
Expand Down Expand Up @@ -96,6 +97,10 @@ export abstract class Synchronizer {
this.pollingIndexer = false
}

public set needGenerateAddress(v: boolean) {
this._needGenerateAddress = v
}

protected async processNextBlockNumber() {
// the processNextBlockNumberQueue is a queue to ensure that ONLY one
// block processing task runs at a time to avoid the data conflict while syncing
Expand Down
29 changes: 20 additions & 9 deletions packages/neuron-wallet/src/services/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,17 @@ export default class AddressService {
receivingAddressCount: number = DefaultAddressNumber.Receiving,
changeAddressCount: number = DefaultAddressNumber.Change
): Promise<AddressInterface[] | undefined> {
const [unusedReceivingAddresses, unusedChangeAddresses] = await this.getGroupedUnusedAddressesByWalletId(walletId)
const unusedReceivingCount = unusedReceivingAddresses.length
const unusedChangeCount = unusedChangeAddresses.length
if (unusedReceivingCount > this.minUnusedAddressCount && unusedChangeCount > this.minUnusedAddressCount) {
return undefined
}
const [receivingCount, changeCount] = await this.getAddressCountsToFillGapLimit(
walletId,
receivingAddressCount,
changeAddressCount
)
if (!receivingCount && !changeCount) return undefined
const maxReceivingAddressIndex = await this.maxAddressIndex(walletId, AddressType.Receiving)
const maxChangeAddressIndex = await this.maxAddressIndex(walletId, AddressType.Change)
const nextReceivingIndex = maxReceivingAddressIndex === undefined ? 0 : maxReceivingAddressIndex + 1
const nextChangeIndex = maxChangeAddressIndex === undefined ? 0 : maxChangeAddressIndex + 1

const receivingCount: number = unusedReceivingCount > this.minUnusedAddressCount ? 0 : receivingAddressCount
const changeCount: number = unusedChangeCount > this.minUnusedAddressCount ? 0 : changeAddressCount

const currentGeneratedAddresses = await this.generateAndSave(
walletId,
extendedKey,
Expand Down Expand Up @@ -140,6 +137,20 @@ export default class AddressService {
return allGeneratedAddresses
}

public static async getAddressCountsToFillGapLimit(
walletId: string,
receivingAddressCount: number = DefaultAddressNumber.Receiving,
changeAddressCount: number = DefaultAddressNumber.Change
) {
const [unusedReceivingAddresses, unusedChangeAddresses] = await this.getGroupedUnusedAddressesByWalletId(walletId)
const unusedReceivingCount = unusedReceivingAddresses.length
const unusedChangeCount = unusedChangeAddresses.length
return [
unusedReceivingCount > this.minUnusedAddressCount ? 0 : receivingAddressCount,
unusedChangeCount > this.minUnusedAddressCount ? 0 : changeAddressCount,
]
}

public static async generateAndSaveForExtendedKey({
walletId,
extendedKey,
Expand Down
19 changes: 19 additions & 0 deletions packages/neuron-wallet/src/services/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ export abstract class Wallet {
}
}

public async needsGenerateAddress() {
return false
}

public abstract checkAndGenerateAddresses(
isImporting?: boolean,
receivingAddressCount?: number,
Expand Down Expand Up @@ -179,6 +183,11 @@ export class FileKeystoreWallet extends Wallet {
return `${this.id}.json`
}

public async needsGenerateAddress() {
const [receiveCount, changeCount] = await AddressService.getAddressCountsToFillGapLimit(this.id)
return receiveCount !== 0 || changeCount !== 0
}

public checkAndGenerateAddresses = async (
isImporting: boolean = false,
receivingAddressCount: number = DefaultAddressNumber.Receiving,
Expand Down Expand Up @@ -365,6 +374,16 @@ export default class WalletService {
}
}

public async checkNeedGenerateAddress(walletIds: string[]) {
for (const walletId of new Set(walletIds)) {
const wallet = this.get(walletId)
if (await wallet.needsGenerateAddress()) {
return true
}
}
return false
}

public create = (props: WalletProperties) => {
if (!props) {
throw new IsRequired('wallet property')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ describe(`Reset sync task`, () => {
jest.doMock('services/wallets', () => ({
getInstance: () => ({ maintainAddressesIfNecessary: stubbedmaintainAddressesIfNecessary }),
}))
jest.doMock('utils/common', () => ({ sleep: stubbedSleep, timeout: stubbedTimeout }))
jest.doMock('utils/common', () => ({
sleep: stubbedSleep,
timeout: stubbedTimeout,
retry: (_: number, __: number, fn: () => void) => fn(),
}))
jest.doMock('services/tx', () => ({ TransactionPersistor: { checkTxLock: jest.fn() } }))

const blockSyncRenderer = require('block-sync-renderer')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ describe('queue', () => {
},
}
})
jest.doMock('../../src/services/wallets', () => {
return {
getInstance() {
return {
checkNeedGenerateAddress: jest.fn(),
}
},
}
})
const Queue = require('../../src/block-sync-renderer/sync/queue').default
queue = new Queue(fakeNodeUrl, addresses)
})
Expand Down
Loading