Skip to content

Commit

Permalink
Merge branch 'develop' into fix-332
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith-CY authored Apr 29, 2024
2 parents 7c5b1ef + 76c3871 commit b51d90f
Show file tree
Hide file tree
Showing 26 changed files with 130 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
strategy:
matrix:
node:
- 18.12.0
- 20.11.1
os:
- macos-latest
- ubuntu-20.04
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"@types/styled-components": "5.1.34",
"@wojtekmaj/enzyme-adapter-react-17": "0.8.0",
"babel-jest": "25.5.1",
"electron": "28.1.0",
"electron": "30.0.0",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.7",
"eslint-config-airbnb": "19.0.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/components/AddressBook/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ const AddressBook = ({ onClose }: { onClose?: () => void }) => {
return `${HIDE_BALANCE} CKB`
}
return (
<CopyZone content={shannonToCKBFormatter(balance, false, '')} className={styles.copyBalance}>
<CopyZone content={shannonToCKBFormatter(balance, false, false)} className={styles.copyBalance}>
<span className="textOverflow">{`${shannonToCKBFormatter(balance)} CKB`}</span>
</CopyZone>
)
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/components/Balance/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const Balance = ({ balance, connectionStatus, syncStatus }: BalanceProps) => {
return (
<>
<span>{`${t('overview.balance')}:`}</span>
<CopyZone content={shannonToCKBFormatter(balance, false, '')} name={t('overview.copy-balance')}>
<CopyZone content={shannonToCKBFormatter(balance, false, false)} name={t('overview.copy-balance')}>
<span className={styles.balanceValue}>{shannonToCKBFormatter(balance)}</span>
</CopyZone>
<BalanceSyncIcon connectionStatus={connectionStatus} syncStatus={syncStatus} />
Expand Down
4 changes: 2 additions & 2 deletions packages/neuron-ui/src/components/DepositDialog/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export const useGenerateDaoDepositTx = ({
payload: res,
})
if (isDepositAll) {
setMaxDepositValue(shannonToCKBFormatter(res?.outputs[0]?.capacity ?? '0', false, ''))
setMaxDepositValue(shannonToCKBFormatter(res?.outputs[0]?.capacity ?? '0', false, false))
if (!isBalanceReserved) {
setErrorMessage(t('messages.remain-ckb-for-withdraw'))
}
Expand Down Expand Up @@ -181,7 +181,7 @@ export const useDepositValue = (balance: string, showDepositDialog: boolean) =>
const amount = shannonToCKBFormatter(
((BigInt(percent) * BigInt(balance)) / BigInt(PERCENT_100)).toString(),
false,
''
false
)
setDepositValue(padFractionDigitsIfDecimal(amount, 8))
},
Expand Down
4 changes: 2 additions & 2 deletions packages/neuron-ui/src/components/NervosDAO/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ const NervosDAO = () => {
</>
) : (
<CopyZone
content={shannonToCKBFormatter(`${free}`, false, '')}
content={shannonToCKBFormatter(`${free}`, false, false)}
name={t('nervos-dao.copy-balance')}
className={styles.balance}
>
Expand All @@ -303,7 +303,7 @@ const NervosDAO = () => {
<div className={styles.value}>
{onlineAndSynced && !isPrivacyMode ? (
<CopyZone
content={shannonToCKBFormatter(`${locked}`, false, '')}
content={shannonToCKBFormatter(`${locked}`, false, false)}
name={t('nervos-dao.copy-balance')}
className={styles.balance}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const TabsVariantWithTxTypes = ({
{isIncomeShow ? (
<div className={clsx(styles.fieldValue, styles.fullRow, styles.income)}>
<CopyZone
content={shannonToCKBFormatter(transaction.value, false, '')}
content={shannonToCKBFormatter(transaction.value, false, false)}
className={styles.incomeCopy}
maskRadius={8}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ export const DAORecord = ({
) : (
<CopyZone
className={clsx(styles.amount, styles.withCopy)}
content={shannonToCKBFormatter(capacity, false, '')}
content={shannonToCKBFormatter(capacity, false, false)}
>
{`${shannonToCKBFormatter(capacity)} CKB`}
</CopyZone>
Expand Down
4 changes: 2 additions & 2 deletions packages/neuron-ui/src/components/Overview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ const Overview = () => {
)}
</span>
{showBalance ? (
<CopyZone content={shannonToCKBFormatter(balance, false, '')} className={styles.copyBalance}>
<CopyZone content={shannonToCKBFormatter(balance, false, false)} className={styles.copyBalance}>
<span className={styles.balanceValue}>{shannonToCKBFormatter(balance)}</span>
</CopyZone>
) : (
Expand All @@ -191,7 +191,7 @@ const Overview = () => {
<Lock />
<span className={styles.lockedTitle}>{t('overview.locked-balance')}&nbsp;:</span>
{showBalance ? (
<CopyZone content={shannonToCKBFormatter(balance, false, '')}>
<CopyZone content={shannonToCKBFormatter(balance, false, false)}>
<span className={styles.lockedBalance}>{shannonToCKBFormatter(lockedBalance)}</span>
</CopyZone>
) : (
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/components/PageContainer/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const useSetBlockNumber = ({
)
const onOpenAddressInExplorer = useCallback(() => {
const explorerUrl = getExplorerUrl(isMainnet)
openExternal(`${explorerUrl}/address/${firstAddress}`)
openExternal(`${explorerUrl}/address/${firstAddress}?sort=time`)
}, [firstAddress, isMainnet])
const onViewBlock = useCallback(() => {
const explorerUrl = getExplorerUrl(isMainnet)
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/components/Send/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const updateTransactionWith =
if (type === 'all') {
const fmtItems = items.map((item, i) => ({
...item,
amount: shannonToCKBFormatter(res.result.outputs[i].capacity, false, ''),
amount: shannonToCKBFormatter(res.result.outputs[i].capacity, false, false),
}))
const totalAmount = outputsToTotalAmount(fmtItems)
setTotalAmount(totalAmount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export const useSendInfo = ({
...v.slice(0, v.length - 1),
{
...v[v.length - 1],
amount: shannonToCKBFormatter(res.outputs[res.outputs.length - 1].capacity, false, ''),
amount: shannonToCKBFormatter(res.outputs[res.outputs.length - 1].capacity, false, false),
disabled: true,
},
])
Expand Down
40 changes: 8 additions & 32 deletions packages/neuron-ui/src/utils/formatters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { formatUnit } from '@ckb-lumos/bi'
import { molecule } from '@ckb-lumos/codec'
import { blockchain } from '@ckb-lumos/base'
import { formatUnit, ckbDecimals } from '@ckb-lumos/bi'
import { TFunction } from 'i18next'
import { FailureFromController } from 'services/remote/remoteApiWrapper'
import { CapacityUnit } from './enums'
Expand Down Expand Up @@ -104,40 +104,16 @@ export const CKBToShannonFormatter = (amount: string = '0', unit: CapacityUnit =
}
}

export const shannonToCKBFormatter = (shannon: string, showPositiveSign?: boolean, delimiter: string = ',') => {
export const shannonToCKBFormatter = (shannon: string, showPositiveSign?: boolean, showCommaSeparator = true) => {
if (Number.isNaN(+shannon)) {
console.warn(`Shannon is not a valid number`)
console.warn(`Invalid shannon value: ${shannon}`)
return shannon
}
if (shannon === null) {
return '0'
}
let sign = ''
if (shannon.startsWith('-')) {
sign = '-'
} else if (showPositiveSign) {
sign = '+'
}
const unsignedShannon = shannon.replace(/^-?0*/, '')
let unsignedCKB = ''
if (unsignedShannon.length <= 8) {
unsignedCKB = `0.${unsignedShannon.padStart(8, '0')}`.replace(/\.?0+$/, '')
} else {
const decimal = `.${unsignedShannon.slice(-8)}`.replace(/\.?0+$/, '')
const int = unsignedShannon.slice(0, -8).replace(/\^0+/, '')
unsignedCKB = `${(
int
.split('')
.reverse()
.join('')
.match(/\d{1,3}/g) || ['0']
)
.join(delimiter)
.split('')
.reverse()
.join('')}${decimal}`
}
return +unsignedCKB === 0 ? '0' : `${sign}${unsignedCKB}`
return new Intl.NumberFormat('en-US', {
useGrouping: showCommaSeparator,
signDisplay: showPositiveSign && +shannon > 0 ? 'always' : 'auto',
maximumFractionDigits: ckbDecimals,
}).format(formatUnit(BigInt(shannon ?? '0'), 'ckb') as any)
}

export const localNumberFormatter = (num: string | number | bigint = 0) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"@types/sqlite3": "3.1.11",
"@types/uuid": "8.3.4",
"devtron": "1.4.0",
"electron": "28.1.0",
"electron": "30.0.0",
"electron-builder": "24.9.1",
"electron-devtools-installer": "3.2.0",
"jest-when": "3.6.0",
Expand Down
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
7 changes: 6 additions & 1 deletion packages/neuron-wallet/src/services/ckb-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ const platform = (): string => {
}
}

enum NeedMigrateMsg {
Wants = 'CKB wants to migrate the data into new format',
Recommends = 'CKB recommends migrating your data into a new format',
}

const { app } = env
let ckb: ChildProcess | null = null

Expand Down Expand Up @@ -124,7 +129,7 @@ export const startCkbNode = async () => {
currentProcess.stderr?.on('data', data => {
const dataString: string = data.toString()
logger.error('CKB:\trun fail:', dataString)
if (dataString.includes('CKB wants to migrate the data into new format')) {
if (dataString.includes(NeedMigrateMsg.Wants) || dataString.includes(NeedMigrateMsg.Recommends)) {
MigrateSubject.next({ type: 'need-migrate' })
}
})
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-wallet/src/services/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default class SettingsService extends Store {

private onLocaleChanged = (lng: Locale) => {
BrowserWindow.getAllWindows().forEach(bw => bw.webContents.send('set-locale', lng))
updateApplicationMenu(null)
updateApplicationMenu(BrowserWindow.getFocusedWindow())
}

migrateDataPath() {
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
Loading

1 comment on commit b51d90f

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

Packaging for test is done in 8874279881

Please sign in to comment.