Skip to content

Commit 1b6b062

Browse files
committed
feat: add typeHash and daoData when sync
1 parent 5efe225 commit 1b6b062

9 files changed

Lines changed: 92 additions & 7 deletions

File tree

packages/neuron-wallet/src/database/chain/meta-info.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface MetaInfo {
88
genesisBlockHash: string
99
systemScriptInfo: SystemScript
1010
chain: string // ckb | ckb_testnet | ckb_dev
11+
daoScriptInfo: SystemScript
1112
}
1213

1314
export const updateMetaInfo = (metaInfo: MetaInfo) => {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import NodeService from 'services/node'
2+
import { ScriptHashType } from 'types/cell-types'
3+
import Core from '@nervosnetwork/ckb-sdk-core'
4+
import { SystemScript } from './lock-utils'
5+
import { scriptToHash } from '@nervosnetwork/ckb-sdk-utils'
6+
7+
export default class DaoUtils {
8+
daoScript: SystemScript
9+
10+
constructor(daoScript: SystemScript) {
11+
this.daoScript = daoScript
12+
}
13+
14+
static daoScriptInfo: SystemScript | undefined
15+
16+
static previousURL: string | undefined
17+
18+
static async loadDaoScript(nodeURL: string): Promise<SystemScript> {
19+
const core = new Core(nodeURL)
20+
21+
const genesisBlock = await core.rpc.getBlockByNumber(BigInt(0))
22+
const systemCellTransaction = genesisBlock.transactions[0]
23+
const daoOutPoint = {
24+
txHash: systemCellTransaction.hash,
25+
index: '2'
26+
}
27+
28+
const daoTypeHash = scriptToHash(systemCellTransaction.outputs[2].type!)
29+
30+
return {
31+
codeHash: daoTypeHash,
32+
outPoint: daoOutPoint,
33+
hashType: ScriptHashType.Type
34+
}
35+
}
36+
37+
static async daoScript(nodeURL: string = NodeService.getInstance().core.rpc.node.url): Promise<SystemScript> {
38+
if (DaoUtils.daoScriptInfo && nodeURL === DaoUtils.previousURL) {
39+
return DaoUtils.daoScriptInfo
40+
}
41+
42+
DaoUtils.daoScriptInfo = await DaoUtils.loadDaoScript(nodeURL)
43+
DaoUtils.previousURL = nodeURL
44+
45+
return DaoUtils.daoScriptInfo
46+
}
47+
48+
static setDaoScript(info: SystemScript) {
49+
DaoUtils.daoScriptInfo = info
50+
DaoUtils.previousURL = NodeService.getInstance().core.rpc.node.url
51+
}
52+
}

packages/neuron-wallet/src/services/sync/check-and-save/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@ export default class CheckAndSave {
55
private block: Block
66
private lockHashes: string[]
77
private url: string
8+
private daoScriptHash: string
89

9-
constructor(block: Block, lockHashes: string[], url: string) {
10+
constructor(block: Block, lockHashes: string[], url: string, daoScriptHash: string) {
1011
this.block = block
1112
this.lockHashes = lockHashes
1213
this.url = url
14+
this.daoScriptHash = daoScriptHash
1315
}
1416

1517
public process = async (): Promise<boolean[]> => {
1618
const txs = this.block.transactions
1719
let result: boolean[] = []
1820
for (const tx of txs) {
19-
const checkTx = new CheckTx(tx, this.url)
21+
const checkTx = new CheckTx(tx, this.url, this.daoScriptHash)
2022
const checkResult = await checkTx.checkAndSave(this.lockHashes)
2123
result.push(checkResult)
2224
}

packages/neuron-wallet/src/services/sync/check-and-save/tx.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@ export default class CheckTx {
1212
private tx: Transaction
1313
private addressesUsedSubject: Subject<AddressesWithURL>
1414
private url: string
15+
private daoTypeHash: string
1516

1617
constructor(
1718
tx: Transaction,
1819
url: string,
20+
daoTypeHash: string,
1921
addressesUsedSubject: Subject<AddressesWithURL> = addressesUsedSubjectParam,
2022
) {
2123
this.tx = tx
2224
this.addressesUsedSubject = addressesUsedSubject
2325

2426
this.url = url
27+
this.daoTypeHash = daoTypeHash
2528
}
2629

2730
public check = async (lockHashes: string[]): Promise<string[]> => {
@@ -51,10 +54,16 @@ export default class CheckTx {
5154
}
5255

5356
public filterOutputs = (lockHashes: string[]) => {
54-
const cells: Cell[] = this.tx.outputs!.map(output => {
57+
const cells: Cell[] = this.tx.outputs!.map((output, index) => {
5558
const checkOutput = new CheckOutput(output)
5659
const result = checkOutput.checkLockHash(lockHashes)
5760
if (result) {
61+
if (output.type) {
62+
this.tx.outputs![index].typeHash = LockUtils.computeScriptHash(output.type)
63+
if (output.typeHash === this.daoTypeHash) {
64+
this.tx.outputs![index].daoData = this.tx.outputsData![index]
65+
}
66+
}
5867
return output
5968
}
6069
return false

packages/neuron-wallet/src/services/sync/get-blocks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ export default class GetBlocks {
3838
return this.core.rpc.getTipBlockNumber()
3939
}
4040

41-
public checkAndSave = async (blocks: Block[], lockHashes: string[]): Promise<void> => {
41+
public checkAndSave = async (blocks: Block[], lockHashes: string[], daoScriptHash: string): Promise<void> => {
4242
const cachedPreviousTxs = new Map()
4343
for (const block of blocks) {
4444
logger.debug(`checking block #${block.header.number}, ${block.transactions.length} txs`)
4545
for (const tx of block.transactions) {
46-
const checkTx = new CheckTx(tx, this.url)
46+
const checkTx = new CheckTx(tx, this.url, daoScriptHash)
4747
const addresses = await checkTx.check(lockHashes)
4848
if (addresses.length > 0) {
4949
for (const input of tx.inputs!) {

packages/neuron-wallet/src/services/sync/queue.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Block, BlockHeader } from 'types/cell-types'
22
import { TransactionPersistor } from 'services/tx'
33
import logger from 'utils/logger'
4+
import LockUtils from 'models/lock-utils'
5+
import DaoUtils from 'models/dao-utils'
46

57
import GetBlocks from './get-blocks'
68
import RangeForCheck, { CheckResultType } from './range-for-check'
@@ -22,6 +24,8 @@ export default class Queue {
2224

2325
private yieldTime = 1
2426

27+
private url: string
28+
2529
constructor(
2630
url: string,
2731
lockHashes: string[],
@@ -32,6 +36,7 @@ export default class Queue {
3236
start: boolean = true
3337
) {
3438
this.lockHashes = lockHashes
39+
this.url = url
3540
this.getBlocksService = new GetBlocks(url)
3641
this.startBlockNumber = BigInt(startBlockNumber)
3742
this.endBlockNumber = BigInt(endBlockNumber)
@@ -117,8 +122,15 @@ export default class Queue {
117122
return
118123
}
119124

125+
const daoScriptInfo = await DaoUtils.daoScript(this.url)
126+
const daoScriptHash = LockUtils.computeScriptHash({
127+
codeHash: daoScriptInfo.codeHash,
128+
args: "0x",
129+
hashType: daoScriptInfo.hashType,
130+
})
131+
120132
// 3. check and save
121-
await this.getBlocksService.checkAndSave(blocks, this.lockHashes)
133+
await this.getBlocksService.checkAndSave(blocks, this.lockHashes, daoScriptHash)
122134

123135
// 4. update currentBlockNumber
124136
const lastBlock = blocks[blocks.length - 1]

packages/neuron-wallet/src/services/tx/transaction-persistor.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,17 @@ export class TransactionPersistor {
162162
output.status = outputStatus
163163
if (o.type) {
164164
output.typeScript = o.type
165+
output.typeHash = o.typeHash ? o.typeHash : null
165166
}
166167
const data = outputsData[index]
167168
if (data && data !== '0x') {
168169
output.hasData = true
169170
} else {
170171
output.hasData = false
171172
}
173+
if (o.daoData) {
174+
output.daoData = o.daoData
175+
}
172176
return output
173177
})
174178

packages/neuron-wallet/src/startup/sync-block-task/init-database.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import LockUtils from 'models/lock-utils'
55
import logger from 'utils/logger'
66
import genesisBlockHash, { getChain } from './genesis'
77
import ChainInfo from 'models/chain-info'
8+
import DaoUtils from '../../models/dao-utils';
89

910
// only used by main process
1011
export class InitDatabase {
@@ -47,7 +48,8 @@ export class InitDatabase {
4748

4849
try {
4950
const systemScriptInfo = await LockUtils.systemScript(url)
50-
updateMetaInfo({ genesisBlockHash: hash, systemScriptInfo, chain })
51+
const daoScriptInfo = await DaoUtils.daoScript(url)
52+
updateMetaInfo({ genesisBlockHash: hash, systemScriptInfo, chain, daoScriptInfo })
5153
} catch (err) {
5254
logger.error('update systemScriptInfo failed:', err)
5355
}
@@ -61,6 +63,7 @@ export class InitDatabase {
6163
chain = metaInfo.chain
6264
ChainInfo.getInstance().setChain(chain)
6365
LockUtils.setSystemScript(metaInfo.systemScriptInfo)
66+
DaoUtils.setDaoScript(metaInfo.daoScriptInfo)
6467
hash = metaInfo.genesisBlockHash
6568
this.success = true
6669
} catch (error) {

packages/neuron-wallet/src/types/cell-types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ export interface Cell {
8383
outPoint?: OutPoint
8484
status?: string
8585
lockHash?: string
86+
typeHash?: string | null
87+
daoData?: string | null
8688
}
8789

8890
export interface OutPoint {

0 commit comments

Comments
 (0)