-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(config-manager): generate script config from genesis (#552)
- Loading branch information
Showing
8 changed files
with
179 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@ckb-lumos/common-scripts": patch | ||
--- | ||
|
||
fix incorrect `TX_HASH` when generate a deployment transaction |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@ckb-lumos/config-manager": minor | ||
--- | ||
|
||
supported generate `ScriptConfig` from a genesis block |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import { Block, Transaction, utils } from "@ckb-lumos/base"; | ||
import { ScriptConfig } from "./types"; | ||
|
||
// https://github.com/nervosnetwork/ckb-sdk-rust/blob/94ce4379454cdaf046f64b346e18e73e029f0ae6/src/constants.rs#L19C1-L24C62 | ||
// the index of a transaction in a block | ||
type TransactionIndex = number; | ||
// the index of an output in a transaction | ||
type OutputIndex = number; | ||
export const SIGHASH_OUTPUT_LOC: [TransactionIndex, OutputIndex] = [0, 1]; | ||
export const MULTISIG_OUTPUT_LOC: [TransactionIndex, OutputIndex] = [0, 4]; | ||
export const DAO_OUTPUT_LOC: [TransactionIndex, OutputIndex] = [0, 2]; | ||
export const SIGHASH_GROUP_OUTPUT_LOC: [TransactionIndex, OutputIndex] = [1, 0]; | ||
// prettier-ignore | ||
export const MULTISIG_GROUP_OUTPUT_LOC: [TransactionIndex, OutputIndex] = [1, 1]; | ||
|
||
/** | ||
* Generate {@link ScriptConfig} for the genesis block, | ||
* use this function when you are on a testnet, | ||
* or you cannot determine which network you are on | ||
* @example | ||
* const rpc = new RPC('http://localhost:8114') | ||
* const genesisBlock = await rpc.getBlockByNumber('0x0') | ||
* const scriptConfig = generateGenesisScriptConfigs(genesisBlock) | ||
* @param genesisBlock | ||
*/ | ||
export function generateGenesisScriptConfigs( | ||
genesisBlock: Block | ||
): Record< | ||
"SECP256K1_BLAKE160" | "SECP256K1_BLAKE160_MULTISIG" | "DAO", | ||
ScriptConfig | ||
> { | ||
if (!genesisBlock || Number(genesisBlock.header.number) !== 0) { | ||
throw new Error("The block must be a genesis block"); | ||
} | ||
|
||
const transactions = genesisBlock.transactions; | ||
|
||
return { | ||
SECP256K1_BLAKE160: { | ||
...createScriptConfig({ | ||
transaction: transactions[SIGHASH_OUTPUT_LOC[0]], | ||
outputIndex: SIGHASH_OUTPUT_LOC[1], | ||
depGroupTransaction: transactions[SIGHASH_GROUP_OUTPUT_LOC[0]], | ||
depGroupOutputIndex: SIGHASH_GROUP_OUTPUT_LOC[1], | ||
}), | ||
SHORT_ID: 0, | ||
}, | ||
SECP256K1_BLAKE160_MULTISIG: { | ||
...createScriptConfig({ | ||
transaction: transactions[MULTISIG_OUTPUT_LOC[0]], | ||
outputIndex: MULTISIG_OUTPUT_LOC[1], | ||
depGroupTransaction: transactions[MULTISIG_GROUP_OUTPUT_LOC[0]], | ||
depGroupOutputIndex: MULTISIG_GROUP_OUTPUT_LOC[1], | ||
}), | ||
SHORT_ID: 1, | ||
}, | ||
DAO: createScriptConfig({ | ||
transaction: transactions[DAO_OUTPUT_LOC[0]], | ||
outputIndex: DAO_OUTPUT_LOC[1], | ||
}), | ||
}; | ||
} | ||
|
||
type ScriptConfigOptions = LocByCode | LocByDepGroup; | ||
|
||
type LocByCode = { | ||
transaction: Transaction; | ||
outputIndex: number; | ||
}; | ||
type LocByDepGroup = { | ||
transaction: Transaction; | ||
outputIndex: number; | ||
depGroupTransaction: Transaction; | ||
depGroupOutputIndex: number; | ||
}; | ||
|
||
function createScriptConfig(config: ScriptConfigOptions): ScriptConfig { | ||
const { transaction, outputIndex } = config; | ||
|
||
const codeHash = utils.computeScriptHash( | ||
mustGenesisBlock(transaction.outputs[outputIndex]?.type) | ||
); | ||
|
||
if ("depGroupTransaction" in config) { | ||
const { depGroupOutputIndex, depGroupTransaction } = config; | ||
|
||
return { | ||
HASH_TYPE: "type", | ||
CODE_HASH: codeHash, | ||
|
||
DEP_TYPE: "depGroup", | ||
TX_HASH: mustGenesisBlock(depGroupTransaction.hash), | ||
INDEX: toHexNumber(depGroupOutputIndex), | ||
}; | ||
} | ||
|
||
return { | ||
HASH_TYPE: "type", | ||
CODE_HASH: codeHash, | ||
|
||
DEP_TYPE: "code", | ||
INDEX: toHexNumber(outputIndex), | ||
TX_HASH: mustGenesisBlock(transaction.hash), | ||
}; | ||
} | ||
|
||
function mustGenesisBlock<T>(x: T): NonNullable<T> { | ||
if (x == null) { | ||
throw new Error("The block must be a genesis block"); | ||
} | ||
return x; | ||
} | ||
|
||
function toHexNumber(number: number): string { | ||
return `0x${number.toString(16)}`; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import test from "ava"; | ||
import { readFile } from "fs/promises"; | ||
import { join } from "path"; | ||
import { generateGenesisScriptConfigs, predefined } from "../src"; | ||
import { Block } from "@ckb-lumos/base"; | ||
|
||
test("generateFromGenesisBlock", async (t) => { | ||
const buf = await readFile(join(__dirname, "genesis-mainnet-block.json")); | ||
const genesisBlock = JSON.parse(buf.toString()); | ||
|
||
const config = generateGenesisScriptConfigs(genesisBlock); | ||
|
||
const predefinedConfig = predefined.LINA.SCRIPTS; | ||
t.deepEqual(config, { | ||
SECP256K1_BLAKE160: predefinedConfig.SECP256K1_BLAKE160, | ||
SECP256K1_BLAKE160_MULTISIG: predefinedConfig.SECP256K1_BLAKE160_MULTISIG, | ||
DAO: predefinedConfig.DAO, | ||
}); | ||
}); | ||
|
||
test("generateFromGenesisBlock with wrong block", async (t) => { | ||
const buf = await readFile(join(__dirname, "genesis-mainnet-block.json")); | ||
const genesisBlock: Block = JSON.parse(buf.toString()); | ||
|
||
t.throws(() => { | ||
const wrongBlock = clone(genesisBlock); | ||
wrongBlock.header.number = "0x111"; | ||
generateGenesisScriptConfigs(wrongBlock); | ||
}); | ||
|
||
t.throws(() => { | ||
const wrongBlock = clone(genesisBlock); | ||
wrongBlock.transactions[0].outputs[1].type = undefined; | ||
generateGenesisScriptConfigs(wrongBlock); | ||
}); | ||
}); | ||
|
||
function clone<T>(obj: T): T { | ||
return JSON.parse(JSON.stringify(obj)); | ||
} |
1cb43fe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
lumos-website – ./
lumos-website-magickbase.vercel.app
lumos-website-git-develop-magickbase.vercel.app
lumos-website.vercel.app
1cb43fe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀 New canary release:
0.0.0-canary-1cb43fe-20230816060512