-
Notifications
You must be signed in to change notification settings - Fork 53
/
Copy pathexecutor.ts
97 lines (86 loc) · 2.62 KB
/
executor.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { DataLoader, ExecuteResult, Executor } from "./types";
import { TransactionSkeletonType } from "@ckb-lumos/helpers";
import { randomBytes } from "@ckb-lumos/crypto";
import { spawnSync } from "child_process";
import { Hash } from "@ckb-lumos/base";
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import { parseDebuggerData, parseDebuggerMessage } from "./parse";
interface DebuggerOptions {
readonly loader: DataLoader;
readonly debuggerPath?: string;
}
type Options = {
/**
* script hash to execute
* @example
* computeScriptHash(inputs[0].lock)
*/
scriptHash: Hash;
/**
* script group type to execute
*/
scriptGroupType: "lock" | "type";
};
// TODO maybe we can compile the ckb-debugger to a wasm or a node module
export class CKBDebugger implements Executor {
loader: DataLoader;
debuggerPath: string;
constructor(payload: DebuggerOptions) {
this.loader = payload.loader;
const debuggerPath = payload.debuggerPath || process.env.CKB_DEBUGGER_PATH;
if (!debuggerPath) {
throw new Error(
"Cannot find ckb-debugger, please set CKB_DEBUGGER_PATH env"
);
}
this.debuggerPath = debuggerPath;
}
/**
* save tx skeleton to tmp file and return the path
* @param txSkeleton
* @private
*/
private saveTmpTxFile(txSkeleton: TransactionSkeletonType): string {
const debuggerData = parseDebuggerData(txSkeleton, this.loader);
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
const randomHex = Buffer.from(randomBytes(18)).toString("hex");
const tempFileName = `lumos-debugger-data-${randomHex}`;
const tmpTxPath = path.join(os.tmpdir(), `${tempFileName}.json`);
fs.writeFileSync(tmpTxPath, JSON.stringify(debuggerData));
return tmpTxPath;
}
async execute(
txSkeleton: TransactionSkeletonType,
options: Options
): Promise<ExecuteResult> {
const tmpTxPath = this.saveTmpTxFile(txSkeleton);
const buf = spawnSync(
this.debuggerPath,
[
"--tx-file",
tmpTxPath,
"--script-hash",
options.scriptHash,
"--script-group-type",
options.scriptGroupType,
],
{
env: { RUST_LOG: "debug" },
}
);
// when ckb-debugger can't be located, they're null.
if (buf.stdout != null && buf.stderr != null) {
return parseDebuggerMessage(
buf.stdout.toString("utf-8"),
buf.stderr.toString("utf-8")
);
} else {
/* c8 ignore next 3 */
throw new Error(
`Failed to install ckb-debugger or ckb-debugger can't be located at ${this.debuggerPath}`
);
}
}
}