bulletin-deploy 0.7.17 → 0.7.19-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/assets/environments.json +23 -5
- package/bin/bulletin-bootstrap +38 -2
- package/bin/bulletin-deploy +8 -26
- package/dist/bug-report.js +4 -4
- package/dist/{chunk-WSHGL6SP.js → chunk-376G4CVG.js} +1 -1
- package/dist/{chunk-VOEFHED3.js → chunk-4TS6R26J.js} +87 -35
- package/dist/{chunk-I5VICJCA.js → chunk-A4TOLXMR.js} +1 -1
- package/dist/{chunk-AJ3IT7P5.js → chunk-D4ZXOJLO.js} +2 -2
- package/dist/{chunk-QWBCK7RY.js → chunk-FLVBTZIW.js} +105 -64
- package/dist/{chunk-BS7SZNE3.js → chunk-KSWXBDHQ.js} +8 -8
- package/dist/{chunk-ME32MC6X.js → chunk-NRWRL75I.js} +1 -1
- package/dist/{chunk-X3F7WHSF.js → chunk-O2HIPNUT.js} +15 -102
- package/dist/{chunk-RPNJEMTM.js → chunk-TW7MAGSE.js} +100 -30
- package/dist/chunk-probe.js +3 -3
- package/dist/deploy.d.ts +11 -1
- package/dist/deploy.js +9 -9
- package/dist/dotns.d.ts +13 -1
- package/dist/dotns.js +6 -4
- package/dist/environments.d.ts +12 -12
- package/dist/environments.js +1 -11
- package/dist/index.js +9 -9
- package/dist/memory-report.js +2 -2
- package/dist/merkle.d.ts +2 -1
- package/dist/merkle.js +13 -11
- package/dist/pool.d.ts +7 -4
- package/dist/pool.js +1 -1
- package/dist/run-state.js +1 -1
- package/dist/telemetry.js +2 -2
- package/dist/version-check.js +3 -3
- package/docs/e2e-bootstrap.md +88 -3
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -79,6 +79,7 @@ bulletin-deploy ./dist my-app00.dot --rpc wss://custom-bulletin.example.com
|
|
|
79
79
|
| Env id | Network | Bulletin available? |
|
|
80
80
|
|---|---|---|
|
|
81
81
|
| `paseo-next` (default) | testnet | yes |
|
|
82
|
+
| `paseo-next-v2` | testnet | yes |
|
|
82
83
|
| `paseo-review` | testnet | yes |
|
|
83
84
|
| `preview` | testnet | yes |
|
|
84
85
|
| `polkadot` | mainnet | not yet |
|
|
@@ -103,6 +104,8 @@ The runtime uses a 24-hour cache at `${XDG_CACHE_HOME:-~/.cache}/bulletin-deploy
|
|
|
103
104
|
| `--js-merkle` | Use pure-JS merkleization instead of the Kubo binary. |
|
|
104
105
|
| `--tag "..."` | Attach a free-form telemetry label. Also readable from `DEPLOY_TAG`. |
|
|
105
106
|
| `--gh-pages-mirror` | After a successful deploy, push the generated CAR to the current repo's `gh-pages` branch as an HTTP mirror. |
|
|
107
|
+
| `--skip-automated-deployment-to-paseo-next-v2` | Suppress the automatic mirror deploy to `paseo-next-v2` that runs after a successful `paseo-next` deploy. |
|
|
108
|
+
| `--fail-on-mirror-error` | Exit non-zero if the automated mirror deploy to `paseo-next-v2` fails (default: warn only). |
|
|
106
109
|
| `--input-car <path>` | Deploy from a pre-built CAR file instead of a build directory. Skips merkleization; reads the root CID from the CAR header. Usage: `bulletin-deploy --input-car site.car my-app.dot` |
|
|
107
110
|
| `--version` | Print the CLI version. |
|
|
108
111
|
| `--help` | Show help. |
|
|
@@ -175,6 +178,25 @@ to the current repo's `gh-pages` branch and prints the Pages URL.
|
|
|
175
178
|
|
|
176
179
|
Use it when you want to validate or consume the mirror feature. The source of truth remains Bulletin plus DotNS.
|
|
177
180
|
|
|
181
|
+
## Automatic Mirror to paseo-next-v2
|
|
182
|
+
|
|
183
|
+
When you deploy to `paseo-next` (the default), `bulletin-deploy` automatically runs a second deploy to `paseo-next-v2` using the same build artefact. This keeps both environments in sync without any extra steps during the period when `paseo-next-v2` is being validated alongside the existing testnet.
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# Standard deploy — mirrors to paseo-next-v2 automatically
|
|
187
|
+
bulletin-deploy ./dist my-app00.dot
|
|
188
|
+
|
|
189
|
+
# Opt out of the mirror
|
|
190
|
+
bulletin-deploy ./dist my-app00.dot --skip-automated-deployment-to-paseo-next-v2
|
|
191
|
+
|
|
192
|
+
# Treat a mirror failure as a hard error instead of a warning
|
|
193
|
+
bulletin-deploy ./dist my-app00.dot --fail-on-mirror-error
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The mirror runs after the primary deploy succeeds. By default, a mirror failure prints a warning and exits zero so it does not block your pipeline. Pass `--fail-on-mirror-error` if you want the process to exit non-zero on mirror failure.
|
|
197
|
+
|
|
198
|
+
This behaviour is temporary and will be removed once `paseo-next-v2` fully replaces `paseo-next`.
|
|
199
|
+
|
|
178
200
|
## Programmatic API
|
|
179
201
|
|
|
180
202
|
```js
|
package/assets/environments.json
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
"network": "testnet",
|
|
7
7
|
"description": "Product Preview net, used by Product Teams",
|
|
8
8
|
"backend": "https://polkadot-app-stg.parity.io/",
|
|
9
|
-
"ipfs": "https://previewnet.substrate.dev/ipfs/"
|
|
9
|
+
"ipfs": "https://previewnet.substrate.dev/ipfs/",
|
|
10
|
+
"autoAccountMapping": true,
|
|
11
|
+
"bulletinAuthorizeV2": true
|
|
10
12
|
},
|
|
11
13
|
{
|
|
12
14
|
"id": "paseo-next",
|
|
@@ -34,19 +36,35 @@
|
|
|
34
36
|
"description": "Next iteration of the Paseo Next testnet",
|
|
35
37
|
"backend": "https://identity-backend-next.parity-testnet.parity.io",
|
|
36
38
|
"ipfs": "https://paseo-bulletin-next-ipfs.polkadot.io",
|
|
37
|
-
"docsUrl": "https://sre.teleport.parity.io/environments/paseo-next/"
|
|
39
|
+
"docsUrl": "https://sre.teleport.parity.io/environments/paseo-next/",
|
|
40
|
+
"autoAccountMapping": true,
|
|
41
|
+
"bulletinAuthorizeV2": true,
|
|
42
|
+
"nativeToEthRatio": 100000000,
|
|
43
|
+
"contracts": {
|
|
44
|
+
"DOTNS_REGISTRAR": "0xE67B22B285912FFfaE23BdfAc8C80c779d99B3e0",
|
|
45
|
+
"DOTNS_REGISTRAR_CONTROLLER": "0x8403e49Ec12F4EA5788f7bc0C0c2F649205774cC",
|
|
46
|
+
"DOTNS_REGISTRY": "0xDeFE1AAE21eC2455bd04b213a51C16d4b426c7ef",
|
|
47
|
+
"DOTNS_RESOLVER": "0xB436A271Beff1DBa6abDf2dbCc7E6d723d505EE6",
|
|
48
|
+
"DOTNS_CONTENT_RESOLVER": "0xBcFa907Ff85dFc62a21b41d48F23D7A73aC42914",
|
|
49
|
+
"DOTNS_REVERSE_RESOLVER": "0x4Ca32Dd0233D8c1B1709e20D9E4edBF2a77D21c3",
|
|
50
|
+
"POP_RULES": "0xd3F059FA65dA566B294b5d755a06054d4bE7ce7C",
|
|
51
|
+
"STORE_FACTORY": "0x4f1885fB6e0b154dCf9C2A8661e578B94aD50775"
|
|
52
|
+
},
|
|
53
|
+
"skipDotnsCli": true
|
|
38
54
|
},
|
|
39
55
|
{
|
|
40
56
|
"id": "polkadot",
|
|
41
57
|
"name": "Polkadot",
|
|
42
58
|
"network": "mainnet",
|
|
43
|
-
"description": "Polkadot mainnet"
|
|
59
|
+
"description": "Polkadot mainnet",
|
|
60
|
+
"autoAccountMapping": true
|
|
44
61
|
},
|
|
45
62
|
{
|
|
46
63
|
"id": "kusama",
|
|
47
64
|
"name": "Kusama",
|
|
48
65
|
"network": "mainnet",
|
|
49
|
-
"description": "Kusama canary network"
|
|
66
|
+
"description": "Kusama canary network",
|
|
67
|
+
"autoAccountMapping": true
|
|
50
68
|
}
|
|
51
69
|
],
|
|
52
70
|
"chains": [
|
|
@@ -260,4 +278,4 @@
|
|
|
260
278
|
}
|
|
261
279
|
],
|
|
262
280
|
"source": "https://docs.google.com/document/d/1xQoAmWDpbjhuXKT79DTNKFzv7ZkFr5npjo0BvrxXDIw"
|
|
263
|
-
}
|
|
281
|
+
}
|
package/bin/bulletin-bootstrap
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import * as fs from "node:fs/promises";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
3
6
|
import { DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE } from "../dist/deploy.js";
|
|
4
7
|
import { bootstrapPool } from "../dist/pool.js";
|
|
5
8
|
import { VERSION } from "../dist/telemetry.js";
|
|
@@ -11,6 +14,7 @@ for (let i = 0; i < args.length; i++) {
|
|
|
11
14
|
if (args[i] === "--pool-size") { flags.poolSize = parseInt(args[++i], 10); }
|
|
12
15
|
else if (args[i] === "--mnemonic") { flags.mnemonic = args[++i]; }
|
|
13
16
|
else if (args[i] === "--rpc") { flags.rpc = args[++i]; }
|
|
17
|
+
else if (args[i] === "--env") { flags.env = args[++i]; }
|
|
14
18
|
else if (args[i] === "--version" || args[i] === "-V") { flags.version = true; }
|
|
15
19
|
else if (args[i] === "--help" || args[i] === "-h") { flags.help = true; }
|
|
16
20
|
else {
|
|
@@ -33,6 +37,7 @@ Usage:
|
|
|
33
37
|
Options:
|
|
34
38
|
--mnemonic "..." Pool root mnemonic (or set BULLETIN_POOL_MNEMONIC / MNEMONIC env var)
|
|
35
39
|
--rpc wss://... Bulletin RPC (or set BULLETIN_RPC env var)
|
|
40
|
+
--env <id> Load environment by id from environments.json (sets default RPC and V2 flag)
|
|
36
41
|
--pool-size N Number of pool accounts to initialize (default: 10)
|
|
37
42
|
--version Show version
|
|
38
43
|
--help Show this help
|
|
@@ -41,8 +46,39 @@ Initialize pool accounts for Bulletin storage authorization.`);
|
|
|
41
46
|
process.exit(0);
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
|
|
49
|
+
let rpc = flags.rpc ?? process.env.BULLETIN_RPC ?? DEFAULT_BULLETIN_RPC;
|
|
45
50
|
const poolSize = flags.poolSize ?? parseInt(process.env.BULLETIN_POOL_SIZE ?? String(DEFAULT_POOL_SIZE), 10);
|
|
46
51
|
const mnemonic = flags.mnemonic ?? process.env.BULLETIN_POOL_MNEMONIC ?? process.env.MNEMONIC;
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
const bootstrapOpts = {};
|
|
54
|
+
|
|
55
|
+
if (flags.env) {
|
|
56
|
+
const envJsonPath = fileURLToPath(new URL("../assets/environments.json", import.meta.url));
|
|
57
|
+
let envDoc;
|
|
58
|
+
try {
|
|
59
|
+
const raw = await fs.readFile(envJsonPath, "utf8");
|
|
60
|
+
envDoc = JSON.parse(raw);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.error(`Error: could not load environments.json: ${e.message}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const envEntry = envDoc.environments.find(e => e.id === flags.env);
|
|
67
|
+
if (!envEntry) {
|
|
68
|
+
const valid = envDoc.environments.map(e => e.id).join(", ");
|
|
69
|
+
console.error(`Error: unknown environment '${flags.env}'. Valid: ${valid}.`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!flags.rpc) {
|
|
74
|
+
const bulletinChain = envDoc.chains.find(c => c.id === "bulletin");
|
|
75
|
+
const ep = bulletinChain?.endpoints?.[flags.env];
|
|
76
|
+
if (ep?.wss) {
|
|
77
|
+
rpc = Array.isArray(ep.wss) ? ep.wss[0] : ep.wss;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
bootstrapOpts.bulletinAuthorizeV2 = envEntry.bulletinAuthorizeV2 ?? false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
await bootstrapPool(rpc, poolSize, mnemonic, bootstrapOpts);
|
package/bin/bulletin-deploy
CHANGED
|
@@ -5,7 +5,7 @@ import { VERSION, setDeployAttribute, captureWarning, closeTelemetry, setRunStat
|
|
|
5
5
|
import { handleFailedDeploy, preReleaseWarning, checkNodeVersion } from "../dist/version-check.js";
|
|
6
6
|
import { setDeployContext, installLogCapture, buildCliFlagsSummary } from "../dist/bug-report.js";
|
|
7
7
|
import { loadRunState, writeRunState, shouldSkipStaleWarning, shouldShowOomHint, probablyOomRssMb } from "../dist/run-state.js";
|
|
8
|
-
import { loadEnvironments, listEnvironments, formatEnvironmentTable, DEFAULT_ENV_ID
|
|
8
|
+
import { loadEnvironments, listEnvironments, formatEnvironmentTable, DEFAULT_ENV_ID } from "../dist/environments.js";
|
|
9
9
|
import { shouldMirrorToPaseoNextV2 } from "../dist/mirror.js";
|
|
10
10
|
import * as fs from "fs";
|
|
11
11
|
|
|
@@ -33,7 +33,6 @@ for (let i = 0; i < args.length; i++) {
|
|
|
33
33
|
else if (args[i] === "--rpc") { flags.rpc = args[++i]; }
|
|
34
34
|
else if (args[i] === "--env") { flags.env = args[++i]; }
|
|
35
35
|
else if (args[i] === "--list-environments") { flags.listEnvironments = true; }
|
|
36
|
-
else if (args[i] === "--refresh-environments") { flags.refreshEnvironments = true; }
|
|
37
36
|
else if (args[i] === "--password") { flags.password = args[++i]; }
|
|
38
37
|
else if (args[i] === "--js-merkle") { flags.jsMerkle = true; }
|
|
39
38
|
else if (args[i] === "--input-car") { flags.inputCar = args[++i]; }
|
|
@@ -44,6 +43,7 @@ for (let i = 0; i < args.length; i++) {
|
|
|
44
43
|
else if (args[i] === "--allow-large-deploy") { flags.allowLargeDeploy = true; }
|
|
45
44
|
else if (args[i] === "--reproducible") { flags.reproducibleSource = "commit"; }
|
|
46
45
|
else if (args[i].startsWith("--reproducible=")) { flags.reproducibleSource = args[i].slice("--reproducible=".length); }
|
|
46
|
+
else if (args[i] === "--skip-dotns-cli") { flags.skipDotnsCli = true; }
|
|
47
47
|
else if (args[i] === "--skip-automated-deployment-to-paseo-next-v2") { flags.skipMirrorToPaseoNextV2 = true; }
|
|
48
48
|
else if (args[i] === "--fail-on-mirror-error") { flags.failOnMirrorError = true; }
|
|
49
49
|
else if (args[i] === "--version" || args[i] === "-V") { flags.version = true; }
|
|
@@ -74,18 +74,7 @@ if (flags.listEnvironments) {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
// positional args, refresh first, then deploy.
|
|
79
|
-
if (flags.refreshEnvironments && positional.length === 0) {
|
|
80
|
-
try {
|
|
81
|
-
const { doc } = await loadEnvironments({ forceRefresh: true });
|
|
82
|
-
console.log(`Refreshed ${doc.environments.length} environments from ${process.env.BULLETIN_ENVIRONMENTS_URL ?? DEFAULT_ENVIRONMENTS_URL}`);
|
|
83
|
-
process.exit(0);
|
|
84
|
-
} catch (e) {
|
|
85
|
-
console.error(`Error: failed to refresh environments: ${e?.message ?? e}`);
|
|
86
|
-
process.exit(1);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
77
|
+
|
|
89
78
|
|
|
90
79
|
if (flags.help || positional.length === 0) {
|
|
91
80
|
console.log(`bulletin-deploy v${VERSION}
|
|
@@ -98,8 +87,6 @@ Options:
|
|
|
98
87
|
Drives both the bulletin RPC and the asset-hub RPC used
|
|
99
88
|
by DotNS. See --list-environments for valid ids.
|
|
100
89
|
--list-environments Print the environments table and exit.
|
|
101
|
-
--refresh-environments Bust the cache and re-fetch environments.json. Composes
|
|
102
|
-
with --env (refresh-then-deploy) or runs solo.
|
|
103
90
|
--mnemonic "..." DotNS owner mnemonic (or set MNEMONIC env var)
|
|
104
91
|
--derivation-path "..." Optional Substrate-style path applied to --mnemonic (e.g. //deploy/3)
|
|
105
92
|
--rpc wss://... Override the bulletin RPC for the chosen --env (or set BULLETIN_RPC).
|
|
@@ -114,6 +101,10 @@ Options:
|
|
|
114
101
|
--description "..." Optional. Sets the "description" text record (≤100 chars recommended).
|
|
115
102
|
--gh-pages-mirror After deploy, push the CAR to the current repo's gh-pages branch
|
|
116
103
|
at bulletin/<domain>.dot.car (opt-in; also set GH_PAGES_MIRROR=1)
|
|
104
|
+
--skip-dotns-cli Use direct contract calls for DotNS operations instead of
|
|
105
|
+
dotns-cli. Auto-set for envs with custom contract addresses
|
|
106
|
+
(e.g. paseo-next-v2). Use to override when dotns-cli lacks
|
|
107
|
+
support for the target chain.
|
|
117
108
|
--skip-automated-deployment-to-paseo-next-v2
|
|
118
109
|
Suppress the automatic mirror deploy to paseo-next-v2.
|
|
119
110
|
--fail-on-mirror-error
|
|
@@ -244,16 +235,6 @@ try {
|
|
|
244
235
|
if (!fs.existsSync(buildDir)) { console.error(`Error: ${buildDir} does not exist`); process.exit(1); }
|
|
245
236
|
}
|
|
246
237
|
|
|
247
|
-
// --refresh-environments composed with a deploy: bust the cache before
|
|
248
|
-
// deploy() loads it, so deploy() picks up fresh data on the next loadEnvironments().
|
|
249
|
-
if (flags.refreshEnvironments) {
|
|
250
|
-
try {
|
|
251
|
-
await loadEnvironments({ forceRefresh: true });
|
|
252
|
-
} catch (e) {
|
|
253
|
-
console.error(`Error: failed to refresh environments: ${e?.message ?? e}`);
|
|
254
|
-
process.exit(1);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
238
|
const effectiveRpc = flags.rpc ?? process.env.BULLETIN_RPC ?? DEFAULT_BULLETIN_RPC;
|
|
258
239
|
const deployTag = flags.tag ?? process.env.DEPLOY_TAG;
|
|
259
240
|
const ci = process.env.GITHUB_ACTIONS === "true" ? {
|
|
@@ -290,6 +271,7 @@ try {
|
|
|
290
271
|
description: flags.description,
|
|
291
272
|
allowLargeDeploy: flags.allowLargeDeploy,
|
|
292
273
|
reproducibleSource: flags.reproducibleSource,
|
|
274
|
+
skipDotnsCli: flags.skipDotnsCli,
|
|
293
275
|
});
|
|
294
276
|
|
|
295
277
|
const output = process.env.GITHUB_OUTPUT;
|
package/dist/bug-report.js
CHANGED
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
offerBugReport,
|
|
10
10
|
scrubSecrets,
|
|
11
11
|
setDeployContext
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-D4ZXOJLO.js";
|
|
13
|
+
import "./chunk-376G4CVG.js";
|
|
14
|
+
import "./chunk-NRWRL75I.js";
|
|
15
|
+
import "./chunk-KSWXBDHQ.js";
|
|
16
16
|
import "./chunk-QGM4M3NI.js";
|
|
17
17
|
export {
|
|
18
18
|
buildCliFlagsSummary,
|
|
@@ -3,8 +3,7 @@ import { sr25519CreateDerive } from "@polkadot-labs/hdkd";
|
|
|
3
3
|
import { DEV_PHRASE, entropyToMiniSecret, mnemonicToEntropy } from "@polkadot-labs/hdkd-helpers";
|
|
4
4
|
import { createClient, Enum } from "polkadot-api";
|
|
5
5
|
import { getPolkadotSigner } from "polkadot-api/signer";
|
|
6
|
-
import { getWsProvider } from "polkadot-api/ws
|
|
7
|
-
import { withPolkadotSdkCompat } from "polkadot-api/polkadot-sdk-compat";
|
|
6
|
+
import { getWsProvider } from "polkadot-api/ws";
|
|
8
7
|
import { Keyring } from "@polkadot/keyring";
|
|
9
8
|
import { cryptoWaitReady } from "@polkadot/util-crypto";
|
|
10
9
|
var PAS_DECIMALS_DIVISOR = 1e10;
|
|
@@ -134,7 +133,13 @@ function aliceKeyring() {
|
|
|
134
133
|
const signer = getPolkadotSigner(alice.publicKey, "Sr25519", (data) => alice.sign(data));
|
|
135
134
|
return { alice, signer };
|
|
136
135
|
}
|
|
137
|
-
|
|
136
|
+
var U32_MAX = 0xFFFFFFFFn;
|
|
137
|
+
function clampU32(n, name) {
|
|
138
|
+
if (n < 0n) throw new Error(`${name} must be non-negative`);
|
|
139
|
+
if (n > U32_MAX) throw new Error(`${name} (${n}) exceeds u32 max \u2014 split the deploy into smaller batches`);
|
|
140
|
+
return Number(n);
|
|
141
|
+
}
|
|
142
|
+
async function ensureAuthorized(api, address, label, bulletinAuthorizeV2) {
|
|
138
143
|
const [auth, currentBlock] = await Promise.all([
|
|
139
144
|
api.query.TransactionStorage.Authorizations.getValue(Enum("Account", address)),
|
|
140
145
|
api.query.System.Number.getValue()
|
|
@@ -142,18 +147,31 @@ async function ensureAuthorized(api, address, label) {
|
|
|
142
147
|
if (isAuthorizationActive(auth, currentBlock)) return;
|
|
143
148
|
console.log(` Auto-authorizing ${label ?? "account"} (${address.slice(0, 8)}...)...`);
|
|
144
149
|
const { signer } = aliceKeyring();
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
if (bulletinAuthorizeV2) {
|
|
151
|
+
await submitAliceTxWithRetry(
|
|
152
|
+
() => api.tx.TransactionStorage.authorize_account({
|
|
153
|
+
who: address,
|
|
154
|
+
transactions: clampU32(BigInt(TOPUP_TRANSACTIONS), "transactions"),
|
|
155
|
+
bytes: TOPUP_BYTES
|
|
156
|
+
}),
|
|
157
|
+
signer,
|
|
158
|
+
`authorize_account(${label ?? "account"})`
|
|
159
|
+
);
|
|
160
|
+
console.log(` Authorized: ${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB`);
|
|
161
|
+
} else {
|
|
162
|
+
const newExpiration = currentBlock + AUTHORIZATION_EXTENSION_BLOCKS;
|
|
163
|
+
await submitAliceTxWithRetry(
|
|
164
|
+
() => api.tx.TransactionStorage.authorize_account({
|
|
165
|
+
who: address,
|
|
166
|
+
expiration: newExpiration
|
|
167
|
+
}),
|
|
168
|
+
signer,
|
|
169
|
+
`authorize_account(${label ?? "account"})`
|
|
170
|
+
);
|
|
171
|
+
console.log(` Authorized: expires at block ${newExpiration} (current: ${currentBlock})`);
|
|
172
|
+
}
|
|
155
173
|
}
|
|
156
|
-
async function topUpBy(api, address, needs, label) {
|
|
174
|
+
async function topUpBy(api, address, needs, label, bulletinAuthorizeV2) {
|
|
157
175
|
const [currentAuth, currentBlock] = await Promise.all([
|
|
158
176
|
api.query.TransactionStorage.Authorizations.getValue(Enum("Account", address)),
|
|
159
177
|
api.query.System.Number.getValue()
|
|
@@ -166,28 +184,42 @@ async function topUpBy(api, address, needs, label) {
|
|
|
166
184
|
console.log(` Pre-auth skipped for ${label ?? "account"} (${address.slice(0, 8)}...): authorized until block ${expiration}, ${txsRemaining} txs / ${fmtMB(bytesRemaining)}MB remaining.`);
|
|
167
185
|
return;
|
|
168
186
|
}
|
|
169
|
-
const newExpiration = currentBlock + AUTHORIZATION_EXTENSION_BLOCKS;
|
|
170
187
|
const { signer } = aliceKeyring();
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
188
|
+
if (bulletinAuthorizeV2) {
|
|
189
|
+
console.log(` Pre-authorizing ${label ?? "account"} (${address.slice(0, 8)}...): granting ${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB...`);
|
|
190
|
+
await submitAliceTxWithRetry(
|
|
191
|
+
() => api.tx.TransactionStorage.authorize_account({
|
|
192
|
+
who: address,
|
|
193
|
+
transactions: clampU32(BigInt(TOPUP_TRANSACTIONS), "transactions"),
|
|
194
|
+
bytes: TOPUP_BYTES
|
|
195
|
+
}),
|
|
196
|
+
signer,
|
|
197
|
+
`topUpBy(${label ?? "account"})`
|
|
198
|
+
);
|
|
199
|
+
console.log(` Pre-authorized: ${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB`);
|
|
200
|
+
} else {
|
|
201
|
+
const newExpiration = currentBlock + AUTHORIZATION_EXTENSION_BLOCKS;
|
|
202
|
+
console.log(` Pre-authorizing ${label ?? "account"} (${address.slice(0, 8)}...): extending authorization to block ${newExpiration}...`);
|
|
203
|
+
await submitAliceTxWithRetry(
|
|
204
|
+
() => api.tx.TransactionStorage.authorize_account({
|
|
205
|
+
who: address,
|
|
206
|
+
expiration: newExpiration
|
|
207
|
+
}),
|
|
208
|
+
signer,
|
|
209
|
+
`topUpBy(${label ?? "account"})`
|
|
210
|
+
);
|
|
211
|
+
console.log(` Pre-authorized: expires at block ${newExpiration}`);
|
|
212
|
+
}
|
|
181
213
|
}
|
|
182
|
-
async function bootstrapPool(bulletinRpc, poolSize = 10, mnemonic) {
|
|
214
|
+
async function bootstrapPool(bulletinRpc, poolSize = 10, mnemonic, opts = {}) {
|
|
183
215
|
console.log(`Bootstrapping ${poolSize} pool accounts on ${bulletinRpc}...
|
|
184
216
|
`);
|
|
185
217
|
await cryptoWaitReady();
|
|
186
218
|
const accounts = derivePoolAccounts(poolSize, mnemonic);
|
|
187
|
-
const client = createClient(
|
|
219
|
+
const client = createClient(getWsProvider(
|
|
188
220
|
bulletinRpc,
|
|
189
221
|
{ heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS }
|
|
190
|
-
))
|
|
222
|
+
));
|
|
191
223
|
const api = client.getUnsafeApi();
|
|
192
224
|
const keyring = new Keyring({ type: "sr25519" });
|
|
193
225
|
const alice = keyring.addFromUri("//Alice");
|
|
@@ -197,19 +229,39 @@ async function bootstrapPool(bulletinRpc, poolSize = 10, mnemonic) {
|
|
|
197
229
|
console.log(`Alice balance: ${formatPasBalance(aliceBalance)} PAS
|
|
198
230
|
`);
|
|
199
231
|
const currentBlock = await api.query.System.Number.getValue();
|
|
200
|
-
|
|
201
|
-
|
|
232
|
+
if (opts.bulletinAuthorizeV2) {
|
|
233
|
+
console.log(`Authorizing accounts with V2 (${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB)
|
|
202
234
|
`);
|
|
235
|
+
} else {
|
|
236
|
+
const authExpiration = currentBlock + AUTHORIZATION_EXTENSION_BLOCKS;
|
|
237
|
+
console.log(`Authorizing accounts until block ${authExpiration} (current: ${currentBlock})
|
|
238
|
+
`);
|
|
239
|
+
}
|
|
203
240
|
for (const account of accounts) {
|
|
204
241
|
console.log(`Account ${account.index}: ${account.address}`);
|
|
205
242
|
try {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
243
|
+
let tx;
|
|
244
|
+
if (opts.bulletinAuthorizeV2) {
|
|
245
|
+
tx = api.tx.TransactionStorage.authorize_account({
|
|
246
|
+
who: account.address,
|
|
247
|
+
transactions: clampU32(BigInt(TOPUP_TRANSACTIONS), "transactions"),
|
|
248
|
+
bytes: TOPUP_BYTES
|
|
249
|
+
});
|
|
250
|
+
} else {
|
|
251
|
+
const authExpiration = currentBlock + AUTHORIZATION_EXTENSION_BLOCKS;
|
|
252
|
+
tx = api.tx.TransactionStorage.authorize_account({
|
|
253
|
+
who: account.address,
|
|
254
|
+
expiration: authExpiration
|
|
255
|
+
});
|
|
256
|
+
}
|
|
210
257
|
const result = await tx.signAndSubmit(aliceSigner);
|
|
211
258
|
if (!result.ok) throw new Error("dispatch failed");
|
|
212
|
-
|
|
259
|
+
if (opts.bulletinAuthorizeV2) {
|
|
260
|
+
console.log(` Authorized: ${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB`);
|
|
261
|
+
} else {
|
|
262
|
+
const authExpiration = currentBlock + AUTHORIZATION_EXTENSION_BLOCKS;
|
|
263
|
+
console.log(` Authorized: expires at block ${authExpiration}`);
|
|
264
|
+
}
|
|
213
265
|
} catch (e) {
|
|
214
266
|
console.log(` Authorization failed: ${e.message?.slice(0, 80)}`);
|
|
215
267
|
}
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
classifyErrorArea,
|
|
3
3
|
isInteractive,
|
|
4
4
|
promptYesNo
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-376G4CVG.js";
|
|
6
6
|
import {
|
|
7
7
|
VERSION,
|
|
8
8
|
getCurrentSentryTraceId
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-NRWRL75I.js";
|
|
10
10
|
|
|
11
11
|
// src/bug-report.ts
|
|
12
12
|
import { execSync, execFileSync } from "child_process";
|