diff --git a/config/config.ts b/config/config.ts index 8b265b9..9679388 100644 --- a/config/config.ts +++ b/config/config.ts @@ -4,18 +4,28 @@ import {LightClientCli} from "../service/light-cli"; const CKB_CLIENT_CLI_PATH = "tmp/ckb-cli-light-client" const CKB_LIGHT_CLIENT_PATH = "tmp/startBlockchain/ckbLightClient/ckb-light-client" -const RPC_DEBUG = false +const DEV_PATH = "tmp/startBlockchain/ckbDevWithIndexAndLightClient" +const CKB_DEV_PATH = "tmp/startBlockchain/ckbDevWithIndexAndLightClient/ckb/target/release" +const CKB_DEV_INDEX_PATH = "tmp/startBlockchain/ckbDevWithIndexAndLightClient/ckb-indexer/target/release" +const CKB_DEV_LIGHT_CLIENT_PATH = "tmp/startBlockchain/ckbDevWithIndexAndLightClient/ckb-light-client/target/release" + +const CKB_DEV_RPC_URL = "http://localhost:8114"; +const CKB_DEV_RPC_INDEX_URL = "http://localhost:8116"; + +const RPC_DEBUG = true const CKB_RPC_URL = "https://testnet.ckb.dev"; +// const CKB_RPC_URL = CKB_DEV_RPC_URL; const CKB_RPC_INDEX_URL = "https://testnet.ckb.dev/indexer"; +// const CKB_RPC_INDEX_URL = CKB_DEV_RPC_INDEX_URL; const CKB_LIGHT_RPC_URL = "http://localhost:9000"; export enum FeeRate { SLOW = 1000, - NORMAL = 100000, + NORMAL = 10000000, FAST = 10000000 } -const uint = 100000000 +const uint = 100000000 const FEE = FeeRate.NORMAL config.initializeConfig( @@ -32,17 +42,19 @@ const CkbClientNode = new LightClient(CKB_LIGHT_CLIENT_PATH) const deprecatedAddr = helpers.generateAddress(script); const newFullAddr = helpers.encodeToAddress(script); const rpcCLient = new RPC(CKB_RPC_URL); +const rpcDevCLient = new RPC(CKB_DEV_RPC_URL); + const {AGGRON4} = config.predefined; const RPC_NETWORK = AGGRON4; const ACCOUNT_PRIVATE = "0xdd50cac37ec6dd12539a968c1a2cbedda75bd8724f7bcad486548eaabb87fc8b" const ACCOUNT_PRIVATE2 = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" const indexer = new Indexer(CKB_RPC_INDEX_URL, CKB_RPC_URL); -const LightCli = new LightClientCli(CKB_CLIENT_CLI_PATH,CKB_LIGHT_RPC_URL) +const LightCli = new LightClientCli(CKB_CLIENT_CLI_PATH, CKB_LIGHT_RPC_URL) const EVERY_ONE_CAN_PAY_DATA = { "CODE_HASH": '0xe683b04139344768348499c23eb1326d5a52d6db006c0d2fece00a831f3660d7', - "HASH_TYPE":"data", + "HASH_TYPE": "data", "TX_HASH": '0xbe5d236f316f5608c53aa682351be4114db07b2e843435e843661ded30924c04', "INDEX": '0x0', "DEP_TYPE": 'code' @@ -50,7 +62,7 @@ const EVERY_ONE_CAN_PAY_DATA = { const EVERY_ONE_CAN_PAY_DATA1 = { "CODE_HASH": '0xe683b04139344768348499c23eb1326d5a52d6db006c0d2fece00a831f3660d7', - "HASH_TYPE":"data1", + "HASH_TYPE": "data1", "TX_HASH": '0xbe5d236f316f5608c53aa682351be4114db07b2e843435e843661ded30924c04', "INDEX": '0x0', "DEP_TYPE": 'code' @@ -86,6 +98,12 @@ export { ACCOUNT_PRIVATE2, LightCli, EVERY_ONE_CAN_PAY_TYPE_ID, - EVERY_ONE_CAN_PAY_DATA - + EVERY_ONE_CAN_PAY_DATA, + CKB_DEV_PATH, + rpcDevCLient, + CKB_DEV_RPC_URL, + CKB_DEV_RPC_INDEX_URL, + DEV_PATH, + CKB_DEV_INDEX_PATH, + CKB_DEV_LIGHT_CLIENT_PATH } diff --git a/package.json b/package.json index bcfb522..c25d25c 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,11 @@ "test-load": "mocha --config test/runners/mocha/.mocharc.load.jsonc --reporter mochawesome", "test-data": "mocha --config test/runners/mocha/.mocharc.data.jsonc --reporter mochawesome", "test-cli": "mocha --config test/runners/mocha/.mocharc.cli.jsonc --reporter mochawesome", - "test-transfer-issue": "mocha --config test/runners/mocha/.mocharc.issue.jsonc --reporter mochawesome" + "test-transfer-issue": "mocha --config test/runners/mocha/.mocharc.issue.jsonc --reporter mochawesome", + "test-index-panic": "mocha --config test/runners/mocha/.mocharc.index-panic.jsonc --reporter mochawesome", + "test-roll-back": "mocha --config test/runners/mocha/.mocharc.light.rollback.jsonc --reporter mochawesome", + "test-roll-back:transfer": "mocha --config test/runners/mocha/.mocharc.light.rollback.jsonc --grep \"transfer\"--reporter mochawesome", + "test-roll-back:cut10": "mocha --config test/runners/mocha/.mocharc.light.rollback.jsonc --grep \"cut 10\"--reporter mochawesome", + "test-roll-back:cut300": "mocha --config test/runners/mocha/.mocharc.light.rollback.jsonc --grep \"cut 300\"--reporter mochawesome" } } diff --git a/resource/cli/example-search-key.withFilter.json b/resource/cli/example-search-key.withFilter.json index 473faad..3da66af 100644 --- a/resource/cli/example-search-key.withFilter.json +++ b/resource/cli/example-search-key.withFilter.json @@ -1,30 +1,25 @@ { - "script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": "0x00010203" - }, - "script_type": "lock", "filter": { - "script": { - "code_hash": "0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e", - "hash_type": "type", - "args": "0x00010203" - }, - "script_len_range": null, - "output_data_len_range": [ - "0x16", - "0x378" - ], - "output_capacity_range": [ - "0xf4240", - "0x5f5e100" - ], "block_range": [ "0x21", "0x3e7" + ], + "script": { + "args": "0x00010203", + "code_hash": "0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e", + "hash_type": "type" + }, + "script_len_range": [ + "0x0", + "0x6f" ] }, - "with_data": false, - "group_by_transaction": null + "group_by_transaction": false, + "script": { + "args": "0x00010203", + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type" + }, + "script_type": "lock", + "with_data": false } diff --git a/rpc/index.ts b/rpc/index.ts index 61cc63e..40cfeb7 100644 --- a/rpc/index.ts +++ b/rpc/index.ts @@ -103,6 +103,25 @@ export async function getScripts(ckbLightClient: string = ckbLightClientRPC) { return res; } +export async function checkScriptsInLightClient(scripts:ScriptObject[],ckbLightClient:string = ckbLightClientRPC){ + let res = await getScripts(ckbLightClient) + let getScriptList = res.map(result=>{ + return { + code_hash:result.script.code_hash, + hash_type:result.script.hash_type, + args:result.script.args + } + }) + + return scripts.some(checkScript=>{ + return getScriptList.some(getScript=>{ + return getScript.code_hash == checkScript.code_hash && + getScript.hash_type == checkScript.hash_type && + getScript.args == checkScript.args + }) + }) +} + export async function waitScriptsUpdate(block_num: BI, ckbLightClient: string = ckbLightClientRPC) { while (true) { let res = await getScripts(ckbLightClient) diff --git a/service/CkbDevService.ts b/service/CkbDevService.ts new file mode 100644 index 0000000..fc0361f --- /dev/null +++ b/service/CkbDevService.ts @@ -0,0 +1,178 @@ +import { + ACCOUNT_PRIVATE, ACCOUNT_PRIVATE2, CKB_DEV_INDEX_PATH, CKB_DEV_LIGHT_CLIENT_PATH, CKB_DEV_PATH, + CKB_DEV_RPC_INDEX_URL, + CKB_DEV_RPC_URL, + CKB_LIGHT_RPC_URL, CKB_RPC_INDEX_URL, DEV_PATH, + rpcDevCLient +} from "../config/config"; +import {BI} from "@ckb-lumos/bi"; +import {getCellsCapacityRequest, ScriptObject, waitScriptsUpdate} from "../rpc"; +import {request} from "./index"; +import {getCellsByRange} from "./txService"; +import {generateAccountFromPrivateKey, TransferService} from "./transfer"; +import {sh, shWithTimeout, shWithTimeOutNotErr} from "./node"; +import {Sleep} from "./util"; + +export const transferDevService = new TransferService(CKB_DEV_RPC_URL,CKB_DEV_RPC_INDEX_URL) +export async function cut_miner_and_wait_lightClient_sync(cut_num: number, miner_num: number) { + const before_cut_tip_height = await rpcDevCLient.get_tip_block_number() + if (BI.from(before_cut_tip_height).toNumber() < cut_num) { + await miner_block_number(cut_num - BI.from(before_cut_tip_height).toNumber()) + } + + await cut_number(cut_num) + await miner_block_number(miner_num) + let tip_num = await rpcDevCLient.get_tip_block_number() + await waitScriptsUpdate(BI.from(tip_num)) +} + +export async function compare_cells_result(scriptObject1: ScriptObject) { + let compare = true; + const indexCells = await getCellsMsg(scriptObject1, CKB_DEV_RPC_INDEX_URL) + console.log("lightCells:") + const lightCells = await getCellsMsg(scriptObject1, CKB_LIGHT_RPC_URL) + // get indexCells but not in light + const indexNotInLightCells = indexCells.filter(cell => !lightCells.some(lightCell => { + return lightCell.block_number == cell.block_number && + lightCell.out_point?.tx_hash == cell.out_point?.tx_hash + })) + + // get lightCells but not in index + const lightNotInIndexCells = lightCells.filter(cell => !indexCells.some(indexCell => { + return indexCell.block_number == cell.block_number && + indexCell.out_point?.tx_hash == cell.out_point?.tx_hash + })) + if (indexNotInLightCells.length != 0) { + + compare = false + console.log("indexNotInLightCells") + indexNotInLightCells.forEach(cell => { + console.log( + "blockNum:", BI.from(cell.block_number).toNumber(), + " hash:", cell.out_point?.tx_hash, + " index:", cell.out_point?.index + ) + }) + + } + if (lightNotInIndexCells.length != 0) { + compare = false + console.log("lightNotInIndexCells") + lightNotInIndexCells.forEach(cell => { + console.log( + "blockNum:", BI.from(cell.block_number).toNumber(), + " hash:", cell.out_point?.tx_hash, + " index:", cell.out_point?.index + ) + }) + } + return compare +} + +export async function cut_number(cut_number: number) { + const tip_number = BI.from(await rpcDevCLient.get_tip_block_number()).toNumber() + const reset_num = tip_number - cut_number + return truncate_to_block(reset_num) +} +export async function truncate_to_block(block_number:number){ + const hash = await rpcDevCLient.get_block_hash(BI.from(block_number).toHexString()) + await truncate(CKB_DEV_RPC_URL, hash) +} + +export async function truncate(url, hash: string) { + await request(100, url, "truncate", [hash]) +} + +export async function miner_block_until_number(end_number: number) { + + for (let i = 0; i < 10000; i++) { + await miner_block() + const tip_number = BI.from(await rpcDevCLient.get_tip_block_number()).toNumber() + if (tip_number > end_number) { + return + } + console.log("[miner]current:" + tip_number + ", expected:", end_number) + } + +} + +export async function miner_block_number(height: number) { + const begin_number = BI.from(await rpcDevCLient.get_tip_block_number()).toNumber() + const end_number = begin_number + height + await miner_block_until_number(end_number) +} + +export async function getCellsMsg(scriptObject1: ScriptObject, url: string) { + const tip_number = await rpcDevCLient.get_tip_block_number(); + let cells = await getCellsByRange(scriptObject1, "lock", undefined, url, ["0x0", BI.from(tip_number).toHexString()]) + cells.forEach(tx => console.log( + "blockNum:", BI.from(tx.block_number).toNumber(), + " hash:", tx.out_point?.tx_hash, + " index:", tx.out_point?.index + )) + return cells + +} + + + +export async function miner_block(kill_port: boolean = true) { + if (kill_port) { + await shWithTimeOutNotErr("lsof -i:8888 | grep LIS | awk '{print $2}'| xargs -n1 kill -9", 2000) + } + await shWithTimeOutNotErr(" cd " + CKB_DEV_PATH + " && ./ckb miner -C dev -l 40 > block.log", 2000) + if(kill_port){ + await shWithTimeOutNotErr("lsof -i:8888 | grep LIS | awk '{print $2}'| xargs -n1 kill -9", 2000) + } + await shWithTimeOutNotErr("cat " + CKB_DEV_PATH + "/block.log | grep Found", 1000) +} + +export async function cleanCkbLightClientEnv() { + await sh("cd " + DEV_PATH + " && rm -rf ckb-light-client/target/release/data") +} + +export async function stopCkbLightClient() { + await shWithTimeOutNotErr("pkill ckb-light-client",1000) +} + +export async function startCkbLightClient() { + await sh("cd " + CKB_DEV_LIGHT_CLIENT_PATH +" && RUST_LOG=info,ckb_light_client=trace ./ckb-light-client run --config-file ./config.toml > node.log 2>&1 &") +} + +export async function cleanAndRestartCkbLightClientEnv() { + await stopCkbLightClient() + await cleanCkbLightClientEnv() + await startCkbLightClient() +} + +export async function cleanAllEnv() { + await sh("cd " + DEV_PATH + " && sh clean.sh") +} + +export async function startEnv() { + await shWithTimeout("cd " + DEV_PATH + " sh start.sh", 100_000) +} + +export async function restartAndSyncCkbIndex() { + await shWithTimeOutNotErr(" pkill ckb-indexer",1000) + await sh("cd " + CKB_DEV_INDEX_PATH + " && rm -rf ckb-test && RUST_LOG=info ./ckb-indexer -s ckb-test > ckb-indexer.log 2>&1 &") + await checkCKbIndexSync() +} + +export async function checkCKbIndexSync() { + let acc1 = generateAccountFromPrivateKey(ACCOUNT_PRIVATE); + let tip_num = await rpcDevCLient.get_tip_block_number() + for (let i = 0; i < 1000; i++) { + let cap = await getCellsCapacityRequest({ + search_key: { + script: acc1.lockScript, + script_type: "lock" + } + },CKB_DEV_RPC_INDEX_URL) + if (BI.from(tip_num).lte(BI.from(cap.block_number))) { + return + } + console.log("current sync:", BI.from(cap.block_number).toNumber(), " expected:", BI.from(tip_num).toNumber()) + await Sleep(1000) + } +} diff --git a/service/node.ts b/service/node.ts index 9f7ba4f..0524ebf 100644 --- a/service/node.ts +++ b/service/node.ts @@ -51,11 +51,33 @@ export { } -async function sh(cmd: string) { +export async function shWithTimeOutNotErr(cmd:string,timeout:number){ console.log('sh:', cmd) return new Promise(function (resolve, reject) { - exec(cmd, { timeout: 10000},(err, stdout, stderr) => { + let c = exec(cmd, { timeout: timeout},(err, stdout, stderr) => { if (err) { + // console.log(err) + if(!c.killed){ + c.kill() + } + resolve(err); + } else { + console.log('response:', stdout) + resolve({stdout, stderr}); + } + }); + }); +} +export async function shWithTimeout(cmd:string,timeout:number){ + console.log('sh:', cmd) + return new Promise(function (resolve, reject) { + let c = exec(cmd, { timeout: timeout},(err, stdout, stderr) => { + if (err) { + console.log(err) + console.log(c.pid) + console.log("killed:",c.killed) + // c.kill() + console.log("killed:",c.killed) reject(err); } else { console.log('response:', stdout) @@ -63,6 +85,9 @@ async function sh(cmd: string) { } }); }); +} +export async function sh(cmd: string) { + return await shWithTimeout(cmd,10000) } diff --git a/service/transfer.ts b/service/transfer.ts index baca2b2..3d9a515 100644 --- a/service/transfer.ts +++ b/service/transfer.ts @@ -19,11 +19,10 @@ import { EVERY_ONE_CAN_PAY_TYPE_ID, CKB_LIGHT_RPC_URL, CKB_RPC_INDEX_URL, CKB_RPC_URL, - FEE, FeeRate, rpcCLient } from "../config/config"; -import {CellDep, DepType} from "@ckb-lumos/base/lib/api"; +import {CellDep} from "@ckb-lumos/base/lib/api"; import {ScriptMsg, sendTransaction, setScripts, waitScriptsUpdate} from "../rpc"; import {fetchTransactionUntilFetched} from "./txService"; @@ -32,10 +31,147 @@ const { ScriptValue } = values; export const { AGGRON4 } = config.predefined; - const defaultRpc = new RPC(CKB_RPC_URL); -const indexer = new Indexer(CKB_RPC_INDEX_URL, CKB_RPC_URL); +const defaultIndexer = new Indexer(CKB_RPC_INDEX_URL, CKB_RPC_URL); + +export class TransferService { + readonly defaultRpc :RPC; + // @ts-ignore + readonly defaultIndexer:Indexer; + constructor(ckb_rpc_url: string,ckb_index_url:string) { + this.defaultRpc = new RPC(ckb_rpc_url) + this.defaultIndexer = new Indexer(ckb_index_url,ckb_rpc_url); + } + + + async capacityOf(address: string): Promise { + const collector = this.defaultIndexer.collector({ + lock: helpers.parseAddress(address, { config: AGGRON4 }), + }); + + let balance = BI.from(0); + for await (const cell of collector.collect()) { + balance = balance.add(cell.cell_output.capacity); + } + return balance; + } + + async transfer(options: transferOptions): Promise { + const transferOutput: Cell = getOutPutCell(options.to,options.amount,"0x"); + return this.send_tx({ + from:options.from, + outputCells:[transferOutput], + privKey:options.privKey, + }); + } + + async send_tx(options: Options): Promise { + let txSkeleton = helpers.TransactionSkeleton({}); + const fromScript = helpers.parseAddress(options.from, { config: AGGRON4 }); + + let neededCapacity = BI.from(0) + for (let i = 0; i < options.outputCells.length; i++) { + neededCapacity = neededCapacity.add(options.outputCells[i].cell_output.capacity) + } + let collectedSum = BI.from(0); + const collected: Cell[] = []; + const collector = this.defaultIndexer.collector({ lock: fromScript, type: "empty" }); + for await (const cell of collector.collect()) { + collectedSum = collectedSum.add(cell.cell_output.capacity); + collected.push(cell); + if (collectedSum >= neededCapacity) break; + } + console.log('total cell balance: ',collectedSum.toString()) + + if (collectedSum < neededCapacity) { + throw new Error("Not enough CKB"); + } + + if(collectedSum.sub(neededCapacity).sub(FeeRate.NORMAL).gt(BI.from('0'))) { + const changeOutput: Cell = { + cell_output: { + capacity: collectedSum.sub(neededCapacity).sub(FeeRate.NORMAL).toHexString(), + lock: fromScript, + }, + data: "0x", + }; + console.log('gen out put extra value ') + txSkeleton = txSkeleton.update("outputs", (outputs) => outputs.push(changeOutput)); + } + let SECP256K1_BLAKE160_HASH = (await this.defaultRpc.get_block_by_number("0x0")).transactions[1].hash + console.log("SECP256K1_BLAKE160_HASH:",SECP256K1_BLAKE160_HASH) + txSkeleton = txSkeleton.update("outputs", (outputs) => outputs.push(...options.outputCells)); + txSkeleton = txSkeleton.update("inputs", (inputs) => inputs.push(...collected)); + txSkeleton = txSkeleton.update("cellDeps", (cellDeps) => + cellDeps.push(...[ + { + out_point: { + tx_hash:SECP256K1_BLAKE160_HASH, + index: AGGRON4.SCRIPTS.SECP256K1_BLAKE160.INDEX, + }, + dep_type: AGGRON4.SCRIPTS.SECP256K1_BLAKE160.DEP_TYPE, + } + ]) + ); + txSkeleton = txSkeleton.update("cellDeps",(cellDeps)=> cellDeps.push(...options.deps)); + + const firstIndex = txSkeleton + .get("inputs") + .findIndex((input) => + new ScriptValue(input.cell_output.lock, { validate: false }).equals( + new ScriptValue(fromScript, { validate: false }) + ) + ); + if (firstIndex !== -1) { + while (firstIndex >= txSkeleton.get("witnesses").size) { + txSkeleton = txSkeleton.update("witnesses", (witnesses) => witnesses.push("0x")); + } + let witness: string = txSkeleton.get("witnesses").get(firstIndex)!; + const newWitnessArgs: WitnessArgs = { + /* 65-byte zeros in hex */ + lock: + "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }; + if (witness !== "0x") { + const witnessArgs = new core.WitnessArgs(new toolkit.Reader(witness)); + const lock = witnessArgs.getLock(); + if (lock.hasValue() && new toolkit.Reader(lock.value().raw()).serializeJson() !== newWitnessArgs.lock) { + throw new Error("Lock field in first witness is set aside for signature!"); + } + const inputType = witnessArgs.getInputType(); + if (inputType.hasValue()) { + newWitnessArgs.input_type = new toolkit.Reader(inputType.value().raw()).serializeJson(); + } + const outputType = witnessArgs.getOutputType(); + if (outputType.hasValue()) { + newWitnessArgs.output_type = new toolkit.Reader(outputType.value().raw()).serializeJson(); + } + } + witness = new toolkit.Reader( + core.SerializeWitnessArgs(toolkit.normalizers.NormalizeWitnessArgs(newWitnessArgs)) + ).serializeJson(); + txSkeleton = txSkeleton.update("witnesses", (witnesses) => witnesses.set(firstIndex, witness)); + } + + + txSkeleton = commons.common.prepareSigningEntries(txSkeleton); + const message = txSkeleton.get("signingEntries").get(0)?.message; + const Sig = hd.key.signRecoverable(message!, options.privKey); + const tx = helpers.sealTransaction(txSkeleton, [Sig]); + if( options.lightMode == true){ + if(options.lightNotInstallCellMode == null||options.lightNotInstallCellMode == false){ + await installTxCells(tx) + } + const hash = await sendTransaction(tx,CKB_LIGHT_RPC_URL) + console.log("The CKB_LIGHT_RPC_URL transaction hash is", hash); + return hash; + } + const hash = await this.defaultRpc.send_transaction(tx, "passthrough"); + console.log("The transaction hash is", hash); + return hash; + } +} type Account = { lockScript: Script; address: Address; @@ -59,7 +195,7 @@ export const generateAccountFromPrivateKey = (privKey: string): Account => { }; export async function capacityOf(address: string): Promise { - const collector = indexer.collector({ + const collector = defaultIndexer.collector({ lock: helpers.parseAddress(address, { config: AGGRON4 }), }); @@ -99,6 +235,7 @@ function getOutPutCell(to:string,amount: string,data:string):Cell{ }; } + export async function transfer(options: transferOptions): Promise { const transferOutput: Cell = getOutPutCell(options.to,options.amount,"0x"); @@ -140,19 +277,10 @@ export async function send_tx_with_input(options:Options):Promise{ }, dep_type: AGGRON4.SCRIPTS.SUDT.DEP_TYPE, } - // { - // out_point: { - // tx_hash: ANY_ONE_CAN_PAY.TX_HASH, - // index: ANY_ONE_CAN_PAY.INDEX, - // }, - // dep_type: "code", - // } + ]) ); - // txSkeleton = txSkeleton.update("cellDeps", (cellDeps) => - // cellDeps.push() - // ); const firstIndex = txSkeleton .get("inputs") @@ -312,18 +440,14 @@ export async function send_tx_options(options:Options):Promise{ export async function send_tx(options: Options): Promise { let txSkeleton = helpers.TransactionSkeleton({}); const fromScript = helpers.parseAddress(options.from, { config: AGGRON4 }); - // const toScript = helpers.parseAddress(options.to, { config: AGGRON4 }); - // additional 0.001 ckb for tx fee - // the tx fee could calculated by tx size - // this is just a simple example let neededCapacity = BI.from(0) for (let i = 0; i < options.outputCells.length; i++) { neededCapacity = neededCapacity.add(options.outputCells[i].cell_output.capacity) } let collectedSum = BI.from(0); const collected: Cell[] = []; - const collector = indexer.collector({ lock: fromScript, type: "empty" }); + const collector = defaultIndexer.collector({ lock: fromScript, type: "empty" }); for await (const cell of collector.collect()) { collectedSum = collectedSum.add(cell.cell_output.capacity); collected.push(cell); @@ -344,40 +468,27 @@ export async function send_tx(options: Options): Promise { data: "0x", }; console.log('gen out put extra value ') - txSkeleton = txSkeleton.update("outputs", (outputs) => outputs.push(changeOutput)); + if(collectedSum.sub(neededCapacity).sub(FeeRate.NORMAL).gt(6100000000)){ + //expected occupied capacity (0x16b969d00) + txSkeleton = txSkeleton.update("outputs", (outputs) => outputs.push(changeOutput)); + }else { + options.outputCells[0].cell_output.capacity = collectedSum.sub(neededCapacity).sub(FeeRate.NORMAL).add(options.outputCells[0].cell_output.capacity).toHexString() + } } + + let SECP256K1_BLAKE160_HASH = (await defaultRpc.get_block_by_number("0x0")).transactions[1].hash + txSkeleton = txSkeleton.update("outputs", (outputs) => outputs.push(...options.outputCells)); txSkeleton = txSkeleton.update("inputs", (inputs) => inputs.push(...collected)); txSkeleton = txSkeleton.update("cellDeps", (cellDeps) => cellDeps.push(...[ { out_point: { - tx_hash: AGGRON4.SCRIPTS.SECP256K1_BLAKE160.TX_HASH, + tx_hash:SECP256K1_BLAKE160_HASH, index: AGGRON4.SCRIPTS.SECP256K1_BLAKE160.INDEX, }, dep_type: AGGRON4.SCRIPTS.SECP256K1_BLAKE160.DEP_TYPE, } - ,{ - out_point: { - tx_hash: AGGRON4.SCRIPTS.SUDT.TX_HASH, - index: AGGRON4.SCRIPTS.SUDT.INDEX, - }, - dep_type: AGGRON4.SCRIPTS.SUDT.DEP_TYPE, - }, - // { - // out_point: { - // tx_hash: ANY_ONE_CAN_PAY_TYPE_ID.TX_HASH, - // index: ANY_ONE_CAN_PAY_TYPE_ID.INDEX, - // }, - // dep_type: AGGRON4.SCRIPTS.SUDT.DEP_TYPE, - // } - // { - // out_point: { - // tx_hash: ANY_ONE_CAN_PAY.TX_HASH, - // index: ANY_ONE_CAN_PAY.INDEX, - // }, - // dep_type: "code", - // } ]) ); txSkeleton = txSkeleton.update("cellDeps",(cellDeps)=> cellDeps.push(...options.deps)); @@ -430,6 +541,7 @@ export async function send_tx(options: Options): Promise { if(options.lightNotInstallCellMode == null||options.lightNotInstallCellMode == false){ await installTxCells(tx) } + console.log("send tx:",tx) const hash = await sendTransaction(tx,CKB_LIGHT_RPC_URL) console.log("The CKB_LIGHT_RPC_URL transaction hash is", hash); return hash; diff --git a/test/common_scripts/deploy.spec.ts b/test/common_scripts/deploy.spec.ts index 12737a8..8fe98f7 100644 --- a/test/common_scripts/deploy.spec.ts +++ b/test/common_scripts/deploy.spec.ts @@ -1,10 +1,14 @@ import { deployContractByArray, upgradeContract} from "../../service/deploy.util"; -import {ACCOUNT_PRIVATE, ACCOUNT_PRIVATE2, EVERY_ONE_CAN_PAY} from "../../config/config"; +import {ACCOUNT_PRIVATE, ACCOUNT_PRIVATE2, CKB_RPC_URL, EVERY_ONE_CAN_PAY, rpcCLient} from "../../config/config"; import * as fs from 'fs-extra'; import {AGGRON4, generateAccountFromPrivateKey, send_tx, send_tx_with_input, transfer} from "../../service/transfer"; import {Hash, HexNumber} from "@ckb-lumos/base/lib/primitive"; import {OutPoint, Script} from "@ckb-lumos/base/lib/api"; import {BI} from "@ckb-lumos/lumos"; +import {request} from "../../service"; +import {CKB_TEST_RPC_URL} from "../unifra/config"; +import {getTransactionWaitCommit} from "../../service/txService"; +import {Sleep} from "../../service/util"; // // fs.readFile('/Users/joe/test.txt', 'utf8' , (err, data) => { // if (err) { @@ -48,32 +52,26 @@ describe('demo', function () { console.log('result:',result) + }) + it("wait tx",async ()=>{ + for (let i = 0; i < 100000000; i++) { + await request(1,CKB_TEST_RPC_URL,"clear_tx_pool",[]) + await Sleep(50) + } + }) it('transfer ', async () => { let account = generateAccountFromPrivateKey(ACCOUNT_PRIVATE) - let tx = await send_tx({ - privKey: ACCOUNT_PRIVATE, - from: account.address, - outputCells: [{ - cell_output: { - capacity: BI.from(100 * 100000000).toHexString(), - lock: { - code_hash: EVERY_ONE_CAN_PAY.CODE_HASH, - hash_type: "type", - args: "0x", - }, - type: { - code_hash: EVERY_ONE_CAN_PAY.CODE_HASH, - hash_type: "type", - args: "0x", - } - }, - data: "0x" - }] - } - ) + let tx = await transfer({ + from: account.address, + to: account.address, + amount: "80", + privKey: ACCOUNT_PRIVATE, + }) console.log('tx:', tx) + + await getTransactionWaitCommit(tx,CKB_RPC_URL,100) }) it('cost any pay ', async () => { diff --git a/test/dev/ckbIndexPanic.spec.ts b/test/dev/ckbIndexPanic.spec.ts new file mode 100644 index 0000000..199705e --- /dev/null +++ b/test/dev/ckbIndexPanic.spec.ts @@ -0,0 +1,43 @@ +import { + cleanAllEnv, + cut_miner_and_wait_lightClient_sync, + miner_block_number, + miner_block_until_number, restartAndSyncCkbIndex, truncate_to_block +} from "../../service/CkbDevService"; +import {ACCOUNT_PRIVATE, CKB_DEV_INDEX_PATH, CKB_DEV_RPC_INDEX_URL, rpcDevCLient} from "../../config/config"; +import {BI} from "@ckb-lumos/bi"; +import {sh} from "../../service/node"; +import {expect} from "chai"; +import {Sleep} from "../../service/util"; +import {getCellsCapacity, getCellsCapacityRequest} from "../../rpc"; +import {generateAccountFromPrivateKey} from "../../service/transfer"; + +describe('ckb-index', function () { + + this.timeout(100000_000) + + it("ckb-index panic test ", async () =>{ + // await cleanAllEnv() + await miner_block_until_number(1050 ) + await truncate_to_block(1020) + await Sleep(1) + await restartAndSyncCkbIndex() + await cut_miner_and_wait_lightClient_sync(90, 91) + try { + await getCellsCapacityRequest({ + search_key: { + script:generateAccountFromPrivateKey(ACCOUNT_PRIVATE).lockScript, + script_type:"lock", + } + }, CKB_DEV_RPC_INDEX_URL) }catch (e){ + console.log(e) + await catCkbIndexLog() + expect("").to.be.equal("failed") + } + }) + +}); + +async function catCkbIndexLog(){ + await sh("cd "+CKB_DEV_INDEX_PATH+" && cat ckb-indexer.log") +} diff --git a/test/dev/ckbLightClientCut.spec.ts b/test/dev/ckbLightClientCut.spec.ts new file mode 100644 index 0000000..9e9da6b --- /dev/null +++ b/test/dev/ckbLightClientCut.spec.ts @@ -0,0 +1,155 @@ +import { + cleanAndRestartCkbLightClientEnv, + compare_cells_result, + cut_miner_and_wait_lightClient_sync, miner_block, + miner_block_until_number, restartAndSyncCkbIndex, transferDevService +} from "../../service/CkbDevService"; +import {expect} from "chai"; +import {generateAccountFromPrivateKey, transfer} from "../../service/transfer"; +import { + ACCOUNT_PRIVATE, + ACCOUNT_PRIVATE2, + CKB_DEV_RPC_INDEX_URL, + CKB_DEV_RPC_URL, CKB_LIGHT_RPC_URL, + rpcDevCLient +} from "../../config/config"; +import {checkScriptsInLightClient, getCellsCapacityRequest, setScripts, waitScriptsUpdate} from "../../rpc"; +import {BI} from "@ckb-lumos/bi"; +import {getTransactionWaitCommit} from "../../service/txService"; + +describe('rollback', function () { + + this.timeout(10000000) + let miner = generateAccountFromPrivateKey(ACCOUNT_PRIVATE) + let acc2 = generateAccountFromPrivateKey(ACCOUNT_PRIVATE2); + + async function initLightClient() { + if (!(await checkScriptsInLightClient([miner.lockScript, acc2.lockScript]))) { + await setScripts([ + { + script: miner.lockScript, + script_type: "lock", + block_number: "0x0" + }, + { + script: acc2.lockScript, + script_type: "lock", + block_number: "0x0" + } + ]) + } + + let tip_num = await rpcDevCLient.get_tip_block_number() + await waitScriptsUpdate(BI.from(tip_num)) + } + + it("cut 10 ,miner 11 ,check rollback succ", async () => { + await cleanAndRestartCkbLightClientEnv() + await miner_block_until_number(1050) + await initLightClient() + // for (let i = 0; i < 100; i++) { + const result = await compare_cells_result(miner.lockScript) + await cut_miner_and_wait_lightClient_sync(13, 14) + const result2 = await compare_cells_result(miner.lockScript) + expect(result).to.be.equal(true) + expect(result2).to.be.equal(true) + // } + }) + + it("cut 300 ,miner 400,check roll back", async () => { + await cleanAndRestartCkbLightClientEnv() + await miner_block_until_number(500) + await initLightClient() + + // for (let i = 0; i < 100; i++) { + const result = await compare_cells_result(miner.lockScript) + await cut_miner_and_wait_lightClient_sync(300, 400) + await restartAndSyncCkbIndex() + const result2 = await compare_cells_result(miner.lockScript) + expect(result).to.be.equal(true) + expect(result2).to.be.equal(true) + // } + }) + + it("transfer roll back ", async () => { + await miner_block_until_number(1500) + await cleanAndRestartCkbLightClientEnv() + await initLightClient() + for (let i = 0; i < 2; i++) { + await transfer_cut_and_wait_light_sync(900) + await restartAndSyncCkbIndex() + let compareMiner = await compare_cells_result(miner.lockScript) + let compareTo = await compare_cells_result(acc2.lockScript) + let result = await getCapMsg() + console.log("result:", result) + // expect(compareMiner).to.be.equal(true) + // expect(compareTo).to.be.equal(true) + expect(result.acc2_light).to.be.equal(result.acc2_index) + } + + }) + + async function getCapMsg() { + const acc1Index = await getCellsCapacityRequest({ + search_key: { + script: miner.lockScript, + script_type: "lock", + } + }, CKB_DEV_RPC_INDEX_URL) + const accLight = await getCellsCapacityRequest({ + search_key: { + script: miner.lockScript, + script_type: "lock", + } + }, CKB_LIGHT_RPC_URL) + + const acc2Index = await getCellsCapacityRequest({ + search_key: { + script: acc2.lockScript, + script_type: "lock", + } + }, CKB_DEV_RPC_INDEX_URL) + const acc2Light = await getCellsCapacityRequest({ + search_key: { + script: acc2.lockScript, + script_type: "lock", + } + }, CKB_LIGHT_RPC_URL) + return { + miner_Index: BI.from(acc1Index.capacity).toNumber(), + miner_light: BI.from(accLight.capacity).toNumber(), + acc2_index: BI.from(acc2Index.capacity).toNumber(), + acc2_light: BI.from(acc2Light.capacity).toNumber() + } + } + + + async function transfer_cut_and_wait_light_sync(transfer_num: number) { + await miner_block(false) + let begin_tip_num = await rpcDevCLient.get_tip_block_number() + let tx = await transferDevService.transfer({ + from: miner.address, + to: acc2.address, + amount: BI.from(transfer_num).toHexString(), + privKey: ACCOUNT_PRIVATE, + }) + + await getTransactionWaitCommit(tx, CKB_DEV_RPC_URL, 10) + await miner_block(false) + await miner_block(false) + await getTransactionWaitCommit(tx, CKB_DEV_RPC_URL, 10000) + let tip = await rpcDevCLient.get_tip_block_number() + await waitScriptsUpdate(BI.from(tip)) + const cap1 = await getCellsCapacityRequest({ + search_key: { + script: acc2.lockScript, + script_type: "lock", + } + }) + console.log("account 2 cap:", BI.from(cap1.capacity).toNumber()) + const end_tip_num = await rpcDevCLient.get_tip_block_number() + let cut_num = BI.from(end_tip_num).sub(begin_tip_num).toNumber() + await cut_miner_and_wait_lightClient_sync(cut_num, cut_num + 10) + } + +}); diff --git a/test/fetch_header.spec.ts b/test/fetch_header.spec.ts index eb1724b..7aae44a 100644 --- a/test/fetch_header.spec.ts +++ b/test/fetch_header.spec.ts @@ -6,7 +6,7 @@ import {BI} from "@ckb-lumos/bi"; describe('fetch_header', function () { - this.timeout(1000_10000) + this.timeout(600_000) it("genesis hash,should return fetched", async () => { // https://pudge.explorer.nervos.org/block/0x10639e0895502b5688a6be8cf69460d76541bfa4821629d86d62ba0aae3f9606 diff --git a/test/fetch_transaction.spec.ts b/test/fetch_transaction.spec.ts index 36dcc56..53572c3 100644 --- a/test/fetch_transaction.spec.ts +++ b/test/fetch_transaction.spec.ts @@ -1,6 +1,6 @@ import {ACCOUNT_PRIVATE, CKB_RPC_URL, rpcCLient} from "../config/config"; import {BI} from "@ckb-lumos/bi"; -import {fetch_header, fetch_transaction} from "../rpc"; +import { fetch_transaction} from "../rpc"; import {expect} from "chai"; import {Sleep} from "../service/util"; import {generateAccountFromPrivateKey, transfer} from "../service/transfer"; @@ -33,7 +33,7 @@ describe('fetch_transaction', function () { let tx = await transfer({ from: account.address, to: account.address, - amount:BI.from(500).toHexString(), + amount:BI.from(501).toHexString(), privKey:ACCOUNT_PRIVATE, }) await waitFetchedHeaderStatusChange(tx,"fetched",10000) diff --git a/test/get_cells.spec.ts b/test/get_cells.spec.ts index d382350..45f86cb 100644 --- a/test/get_cells.spec.ts +++ b/test/get_cells.spec.ts @@ -18,7 +18,7 @@ import {Cell} from "@ckb-lumos/base/lib/api"; describe('get_cell', function () { - this.timeout(1000000000) + this.timeout(600_000) describe('search_key', function () { diff --git a/test/get_cells_capacity.spec.ts b/test/get_cells_capacity.spec.ts index caadba2..3993eb1 100644 --- a/test/get_cells_capacity.spec.ts +++ b/test/get_cells_capacity.spec.ts @@ -21,7 +21,7 @@ import {getMinBlockNumByCells} from "./get_cells.spec"; describe('get_cells_capacity', function () { - this.timeout(100000000) + this.timeout(600_000) describe('search_key', function () { const snapshot = true diff --git a/test/get_header.spec.ts b/test/get_header.spec.ts index 1d72ef4..90dc352 100644 --- a/test/get_header.spec.ts +++ b/test/get_header.spec.ts @@ -7,7 +7,7 @@ import {generateAccountFromPrivateKey} from "../service/transfer"; describe('get_header', function () { - this.timeout(600000) + this.timeout(600_000) it("query the hash that does not exist on the ckb chain,should return null", async () => { let response = await getHeader("0x1d7c6f92fa3335bf01c3f43f8970cb586d2dee81b90d363169dbe1bba98d6c11") diff --git a/test/get_tip_header.spec.ts b/test/get_tip_header.spec.ts index 8fd5c42..fa11580 100644 --- a/test/get_tip_header.spec.ts +++ b/test/get_tip_header.spec.ts @@ -4,7 +4,7 @@ import * as assert from "assert"; describe('get_tip_header', function () { - this.timeout(100000) + this.timeout(10000) it('light node getTipHeader,should result in ckb',async()=>{ let lightRes = await getTipHeader(CKB_LIGHT_RPC_URL) let indexRes = await getHeader(lightRes.hash,CKB_RPC_URL) diff --git a/test/get_transaction.spec.ts b/test/get_transaction.spec.ts index 945562e..3bb6e15 100644 --- a/test/get_transaction.spec.ts +++ b/test/get_transaction.spec.ts @@ -13,7 +13,7 @@ import {Sleep} from "../service/util"; describe('get_transaction', function () { - this.timeout(1000000) + this.timeout(600_000) it('txHash does not conform to hash rules', async () => { try { await getTransaction("0x3a46167541123530ac8100841d4e014028c60af18305e5594452d0b8aa65b1") @@ -60,7 +60,7 @@ describe('get_transaction', function () { } // @ts-ignore - await setScripts([{script: script, block_number: BI.from(cells.objects[0].block_number).sub(1).toHexString()}]) + await setScripts([{script: script, script_type:"lock",block_number: BI.from(cells.objects[0].block_number).sub(1).toHexString()}]) let collect_cells_length = 0 await waitScriptsUpdate(BI.from(cells.objects[0].block_number).add(100)) let lightCells = await getCells(script) diff --git a/test/runners/mocha/.mocharc.dev.jsonc b/test/runners/mocha/.mocharc.dev.jsonc new file mode 100644 index 0000000..2083470 --- /dev/null +++ b/test/runners/mocha/.mocharc.dev.jsonc @@ -0,0 +1,8 @@ +{ + "require": [ + "test/runners/mocha/init.js" + ], + "spec": [ + "test/dev/ckbLightClientCut.spec.ts" + ] +} diff --git a/test/runners/mocha/.mocharc.index-panic.jsonc b/test/runners/mocha/.mocharc.index-panic.jsonc new file mode 100644 index 0000000..265a596 --- /dev/null +++ b/test/runners/mocha/.mocharc.index-panic.jsonc @@ -0,0 +1,8 @@ +{ + "require": [ + "test/runners/mocha/init.js" + ], + "spec": [ + "test/dev/ckbIndexPanic.spec.ts" + ] +} diff --git a/test/runners/mocha/.mocharc.jsonc b/test/runners/mocha/.mocharc.jsonc index 7fb2d80..6b643e6 100644 --- a/test/runners/mocha/.mocharc.jsonc +++ b/test/runners/mocha/.mocharc.jsonc @@ -3,12 +3,17 @@ "test/runners/mocha/init.js" ], "spec": [ - "test/get_tip_header.spec.ts", - "test/get_header.spec.ts", - "test/get_transaction.spec.ts", - "test/set_scripts.spec.ts", - "test/scenes.test.ts", - "test/get_cells.spec.ts", - "test/get_cells_capacity.spec.ts" + "test/fetch_header.spec.ts", + "test/fetch_transaction.spec.ts", +// "test/get_cells.spec.ts", + "test/get_cells_capacity.spec.ts", + "test/get_genesis_block.spec.ts", + "test/get_header.spec.ts", + "test/get_scripts.spec.ts", + "test/get_tip_header.spec.ts" +// "test/get_transaction.spec.ts", +// "test/get_transactions.spec.ts", +// "test/set_scripts.spec.ts", +// "test/scenes.test.ts" ] } diff --git a/test/runners/mocha/.mocharc.light.rollback.jsonc b/test/runners/mocha/.mocharc.light.rollback.jsonc new file mode 100644 index 0000000..2083470 --- /dev/null +++ b/test/runners/mocha/.mocharc.light.rollback.jsonc @@ -0,0 +1,8 @@ +{ + "require": [ + "test/runners/mocha/init.js" + ], + "spec": [ + "test/dev/ckbLightClientCut.spec.ts" + ] +} diff --git a/test/scenes.test.ts b/test/scenes.test.ts index 4c2648b..084938a 100644 --- a/test/scenes.test.ts +++ b/test/scenes.test.ts @@ -17,12 +17,12 @@ import { import {expect} from "chai"; import {BI, RPC} from "@ckb-lumos/lumos"; import {Output} from "@ckb-lumos/base/lib/api"; -import { generateAccountFromPrivateKey, getBlockNumByTxHash, send_tx} from "../service/transfer"; +import {AGGRON4, generateAccountFromPrivateKey, getBlockNumByTxHash, send_tx} from "../service/transfer"; import {issueTokenCell} from "../service/sudt"; import {Sleep} from "../service/util"; describe('scenes', function () { - this.timeout(1000000000) + this.timeout(600_000) describe('clean data ', function () { before(async () => { @@ -145,7 +145,16 @@ describe('scenes', function () { from: acc.address, outputCells: [cell], privKey: ACCOUNT_PRIVATE, - lightMode: true + lightMode: true, + deps: [ + { + out_point: { + tx_hash: AGGRON4.SCRIPTS.SUDT.TX_HASH, + index: AGGRON4.SCRIPTS.SUDT.INDEX, + }, + dep_type: AGGRON4.SCRIPTS.SUDT.DEP_TYPE, + } + ] }) console.log('tx:', tx) }) @@ -169,7 +178,7 @@ describe('scenes', function () { // cost tx: https://pudge.explorer.nervos.org/transaction/0x1850f997f867b6d3f1154444498a15e9fc4ce080215e34d0c41b33349bcc119a { script: MINER_SCRIPT3, - script_type:"lock", + script_type: "lock", block_number: "0x0" // block_number:"0x3e8" @@ -340,7 +349,7 @@ describe('scenes', function () { it('get capacity,should > 0', async () => { let capacityOnSync = await getCellsCapacity(MINER_SCRIPT3) - expect(BI.from(capacityOnSync).toNumber()).to.be.gt(0) + expect(BI.from(capacityOnSync.capacity).toNumber()).to.be.gt(0) }) }); @@ -375,7 +384,7 @@ describe('scenes', function () { // cost tx: https://pudge.explorer.nervos.org/transaction/0x1850f997f867b6d3f1154444498a15e9fc4ce080215e34d0c41b33349bcc119a { script: MINER_SCRIPT3, - script_type:"lock", + script_type: "lock", block_number: "0x0" }]) @@ -427,33 +436,33 @@ describe('scenes', function () { it('高度未达到上次set_script,get_cell收集的数量不变', async () => { for (let i = 0; i < 100; i++) { let capacity = await getCellsCapacity(MINER_SCRIPT3) - let height = await getScriptsHeight() - console.log('height:',height.toNumber(),' cap:',BI.from(capacity).toNumber()) + let height = await getScriptsHeight() + console.log('height:', height.toNumber(), ' cap:', BI.from(capacity.capacity).toNumber()) } }) }); describe('get_transactions', function () { - it('should > 0 ',async ()=>{ - let scriptLength = await getTransactionsLength(MINER_SCRIPT3,undefined,CKB_LIGHT_RPC_URL) + it('should > 0 ', async () => { + let scriptLength = await getTransactionsLength(MINER_SCRIPT3, undefined, CKB_LIGHT_RPC_URL) expect(scriptLength).to.be.gt(1) }) }); describe('get_cells_capacity', function () { - it('should > 0',async ()=>{ + it('should > 0', async () => { let result = await getCellsCapacity(MINER_SCRIPT3) - expect(BI.from(result).toNumber()).to.be.gt(1) + expect(BI.from(result.capacity).toNumber()).to.be.gt(1) }) }); }); describe('script [[]]', function () { - before(async ()=>{ + before(async () => { await setScripts([]) let result = await getScripts() - console.log('result:',result) + console.log('result:', result) expect(result.toString()).to.be.equal('') }) describe('get_cells', function () { @@ -462,12 +471,12 @@ describe('scenes', function () { //todo }) }); - describe('getCellsCapacity',function (){ - it('The previous script will not continue to update',async ()=>{ + describe('getCellsCapacity', function () { + it('The previous script will not continue to update', async () => { let response = await getCellsCapacity(MINER_SCRIPT3) - await Sleep(1000*10) + await Sleep(1000 * 10) let response2 = await getCellsCapacity(MINER_SCRIPT3) - expect(response).to.be.equal(response2) + expect(response.capacity).to.be.equal(response2.capacity) }) }) }); @@ -524,20 +533,21 @@ async function getScriptsHeight(): Promise { let scriptObj = await getScripts() return BI.from(scriptObj[0].block_number) } -export async function getTransactionsLength(scriptObject: ScriptObject,lastCursor:string,url:string) { + +export async function getTransactionsLength(scriptObject: ScriptObject, lastCursor: string, url: string) { let totalSize = 0 - while (true){ + while (true) { let result = await getTransactions({ - script:scriptObject, + script: scriptObject, script_type: "lock", - group_by_transaction:true - },{sizeLimit:10000,lastCursor:lastCursor},url) - if(result.objects.length == 0){ + group_by_transaction: true + }, {sizeLimit: 10000, lastCursor: lastCursor}, url) + if (result.objects.length == 0) { break } totalSize += result.objects.length lastCursor = result.lastCursor - console.log('current totalSize:',totalSize,'cursor:',lastCursor) + console.log('current totalSize:', totalSize, 'cursor:', lastCursor) } return totalSize } diff --git a/test/send_transaction.spec.ts b/test/send_transaction.spec.ts index 4dbb3c5..a98cc7d 100644 --- a/test/send_transaction.spec.ts +++ b/test/send_transaction.spec.ts @@ -6,32 +6,7 @@ import {getCells} from "../rpc"; describe('send_transaction', function () { // transfer test - this.timeout(100000000) - it('should ', async () => { - console.log('demo') - let acc = generateAccountFromPrivateKey(ACCOUNT_PRIVATE) - - //get cells - // let cells = await getCells(acc.lockScript,CKB_RPC_INDEX_URL) - // console.log('cell:',cells) - // update all cells - - // send tx - - // until cells update - - // get cell will update - - let tx = await transfer({ - from: acc.address, - to: "ckt1qyq8s90x8tkwv2hpx6tn8696fx8m7klr6m6stqrkje", - amount: "500", - privKey: ACCOUNT_PRIVATE, - }) - console.log('tx:', tx) - - // - }); + this.timeout(600_000) it('发送一笔重复的交易', async () => { @@ -40,7 +15,7 @@ describe('send_transaction', function () { }) it('发送一笔包含已经用过cell的交易', async () => { - + 600000 }) it('发送一笔执行会报错的交易', async () => { diff --git a/test/set_scripts.spec.ts b/test/set_scripts.spec.ts index c930086..918b2e4 100644 --- a/test/set_scripts.spec.ts +++ b/test/set_scripts.spec.ts @@ -59,7 +59,7 @@ describe('set_scripts', function () { it('set with too many scripts,should return null',async ()=>{ - const size = 33000; + const size = 10000; let scripts:ScriptMsg[] = []; for (let i = 0; i < size; i++) {