bulletin-deploy 0.11.0 → 0.12.0-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/bin/bulletin-bootstrap +23 -1
- package/dist/auth-config.js +3 -3
- package/dist/bug-report.js +4 -4
- package/dist/{chunk-VFPXDXIV.js → chunk-2PRHTUHE.js} +2 -2
- package/dist/{chunk-4CVD6CNN.js → chunk-75PLFYYJ.js} +1 -1
- package/dist/{chunk-EAB5STKF.js → chunk-7SN7TQC2.js} +12 -2
- package/dist/{chunk-MBZFAQF4.js → chunk-A3HTUQQC.js} +1 -1
- package/dist/{chunk-Y3WDLLDM.js → chunk-HL5275I7.js} +2 -2
- package/dist/{chunk-BN4PKWRZ.js → chunk-IYOS2XDE.js} +3 -3
- package/dist/{chunk-D4C2PBRO.js → chunk-LBBCHLXD.js} +1 -1
- package/dist/{chunk-QVAZ3P7Q.js → chunk-O5TFXD3J.js} +38 -1
- package/dist/{chunk-WFO7E5CI.js → chunk-PPZ3P7AJ.js} +55 -12
- package/dist/{chunk-ABX6QCX5.js → chunk-QKMMEOG7.js} +158 -61
- package/dist/{chunk-MRQPJLPS.js → chunk-XVQICFTB.js} +22 -1
- package/dist/{chunk-6C75PEHQ.js → chunk-ZAGFZ73G.js} +1 -1
- package/dist/chunk-probe.d.ts +43 -1
- package/dist/chunk-probe.js +11 -5
- package/dist/commands/login.js +11 -11
- package/dist/commands/logout.js +4 -4
- package/dist/commands/transfer.js +4 -4
- package/dist/commands/whoami.js +3 -3
- package/dist/deploy-actors.js +6 -6
- package/dist/deploy.d.ts +45 -1
- package/dist/deploy.js +17 -11
- package/dist/dotns.d.ts +33 -1
- package/dist/dotns.js +14 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +18 -12
- package/dist/manifest/publish.js +12 -12
- package/dist/memory-report.js +2 -2
- package/dist/merkle.js +11 -11
- package/dist/personhood/bootstrap.js +4 -4
- package/dist/personhood/people-client.js +4 -4
- package/dist/personhood/reprove.js +19 -2
- package/dist/pool.d.ts +11 -1
- package/dist/pool.js +9 -1
- package/dist/run-state.js +1 -1
- package/dist/sss-allowance-cache.js +4 -4
- package/dist/storage-signer.d.ts +28 -3
- package/dist/storage-signer.js +13 -11
- package/dist/telemetry.js +2 -2
- package/dist/version-check.js +3 -3
- package/package.json +1 -1
- package/tools/release-retry-wrapper.mjs +6 -0
package/bin/bulletin-bootstrap
CHANGED
|
@@ -4,7 +4,7 @@ import * as fs from "node:fs/promises";
|
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE } from "../dist/deploy.js";
|
|
7
|
-
import { bootstrapPool } from "../dist/pool.js";
|
|
7
|
+
import { bootstrapPool, BULLETIN_BLOCKS_PER_DAY, isAutoReauthorizeAllowed } from "../dist/pool.js";
|
|
8
8
|
import { VERSION } from "../dist/telemetry.js";
|
|
9
9
|
|
|
10
10
|
const args = process.argv.slice(2);
|
|
@@ -16,6 +16,7 @@ for (let i = 0; i < args.length; i++) {
|
|
|
16
16
|
else if (args[i] === "--authorizer") { flags.authorizer = args[++i]; }
|
|
17
17
|
else if (args[i] === "--rpc") { flags.rpc = args[++i]; }
|
|
18
18
|
else if (args[i] === "--env") { flags.env = args[++i]; }
|
|
19
|
+
else if (args[i] === "--pre-check") { flags.preCheck = true; }
|
|
19
20
|
else if (args[i] === "--version" || args[i] === "-V") { flags.version = true; }
|
|
20
21
|
else if (args[i] === "--help" || args[i] === "-h") { flags.help = true; }
|
|
21
22
|
else {
|
|
@@ -52,11 +53,22 @@ Options:
|
|
|
52
53
|
--rpc wss://... Bulletin RPC endpoint (or set BULLETIN_RPC env var)
|
|
53
54
|
--env <id> Load environment by id from environments.json
|
|
54
55
|
--pool-size N Number of pool accounts to check/initialize (default: 10)
|
|
56
|
+
--pre-check E2E pre-flight mode (#1059): renew any account expiring
|
|
57
|
+
within 24h, not just already-expired ones. Requires
|
|
58
|
+
--env, and is hard-gated to environments where
|
|
59
|
+
environments.json has network != "mainnet" and
|
|
60
|
+
bulletinAutoAuthorize: true — refuses to write
|
|
61
|
+
otherwise, even with --authorizer supplied.
|
|
55
62
|
--version Show version
|
|
56
63
|
--help Show this help`);
|
|
57
64
|
process.exit(0);
|
|
58
65
|
}
|
|
59
66
|
|
|
67
|
+
if (flags.preCheck && !flags.env) {
|
|
68
|
+
console.error("Error: --pre-check requires --env <id>");
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
60
72
|
let rpc = flags.rpc ?? process.env.BULLETIN_RPC ?? DEFAULT_BULLETIN_RPC;
|
|
61
73
|
const poolSize = flags.poolSize ?? parseInt(process.env.BULLETIN_POOL_SIZE ?? String(DEFAULT_POOL_SIZE), 10);
|
|
62
74
|
const mnemonic = flags.mnemonic ?? process.env.BULLETIN_POOL_MNEMONIC ?? process.env.MNEMONIC;
|
|
@@ -94,6 +106,16 @@ if (flags.env) {
|
|
|
94
106
|
}
|
|
95
107
|
|
|
96
108
|
bootstrapOpts.bulletinAuthorizeV2 = envEntry.bulletinAuthorizeV2 ?? false;
|
|
109
|
+
|
|
110
|
+
if (flags.preCheck) {
|
|
111
|
+
// #1059: widen the "needs authorization" threshold to 24h-before-expiry,
|
|
112
|
+
// and hard-gate the actual write to environments cleared for it. This is
|
|
113
|
+
// a config-driven (environments.json) gate, not a CLI flag override —
|
|
114
|
+
// --pre-check can never itself grant write access on an env that isn't
|
|
115
|
+
// eligible.
|
|
116
|
+
bootstrapOpts.reauthBufferBlocks = BULLETIN_BLOCKS_PER_DAY;
|
|
117
|
+
bootstrapOpts.allowAutoReauthorize = isAutoReauthorizeAllowed(envEntry);
|
|
118
|
+
}
|
|
97
119
|
}
|
|
98
120
|
|
|
99
121
|
await bootstrapPool(rpc, poolSize, mnemonic, bootstrapOpts);
|
package/dist/auth-config.js
CHANGED
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
getPeopleChainEndpoints,
|
|
10
10
|
hasPersistedSession,
|
|
11
11
|
resolveBulletinEndpoints
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-LBBCHLXD.js";
|
|
13
13
|
import "./chunk-TSPERKUS.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-7SN7TQC2.js";
|
|
15
|
+
import "./chunk-ZAGFZ73G.js";
|
|
16
16
|
import "./chunk-JSYQ3JQS.js";
|
|
17
17
|
import "./chunk-ZOC4GITL.js";
|
|
18
18
|
export {
|
package/dist/bug-report.js
CHANGED
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
offerBugReport,
|
|
11
11
|
scrubSecrets,
|
|
12
12
|
setDeployContext
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-IYOS2XDE.js";
|
|
14
|
+
import "./chunk-A3HTUQQC.js";
|
|
15
|
+
import "./chunk-7SN7TQC2.js";
|
|
16
|
+
import "./chunk-ZAGFZ73G.js";
|
|
17
17
|
export {
|
|
18
18
|
buildCliFlagsSummary,
|
|
19
19
|
buildLabels,
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
resolveDotnsConnectOptions,
|
|
8
8
|
storeDirectory,
|
|
9
9
|
storeFile
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QKMMEOG7.js";
|
|
11
11
|
import {
|
|
12
12
|
DotNS
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PPZ3P7AJ.js";
|
|
14
14
|
import {
|
|
15
15
|
getPopSelfServeConfig,
|
|
16
16
|
loadEnvironments,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
package_default,
|
|
3
3
|
writeRunState
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZAGFZ73G.js";
|
|
5
5
|
|
|
6
6
|
// src/memory-report.ts
|
|
7
7
|
import * as fs2 from "fs";
|
|
@@ -241,7 +241,11 @@ var DEPLOY_SEED_STORAGE = {
|
|
|
241
241
|
};
|
|
242
242
|
var DEPLOY_SEED_PROBE = {
|
|
243
243
|
"deploy.probe.finality_miss_count": 0,
|
|
244
|
-
"deploy.probe.finality_miss_reupload_count": 0
|
|
244
|
+
"deploy.probe.finality_miss_reupload_count": 0,
|
|
245
|
+
// #1049: chunks present at best-block but not yet at finalised head.
|
|
246
|
+
// These are NEVER re-uploaded — only tracked so we can see finality lag
|
|
247
|
+
// without conflating it with genuinely-dropped (re-uploaded) chunks.
|
|
248
|
+
"deploy.probe.finality_lagging_count": 0
|
|
245
249
|
};
|
|
246
250
|
var DEPLOY_SEED_POOL = {
|
|
247
251
|
"deploy.pool.eligible_count": 0,
|
|
@@ -337,6 +341,12 @@ var ERROR_KIND_RULES = [
|
|
|
337
341
|
[/requires ProofOfPersonhood(?:Full|Lite|Light),\s*but this signer is NoStatus/i, "naming.pop_required"],
|
|
338
342
|
[/requires NoStatus,\s*but this signer is ProofOfPersonhood/i, "naming.nostatus_required"],
|
|
339
343
|
[/Cannot decode zero data.*with ABI parameters/i, "naming.contract_unavailable"],
|
|
344
|
+
// Issue #1060: contractCall's own empty-`0x`-data guard (src/dotns.ts, #729) throws
|
|
345
|
+
// an actionable wrapper instead of letting the raw viem message above reach a
|
|
346
|
+
// caller. Same failure family (a DotNS contract read came back empty) — classify
|
|
347
|
+
// it the same way instead of letting it fall into 'unknown'.
|
|
348
|
+
[/No contract deployed at .+ returned empty success data/i, "naming.contract_unavailable"],
|
|
349
|
+
[/Contract call returned empty data — contract=/i, "naming.contract_unavailable"],
|
|
340
350
|
[/Domain\s+\S+\.dot\s+is already owned by\s+0x[a-fA-F0-9]+/i, "naming.already_owned"],
|
|
341
351
|
[/Cannot deploy\s+[\w.-]+\.dot:\s*parent\s+[\w.-]+\.dot\s+is owned by/i, "naming.subdomain_orphan"],
|
|
342
352
|
[/Post-deploy verification failed for .+: on-chain contenthash is /i, "verify.contenthash_mismatch"],
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
} from "./chunk-5FLTDWWP.js";
|
|
5
5
|
import {
|
|
6
6
|
DOT_PRODUCT_ID
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-LBBCHLXD.js";
|
|
8
8
|
import {
|
|
9
9
|
DEFAULT_MNEMONIC
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-PPZ3P7AJ.js";
|
|
11
11
|
|
|
12
12
|
// src/deploy-actors.ts
|
|
13
13
|
var DEFAULT_WORKER_SURI = DEFAULT_MNEMONIC;
|
|
@@ -2,15 +2,15 @@ import {
|
|
|
2
2
|
classifyErrorArea,
|
|
3
3
|
isInteractive,
|
|
4
4
|
promptYesNo
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-A3HTUQQC.js";
|
|
6
6
|
import {
|
|
7
7
|
VERSION,
|
|
8
8
|
getCurrentSentryTraceId,
|
|
9
9
|
resolveIssueRepoSlug
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-7SN7TQC2.js";
|
|
11
11
|
import {
|
|
12
12
|
package_default
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-ZAGFZ73G.js";
|
|
14
14
|
|
|
15
15
|
// src/bug-report.ts
|
|
16
16
|
import { execSync, execFileSync } from "child_process";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
captureWarning
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7SN7TQC2.js";
|
|
4
4
|
|
|
5
5
|
// src/chunk-probe.ts
|
|
6
6
|
import { Twox128, Blake2128Concat, decAnyMetadata, unifyMetadata } from "@polkadot-api/substrate-bindings";
|
|
@@ -166,6 +166,40 @@ async function probeChunks(cids, options) {
|
|
|
166
166
|
}
|
|
167
167
|
return results;
|
|
168
168
|
}
|
|
169
|
+
function classifyFinalityGap(missingAtFinalized, bestBlockResults) {
|
|
170
|
+
const presentAtBest = new Set(
|
|
171
|
+
bestBlockResults.filter((r) => r.present === true).map((r) => r.cid)
|
|
172
|
+
);
|
|
173
|
+
const lagging = [];
|
|
174
|
+
const reallyMissing = [];
|
|
175
|
+
for (const cid of missingAtFinalized) {
|
|
176
|
+
if (presentAtBest.has(cid)) lagging.push(cid);
|
|
177
|
+
else reallyMissing.push(cid);
|
|
178
|
+
}
|
|
179
|
+
return { reallyMissing, lagging };
|
|
180
|
+
}
|
|
181
|
+
async function probeFinalityGap(missingAtFinalized, options) {
|
|
182
|
+
if (missingAtFinalized.length === 0) return { reallyMissing: [], lagging: [] };
|
|
183
|
+
let bestBlockResults = await probeChunks(missingAtFinalized, { ...options, atFinalized: false });
|
|
184
|
+
const indeterminate = bestBlockResults.filter((r) => r.present === null).map((r) => r.cid);
|
|
185
|
+
if (indeterminate.length > 0) {
|
|
186
|
+
const retry = await probeChunks(indeterminate, { ...options, atFinalized: false });
|
|
187
|
+
const retryByCid = new Map(retry.map((r) => [r.cid, r]));
|
|
188
|
+
bestBlockResults = bestBlockResults.map((r) => r.present === null ? retryByCid.get(r.cid) ?? r : r);
|
|
189
|
+
}
|
|
190
|
+
return classifyFinalityGap(missingAtFinalized, bestBlockResults);
|
|
191
|
+
}
|
|
192
|
+
async function getBestBlockNumber(client) {
|
|
193
|
+
try {
|
|
194
|
+
const header = await client._request("chain_getHeader", []);
|
|
195
|
+
const hex = header?.number;
|
|
196
|
+
if (typeof hex !== "string") return null;
|
|
197
|
+
const n = parseInt(hex, 16);
|
|
198
|
+
return Number.isFinite(n) ? n : null;
|
|
199
|
+
} catch {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
169
203
|
function _resetProbeSession() {
|
|
170
204
|
_metadataChecked = false;
|
|
171
205
|
_crossValidated = false;
|
|
@@ -180,6 +214,9 @@ export {
|
|
|
180
214
|
ChainProbeCrossValidationError,
|
|
181
215
|
_decodeStorageValue,
|
|
182
216
|
probeChunks,
|
|
217
|
+
classifyFinalityGap,
|
|
218
|
+
probeFinalityGap,
|
|
219
|
+
getBestBlockNumber,
|
|
183
220
|
_resetProbeSession,
|
|
184
221
|
_bypassMetadataCheckForTest
|
|
185
222
|
};
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-SI2ZUOYD.js";
|
|
4
4
|
import {
|
|
5
5
|
isTestnetSpecName
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XVQICFTB.js";
|
|
7
7
|
import {
|
|
8
8
|
captureWarning,
|
|
9
9
|
markCodePath,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
setDeploySentryTag,
|
|
12
12
|
truncateAddress,
|
|
13
13
|
withSpan
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-7SN7TQC2.js";
|
|
15
15
|
import {
|
|
16
16
|
validateContractAddresses
|
|
17
17
|
} from "./chunk-JSYQ3JQS.js";
|
|
@@ -50,6 +50,11 @@ var CODE_PATHS = {
|
|
|
50
50
|
// true → automated mapping via EVM key derivation
|
|
51
51
|
// false → standard check (already-mapped or manually register)
|
|
52
52
|
DOTNS_AUTO_MAPPING: "dotns.auto-mapping",
|
|
53
|
+
// NOTE (issue #706): marked "exempt" in tools/check-code-path-coverage.py's
|
|
54
|
+
// CODE_PATHS mirror — it's a real fallback for external DotNS library
|
|
55
|
+
// callers, but Parity-internal telemetry never sees that population, so
|
|
56
|
+
// it always reads 0 hits here regardless of real-world usage. Confirmed
|
|
57
|
+
// non-dead in PR #756 and again for #706; keep the branch and the ID.
|
|
53
58
|
DOTNS_MANUAL_MAPPING: "dotns.manual-mapping"
|
|
54
59
|
};
|
|
55
60
|
|
|
@@ -126,7 +131,23 @@ var TX_WALL_CLOCK_CEILING_MS = 24e4;
|
|
|
126
131
|
var TX_NO_PROGRESS_MS = 9e4;
|
|
127
132
|
var WS_HEARTBEAT_TIMEOUT_MS = 3e5;
|
|
128
133
|
var DOTNS_TX_MAX_ATTEMPTS = 3;
|
|
134
|
+
var WatcherSilentNoEventError = class extends Error {
|
|
135
|
+
constructor(silentMs) {
|
|
136
|
+
super(`transaction watcher silent for ${Math.floor(silentMs / 1e3)}s \u2014 no response received (did you approve on your phone?)`);
|
|
137
|
+
this.name = "WatcherSilentNoEventError";
|
|
138
|
+
}
|
|
139
|
+
};
|
|
129
140
|
var VERIFY_EFFECT_CHAIN_SECONDS = 60;
|
|
141
|
+
var NONCE_ADVANCE_VERIFY_RETRIES = 3;
|
|
142
|
+
var NONCE_ADVANCE_VERIFY_RETRY_INTERVAL_MS = 2e3;
|
|
143
|
+
async function verifyEffectWithGrace(verifyEffect, { retries = NONCE_ADVANCE_VERIFY_RETRIES, intervalMs = NONCE_ADVANCE_VERIFY_RETRY_INTERVAL_MS } = {}) {
|
|
144
|
+
if (await verifyEffect()) return true;
|
|
145
|
+
for (let attempt = 0; attempt < retries; attempt++) {
|
|
146
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
147
|
+
if (await verifyEffect()) return true;
|
|
148
|
+
}
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
130
151
|
function classifyTxRetryDecision(err) {
|
|
131
152
|
const msg = err instanceof Error ? err.message : String(err);
|
|
132
153
|
const lower = msg.toLowerCase();
|
|
@@ -138,6 +159,12 @@ function classifyTxRetryDecision(err) {
|
|
|
138
159
|
if (lower.includes("transaction watcher silent")) return "retry";
|
|
139
160
|
return "abort";
|
|
140
161
|
}
|
|
162
|
+
function classifyWatcherSilentFastFail(err, isPhoneSigner) {
|
|
163
|
+
if (err instanceof WatcherSilentNoEventError && isPhoneSigner === true) {
|
|
164
|
+
return new NonRetryableError("No signature received from the phone \u2014 re-run when you can approve on your phone.");
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
141
168
|
var DOTNS_RETRY_BASE_MS = 400;
|
|
142
169
|
var DOTNS_RETRY_MAX_MS = 6e3;
|
|
143
170
|
function dotnsRetryBackoffMs(attempt, rand = Math.random) {
|
|
@@ -696,7 +723,7 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
696
723
|
if (nonce.advanced) {
|
|
697
724
|
if (opts.verifyEffect) {
|
|
698
725
|
statusCallback("verifying");
|
|
699
|
-
const observed = await opts.verifyEffect
|
|
726
|
+
const observed = await verifyEffectWithGrace(opts.verifyEffect);
|
|
700
727
|
if (!observed) {
|
|
701
728
|
statusCallback("failed");
|
|
702
729
|
finish(reject)(new Error(`nonce-advance fallback: nonce moved past ${opts.nonceFallback.expectedNonce} but expected on-chain effect not observable (likely a different tx of ours consumed the nonce, or our tx was reorged out)`));
|
|
@@ -724,7 +751,11 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
724
751
|
const silentMs = Date.now() - lastEventAt;
|
|
725
752
|
if (silentMs > TX_NO_PROGRESS_MS) {
|
|
726
753
|
statusCallback("failed");
|
|
727
|
-
|
|
754
|
+
if (lastEventType === "(none)") {
|
|
755
|
+
finish(reject)(new WatcherSilentNoEventError(silentMs));
|
|
756
|
+
} else {
|
|
757
|
+
finish(reject)(new Error(`transaction watcher silent for ${Math.floor(silentMs / 1e3)}s after ${lastEventType}`));
|
|
758
|
+
}
|
|
728
759
|
return;
|
|
729
760
|
}
|
|
730
761
|
} catch {
|
|
@@ -794,6 +825,11 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
794
825
|
return await this.signAndSubmitExtrinsic(buildExtrinsic(), signer, filter.callback, opts);
|
|
795
826
|
} catch (e) {
|
|
796
827
|
lastError = e;
|
|
828
|
+
const fastFail = classifyWatcherSilentFastFail(e, opts.isPhoneSigner);
|
|
829
|
+
if (fastFail) {
|
|
830
|
+
filter.flush();
|
|
831
|
+
throw fastFail;
|
|
832
|
+
}
|
|
797
833
|
const decision = classifyTxRetryDecision(e);
|
|
798
834
|
const msg = e?.message ?? String(e);
|
|
799
835
|
if (!shouldRetryTxAttempt(attempt, DOTNS_TX_MAX_ATTEMPTS, decision)) {
|
|
@@ -1430,18 +1466,19 @@ var DotNS = class {
|
|
|
1430
1466
|
if (rawData.length <= 2) {
|
|
1431
1467
|
const hasCode = await this.clientWrapper.hasContractCode(contractAddress);
|
|
1432
1468
|
const name = dotnsContractName(contractAddress, this._contracts);
|
|
1469
|
+
const env = this._environmentId ?? "(unset)";
|
|
1433
1470
|
if (hasCode === false) {
|
|
1434
1471
|
throw new Error(
|
|
1435
|
-
`No contract deployed at ${contractAddress} (${name}) \u2014 the dry-run call to ${functionName} returned empty success data, which on pallet-revive means the target address has no contract code. Check environments.json / --contract config for this network.`
|
|
1472
|
+
`No contract deployed at ${contractAddress} (${name}) env=${env} \u2014 the dry-run call to ${functionName} returned empty success data, which on pallet-revive means the target address has no contract code. Check environments.json / --contract config for this network.`
|
|
1436
1473
|
);
|
|
1437
1474
|
}
|
|
1438
1475
|
if (hasCode === null) {
|
|
1439
1476
|
throw new Error(
|
|
1440
|
-
`Contract call returned empty data \u2014 contract=${name} (${contractAddress}) functionName=${functionName}. Could not verify whether contract code exists at this address (runtime code-presence query failed); investigate the contract/ABI or the configured address.`
|
|
1477
|
+
`Contract call returned empty data \u2014 contract=${name} (${contractAddress}) env=${env} functionName=${functionName}. Could not verify whether contract code exists at this address (runtime code-presence query failed); investigate the contract/ABI or the configured address.`
|
|
1441
1478
|
);
|
|
1442
1479
|
}
|
|
1443
1480
|
throw new Error(
|
|
1444
|
-
`Contract call returned empty data \u2014 contract=${name} (${contractAddress}) functionName=${functionName}. The address has contract code but the call returned no bytes, which is unexpected for this read. Investigate the contract/ABI rather than masking it with a default.`
|
|
1481
|
+
`Contract call returned empty data \u2014 contract=${name} (${contractAddress}) env=${env} functionName=${functionName}. The address has contract code but the call returned no bytes, which is unexpected for this read. Investigate the contract/ABI rather than masking it with a default.`
|
|
1445
1482
|
);
|
|
1446
1483
|
}
|
|
1447
1484
|
return decodeFunctionResult({ abi: contractAbi, functionName, data: rawData });
|
|
@@ -1819,7 +1856,7 @@ var DotNS = class {
|
|
|
1819
1856
|
const target = this._contracts.DOTNS_CONTENT_RESOLVER;
|
|
1820
1857
|
let current = null;
|
|
1821
1858
|
try {
|
|
1822
|
-
current = await this.
|
|
1859
|
+
current = await this.contractCallNullable(this._contracts.DOTNS_REGISTRY, DOTNS_REGISTRY_ABI, "resolver", [node]);
|
|
1823
1860
|
} catch {
|
|
1824
1861
|
}
|
|
1825
1862
|
if (typeof current === "string" && current.toLowerCase() === target.toLowerCase()) {
|
|
@@ -1833,7 +1870,7 @@ var DotNS = class {
|
|
|
1833
1870
|
async getTextRecord(domainName, key) {
|
|
1834
1871
|
this.ensureConnected();
|
|
1835
1872
|
const node = namehash(`${domainName}.dot`);
|
|
1836
|
-
const result = await this.
|
|
1873
|
+
const result = await this.contractCallNullable(
|
|
1837
1874
|
this._contracts.DOTNS_CONTENT_RESOLVER,
|
|
1838
1875
|
DOTNS_TEXT_RESOLVER_ABI,
|
|
1839
1876
|
"text",
|
|
@@ -1880,7 +1917,7 @@ var DotNS = class {
|
|
|
1880
1917
|
let onChainValue = "";
|
|
1881
1918
|
let lastPrintedElapsed = -1;
|
|
1882
1919
|
while (true) {
|
|
1883
|
-
const onChain = await withTimeout(this.
|
|
1920
|
+
const onChain = await withTimeout(this.contractCallNullable(this._contracts.DOTNS_CONTENT_RESOLVER, DOTNS_TEXT_RESOLVER_ABI, "text", [node, key]), 3e4, "text");
|
|
1884
1921
|
onChainValue = onChain ?? "";
|
|
1885
1922
|
if (onChainValue === value) break;
|
|
1886
1923
|
const nowChainMs = Number(await this.clientWrapper.client.query.Timestamp.Now.getValue());
|
|
@@ -1937,7 +1974,7 @@ var DotNS = class {
|
|
|
1937
1974
|
const startChainMs = Number(await this.clientWrapper.client.query.Timestamp.Now.getValue());
|
|
1938
1975
|
let lastResults = [];
|
|
1939
1976
|
while (true) {
|
|
1940
|
-
lastResults = await Promise.all(entries.map((e) => withTimeout(this.
|
|
1977
|
+
lastResults = await Promise.all(entries.map((e) => withTimeout(this.contractCallNullable(this._contracts.DOTNS_CONTENT_RESOLVER, DOTNS_TEXT_RESOLVER_ABI, "text", [node, e.key]), 3e4, "text").then((onChain) => ({ key: e.key, expected: e.value, onChain: onChain ?? "" }))));
|
|
1941
1978
|
if (lastResults.every((v) => v.onChain === v.expected)) break;
|
|
1942
1979
|
const nowChainMs = Number(await this.clientWrapper.client.query.Timestamp.Now.getValue());
|
|
1943
1980
|
const chainElapsed = (nowChainMs - startChainMs) / 1e3;
|
|
@@ -2102,10 +2139,11 @@ var DotNS = class {
|
|
|
2102
2139
|
this.ensureConnected();
|
|
2103
2140
|
const node = namehash(`${domainName}.dot`);
|
|
2104
2141
|
const result = await withTimeout(
|
|
2105
|
-
this.
|
|
2142
|
+
this.contractCallNullable(this._contracts.DOTNS_CONTENT_RESOLVER, DOTNS_CONTENT_RESOLVER_ABI, "contenthash", [node]),
|
|
2106
2143
|
3e4,
|
|
2107
2144
|
"contenthash"
|
|
2108
2145
|
);
|
|
2146
|
+
if (result === null) return "0x";
|
|
2109
2147
|
return typeof result === "string" ? result : result?.toString?.() ?? String(result);
|
|
2110
2148
|
}
|
|
2111
2149
|
async classifyName(label) {
|
|
@@ -2759,8 +2797,13 @@ export {
|
|
|
2759
2797
|
TX_NO_PROGRESS_MS,
|
|
2760
2798
|
WS_HEARTBEAT_TIMEOUT_MS,
|
|
2761
2799
|
DOTNS_TX_MAX_ATTEMPTS,
|
|
2800
|
+
WatcherSilentNoEventError,
|
|
2762
2801
|
VERIFY_EFFECT_CHAIN_SECONDS,
|
|
2802
|
+
NONCE_ADVANCE_VERIFY_RETRIES,
|
|
2803
|
+
NONCE_ADVANCE_VERIFY_RETRY_INTERVAL_MS,
|
|
2804
|
+
verifyEffectWithGrace,
|
|
2763
2805
|
classifyTxRetryDecision,
|
|
2806
|
+
classifyWatcherSilentFastFail,
|
|
2764
2807
|
dotnsRetryBackoffMs,
|
|
2765
2808
|
shouldRetryTxAttempt,
|
|
2766
2809
|
shouldRegateBeforeResign,
|