Skip to content

Commit fd4657e

Browse files
author
Luca Cillario
committed
Add router and vrf oracle to validator cli
1 parent a1dfd59 commit fd4657e

File tree

5 files changed

+247
-5
lines changed

5 files changed

+247
-5
lines changed

.github/packages/npm-package/ephemeralValidator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import fs from "fs";
33
import { spawn, spawnSync } from "child_process";
44
import path from "path";
55
import { arch, platform } from "os";
6-
import { version } from "./package.json";
6+
import { VERSIONS } from "./versions";
77

8-
const PACKAGE_VERSION = `ephemeral-validator ${version}`;
8+
const PACKAGE_VERSION = `ephemeral-validator ${VERSIONS.EPHEMERAL_VALIDATOR}`;
99

1010
function getBinaryVersion(location: string): [string | null, string | null] {
1111
const result = spawnSync(location, ["--version"]);

.github/packages/npm-package/package.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@magicblock-labs/ephemeral-validator",
3-
"version": "0.2.3",
3+
"version": "0.2.5",
44
"description": "MagicBlock Ephemeral Validator",
55
"homepage": "https://github.com/magicblock-labs/ephemeral-validator#readme",
66
"bugs": {
@@ -13,7 +13,9 @@
1313
"license": "Business Source License 1.1",
1414
"bin": {
1515
"ephemeral-validator": "ephemeralValidator.js",
16-
"mb-test-validator": "mbTestValidator.js"
16+
"mb-test-validator": "mbTestValidator.js",
17+
"rpc-router": "rpcRouter.js",
18+
"vrf-oracle": "vrfOracle.js"
1719
},
1820
"scripts": {
1921
"typecheck": "tsc --noEmit",
@@ -32,7 +34,15 @@
3234
"@magicblock-labs/ephemeral-validator-darwin-x64": "0.2.3",
3335
"@magicblock-labs/ephemeral-validator-linux-arm64": "0.2.3",
3436
"@magicblock-labs/ephemeral-validator-linux-x64": "0.2.3",
35-
"@magicblock-labs/ephemeral-validator-windows-x64": "0.2.3"
37+
"@magicblock-labs/ephemeral-validator-windows-x64": "0.2.3",
38+
"@magicblock-labs/vrf-oracle-linux-x64": "0.2.0",
39+
"@magicblock-labs/vrf-oracle-linux-arm64": "0.2.0",
40+
"@magicblock-labs/vrf-oracle-darwin-x64": "0.2.0",
41+
"@magicblock-labs/vrf-oracle-darwin-arm64": "0.2.0",
42+
"@magicblock-labs/rpc-router-linux-x64": "0.0.1",
43+
"@magicblock-labs/rpc-router-linux-arm64": "0.0.1",
44+
"@magicblock-labs/rpc-router-darwin-x64": "0.0.1",
45+
"@magicblock-labs/rpc-router-darwin-arm64": "0.0.1"
3646
},
3747
"publishConfig": {
3848
"access": "public"
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/env node
2+
import fs from "fs";
3+
import { spawn, spawnSync } from "child_process";
4+
import path from "path";
5+
import { arch, platform } from "os";
6+
import { VERSIONS } from "./versions";
7+
8+
const PACKAGE_VERSION = `rpc-router ${VERSIONS.RPC_ROUTER}`;
9+
10+
function getBinaryVersion(location: string): [string | null, string | null] {
11+
const result = spawnSync(location, ["--version"]);
12+
const error: string | null =
13+
(result.error && result.error.toString()) ||
14+
(result.stderr.length > 0 && result.stderr.toString().trim()) ||
15+
null;
16+
return [error, result.stdout && result.stdout.toString().trim()];
17+
}
18+
19+
function getExePath(): string {
20+
let os: string = platform();
21+
let extension = "";
22+
if (["win32", "cygwin"].includes(os)) {
23+
os = "windows";
24+
extension = ".exe";
25+
}
26+
const binaryName = `@magicblock-labs/rpc-router-${os}-${arch()}/bin/rpc-router${extension}`;
27+
try {
28+
return require.resolve(binaryName);
29+
} catch (e) {
30+
throw new Error(
31+
`Couldn't find application binary inside node_modules for ${os}-${arch()}, expected location: ${binaryName}`,
32+
);
33+
}
34+
}
35+
36+
function runWithForwardedExit(child: ReturnType<typeof spawn>): void {
37+
child.on("exit", (code: number | null, signal: NodeJS.Signals | null) => {
38+
process.on("exit", () => {
39+
if (signal) {
40+
process.kill(process.pid, signal);
41+
} else if (code !== null) {
42+
process.exit(code);
43+
}
44+
});
45+
});
46+
47+
process.on("SIGINT", () => {
48+
child.kill("SIGINT");
49+
child.kill("SIGTERM");
50+
});
51+
}
52+
53+
function runRpcRouter(location: string): void {
54+
const args = process.argv.slice(2);
55+
const env = {
56+
...process.env,
57+
};
58+
const ephemeralValidator = spawn(location, args, { stdio: "inherit", env});
59+
runWithForwardedExit(ephemeralValidator);
60+
}
61+
62+
function tryPackageRpcRouter(): boolean {
63+
try {
64+
const path = getExePath();
65+
runRpcRouter(path);
66+
return true;
67+
} catch (e) {
68+
console.error(
69+
"Failed to run rpc-router from package:",
70+
e instanceof Error ? e.message : e,
71+
);
72+
return false;
73+
}
74+
}
75+
76+
function trySystemRpcRouter(): void {
77+
const absolutePath = process.env.PATH?.split(path.delimiter)
78+
.filter((dir) => dir !== path.dirname(process.argv[1]))
79+
.find((dir) => {
80+
try {
81+
fs.accessSync(`${dir}/rpc-router`, fs.constants.X_OK);
82+
return true;
83+
} catch {
84+
return false;
85+
}
86+
});
87+
88+
if (!absolutePath) {
89+
console.error(
90+
`Could not find globally installed rpc-router, please install with cargo.`,
91+
);
92+
process.exit(1);
93+
}
94+
95+
const absoluteBinaryPath = `${absolutePath}/rpc-router`;
96+
const [error, binaryVersion] = getBinaryVersion(absoluteBinaryPath);
97+
98+
if (error !== null) {
99+
console.error(`Failed to get version of global binary: ${error}`);
100+
return;
101+
}
102+
if (binaryVersion !== PACKAGE_VERSION) {
103+
console.error(
104+
`Globally installed rpc-router version is not correct. Expected "${PACKAGE_VERSION}", found "${binaryVersion}".`,
105+
);
106+
return;
107+
}
108+
109+
runRpcRouter(absoluteBinaryPath);
110+
}
111+
112+
// If the first argument is our special command, run the test validator and exit.
113+
tryPackageRpcRouter() || trySystemRpcRouter();
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const VERSIONS = {
2+
EPHEMERAL_VALIDATOR: "0.2.3",
3+
RPC_ROUTER: "0.0.1",
4+
VRF_ORACLE: "0.2.0",
5+
} as const;
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env node
2+
import fs from "fs";
3+
import { spawn, spawnSync } from "child_process";
4+
import path from "path";
5+
import { arch, platform } from "os";
6+
import { VERSIONS } from "./versions";
7+
8+
const PACKAGE_VERSION = `vrf-oracle ${VERSIONS.VRF_ORACLE}`;
9+
10+
function getBinaryVersion(location: string): [string | null, string | null] {
11+
const result = spawnSync(location, ["--version"]);
12+
const error: string | null =
13+
(result.error && result.error.toString()) ||
14+
(result.stderr.length > 0 && result.stderr.toString().trim()) ||
15+
null;
16+
return [error, result.stdout && result.stdout.toString().trim()];
17+
}
18+
19+
function getExePath(): string {
20+
let os: string = platform();
21+
let extension = "";
22+
if (["win32", "cygwin"].includes(os)) {
23+
os = "windows";
24+
extension = ".exe";
25+
}
26+
const binaryName = `@magicblock-labs/vrf-oracle-${os}-${arch()}/bin/vrf-oracle${extension}`;
27+
try {
28+
return require.resolve(binaryName);
29+
} catch (e) {
30+
throw new Error(
31+
`Couldn't find application binary inside node_modules for ${os}-${arch()}, expected location: ${binaryName}`,
32+
);
33+
}
34+
}
35+
36+
function runWithForwardedExit(child: ReturnType<typeof spawn>): void {
37+
child.on("exit", (code: number | null, signal: NodeJS.Signals | null) => {
38+
process.on("exit", () => {
39+
if (signal) {
40+
process.kill(process.pid, signal);
41+
} else if (code !== null) {
42+
process.exit(code);
43+
}
44+
});
45+
});
46+
47+
process.on("SIGINT", () => {
48+
child.kill("SIGINT");
49+
child.kill("SIGTERM");
50+
});
51+
}
52+
53+
function runVrfOracle(location: string): void {
54+
const args = process.argv.slice(2);
55+
const env = {
56+
...process.env,
57+
RUST_LOG: "quiet",
58+
};
59+
const vrfOracle = spawn(location, args, { stdio: "inherit", env});
60+
runWithForwardedExit(vrfOracle);
61+
}
62+
63+
function tryPackageVrfOracle(): boolean {
64+
try {
65+
const path = getExePath();
66+
runVrfOracle(path);
67+
return true;
68+
} catch (e) {
69+
console.error(
70+
"Failed to run vrf-oracle from package:",
71+
e instanceof Error ? e.message : e,
72+
);
73+
return false;
74+
}
75+
}
76+
77+
function trySystemVrfOracle(): void {
78+
const absolutePath = process.env.PATH?.split(path.delimiter)
79+
.filter((dir) => dir !== path.dirname(process.argv[1]))
80+
.find((dir) => {
81+
try {
82+
fs.accessSync(`${dir}/vrf-oracle`, fs.constants.X_OK);
83+
return true;
84+
} catch {
85+
return false;
86+
}
87+
});
88+
89+
if (!absolutePath) {
90+
console.error(
91+
`Could not find globally installed vrf-oracle, please install with cargo.`,
92+
);
93+
process.exit(1);
94+
}
95+
96+
const absoluteBinaryPath = `${absolutePath}/vrf-oracle`;
97+
const [error, binaryVersion] = getBinaryVersion(absoluteBinaryPath);
98+
99+
if (error !== null) {
100+
console.error(`Failed to get version of global binary: ${error}`);
101+
return;
102+
}
103+
if (binaryVersion !== PACKAGE_VERSION) {
104+
console.error(
105+
`Globally installed vrf-oracle version is not correct. Expected "${PACKAGE_VERSION}", found "${binaryVersion}".`,
106+
);
107+
return;
108+
}
109+
110+
runVrfOracle(absoluteBinaryPath);
111+
}
112+
113+
// If the first argument is our special command, run the test validator and exit.
114+
tryPackageVrfOracle() || trySystemVrfOracle();

0 commit comments

Comments
 (0)