diff --git a/CHANGELOG.md b/CHANGELOG.md
index beb859d982..944a2d5f33 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,29 @@
+## [0.25.1](https://github.com/nervosnetwork/neuron/compare/v0.25.0...v0.25.1) (2019-11-18)
+
+
+### Bug Fixes
+
+* Genesis block should be scanned when next scan range ([6947864](https://github.com/nervosnetwork/neuron/commit/6947864)), closes [#1](https://github.com/nervosnetwork/neuron/issues/1)
+* set restart start number to -1 ([06b030e](https://github.com/nervosnetwork/neuron/commit/06b030e))
+* sync when start node ([219d99c](https://github.com/nervosnetwork/neuron/commit/219d99c))
+* **neuron-ui:** remove /s from difficulty units ([2a45e63](https://github.com/nervosnetwork/neuron/commit/2a45e63))
+
+
+### Features
+
+* Add a clear cache button on general settings view ([429be9c](https://github.com/nervosnetwork/neuron/commit/429be9c))
+* Add description for clear cache feature ([38aa4c4](https://github.com/nervosnetwork/neuron/commit/38aa4c4))
+* Delete cell db files when clearing cache ([83ff29d](https://github.com/nervosnetwork/neuron/commit/83ff29d))
+* Do not update network info too often ([819793a](https://github.com/nervosnetwork/neuron/commit/819793a))
+* Only update network's genesis hash and chain when they're actually fetched from RPC and valid ([507131b](https://github.com/nervosnetwork/neuron/commit/507131b))
+* Show popup message when clearing cache finishes ([7dfe670](https://github.com/nervosnetwork/neuron/commit/7dfe670))
+* start/stop syncing with sync controller ([afde49d](https://github.com/nervosnetwork/neuron/commit/afde49d))
+* **neuron-ui:** add clear cache button on the general settings ([7419d37](https://github.com/nervosnetwork/neuron/commit/7419d37))
+* **neuron-ui:** update the i18n texts of nervos dao. ([b445a0c](https://github.com/nervosnetwork/neuron/commit/b445a0c))
+* **neuron-ui:** update the pagination style ([646cf8f](https://github.com/nervosnetwork/neuron/commit/646cf8f))
+
+
+
# [0.25.0](https://github.com/nervosnetwork/neuron/compare/v0.24.5...v0.25.0) (2019-11-16)
diff --git a/README.md b/README.md
index 913f9fdff6..c474ce68a0 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ $ yarn bootstrap
### Start Neuron
-A local CKB node is required for Neuron wallet to talk to it via RPC APIs and get data. Please follow the [Nervos CKB doc](https://docs.nervos.org/getting-started/introduction) to get CKB node up and running first.
+A local CKB node is required for Neuron wallet to talk to it via RPC APIs and get data. Please follow the [Nervos CKB doc](https://docs.nervos.org/references/neuron-wallet-guide.html#1-run-a-ckb-mainnet-node) to get CKB node up and running first.
### Start Neuron in Development Mode
diff --git a/lerna.json b/lerna.json
index 7f8e065009..91991a3759 100644
--- a/lerna.json
+++ b/lerna.json
@@ -2,7 +2,7 @@
"packages": [
"packages/*"
],
- "version": "0.25.0",
+ "version": "0.25.1",
"npmClient": "yarn",
"useWorkspaces": true
}
diff --git a/package.json b/package.json
index 5be6db89bd..1b7b788329 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "neuron",
"productName": "Neuron",
"description": "CKB Neuron Wallet",
- "version": "0.25.0",
+ "version": "0.25.1",
"private": true,
"author": {
"name": "Nervos Core Dev",
diff --git a/packages/neuron-ui/package.json b/packages/neuron-ui/package.json
index dd1352d594..074933c3a6 100644
--- a/packages/neuron-ui/package.json
+++ b/packages/neuron-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "neuron-ui",
- "version": "0.25.0",
+ "version": "0.25.1",
"private": true,
"author": {
"name": "Nervos Core Dev",
diff --git a/packages/neuron-ui/src/components/CustomRows/DAORecordRow.tsx b/packages/neuron-ui/src/components/CustomRows/DAORecordRow.tsx
index 0594d8ab65..4c2af59918 100644
--- a/packages/neuron-ui/src/components/CustomRows/DAORecordRow.tsx
+++ b/packages/neuron-ui/src/components/CustomRows/DAORecordRow.tsx
@@ -96,7 +96,7 @@ const DAORecord = ({
metaInfo = t('nervos-dao.blocks-left', {
epochs: localNumberFormatter(epochs),
blocks: localNumberFormatter(currentEpochInfo.length - currentEpochInfo.index),
- days: localNumberFormatter(epochs / BigInt(6)),
+ days: localNumberFormatter(Math.round(Number(epochs) / 6)),
})
}
}
@@ -153,7 +153,7 @@ const DAORecord = ({
{`APC: ~${apc}%`}
- {uniformTimeFormatter(+timestamp)}
+ {t('nervos-dao.deposit-at', { time: uniformTimeFormatter(+timestamp) })}
{metaInfo}
diff --git a/packages/neuron-ui/src/components/GeneralSetting/index.tsx b/packages/neuron-ui/src/components/GeneralSetting/index.tsx
index ced18634cf..f535311820 100644
--- a/packages/neuron-ui/src/components/GeneralSetting/index.tsx
+++ b/packages/neuron-ui/src/components/GeneralSetting/index.tsx
@@ -1,8 +1,45 @@
-import React from 'react'
-import { Stack } from 'office-ui-fabric-react'
+import React, { useCallback, useState } from 'react'
+import { useTranslation } from 'react-i18next'
+import { Stack, PrimaryButton, Spinner, Text } from 'office-ui-fabric-react'
+import { StateWithDispatch } from 'states/stateProvider/reducer'
+import { addPopup } from 'states/stateProvider/actionCreators'
+import { clearCellCache } from 'services/remote'
-const GeneralSetting = () => {
- return
+const GeneralSetting = ({ dispatch }: React.PropsWithoutRef) => {
+ const [t] = useTranslation()
+ const [clearing, setClearing] = useState(false)
+
+ const clearCache = useCallback(() => {
+ setClearing(true)
+ setTimeout(() => {
+ clearCellCache().finally(() => {
+ addPopup('clear-cache-successfully')(dispatch)
+ setClearing(false)
+ })
+ }, 100)
+ }, [dispatch])
+
+ return (
+
+
+
+ {clearing ? : t('settings.general.clear-cache')}
+
+
+
+ {t('settings.general.clear-cache-description')}
+
+
+ )
}
GeneralSetting.displayName = 'GeneralSetting'
diff --git a/packages/neuron-ui/src/components/NervosDAO/DepositDialog.tsx b/packages/neuron-ui/src/components/NervosDAO/DepositDialog.tsx
index 216d5ba756..b61654d090 100644
--- a/packages/neuron-ui/src/components/NervosDAO/DepositDialog.tsx
+++ b/packages/neuron-ui/src/components/NervosDAO/DepositDialog.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { useMemo } from 'react'
import {
Stack,
Dialog,
@@ -7,13 +7,15 @@ import {
Text,
DefaultButton,
PrimaryButton,
+ ActionButton,
DialogType,
DialogFooter,
Spinner,
SpinnerSize,
} from 'office-ui-fabric-react'
-import { useTranslation } from 'react-i18next'
-import { SHANNON_CKB_RATIO } from 'utils/const'
+import { useTranslation, Trans } from 'react-i18next'
+import { SHANNON_CKB_RATIO, NERVOS_DAO_RFC_URL } from 'utils/const'
+import { openExternal } from 'services/remote'
const DepositDialog = ({
show,
@@ -28,6 +30,28 @@ const DepositDialog = ({
errorMessage,
}: any) => {
const [t] = useTranslation()
+ const rfcLink = useMemo(
+ () => (
+ openExternal(NERVOS_DAO_RFC_URL)}
+ ariaLabel="Nervos DAO RFC"
+ />
+ ),
+ []
+ )
const maxValue = +(BigInt(balance) / BigInt(SHANNON_CKB_RATIO)).toString()
if (!show) {
@@ -63,13 +87,9 @@ const DepositDialog = ({
{`${t('nervos-dao.notice')}:`}
- {t('nervos-dao.deposit-terms')
- .split('\n')
- .map(term => (
-
- {term}
-
- ))}
+
+
+
diff --git a/packages/neuron-ui/src/components/NervosDAO/WithdrawDialog.tsx b/packages/neuron-ui/src/components/NervosDAO/WithdrawDialog.tsx
index 95f066ff25..02eac05dc7 100644
--- a/packages/neuron-ui/src/components/NervosDAO/WithdrawDialog.tsx
+++ b/packages/neuron-ui/src/components/NervosDAO/WithdrawDialog.tsx
@@ -65,16 +65,17 @@ const WithdrawDialog = ({
? t('nervos-dao.notice-wait-time', {
epochs: localNumberFormatter(epochs),
blocks: localNumberFormatter(currentEpochInfo.length - currentEpochInfo.index),
- days: localNumberFormatter(epochs / BigInt(6)),
+ days: localNumberFormatter(Math.round(Number(epochs) / 6)),
})
: ''
const alert =
epochs <= BigInt(5) && epochs >= BigInt(0)
? t('nervos-dao.withdraw-alert', {
- epochs,
- hours: epochs * BigInt(4),
- days: (epochs + BigInt(180)) / BigInt(6),
+ epochs: localNumberFormatter(epochs),
+ hours: localNumberFormatter(epochs * BigInt(4)),
+ nextLeftEpochs: localNumberFormatter(epochs + BigInt(180)),
+ days: localNumberFormatter(Math.round((Number(epochs) + 180) / 6)),
})
: ''
diff --git a/packages/neuron-ui/src/components/NervosDAO/index.tsx b/packages/neuron-ui/src/components/NervosDAO/index.tsx
index e3ecfbca97..6f9ab71f59 100644
--- a/packages/neuron-ui/src/components/NervosDAO/index.tsx
+++ b/packages/neuron-ui/src/components/NervosDAO/index.tsx
@@ -265,7 +265,7 @@ const NervosDAO = ({
return (
<>
- {t('nervos-dao.deposit-receipts')}
+ {t('nervos-dao.deposit-records')}
{records.map((record, i) => {
diff --git a/packages/neuron-ui/src/components/Settings/index.tsx b/packages/neuron-ui/src/components/Settings/index.tsx
index a2d21a06e5..dccb8244b0 100644
--- a/packages/neuron-ui/src/components/Settings/index.tsx
+++ b/packages/neuron-ui/src/components/Settings/index.tsx
@@ -13,7 +13,7 @@ import { WalletWizardPath } from 'components/WalletWizard'
import { Routes } from 'utils/const'
const pivotItems = [
- // { label: 'settings.setting-tabs.general', url: Routes.SettingsGeneral },
+ { label: 'settings.setting-tabs.general', url: Routes.SettingsGeneral },
{ label: 'settings.setting-tabs.wallets', url: Routes.SettingsWallets },
{ label: 'settings.setting-tabs.network', url: Routes.SettingsNetworks },
]
diff --git a/packages/neuron-ui/src/containers/Main/index.tsx b/packages/neuron-ui/src/containers/Main/index.tsx
index 53bd745f0a..a065e52df6 100644
--- a/packages/neuron-ui/src/containers/Main/index.tsx
+++ b/packages/neuron-ui/src/containers/Main/index.tsx
@@ -1,5 +1,5 @@
import React, { useMemo } from 'react'
-import { Route, RouteComponentProps, Switch, Redirect } from 'react-router-dom'
+import { Route, RouteComponentProps } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import { useState } from 'states/stateProvider'
@@ -102,12 +102,12 @@ export const mainContents: CustomRouter.Route[] = [
exact: false,
comp: ImportKeystore,
},
- // {
- // name: `PasswordRequest`,
- // path: '/',
- // exact: false,
- // comp: PasswordRequest,
- // },
+ {
+ name: `PasswordRequest`,
+ path: '/',
+ exact: false,
+ comp: PasswordRequest,
+ },
{
name: `NervosDAO`,
path: Routes.NervosDAO,
@@ -158,26 +158,16 @@ const MainContent = ({
return (
<>
- {
- return
- }}
- />
-
-
- {mainContents.map(container => (
- {
- return
- }}
- />
- ))}
-
+ {mainContents.map(container => (
+ {
+ return
+ }}
+ />
+ ))}
>
)
}
diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json
index eb738235f7..7521caf19c 100644
--- a/packages/neuron-ui/src/locales/en.json
+++ b/packages/neuron-ui/src/locales/en.json
@@ -178,7 +178,8 @@
"network": "Network"
},
"general": {
- "skip-data-and-type": "Skip the Cells which contain Data or Type Script",
+ "clear-cache": "Clear cache",
+ "clear-cache-description": "Clear cache if you encounter data sync or balance display problems. Neuron will rescan block data.",
"show": "Show",
"hide": "Hide"
},
@@ -257,6 +258,7 @@
"delete-wallet-successfully": "The wallet was deleted",
"create-network-successfully": "The network was created",
"update-network-successfully": "The network was updated",
+ "clear-cache-successfully": "The cache was cleared",
"addr-copied": "Address has been copied to the clipboard",
"qrcode-copied": "QR Code has been copied to the clipboard",
"view-the-run-node-doc": "View the guide in browser",
@@ -319,29 +321,26 @@
"free": "Free",
"locked": "Locked",
"deposit": "Deposit",
- "deposit-receipts": "Deposit Receipts",
+ "deposit-records": "Deposit Records",
"apc": "APC",
"deposit-at": "Deposit at {{time}}",
- "claim": "Claim",
- "withdraw": "Withdraw",
"fee": "Transaction fee",
"deposit-to-nervos-dao": "Deposit to Nervos DAO",
"withdraw-from-nervos-dao": "Withdraw from Nervos DAO",
"notice": "Notice",
"cancel": "Cancel",
"proceed": "Proceed",
- "deposit-value": "Deposit",
"compensation": "Compensation",
- "notice-wait-time": "Notice: You need to wait {{epochs}} epochs {{blocks}} blocks(~{{days}} days) to claim the saving.",
- "deposit-terms": "Nervos DAO needs 102 CKB for receipt storage, which is not compensation-bearing.\nNervos DAO is a system layer decentralized infrastructure. Your saving here is secure.\nAccording to the Nervos DAO protocol, you need at least 180 epochs to withdraw your deposit.",
- "deposited-action-label": "Withdraw",
- "withdrawing-action-label": "Claim",
- "minimal-fee-required": "The minimum deposit capacity is {{minimal}} CKB",
+ "notice-wait-time": "Notice: You need to wait {{epochs}} epochs {{blocks}} blocks(~{{days}} days) to complete the withdraw.",
+ "deposit-terms": "Nervos DAO needs 102 CKBytes for deposit cell storage, which is not compensation-bearing. Please visit the <0>Nervos DAO RFC0> for more information about Nervos DAO",
+ "deposited-action-label": "Request withdraw",
+ "withdrawing-action-label": "Withdraw",
+ "minimal-fee-required": "The minimum deposit capacity is {{minimal}} CKBytes",
"compensation-accumulated": "{{blockNumber}} blocks compensation accumulated",
"blocks-left": "{{epochs}} epochs {{blocks}} blocks left(~{{days}} days)",
- "withdraw-alert": "Hint: these are only {{epochs}} epochs (~{{hours}} hours) left to the next deposit claim period. If your start withdrawing transaction is not confirmed before that, your deposit will be locked until the next period (~{{days}} days). And you won’t get more compensation for the prolonged lock period.",
- "insufficient-period-alert-title": "Insufficient Period",
- "insufficient-period-alert-message": "Nervos DAO needs at least 4 epochs to handle your request."
+ "withdraw-alert": "Hint: these are only {{epochs}} epochs (~{{hours}} hours) until the end of your current lock period. If you wish to withdraw in current lock period, please send withdraw request in time. There are {{nextLeftEpochs}} epochs(~{{days}} days) until the end of your next lock period.",
+ "insufficient-period-alert-title": "Referenced Header is Invalid",
+ "insufficient-period-alert-message": "Only mature header can be referenced in transactions(Matureness requires 4 epochs)"
}
}
}
diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json
index 61a8e0e30b..4809dc1eae 100644
--- a/packages/neuron-ui/src/locales/zh.json
+++ b/packages/neuron-ui/src/locales/zh.json
@@ -178,7 +178,8 @@
"network": "网络"
},
"general": {
- "skip-data-and-type": "忽略包含 Data 或 Type Script 的 Cells",
+ "clear-cache": "清空缓存",
+ "clear-cache-description": "当数据同步或显示出现问题时,可以清空缓存,Neuron 会重新同步所有块数据。",
"show": "显示",
"hide": "隐藏"
},
@@ -257,6 +258,7 @@
"delete-wallet-successfully": "已删除钱包",
"create-network-successfully": "已添加新节点",
"update-network-successfully": "已更新节点信息",
+ "clear-cache-successfully": "已清空数据缓存",
"addr-copied": "已复制地址到剪贴板",
"qrcode-copied": "已复制二维码到剪贴板",
"view-the-run-node-doc": "打开浏览器查看文档",
@@ -319,29 +321,26 @@
"free": "当前可用",
"locked": "已锁定",
"deposit": "存入",
- "deposit-receipts": "存款凭证",
+ "deposit-records": "锁定记录",
"apc": "年化锁定补贴率",
- "deposit-at": "存入于{{time}}",
- "claim": "取款",
- "withdraw": "结算",
+ "deposit-at": "存入于 {{time}}",
"fee": "手续费",
"deposit-to-nervos-dao": "存入 Nervos DAO",
"withdraw-from-nervos-dao": "从 Nervos DAO 取出",
"notice": "注意",
"cancel": "取消",
"proceed": "继续",
- "deposit-value": "存款",
"compensation": "锁定补贴",
- "notice-wait-time": "注意: 您需要等待 {{epochs}} epochs {{blocks}} 区块(~{{days}}天)完成最终取款。",
- "deposit-terms": "存入 NervosDAO 的资产中需要 102 CKB 作为存款凭证的存储,这部分 CKB 是无法产生锁定补贴的。\nNervos DAO 是一个系统层面的去中心化底层设施。您在其中存款是十分安全的。\n根据 Nervos DAO 的协议, 您需要等待至少 180 个 epochs 才能取回您的存款。",
- "deposited-action-label": "结算",
- "withdrawing-action-label": "取款",
- "minimal-fee-required": "存入金额应不少于 {{minimal}} CKB",
+ "notice-wait-time": "注意: 您需要等待 {{epochs}} epochs {{blocks}} 区块(约 {{days}} 天)完成最终取出操作。",
+ "deposit-terms": "Nervos DAO 需要 102 CKBytes 作为锁定记录的存储,这部分 CKBytes 是无法产生锁定补贴的。请查看 <0>Nervos DAO RFC0> 以了解 Nervos DAO 更多信息。",
+ "deposited-action-label": "申请取出",
+ "withdrawing-action-label": "取出",
+ "minimal-fee-required": "存入数量应不少于 {{minimal}} CKBytes",
"compensation-accumulated": "已累计 {{blockNumber}} 个块的锁定补贴",
- "blocks-left": " 还需等待 {{epochs}} epochs {{blocks}} 个块(~{{days}} 天)",
- "withdraw-alert": "提示:本补贴申请距离 Nervos DAO 规则允许的最近一个撤出周期仅剩下 {{epochs}} 个 epoch (约 {{hours}} 小时),存在交易拥堵无法上链从而导致只能在下一个撤出周期(约 {{days}} 天)撤出,且无法获得新增撤出周期期间补偿的可能。",
- "insufficient-period-alert-title": "未达到要求周期",
- "insufficient-period-alert-message": "Nervos DAO 要求您在至少 4 个 epochs 后执行此操作"
+ "blocks-left": " 还需等待 {{epochs}} epochs {{blocks}} 个块(约 {{days}} 天)",
+ "withdraw-alert": "提示:本补贴申请距离 Nervos DAO 规则允许的最近一个锁定周期仅剩下 {{epochs}} 个 epoch (约 {{hours}} 小时)。 如果您希望在本锁定周期取出,请及时提交取出申请,以确保取出申请能在本锁定周期结束之前上链。下一个锁定周期的结束时间预计为 {{nextLeftEpochs}} 个 epochs (约 {{days}} 天)。",
+ "insufficient-period-alert-title": "Header 引用无效",
+ "insufficient-period-alert-message": "交易只能引用已成熟的 Header(成熟期为 4 个 epochs)"
}
}
}
diff --git a/packages/neuron-ui/src/services/remote/app.ts b/packages/neuron-ui/src/services/remote/app.ts
index 69bb68af3a..238c302074 100644
--- a/packages/neuron-ui/src/services/remote/app.ts
+++ b/packages/neuron-ui/src/services/remote/app.ts
@@ -5,8 +5,11 @@ export const getNeuronWalletState = apiMethodWrapper(api => () => api.load
export const handleViewError = apiMethodWrapper(api => errorMessage => api.handleViewError(errorMessage))
export const contextMenu = apiMethodWrapper<{ type: string; id: string }>(api => params => api.contextMenu(params))
+export const clearCellCache = apiMethodWrapper(api => () => api.clearCellCache())
+
export default {
getNeuronWalletState,
handleViewError,
contextMenu,
+ clearCellCache,
}
diff --git a/packages/neuron-ui/src/states/stateProvider/actionCreators/app.ts b/packages/neuron-ui/src/states/stateProvider/actionCreators/app.ts
index c0446b5e7d..9827d871f3 100644
--- a/packages/neuron-ui/src/states/stateProvider/actionCreators/app.ts
+++ b/packages/neuron-ui/src/states/stateProvider/actionCreators/app.ts
@@ -60,6 +60,7 @@ export const initAppState = () => (dispatch: StateDispatch, history: any) => {
})
}
+// text: an i18n key under `messages`
export const addPopup = (text: string) => (dispatch: StateDispatch) => {
dispatch({
type: AppActions.PopIn,
diff --git a/packages/neuron-ui/src/stories/GeneralSetting.stories.tsx b/packages/neuron-ui/src/stories/GeneralSetting.stories.tsx
index b016ba1553..a8823d6ac1 100644
--- a/packages/neuron-ui/src/stories/GeneralSetting.stories.tsx
+++ b/packages/neuron-ui/src/stories/GeneralSetting.stories.tsx
@@ -2,9 +2,23 @@ import React from 'react'
import { storiesOf } from '@storybook/react'
import { withKnobs } from '@storybook/addon-knobs'
import GeneralSetting from 'components/GeneralSetting'
+import initStates from 'states/initStates'
+
+const states: { [title: string]: boolean } = {
+ 'Clear cell cache on': true,
+ 'Clear cell cache off': false,
+}
const stories = storiesOf('GeneralSettings', module)
+Object.entries(states).forEach(([title]) => {
+ const props = { ...initStates, settings: { ...initStates.settings }, dispatch: () => {} }
+ stories.add(title, () => )
+})
+
stories.addDecorator(withKnobs).add('With knobs', () => {
- return
+ const props = {
+ ...initStates,
+ }
+ return {}} />
})
diff --git a/packages/neuron-ui/src/styles/index.scss b/packages/neuron-ui/src/styles/index.scss
index 5f0770add3..d98b58e9de 100755
--- a/packages/neuron-ui/src/styles/index.scss
+++ b/packages/neuron-ui/src/styles/index.scss
@@ -119,6 +119,15 @@ navbar {
// hack fabric ui experimental pagination style
.ms-Pagination-container {
+ position: relative;
+
+ &>div:last-child {
+ position: absolute;
+ right: 0;
+ top: 50%;
+ transform: translateY(-50%);
+ }
+
button[aria-selected=false] {
color: #0078d4 !important;
text-decoration: underline;
diff --git a/packages/neuron-ui/src/tests/formatters/difficultyFormatter/fixtures.json b/packages/neuron-ui/src/tests/formatters/difficultyFormatter/fixtures.json
index b7c5781b48..b0f2043ba2 100644
--- a/packages/neuron-ui/src/tests/formatters/difficultyFormatter/fixtures.json
+++ b/packages/neuron-ui/src/tests/formatters/difficultyFormatter/fixtures.json
@@ -1,8 +1,8 @@
[
- { "difficulty": 0, "expected": "0 H/s" },
- { "difficulty": 123, "expected": "123 H/s" },
- { "difficulty": 12345, "expected": "12,345 H/s" },
- { "difficulty": 123454669, "expected": "123,454.67 KH/s" },
- { "difficulty": 1234546698945, "expected": "1,234.55 GH/s" },
- { "difficulty": 100003439, "expected": "100,003.44 KH/s" }
+ { "difficulty": 0, "expected": "0 H" },
+ { "difficulty": 123, "expected": "123 H" },
+ { "difficulty": 12345, "expected": "12,345 H" },
+ { "difficulty": 123454669, "expected": "123,454.67 KH" },
+ { "difficulty": 1234546698945, "expected": "1,234.55 GH" },
+ { "difficulty": 100003439, "expected": "100,003.44 KH" }
]
diff --git a/packages/neuron-ui/src/utils/const.ts b/packages/neuron-ui/src/utils/const.ts
index 56cbfa740f..8c41f126af 100644
--- a/packages/neuron-ui/src/utils/const.ts
+++ b/packages/neuron-ui/src/utils/const.ts
@@ -20,6 +20,8 @@ export const MEDIUM_FEE_RATE = 6000
export const WITHDRAW_EPOCHS = 180
export const RUN_NODE_GUIDE_URL = 'https://docs.nervos.org/references/neuron-wallet-guide.html#1-run-a-ckb-mainnet-node'
+export const NERVOS_DAO_RFC_URL =
+ 'https://github.com/nervosnetwork/rfcs/tree/master/rfcs/0000-dao-deposit-withdraw/0000-dao-deposit-withdraw.md'
export enum ConnectionStatus {
Online = 'online',
diff --git a/packages/neuron-ui/src/utils/formatters.ts b/packages/neuron-ui/src/utils/formatters.ts
index 805d7879a7..77b2080ffa 100644
--- a/packages/neuron-ui/src/utils/formatters.ts
+++ b/packages/neuron-ui/src/utils/formatters.ts
@@ -179,14 +179,14 @@ export const failureResToNotification = (res: any): State.Message => {
export const difficultyFormatter = (value: bigint) => {
const units = new Map([
- ['YH/s', 1e24],
- ['ZH/s', 1e21],
- ['EH/s', 1e18],
- ['PH/s', 1e15],
- ['TH/s', 1e12],
- ['GH/s', 1e9],
- ['MH/s', 1e6],
- ['KH/s', 1e3],
+ ['YH', 1e24],
+ ['ZH', 1e21],
+ ['EH', 1e18],
+ ['PH', 1e15],
+ ['TH', 1e12],
+ ['GH', 1e9],
+ ['MH', 1e6],
+ ['KH', 1e3],
])
/* eslint-disable no-restricted-syntax */
@@ -199,7 +199,7 @@ export const difficultyFormatter = (value: bigint) => {
}
/* eslint-enable no-restricted-syntax */
- return `${localNumberFormatter(value)} H/s`
+ return `${localNumberFormatter(value)} H`
}
export default {
diff --git a/packages/neuron-wallet/package.json b/packages/neuron-wallet/package.json
index f69346cc63..a518cea225 100644
--- a/packages/neuron-wallet/package.json
+++ b/packages/neuron-wallet/package.json
@@ -3,7 +3,7 @@
"productName": "Neuron",
"description": "CKB Neuron Wallet",
"homepage": "https://www.nervos.org/",
- "version": "0.25.0",
+ "version": "0.25.1",
"private": true,
"author": {
"name": "Nervos Core Dev",
@@ -64,7 +64,7 @@
"electron-devtools-installer": "2.2.4",
"electron-notarize": "0.1.1",
"lint-staged": "9.2.5",
- "neuron-ui": "0.25.0",
+ "neuron-ui": "0.25.1",
"rimraf": "3.0.0",
"spectron": "8.0.0",
"ts-transformer-imports": "0.4.3",
diff --git a/packages/neuron-wallet/src/controllers/api.ts b/packages/neuron-wallet/src/controllers/api.ts
index 573bc6747d..7316bfbfd4 100644
--- a/packages/neuron-wallet/src/controllers/api.ts
+++ b/packages/neuron-wallet/src/controllers/api.ts
@@ -4,7 +4,7 @@ import env from 'env'
import i18n from 'utils/i18n'
import { popContextMenu } from './app/menu'
import { showWindow } from './app/show-window'
-import { TransactionsController, WalletsController, SyncInfoController, NetworksController } from 'controllers'
+import { TransactionsController, WalletsController, SyncController, NetworksController } from 'controllers'
import { NetworkType, NetworkID, Network } from 'types/network'
import NetworksService from 'services/networks'
import WalletsService from 'services/wallets'
@@ -40,7 +40,7 @@ export default class ApiController {
networksService.getCurrentID(),
networksService.getAll(),
- SyncInfoController.currentBlockNumber()
+ SyncController.currentBlockNumber()
.then(res => {
if (res.status) {
return res.result.currentBlockNumber
@@ -297,4 +297,12 @@ export default class ApiController {
) {
return DaoController.getDaoCells(params)
}
+
+ // settings
+ @MapApiResponse
+ public static async clearCellCache() {
+ await SyncController.stopSyncing()
+ await SyncController.deleteData()
+ return SyncController.startSyncing()
+ }
}
diff --git a/packages/neuron-wallet/src/controllers/index.ts b/packages/neuron-wallet/src/controllers/index.ts
index ece40cf0d7..cf339b4cbc 100644
--- a/packages/neuron-wallet/src/controllers/index.ts
+++ b/packages/neuron-wallet/src/controllers/index.ts
@@ -2,7 +2,7 @@ import AppController from './app'
import NetworksController from './networks'
import WalletsController from './wallets'
import TransactionsController from './transactions'
-import SyncInfoController from './sync-info'
+import SyncController from './sync'
import UpdateController from './update'
import ApiController from './api'
@@ -12,7 +12,7 @@ export {
NetworksController,
WalletsController,
TransactionsController,
- SyncInfoController,
+ SyncController,
UpdateController,
ApiController,
}
diff --git a/packages/neuron-wallet/src/controllers/sync-info.ts b/packages/neuron-wallet/src/controllers/sync-info.ts
deleted file mode 100644
index 786380441e..0000000000
--- a/packages/neuron-wallet/src/controllers/sync-info.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import BlockNumber from 'services/sync/block-number'
-import { ResponseCode } from 'utils/const'
-
-export default class SyncInfoController {
- public static async currentBlockNumber() {
- const blockNumber = new BlockNumber()
- const current: bigint = await blockNumber.getCurrent()
-
- return {
- status: ResponseCode.Success,
- result: {
- currentBlockNumber: current.toString(),
- },
- }
- }
-}
diff --git a/packages/neuron-wallet/src/controllers/sync.ts b/packages/neuron-wallet/src/controllers/sync.ts
new file mode 100644
index 0000000000..bdae9a1d40
--- /dev/null
+++ b/packages/neuron-wallet/src/controllers/sync.ts
@@ -0,0 +1,45 @@
+import BlockNumber from 'services/sync/block-number'
+import { createSyncBlockTask, killSyncBlockTask } from 'startup/sync-block-task/create'
+import ChainCleaner from 'database/chain/cleaner'
+import { ResponseCode } from 'utils/const'
+
+export default class SyncController {
+ public static async startSyncing() {
+ createSyncBlockTask()
+
+ return {
+ status: ResponseCode.Success,
+ result: true
+ }
+ }
+
+ public static async stopSyncing() {
+ killSyncBlockTask()
+
+ return {
+ status: ResponseCode.Success,
+ result: true
+ }
+ }
+
+ public static async deleteData() {
+ ChainCleaner.clean()
+
+ return {
+ status: ResponseCode.Success,
+ result: true
+ }
+ }
+
+ public static async currentBlockNumber() {
+ const blockNumber = new BlockNumber()
+ const current: bigint = await blockNumber.getCurrent()
+
+ return {
+ status: ResponseCode.Success,
+ result: {
+ currentBlockNumber: current.toString(),
+ },
+ }
+ }
+}
diff --git a/packages/neuron-wallet/src/database/address/address-dao.ts b/packages/neuron-wallet/src/database/address/address-dao.ts
index 9d6414ca3f..a748b18907 100644
--- a/packages/neuron-wallet/src/database/address/address-dao.ts
+++ b/packages/neuron-wallet/src/database/address/address-dao.ts
@@ -154,12 +154,6 @@ export default class AddressDao {
})
}
- public static findByAddress(address: string, walletId: string): Address | undefined {
- return AddressStore.getAll().find(value => {
- return value.address === address && value.walletId == walletId
- })
- }
-
public static findByAddresses(addresses: string[]): Address[] {
return AddressStore.getAll().filter(value => {
return addresses.includes(value.address)
@@ -178,7 +172,10 @@ export default class AddressDao {
}
public static updateDescription(walletId: string, address: string, description: string): Address | undefined {
- const item = AddressDao.findByAddress(address, walletId)
+ const item = AddressStore.getAll().find(value => {
+ return value.walletId === walletId
+ && value.address === address
+ })
if (!item) {
return undefined
}
diff --git a/packages/neuron-wallet/src/database/chain/cleaner.ts b/packages/neuron-wallet/src/database/chain/cleaner.ts
new file mode 100644
index 0000000000..e168a1bc07
--- /dev/null
+++ b/packages/neuron-wallet/src/database/chain/cleaner.ts
@@ -0,0 +1,14 @@
+import { getConnection } from 'typeorm'
+import InputEntity from './entities/input'
+import OutputEntity from './entities/output'
+import TransactionEntity from './entities/transaction'
+import SyncInfoEntity from './entities/sync-info'
+
+// Clean local sqlite storage
+export default class ChainCleaner {
+ public static async clean() {
+ for (const entity of [InputEntity, OutputEntity, TransactionEntity, SyncInfoEntity]) {
+ await getConnection().getRepository(entity).clear()
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/neuron-wallet/src/database/chain/ormconfig.ts b/packages/neuron-wallet/src/database/chain/ormconfig.ts
index 988f8a6c1d..058b5919b5 100644
--- a/packages/neuron-wallet/src/database/chain/ormconfig.ts
+++ b/packages/neuron-wallet/src/database/chain/ormconfig.ts
@@ -22,9 +22,9 @@ import { AddInputIndexToInput1573461100330 } from './migrations/1573461100330-Ad
export const CONNECTION_NOT_FOUND_NAME = 'ConnectionNotFoundError'
-const dbPath = (networkName: string): string => {
- const name = `cell-${networkName}.sqlite`
- return path.join(env.fileBasePath, 'cells', name)
+const dbPath = (name: string): string => {
+ const filename = `cell-${name}.sqlite`
+ return path.join(env.fileBasePath, 'cells', filename)
}
const connectOptions = async (genesisBlockHash: string): Promise => {
diff --git a/packages/neuron-wallet/src/main.ts b/packages/neuron-wallet/src/main.ts
index 257b253887..95b6030ec8 100644
--- a/packages/neuron-wallet/src/main.ts
+++ b/packages/neuron-wallet/src/main.ts
@@ -1,8 +1,8 @@
import { app } from 'electron'
import AppController from 'controllers/app'
+import SyncController from 'controllers/sync'
import WalletService from 'services/wallets'
-import createSyncBlockTask from 'startup/sync-block-task/create'
import { changeLanguage } from 'utils/i18n'
const appController = new AppController()
@@ -11,7 +11,7 @@ app.on('ready', async () => {
changeLanguage(app.getLocale())
WalletService.getInstance().generateAddressesIfNecessary()
- createSyncBlockTask()
+ SyncController.startSyncing()
appController.openWindow()
})
diff --git a/packages/neuron-wallet/src/services/addresses.ts b/packages/neuron-wallet/src/services/addresses.ts
index a689eeaa02..9d876969d9 100644
--- a/packages/neuron-wallet/src/services/addresses.ts
+++ b/packages/neuron-wallet/src/services/addresses.ts
@@ -17,11 +17,6 @@ export interface AddressMetaInfo {
}
export default class AddressService {
- public static isAddressUsed = (address: string, walletId: string): boolean => {
- const addressEntity = AddressDao.findByAddress(address, walletId)
- return !!addressEntity
- }
-
public static generateAndSave = (
walletId: string,
extendedKey: AccountExtendedPublicKey,
@@ -52,9 +47,8 @@ export default class AddressService {
}
private static notifyAddressCreated = (addresses: AddressInterface[], isImporting: boolean | undefined) => {
- const version = AddressService.getAddressVersion()
const addrs = addresses
- .filter(addr => addr.version === version)
+ .filter(addr => addr.version === AddressService.getAddressVersion())
.map(addr => {
const address = addr
address.isImporting = isImporting
@@ -190,9 +184,7 @@ export default class AddressService {
}
public static nextUnusedAddress = (walletId: string): AddressInterface | undefined => {
- const version = AddressService.getAddressVersion()
-
- const addressEntity = AddressDao.nextUnusedAddress(walletId, version)
+ const addressEntity = AddressDao.nextUnusedAddress(walletId, AddressService.getAddressVersion())
if (!addressEntity) {
return undefined
}
@@ -200,9 +192,7 @@ export default class AddressService {
}
public static nextUnusedChangeAddress = (walletId: string): AddressInterface | undefined => {
- const version = AddressService.getAddressVersion()
-
- const addressEntity = AddressDao.nextUnusedChangeAddress(walletId, version)
+ const addressEntity = AddressDao.nextUnusedChangeAddress(walletId, AddressService.getAddressVersion())
if (!addressEntity) {
return undefined
}
@@ -210,19 +200,15 @@ export default class AddressService {
}
public static allAddresses = (): AddressInterface[] => {
- const version = AddressService.getAddressVersion()
-
- return AddressDao.allAddresses(version)
+ return AddressDao.allAddresses( AddressService.getAddressVersion())
}
public static allAddressesByWalletId = (walletId: string): AddressInterface[] => {
- const version = AddressService.getAddressVersion()
- return AddressDao.allAddressesByWalletId(walletId, version)
+ return AddressDao.allAddressesByWalletId(walletId, AddressService.getAddressVersion())
}
public static usedAddresses = (walletId: string): AddressInterface[] => {
- const version = AddressService.getAddressVersion()
- return AddressDao.usedAddressesByWalletId(walletId, version)
+ return AddressDao.usedAddressesByWalletId(walletId, AddressService.getAddressVersion())
}
public static updateDescription = (walletId: string, address: string, description: string): AddressInterface | undefined => {
diff --git a/packages/neuron-wallet/src/services/indexer/queue.ts b/packages/neuron-wallet/src/services/indexer/queue.ts
index daedb4373c..b21234c887 100644
--- a/packages/neuron-wallet/src/services/indexer/queue.ts
+++ b/packages/neuron-wallet/src/services/indexer/queue.ts
@@ -87,7 +87,7 @@ export default class IndexerQueue {
try {
this.inProcess = true
if (this.resetFlag) {
- await this.blockNumberService.updateCurrent(BigInt(0))
+ await this.blockNumberService.updateCurrent(BigInt(-1))
this.resetFlag = false
}
const { lockHashInfos } = this
@@ -215,7 +215,7 @@ export default class IndexerQueue {
if (type === TxPointType.CreatedBy && this.latestCreatedBy.includes(txUniqueFlag)) {
const address = LockUtils.lockScriptToAddress(
transaction.outputs![parseInt(txPoint.index, 16)].lock,
- NetworksService.getInstance().isMainnet ? AddressPrefix.Mainnet : AddressPrefix.Testnet
+ NetworksService.getInstance().isMainnet() ? AddressPrefix.Mainnet : AddressPrefix.Testnet
)
AddressesUsedSubject.getSubject().next({
addresses: [address],
@@ -280,7 +280,7 @@ export default class IndexerQueue {
if (type === TxPointType.CreatedBy) {
address = LockUtils.lockScriptToAddress(
transaction.outputs![parseInt(txPoint.index, 16)].lock,
- NetworksService.getInstance().isMainnet ? AddressPrefix.Mainnet : AddressPrefix.Testnet
+ NetworksService.getInstance().isMainnet() ? AddressPrefix.Mainnet : AddressPrefix.Testnet
)
this.latestCreatedBy.push(txUniqueFlag)
} else if (type === TxPointType.ConsumedBy) {
@@ -289,7 +289,7 @@ export default class IndexerQueue {
if (output) {
address = LockUtils.lockScriptToAddress(
output.lock,
- NetworksService.getInstance().isMainnet ? AddressPrefix.Mainnet : AddressPrefix.Testnet
+ NetworksService.getInstance().isMainnet() ? AddressPrefix.Mainnet : AddressPrefix.Testnet
)
}
}
diff --git a/packages/neuron-wallet/src/services/networks.ts b/packages/neuron-wallet/src/services/networks.ts
index 6e46780892..0f499da69a 100644
--- a/packages/neuron-wallet/src/services/networks.ts
+++ b/packages/neuron-wallet/src/services/networks.ts
@@ -9,7 +9,6 @@ import { Validate, Required } from 'decorators'
import { UsedName, NetworkNotFound, InvalidFormat } from 'exceptions'
import { NetworkListSubject, CurrentNetworkIDSubject } from 'models/subjects/networks'
import { MAINNET_GENESIS_HASH, EMPTY_GENESIS_HASH, NetworkID, NetworkName, NetworkRemote, NetworksKey, NetworkType, Network, NetworkWithID } from 'types/network'
-import logger from 'utils/logger'
export const networkSwitchSubject = new BehaviorSubject(undefined)
@@ -43,28 +42,12 @@ export default class NetworksService extends Store {
const currentNetworkList = this.getAll()
NetworkListSubject.next({ currentNetworkList })
- Promise.all(currentNetworkList.map(n => {
- if (n.type == NetworkType.Default) {
- return n
- } else {
- const core = new Core(n.remote)
- return Promise.all([
- core.rpc.getBlockchainInfo(),
- core.rpc.getBlockHash('0x0')
- ]).then(([info, genesisHash]) => ({
- ...n,
- chain: info.chain,
- genesisHash
- }))
- }
- })).then(networkList => {
- this.updateAll(networkList)
- }).catch((err: Error) => {
- logger.error(err)
- })
-
const currentNetwork = this.getCurrent()
if (currentNetwork) {
+ if (currentNetwork.type !== NetworkType.Default) {
+ this.update(currentNetwork.id, {}) // Update to trigger chain/genesis hash refresh
+ }
+
CurrentNetworkIDSubject.next({ currentNetworkID: currentNetwork.id })
networkSwitchSubject.next(currentNetwork)
}
@@ -95,13 +78,11 @@ export default class NetworksService extends Store {
}
public getAll = () => {
- const list = this.readSync(NetworksKey.List)
- return list || presetNetworks.networks
+ return this.readSync(NetworksKey.List) || presetNetworks.networks
}
public getCurrent(): NetworkWithID {
- const currentID = this.getCurrentID()
- return this.get(currentID) || this.defaultOne()! // Should always have at least one network
+ return this.get(this.getCurrentID()) || this.defaultOne()! // Should always have at least one network
}
public get(@Required id: NetworkID) {
@@ -161,19 +142,24 @@ export default class NetworksService extends Store {
const chain = await core.rpc
.getBlockchainInfo()
.then(info => info.chain)
- .catch(() => 'ckb_dev')
- network.chain = chain
+ .catch(() => '')
+ if (chain !== '') {
+ network.chain = chain
+ }
const genesisHash = await core.rpc
.getBlockHash('0x0')
.catch(() => EMPTY_GENESIS_HASH)
- network.genesisHash = genesisHash
+ if (genesisHash !== EMPTY_GENESIS_HASH) {
+ network.genesisHash = genesisHash
+ }
}
this.updateAll(list)
- const currentID = this.getCurrentID()
- if (currentID === id) {
- await this.activate(id)
+
+ if (this.getCurrentID() === id) {
+ CurrentNetworkIDSubject.next({ currentNetworkID: id })
+ networkSwitchSubject.next(network)
}
}
@@ -198,27 +184,13 @@ export default class NetworksService extends Store {
if (!network) {
throw new NetworkNotFound(id)
}
- this.writeSync(NetworksKey.Current, id)
- // No need to update the default mainnet
- if (network.type === NetworkType.Default) {
- return
+ // No need to update the default mainnet's genesis hash
+ if (network.type !== NetworkType.Default) {
+ this.update(id, {})
}
- const core = new Core(network.remote)
-
- const chain = await core.rpc
- .getBlockchainInfo()
- .then(info => info.chain)
- .catch(() => '')
-
- const genesisHash = await core.rpc
- .getBlockHash('0x0')
- .catch(() => EMPTY_GENESIS_HASH)
-
- if (chain && chain !== network.chain && genesisHash && genesisHash !== network.genesisHash) {
- this.update(id, { chain, genesisHash })
- }
+ this.writeSync(NetworksKey.Current, id)
}
public getCurrentID = () => {
@@ -226,8 +198,7 @@ export default class NetworksService extends Store {
}
public defaultOne = () => {
- const list = this.getAll()
- return list.find(item => item.type === NetworkType.Default) || presetNetworks.networks[0]
+ return this.getAll().find(item => item.type === NetworkType.Default) || presetNetworks.networks[0]
}
public isMainnet = (): boolean => {
diff --git a/packages/neuron-wallet/src/services/sync/block-listener.ts b/packages/neuron-wallet/src/services/sync/block-listener.ts
index e509503e56..5aed6e8d2b 100644
--- a/packages/neuron-wallet/src/services/sync/block-listener.ts
+++ b/packages/neuron-wallet/src/services/sync/block-listener.ts
@@ -50,7 +50,7 @@ export default class BlockListener {
// start listening
public start = async (restart: boolean = false) => {
if (restart) {
- await this.currentBlockNumber.updateCurrent(BigInt(0))
+ await this.currentBlockNumber.updateCurrent(BigInt(-1))
}
try {
@@ -123,7 +123,9 @@ export default class BlockListener {
const endBlockNumber: string = this.tipBlockNumber.toString()
if (this.queue) {
- this.queue.resetEndBlockNumber(endBlockNumber)
+ if (this.tipBlockNumber > BigInt(0)) {
+ this.queue.resetEndBlockNumber(endBlockNumber)
+ }
} else {
const startBlockNumber: string = await this.getStartBlockNumber()
this.queue = new Queue(
diff --git a/packages/neuron-wallet/src/services/sync/check-and-save/index.ts b/packages/neuron-wallet/src/services/sync/check-and-save/index.ts
deleted file mode 100644
index 50d0a28be4..0000000000
--- a/packages/neuron-wallet/src/services/sync/check-and-save/index.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Block } from 'types/cell-types'
-import CheckTx from './tx'
-
-export default class CheckAndSave {
- private block: Block
- private lockHashes: string[]
- private url: string
- private daoScriptHash: string
-
- constructor(block: Block, lockHashes: string[], url: string, daoScriptHash: string) {
- this.block = block
- this.lockHashes = lockHashes
- this.url = url
- this.daoScriptHash = daoScriptHash
- }
-
- public process = async (): Promise => {
- const txs = this.block.transactions
- let result: boolean[] = []
- for (const tx of txs) {
- const checkTx = new CheckTx(tx, this.url, this.daoScriptHash)
- const checkResult = await checkTx.checkAndSave(this.lockHashes)
- result.push(checkResult)
- }
- return result
- }
-}
diff --git a/packages/neuron-wallet/src/services/sync/check-and-save/tx.ts b/packages/neuron-wallet/src/services/sync/check-and-save/tx.ts
index c6f67bd139..a0f0636ac6 100644
--- a/packages/neuron-wallet/src/services/sync/check-and-save/tx.ts
+++ b/packages/neuron-wallet/src/services/sync/check-and-save/tx.ts
@@ -36,7 +36,7 @@ export default class CheckTx {
const outputAddresses: string[] = outputs.map(output => {
return LockUtils.lockScriptToAddress(
output.lock,
- NetworksService.getInstance().isMainnet ? AddressPrefix.Mainnet : AddressPrefix.Testnet
+ NetworksService.getInstance().isMainnet() ? AddressPrefix.Mainnet : AddressPrefix.Testnet
)
})
@@ -93,7 +93,7 @@ export default class CheckTx {
addresses.push(
LockUtils.lockScriptToAddress(
output.lock,
- NetworksService.getInstance().isMainnet ? AddressPrefix.Mainnet : AddressPrefix.Testnet
+ NetworksService.getInstance().isMainnet() ? AddressPrefix.Mainnet : AddressPrefix.Testnet
)
)
}
diff --git a/packages/neuron-wallet/src/services/sync/queue.ts b/packages/neuron-wallet/src/services/sync/queue.ts
index 671354a46e..d99d8c2d6e 100644
--- a/packages/neuron-wallet/src/services/sync/queue.ts
+++ b/packages/neuron-wallet/src/services/sync/queue.ts
@@ -57,7 +57,12 @@ export default class Queue {
this.inProcess = true
if (this.lockHashes.length !== 0) {
- const current: bigint = await this.currentBlockNumber.getCurrent()
+ let current: bigint = await this.currentBlockNumber.getCurrent()
+ if (current === BigInt(0)) {
+ // If it scans from genesis block but current block number was already set to 0,
+ // set it to -1 to make sure `startNumber` would be set to 0.
+ current = BigInt(-1)
+ }
const startNumber: bigint = current + BigInt(1)
const endNumber: bigint = current + BigInt(this.fetchSize)
const realEndNumber: bigint = endNumber < this.endBlockNumber ? endNumber : this.endBlockNumber
diff --git a/packages/neuron-wallet/src/services/sync/renderer-params.ts b/packages/neuron-wallet/src/services/sync/renderer-params.ts
index 30f0fee9c9..e426dcb183 100644
--- a/packages/neuron-wallet/src/services/sync/renderer-params.ts
+++ b/packages/neuron-wallet/src/services/sync/renderer-params.ts
@@ -1,5 +1,7 @@
import { remote } from 'electron'
-export const { networkSwitchSubject, nodeService, addressChangeSubject, addressesUsedSubject } = remote.require(
+export const {
+ networkSwitchSubject, nodeService, addressChangeSubject, addressesUsedSubject
+} = remote.require(
'./startup/sync-block-task/params'
)
diff --git a/packages/neuron-wallet/src/startup/sync-block-task/create.ts b/packages/neuron-wallet/src/startup/sync-block-task/create.ts
index 020c2610a1..19b8d04fe9 100644
--- a/packages/neuron-wallet/src/startup/sync-block-task/create.ts
+++ b/packages/neuron-wallet/src/startup/sync-block-task/create.ts
@@ -8,6 +8,10 @@ import AddressService from 'services/addresses'
import genesisBlockHash from './genesis'
import InitDatabase from './init-database'
import DataUpdateSubject from 'models/subjects/data-update'
+import logger from 'utils/logger'
+import NodeService from 'services/node'
+import NetworksService from 'services/networks'
+import { distinctUntilChanged } from 'rxjs/operators'
export { genesisBlockHash }
@@ -22,41 +26,65 @@ export interface DatabaseInitParams {
chain: string
}
+// network switch or network connect
+const networkChange = async (network: NetworkWithID) => {
+ await InitDatabase.getInstance().stopAndWait()
+ const info = await InitDatabase.getInstance().init(network)
+
+ DataUpdateSubject.next({
+ dataType: 'transaction',
+ actionType: 'update',
+ })
+
+ if (info !== 'killed') {
+ const databaseInitParams: DatabaseInitParams = {
+ network,
+ genesisBlockHash: info.hash,
+ chain: info.chain
+ }
+ databaseInitSubject.next(databaseInitParams)
+ // re init txCount in addresses if switch network
+ await updateAllAddressesTxCount(network.remote)
+ }
+}
+
export const databaseInitSubject = new ReplaySubject(1)
networkSwitchSubject.subscribe(async (network: NetworkWithID | undefined) => {
if (network) {
- // TODO: only switch if genesisHash is different
-
- await InitDatabase.getInstance().stopAndWait()
- const info = await InitDatabase.getInstance().init(network)
-
- DataUpdateSubject.next({
- dataType: 'transaction',
- actionType: 'update',
- })
+ await networkChange(network)
+ }
+})
- if (info !== 'killed') {
- const databaseInitParams: DatabaseInitParams = {
- network,
- genesisBlockHash: info.hash,
- chain: info.chain
+NodeService
+ .getInstance()
+ .connectionStatusSubject
+ .pipe(distinctUntilChanged())
+ .subscribe(async (status: boolean) => {
+ if (status && InitDatabase.getInstance().isUsingPrevious()) {
+ const network = NetworksService.getInstance().getCurrent()
+ logger.debug('networkConnect:', network)
+ if (network) {
+ await networkChange(network)
}
- databaseInitSubject.next(databaseInitParams)
- // re init txCount in addresses if switch network
- await updateAllAddressesTxCount(network.remote)
}
- }
-})
+ })
const loadURL = `file://${path.join(__dirname, 'index.html')}`
export { networkSwitchSubject }
+let syncBlockBackgroundWindow: BrowserWindow | null
+
// create a background task to sync transactions
// this task is a renderer process
-const createSyncBlockTask = () => {
- let syncBlockBackgroundWindow: BrowserWindow | null = new BrowserWindow({
+export const createSyncBlockTask = () => {
+ if (syncBlockBackgroundWindow) {
+ return
+ }
+
+ console.info('Start sync block background process')
+ syncBlockBackgroundWindow = new BrowserWindow({
width: 1366,
height: 768,
show: false,
@@ -65,8 +93,6 @@ const createSyncBlockTask = () => {
},
})
- syncBlockBackgroundWindow.loadURL(loadURL)
-
syncBlockBackgroundWindow.on('ready-to-show', async () => {
if (env.isDevMode && process.env.DEV_SYNC_TASK) {
syncBlockBackgroundWindow!.show()
@@ -79,7 +105,15 @@ const createSyncBlockTask = () => {
syncBlockBackgroundWindow = null
})
+ syncBlockBackgroundWindow.loadURL(loadURL)
+
return syncBlockBackgroundWindow
}
-export default createSyncBlockTask
+export const killSyncBlockTask = async () => {
+ if (syncBlockBackgroundWindow) {
+ console.info('Kill sync block background process')
+ // TODO: kill block number listener
+ syncBlockBackgroundWindow.close()
+ }
+}
diff --git a/packages/neuron-wallet/src/startup/sync-block-task/init-database.ts b/packages/neuron-wallet/src/startup/sync-block-task/init-database.ts
index dcdbfcc6e5..77c7a1eb40 100644
--- a/packages/neuron-wallet/src/startup/sync-block-task/init-database.ts
+++ b/packages/neuron-wallet/src/startup/sync-block-task/init-database.ts
@@ -28,6 +28,12 @@ export class InitDatabase {
private killed: boolean = false
+ private usingPrevious: boolean = false
+
+ public isUsingPrevious = (): boolean => {
+ return this.usingPrevious
+ }
+
public init = async (network: NetworkWithID) => {
if (InitDatabase.previous) {
await InitDatabase.previous.stopAndWait()
@@ -39,6 +45,7 @@ export class InitDatabase {
let chain: string = ''
while (!this.stopped && !this.success) {
try {
+ this.usingPrevious = false
hash = await genesisBlockHash(network.remote)
await initConnection(hash)
chain = await getChain(network.remote)
@@ -68,6 +75,7 @@ export class InitDatabase {
DaoUtils.setDaoScript(metaInfo.daoScriptInfo)
hash = metaInfo.genesisBlockHash
this.success = true
+ this.usingPrevious = true
} catch (error) {
logger.error('get cached meta info error:', err)
Utils.sleep(5000)
diff --git a/packages/neuron-wallet/src/startup/sync-block-task/sync.ts b/packages/neuron-wallet/src/startup/sync-block-task/sync.ts
index 7d0e7d87f8..e0a05985a1 100644
--- a/packages/neuron-wallet/src/startup/sync-block-task/sync.ts
+++ b/packages/neuron-wallet/src/startup/sync-block-task/sync.ts
@@ -79,4 +79,4 @@ export const switchNetwork = async (url: string, genesisBlockHash: string, _chai
})
blockListener.start()
-}
+}
\ No newline at end of file
diff --git a/packages/neuron-wallet/tests/database/address/dao.test.ts b/packages/neuron-wallet/tests/database/address/dao.test.ts
index 68615fad3c..1859fbf48e 100644
--- a/packages/neuron-wallet/tests/database/address/dao.test.ts
+++ b/packages/neuron-wallet/tests/database/address/dao.test.ts
@@ -143,14 +143,6 @@ describe('Address Dao tests', () => {
expect(walletTwo.length).toEqual(1)
})
- it('findByAddress', () => {
- AddressDao.create([address, usedAddress])
-
- const one = AddressDao.findByAddress(address.address, address.walletId)
-
- expect(one!.address).toEqual(address.address)
- })
-
it('unusedAddressesCount', () => {
AddressDao.create([address, changeAddress])
diff --git a/packages/neuron-wallet/tests/services/address.test.ts b/packages/neuron-wallet/tests/services/address.test.ts
index 2297c8f3a6..f2d05f477a 100644
--- a/packages/neuron-wallet/tests/services/address.test.ts
+++ b/packages/neuron-wallet/tests/services/address.test.ts
@@ -54,7 +54,7 @@ describe('Key tests with db', () => {
pendingBalance: '0',
balance: '0',
blake160: '0x36c329ed630d6ce750712a477543672adab57f4c',
- version: NetworksService.getInstance().isMainnet ? AddressVersion.Mainnet : AddressVersion.Testnet,
+ version: NetworksService.getInstance().isMainnet() ? AddressVersion.Mainnet : AddressVersion.Testnet,
}
const usedAddress: Address = {
@@ -69,7 +69,7 @@ describe('Key tests with db', () => {
pendingBalance: '0',
balance: '0',
blake160: '0x36c329ed630d6ce750712a477543672adab57f4c',
- version: NetworksService.getInstance().isMainnet ? AddressVersion.Mainnet : AddressVersion.Testnet,
+ version: NetworksService.getInstance().isMainnet() ? AddressVersion.Mainnet : AddressVersion.Testnet,
}
const changeAddress: Address = {
@@ -84,7 +84,7 @@ describe('Key tests with db', () => {
pendingBalance: '0',
balance: '0',
blake160: '0x36c329ed630d6ce750712a477543672adab57f4c',
- version: NetworksService.getInstance().isMainnet ? AddressVersion.Mainnet : AddressVersion.Testnet,
+ version: NetworksService.getInstance().isMainnet() ? AddressVersion.Mainnet : AddressVersion.Testnet,
}
beforeEach(() => {
@@ -139,23 +139,17 @@ describe('Key tests with db', () => {
expect(all.length).toEqual((2 + 1) * 2 * 2)
})
- it('isAddressUsed', () => {
- AddressDao.create([address, usedAddress])
- const used = AddressService.isAddressUsed(address.address, walletId)
- expect(used).toBe(true)
- })
-
it('nextUnusedAddress', () => {
AddressDao.create([address, usedAddress, changeAddress])
const addr = AddressService.nextUnusedAddress(walletId)
- const addrDao = AddressDao.nextUnusedAddress(walletId, NetworksService.getInstance().isMainnet ? AddressVersion.Mainnet : AddressVersion.Testnet)
+ const addrDao = AddressDao.nextUnusedAddress(walletId, NetworksService.getInstance().isMainnet() ? AddressVersion.Mainnet : AddressVersion.Testnet)
expect(addr).toEqual(addrDao)
})
it('nextUnusedChangeAddress', () => {
AddressDao.create([address, usedAddress, changeAddress])
const addr = AddressService.nextUnusedChangeAddress(walletId)
- const addrDao = AddressDao.nextUnusedChangeAddress(walletId, NetworksService.getInstance().isMainnet ? AddressVersion.Mainnet : AddressVersion.Testnet)
+ const addrDao = AddressDao.nextUnusedChangeAddress(walletId, NetworksService.getInstance().isMainnet() ? AddressVersion.Mainnet : AddressVersion.Testnet)
expect(addr).toEqual(addrDao)
})
diff --git a/packages/neuron-wallet/tests/services/networks.test.ts b/packages/neuron-wallet/tests/services/networks.test.ts
index c179beef5c..a162fb1e58 100644
--- a/packages/neuron-wallet/tests/services/networks.test.ts
+++ b/packages/neuron-wallet/tests/services/networks.test.ts
@@ -26,17 +26,11 @@ describe(`Unit tests of networks service`, () => {
let service: NetworksService = new NetworksService()
- beforeEach(done => {
+ beforeEach(() => {
service = new NetworksService()
- setTimeout(() => {
- done()
- }, 1000)
})
- afterEach(done => {
+ afterEach(() => {
service.clear()
- setTimeout(() => {
- done()
- }, 1000)
})
describe(`success cases`, () => {
@@ -132,7 +126,7 @@ describe(`Unit tests of networks service`, () => {
expect(currentID).toBe('mainnet')
})
- it(`reset the netowrks`, async () => {
+ it(`reset the networks`, async () => {
await service.create(newNetwork.name, newNetwork.remote)
const newNetworkList = service.getAll()
expect(newNetworkList.length).toBe(2)