Skip to content

Commit

Permalink
refactor: refactor models/multisig with lumos (nervosnetwork#3156)
Browse files Browse the repository at this point in the history
* refactor: refactor models/multisig with lumos

Signed-off-by: Tom Wang <[email protected]>

* refactor: move BLAKE160_HEX_LENGTH to blake2b.ts

Signed-off-by: Tom Wang <[email protected]>

* feat: Add help link for sync failed.

Signed-off-by: Tom Wang <[email protected]>

* ci: upgrade github actions version (nervosnetwork#3161)

Co-authored-by: Chen Yu <[email protected]>
Signed-off-by: Tom Wang <[email protected]>

---------

Signed-off-by: Tom Wang <[email protected]>
Co-authored-by: yanguoyu <[email protected]>
Co-authored-by: Chen Yu <[email protected]>
  • Loading branch information
3 people committed May 29, 2024
1 parent a6b850c commit e01c1f5
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 57 deletions.
2 changes: 2 additions & 0 deletions packages/neuron-wallet/src/models/blake2b.ts
Original file line number Diff line number Diff line change
@@ -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

Expand Down
49 changes: 15 additions & 34 deletions packages/neuron-wallet/src/models/multisig.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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'

Expand All @@ -24,58 +26,37 @@ 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)
}

static getMultisigScript(blake160s: string[], r: number, m: number, n: number) {
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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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({
Expand Down
6 changes: 3 additions & 3 deletions packages/neuron-wallet/tests/models/multi-sign.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})

Expand All @@ -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)
})
})
4 changes: 2 additions & 2 deletions packages/neuron-wallet/tests/services/cells.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
Expand Down Expand Up @@ -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)
})
Expand Down
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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)
})
})
})
Expand Down Expand Up @@ -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)
})
})

Expand Down Expand Up @@ -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),
Expand Down

0 comments on commit e01c1f5

Please sign in to comment.