Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adapt ckb light node (#2590) #2615

Merged
merged 27 commits into from
May 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b0051f7
feat: Adapt ckb light node (#2590)
yanguoyu Mar 24, 2023
ac9c1f5
fix: Download light client binary when transfer system type. (#2617)
yanguoyu Mar 24, 2023
5b0fb65
fix: If switch node type, should close others node. (#2618)
yanguoyu Mar 25, 2023
9307914
fix: Adapt light client send transaction.
yanguoyu Apr 1, 2023
4dcbea7
fix: use linux portable for compatibility
Keith-CY Apr 12, 2023
42ae5ae
fix: Some optimize for light client. (#2632)
yanguoyu Apr 17, 2023
085659b
fix: Fix some bugs, details are in description. (#2641)
yanguoyu Apr 21, 2023
e440f1b
fix: When use light client, ignore show method not found error.
yanguoyu Apr 21, 2023
d6be73c
fix: Fix test case (#2650)
yanguoyu Apr 25, 2023
85b9fbb
Merge pull request #2649 from nervosnetwork/develop
Keith-CY Apr 26, 2023
97c9bc0
fix: Show some tips about light client. (#2642)
yanguoyu Apr 28, 2023
b3cd08d
Merge branch 'develop' into support-light-client
Keith-CY Apr 28, 2023
beea565
fix: Update light client version. Disabled input when migrate sudt.
yanguoyu May 5, 2023
1d8af22
Merge pull request #2653 from yanguoyu/fix-light-client
Keith-CY May 8, 2023
d8012b2
fix: fix some bugs (#2659)
yanguoyu May 15, 2023
240cadf
Merge branch 'develop' into support-light-client
Keith-CY May 15, 2023
1b3d647
Merge branch 'merge-develop-into-support-light-client' into support-l…
Keith-CY May 15, 2023
f527c0f
Merge branch 'develop' of https://github.com/nervosnetwork/neuron int…
Keith-CY May 15, 2023
68c92d1
Merge branch 'develop' into merge-develop-into-support-light-client
Keith-CY May 16, 2023
91ed812
Merge pull request #2668 from nervosnetwork/merge-develop-into-suppor…
Keith-CY May 17, 2023
e29efd9
fix: set default fee rate if fee rate api throws
Keith-CY May 18, 2023
7a640f2
Merge pull request #2673 from nervosnetwork/fix-fee-rate-api-error
Keith-CY May 19, 2023
fed0503
fix: Fix some bugs. (#2675)
yanguoyu May 22, 2023
8b59e20
fix: Fix dao progress bar and light client should not verify version …
yanguoyu May 24, 2023
d84682a
fix: Fix multisig with light client (#2682)
yanguoyu May 26, 2023
673cf85
Fix clean cache and network display (#2685)
yanguoyu May 26, 2023
4b9219a
Merge branch 'develop' into support-light-client
Keith-CY May 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ckb-light-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v0.2.4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ release
/packages/neuron-wallet/bin/mac
/packages/neuron-wallet/bin/linux
/packages/neuron-wallet/bin/win
/packages/neuron-wallet/light

# misc
.DS_Store
Expand Down
10 changes: 7 additions & 3 deletions packages/neuron-ui/src/components/ClearCache/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const IDs = {
rebuildCacheOption: 'rebuild-cache-option',
}

const ClearCache = ({ dispatch }: { dispatch: StateDispatch }) => {
const ClearCache = ({ dispatch, hideRebuild }: { dispatch: StateDispatch; hideRebuild?: boolean }) => {
const [t] = useTranslation()
const [clearedDate, setClearedDate] = useState(cacheClearDate.load())
const [isClearing, setIsClearing] = useState(false)
Expand Down Expand Up @@ -96,8 +96,12 @@ const ClearCache = ({ dispatch }: { dispatch: StateDispatch }) => {
<div className={styles.options}>
<input type="checkbox" id={IDs.refreshCacheOption} checked disabled />
<label htmlFor={IDs.refreshCacheOption}>{t(`${I18N_PATH}.options.refresh.label`)}</label>
<input type="checkbox" id={IDs.rebuildCacheOption} checked={isRebuild} onChange={toggleIsRebuild} />
<label htmlFor={IDs.rebuildCacheOption}>{t(`${I18N_PATH}.options.rebuild.label`)}</label>
{hideRebuild ? null : (
<>
<input type="checkbox" id={IDs.rebuildCacheOption} checked={isRebuild} onChange={toggleIsRebuild} />
<label htmlFor={IDs.rebuildCacheOption}>{t(`${I18N_PATH}.options.rebuild.label`)}</label>
</>
)}
</div>
<div className={styles.footer}>
<Button type="submit" label={t(`${I18N_PATH}.buttons.ok`)} onClick={handleSubmit} id={IDs.submitClearCache} />
Expand Down
17 changes: 13 additions & 4 deletions packages/neuron-ui/src/components/DataSetting/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React, { useCallback, useEffect, useState } from 'react'
import React, { useCallback, useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import Button from 'widgets/Button'
import ClearCache from 'components/ClearCache'
import { useDispatch } from 'states'
import { useDispatch, useState as useGlobalState } from 'states'
import { ReactComponent as Attention } from 'widgets/Icons/ExperimentalAttention.svg'
import CopyZone from 'widgets/CopyZone'
import { OpenFolder, InfoCircleOutlined } from 'widgets/Icons/icon'
import { shell } from 'electron'
import Spinner from 'widgets/Spinner'
import { getIsCkbRunExternal } from 'services/remote'
import { isSuccessResponse } from 'utils'
import { LIGHT_NETWORK_TYPE } from 'utils/const'
import { useDataPath } from './hooks'

import styles from './index.module.scss'
Expand Down Expand Up @@ -99,10 +100,18 @@ const SetItem = () => {

const DataSetting = () => {
const dispatch = useDispatch()
const {
chain: { networkID },
settings: { networks = [] },
} = useGlobalState()
const isLightClient = useMemo(() => networks.find(n => n.id === networkID)?.type === LIGHT_NETWORK_TYPE, [
networkID,
networks,
])
return (
<div className={styles.root}>
<SetItem />
<ClearCache dispatch={dispatch} />
{isLightClient ? null : <SetItem />}
<ClearCache dispatch={dispatch} hideRebuild={isLightClient} />
</div>
)
}
Expand Down
41 changes: 39 additions & 2 deletions packages/neuron-ui/src/components/MultisigAddress/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import {
getMultisigBalances,
loadMultisigTxJson,
OfflineSignJSON,
getMultisigSyncProgress,
} from 'services/remote'
import { addressToScript, scriptToAddress } from '@nervosnetwork/ckb-sdk-utils'
import { addressToScript, scriptToAddress, scriptToHash } from '@nervosnetwork/ckb-sdk-utils'

export const useSearch = (clearSelected: () => void, onFilterConfig: (searchKey: string) => void) => {
const [keywords, setKeywords] = useState('')
Expand Down Expand Up @@ -279,19 +280,43 @@ export const useSubscription = ({
walletId,
isMainnet,
configs,
isLightClient,
}: {
walletId: string
isMainnet: boolean
configs: MultisigConfig[]
isLightClient: boolean
}) => {
const [multisigBanlances, setMultisigBanlances] = useState<Record<string, string>>({})
const [multisigSyncProgress, setMultisigSyncProgress] = useState<Record<string, number>>({})
const getAndSaveMultisigBalances = useCallback(() => {
getMultisigBalances({ isMainnet, multisigAddresses: configs.map(v => v.fullPayload) }).then(res => {
if (isSuccessResponse(res) && res.result) {
setMultisigBanlances(res.result)
}
})
}, [setMultisigBanlances, isMainnet, configs])
const hashToPayload = useMemo(
() =>
configs.reduce<Record<string, string>>(
(pre, cur) => ({ ...pre, [scriptToHash(addressToScript(cur.fullPayload))]: cur.fullPayload }),
{}
),
[configs]
)
const getAndSaveMultisigSyncProgress = useCallback(() => {
getMultisigSyncProgress(Object.keys(hashToPayload)).then(res => {
if (isSuccessResponse(res) && res.result) {
const tmp: Record<string, number> = {}
res.result.forEach(v => {
if (hashToPayload[v.hash]) {
tmp[hashToPayload[v.hash]] = v.blockStartNumber
}
})
setMultisigSyncProgress(tmp)
}
})
}, [hashToPayload])
useEffect(() => {
const dataUpdateSubscription = MultisigOutputUpdate.subscribe(() => {
getAndSaveMultisigBalances()
Expand All @@ -301,5 +326,17 @@ export const useSubscription = ({
dataUpdateSubscription.unsubscribe()
}
}, [walletId, getAndSaveMultisigBalances])
return multisigBanlances
useEffect(() => {
let interval: ReturnType<typeof setInterval> | undefined
if (isLightClient) {
interval = setInterval(() => {
getAndSaveMultisigSyncProgress()
}, 10000)
getAndSaveMultisigSyncProgress()
}
return () => {
clearInterval(interval)
}
}, [isLightClient, getAndSaveMultisigSyncProgress])
return { multisigBanlances, multisigSyncProgress }
}
19 changes: 16 additions & 3 deletions packages/neuron-ui/src/components/MultisigAddress/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { EditTextField } from 'widgets/TextField'
import { MultisigConfig } from 'services/remote'
import PasswordRequest from 'components/PasswordRequest'
import ApproveMultisigTx from 'components/ApproveMultisigTx'
import { LIGHT_NETWORK_TYPE } from 'utils/const'
import { useSearch, useConfigManage, useExportConfig, useActions, useSubscription } from './hooks'

import styles from './multisigAddress.module.scss'
Expand Down Expand Up @@ -52,6 +53,10 @@ const MultisigAddress = () => {
// eslint-disable-next-line
}, [i18n.language])
const isMainnet = isMainnetUtil(networks, networkID)
const isLightClient = useMemo(() => networks.find(n => n.id === networkID)?.type === LIGHT_NETWORK_TYPE, [
networks,
networkID,
])
const { openDialog, closeDialog, dialogRef, isDialogOpen } = useDialogWrapper()
const {
allConfigs,
Expand All @@ -65,7 +70,12 @@ const MultisigAddress = () => {
walletId,
isMainnet,
})
const multisigBanlances = useSubscription({ walletId, isMainnet, configs: allConfigs })
const { multisigBanlances, multisigSyncProgress } = useSubscription({
walletId,
isMainnet,
configs: allConfigs,
isLightClient,
})
const { deleteAction, infoAction, sendAction, approveAction } = useActions({ deleteConfigById })
const onClickItem = useCallback(
(multisigConfig: MultisigConfig) => (option: { key: string }) => {
Expand Down Expand Up @@ -138,8 +148,10 @@ const MultisigAddress = () => {
<th className={styles.checkBoxTh}>
<input type="checkbox" onChange={onChangeCheckedAll} checked={isAllSelected} />
</th>
{['address', 'alias', 'type', 'balance'].map(field => (
<th key={field}>{t(`multisig-address.table.${field}`)}</th>
{['address', 'alias', 'type', ...(isLightClient ? ['sync-block'] : []), 'balance'].map(field => (
<th key={field} data-field={field}>
{t(`multisig-address.table.${field}`)}
</th>
))}
</tr>
</thead>
Expand Down Expand Up @@ -173,6 +185,7 @@ const MultisigAddress = () => {
&nbsp;of&nbsp;
{v.n}
</td>
{isLightClient ? <td>{multisigSyncProgress?.[v.fullPayload] ?? 0}</td> : null}
<td>
{shannonToCKBFormatter(multisigBanlances[v.fullPayload])}
&nbsp;CKB
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
padding: 8px;
min-width: 40px;
text-align: left;

&[data-field="sync-block"] {
min-width: 70px;
}
}

.checkBoxTh {
Expand Down
90 changes: 58 additions & 32 deletions packages/neuron-ui/src/components/NervosDAO/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
generateDaoDepositTx,
generateDaoClaimTx,
} from 'services/remote'
import { ckbCore, getHeaderByNumber } from 'services/chain'
import { ckbCore, getHeader } from 'services/chain'
import { isErrorWithI18n } from 'exceptions'
import { calculateMaximumWithdraw } from '@nervosnetwork/ckb-sdk-utils'

Expand Down Expand Up @@ -84,12 +84,14 @@ export const useInitData = ({
updateDepositValue,
wallet,
setGenesisBlockTimestamp,
genesisBlockHash,
}: {
clearGeneratedTx: () => void
dispatch: React.Dispatch<StateAction>
updateDepositValue: (value: string) => void
wallet: State.Wallet
setGenesisBlockTimestamp: React.Dispatch<React.SetStateAction<number | undefined>>
genesisBlockHash?: string
}) =>
useEffect(() => {
updateNervosDaoData({ walletID: wallet.id })(dispatch)
Expand All @@ -103,9 +105,11 @@ export const useInitData = ({
: BigInt(0)
}`
)
getHeaderByNumber('0x0')
.then(header => setGenesisBlockTimestamp(+header.timestamp))
.catch(err => console.error(err))
if (genesisBlockHash) {
getHeader(genesisBlockHash)
.then(header => setGenesisBlockTimestamp(+header.timestamp))
.catch(err => console.error(err))
}
return () => {
clearInterval(intervalId)
clearNervosDaoData()(dispatch)
Expand Down Expand Up @@ -450,15 +454,15 @@ export const useOnSlide = ({

export const useUpdateWithdrawList = ({
records,
tipBlockHash,
tipDao,
setWithdrawList,
}: {
records: Readonly<State.NervosDAORecord[]>
tipBlockHash: string
tipDao?: string
setWithdrawList: React.Dispatch<React.SetStateAction<Map<string, string | null>>>
}) =>
useEffect(() => {
if (!tipBlockHash) {
if (!tipDao) {
setWithdrawList(new Map())
return
}
Expand All @@ -473,7 +477,6 @@ export const useUpdateWithdrawList = ({
const blockHashes = [
...(committedTx.map(v => v.txStatus.blockHash).filter(v => !!v) as string[]),
...(records.map(v => (v.depositOutPoint ? v.blockHash : null)).filter(v => !!v) as string[]),
tipBlockHash,
]
return ckbCore.rpc
.createBatchRequest<'getHeader', string[], CKBComponents.BlockHeader[]>(
Expand All @@ -494,7 +497,7 @@ export const useUpdateWithdrawList = ({
const withdrawList = new Map()
records.forEach(record => {
const key = getRecordKey(record)
const withdrawBlockHash = record.depositOutPoint ? record.blockHash : tipBlockHash
const withdrawBlockHash = record.depositOutPoint ? record.blockHash : undefined
const formattedDepositOutPoint = record.depositOutPoint
? {
txHash: record.depositOutPoint.txHash,
Expand All @@ -509,7 +512,7 @@ export const useUpdateWithdrawList = ({
return
}
const depositDAO = hashHeaderMap.get(tx.txStatus.blockHash!)
const withdrawDAO = hashHeaderMap.get(withdrawBlockHash)
const withdrawDAO = withdrawBlockHash ? hashHeaderMap.get(withdrawBlockHash) : tipDao
if (!depositDAO || !withdrawDAO) {
return
}
Expand All @@ -529,7 +532,23 @@ export const useUpdateWithdrawList = ({
.catch(() => {
setWithdrawList(new Map())
})
}, [records, tipBlockHash, setWithdrawList])
}, [records, tipDao, setWithdrawList])

const getBlockHashes = (txHashes: string[]) => {
const batchParams: ['getTransaction', string][] = txHashes.map(v => ['getTransaction', v])
return ckbCore.rpc
.createBatchRequest<'getTransaction', [string], CKBComponents.TransactionWithStatus[]>(batchParams)
.exec()
.then(res => {
return res.map((v, idx) => ({
txHash: txHashes[idx],
blockHash: v.txStatus.blockHash,
}))
})
.catch(() => {
return []
})
}

export const useUpdateDepositEpochList = ({
records,
Expand All @@ -542,28 +561,35 @@ export const useUpdateDepositEpochList = ({
}) =>
useEffect(() => {
if (connectionStatus === 'online') {
const recordKeyIdxMap = new Map<string, number>()
const batchParams: ['getHeaderByNumber', bigint][] = []
records.forEach((record, idx) => {
const depositBlockNumber = record.depositOutPoint
? ckbCore.utils.toUint64Le(record.daoData)
: record.blockNumber
if (depositBlockNumber) {
batchParams.push(['getHeaderByNumber', BigInt(depositBlockNumber)])
recordKeyIdxMap.set(getRecordKey(record), idx)
}
})
ckbCore.rpc
.createBatchRequest<'getHeaderByNumber', any, CKBComponents.BlockHeader[]>(batchParams)
.exec()
.then(res => {
const epochList = new Map()
records.forEach(record => {
const key = getRecordKey(record)
epochList.set(key, recordKeyIdxMap.get(key) !== undefined ? res[recordKeyIdxMap.get(key)!]?.epoch : null)
getBlockHashes(records.map(v => v.depositOutPoint?.txHash).filter(v => !!v) as string[]).then(
depositBlockHashes => {
const recordKeyIdx: string[] = []
const batchParams: ['getHeader', string][] = []
records.forEach((record) => {
if (!record.depositOutPoint && record.blockHash) {
batchParams.push(['getHeader', record.blockHash])
recordKeyIdx.push(record.outPoint.txHash)
}
})
setDepositEpochList(epochList)
})
depositBlockHashes.forEach((v) => {
if (v.blockHash) {
batchParams.push(['getHeader', v.blockHash])
recordKeyIdx.push(v.txHash)
}
})
ckbCore.rpc
.createBatchRequest<'getHeader', any, CKBComponents.BlockHeader[]>(batchParams)
.exec()
.then(res => {
const epochList = new Map()
records.forEach(record => {
const key = record.depositOutPoint ? record.depositOutPoint.txHash : record.outPoint.txHash
epochList.set(key, res[recordKeyIdx.indexOf(key)]?.epoch)
})
setDepositEpochList(epochList)
})
}
)
}
}, [records, setDepositEpochList, connectionStatus])

Expand Down
Loading