From beeb8fa4859768ab05081bcbe74ba2d29211e5fc Mon Sep 17 00:00:00 2001
From: yanguoyu <841185308@qq.com>
Date: Thu, 16 May 2024 22:27:16 +0800
Subject: [PATCH 01/10] feat: Add help link for sync failed.
---
.../GeneralSetting/generalSetting.module.scss | 2 +-
.../src/components/SyncStatus/index.tsx | 44 +++++++++++-
.../SyncStatus/syncStatus.module.scss | 68 ++++++++++++++++++-
packages/neuron-ui/src/locales/en.json | 7 +-
packages/neuron-ui/src/locales/es.json | 7 +-
packages/neuron-ui/src/locales/fr.json | 7 +-
packages/neuron-ui/src/locales/zh-tw.json | 7 +-
packages/neuron-ui/src/locales/zh.json | 7 +-
.../neuron-ui/src/widgets/Icons/Question.svg | 12 ++++
packages/neuron-ui/src/widgets/Icons/icon.tsx | 2 +
.../src/widgets/Tooltip/tooltip.module.scss | 12 ++--
11 files changed, 154 insertions(+), 21 deletions(-)
create mode 100644 packages/neuron-ui/src/widgets/Icons/Question.svg
diff --git a/packages/neuron-ui/src/components/GeneralSetting/generalSetting.module.scss b/packages/neuron-ui/src/components/GeneralSetting/generalSetting.module.scss
index 92e5f8d34f..39881944b7 100644
--- a/packages/neuron-ui/src/components/GeneralSetting/generalSetting.module.scss
+++ b/packages/neuron-ui/src/components/GeneralSetting/generalSetting.module.scss
@@ -9,7 +9,7 @@ $action-button-width: 11.25rem;
gap: 16px;
.content {
- width: 176px;
+ min-width: 176px;
padding: 16px;
background: var(--input-disabled-color);
border-radius: 8px;
diff --git a/packages/neuron-ui/src/components/SyncStatus/index.tsx b/packages/neuron-ui/src/components/SyncStatus/index.tsx
index 5735881e07..d425869b0e 100644
--- a/packages/neuron-ui/src/components/SyncStatus/index.tsx
+++ b/packages/neuron-ui/src/components/SyncStatus/index.tsx
@@ -1,10 +1,11 @@
import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { SyncStatus as SyncStatusEnum, ConnectionStatus, clsx, localNumberFormatter, getSyncLeftTime } from 'utils'
-import { Confirming, NewTab } from 'widgets/Icons/icon'
+import { Confirming, NewTab, Question } from 'widgets/Icons/icon'
import { ReactComponent as UnexpandStatus } from 'widgets/Icons/UnexpandStatus.svg'
import { ReactComponent as StartBlock } from 'widgets/Icons/StartBlock.svg'
import Tooltip from 'widgets/Tooltip'
+import { openExternal } from 'services/remote'
import styles from './syncStatus.module.scss'
const SyncDetail = ({
@@ -53,7 +54,17 @@ const SyncDetail = ({
) : null}
-
{t('network-status.left-time')}
+
+ {t('network-status.left-time')}:
+ {t('network-status.left-time-tip')}
}
+ className={styles.question}
+ tipClassName={styles.questionTip}
+ placement="right-bottom"
+ >
+
+
+
{getSyncLeftTime(estimate)}
{isLightClient && (
@@ -114,7 +125,34 @@ const SyncStatus = ({
}
if (ConnectionStatus.Offline === connectionStatus) {
- return {t('sync.sync-failed')}
+ return (
+
+ {t('sync.sync-failed')}
+
+ {t('sync.sync-failed-detail')}
+
+
+
+ }
+ trigger="click"
+ placement="left-bottom"
+ showTriangle
+ tipClassName={styles.helpTip}
+ >
+
+
+
+ )
}
if (SyncStatusEnum.SyncNotStart === syncStatus) {
diff --git a/packages/neuron-ui/src/components/SyncStatus/syncStatus.module.scss b/packages/neuron-ui/src/components/SyncStatus/syncStatus.module.scss
index 0392091b75..130bb5597b 100755
--- a/packages/neuron-ui/src/components/SyncStatus/syncStatus.module.scss
+++ b/packages/neuron-ui/src/components/SyncStatus/syncStatus.module.scss
@@ -99,6 +99,37 @@
.title {
font-size: 12px;
font-weight: 400;
+ display: flex;
+ align-items: center;
+
+ .question {
+ height: 14px;
+ flex: 1 1 auto;
+ svg {
+ margin-left: 4px;
+ cursor: pointer;
+ path {
+ stroke: var(--secondary-text-color);
+ }
+ &:hover {
+ path {
+ stroke: var(--primary-color);
+ }
+ }
+ }
+ }
+
+ .questionTip {
+ top: calc(100% + 28px);
+ right: -36px;
+ width: 200px;
+ left: inherit;
+ }
+
+ .leftTimeTip {
+ white-space: normal;
+ width: 200px;
+ }
}
.number {
color: var(--third-text-color);
@@ -110,8 +141,20 @@
.redDot {
position: relative;
- color: '#FF1E1E';
+ color: var(--error-color);
padding-left: 14px;
+ display: flex;
+ align-items: center;
+
+ & > div {
+ height: 14px;
+ }
+
+ svg {
+ margin-left: 4px;
+ cursor: pointer;
+ }
+
&::before {
content: '';
height: 6px;
@@ -122,4 +165,27 @@
top: calc(50% - 3px);
background: var(--error-color);
}
+
+ .helpTip {
+ margin-top: 20px;
+ right: -10px !important;
+
+ & > div:nth-last-child(1) {
+ right: 12px;
+ }
+ }
+
+ .failedDetail {
+ white-space: normal;
+ min-width: 250px;
+ }
+ .openHelper {
+ font-weight: 500;
+ background: inherit;
+ color: var(--primary-color);
+ border: none;
+ padding: 0;
+ margin: 0;
+ cursor: pointer;
+ }
}
diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json
index 037af66417..9e4244118b 100644
--- a/packages/neuron-ui/src/locales/en.json
+++ b/packages/neuron-ui/src/locales/en.json
@@ -36,7 +36,8 @@
"set-start-block-number": "Set start block number"
},
"migrating": "migrating...",
- "left-time": "Left Time"
+ "left-time": "Time Remaining",
+ "left-time-tip": "The time remaining is an estimate and is related to the current network and other factors, and is for reference only."
},
"import-hardware": {
"title": {
@@ -687,7 +688,9 @@
"block-number": "block number",
"syncing-balance": "Balance is updating",
"slow": "Sync is slow",
- "sync-failed": "Sync failed, please check network",
+ "sync-failed": "Synchronization failed",
+ "sync-failed-detail": "Synchronization failed due to network node or other problems.",
+ "learn-more": "Learn More",
"sync-not-start": "Sync not started yet, please try to restart Neuron Wallet",
"connecting": "Connecting"
},
diff --git a/packages/neuron-ui/src/locales/es.json b/packages/neuron-ui/src/locales/es.json
index 0a62c02f52..7c9046316e 100644
--- a/packages/neuron-ui/src/locales/es.json
+++ b/packages/neuron-ui/src/locales/es.json
@@ -35,7 +35,8 @@
"set-start-block-number": "Establecer el número de bloque inicial"
},
"migrating": "migrando...",
- "left-time": "Tiempo restante"
+ "left-time": "Tiempo restante",
+ "left-time-tip": "El tiempo restante es una estimación y está relacionado con la red actual y otros factores, y es solo para referencia."
},
"import-hardware": {
"title": {
@@ -670,7 +671,9 @@
"block-number": "número de bloque",
"syncing-balance": "El saldo se está actualizando",
"slow": "La sincronización es lenta",
- "sync-failed": "Error de sincronización, por favor compruebe la red",
+ "sync-failed": "sincronización fallida",
+ "sync-failed-detail": "Debido a nodos de red u otros problemas, la sincronización ha fallado.",
+ "learn-more": "Saber más",
"sync-not-start": "La sincronización no se ha iniciado todavía, por favor intente reiniciar Neuron Wallet",
"connecting": "Conectando"
},
diff --git a/packages/neuron-ui/src/locales/fr.json b/packages/neuron-ui/src/locales/fr.json
index c355aabd83..9265e92776 100644
--- a/packages/neuron-ui/src/locales/fr.json
+++ b/packages/neuron-ui/src/locales/fr.json
@@ -36,7 +36,8 @@
"set-start-block-number": "Définir le numéro de bloc de départ"
},
"migrating": "migration en cours...",
- "left-time": "Temps restant"
+ "left-time": "Temps restant",
+ "left-time-tip": "Le temps restant est une estimation et est lié au réseau actuel et à d'autres facteurs, et est fourni à titre indicatif seulement."
},
"import-hardware": {
"title": {
@@ -677,7 +678,9 @@
"block-number": "numéro de bloc",
"syncing-balance": "La balance est en cours de mise à jour",
"slow": "La synchronisation est lente",
- "sync-failed": "Échec de la synchronisation, veuillez vérifier le réseau",
+ "sync-failed": "échec de la synchronisation",
+ "sync-failed-detail": "En raison de nœuds réseau ou d'autres problèmes, la synchronisation a échoué.",
+ "learn-more": "En savoir plus",
"sync-not-start": "La synchronisation n'a pas encore commencé, veuillez essayer de redémarrer le Wallet Neuron",
"connecting": "Connexion en cours"
},
diff --git a/packages/neuron-ui/src/locales/zh-tw.json b/packages/neuron-ui/src/locales/zh-tw.json
index e1de094b06..47ff57a27c 100644
--- a/packages/neuron-ui/src/locales/zh-tw.json
+++ b/packages/neuron-ui/src/locales/zh-tw.json
@@ -36,7 +36,8 @@
"set-start-block-number": "設置同步起始區塊"
},
"migrating": "正在數據遷移...",
- "left-time": "剩余時間"
+ "left-time": "剩余時間",
+ "left-time-tip": "剩余時間僅為估計值,與當前網絡和其他因素有關,僅供參考。"
},
"import-hardware": {
"title": {
@@ -681,7 +682,9 @@
"block-number": "區塊高度",
"syncing-balance": "區塊同步中, 正在獲取最新余額",
"slow": "同步緩慢,請檢查網絡",
- "sync-failed": "連接失敗, 請檢查網絡",
+ "sync-failed": "同步失敗",
+ "sync-failed-detail": "由於網絡節點或其他問題,同步失敗。",
+ "learn-more": "了解更多",
"sync-not-start": "同步尚未開始, 請嘗試重啟",
"connecting": "正在連接節點"
},
diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json
index 3355e80542..7d0a45f220 100644
--- a/packages/neuron-ui/src/locales/zh.json
+++ b/packages/neuron-ui/src/locales/zh.json
@@ -36,7 +36,8 @@
"set-start-block-number": "设置同步起始区块"
},
"migrating": "正在数据迁移...",
- "left-time": "剩余时间"
+ "left-time": "剩余时间",
+ "left-time-tip": "剩余时间仅为估计值,与当前网络和其他因素有关,仅供参考。"
},
"import-hardware": {
"title": {
@@ -680,7 +681,9 @@
"block-number": "区块高度",
"syncing-balance": "区块同步中, 正在获取最新余额",
"slow": "同步缓慢,请检查网络",
- "sync-failed": "连接失败, 请检查网络",
+ "sync-failed": "同步失败",
+ "sync-failed-detail": "由于网络节点或其他问题,同步失败。",
+ "learn-more": "了解更多",
"sync-not-start": "同步尚未开始, 请尝试重启",
"connecting": "正在连接节点"
},
diff --git a/packages/neuron-ui/src/widgets/Icons/Question.svg b/packages/neuron-ui/src/widgets/Icons/Question.svg
new file mode 100644
index 0000000000..c2e6b78f5c
--- /dev/null
+++ b/packages/neuron-ui/src/widgets/Icons/Question.svg
@@ -0,0 +1,12 @@
+
diff --git a/packages/neuron-ui/src/widgets/Icons/icon.tsx b/packages/neuron-ui/src/widgets/Icons/icon.tsx
index 806510ad82..c8a1f9bd2e 100644
--- a/packages/neuron-ui/src/widgets/Icons/icon.tsx
+++ b/packages/neuron-ui/src/widgets/Icons/icon.tsx
@@ -57,6 +57,7 @@ import { ReactComponent as DeleteSvg } from './Delete.svg'
import { ReactComponent as ImportKeystoreSvg } from './SoftWalletImportKeystore.svg'
import { ReactComponent as ImportHardwareSvg } from './HardWalletImport.svg'
import { ReactComponent as DepositTimeSortSvg } from './DepositTimeSort.svg'
+import { ReactComponent as QuestionSvg } from './Question.svg'
import styles from './icon.module.scss'
@@ -130,3 +131,4 @@ export const Delete = WrapSvg(DeleteSvg)
export const ImportKeystore = WrapSvg(ImportKeystoreSvg)
export const ImportHardware = WrapSvg(ImportHardwareSvg)
export const DepositTimeSort = WrapSvg(DepositTimeSortSvg)
+export const Question = WrapSvg(QuestionSvg)
diff --git a/packages/neuron-ui/src/widgets/Tooltip/tooltip.module.scss b/packages/neuron-ui/src/widgets/Tooltip/tooltip.module.scss
index 6c4d88ffd1..111bd6d1d3 100644
--- a/packages/neuron-ui/src/widgets/Tooltip/tooltip.module.scss
+++ b/packages/neuron-ui/src/widgets/Tooltip/tooltip.module.scss
@@ -251,25 +251,25 @@ $placements: left, right, top, bottom, left-top, right-top, left-bottom, right-b
.tipWithNode {
position: relative;
- .tip {
+ > .tip {
@include tip;
}
&[data-type='always-dark'] {
- .tip {
+ > .tip {
background: #000000;
color: #ffffff;
}
}
&[data-trigger='click'] {
- &[data-tip-show='true'] .tip {
+ &[data-tip-show='true'] > .tip {
display: block;
}
}
@each $placement in $placements {
- @include tip-placement($placement, ' .tip');
+ @include tip-placement($placement, '> .tip');
}
&[data-trigger='hover'] {
@@ -286,14 +286,14 @@ $placements: left, right, top, bottom, left-top, right-top, left-bottom, right-b
&[data-has-trigger='true'] {
&[data-placement='bottom'] {
&:not([data-trigger-next-to-child='true']) {
- & .tip {
+ & > .tip {
top: calc(100% + 20px);
}
}
}
&[data-placement='top'] {
&[data-trigger-next-to-child='true'] {
- & .tip {
+ & > .tip {
margin-bottom: 2px;
}
}
From 4a4aa6bbbf0371c137f7b8d9dd1cca517e191ae0 Mon Sep 17 00:00:00 2001
From: Tom Wang
Date: Tue, 21 May 2024 16:34:09 +0800
Subject: [PATCH 02/10] ci: upgrade github actions version (#3161)
Co-authored-by: Chen Yu
---
.github/workflows/check-code-style.yml | 2 +-
.github/workflows/check_storybook.yml | 2 +-
.github/workflows/package.yml | 4 ++--
.github/workflows/package_for_test.yml | 8 ++++----
.github/workflows/unit_tests.yml | 2 +-
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/.github/workflows/check-code-style.yml b/.github/workflows/check-code-style.yml
index 87de0e3831..3584d79ce5 100644
--- a/.github/workflows/check-code-style.yml
+++ b/.github/workflows/check-code-style.yml
@@ -18,7 +18,7 @@ jobs:
cache: "yarn"
- name: Restore
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
node_modules
diff --git a/.github/workflows/check_storybook.yml b/.github/workflows/check_storybook.yml
index 1f351e7fb1..82aded4a8d 100644
--- a/.github/workflows/check_storybook.yml
+++ b/.github/workflows/check_storybook.yml
@@ -35,7 +35,7 @@ jobs:
cache: "yarn"
- name: Restore
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
node_modules
diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml
index e4a0171d42..0b74b02f2f 100644
--- a/.github/workflows/package.yml
+++ b/.github/workflows/package.yml
@@ -42,7 +42,7 @@ jobs:
cache: "yarn"
- name: Restore
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
node_modules
@@ -51,7 +51,7 @@ jobs:
- name: Add msbuild to PATH
if: matrix.os == 'windows-2019'
- uses: microsoft/setup-msbuild@v1.3.1
+ uses: microsoft/setup-msbuild@v2
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: "true"
diff --git a/.github/workflows/package_for_test.yml b/.github/workflows/package_for_test.yml
index 757811fc6d..a475701b0c 100644
--- a/.github/workflows/package_for_test.yml
+++ b/.github/workflows/package_for_test.yml
@@ -53,7 +53,7 @@ jobs:
cache: "yarn"
- name: Restore
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
node_modules
@@ -62,7 +62,7 @@ jobs:
- name: Add msbuild to PATH
if: matrix.os == 'windows-2019'
- uses: microsoft/setup-msbuild@v1.3.1
+ uses: microsoft/setup-msbuild@v2
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: "true"
@@ -225,7 +225,7 @@ jobs:
- name: Comment by pull request comment event
if: ${{ github.event_name == 'issue_comment' }}
- uses: peter-evans/create-or-update-comment@v3
+ uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ github.event.comment.id }}
body: |
@@ -242,7 +242,7 @@ jobs:
steps:
- name: Comment by pull request comment event when package failed
if: ${{ github.event_name == 'issue_comment' }}
- uses: peter-evans/create-or-update-comment@v3
+ uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ github.event.comment.id }}
body: Packageing failed in [${{ github.run_id }}](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}). @${{ github.event.comment.user.login }}
diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml
index e77a974953..334bc4c2f9 100644
--- a/.github/workflows/unit_tests.yml
+++ b/.github/workflows/unit_tests.yml
@@ -35,7 +35,7 @@ jobs:
cache: "yarn"
- name: Restore
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
node_modules
From 590dc0d8693122d534dcc00debccd893624260cc Mon Sep 17 00:00:00 2001
From: Tom Wang
Date: Tue, 21 May 2024 19:17:42 +0800
Subject: [PATCH 03/10] refactor: refactor models/multisig with lumos (#3156)
* refactor: refactor models/multisig with lumos
Signed-off-by: Tom Wang
* refactor: move BLAKE160_HEX_LENGTH to blake2b.ts
Signed-off-by: Tom Wang
* feat: Add help link for sync failed.
Signed-off-by: Tom Wang
* ci: upgrade github actions version (#3161)
Co-authored-by: Chen Yu
Signed-off-by: Tom Wang
---------
Signed-off-by: Tom Wang
Co-authored-by: yanguoyu <841185308@qq.com>
Co-authored-by: Chen Yu
---
packages/neuron-wallet/src/models/blake2b.ts | 2 +
packages/neuron-wallet/src/models/multisig.ts | 49 ++++++-------------
.../src/services/tx/transaction-generator.ts | 6 +--
.../tests/models/multi-sign.test.ts | 6 +--
.../tests/services/cells.test.ts | 4 +-
.../services/tx/transaction-generator.test.ts | 27 +++++-----
6 files changed, 37 insertions(+), 57 deletions(-)
diff --git a/packages/neuron-wallet/src/models/blake2b.ts b/packages/neuron-wallet/src/models/blake2b.ts
index 7dc99b6c7e..33c01368df 100644
--- a/packages/neuron-wallet/src/models/blake2b.ts
+++ b/packages/neuron-wallet/src/models/blake2b.ts
@@ -1,6 +1,8 @@
import { CKBHasher } from '@ckb-lumos/base/lib/utils'
import { bytes } from '@ckb-lumos/codec'
+export const BLAKE160_HEX_LENGTH = 42
+
export default class Blake2b {
private blake2b: CKBHasher
diff --git a/packages/neuron-wallet/src/models/multisig.ts b/packages/neuron-wallet/src/models/multisig.ts
index 39f2153d41..6d62aaf6a6 100644
--- a/packages/neuron-wallet/src/models/multisig.ts
+++ b/packages/neuron-wallet/src/models/multisig.ts
@@ -1,6 +1,8 @@
import { MultisigPrefixError } from '../exceptions'
-import Blake2b from './blake2b'
import SystemScriptInfo from './system-script-info'
+import { since } from '@ckb-lumos/base'
+import { bytes, number } from '@ckb-lumos/codec'
+import Blake2b, { BLAKE160_HEX_LENGTH } from './blake2b'
export interface MultisigPrefix {
S: string
@@ -11,7 +13,7 @@ export interface MultisigPrefix {
export default class Multisig {
// 1 epoch = 4h = 240min
- EPOCH_MINUTES = 240
+ static EPOCH_MINUTES = 240
static defaultS: string = '00'
@@ -24,32 +26,22 @@ export default class Multisig {
static hash(blake160s: string[], r: number = 0, m: number = 1, n: number = 1): string {
const serializeResult = Multisig.serialize(blake160s, r, m, n)
- return Blake2b.digest(serializeResult).slice(0, 42)
+ return Blake2b.digest(serializeResult).slice(0, BLAKE160_HEX_LENGTH)
}
- since(minutes: number, headerEpoch: string): string {
+ static since(minutes: number, headerEpoch: string): string {
if (minutes < 0) {
throw new Error("minutes to calculate since can't be less than 0")
}
- const currentEpochInfo = this.parseEpoch(BigInt(headerEpoch))
- const totalMinutes =
- minutes +
- parseInt(
- (
- (parseInt(currentEpochInfo.index.toString()) / parseInt(currentEpochInfo.length.toString())) *
- this.EPOCH_MINUTES
- ).toString()
- )
+ const currentEpoch = since.parseEpoch(headerEpoch)
+ const totalMinutes = minutes + Math.floor((currentEpoch.index / currentEpoch.length) * this.EPOCH_MINUTES)
const leftMinutes = totalMinutes % this.EPOCH_MINUTES
- const epochs: bigint =
- BigInt(parseInt((totalMinutes / this.EPOCH_MINUTES).toString(), 10)) + currentEpochInfo.number
- const result = this.epochSince(BigInt(this.EPOCH_MINUTES), BigInt(leftMinutes), epochs)
- const buf = Buffer.alloc(8)
- buf.writeBigUInt64LE(result)
- return `0x${buf.toString('hex')}`
+ const epochs = Math.floor(totalMinutes / this.EPOCH_MINUTES) + currentEpoch.number
+ const result = this.epochSince(BigInt(this.EPOCH_MINUTES), BigInt(leftMinutes), BigInt(epochs))
+ return bytes.hexify(number.Uint64LE.pack(result))
}
- args(blake160: string, minutes: number, headerEpoch: string): string {
+ static args(blake160: string, minutes: number, headerEpoch: string): string {
return Multisig.hash([blake160]) + this.since(minutes, headerEpoch).slice(2)
}
@@ -57,25 +49,14 @@ export default class Multisig {
return SystemScriptInfo.generateMultiSignScript(Multisig.hash(blake160s, r, m, n))
}
- parseSince(args: string): bigint {
- const str = args.slice(42)
- const buf = Buffer.from(str, 'hex')
- const sin: bigint = buf.readBigUInt64LE()
- return sin
+ static parseSince(args: string): bigint {
+ return number.Uint64LE.unpack(`0x${args.slice(BLAKE160_HEX_LENGTH)}`).toBigInt()
}
- private epochSince(length: bigint, index: bigint, number: bigint): bigint {
+ private static epochSince(length: bigint, index: bigint, number: bigint): bigint {
return (BigInt(0x20) << BigInt(56)) + (length << BigInt(40)) + (index << BigInt(24)) + number
}
- private parseEpoch(epoch: bigint) {
- return {
- length: (epoch >> BigInt(40)) & BigInt(0xffff),
- index: (epoch >> BigInt(24)) & BigInt(0xffff),
- number: epoch & BigInt(0xffffff),
- }
- }
-
private static getMultisigParamsHex(v: number) {
if (v < 0 || v > 255) {
throw new MultisigPrefixError()
diff --git a/packages/neuron-wallet/src/services/tx/transaction-generator.ts b/packages/neuron-wallet/src/services/tx/transaction-generator.ts
index 3164d353cc..78746dc8b5 100644
--- a/packages/neuron-wallet/src/services/tx/transaction-generator.ts
+++ b/packages/neuron-wallet/src/services/tx/transaction-generator.ts
@@ -212,7 +212,7 @@ export class TransactionGenerator {
if (date) {
const blake160 = lockScript.args
const minutes: number = +((BigInt(date) - BigInt(tipHeaderTimestamp)) / BigInt(1000 * 60)).toString()
- const script = SystemScriptInfo.generateMultiSignScript(new Multisig().args(blake160, +minutes, tipHeaderEpoch))
+ const script = SystemScriptInfo.generateMultiSignScript(Multisig.args(blake160, +minutes, tipHeaderEpoch))
output.setLock(script)
output.setMultiSignBlake160(script.args.slice(0, 42))
}
@@ -333,7 +333,7 @@ export class TransactionGenerator {
const blake160 = lockScript.args
const minutes: number = +((BigInt(date) - BigInt(tipHeaderTimestamp)) / BigInt(1000 * 60)).toString()
const script: Script = SystemScriptInfo.generateMultiSignScript(
- new Multisig().args(blake160, minutes, tipHeaderEpoch)
+ Multisig.args(blake160, minutes, tipHeaderEpoch)
)
output.setLock(script)
output.setMultiSignBlake160(script.args.slice(0, 42))
@@ -625,7 +625,7 @@ export class TransactionGenerator {
lock: lockScript,
})
- const since = new Multisig().parseSince(prevOutput.lock.args)
+ const since = Multisig.parseSince(prevOutput.lock.args)
const input = new Input(outPoint, since.toString(), prevOutput.capacity, prevOutput.lock)
const tx = Transaction.fromObject({
diff --git a/packages/neuron-wallet/tests/models/multi-sign.test.ts b/packages/neuron-wallet/tests/models/multi-sign.test.ts
index bf9416a94b..97fe34b0e6 100644
--- a/packages/neuron-wallet/tests/models/multi-sign.test.ts
+++ b/packages/neuron-wallet/tests/models/multi-sign.test.ts
@@ -15,13 +15,13 @@ describe('MultiSign Test', () => {
const serialized = '0x0000010136c329ed630d6ce750712a477543672adab57f4c'
it('since', () => {
- const since = new Multisig().since(minutes, headerEpoch)
+ const since = Multisig.since(minutes, headerEpoch)
expect(since).toEqual(expectedSince)
})
it('since, minutes < 0', () => {
expect(() => {
- new Multisig().since(-1, headerEpoch)
+ Multisig.since(-1, headerEpoch)
}).toThrowError()
})
@@ -47,7 +47,7 @@ describe('MultiSign Test', () => {
})
it('args', () => {
- const args = new Multisig().args(bob.blake160, minutes, headerEpoch)
+ const args = Multisig.args(bob.blake160, minutes, headerEpoch)
expect(args).toEqual(expectedArgs)
})
})
diff --git a/packages/neuron-wallet/tests/services/cells.test.ts b/packages/neuron-wallet/tests/services/cells.test.ts
index 8d3dcd17d1..813a373f69 100644
--- a/packages/neuron-wallet/tests/services/cells.test.ts
+++ b/packages/neuron-wallet/tests/services/cells.test.ts
@@ -1676,7 +1676,7 @@ describe('CellsService', () => {
'61',
OutputStatus.Sent,
false,
- SystemScriptInfo.generateMultiSignScript(new Multisig().args(bob.blake160, +10, '0x7080291000049'))
+ SystemScriptInfo.generateMultiSignScript(Multisig.args(bob.blake160, +10, '0x7080291000049'))
)
await expect(CellsService.getLiveOrSentCellByWalletId(bob.walletId)).resolves.toHaveLength(1)
})
@@ -1718,7 +1718,7 @@ describe('CellsService', () => {
it('MULTI_LOCK_TIME', () => {
const output = Output.fromObject({
capacity: '1000',
- lock: SystemScriptInfo.generateMultiSignScript(new Multisig().args(bob.blake160, +10, '0x7080291000049')),
+ lock: SystemScriptInfo.generateMultiSignScript(Multisig.args(bob.blake160, +10, '0x7080291000049')),
})
expect(CellsService.getCellLockType(output)).toBe(LockScriptCategory.MULTI_LOCK_TIME)
})
diff --git a/packages/neuron-wallet/tests/services/tx/transaction-generator.test.ts b/packages/neuron-wallet/tests/services/tx/transaction-generator.test.ts
index 3644000e9d..c5217e5f11 100644
--- a/packages/neuron-wallet/tests/services/tx/transaction-generator.test.ts
+++ b/packages/neuron-wallet/tests/services/tx/transaction-generator.test.ts
@@ -1,4 +1,5 @@
import { when } from 'jest-when'
+import { since } from '@ckb-lumos/base'
import { bytes } from '@ckb-lumos/codec'
import OutputEntity from '../../../src/database/chain/entities/output'
import InputEntity from '../../../src/database/chain/entities/input'
@@ -470,13 +471,11 @@ describe('TransactionGenerator', () => {
const multiSignOutput = tx.outputs.find(o => o.lock.codeHash === SystemScriptInfo.MULTI_SIGN_CODE_HASH)
expect(multiSignOutput).toBeDefined()
- const multiSign = new Multisig()
- const epoch = multiSign.parseSince(multiSignOutput!.lock.args)
- // @ts-ignore: Private method
- const parsedEpoch = multiSign.parseEpoch(epoch)
- expect(parsedEpoch.number).toEqual(BigInt(5))
- expect(parsedEpoch.length).toEqual(BigInt(240))
- expect(parsedEpoch.index).toEqual(BigInt(43))
+ const epoch = Multisig.parseSince(multiSignOutput!.lock.args)
+ const parsedEpoch = since.parseEpoch(epoch)
+ expect(parsedEpoch.number).toEqual(5)
+ expect(parsedEpoch.length).toEqual(240)
+ expect(parsedEpoch.index).toEqual(43)
})
})
})
@@ -733,13 +732,11 @@ describe('TransactionGenerator', () => {
expect(tx.outputs[0].lock.codeHash).toEqual(SystemScriptInfo.MULTI_SIGN_CODE_HASH)
- const multiSign = new Multisig()
- const epoch = multiSign.parseSince(tx.outputs[0].lock.args)
- // @ts-ignore: Private method
- const parsedEpoch = multiSign.parseEpoch(epoch)
- expect(parsedEpoch.number).toEqual(BigInt(5))
- expect(parsedEpoch.length).toEqual(BigInt(240))
- expect(parsedEpoch.index).toEqual(BigInt(43))
+ const epoch = Multisig.parseSince(tx.outputs[0].lock.args)
+ const parsedEpoch = since.parseEpoch(epoch)
+ expect(parsedEpoch.number).toEqual(5)
+ expect(parsedEpoch.length).toEqual(240)
+ expect(parsedEpoch.index).toEqual(43)
})
})
@@ -1045,7 +1042,7 @@ describe('TransactionGenerator', () => {
describe('generateWithdrawMultiSignTx', () => {
const prevOutput = Output.fromObject({
capacity: toShannon('1000'),
- lock: SystemScriptInfo.generateMultiSignScript(new Multisig().args(bob.lockScript.args, 100, '0x7080018000001')),
+ lock: SystemScriptInfo.generateMultiSignScript(Multisig.args(bob.lockScript.args, 100, '0x7080018000001')),
})
const outPoint = OutPoint.fromObject({
txHash: '0x' + '0'.repeat(64),
From a54408074c61886e6f220b1d2474049f80ef9df4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=A5=E5=9B=BD=E5=AE=87?= <841185308@qq.com>
Date: Fri, 24 May 2024 15:10:47 +0800
Subject: [PATCH 04/10] Merge master into dev (#3168)
* chore: Update ckb node assume valid target for rc/v0.116.0.
* chore: update versions and changelogs
* fix: Use hex to avoid unexpected string. (#3162)
* fix: Use lumos to init Buffer (#3164)
* Update Neuron compatibility table (#3158)
feat: Update Neuron compatibility table
Co-authored-by: Keith-CY
* fix: amend transaction when consume cells (#3166)
* docs: add video introduction to v0.116.0 in changelog
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Chen Yu
Co-authored-by: Keith-CY
Co-authored-by: devchenyan
---
CHANGELOG.md | 36 +++++++++++++++++++
compatible.json | 16 +++++++++
lerna.json | 2 +-
package.json | 2 +-
packages/neuron-ui/package.json | 2 +-
.../src/components/AmendSend/index.tsx | 31 +++++++++++-----
packages/neuron-wallet/.env | 4 +--
packages/neuron-wallet/package.json | 4 +--
.../neuron-wallet/src/controllers/wallets.ts | 4 +--
.../neuron-wallet/src/services/settings.ts | 5 ++-
.../src/services/sign-message.ts | 5 +--
11 files changed, 90 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a35aea95a9..3c71658c54 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,39 @@
+# 0.116.0 (2024-05-24)
+
+### CKB Node & Light Client
+
+- [CKB@v0.116.1](https://github.com/nervosnetwork/ckb/releases/tag/v0.116.1) was released on May. 11st, 2024. This version of CKB node is now bundled and preconfigured in Neuron.
+- [CKB Light Client@v0.3.7](https://github.com/nervosnetwork/ckb-light-client/releases/tag/v0.3.7) was released on Apr. 13th, 2024. This version of CKB Light Client is now bundled and preconfigured in Neuron
+
+### Assumed valid target
+
+Block before `0x6dd077b407d019a0bce0cbad8c34e69a524ae4b2599b9feda2c7491f3559d32c`(at height `13,007,704`) will be skipped in validation.(https://github.com/nervosnetwork/neuron/pull/3157)
+
+---
+
+[](https://youtu.be/QXv8by2C8zU)
+
+YouTube: https://youtu.be/QXv8by2C8zU
+
+---
+
+## New features
+
+- 3134: Support 'replace-by-fee' nervos dao transactions and sudt transactions.(@devchenyan)
+- 3144: Reduce size of light client log in debug information and reveal start-block-number in log.(@yanguoyu)
+- 3064: Support locking window by pin code.(@yanguoyu)
+- 3131: Add detailed result for nervos dao transaction.(@devchenyan)
+
+## Bug fixes
+
+- 3121: Locate the first transaction on Explorer directly when users want to set the start-block-number for light client.(@yanguoyu)
+- 3101: Show migration instruction properly.(@devchenyan)
+- 3062: Migrate legacy ACP to active ACP account(@yanguoyu)
+- 3141: Fix some issues about light client synchronizaiton.(@yanguoyu)
+- 3120: Remove all sync data when start-block-number is set less than before.(@yanguoyu)
+
+**Full Changelog**: https://github.com/nervosnetwork/neuron/compare/v0.114.3...v0.116.0
+
# 0.114.3 (2024-04-16)
### CKB Node & Light Client
diff --git a/compatible.json b/compatible.json
index 028ff3cb04..b2865b7a18 100644
--- a/compatible.json
+++ b/compatible.json
@@ -99,6 +99,22 @@
"0.3",
"0.2"
]
+ },
+ "0.116": {
+ "full": [
+ "0.116",
+ "0.115",
+ "0.114",
+ "0.113",
+ "0.112",
+ "0.111",
+ "0.110",
+ "0.109"
+ ],
+ "light": [
+ "0.3",
+ "0.2"
+ ]
}
}
}
diff --git a/lerna.json b/lerna.json
index 0e77734cb4..922158bfd4 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,6 +1,6 @@
{
"packages": ["packages/*"],
- "version": "0.114.3",
+ "version": "0.116.0",
"npmClient": "yarn",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
diff --git a/package.json b/package.json
index 62c7a5ad1b..e8c55808df 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "neuron",
"productName": "Neuron",
"description": "CKB Neuron Wallet",
- "version": "0.114.3",
+ "version": "0.116.0",
"private": true,
"author": {
"name": "Nervos Core Dev",
diff --git a/packages/neuron-ui/package.json b/packages/neuron-ui/package.json
index 5c6ce190e1..b98ed97822 100644
--- a/packages/neuron-ui/package.json
+++ b/packages/neuron-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "neuron-ui",
- "version": "0.114.3",
+ "version": "0.116.0",
"private": true,
"author": {
"name": "Nervos Core Dev",
diff --git a/packages/neuron-ui/src/components/AmendSend/index.tsx b/packages/neuron-ui/src/components/AmendSend/index.tsx
index 92eb75675d..7ba3873d1e 100644
--- a/packages/neuron-ui/src/components/AmendSend/index.tsx
+++ b/packages/neuron-ui/src/components/AmendSend/index.tsx
@@ -96,6 +96,15 @@ const AmendSend = () => {
return ''
}
+ const inputsCapacity = useMemo(() => {
+ if (transaction) {
+ return transaction.inputs.reduce((total, cur) => {
+ return total + BigInt(cur.capacity || '0')
+ }, BigInt(0))
+ }
+ return undefined
+ }, [transaction])
+
const items: {
address: string
amount: string
@@ -103,21 +112,25 @@ const AmendSend = () => {
isLastOutput: boolean
output: State.DetailedOutput
}[] = useMemo(() => {
- if (transaction && transaction.outputs.length) {
+ if (transaction && transaction.outputs.length && inputsCapacity) {
const lastOutputAddress = getLastOutputAddress(transaction.outputs)
return transaction.outputs.map(output => {
const address = scriptToAddress(output.lock, { isMainnet })
+ const capacity =
+ transaction.outputs.length === 1 && address === lastOutputAddress
+ ? (inputsCapacity - fee).toString()
+ : output.capacity
return {
- capacity: output.capacity,
+ capacity,
address,
output,
- amount: shannonToCKBFormatter(output.capacity || '0'),
+ amount: shannonToCKBFormatter(capacity || '0'),
isLastOutput: address === lastOutputAddress,
}
})
}
return []
- }, [transaction?.outputs])
+ }, [transaction?.outputs, inputsCapacity, fee])
const outputsCapacity = useMemo(() => {
const outputList = items.length === 1 ? items : items.filter(item => !item.isLastOutput)
@@ -129,15 +142,15 @@ const AmendSend = () => {
const totalAmount = shannonToCKBFormatter(outputsCapacity.toString())
const lastOutputsCapacity = useMemo(() => {
- if (transaction) {
- const inputsCapacity = transaction.inputs.reduce((total, cur) => {
- return total + BigInt(cur.capacity || '0')
- }, BigInt(0))
+ if (inputsCapacity) {
+ if (items.length === 1) {
+ return BigInt(items[0].capacity || '0')
+ }
return inputsCapacity - outputsCapacity - fee
}
return undefined
- }, [transaction, fee, outputsCapacity])
+ }, [inputsCapacity, fee, outputsCapacity, items])
useEffect(() => {
if (transaction && lastOutputsCapacity !== undefined) {
diff --git a/packages/neuron-wallet/.env b/packages/neuron-wallet/.env
index f32862920f..3c4d9296b8 100644
--- a/packages/neuron-wallet/.env
+++ b/packages/neuron-wallet/.env
@@ -117,5 +117,5 @@ DAO_CODE_HASH=0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e
MULTISIG_CODE_HASH=0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8
# CKB NODE OPTIONS
-CKB_NODE_ASSUME_VALID_TARGET='0x9443ad8da9172d484367bc5467988cba7a0c46028398309edfdda7d2d79be897'
-CKB_NODE_DATA_SIZE=53
+CKB_NODE_ASSUME_VALID_TARGET='0x6dd077b407d019a0bce0cbad8c34e69a524ae4b2599b9feda2c7491f3559d32c'
+CKB_NODE_DATA_SIZE=54
diff --git a/packages/neuron-wallet/package.json b/packages/neuron-wallet/package.json
index 77479adeae..cad2f98bff 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.114.3",
+ "version": "0.116.0",
"private": true,
"author": {
"name": "Nervos Core Dev",
@@ -97,7 +97,7 @@
"electron-builder": "24.9.1",
"electron-devtools-installer": "3.2.0",
"jest-when": "3.6.0",
- "neuron-ui": "0.114.3",
+ "neuron-ui": "0.116.0",
"typescript": "5.3.3"
}
}
diff --git a/packages/neuron-wallet/src/controllers/wallets.ts b/packages/neuron-wallet/src/controllers/wallets.ts
index 29bff5030e..db66030bfa 100644
--- a/packages/neuron-wallet/src/controllers/wallets.ts
+++ b/packages/neuron-wallet/src/controllers/wallets.ts
@@ -168,8 +168,8 @@ export default class WalletsController {
const keystoreObject = Keystore.fromJson(keystore)
const masterPrivateKey = keystoreObject.extendedPrivateKey(password)
const masterKeychain = new Keychain(
- Buffer.from(masterPrivateKey.privateKey, 'hex'),
- Buffer.from(masterPrivateKey.chainCode, 'hex')
+ Buffer.from(bytes.bytify(masterPrivateKey.privateKey)),
+ Buffer.from(bytes.bytify(masterPrivateKey.chainCode))
)
const accountKeychain = masterKeychain.derivePath(AccountExtendedPublicKey.ckbAccountPath)
const accountExtendedPublicKey = new AccountExtendedPublicKey(
diff --git a/packages/neuron-wallet/src/services/settings.ts b/packages/neuron-wallet/src/services/settings.ts
index d482390249..f836ba5e0e 100644
--- a/packages/neuron-wallet/src/services/settings.ts
+++ b/packages/neuron-wallet/src/services/settings.ts
@@ -88,7 +88,7 @@ export default class SettingsService extends Store {
private generateEncryptString(str: string) {
if (safeStorage.isEncryptionAvailable()) {
- return safeStorage.encryptString(str).toString('utf-8')
+ return safeStorage.encryptString(str).toString('hex')
}
const hash = crypto.createHash('sha256')
hash.update(str)
@@ -108,6 +108,9 @@ export default class SettingsService extends Store {
}
verifyLockWindowPassword(password: string) {
+ if (safeStorage.isEncryptionAvailable()) {
+ return safeStorage.decryptString(Buffer.from(this.lockWindowInfo.encryptedPassword!, 'hex')) === password
+ }
const encryptedPassword = this.generateEncryptString(password)
return SettingsService.getInstance().lockWindowInfo.encryptedPassword === encryptedPassword
}
diff --git a/packages/neuron-wallet/src/services/sign-message.ts b/packages/neuron-wallet/src/services/sign-message.ts
index 8d3bfd562d..aeaf32dca7 100644
--- a/packages/neuron-wallet/src/services/sign-message.ts
+++ b/packages/neuron-wallet/src/services/sign-message.ts
@@ -6,6 +6,7 @@ import { ec as EC } from 'elliptic'
import { AddressNotFound } from '../exceptions'
import HardwareWalletService from './hardware'
import AddressParser from '../models/address-parser'
+import { bytes } from '@ckb-lumos/codec'
export default class SignMessage {
static GENERATE_COUNT = 100
@@ -91,8 +92,8 @@ export default class SignMessage {
private static getPrivateKey(wallet: Wallet, path: string, password: string): string {
const masterPrivateKey = wallet.loadKeystore().extendedPrivateKey(password)
const masterKeychain = new Keychain(
- Buffer.from(masterPrivateKey.privateKey, 'hex'),
- Buffer.from(masterPrivateKey.chainCode, 'hex')
+ Buffer.from(bytes.bytify(masterPrivateKey.privateKey)),
+ Buffer.from(bytes.bytify(masterPrivateKey.chainCode))
)
return `0x${masterKeychain.derivePath(path).privateKey.toString('hex')}`
From bed901be78d39e3edcf15032c6bacc44c8d9023e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=A5=E5=9B=BD=E5=AE=87?= <841185308@qq.com>
Date: Fri, 24 May 2024 15:21:08 +0800
Subject: [PATCH 05/10] fix: Replace `Asset` to `Amount` and better 'Asset'
data format (#3151)
fix: Replace `Asset` to `Amount`
---
.../components/FormattedTokenAmount/index.tsx | 24 +++++++-----
.../src/components/History/index.tsx | 2 +-
.../src/components/Overview/index.tsx | 2 +-
packages/neuron-ui/src/locales/en.json | 4 +-
packages/neuron-ui/src/locales/es.json | 4 +-
packages/neuron-ui/src/locales/fr.json | 4 +-
packages/neuron-ui/src/locales/zh-tw.json | 4 +-
packages/neuron-ui/src/locales/zh.json | 4 +-
packages/neuron-ui/src/types/App/index.d.ts | 1 +
.../src/models/chain/transaction.ts | 11 +++++-
.../src/services/tx/transaction-service.ts | 38 ++++++++++++++++---
11 files changed, 69 insertions(+), 29 deletions(-)
diff --git a/packages/neuron-ui/src/components/FormattedTokenAmount/index.tsx b/packages/neuron-ui/src/components/FormattedTokenAmount/index.tsx
index 4a180ba15f..b31da32d3c 100644
--- a/packages/neuron-ui/src/components/FormattedTokenAmount/index.tsx
+++ b/packages/neuron-ui/src/components/FormattedTokenAmount/index.tsx
@@ -12,7 +12,7 @@ type FormattedTokenAmountProps = { item: State.Transaction; show: boolean; symbo
type AmountProps = Omit & {
sudtAmount?: string
isReceive: boolean
- amount: string
+ amount?: string
symbolClassName?: string
}
@@ -30,18 +30,18 @@ const Amount = ({ sudtAmount, show, item, isReceive, amount, symbolClassName, sy
) : (
-
- {amount}
+
+ {amount ?? '--'}
- {symbol}
+ {amount ? symbol : ''}
)
}
export const FormattedTokenAmount = ({ item, show, symbolClassName }: FormattedTokenAmountProps) => {
- let amount = '--'
+ let amount: string | undefined
let sudtAmount = ''
- let copyText = amount
+ let copyText: string | undefined = amount
let isReceive = false
let symbol = ''
@@ -61,16 +61,22 @@ export const FormattedTokenAmount = ({ item, show, symbolClassName }: FormattedT
isReceive = !sudtAmount.includes('-')
}
} else {
- amount = show ? `${shannonToCKBFormatter(item.value, true)}` : `${HIDE_BALANCE}`
- isReceive = !amount.includes('-')
+ amount = show
+ ? `${shannonToCKBFormatter(item.nervosDao ? item.daoCapacity ?? '--' : item.value, true)}`
+ : `${HIDE_BALANCE}`
+ isReceive = !amount?.includes('-')
copyText = `${amount} CKB`
symbol = 'CKB'
+ if (item.nervosDao && item.daoCapacity === undefined) {
+ amount = undefined
+ copyText = undefined
+ }
}
}
const props = { sudtAmount, show, item, isReceive, amount, symbolClassName, symbol }
- return show ? (
+ return show && copyText ? (
diff --git a/packages/neuron-ui/src/components/History/index.tsx b/packages/neuron-ui/src/components/History/index.tsx
index 6e1f19c2d3..f012415c87 100644
--- a/packages/neuron-ui/src/components/History/index.tsx
+++ b/packages/neuron-ui/src/components/History/index.tsx
@@ -126,7 +126,7 @@ const History = () => {
sortable: true,
},
{
- title: t('history.table.amount'),
+ title: t('history.table.asset'),
dataIndex: 'amount',
align: 'left',
isBalance: true,
diff --git a/packages/neuron-ui/src/components/Overview/index.tsx b/packages/neuron-ui/src/components/Overview/index.tsx
index 9ce1a0a94b..2aaf350574 100644
--- a/packages/neuron-ui/src/components/Overview/index.tsx
+++ b/packages/neuron-ui/src/components/Overview/index.tsx
@@ -268,7 +268,7 @@ const Overview = () => {
},
},
{
- title: t('overview.amount'),
+ title: t('overview.asset'),
dataIndex: 'amount',
align: 'left',
isBalance: true,
diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json
index 2a90be36e6..1842c982ef 100644
--- a/packages/neuron-ui/src/locales/en.json
+++ b/packages/neuron-ui/src/locales/en.json
@@ -142,7 +142,7 @@
"activity": "Activity",
"datetime": "Date & Time",
"status": "Status",
- "amount": "Amount",
+ "asset": "Asset",
"address": "Address",
"sent": "Sent",
"sending": "Sending",
@@ -313,7 +313,7 @@
"name": "Wallet Name",
"type": "Type",
"balance": "Balance",
- "amount": "Amount",
+ "asset": "Asset",
"timestamp": "Time",
"status": "Status",
"operation": "Operation"
diff --git a/packages/neuron-ui/src/locales/es.json b/packages/neuron-ui/src/locales/es.json
index 8c35cae3c0..3ac8e1f57f 100644
--- a/packages/neuron-ui/src/locales/es.json
+++ b/packages/neuron-ui/src/locales/es.json
@@ -135,7 +135,7 @@
"activity": "Actividad",
"datetime": "Fecha y Hora",
"status": "Estado",
- "amount": "Cantidad",
+ "asset": "Activos",
"address": "Dirección",
"sent": "Enviado",
"sending": "Enviando",
@@ -305,7 +305,7 @@
"name": "Nombre de la Billetera",
"type": "Tipo",
"balance": "Saldo",
- "amount": "Cantidad",
+ "asset": "activos",
"timestamp": "Tiempo",
"status": "Estado",
"operation": "Operación"
diff --git a/packages/neuron-ui/src/locales/fr.json b/packages/neuron-ui/src/locales/fr.json
index ae9db42555..a609830ca1 100644
--- a/packages/neuron-ui/src/locales/fr.json
+++ b/packages/neuron-ui/src/locales/fr.json
@@ -142,7 +142,7 @@
"activity": "Activité",
"datetime": "Date et heure",
"status": "Statut",
- "amount": "Montant",
+ "asset": "actifs",
"address": "Adresse",
"sent": "Envoyé",
"sending": "Envoi",
@@ -312,7 +312,7 @@
"name": "Nom du Wallet",
"type": "Type",
"balance": "Solde",
- "amount": "Montant",
+ "asset": "actifs",
"timestamp": "Heure",
"status": "Statut",
"operation": "Opération"
diff --git a/packages/neuron-ui/src/locales/zh-tw.json b/packages/neuron-ui/src/locales/zh-tw.json
index 76946f85f3..8e61fb1c5d 100644
--- a/packages/neuron-ui/src/locales/zh-tw.json
+++ b/packages/neuron-ui/src/locales/zh-tw.json
@@ -136,7 +136,7 @@
"activity": "收支活動",
"datetime": "時間",
"status": "狀態",
- "amount": "金額",
+ "asset": "資產",
"address": "地址",
"sent": "已發送",
"sending": "正在發送",
@@ -308,7 +308,7 @@
"name": "錢包名稱",
"type": "類型",
"balance": "余額",
- "amount": "金額",
+ "asset": "資產",
"timestamp": "時間",
"status": "狀態",
"operation": "操作"
diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json
index 55109b76e9..d0ad40e458 100644
--- a/packages/neuron-ui/src/locales/zh.json
+++ b/packages/neuron-ui/src/locales/zh.json
@@ -135,7 +135,7 @@
"activity": "收支活动",
"datetime": "时间",
"status": "状态",
- "amount": "金额",
+ "asset": "资产",
"address": "地址",
"sent": "已发送",
"sending": "正在发送",
@@ -306,7 +306,7 @@
"name": "钱包名称",
"type": "类型",
"balance": "余额",
- "amount": "金额",
+ "asset": "资产",
"timestamp": "时间",
"status": "状态",
"operation": "操作"
diff --git a/packages/neuron-ui/src/types/App/index.d.ts b/packages/neuron-ui/src/types/App/index.d.ts
index 76ce82827b..e9902f710c 100644
--- a/packages/neuron-ui/src/types/App/index.d.ts
+++ b/packages/neuron-ui/src/types/App/index.d.ts
@@ -19,6 +19,7 @@ declare namespace State {
data: string
}
assetAccountType?: 'CKB' | 'sUDT' | string
+ daoCapacity?: string
}
interface DetailedInput {
diff --git a/packages/neuron-wallet/src/models/chain/transaction.ts b/packages/neuron-wallet/src/models/chain/transaction.ts
index 1f4a0d1223..a8942bb43c 100644
--- a/packages/neuron-wallet/src/models/chain/transaction.ts
+++ b/packages/neuron-wallet/src/models/chain/transaction.ts
@@ -82,6 +82,8 @@ export default class Transaction {
public signatures: Signatures = {}
public assetAccountType?: AssetAccountType
+ public daoCapacity?: string
+
constructor(
version: string,
cellDeps: CellDep[] = [],
@@ -106,7 +108,8 @@ export default class Transaction {
sudtInfo?: SudtInfo,
nftType?: NFTInfo,
signatures: Signatures = {},
- assetAccountType?: AssetAccountType
+ assetAccountType?: AssetAccountType,
+ daoCapacity?: string
) {
this.cellDeps = cellDeps
this.headerDeps = headerDeps
@@ -133,6 +136,7 @@ export default class Transaction {
this.sudtInfo = sudtInfo
this.nftInfo = nftType
this.signatures = signatures
+ this.daoCapacity = daoCapacity
TypeCheckerUtils.hashChecker(...this.headerDeps, this.blockHash)
TypeCheckerUtils.numberChecker(
this.version,
@@ -171,6 +175,7 @@ export default class Transaction {
nftInfo,
signatures = {},
assetAccountType,
+ daoCapacity,
}: {
version: string
cellDeps?: CellDep[]
@@ -196,6 +201,7 @@ export default class Transaction {
nftInfo?: NFTInfo
signatures?: Signatures
assetAccountType?: AssetAccountType
+ daoCapacity?: string
}): Transaction {
return new Transaction(
version,
@@ -226,7 +232,8 @@ export default class Transaction {
sudtInfo,
nftInfo,
signatures,
- assetAccountType
+ assetAccountType,
+ daoCapacity
)
}
diff --git a/packages/neuron-wallet/src/services/tx/transaction-service.ts b/packages/neuron-wallet/src/services/tx/transaction-service.ts
index eb5cf93dd3..8b43057ed9 100644
--- a/packages/neuron-wallet/src/services/tx/transaction-service.ts
+++ b/packages/neuron-wallet/src/services/tx/transaction-service.ts
@@ -256,6 +256,7 @@ export class TransactionsService {
.addSelect('input.transactionHash', 'transactionHash')
.addSelect('input.outPointTxHash', 'outPointTxHash')
.addSelect('input.outPointIndex', 'outPointIndex')
+ .addSelect('input.data', 'data')
.where(
`
input.transactionHash IN (:...txHashes) AND
@@ -266,7 +267,13 @@ export class TransactionsService {
walletId: params.walletID,
}
)
- .getRawMany()
+ .getRawMany<{
+ capacity: string
+ transactionHash: string
+ outPointTxHash: string
+ outPointIndex: string
+ data: string
+ }>()
const outputs = await connection
.getRepository(OutputEntity)
@@ -284,7 +291,7 @@ export class TransactionsService {
walletId: params.walletID,
}
)
- .getRawMany()
+ .getRawMany<{ capacity: string; transactionHash: string; daoData: string }>()
const assetAccountInputs = await connection
.getRepository(InputEntity)
@@ -373,13 +380,17 @@ export class TransactionsService {
).filter(o => inputPreviousTxHashes.includes(o.txHash))
const sums = new Map()
- const daoFlag = new Map()
+ const daoInfo = new Map()
outputs.map(o => {
const s = sums.get(o.transactionHash) || BigInt(0)
sums.set(o.transactionHash, s + BigInt(o.capacity))
if (o.daoData) {
- daoFlag.set(o.transactionHash, true)
+ if (daoInfo.has(o.transactionHash)) {
+ daoInfo.get(o.transactionHash)!.outputs.push(o)
+ } else {
+ daoInfo.set(o.transactionHash, { inputs: [], outputs: [o] })
+ }
}
})
@@ -391,7 +402,11 @@ export class TransactionsService {
return dc.txHash === i.outPointTxHash && dc.index === i.outPointIndex
})
if (result) {
- daoFlag.set(i.transactionHash, true)
+ if (daoInfo.has(i.transactionHash)) {
+ daoInfo.get(i.transactionHash)!.inputs.push(i)
+ } else {
+ daoInfo.set(i.transactionHash, { inputs: [i], outputs: [] })
+ }
}
})
@@ -477,6 +492,16 @@ export class TransactionsService {
nftInfo = { type: NFTType.Receive, data: receiveNFTCell.typeArgs! }
}
+ const txDaoInfo = daoInfo.get(tx.hash)
+ let daoCapacity: string | undefined
+ if (txDaoInfo) {
+ if (txDaoInfo.inputs.length && !txDaoInfo.outputs.length) {
+ daoCapacity = txDaoInfo.inputs.reduce((pre, cur) => BigInt(cur.capacity) + pre, BigInt(value)).toString()
+ } else if (!txDaoInfo.inputs.length && txDaoInfo.outputs.length) {
+ daoCapacity = `-${txDaoInfo.outputs.reduce((pre, cur) => BigInt(cur.capacity) + pre, BigInt(0)).toString()}`
+ }
+ }
+
return Transaction.fromObject({
timestamp: tx.timestamp,
value: value.toString(),
@@ -484,7 +509,7 @@ export class TransactionsService {
version: tx.version,
type: txType,
assetAccountType: assetAccountType,
- nervosDao: daoFlag.get(tx.hash!),
+ nervosDao: !!txDaoInfo,
status: tx.status,
description: tx.description,
createdAt: tx.createdAt,
@@ -492,6 +517,7 @@ export class TransactionsService {
blockNumber: tx.blockNumber,
sudtInfo: sudtInfo,
nftInfo: nftInfo,
+ daoCapacity,
})
})
)
From b44892adf2784a7e58b99e83defac134c9862dd0 Mon Sep 17 00:00:00 2001
From: Tom Wang
Date: Mon, 27 May 2024 10:51:11 +0800
Subject: [PATCH 06/10] refactor: replace LumosCell, LumosCellQuery with Cell,
QueryOptions (#3163)
* refactor: replace LumosCell, LumosCellQuery with Cell, QueryOptions
* refactor: use type CellWithOutPoint for live cells data
---
.../src/block-sync-renderer/index.ts | 6 ++--
.../block-sync-renderer/sync/synchronizer.ts | 36 +++----------------
.../src/block-sync-renderer/task.ts | 4 +--
.../src/models/chain/live-cell.ts | 6 ++--
.../src/services/live-cell-service.ts | 12 +++----
.../block-sync-renderer/synchronizer.test.ts | 34 +++++++++---------
.../tests/models/chain/live-cell.test.ts | 5 ++-
.../services/tx/transaction-generator.test.ts | 14 ++++----
8 files changed, 44 insertions(+), 73 deletions(-)
diff --git a/packages/neuron-wallet/src/block-sync-renderer/index.ts b/packages/neuron-wallet/src/block-sync-renderer/index.ts
index cf690f014b..19b0394649 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/index.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/index.ts
@@ -9,7 +9,7 @@ import DataUpdateSubject from '../models/subjects/data-update'
import AddressCreatedSubject from '../models/subjects/address-created-subject'
import WalletDeletedSubject from '../models/subjects/wallet-deleted-subject'
import TxDbChangedSubject from '../models/subjects/tx-db-changed-subject'
-import { LumosCellQuery, LumosCell } from './sync/synchronizer'
+import { type Cell, type QueryOptions } from '@ckb-lumos/base'
import { WorkerMessage, StartParams, QueryIndexerParams } from './task'
import logger from '../utils/logger'
import CommonUtils from '../utils/common'
@@ -88,7 +88,7 @@ export const switchToNetwork = async (newNetwork: Network, reconnected = false,
await resetSyncTaskQueue.asyncPush(shouldSync)
}
-export const queryIndexer = async (query: LumosCellQuery): Promise => {
+export const queryIndexer = async (query: QueryOptions): Promise => {
const _child = child
if (!_child) {
return []
@@ -102,7 +102,7 @@ export const queryIndexer = async (query: LumosCellQuery): Promise
return registerRequest(_child, msg).catch(err => {
logger.error(`Sync:\tfailed to register query indexer task`, err)
return []
- }) as Promise
+ }) as Promise|
}
export const createBlockSyncTask = async () => {
diff --git a/packages/neuron-wallet/src/block-sync-renderer/sync/synchronizer.ts b/packages/neuron-wallet/src/block-sync-renderer/sync/synchronizer.ts
index b8d1a789a2..01fcfa3a12 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/sync/synchronizer.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/sync/synchronizer.ts
@@ -1,7 +1,7 @@
import { Subject } from 'rxjs'
import { queue, QueueObject } from 'async'
+import { type QueryOptions } from '@ckb-lumos/base'
import { Indexer as CkbIndexer, CellCollector } from '@ckb-lumos/ckb-indexer'
-import { QueryOptions } from '@ckb-lumos/base'
import AddressMeta from '../../database/address/meta'
import { Address } from '../../models/address'
import { SyncAddressType } from '../../database/chain/entities/sync-progress'
@@ -14,34 +14,6 @@ export interface BlockTips {
indexerTipNumber: number | undefined
}
-export interface LumosCellQuery {
- lock: CKBComponents.Script | null
- type: CKBComponents.Script | null
- data: string | null
-}
-
-export interface LumosCell {
- blockHash: string
- outPoint: {
- txHash: string
- index: string
- }
- cellOutput: {
- capacity: string
- lock: {
- codeHash: string
- args: string
- hashType: string
- }
- type?: {
- codeHash: string
- args: string
- hashType: string
- }
- }
- data?: string
-}
-
export interface AppendScript {
walletId: string
script: CKBComponents.Script
@@ -57,7 +29,7 @@ export abstract class Synchronizer {
protected processingBlockNumber?: string
protected addressesByWalletId: Map = new Map()
protected pollingIndexer: boolean = false
- private indexerQueryQueue: QueueObject | undefined
+ private indexerQueryQueue: QueueObject | undefined
protected _needGenerateAddress: boolean = false
abstract connect(): Promise
@@ -155,7 +127,7 @@ export abstract class Synchronizer {
return false
}
- public async getLiveCellsByScript(query: LumosCellQuery) {
+ public async getLiveCellsByScript(query: QueryOptions) {
return new Promise((resolve, reject) => {
this.indexerQueryQueue!.push(query, (err: any, result: unknown) => {
if (err) {
@@ -166,7 +138,7 @@ export abstract class Synchronizer {
})
}
- private async collectLiveCellsByScript(query: LumosCellQuery) {
+ private async collectLiveCellsByScript(query: QueryOptions) {
const { lock, type, data } = query
if (!lock && !type) {
throw new Error('at least one parameter is required')
diff --git a/packages/neuron-wallet/src/block-sync-renderer/task.ts b/packages/neuron-wallet/src/block-sync-renderer/task.ts
index e10291360e..4d5c4b9d5a 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/task.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/task.ts
@@ -1,4 +1,4 @@
-import type { LumosCellQuery } from './sync/synchronizer'
+import { type QueryOptions } from '@ckb-lumos/base'
import initConnection from '../database/chain/ormconfig'
import { register as registerTxStatusListener } from './tx-status-listener'
import SyncQueue from './sync/queue'
@@ -35,7 +35,7 @@ export interface StartParams {
nodeType: SyncQueueParams[3]
}
-export type QueryIndexerParams = LumosCellQuery
+export type QueryIndexerParams = QueryOptions
export const listener = async ({ type, id, channel, message }: WorkerMessage) => {
if (type === 'kill') {
diff --git a/packages/neuron-wallet/src/models/chain/live-cell.ts b/packages/neuron-wallet/src/models/chain/live-cell.ts
index c57fb25fed..9a7cda74a2 100644
--- a/packages/neuron-wallet/src/models/chain/live-cell.ts
+++ b/packages/neuron-wallet/src/models/chain/live-cell.ts
@@ -1,6 +1,6 @@
import Script, { ScriptHashType } from './script'
import OutPoint from './out-point'
-import { LumosCell } from '../../block-sync-renderer/sync/synchronizer'
+import { type Cell, type OutPoint as IOutPoint } from '@ckb-lumos/base'
const LUMOS_HASH_TYPE_MAP: Record = {
type: ScriptHashType.Type,
@@ -8,6 +8,8 @@ const LUMOS_HASH_TYPE_MAP: Record = {
data: ScriptHashType.Data,
}
+export type CellWithOutPoint = Cell & { outPoint: IOutPoint }
+
export default class LiveCell {
public txHash: string
public outputIndex: string
@@ -54,7 +56,7 @@ export default class LiveCell {
return undefined
}
- public static fromLumos(cell: LumosCell): LiveCell {
+ public static fromLumos(cell: CellWithOutPoint): LiveCell {
const type = cell.cellOutput.type
? new Script(
cell.cellOutput.type.codeHash,
diff --git a/packages/neuron-wallet/src/services/live-cell-service.ts b/packages/neuron-wallet/src/services/live-cell-service.ts
index 4b7766d3db..3fe38814a6 100644
--- a/packages/neuron-wallet/src/services/live-cell-service.ts
+++ b/packages/neuron-wallet/src/services/live-cell-service.ts
@@ -1,7 +1,7 @@
import Script from '../models/chain/script'
-import LiveCell from '../models/chain/live-cell'
+import LiveCell, { CellWithOutPoint } from '../models/chain/live-cell'
import { queryIndexer } from '../block-sync-renderer/index'
-import { LumosCell, LumosCellQuery } from '../block-sync-renderer/sync/synchronizer'
+import { type QueryOptions } from '@ckb-lumos/base'
export default class LiveCellService {
private static instance: LiveCellService
@@ -20,14 +20,14 @@ export default class LiveCellService {
lock: Script | null,
type: Script | null,
data: string | null
- ): Promise {
+ ): Promise {
if (!lock && !type) {
throw new Error('at least one parameter is required')
}
- const query: LumosCellQuery = { lock, type, data }
- const liveCells: LumosCell[] = await queryIndexer(query)
- return liveCells
+ const query = { lock, type, data } as QueryOptions
+ const liveCells = await queryIndexer(query)
+ return liveCells as CellWithOutPoint[]
}
public async getOneByLockScriptAndTypeScript(lock: Script | null, type: Script | null) {
diff --git a/packages/neuron-wallet/tests/block-sync-renderer/synchronizer.test.ts b/packages/neuron-wallet/tests/block-sync-renderer/synchronizer.test.ts
index c3c1e7e325..f237f7068d 100644
--- a/packages/neuron-wallet/tests/block-sync-renderer/synchronizer.test.ts
+++ b/packages/neuron-wallet/tests/block-sync-renderer/synchronizer.test.ts
@@ -1,8 +1,9 @@
import { scriptToAddress } from '../../src/utils/scriptAndAddress'
import { AddressType } from '@ckb-lumos/hd'
+import { QueryOptions, type Cell } from '@ckb-lumos/base'
import { Address, AddressVersion } from '../../src/models/address'
import SystemScriptInfo from '../../src/models/system-script-info'
-import { Synchronizer, type LumosCell, type LumosCellQuery } from '../../src/block-sync-renderer/sync/synchronizer'
+import { Synchronizer } from '../../src/block-sync-renderer/sync/synchronizer'
import AddressMeta from '../../src/database/address/meta'
import IndexerTxHashCache from '../../src/database/chain/entities/indexer-tx-hash-cache'
import { ScriptHashType } from '../../src/models/chain/script'
@@ -220,10 +221,11 @@ describe('unit tests for IndexerConnector', () => {
})
describe('#getLiveCellsByScript', () => {
- let fakeCell1: LumosCell, fakeCell2: LumosCell
- let cells: LumosCell[]
+ let fakeCell1: Cell, fakeCell2: Cell
+ let cells: Cell[]
fakeCell1 = {
+ data: '0x',
blockHash: '0x',
outPoint: {
txHash: '0x',
@@ -244,6 +246,7 @@ describe('unit tests for IndexerConnector', () => {
},
}
fakeCell2 = {
+ data: '0x',
blockHash: '0x',
outPoint: {
txHash: '0x',
@@ -257,7 +260,7 @@ describe('unit tests for IndexerConnector', () => {
args: '0x2',
},
type: {
- hashType: 'lock',
+ hashType: 'data',
codeHash: '0xcode',
args: '0x2',
},
@@ -272,7 +275,7 @@ describe('unit tests for IndexerConnector', () => {
})
describe('when success', () => {
- const query: LumosCellQuery = {
+ const query = {
lock: {
hashType: ScriptHashType.Data,
codeHash: '0xcode',
@@ -283,7 +286,6 @@ describe('unit tests for IndexerConnector', () => {
codeHash: '0xcode',
args: '0x',
},
- data: null,
}
beforeEach(async () => {
@@ -298,14 +300,14 @@ describe('unit tests for IndexerConnector', () => {
it('transform the query parameter', () => {
expect(stubbedCellCollectorConstructor.mock.calls[0][1]).toEqual({
lock: {
- hashType: query.lock!.hashType,
- codeHash: query.lock!.codeHash,
- args: query.lock!.args,
+ hashType: query.lock.hashType,
+ codeHash: query.lock.codeHash,
+ args: query.lock.args,
},
type: {
- hashType: query.type!.hashType,
- codeHash: query.type!.codeHash,
- args: query.type!.args,
+ hashType: query.type.hashType,
+ codeHash: query.type.codeHash,
+ args: query.type.args,
},
data: 'any',
})
@@ -316,7 +318,7 @@ describe('unit tests for IndexerConnector', () => {
})
})
describe('when handling concurrent requests', () => {
- const query1: LumosCellQuery = {
+ const query1: QueryOptions = {
lock: {
hashType: ScriptHashType.Data,
codeHash: '0xcode',
@@ -327,9 +329,8 @@ describe('unit tests for IndexerConnector', () => {
codeHash: '0xcode',
args: '0x1',
},
- data: null,
}
- const query2: LumosCellQuery = {
+ const query2: QueryOptions = {
lock: {
hashType: ScriptHashType.Type,
codeHash: '0xcode',
@@ -340,7 +341,6 @@ describe('unit tests for IndexerConnector', () => {
codeHash: '0xcode',
args: '0x2',
},
- data: null,
}
const results: unknown[] = []
@@ -401,7 +401,7 @@ describe('unit tests for IndexerConnector', () => {
it('throws error', async () => {
let err
try {
- await synchronizer.getLiveCellsByScript({ lock: null, type: null, data: null })
+ await synchronizer.getLiveCellsByScript({})
} catch (error) {
err = error
}
diff --git a/packages/neuron-wallet/tests/models/chain/live-cell.test.ts b/packages/neuron-wallet/tests/models/chain/live-cell.test.ts
index 84a9b97830..1bc5cba2fd 100644
--- a/packages/neuron-wallet/tests/models/chain/live-cell.test.ts
+++ b/packages/neuron-wallet/tests/models/chain/live-cell.test.ts
@@ -1,6 +1,5 @@
import Script, { ScriptHashType } from '../../../src/models/chain/script'
-import { LumosCell } from '../../../src/block-sync-renderer/sync/synchronizer'
-import LiveCell from '../../../src/models/chain/live-cell'
+import LiveCell, { CellWithOutPoint } from '../../../src/models/chain/live-cell'
describe('LiveCell Test', () => {
const INITIAL_DATA = {
@@ -88,7 +87,7 @@ describe('LiveCell Test', () => {
})
describe('get cells from lumos cell', () => {
- const LUMOS_CELL: LumosCell = {
+ const LUMOS_CELL: CellWithOutPoint = {
blockHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
outPoint: {
txHash: INITIAL_DATA.txHash,
diff --git a/packages/neuron-wallet/tests/services/tx/transaction-generator.test.ts b/packages/neuron-wallet/tests/services/tx/transaction-generator.test.ts
index c5217e5f11..c8ba7d414a 100644
--- a/packages/neuron-wallet/tests/services/tx/transaction-generator.test.ts
+++ b/packages/neuron-wallet/tests/services/tx/transaction-generator.test.ts
@@ -1,6 +1,6 @@
import { when } from 'jest-when'
-import { since } from '@ckb-lumos/base'
import { bytes } from '@ckb-lumos/codec'
+import { since } from '@ckb-lumos/base'
import OutputEntity from '../../../src/database/chain/entities/output'
import InputEntity from '../../../src/database/chain/entities/input'
import TransactionEntity from '../../../src/database/chain/entities/transaction'
@@ -28,7 +28,7 @@ import {
SudtAcpHaveDataError,
TargetOutputNotFoundError,
} from '../../../src/exceptions'
-import LiveCell from '../../../src/models/chain/live-cell'
+import LiveCell, { CellWithOutPoint } from '../../../src/models/chain/live-cell'
import { keyInfos } from '../../setupAndTeardown/public-key-info.fixture'
const randomHex = (length: number = 64): string => {
@@ -86,7 +86,6 @@ import HdPublicKeyInfo from '../../../src/database/chain/entities/hd-public-key-
import AssetAccount from '../../../src/models/asset-account'
import MultisigConfigModel from '../../../src/models/multisig-config'
import MultisigOutput from '../../../src/database/chain/entities/multisig-output'
-import { LumosCell } from '../../../src/block-sync-renderer/sync/synchronizer'
import { closeConnection, getConnection, initConnection } from '../../setupAndTeardown'
describe('TransactionGenerator', () => {
@@ -1097,8 +1096,8 @@ describe('TransactionGenerator', () => {
tokenID: string | undefined = undefined,
lockScript: Script = bobAnyoneCanPayLockScript,
customData: string = '0x'
- ): LumosCell => {
- const liveCell: LumosCell = {
+ ): CellWithOutPoint => {
+ const liveCell: CellWithOutPoint = {
blockHash: randomHex(),
outPoint: {
txHash: randomHex(),
@@ -1109,18 +1108,17 @@ describe('TransactionGenerator', () => {
lock: {
codeHash: lockScript.codeHash,
args: lockScript.args,
- hashType: lockScript.hashType.toString(),
+ hashType: lockScript.hashType,
},
},
data: '0x',
}
if (tokenID) {
const typeScript = assetAccountInfo.generateSudtScript(tokenID)
- // @ts-ignore
liveCell.cellOutput.type = {
codeHash: typeScript.codeHash,
args: typeScript.args,
- hashType: typeScript.hashType.toString(),
+ hashType: typeScript.hashType,
}
}
liveCell.data = amount ? BufferUtils.writeBigUInt128LE(BigInt(amount)) : '0x'
From 810ff2f91ca6618844d2633c068d60e55b298ea4 Mon Sep 17 00:00:00 2001
From: Tom Wang
Date: Tue, 28 May 2024 10:11:34 +0800
Subject: [PATCH 07/10] refactor: remove indexerUrl (#3170)
---
packages/neuron-wallet/src/block-sync-renderer/index.ts | 1 -
.../src/block-sync-renderer/sync/full-synchronizer.ts | 4 ++--
.../src/block-sync-renderer/sync/light-synchronizer.ts | 6 +-----
.../neuron-wallet/src/block-sync-renderer/sync/queue.ts | 6 ++----
.../src/block-sync-renderer/sync/synchronizer.ts | 4 ++--
packages/neuron-wallet/src/block-sync-renderer/task.ts | 5 ++---
.../tests/block-sync-renderer/full-synchronizer.test.ts | 8 +++-----
.../index/createBlockSyncTask.test.ts | 1 -
.../tests/block-sync-renderer/synchronizer.test.ts | 9 +--------
.../neuron-wallet/tests/block-sync-renderer/task.test.ts | 2 --
10 files changed, 13 insertions(+), 33 deletions(-)
diff --git a/packages/neuron-wallet/src/block-sync-renderer/index.ts b/packages/neuron-wallet/src/block-sync-renderer/index.ts
index 19b0394649..7bada7dac1 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/index.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/index.ts
@@ -177,7 +177,6 @@ export const createBlockSyncTask = async () => {
genesisHash: network.genesisHash,
url: network.remote,
addressMetas,
- indexerUrl: network.remote,
nodeType: network.type,
}
const msg: Required> = { type: 'call', channel: 'start', id: requestId++, message }
diff --git a/packages/neuron-wallet/src/block-sync-renderer/sync/full-synchronizer.ts b/packages/neuron-wallet/src/block-sync-renderer/sync/full-synchronizer.ts
index 972d37e5f0..eecace1ccf 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/sync/full-synchronizer.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/sync/full-synchronizer.ts
@@ -10,8 +10,8 @@ import IndexerCacheService from './indexer-cache-service'
export default class FullSynchronizer extends Synchronizer {
private rpcService: RpcService
- constructor(addresses: Address[], nodeUrl: string, indexerUrl: string, nodeType: NetworkType) {
- super({ addresses, nodeUrl, indexerUrl })
+ constructor(addresses: Address[], nodeUrl: string, nodeType: NetworkType) {
+ super({ addresses, nodeUrl })
this.rpcService = new RpcService(nodeUrl, nodeType)
}
diff --git a/packages/neuron-wallet/src/block-sync-renderer/sync/light-synchronizer.ts b/packages/neuron-wallet/src/block-sync-renderer/sync/light-synchronizer.ts
index f87dddf99b..d7b1fe7db6 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/sync/light-synchronizer.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/sync/light-synchronizer.ts
@@ -29,11 +29,7 @@ export default class LightSynchronizer extends Synchronizer {
private addressMetas: AddressMeta[]
constructor(addresses: Address[], nodeUrl: string) {
- super({
- addresses,
- nodeUrl,
- indexerUrl: nodeUrl,
- })
+ super({ addresses, nodeUrl })
this.lightRpc = new LightRPC(nodeUrl)
this.addressMetas = addresses.map(address => AddressMeta.fromObject(address))
// fetch some dep cell
diff --git a/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts b/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts
index 027bc14967..2c5d5008a5 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts
@@ -28,7 +28,6 @@ export default class Queue {
#lockHashes: string[]
#url: string // ckb node
#nodeType: NetworkType
- #indexerUrl: string
#addresses: AddressInterface[]
#rpcService: RpcService
#indexerConnector: Synchronizer | undefined
@@ -39,9 +38,8 @@ export default class Queue {
#anyoneCanPayLockHashes: string[]
#assetAccountInfo: AssetAccountInfo
- constructor(url: string, addresses: AddressInterface[], indexerUrl: string, nodeType: NetworkType) {
+ constructor(url: string, addresses: AddressInterface[], nodeType: NetworkType) {
this.#url = url
- this.#indexerUrl = indexerUrl
this.#addresses = addresses
this.#rpcService = new RpcService(url, nodeType)
this.#nodeType = nodeType
@@ -70,7 +68,7 @@ export default class Queue {
if (this.#url === BUNDLED_LIGHT_CKB_URL) {
this.#indexerConnector = new LightSynchronizer(this.#addresses, this.#url)
} else {
- this.#indexerConnector = new FullSynchronizer(this.#addresses, this.#url, this.#indexerUrl, this.#nodeType)
+ this.#indexerConnector = new FullSynchronizer(this.#addresses, this.#url, this.#nodeType)
}
await this.#indexerConnector!.connect()
} catch (error) {
diff --git a/packages/neuron-wallet/src/block-sync-renderer/sync/synchronizer.ts b/packages/neuron-wallet/src/block-sync-renderer/sync/synchronizer.ts
index 01fcfa3a12..cd6b840581 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/sync/synchronizer.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/sync/synchronizer.ts
@@ -40,8 +40,8 @@ export abstract class Synchronizer {
// do nothing
}
- constructor({ addresses, nodeUrl, indexerUrl }: { addresses: Address[]; nodeUrl: string; indexerUrl: string }) {
- this.indexer = new CkbIndexer(nodeUrl, indexerUrl)
+ constructor({ addresses, nodeUrl }: { addresses: Address[]; nodeUrl: string }) {
+ this.indexer = new CkbIndexer(nodeUrl)
this.addressesByWalletId = addresses
.map(address => AddressMeta.fromObject(address))
.reduce((addressesByWalletId, addressMeta) => {
diff --git a/packages/neuron-wallet/src/block-sync-renderer/task.ts b/packages/neuron-wallet/src/block-sync-renderer/task.ts
index 4d5c4b9d5a..dc937616dd 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/task.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/task.ts
@@ -31,8 +31,7 @@ export interface StartParams {
genesisHash: string
url: SyncQueueParams[0]
addressMetas: SyncQueueParams[1]
- indexerUrl: SyncQueueParams[2]
- nodeType: SyncQueueParams[3]
+ nodeType: SyncQueueParams[2]
}
export type QueryIndexerParams = QueryOptions
@@ -63,7 +62,7 @@ export const listener = async ({ type, id, channel, message }: WorkerMessage) =>
try {
await initConnection(message.genesisHash)
- syncQueue = new SyncQueue(message.url, message.addressMetas, message.indexerUrl, message.nodeType)
+ syncQueue = new SyncQueue(message.url, message.addressMetas, message.nodeType)
syncQueue.start()
} catch (err) {
logger.error(`Block Sync Task:\t`, err)
diff --git a/packages/neuron-wallet/tests/block-sync-renderer/full-synchronizer.test.ts b/packages/neuron-wallet/tests/block-sync-renderer/full-synchronizer.test.ts
index b4f2cd19fd..b4af6a23a4 100644
--- a/packages/neuron-wallet/tests/block-sync-renderer/full-synchronizer.test.ts
+++ b/packages/neuron-wallet/tests/block-sync-renderer/full-synchronizer.test.ts
@@ -87,14 +87,12 @@ describe('unit tests for IndexerConnector', () => {
})
describe('#constructor', () => {
- const STUB_URI = 'stub_uri'
-
describe('when init with indexer folder path', () => {
beforeEach(() => {
- new stubbedFullSynchronizer([], nodeUrl, STUB_URI)
+ new stubbedFullSynchronizer([], nodeUrl)
})
it('inits lumos indexer with a node url and indexer folder path', () => {
- expect(stubbedIndexerConstructor).toHaveBeenCalledWith(nodeUrl, STUB_URI)
+ expect(stubbedIndexerConstructor).toHaveBeenCalledWith(nodeUrl)
})
})
describe('when init without indexer folder path', () => {
@@ -102,7 +100,7 @@ describe('unit tests for IndexerConnector', () => {
new stubbedFullSynchronizer([], nodeUrl)
})
it('inits mercury indexer with a node url and a default port', () => {
- expect(stubbedIndexerConstructor).toHaveBeenCalledWith(nodeUrl, STUB_URI)
+ expect(stubbedIndexerConstructor).toHaveBeenCalledWith(nodeUrl)
})
})
})
diff --git a/packages/neuron-wallet/tests/block-sync-renderer/index/createBlockSyncTask.test.ts b/packages/neuron-wallet/tests/block-sync-renderer/index/createBlockSyncTask.test.ts
index 61da50c476..d53022eb38 100644
--- a/packages/neuron-wallet/tests/block-sync-renderer/index/createBlockSyncTask.test.ts
+++ b/packages/neuron-wallet/tests/block-sync-renderer/index/createBlockSyncTask.test.ts
@@ -75,7 +75,6 @@ describe(`Create block sync task`, () => {
message: {
addressMetas: STUB_ADDRESS_METAS,
genesisHash: STUB_NETWORK.genesisHash,
- indexerUrl: STUB_NETWORK.remote,
nodeType: NetworkType.Normal,
url: STUB_NETWORK.remote,
},
diff --git a/packages/neuron-wallet/tests/block-sync-renderer/synchronizer.test.ts b/packages/neuron-wallet/tests/block-sync-renderer/synchronizer.test.ts
index f237f7068d..9836446cf2 100644
--- a/packages/neuron-wallet/tests/block-sync-renderer/synchronizer.test.ts
+++ b/packages/neuron-wallet/tests/block-sync-renderer/synchronizer.test.ts
@@ -111,22 +111,18 @@ describe('unit tests for IndexerConnector', () => {
})
describe('#constructor', () => {
- const STUB_URI = 'stub_uri'
-
it('inits lumos indexer with a node url and indexer folder path', () => {
new TestSynchronizer({
addresses: [],
nodeUrl,
- indexerUrl: STUB_URI,
})
- expect(stubbedIndexerConstructor).toHaveBeenCalledWith(nodeUrl, STUB_URI)
+ expect(stubbedIndexerConstructor).toHaveBeenCalledWith(nodeUrl)
})
it('init with addresses', () => {
const synchronizer = new TestSynchronizer({
addresses: [addressObj1, addressObj2],
nodeUrl,
- indexerUrl: STUB_URI,
})
expect(synchronizer.getAddressesByWalletId().get(walletId1)?.[0]).toStrictEqual(
AddressMeta.fromObject(addressObj1)
@@ -141,7 +137,6 @@ describe('unit tests for IndexerConnector', () => {
const synchronizer = new TestSynchronizer({
addresses: [addressObj1, addressObj2],
nodeUrl,
- indexerUrl: '',
})
it('no cached tx', async () => {
stubbedNextUnprocessedTxsGroupedByBlockNumberFn.mockResolvedValue([])
@@ -179,7 +174,6 @@ describe('unit tests for IndexerConnector', () => {
const synchronizer = new TestSynchronizer({
addresses: [addressObj1, addressObj2],
nodeUrl,
- indexerUrl: '',
})
synchronizer.blockTipsSubject.subscribe(stubbedBlockTipsSubscribe)
@@ -271,7 +265,6 @@ describe('unit tests for IndexerConnector', () => {
const synchronizer = new TestSynchronizer({
addresses: [addressObj1, addressObj2],
nodeUrl,
- indexerUrl: '',
})
describe('when success', () => {
diff --git a/packages/neuron-wallet/tests/block-sync-renderer/task.test.ts b/packages/neuron-wallet/tests/block-sync-renderer/task.test.ts
index 413e782d13..9e0369e00a 100644
--- a/packages/neuron-wallet/tests/block-sync-renderer/task.test.ts
+++ b/packages/neuron-wallet/tests/block-sync-renderer/task.test.ts
@@ -6,7 +6,6 @@ const STUB_START_MESSAGE = {
genesisHash: 'stub_genesis_hash',
url: 'stub_url',
addressMetas: 'stub_address_metas',
- indexerUrl: 'stub_indexer_url',
nodeType: 2,
},
}
@@ -71,7 +70,6 @@ describe(`Block Sync Task`, () => {
expect(stubbedSyncQueue).toHaveBeenCalledWith(
STUB_START_MESSAGE.message.url,
STUB_START_MESSAGE.message.addressMetas,
- STUB_START_MESSAGE.message.indexerUrl,
STUB_START_MESSAGE.message.nodeType
)
expect(stubbedSyncQueueStart).toHaveBeenCalled()
From 493d07bed56276b30e18eb2ea6c2dd798c843a6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=A5=E5=9B=BD=E5=AE=87?= <841185308@qq.com>
Date: Tue, 28 May 2024 12:24:47 +0800
Subject: [PATCH 08/10] perf: Optimize synchronization logic for multiple
wallets in the light client. (#3160)
perf: Optimize synchronization logic for multiple wallets in a light client node
Co-authored-by: Chen Yu
---
.../sync/light-synchronizer.ts | 53 +++---
.../light-synchronizer.test.ts | 165 +++++++++++++++++-
2 files changed, 190 insertions(+), 28 deletions(-)
diff --git a/packages/neuron-wallet/src/block-sync-renderer/sync/light-synchronizer.ts b/packages/neuron-wallet/src/block-sync-renderer/sync/light-synchronizer.ts
index d7b1fe7db6..eb1f52bcf0 100644
--- a/packages/neuron-wallet/src/block-sync-renderer/sync/light-synchronizer.ts
+++ b/packages/neuron-wallet/src/block-sync-renderer/sync/light-synchronizer.ts
@@ -23,6 +23,7 @@ import NetworksService from '../../services/networks'
import { getConnection } from '../../database/chain/connection'
const unpackGroup = molecule.vector(blockchain.OutPoint)
+const THRESHOLD_BLOCK_NUMBER_IN_DIFF_WALLET = 100_000
export default class LightSynchronizer extends Synchronizer {
private lightRpc: LightRPC
@@ -167,6 +168,18 @@ export default class LightSynchronizer extends Synchronizer {
await getConnection('light').manager.save(updatedSyncProgress, { chunk: 100 })
}
+ private static async getWalletsSyncedMinBlockNumber() {
+ const walletMinBlockNumber = await SyncProgressService.getWalletMinLocalSavedBlockNumber()
+ const wallets = await WalletService.getInstance().getAll()
+ return wallets.reduce>(
+ (pre, cur) => ({
+ ...pre,
+ [cur.id]: Math.max(parseInt(cur.startBlockNumber ?? '0x0'), walletMinBlockNumber?.[cur.id] ?? 0),
+ }),
+ {}
+ )
+ }
+
private async initSyncProgress(appendScripts: AppendScript[] = []) {
if (!this.addressMetas.length && !appendScripts.length) {
return
@@ -174,13 +187,13 @@ export default class LightSynchronizer extends Synchronizer {
const existSyncArgses = await SyncProgressService.getExistingSyncArgses()
const syncScripts = await this.lightRpc.getScripts()
const retainedSyncScripts = syncScripts.filter(v => existSyncArgses.has(v.script.args))
- const existSyncscripts: Record = {}
+ const existSyncScripts: Record = {}
retainedSyncScripts.forEach(v => {
- existSyncscripts[scriptToHash(v.script)] = v
+ existSyncScripts[scriptToHash(v.script)] = v
})
+ const walletMinBlockNumber = await LightSynchronizer.getWalletsSyncedMinBlockNumber()
const currentWalletId = WalletService.getInstance().getCurrent()?.id
const allScripts = this.addressMetas
- .filter(v => (currentWalletId ? v.walletId === currentWalletId : true))
.map(addressMeta => {
const lockScripts = [
addressMeta.generateDefaultLockScript(),
@@ -194,32 +207,32 @@ export default class LightSynchronizer extends Synchronizer {
}))
})
.flat()
- const walletMinBlockNumber = await SyncProgressService.getWalletMinLocalSavedBlockNumber()
- const wallets = await WalletService.getInstance().getAll()
- const walletStartBlockMap = wallets.reduce>(
- (pre, cur) => ({ ...pre, [cur.id]: cur.startBlockNumber }),
- {}
- )
+ .filter(v => {
+ return (
+ !currentWalletId ||
+ v.walletId === currentWalletId ||
+ walletMinBlockNumber[v.walletId] >
+ walletMinBlockNumber[currentWalletId] - THRESHOLD_BLOCK_NUMBER_IN_DIFF_WALLET
+ )
+ })
const otherTypeSyncBlockNumber = await SyncProgressService.getOtherTypeSyncBlockNumber()
const addScripts = [
...allScripts
- .filter(
- v =>
- !existSyncscripts[scriptToHash(v.script)] ||
- +existSyncscripts[scriptToHash(v.script)].blockNumber < +(walletStartBlockMap[v.walletId] ?? 0)
- )
- .map(v => {
- const blockNumber = Math.max(
- parseInt(walletStartBlockMap[v.walletId] ?? '0x0'),
- walletMinBlockNumber?.[v.walletId] ?? 0
+ .filter(v => {
+ const scriptHash = scriptToHash(v.script)
+ return (
+ !existSyncScripts[scriptHash] ||
+ +existSyncScripts[scriptHash].blockNumber < walletMinBlockNumber[v.walletId]
)
+ })
+ .map(v => {
return {
...v,
- blockNumber: `0x${blockNumber.toString(16)}`,
+ blockNumber: `0x${walletMinBlockNumber[v.walletId].toString(16)}`,
}
}),
...appendScripts
- .filter(v => !existSyncscripts[scriptToHash(v.script)])
+ .filter(v => !existSyncScripts[scriptToHash(v.script)])
.map(v => ({
...v,
blockNumber: `0x${(otherTypeSyncBlockNumber[scriptToHash(v.script)] ?? 0).toString(16)}`,
diff --git a/packages/neuron-wallet/tests/block-sync-renderer/light-synchronizer.test.ts b/packages/neuron-wallet/tests/block-sync-renderer/light-synchronizer.test.ts
index ccd7ee549e..8279828f14 100644
--- a/packages/neuron-wallet/tests/block-sync-renderer/light-synchronizer.test.ts
+++ b/packages/neuron-wallet/tests/block-sync-renderer/light-synchronizer.test.ts
@@ -24,6 +24,7 @@ const schedulerWaitMock = jest.fn()
const getMultisigConfigForLightMock = jest.fn()
const walletGetCurrentMock = jest.fn()
const walletGetAllMock = jest.fn()
+const updateBlockStartNumberMock = jest.fn()
function mockReset() {
getSyncStatusMock.mockReset()
@@ -46,6 +47,8 @@ function mockReset() {
removeByHashesAndAddressType.mockReset()
walletGetCurrentMock.mockReset()
walletGetAllMock.mockReset()
+
+ updateBlockStartNumberMock.mockReset()
}
jest.mock('../../src/services/sync-progress', () => {
@@ -138,6 +141,7 @@ describe('test light synchronizer', () => {
})
it('when syncing script in the local DB', async () => {
getScriptsMock.mockResolvedValue([{ script, blockNumber: '0xaa' }])
+ walletGetAllMock.mockReturnValue([{ id: 'walletId' }])
getExistingSyncArgsesMock.mockResolvedValue(new Set([script.args]))
const addressMeta = AddressMeta.fromObject({
walletId: 'walletId',
@@ -187,6 +191,7 @@ describe('test light synchronizer', () => {
})
it('when syncing script not in the local DB', async () => {
getScriptsMock.mockResolvedValue([{ script, blockNumber: '0xaa' }])
+ walletGetAllMock.mockReturnValue([{ id: 'walletId' }])
getExistingSyncArgsesMock.mockResolvedValue(new Set())
const addressMeta = AddressMeta.fromObject({
walletId: 'walletId',
@@ -256,6 +261,7 @@ describe('test light synchronizer', () => {
addressType: 0,
blake160: script.args,
})
+ walletGetAllMock.mockReturnValue([{ id: 'walletId' }])
getWalletMinLocalSavedBlockNumberMock.mockResolvedValue({ walletId: 170 })
const connect = new LightSynchronizer([addressMeta], '')
//@ts-ignore
@@ -367,6 +373,152 @@ describe('test light synchronizer', () => {
)
expect(setScriptsMock).toHaveBeenLastCalledWith([], 'delete')
})
+ it('when other wallet min synced block number near the current wallet', async () => {
+ walletGetCurrentMock.mockReturnValue({ id: 'walletId1' })
+ walletGetAllMock.mockReturnValue([
+ { id: 'walletId1', startBlockNumber: '0xaa' },
+ { id: 'walletId2', startBlockNumber: '0xab' },
+ ])
+ const addressMeta1 = AddressMeta.fromObject({
+ walletId: 'walletId1',
+ address,
+ path: '',
+ addressIndex: 10,
+ addressType: 0,
+ blake160: script.args,
+ })
+ const script2: Script = {
+ args: '0x403f0d4e833b2a8d372772a63facaa310dfeef93',
+ codeHash: '0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8',
+ hashType: 'type',
+ }
+ const getScriptsResult = [{ script: script2, blockNumber: '0xaa', scriptType: 'lock' }]
+ getScriptsMock.mockResolvedValue(getScriptsResult)
+ getExistingSyncArgsesMock.mockResolvedValue(new Set([script2.args]))
+ const addressMeta2 = AddressMeta.fromObject({
+ walletId: 'walletId2',
+ address,
+ path: '',
+ addressIndex: 10,
+ addressType: 0,
+ blake160: script2.args,
+ })
+ const connect = new LightSynchronizer([addressMeta1, addressMeta2], '')
+ //@ts-ignore
+ await connect.initSyncProgress()
+ expect(setScriptsMock).toHaveBeenNthCalledWith(
+ 1,
+ [
+ ...[
+ addressMeta1.generateDefaultLockScript().toSDK(),
+ addressMeta1.generateACPLockScript().toSDK(),
+ addressMeta1.generateLegacyACPLockScript().toSDK(),
+ ].map(script => ({
+ script,
+ scriptType: 'lock',
+ walletId: addressMeta1.walletId,
+ blockNumber: '0xaa',
+ })),
+ ...[
+ addressMeta2.generateDefaultLockScript().toSDK(),
+ addressMeta2.generateACPLockScript().toSDK(),
+ addressMeta2.generateLegacyACPLockScript().toSDK(),
+ ].map(script => ({
+ script,
+ scriptType: 'lock',
+ walletId: addressMeta2.walletId,
+ blockNumber: '0xab',
+ })),
+ ],
+ 'partial'
+ )
+ expect(setScriptsMock).toHaveBeenLastCalledWith([], 'delete')
+ expect(initSyncProgressMock).toBeCalledWith([
+ ...[
+ addressMeta1.generateDefaultLockScript().toSDK(),
+ addressMeta1.generateACPLockScript().toSDK(),
+ addressMeta1.generateLegacyACPLockScript().toSDK(),
+ ].map(script => ({
+ script,
+ scriptType: 'lock',
+ walletId: addressMeta1.walletId,
+ blockNumber: '0xaa',
+ })),
+ ...[
+ addressMeta2.generateDefaultLockScript().toSDK(),
+ addressMeta2.generateACPLockScript().toSDK(),
+ addressMeta2.generateLegacyACPLockScript().toSDK(),
+ ].map(script => ({
+ script,
+ scriptType: 'lock',
+ walletId: addressMeta2.walletId,
+ blockNumber: '0xab',
+ })),
+ ])
+ expect(updateSyncProgressFlagMock).toBeCalledWith(['walletId1', 'walletId2'])
+ })
+ it('when other wallet min synced block number bigger than the current wallet', async () => {
+ walletGetCurrentMock.mockReturnValue({ id: 'walletId1' })
+ walletGetAllMock.mockReturnValue([
+ { id: 'walletId1', startBlockNumber: '0xaaaa0' },
+ { id: 'walletId2', startBlockNumber: '0xab' },
+ ])
+ const addressMeta1 = AddressMeta.fromObject({
+ walletId: 'walletId1',
+ address,
+ path: '',
+ addressIndex: 10,
+ addressType: 0,
+ blake160: script.args,
+ })
+ const script2: Script = {
+ args: '0x403f0d4e833b2a8d372772a63facaa310dfeef93',
+ codeHash: '0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8',
+ hashType: 'type',
+ }
+ const getScriptsResult = [{ script: script2, blockNumber: '0xab', scriptType: 'lock' }]
+ getScriptsMock.mockResolvedValue(getScriptsResult)
+ getExistingSyncArgsesMock.mockResolvedValue(new Set([script2.args]))
+ const addressMeta2 = AddressMeta.fromObject({
+ walletId: 'walletId2',
+ address,
+ path: '',
+ addressIndex: 10,
+ addressType: 0,
+ blake160: script2.args,
+ })
+ const connect = new LightSynchronizer([addressMeta1, addressMeta2], '')
+ //@ts-ignore
+ await connect.initSyncProgress()
+ expect(setScriptsMock).toHaveBeenNthCalledWith(
+ 1,
+ [
+ addressMeta1.generateDefaultLockScript().toSDK(),
+ addressMeta1.generateACPLockScript().toSDK(),
+ addressMeta1.generateLegacyACPLockScript().toSDK(),
+ ].map(script => ({
+ script,
+ scriptType: 'lock',
+ walletId: addressMeta1.walletId,
+ blockNumber: '0xaaaa0',
+ })),
+ 'partial'
+ )
+ expect(setScriptsMock).toHaveBeenLastCalledWith(getScriptsResult, 'delete')
+ expect(initSyncProgressMock).toBeCalledWith(
+ [
+ addressMeta1.generateDefaultLockScript().toSDK(),
+ addressMeta1.generateACPLockScript().toSDK(),
+ addressMeta1.generateLegacyACPLockScript().toSDK(),
+ ].map(script => ({
+ script,
+ scriptType: 'lock',
+ walletId: addressMeta1.walletId,
+ blockNumber: '0xaaaa0',
+ }))
+ )
+ expect(updateSyncProgressFlagMock).toBeCalledWith(['walletId1', 'walletId2'])
+ })
})
describe('test initSync', () => {
@@ -428,16 +580,10 @@ describe('test light synchronizer', () => {
})
describe('#notifyCurrentBlockNumberProcessed', () => {
- const synchronizer = new LightSynchronizer([], '')
- const updateBlockStartNumberMock = jest.fn()
- beforeAll(() => {
+ it('last process block number finish', async () => {
+ const synchronizer = new LightSynchronizer([], '')
// @ts-ignore private property
synchronizer.updateBlockStartNumber = updateBlockStartNumberMock
- })
- beforeEach(() => {
- updateBlockStartNumberMock.mockReset()
- })
- it('last process block number finish', async () => {
// @ts-ignore private property
synchronizer.processingBlockNumber = '0xaa'
getCurrentWalletMinSyncedBlockNumberMock.mockResolvedValueOnce(100)
@@ -447,6 +593,9 @@ describe('test light synchronizer', () => {
expect(updateBlockStartNumberMock).toBeCalledWith(100)
})
it('not last process block number finish', async () => {
+ const synchronizer = new LightSynchronizer([], '')
+ // @ts-ignore private property
+ synchronizer.updateBlockStartNumber = updateBlockStartNumberMock
// @ts-ignore private property
synchronizer.processingBlockNumber = undefined
await synchronizer.notifyCurrentBlockNumberProcessed('0xaa')
From 43f605e574cf3a88df290e86540a5fe082d47226 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Tue, 28 May 2024 05:50:04 +0000
Subject: [PATCH 09/10] chore: Update ckb node assume valid target for
rc/v0.116.1.
---
packages/neuron-wallet/.env | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/neuron-wallet/.env b/packages/neuron-wallet/.env
index 3c4d9296b8..cd45f7ec95 100644
--- a/packages/neuron-wallet/.env
+++ b/packages/neuron-wallet/.env
@@ -117,5 +117,5 @@ DAO_CODE_HASH=0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e
MULTISIG_CODE_HASH=0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8
# CKB NODE OPTIONS
-CKB_NODE_ASSUME_VALID_TARGET='0x6dd077b407d019a0bce0cbad8c34e69a524ae4b2599b9feda2c7491f3559d32c'
-CKB_NODE_DATA_SIZE=54
+CKB_NODE_ASSUME_VALID_TARGET='0x1eb76fb4b5b948b96494a8f80fe9b8d0fe00dcbae082bff000a6647c6239d9c8'
+CKB_NODE_DATA_SIZE=55
From 1fb592c59edcdcdf6d57df770949a863c59371ed Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Tue, 28 May 2024 05:58:01 +0000
Subject: [PATCH 10/10] chore: Update ckb node assume valid target for
rc/v0.116.1.
---
packages/neuron-wallet/.env | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/neuron-wallet/.env b/packages/neuron-wallet/.env
index cd45f7ec95..0f76d563dc 100644
--- a/packages/neuron-wallet/.env
+++ b/packages/neuron-wallet/.env
@@ -117,5 +117,5 @@ DAO_CODE_HASH=0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e
MULTISIG_CODE_HASH=0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8
# CKB NODE OPTIONS
-CKB_NODE_ASSUME_VALID_TARGET='0x1eb76fb4b5b948b96494a8f80fe9b8d0fe00dcbae082bff000a6647c6239d9c8'
+CKB_NODE_ASSUME_VALID_TARGET='0x88b9835cfcb167eddf63f85066debfb9b877c0f9bd51bb1abb1b0eaaa00f70f5'
CKB_NODE_DATA_SIZE=55
| |