Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix: Show the tip of looking for valid target #3195

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/neuron-wallet/.env
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,5 @@ MULTISIG_CODE_HASH=0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc963

# CKB NODE OPTIONS
CKB_NODE_ASSUME_VALID_TARGET='0x6dd077b407d019a0bce0cbad8c34e69a524ae4b2599b9feda2c7491f3559d32c'
CKB_NODE_DATA_SIZE=54
CKB_NODE_ASSUME_VALID_TARGET_BLOCK_NUMBER=13007704
CKB_NODE_DATA_SIZE=56
16 changes: 14 additions & 2 deletions packages/neuron-wallet/src/controllers/sync-api.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import EventEmiter from 'events'
import { debounceTime } from 'rxjs/operators'
import env from '../env'
import RpcService from '../services/rpc-service'
import SyncedBlockNumber from '../models/synced-block-number'
import SyncStateSubject from '../models/subjects/sync-state-subject'
import { CurrentNetworkIDSubject } from '../models/subjects/networks'
import MultisigService from '../services/multisig'
import { getLookingValidTargetStatus } from '../services/ckb-runner'
import NetworksService from '../services/networks'
import { NetworkType } from '../models/network'

const TEN_MINS = 600000
const MAX_TIP_BLOCK_DELAY = 180000
const { app } = env

export enum SyncStatus {
SyncNotStart,
Expand Down Expand Up @@ -137,6 +139,16 @@ export default class SyncApiController {

const remainingBlocksToCache = bestKnownBlockNumber - cacheTipNumber
const remainingBlocksToIndex = bestKnownBlockNumber - indexerTipNumber
const setAssumeValidTargetBlockNumber =
app.isPackaged &&
process.env.CKB_NODE_ASSUME_VALID_TARGET &&
process.env.CKB_NODE_ASSUME_VALID_TARGET_BLOCK_NUMBER
? +process.env.CKB_NODE_ASSUME_VALID_TARGET_BLOCK_NUMBER
: undefined
const isLookingValidTarget =
network.type === NetworkType.Default &&
!!setAssumeValidTargetBlockNumber &&
bestKnownBlockNumber < setAssumeValidTargetBlockNumber

const newSyncState: SyncState = {
nodeUrl: network.remote,
Expand All @@ -149,7 +161,7 @@ export default class SyncApiController {
cacheRate: undefined,
estimate: undefined,
status: SyncStatus.Syncing,
isLookingValidTarget: getLookingValidTargetStatus(),
isLookingValidTarget,
validTarget: process.env.CKB_NODE_ASSUME_VALID_TARGET,
}

Expand Down
16 changes: 0 additions & 16 deletions packages/neuron-wallet/src/services/ckb-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,6 @@ const initCkb = async () => {
})
}

let isLookingValidTarget: boolean = false
let lastLogTime: number
export const getLookingValidTargetStatus = () => isLookingValidTarget

export const getNodeUrl = () => `${BUNDLED_URL_PREFIX}${rpcPort}`

const removeOldIndexerIfRunSuccess = () => {
Expand Down Expand Up @@ -144,29 +140,17 @@ export const startCkbNode = async () => {
logger.error('CKB:\trun fail:', dataString)
return
}
if (
dataString.includes(
`can't find assume valid target temporarily, hash: Byte32(${process.env.CKB_NODE_ASSUME_VALID_TARGET})`
)
) {
isLookingValidTarget = true
lastLogTime = Date.now()
} else if (lastLogTime && Date.now() - lastLogTime > 10000) {
isLookingValidTarget = false
}
})

currentProcess.on('error', error => {
logger.error('CKB:\trun fail:', error)
isLookingValidTarget = false
if (Object.is(ckb, currentProcess)) {
ckb = null
}
})

currentProcess.on('close', code => {
logger.info(`CKB:\tprocess closed with code ${code}`)
isLookingValidTarget = false
if (Object.is(ckb, currentProcess)) {
ckb = null
}
Expand Down
26 changes: 22 additions & 4 deletions packages/neuron-wallet/tests/controllers/sync-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,17 @@ jest.doMock('models/subjects/networks', () => {
},
}
})
jest.doMock('services/ckb-runner', () => ({
getLookingValidTargetStatus: jest.fn(),
}))
jest.mock('undici', () => ({
request: () => jest.fn()(),
}))
jest.mock('services/multisig', () => ({
syncMultisigOutput: () => jest.fn(),
}))
jest.mock('env', () => ({
app: {
isPackaged: true,
},
}))

describe('SyncApiController', () => {
const emitter = new Emitter()
Expand Down Expand Up @@ -131,7 +133,7 @@ describe('SyncApiController', () => {
bestKnownBlockNumber: bestKnownBlockNumber.toString(16),
bestKnownBlockTimestamp: `0x${bestKnownBlockTimestamp.toString(16)}`,
})
getCurrentNetworkMock.mockReturnValue({ remote: fakeNodeUrl })
getCurrentNetworkMock.mockReturnValue({ remote: fakeNodeUrl, type: 0 })
stubbedGetTipHeader.mockResolvedValue({ timestamp: '180000' })
})
describe('on cache-tip-block-updated', () => {
Expand All @@ -148,9 +150,15 @@ describe('SyncApiController', () => {
timestamp: '187000',
}
beforeEach(async () => {
process.env.CKB_NODE_ASSUME_VALID_TARGET = '0x'
process.env.CKB_NODE_ASSUME_VALID_TARGET_BLOCK_NUMBER = '100000'
await sendFakeCacheBlockTipEvent(fakeState1)
await sendFakeCacheBlockTipEvent(fakeState2)
})
afterAll(() => {
delete process.env['CKB_NODE_ASSUME_VALID_TARGET']
delete process.env['CKB_NODE_ASSUME_VALID_TARGET_BLOCK_NUMBER']
})
it('broadcast event of synced', () => {
expect(stubbedSyncStateSubjectNext).toHaveBeenCalledWith({
nodeUrl: fakeNodeUrl,
Expand All @@ -163,6 +171,8 @@ describe('SyncApiController', () => {
cacheRate: undefined,
estimate: undefined,
status: 3,
isLookingValidTarget: true,
validTarget: '0x',
})
})
it('#getSyncStatus returns synced', async () => {
Expand Down Expand Up @@ -203,6 +213,7 @@ describe('SyncApiController', () => {
cacheRate: undefined,
estimate: undefined,
status: 2,
isLookingValidTarget: false,
})
})
it('#getSyncStatus returns syncing', async () => {
Expand Down Expand Up @@ -240,6 +251,7 @@ describe('SyncApiController', () => {
cacheRate: undefined,
estimate: undefined,
status: 1,
isLookingValidTarget: false,
})
})
it('#getSyncStatus returns sync pending', async () => {
Expand Down Expand Up @@ -271,6 +283,7 @@ describe('SyncApiController', () => {
cacheRate: undefined,
estimate: undefined,
status: 2,
isLookingValidTarget: false,
})
})
it('stores next block number', () => {
Expand Down Expand Up @@ -304,6 +317,7 @@ describe('SyncApiController', () => {
cacheRate: undefined,
estimate: Math.round((bestKnownBlockNumber - parseInt(fakeState2.indexerTipNumber)) / indexRate),
status: 2,
isLookingValidTarget: false,
}
beforeEach(async () => {
await sendFakeCacheBlockTipEvent(fakeState1)
Expand Down Expand Up @@ -399,6 +413,7 @@ describe('SyncApiController', () => {
cacheRate: undefined,
estimate: undefined,
status: 2,
isLookingValidTarget: false,
})
})
it('stores next block number', () => {
Expand Down Expand Up @@ -446,6 +461,7 @@ describe('SyncApiController', () => {
indexerTipNumber: parseInt(fakeState3.indexerTipNumber),
estimate: Math.round((bestKnownBlockNumber - parseInt(fakeState3.indexerTipNumber)) / indexRate),
status: 2,
isLookingValidTarget: false,
})
})
it('stores next block number', () => {
Expand All @@ -472,6 +488,7 @@ describe('SyncApiController', () => {
indexerTipNumber: parseInt(fakeState3.indexerTipNumber),
estimate: undefined,
status: 2,
isLookingValidTarget: false,
})
})
it('#getSyncStatus returns syncing', async () => {
Expand Down Expand Up @@ -516,6 +533,7 @@ describe('SyncApiController', () => {
cacheRate: undefined,
estimate: undefined,
status: 2,
isLookingValidTarget: false,
})
})
it('#getSyncStatus returns syncing', async () => {
Expand Down
57 changes: 1 addition & 56 deletions packages/neuron-wallet/tests/services/ckb-runner.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { EventEmitter } from 'typeorm/platform/PlatformTools'
import path from 'path'
import { scheduler } from 'timers/promises'

const stubbedChildProcess = jest.fn()
const stubbedSpawn = jest.fn()
Expand Down Expand Up @@ -92,13 +91,7 @@ jest.doMock('../../src/utils/toml', () => ({
jest.doMock('../../src/utils/get-usable-port', () => ({
getUsablePort: getUsablePortMock,
}))
const {
startCkbNode,
stopCkbNode,
getLookingValidTargetStatus,
migrateCkbData,
getNodeUrl,
} = require('../../src/services/ckb-runner')
const { startCkbNode, stopCkbNode, migrateCkbData, getNodeUrl } = require('../../src/services/ckb-runner')

describe('ckb runner', () => {
let stubbedCkb: any = new EventEmitter()
Expand Down Expand Up @@ -199,54 +192,6 @@ describe('ckb runner', () => {
})
})

describe('with assume valid target', () => {
beforeEach(async () => {
stubbedProcess.platform = platform
app.isPackaged = true
stubbedProcess.env = { CKB_NODE_ASSUME_VALID_TARGET: '0x' + '0'.repeat(64) }
stubbedExistsSync.mockReturnValue(true)
await startCkbNode()
})
afterEach(async () => {
app.isPackaged = false
stubbedProcess.env = {}
const promise = stopCkbNode()
stubbedCkb.emit('close')
await promise
})
it('runs ckb binary', () => {
expect(stubbedSpawn).toHaveBeenCalledWith(
expect.stringContaining(path.join('bin', 'ckb')),
['run', '-C', ckbDataPath, '--indexer', '--assume-valid-target', '0x' + '0'.repeat(64)],
{ stdio: ['ignore', 'pipe', 'pipe'] }
)
})
it('is Looking valid target', () => {
stubbedCkb.stdout.emit(
'data',
`can't find assume valid target temporarily, hash: Byte32(0x${'0'.repeat(64)})`
)
expect(getLookingValidTargetStatus()).toBeTruthy()
})
it('is Looking valid target', async () => {
stubbedCkb.stdout.emit(
'data',
`can't find assume valid target temporarily, hash: Byte32(0x${'0'.repeat(64)})`
)
await scheduler.wait(11000)
stubbedCkb.stdout.emit('data', `had find valid target`)
expect(getLookingValidTargetStatus()).toBeFalsy()
}, 15000)
it('ckb has closed', async () => {
stubbedCkb.stdout.emit(
'data',
`can't find assume valid target temporarily, hash: Byte32(0x${'0'.repeat(64)})`
)
stubbedCkb.emit('close')
expect(getLookingValidTargetStatus()).toBeFalsy()
})
})

it('port is not usable', async () => {
stubbedExistsSync.mockReturnValue(true)
getUsablePortMock.mockReset()
Expand Down
6 changes: 4 additions & 2 deletions scripts/update-wallet-env.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ async function rpcRequest(method, params = []) {
const ESTIMATE_BLOCK_COUNT_PER_DAY = 8_000
const envFilePath = path.resolve(__dirname, '../packages/neuron-wallet/.env')
const validTargetReg = /(CKB_NODE_ASSUME_VALID_TARGET=)[\S]*/
const blockNumberReg = /(CKB_NODE_ASSUME_VALID_TARGET_BLOCK_NUMBER=)[\S]*/
const ckbNodeDataSizeReg = /(CKB_NODE_DATA_SIZE=)[\S]*/

async function getValidTarget() {
const tipBlockNumber = (await rpcRequest('get_tip_block_number')).result
const validTargetBlockNumber = `0x${(BigInt(tipBlockNumber) - BigInt(ESTIMATE_BLOCK_COUNT_PER_DAY)).toString(16)}`
return (await rpcRequest('get_block_hash', [validTargetBlockNumber])).result
return [validTargetBlockNumber, (await rpcRequest('get_block_hash', [validTargetBlockNumber])).result]
}

async function getCKBNodeSize() {
Expand All @@ -41,12 +42,13 @@ async function getCKBNodeSize() {
;(async function () {
try {
console.info('start updating env file')
const blockHash = await getValidTarget()
const [blockNumber, blockHash] = await getValidTarget()
const ckbNodeDataSize = await getCKBNodeSize()
const originEnvContent = fs.readFileSync(envFilePath).toString('utf-8')
fs.writeFileSync(
envFilePath,
originEnvContent.replace(validTargetReg, `CKB_NODE_ASSUME_VALID_TARGET='${blockHash}'`)
.replace(blockNumberReg, `CKB_NODE_ASSUME_VALID_TARGET_BLOCK_NUMBER=${+blockNumber}`)
.replace(ckbNodeDataSizeReg, `CKB_NODE_DATA_SIZE=${ckbNodeDataSize}`)
)
console.info('write success')
Expand Down