Skip to content

Refactor: remove models/script and repalce with lumos - #2762

Closed
zhangyouxin wants to merge 2 commits into
nervosnetwork:developfrom
zhangyouxin:refactor-script
Closed

Refactor: remove models/script and repalce with lumos #2762
zhangyouxin wants to merge 2 commits into
nervosnetwork:developfrom
zhangyouxin:refactor-script

Conversation

@zhangyouxin

@zhangyouxin zhangyouxin commented Jul 6, 2023

Copy link
Copy Markdown
Contributor

Description

This PR removes most of model/chain/Script.ts in packages/neuron-wallet, and a subtask extracted from #2734

changed

  • refactored Script class
  • remove method fromObject
  • remove method toSDK
  • remove method computeHash
  • change calculateScriptBytesize to a pure function (maybe refactor to codec in future)

}

public calculateBytesize(): number {
return 1 + HexUtils.byteLength(this.codeHash) + HexUtils.byteLength(this.args)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried to replace with blockchain.Script.pack(script).bytelength, but that way the molecule encoding introduces 20 bytes of header.

Not sure why we need this logic here but just keep it, if this logic is used to calculate tx size, then it can be refactored to blockchain.Script.pack in the future.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not used to calculate tx size, it is used to calculate how many capacity needs to hold the cell.

private multiSignOutPointInfo = new Map<string, OutPoint>()

public getDaoScriptHash(): Hash {
return utils.computeScriptHash(SystemScriptInfo.DAO_SCRIPT)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static DAO_SCRIPT_HASH = utils.computeScriptHash(DAO_SCRIPT) is not a good pattern and somehow doesn't work, it could be a constant in pure utility file, but here in a class just use a public method is ok.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the DAO_SCRIPT is static, why we should use a function to compute it instead of just export it as a static. Is there any context of static DAO_SCRIPT_HASH = utils.computeScriptHash(DAO_SCRIPT) is not a good pattern and somehow doesn't work

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you help me be by fetching this branch on your local machine and change to static DAO_SCRIPT_HASH = utils.computeScriptHash(DAO_SCRIPT), I thought it should work, but it just doesn't, always prompting an error when i ran yarn test, didn't find a proper reason but class method works, so I just blamed it on static methods.

capacity: nftCell.capacity,
lock: outputLock,
type: nftCell.type ? new Script(nftCell.type.codeHash, nftCell.type.args, nftCell.type.hashType) : null,
type: nftCell.type ?? null,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original code defaults to null, so just keep it the same

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we can only set nftCell.type

const addressInfo: Address = {
address,
blake160: '0xfakeblake160',
blake160: `0x${'0'.repeat(40)}`,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This blake160 here will be used to calculate args then utils.computeScriptHash(script: Script), so that blake160 needs to be a valid HexString here, otherwise it won't build.

Script.fromObject({ codeHash: '', args: '', hashType: ScriptHashType.Type }),
Script.fromObject({ codeHash: '', args: '', hashType: ScriptHashType.Type }),
{ codeHash: '0x' + '0'.repeat(64), args: '0x', hashType: 'type' },
{ codeHash: '0x' + '0'.repeat(64), args: '0x', hashType: 'type' },

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous, utils.computeScriptHash(script: Script) needs valid 'HexString's

const lockScript2 = new Script(codeHash, fakeArgs2, ScriptHashType.Type)
const lockScript3 = new Script(codeHash, fakeArgs3, ScriptHashType.Type)
const lockScript1: Script = {
args: '0x01',

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous, utils.computeScriptHash(script: Script) needs valid 'HexString's

})

describe('with full address', () => {
it(`only full address, 43 capacity`, async () => {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test case is meant to be unchanged, but it just fails anyway, I find that 43 CKBytes is not enough to send a transaction though, so it always throws out an error of capacity too small, I think it should be at least 61 ?

lock: Script.fromObject({
args: '',
lock: {
args: '0x',

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous, utils.computeScriptHash(script: Script) needs valid 'HexString's

@@ -1,7 +1,7 @@
import { In, MigrationInterface, QueryRunner } from "typeorm";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe I should not edit this migration file, but it does not build if I don't change it, how should it be?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe changing the type will not have a side effect.

@zhangyouxin
zhangyouxin marked this pull request as ready for review July 6, 2023 08:13
),
codeHash: process.env.MAINNET_SUDT_SCRIPT_CODEHASH!,
hashType: process.env.MAINNET_SUDT_SCRIPT_HASHTYPE! as ScriptHashType,
hashType: process.env.MAINNET_SUDT_SCRIPT_HASHTYPE! as HashType,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

process.env.MAINNET_SUDT_SCRIPT_HASHTYPE can be re-declared

Data1 = 'data1',
}

export default class Script {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason to remove the Script class? Neuron uses the class style model, maybe we can just keep using it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a big task of refactoring with lumos and there were many fromObject and toSDK calls in the codebase, with this PR the codes can be more simple and "lumosified", but this PR could be closed if it's not a necessary one.

{
address: addressMeta.address,
lockHash: lockScript.computeHash(),
lockHash: utils.computeScriptHash(lockScript),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can keep using the class model in Neuron to keep the code pattern

if (
previousOutput.type?.computeHash() === SystemScriptInfo.DAO_SCRIPT_HASH &&
previousOutput.type &&
utils.computeScriptHash(previousOutput.type) === SystemScriptInfo.getInstance().getDaoScriptHash() &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we should refactor the SystemScriptInfo.DAO_SCRIPT_HASH here?

private multiSignOutPointInfo = new Map<string, OutPoint>()

public getDaoScriptHash(): Hash {
return utils.computeScriptHash(SystemScriptInfo.DAO_SCRIPT)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the DAO_SCRIPT is static, why we should use a function to compute it instead of just export it as a static. Is there any context of static DAO_SCRIPT_HASH = utils.computeScriptHash(DAO_SCRIPT) is not a good pattern and somehow doesn't work

this.lockHash = lockHash || this.lock?.computeHash()

this.lockHash = lockHash
if (lock) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (lock) {
if (lock && !lockHash) {

this.typeHash = typeHash || this.type?.computeHash()

this.typeHash = typeHash
if (type) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (type) {
if (type && !typeHash) {

LUMOS_HASH_TYPE_MAP[cell.cellOutput.type.hashType] ?? ScriptHashType.Data
)
: null
const type = (cell.cellOutput.type as Script) || null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can define LumosCell.cellOutput.type to Script

cell.cellOutput.lock.args,
LUMOS_HASH_TYPE_MAP[cell.cellOutput.lock.hashType] ?? ScriptHashType.Data
),
cell.cellOutput.lock as Script,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can define LumosCell.cellOutput.lock to Script

}
// calculate bytelength of script, but without the header bytes of molecule encoding
// TODO: refactor me with @ckb-lumos/codec
export const calculateScriptBytesize = (script: Script): number => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Bytesize a word? Maybe ByteSize?

}

public calculateBytesize(): number {
return 1 + HexUtils.byteLength(this.codeHash) + HexUtils.byteLength(this.args)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not used to calculate tx size, it is used to calculate how many capacity needs to hold the cell.

capacity: nftCell.capacity,
lock: outputLock,
type: nftCell.type ? new Script(nftCell.type.codeHash, nftCell.type.args, nftCell.type.hashType) : null,
type: nftCell.type ?? null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we can only set nftCell.type

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants