crypto-aio 0.1.0 → 0.2.0
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/CHANGELOG.md +151 -1
- package/README.md +32 -12
- package/dist/adapters/evm/builder.js +64 -4
- package/dist/adapters/evm/builder.js.map +1 -1
- package/dist/adapters/evm/decode.js +6 -1
- package/dist/adapters/evm/decode.js.map +1 -1
- package/dist/adapters/evm/ethers-client.js +4 -0
- package/dist/adapters/evm/ethers-client.js.map +1 -1
- package/dist/adapters/evm/fees.d.ts +24 -0
- package/dist/adapters/evm/fees.js +47 -4
- package/dist/adapters/evm/fees.js.map +1 -1
- package/dist/adapters/evm/index.d.ts +1 -1
- package/dist/adapters/evm/index.js +2 -1
- package/dist/adapters/evm/index.js.map +1 -1
- package/dist/adapters/evm/network.d.ts +5 -0
- package/dist/adapters/evm/network.js +21 -2
- package/dist/adapters/evm/network.js.map +1 -1
- package/dist/adapters/evm/plugin.d.ts +5 -6
- package/dist/adapters/evm/plugin.js +50 -2
- package/dist/adapters/evm/plugin.js.map +1 -1
- package/dist/adapters/evm/proofs.js +17 -5
- package/dist/adapters/evm/proofs.js.map +1 -1
- package/dist/adapters/evm/reader.d.ts +18 -0
- package/dist/adapters/evm/reader.js +34 -0
- package/dist/adapters/evm/reader.js.map +1 -1
- package/dist/adapters/evm/tokens.d.ts +3 -0
- package/dist/adapters/evm/tokens.js.map +1 -1
- package/dist/adapters/evm/types.d.ts +10 -0
- package/dist/adapters/evm/types.js.map +1 -1
- package/dist/adapters/evm/web3-client.d.ts +6 -3
- package/dist/adapters/evm/web3-client.js +19 -2
- package/dist/adapters/evm/web3-client.js.map +1 -1
- package/dist/adapters/solana/builder.js +29 -18
- package/dist/adapters/solana/builder.js.map +1 -1
- package/dist/adapters/solana/fees.d.ts +12 -3
- package/dist/adapters/solana/fees.js +13 -4
- package/dist/adapters/solana/fees.js.map +1 -1
- package/dist/adapters/solana/message.d.ts +15 -0
- package/dist/adapters/solana/message.js +120 -0
- package/dist/adapters/solana/message.js.map +1 -0
- package/dist/adapters/solana/plugin.js +4 -1
- package/dist/adapters/solana/plugin.js.map +1 -1
- package/dist/adapters/solana/types.d.ts +8 -5
- package/dist/adapters/solana/types.js.map +1 -1
- package/dist/adapters/solana/web3.js +10 -32
- package/dist/adapters/solana/web3.js.map +1 -1
- package/dist/adapters/ton/proofs.js +18 -76
- package/dist/adapters/ton/proofs.js.map +1 -1
- package/dist/adapters/ton/reader.d.ts +45 -4
- package/dist/adapters/ton/reader.js +200 -5
- package/dist/adapters/ton/reader.js.map +1 -1
- package/dist/adapters/ton/trace.d.ts +26 -0
- package/dist/adapters/ton/trace.js +35 -9
- package/dist/adapters/ton/trace.js.map +1 -1
- package/dist/adapters/tron/abi.d.ts +2 -0
- package/dist/adapters/tron/abi.js +2 -0
- package/dist/adapters/tron/abi.js.map +1 -1
- package/dist/adapters/tron/builder.js +20 -4
- package/dist/adapters/tron/builder.js.map +1 -1
- package/dist/adapters/tron/decode.d.ts +2 -0
- package/dist/adapters/tron/decode.js +1 -1
- package/dist/adapters/tron/decode.js.map +1 -1
- package/dist/adapters/tron/proofs.js +1 -0
- package/dist/adapters/tron/proofs.js.map +1 -1
- package/dist/adapters/tron/reader.d.ts +10 -0
- package/dist/adapters/tron/reader.js +17 -0
- package/dist/adapters/tron/reader.js.map +1 -1
- package/dist/adapters/tron/tokens.d.ts +2 -0
- package/dist/adapters/tron/tokens.js.map +1 -1
- package/dist/adapters/utxo/builder.js +1 -1
- package/dist/adapters/utxo/builder.js.map +1 -1
- package/dist/adapters/utxo/chains.js +2 -1
- package/dist/adapters/utxo/chains.js.map +1 -1
- package/dist/adapters/utxo/context.d.ts +6 -0
- package/dist/adapters/utxo/context.js +8 -1
- package/dist/adapters/utxo/context.js.map +1 -1
- package/dist/adapters/utxo/decode.d.ts +8 -0
- package/dist/adapters/utxo/decode.js +36 -0
- package/dist/adapters/utxo/decode.js.map +1 -1
- package/dist/adapters/utxo/driver.js +5 -0
- package/dist/adapters/utxo/driver.js.map +1 -1
- package/dist/adapters/utxo/esplora.d.ts +23 -2
- package/dist/adapters/utxo/esplora.js +49 -2
- package/dist/adapters/utxo/esplora.js.map +1 -1
- package/dist/adapters/utxo/proofs.d.ts +15 -6
- package/dist/adapters/utxo/proofs.js +185 -47
- package/dist/adapters/utxo/proofs.js.map +1 -1
- package/dist/adapters/utxo/rawblock.d.ts +46 -0
- package/dist/adapters/utxo/rawblock.js +159 -0
- package/dist/adapters/utxo/rawblock.js.map +1 -0
- package/dist/adapters/utxo/rawtx.d.ts +14 -0
- package/dist/adapters/utxo/rawtx.js +44 -14
- package/dist/adapters/utxo/rawtx.js.map +1 -1
- package/dist/core/blockchain/handle.d.ts +6 -27
- package/dist/core/blockchain/handle.js +112 -112
- package/dist/core/blockchain/handle.js.map +1 -1
- package/dist/core/config/types.d.ts +15 -0
- package/dist/core/config/types.js.map +1 -1
- package/dist/core/container/container.d.ts +1 -8
- package/dist/core/container/container.js +42 -8
- package/dist/core/container/container.js.map +1 -1
- package/dist/core/driver/types.d.ts +34 -1
- package/dist/core/driver/types.js.map +1 -1
- package/dist/core/errors/codes.d.ts +10 -0
- package/dist/core/errors/codes.js +4 -0
- package/dist/core/errors/codes.js.map +1 -1
- package/dist/core/lifecycle/engine-rules.d.ts +3 -4
- package/dist/core/lifecycle/engine-rules.js +16 -6
- package/dist/core/lifecycle/engine-rules.js.map +1 -1
- package/dist/core/lifecycle/engine.d.ts +2 -0
- package/dist/core/lifecycle/engine.js +19 -1
- package/dist/core/lifecycle/engine.js.map +1 -1
- package/dist/core/lifecycle/evaluate.js +9 -4
- package/dist/core/lifecycle/evaluate.js.map +1 -1
- package/dist/core/lifecycle/monitor.js +16 -6
- package/dist/core/lifecycle/monitor.js.map +1 -1
- package/dist/core/lifecycle/reconcile.d.ts +1 -1
- package/dist/core/lifecycle/reconcile.js +1 -1
- package/dist/core/lifecycle/reconcile.js.map +1 -1
- package/dist/core/lifecycle/workers.d.ts +9 -3
- package/dist/core/lifecycle/workers.js +32 -14
- package/dist/core/lifecycle/workers.js.map +1 -1
- package/dist/core/model/ids.d.ts +1 -0
- package/dist/core/model/ids.js +1 -0
- package/dist/core/model/ids.js.map +1 -1
- package/dist/core/model/ordering.d.ts +8 -0
- package/dist/core/model/ordering.js.map +1 -1
- package/dist/core/model/transaction.d.ts +7 -0
- package/dist/core/model/transaction.js.map +1 -1
- package/dist/core/observe/scanner.js +3 -0
- package/dist/core/observe/scanner.js.map +1 -1
- package/dist/core/signing/wallet.js +8 -0
- package/dist/core/signing/wallet.js.map +1 -1
- package/dist/core/store/format.d.ts +20 -0
- package/dist/core/store/format.js +86 -0
- package/dist/core/store/format.js.map +1 -0
- package/dist/core/store/memory.js +2 -2
- package/dist/core/store/memory.js.map +1 -1
- package/dist/core/store/types.d.ts +15 -3
- package/dist/core/store/types.js +2 -0
- package/dist/core/store/types.js.map +1 -1
- package/dist/core/transport/http-transport.js +21 -13
- package/dist/core/transport/http-transport.js.map +1 -1
- package/dist/core/transport/types.d.ts +16 -1
- package/dist/core/transport/types.js.map +1 -1
- package/dist/core/util/json.d.ts +7 -1
- package/dist/core/util/json.js +13 -4
- package/dist/core/util/json.js.map +1 -1
- package/dist/core/util/names.d.ts +6 -0
- package/dist/core/util/names.js +10 -0
- package/dist/core/util/names.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/testing/contracts/operations.js +20 -1
- package/dist/testing/contracts/operations.js.map +1 -1
- package/dist/testing/env.d.ts +5 -0
- package/dist/testing/env.js +1 -1
- package/dist/testing/env.js.map +1 -1
- package/dist/testing/faulty-store.d.ts +2 -0
- package/dist/testing/faulty-store.js +5 -0
- package/dist/testing/faulty-store.js.map +1 -1
- package/package.json +17 -7
|
@@ -28,10 +28,15 @@ function evaluateOperation(op, observations) {
|
|
|
28
28
|
if (reverted) {
|
|
29
29
|
return {
|
|
30
30
|
state: 'failed',
|
|
31
|
-
error:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
error: of(reverted)?.failure === 'unevidenced'
|
|
32
|
+
? {
|
|
33
|
+
code: 'TX_UNEVIDENCED',
|
|
34
|
+
message: 'the transaction executed, but shows no transfer to the recipient: check the chain before paying again',
|
|
35
|
+
}
|
|
36
|
+
: {
|
|
37
|
+
code: 'TX_REVERTED',
|
|
38
|
+
message: 'the transaction was included but failed on chain',
|
|
39
|
+
},
|
|
35
40
|
winner: reverted,
|
|
36
41
|
};
|
|
37
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../../src/core/lifecycle/evaluate.ts"],"names":[],"mappings":";;AAwBA,
|
|
1
|
+
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../../src/core/lifecycle/evaluate.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CodesOf } from '../errors/codes';\nimport type {\n AttemptObservation,\n AttemptRecord,\n OperationRecord,\n OperationState,\n} from '../store/types';\n\nexport interface Evaluation {\n readonly state: OperationState;\n readonly outcome?: 'executed' | 'cancelled';\n readonly error?: { readonly code: CodesOf<'chain'>; readonly message: string };\n /** The Attempt whose proven result decided the Operation. */\n readonly winner?: AttemptRecord;\n}\n\nconst PROVEN_DEAD = new Set(['rejected', 'replaced', 'expired']);\n\n/**\n * Pure: derives the Operation state from its Attempts' observations.\n * Every terminal verdict rests on `proven` evidence only: an executed or reverted Attempt\n * proven in finalized state, or every Attempt proven dead (rejected, replaced, expired).\n * Observed-only states (`dropped`, `refused`, absence, an unfinalized block) never end it.\n */\nexport function evaluateOperation(\n op: OperationRecord,\n observations: ReadonlyMap<string, AttemptObservation>,\n): Evaluation {\n if (op.attempts.length === 0) return { state: op.state };\n const of = (attempt: AttemptRecord) => observations.get(attempt.id);\n const provenAs = (attempt: AttemptRecord, state: string) => {\n const o = of(attempt);\n return o?.evidence === 'proven' && o.state === state;\n };\n const executed = op.attempts.find((a) => provenAs(a, 'final'));\n if (executed) {\n return {\n state: 'final',\n outcome: executed.purpose === 'cancel' ? 'cancelled' : 'executed',\n winner: executed,\n };\n }\n const reverted = op.attempts.find((a) => provenAs(a, 'failed'));\n if (reverted) {\n return {\n state: 'failed',\n error:\n of(reverted)?.failure === 'unevidenced'\n ? {\n code: 'TX_UNEVIDENCED',\n message:\n 'the transaction executed, but shows no transfer to the recipient: check the chain before paying again',\n }\n : {\n code: 'TX_REVERTED',\n message: 'the transaction was included but failed on chain',\n },\n winner: reverted,\n };\n }\n const all = op.attempts.map(of);\n if (all.every((o) => o?.evidence === 'proven' && PROVEN_DEAD.has(o.state))) {\n if (all.some((o) => o?.state === 'expired')) {\n return {\n state: 'expired',\n error: {\n code: 'TX_EXPIRED',\n message: 'the transaction expired without being included',\n },\n };\n }\n if (all.every((o) => o?.state === 'rejected')) {\n return {\n state: 'failed',\n error: { code: 'TX_REJECTED', message: 'every attempt was rejected as invalid' },\n };\n }\n return {\n state: 'failed',\n error: {\n code: 'TX_REPLACED',\n message: 'the ordering slot was consumed by another transaction',\n },\n };\n }\n if (all.some((o) => o?.state === 'included' || o?.state === 'failed'))\n return { state: 'included' };\n const visible = all.some((o) => o?.state === 'mempool');\n if (op.state === 'stalled' && !visible) return { state: 'stalled' };\n if (op.state === 'signed' && !visible) return { state: 'signed' };\n return { state: 'submitted' };\n}\n"]}
|
|
@@ -279,6 +279,7 @@ class Monitor {
|
|
|
279
279
|
// Why an included transaction failed, as the driver's fixed text; any earlier
|
|
280
280
|
// reason (a refusal, an old failure) is cleared otherwise.
|
|
281
281
|
reason: seen.success === false ? seen.reason : undefined,
|
|
282
|
+
failure: seen.success === false ? (seen.failure ?? 'reverted') : undefined,
|
|
282
283
|
firstSeenAt: current?.firstSeenAt ?? now,
|
|
283
284
|
lastSeenAt: now,
|
|
284
285
|
};
|
|
@@ -304,6 +305,7 @@ class Monitor {
|
|
|
304
305
|
blockHeight: undefined,
|
|
305
306
|
confirmations: 0,
|
|
306
307
|
reason: undefined,
|
|
308
|
+
failure: undefined,
|
|
307
309
|
};
|
|
308
310
|
patch =
|
|
309
311
|
seen.seen === 'mempool'
|
|
@@ -364,7 +366,7 @@ class Monitor {
|
|
|
364
366
|
blockHash: proof.blockHash,
|
|
365
367
|
txHash: proof.txHash,
|
|
366
368
|
confirmations: depth(head, proof.blockHeight),
|
|
367
|
-
|
|
369
|
+
...failureOf(proof),
|
|
368
370
|
};
|
|
369
371
|
}
|
|
370
372
|
/**
|
|
@@ -413,7 +415,7 @@ class Monitor {
|
|
|
413
415
|
blockHeight: proof.blockHeight,
|
|
414
416
|
blockHash: proof.blockHash,
|
|
415
417
|
txHash: proof.txHash,
|
|
416
|
-
|
|
418
|
+
...failureOf(proof),
|
|
417
419
|
};
|
|
418
420
|
}
|
|
419
421
|
return { state: deadSlot ? 'replaced' : 'expired', evidence: 'proven' };
|
|
@@ -422,7 +424,12 @@ class Monitor {
|
|
|
422
424
|
return { state: 'replaced', evidence: 'observed' };
|
|
423
425
|
}
|
|
424
426
|
if (current?.state === 'refused') {
|
|
425
|
-
return {
|
|
427
|
+
return {
|
|
428
|
+
state: 'refused',
|
|
429
|
+
evidence: 'observed',
|
|
430
|
+
reason: current.reason,
|
|
431
|
+
failure: undefined,
|
|
432
|
+
};
|
|
426
433
|
}
|
|
427
434
|
const since = current?.lastSeenAt ?? current?.lastBroadcastAt ?? attempt.createdAt;
|
|
428
435
|
const dropped = now - since >= this.deps.lifecycle().droppedGracePeriodMs;
|
|
@@ -446,6 +453,7 @@ class Monitor {
|
|
|
446
453
|
evidence: 'proven',
|
|
447
454
|
replacedBy: winner.ref.id,
|
|
448
455
|
reason: undefined,
|
|
456
|
+
failure: undefined,
|
|
449
457
|
});
|
|
450
458
|
}
|
|
451
459
|
}
|
|
@@ -596,11 +604,13 @@ function depth(head, height) {
|
|
|
596
604
|
return d > 0n ? Number(d) : 0;
|
|
597
605
|
}
|
|
598
606
|
/**
|
|
599
|
-
* A proven failure's fixed reason; a success clears
|
|
607
|
+
* A proven failure's fixed reason and what failed; a success clears both. Drivers give a
|
|
600
608
|
* fixed text because a node's own text can carry addresses or amounts; the stored reason
|
|
601
609
|
* is sensitive data, and no event carries it.
|
|
602
610
|
*/
|
|
603
|
-
function
|
|
604
|
-
return proof.success
|
|
611
|
+
function failureOf(proof) {
|
|
612
|
+
return proof.success
|
|
613
|
+
? { reason: undefined, failure: undefined }
|
|
614
|
+
: { reason: proof.reason, failure: proof.failure ?? 'reverted' };
|
|
605
615
|
}
|
|
606
616
|
//# sourceMappingURL=monitor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../../src/core/lifecycle/monitor.ts"],"names":[],"mappings":"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","sourcesContent":["import { statusFromObservation } from '../blockchain/mapping';\nimport type { ResolvedSelection } from '../config/types';\nimport type { ProofSource } from '../driver/types';\nimport {\n ChainError,\n StateError,\n TimeoutError,\n ValidationError,\n isCryptoAioError,\n type SerializedError,\n} from '../errors/error';\nimport type { EventBus } from '../events/bus';\nimport type { Logger } from '../events/logger';\nimport type { TxStatus } from '../model/transaction';\nimport {\n isTerminal,\n type AttemptObservation,\n type AttemptRecord,\n type ClearableField,\n type Fence,\n type OperationPatch,\n type OperationRecord,\n type Stores,\n} from '../store/types';\nimport { isStaleView } from '../transport/stale-view';\nimport type { Clock } from '../util/clock';\nimport {\n PRE_SIGNING_STATES,\n errorCode,\n rehydrateError,\n type OperationEngine,\n type OperationTarget,\n type ReadTarget,\n type ResolvedLifecycle,\n} from './engine';\nimport { evaluateOperation } from './evaluate';\nimport {\n loadObservations,\n writeObservation,\n type ObservationDeps,\n type ObservationPatch,\n} from './observations';\nimport { statusOf, type OperationView } from './views';\nimport { Workers, type RecoveryReport, type WorkerOptions } from './workers';\n\nexport interface WaitOptions {\n /** Default: the handle's `confirmations`. Ignored when `finality: 'final'`. */\n readonly confirmations?: number;\n readonly finality?: 'included' | 'final';\n readonly timeoutMs?: number;\n readonly pollIntervalMs?: number;\n readonly signal?: AbortSignal;\n}\n\nexport interface ConfirmationResult {\n readonly status: TxStatus;\n readonly operation?: OperationView;\n}\n\nexport interface TxStatusEvent {\n readonly status: TxStatus;\n readonly operation?: OperationView;\n}\n\nexport type { RecoveryReport, WorkerOptions } from './workers';\n\n/**\n * Rebuilds the wallet-bound target of a stored Operation (from its `context`); `undefined`\n * (or a rejection) when it cannot be resolved any more, e.g. its wallet config is gone.\n */\nexport type TargetResolver = (\n op: OperationRecord,\n) => Promise<OperationTarget | undefined>;\n\n/** Rebuilds the signer-free read target of a stored Operation; see `TargetResolver`. */\nexport type ReadResolver = (op: OperationRecord) => Promise<ReadTarget | undefined>;\n\nexport interface MonitorDeps {\n readonly engine: OperationEngine;\n readonly stores: Stores;\n readonly events: EventBus;\n readonly clock: Clock;\n readonly log: Logger;\n readonly namespace: string;\n readonly lifecycle: () => ResolvedLifecycle;\n /**\n * Every check, worker pass and recovery read runs on this target (no wallet), so a\n * signer rotated out of config or a hung `getPublicKey` never stalls monitoring.\n */\n readonly resolveRead: ReadResolver;\n /**\n * Resolved lazily, only for the writes that need a wallet-bound target: the\n * all-rejected verdict, nonce reconciliation and recovery's resend (none of them signs).\n * Known gap: for the all-rejected verdict this resolution is bounded neither by the\n * pass `signal` nor by a per-pass cache, so each such Operation of a pass can wait up\n * to `lifecycle.signTimeoutMs` for a wallet whose resolution keeps failing.\n */\n readonly resolveTarget: TargetResolver;\n}\n\ninterface Snapshot {\n readonly status: TxStatus;\n readonly record?: OperationRecord;\n}\n\nconst SETTLED = new Set(['final', 'failed', 'rejected', 'replaced', 'expired']);\nconst UNKNOWN: TxStatus = {\n state: 'unknown',\n evidence: 'observed',\n confirmations: 0,\n finality: 'none',\n};\n\n/** Proven and settled: nothing observed later may overwrite it. */\nfunction isSettled(observation: AttemptObservation | null | undefined): boolean {\n return observation?.evidence === 'proven' && SETTLED.has(observation.state);\n}\n\n/**\n * Watches Attempts on chain and moves their Operation on evidence.\n * Observed data (a single endpoint's view, absence, `dropped`, `refused`, an unfinalized\n * block) only ever produces non-terminal states; a terminal state needs `proven` evidence\n * (finalized data confirmed by quorum proof reads). A stale view decides nothing.\n */\nexport class Monitor {\n /** The worker loop and recovery, over this monitor's checks. */\n readonly #workers: Workers;\n\n constructor(private readonly deps: MonitorDeps) {\n this.#workers = new Workers(deps, {\n checkPass: (target, op, fence, signal) =>\n this.#checkPass(target, op, fence, signal),\n check: (target, op, fence, signal) => this.check(target, op, fence, signal),\n find: (ref) => this.find(ref),\n });\n }\n\n private get observationDeps(): ObservationDeps {\n return {\n operations: this.deps.stores.operations,\n events: this.deps.events,\n namespace: this.deps.namespace,\n };\n }\n\n /** Finds a managed Operation by id, Attempt ref or observed canonical tx hash. */\n async find(ref: string): Promise<OperationRecord | null> {\n const store = this.deps.stores.operations;\n return (\n (await store.get(this.deps.namespace, ref)) ??\n (await store.findByRef(this.deps.namespace, ref))\n );\n }\n\n /**\n * One evaluation pass: observe live Attempts, persist observations, apply the transition.\n * `signal` is checked before every read, so an aborted pass stops after at most the\n * read in flight; it then throws the signal's reason and decides nothing further.\n */\n async check(\n target: ReadTarget,\n op: OperationRecord,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<OperationRecord> {\n return (await this.#checkPass(target, op, fence, signal)).record;\n }\n\n /** `check`, also telling whether the view was stale (it then decided nothing). */\n async #checkPass(\n target: ReadTarget,\n op: OperationRecord,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<{ readonly record: OperationRecord; readonly stale: boolean }> {\n if (isTerminal(op.state) || PRE_SIGNING_STATES.has(op.state))\n return { record: op, stale: false };\n const { pooled } = target;\n signal?.throwIfAborted();\n await pooled.transport.ensureFreshHealth(signal);\n signal?.throwIfAborted();\n const [head, finalized] = await Promise.all([\n pooled.driver.reader.getBlockHeight(),\n pooled.driver.reader.getFinalizedHeight(),\n ]);\n if (isStaleView(pooled.transport, head)) return { record: op, stale: true };\n const observations = new Map<string, AttemptObservation>();\n for (const attempt of op.attempts) {\n try {\n observations.set(\n attempt.id,\n await this.observeAttempt(target, op, attempt, head, finalized, signal),\n );\n } catch (error) {\n if (signal?.aborted || !isCryptoAioError(error) || !error.retryable) throw error;\n const current = await this.deps.stores.operations.getObservation(attempt.id);\n if (current) observations.set(attempt.id, current);\n }\n }\n return {\n record: await this.applyEvaluation(op, observations, fence, signal),\n stale: false,\n };\n }\n\n /** Current status of a managed Operation (after a check) or of an arbitrary transaction id. */\n async status(target: ReadTarget, ref: string, signal?: AbortSignal): Promise<Snapshot> {\n let record = await this.find(ref);\n if (!record) return { status: await this.rawStatus(target, ref) };\n assertSameNetwork(target.selection, record);\n if (!isTerminal(record.state) && !PRE_SIGNING_STATES.has(record.state)) {\n try {\n record = await this.check(target, record, undefined, signal);\n } catch (error) {\n if (signal?.aborted || !isCryptoAioError(error) || !error.retryable) throw error;\n }\n }\n const observations = await loadObservations(this.deps.stores.operations, record);\n return { status: this.bestStatus(record, observations), record };\n }\n\n /**\n * Polls until the wanted status: `confirmations` (default: the handle's) or, with\n * `finality: 'final'`, proven finality for a managed Operation and observed finality for\n * a transaction it does not manage. The caller's `signal` and the deadline bound\n * every pass and sleep; a pass stops after at most the read in flight.\n */\n async waitFor(\n target: ReadTarget,\n ref: string,\n options: WaitOptions = {},\n ): Promise<Snapshot> {\n const { signal } = options;\n if (signal?.aborted) throw signal.reason;\n const lifecycle = this.deps.lifecycle();\n const deadline =\n this.deps.clock.now() + (options.timeoutMs ?? lifecycle.waitTimeoutMs);\n const poll = options.pollIntervalMs ?? lifecycle.pollIntervalMs;\n const wanted = options.confirmations ?? target.selection.confirmations;\n const wantFinal = options.finality === 'final';\n let last: Snapshot | undefined;\n const stopped = (): unknown =>\n signal?.aborted\n ? signal.reason\n : new TimeoutError(\n 'TIMEOUT',\n 'the transaction was not confirmed before the timeout',\n {\n context: last?.record ? { operationId: last.record.id } : {},\n },\n );\n // One signal for every pass and sleep: the caller's abort or the deadline.\n const bound = new AbortController();\n const finished = new AbortController();\n const onAbort = () => bound.abort();\n signal?.addEventListener('abort', onAbort, { once: true });\n this.deps.clock\n .sleep(Math.max(0, deadline - this.deps.clock.now()), finished.signal)\n .then(onAbort, () => undefined);\n try {\n for (;;) {\n if (bound.signal.aborted || this.deps.clock.now() >= deadline) throw stopped();\n let snapshot: Snapshot | undefined;\n try {\n snapshot = await this.status(target, ref, bound.signal);\n } catch (error) {\n if (bound.signal.aborted) throw stopped();\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n }\n if (snapshot) {\n last = snapshot;\n const { status, record } = snapshot;\n if (record?.state === 'final') return snapshot;\n if (record && (record.state === 'failed' || record.state === 'expired')) {\n throw rehydrateError(record.error ?? this.defaultError(record), record.id);\n }\n if (record?.state === 'abandoned') {\n throw new StateError(\n 'INVALID_TRANSITION',\n `operation '${record.id}' was abandoned`,\n );\n }\n if (!record && status.state === 'failed' && status.finality === 'final') {\n throw new ChainError(\n 'TX_REVERTED',\n 'the transaction was included but failed on chain',\n );\n }\n const reached = wantFinal\n ? status.state === 'final' || unmanagedFinal(snapshot)\n : status.state === 'final' ||\n (status.state === 'included' && status.confirmations >= wanted);\n if (reached) return snapshot;\n }\n try {\n await this.deps.clock.sleep(poll, bound.signal);\n } catch {\n throw stopped();\n }\n }\n } finally {\n finished.abort();\n signal?.removeEventListener('abort', onAbort);\n }\n }\n\n /**\n * Yields each status change until the Operation is terminal, or until a transaction\n * it does not manage reaches observed finality, whether it succeeded or reverted. Ends\n * quietly when `signal` aborts.\n */\n async *watch(\n target: ReadTarget,\n ref: string,\n options: { readonly pollIntervalMs?: number; readonly signal?: AbortSignal } = {},\n ): AsyncGenerator<Snapshot> {\n const { signal } = options;\n const poll = options.pollIntervalMs ?? this.deps.lifecycle().pollIntervalMs;\n let last = '';\n while (!signal?.aborted) {\n let snapshot: Snapshot | undefined;\n try {\n snapshot = await this.status(target, ref, signal);\n } catch (error) {\n if (signal?.aborted) return;\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n }\n if (snapshot) {\n const { status, record } = snapshot;\n const key = [\n status.state,\n status.evidence,\n status.confirmations,\n status.blockHash ?? '',\n record?.state ?? '',\n ].join('|');\n if (key !== last) {\n last = key;\n yield snapshot;\n }\n if (record ? isTerminal(record.state) : unmanagedFinal(snapshot)) return;\n }\n try {\n await this.deps.clock.sleep(poll, signal);\n } catch {\n return;\n }\n }\n }\n\n // ---- workers and recovery ------------------------------------------------------------\n\n /** One worker pass (see `Workers.runOnce`); resolves to how many Operations it claimed. */\n runOnce(options: {\n readonly workerId: string;\n readonly batch?: number;\n readonly signal?: AbortSignal;\n }): Promise<number> {\n return this.#workers.runOnce(options);\n }\n\n /** Runs worker passes until `signal` aborts (see `Workers.start`). */\n start(options: WorkerOptions = {}): Promise<void> {\n return this.#workers.start(options);\n }\n\n /** Startup recovery for this namespace; it never signs (see `Workers.recover`). */\n recover(options: { readonly signal?: AbortSignal } = {}): Promise<RecoveryReport> {\n return this.#workers.recover(options);\n }\n\n // ---- observation ---------------------------------------------------------------------\n\n private async observeAttempt(\n target: ReadTarget,\n op: OperationRecord,\n attempt: AttemptRecord,\n head: bigint,\n finalized: bigint,\n signal?: AbortSignal,\n ): Promise<AttemptObservation> {\n const current = await this.deps.stores.operations.getObservation(attempt.id);\n if (current && isSettled(current)) return current;\n const { driver } = target.pooled;\n const from = op.intent.from;\n const now = this.deps.clock.now();\n signal?.throwIfAborted();\n const seen = await driver.reader.observe(attempt.ref, attempt.ordering, from);\n signal?.throwIfAborted();\n let reorgedFrom: string | undefined;\n let patch: ObservationPatch;\n if (seen.seen === 'block' && seen.blockHeight !== undefined) {\n // The transaction is in another block than recorded: its old block was orphaned, once\n // the quorum confirms it; one endpoint's other block alone decides nothing.\n if (\n current?.blockHash !== undefined &&\n seen.blockHash !== undefined &&\n current.blockHash !== seen.blockHash\n ) {\n if (!(await this.orphaned(target, current))) return current;\n signal?.throwIfAborted();\n reorgedFrom = current.blockHash;\n }\n patch = {\n state: seen.success === false ? 'failed' : 'included',\n evidence: 'observed',\n confirmations: depth(head, seen.blockHeight),\n blockHeight: seen.blockHeight,\n blockHash: seen.blockHash,\n ...(seen.txHash !== undefined ? { txHash: seen.txHash } : {}),\n // Why an included transaction failed, as the driver's fixed text; any earlier\n // reason (a refusal, an old failure) is cleared otherwise.\n reason: seen.success === false ? seen.reason : undefined,\n firstSeenAt: current?.firstSeenAt ?? now,\n lastSeenAt: now,\n };\n if (seen.blockHeight <= finalized)\n patch = await this.proveFinal(target, op, attempt, patch, head, signal);\n } else {\n if (current?.blockHash !== undefined) {\n // Absence (or a mempool sighting) of an included transaction is not evidence of a\n // reorg by itself: a lagging or inconsistent endpoint shows the same. Only a\n // quorum-served different block at the recorded height proves it; otherwise decide\n // nothing.\n if (!(await this.orphaned(target, current))) return current;\n signal?.throwIfAborted();\n reorgedFrom = current.blockHash;\n }\n // Out of a block, an earlier failure's reason no longer applies (a refusal keeps\n // its own, below). Clearing relies on `putObservation` replacing the whole record,\n // a key set to `undefined` being absent.\n const cleared: ObservationPatch = {\n blockHash: undefined,\n blockHeight: undefined,\n confirmations: 0,\n reason: undefined,\n };\n patch =\n seen.seen === 'mempool'\n ? {\n ...cleared,\n state: 'mempool',\n evidence: 'observed',\n firstSeenAt: current?.firstSeenAt ?? now,\n lastSeenAt: now,\n }\n : {\n ...cleared,\n ...(await this.whenAbsent(target, op, attempt, current, now, signal)),\n };\n }\n // This patch was derived from `current`; when another writer changed the\n // observation meanwhile (possibly with stronger evidence), keep theirs and decide nothing.\n let applied = false;\n const saved = await writeObservation(\n this.observationDeps,\n attempt,\n op.id,\n (stored) => {\n applied = (stored?.version ?? null) === (current?.version ?? null);\n return applied ? patch : undefined;\n },\n );\n if (!applied) return saved;\n if (reorgedFrom !== undefined) this.#reorged(op, attempt, reorgedFrom);\n if (\n saved.state === 'dropped' &&\n attempt.id === op.activeAttemptId &&\n op.state !== 'stalled'\n ) {\n signal?.throwIfAborted();\n await this.#rebroadcastDropped(target, op, attempt, saved, now, signal);\n }\n return saved;\n }\n\n /**\n * A block at or below the finalized height becomes `final`/`failed` + `proven` only when\n * the quorum proof confirms it. A retryable proof failure (e.g. PROVIDER_INCONSISTENT)\n * decides nothing: the observed patch is kept.\n */\n private async proveFinal(\n target: ReadTarget,\n op: OperationRecord,\n attempt: AttemptRecord,\n patch: ObservationPatch,\n head: bigint,\n signal?: AbortSignal,\n ): Promise<ObservationPatch> {\n let proof: Awaited<ReturnType<ProofSource['includedFinal']>>;\n signal?.throwIfAborted();\n try {\n proof = await target.pooled.driver.proofs.includedFinal(\n attempt.ref,\n attempt.ordering,\n op.intent.from,\n );\n } catch (error) {\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n return patch;\n }\n if (!proof.included) return patch;\n return {\n ...patch,\n state: proof.success ? 'final' : 'failed',\n evidence: 'proven',\n blockHeight: proof.blockHeight,\n blockHash: proof.blockHash,\n txHash: proof.txHash,\n confirmations: depth(head, proof.blockHeight),\n reason: failureReason(proof),\n };\n }\n\n /**\n * Whether the block recorded for `observation` is no longer the one at its height.\n * Only the quorum-served hash decides; a disagreement or other retryable failure, or no\n * block at that height yet, decides nothing (`false`).\n */\n private async orphaned(\n target: ReadTarget,\n observation: AttemptObservation,\n ): Promise<boolean> {\n const { blockHeight, blockHash } = observation;\n if (blockHeight === undefined || blockHash === undefined) return false;\n let canonical: string | null;\n try {\n canonical = await target.pooled.driver.proofs.blockHash(blockHeight, 'latest');\n } catch (error) {\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n return false;\n }\n return canonical !== null && canonical !== blockHash;\n }\n\n /** The transaction is not visible anywhere we can see: only finalized proofs may declare it dead. */\n private async whenAbsent(\n target: ReadTarget,\n op: OperationRecord,\n attempt: AttemptRecord,\n current: AttemptObservation | null,\n now: number,\n signal?: AbortSignal,\n ): Promise<ObservationPatch> {\n const { proofs } = target.pooled.driver;\n const read = <T>(work: () => Promise<T>): Promise<T> => {\n signal?.throwIfAborted();\n return work();\n };\n // The built ordering (never the reservation, whose seqno `validUntil`\n // the driver may have replaced while building).\n const ordering = attempt.ordering;\n const from = op.intent.from;\n const slotted =\n ordering.kind === 'nonce' ||\n ordering.kind === 'seqno' ||\n ordering.kind === 'inputs';\n const expiring = ordering.kind === 'expiry' || ordering.kind === 'seqno';\n const deadSlot =\n slotted && (await read(() => proofs.slotConsumed(ordering, from, 'finalized')));\n const deadExpiry =\n !deadSlot && expiring && (await read(() => proofs.expired(ordering)));\n if (deadSlot || deadExpiry) {\n const proof = await read(() => proofs.includedFinal(attempt.ref, ordering, from));\n if (proof.included) {\n return {\n state: proof.success ? 'final' : 'failed',\n evidence: 'proven',\n blockHeight: proof.blockHeight,\n blockHash: proof.blockHash,\n txHash: proof.txHash,\n reason: failureReason(proof),\n };\n }\n return { state: deadSlot ? 'replaced' : 'expired', evidence: 'proven' };\n }\n if (slotted && (await read(() => proofs.slotConsumed(ordering, from, 'latest')))) {\n return { state: 'replaced', evidence: 'observed' };\n }\n if (current?.state === 'refused') {\n return { state: 'refused', evidence: 'observed', reason: current.reason };\n }\n const since = current?.lastSeenAt ?? current?.lastBroadcastAt ?? attempt.createdAt;\n const dropped = now - since >= this.deps.lifecycle().droppedGracePeriodMs;\n return { state: dropped ? 'dropped' : 'pending', evidence: 'observed' };\n }\n\n private async applyEvaluation(\n op: OperationRecord,\n observations: ReadonlyMap<string, AttemptObservation>,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<OperationRecord> {\n const evaluation = evaluateOperation(op, observations);\n const { winner } = evaluation;\n if (winner) {\n // The winner consumed the ordering slot: every other Attempt is proven replaced by it.\n // As in `whenAbsent`, a proven `replaced` carries no reason: a refusal's no longer\n // applies.\n const linked = (o: AttemptObservation | null | undefined) =>\n isSettled(o) && !(o?.state === 'replaced' && o.replacedBy === undefined);\n for (const attempt of op.attempts) {\n if (attempt.id === winner.id || linked(observations.get(attempt.id))) continue;\n await writeObservation(this.observationDeps, attempt, op.id, (stored) =>\n linked(stored)\n ? undefined\n : {\n state: 'replaced',\n evidence: 'proven',\n replacedBy: winner.ref.id,\n reason: undefined,\n },\n );\n }\n }\n // Failing an all-rejected Operation releases its nonce, so the engine applies it\n // under the address lease; the monitor never makes a reservation-holding transition.\n if (evaluation.error?.code === 'TX_REJECTED')\n return this.failRejected(op, signal, fence);\n const terminal = isTerminal(evaluation.state);\n // A read-only pass (no fence) writes the Operation only when its state, outcome\n // or error changes, never just to schedule it: a version bump would make a concurrent\n // engine write (e.g. right after a broadcast) lose its compare-and-set. Scheduling\n // (`nextCheckAt`) belongs to fenced workers and to engine transitions.\n const changed =\n evaluation.state !== op.state ||\n (evaluation.outcome !== undefined && evaluation.outcome !== op.outcome) ||\n (evaluation.error !== undefined && evaluation.error.code !== op.error?.code);\n if (!changed && !fence) return op;\n const clear: ClearableField[] = [];\n if (terminal) clear.push('nextCheckAt');\n if (op.state === 'stalled' && evaluation.state !== 'stalled' && !evaluation.error)\n clear.push('error');\n const patch: OperationPatch = {\n ...(evaluation.state !== op.state ? { state: evaluation.state } : {}),\n ...(evaluation.outcome ? { outcome: evaluation.outcome } : {}),\n ...(evaluation.error\n ? {\n error: new ChainError(evaluation.error.code, evaluation.error.message, {\n context: { operationId: op.id },\n }).toJSON(),\n }\n : {}),\n ...(fence && !terminal\n ? { nextCheckAt: this.deps.clock.now() + this.deps.lifecycle().pollIntervalMs }\n : {}),\n ...(clear.length > 0 ? { clear } : {}),\n };\n return this.deps.engine.update(op, patch, fence);\n }\n\n /**\n * Hands the all-rejected verdict to the engine: an unfenced pass (`tryOnce`) tries the\n * lease once, a fenced one waits `acquireTimeoutMs`, and either wait is bounded by the\n * pass `signal` (the caller's abort and, in `waitFor`, its deadline). A fenced pass's\n * terminal write carries its claim `fence`, so a worker whose claim was taken over writes\n * nothing. An unresolvable target leaves the Operation non-terminal.\n */\n private async failRejected(\n op: OperationRecord,\n signal: AbortSignal | undefined,\n fence: Fence | undefined,\n ): Promise<OperationRecord> {\n let target: OperationTarget | undefined;\n let failure: unknown;\n try {\n target = await this.deps.resolveTarget(op);\n } catch (error) {\n failure = error;\n }\n if (!target) {\n this.deps.log.warn('cannot resolve the target to fail a rejected operation', {\n operationId: op.id,\n code: errorCode(failure),\n });\n return op;\n }\n // Every unfenced pass (`getTransactionStatus`, `watch`, `waitFor`), signalled or not,\n // tries the lease once: a busy lease leaves the Operation for a later pass. Only a\n // fenced worker pass waits `acquireTimeoutMs`.\n return this.deps.engine.failRejected(target, op, {\n signal,\n ...(fence ? { fence } : { acquireTimeoutMs: 0 }),\n });\n }\n\n private bestStatus(\n record: OperationRecord,\n observations: ReadonlyMap<string, AttemptObservation>,\n ): TxStatus {\n const all = record.attempts\n .map((a) => observations.get(a.id))\n .filter((o): o is AttemptObservation => o !== undefined);\n const chosen =\n all.find(\n (o) => o.state === 'final' || (o.state === 'failed' && o.evidence === 'proven'),\n ) ??\n all\n .filter((o) => o.state === 'included' || o.state === 'failed')\n .sort((a, b) => b.confirmations - a.confirmations)[0] ??\n (record.activeAttemptId ? observations.get(record.activeAttemptId) : undefined);\n return chosen ? statusOf(chosen) : UNKNOWN;\n }\n\n private async rawStatus(target: ReadTarget, id: string): Promise<TxStatus> {\n const { reader } = target.pooled.driver;\n const [observation, head, finalized] = await Promise.all([\n reader.observe({ id, idKind: 'tx-hash', canonical: true }, undefined, undefined),\n reader.getBlockHeight(),\n reader.getFinalizedHeight(),\n ]);\n return statusFromObservation(observation, head, finalized);\n }\n\n private defaultError(record: OperationRecord): SerializedError {\n const code = record.state === 'expired' ? 'TX_EXPIRED' : 'TX_REJECTED';\n return new ChainError(code, `operation ended in state '${record.state}'`).toJSON();\n }\n\n #reorged(op: OperationRecord, attempt: AttemptRecord, previousBlockHash: string): void {\n this.deps.events.emit('tx.reorged', {\n namespace: this.deps.namespace,\n operationId: op.id,\n attemptId: attempt.id,\n previousBlockHash,\n });\n }\n\n /**\n * Resends the stored raw bytes of a dropped active Attempt, at most once per\n * `rebroadcastIntervalMs`. The answer decides nothing: `dropped` is never terminal,\n * and a refusal or rejection of bytes a node once held says nothing about them. An\n * acceptance is remembered (`firstSeenAt`) like the engine's broadcast path does.\n */\n async #rebroadcastDropped(\n target: ReadTarget,\n op: OperationRecord,\n attempt: AttemptRecord,\n observation: AttemptObservation,\n now: number,\n signal?: AbortSignal,\n ): Promise<void> {\n if (\n now - (observation.lastBroadcastAt ?? 0) <\n this.deps.lifecycle().rebroadcastIntervalMs\n )\n return;\n let accepted = false;\n try {\n const result = await target.pooled.driver.broadcaster.broadcast(\n { raw: attempt.raw, ref: attempt.ref },\n signal ? { signal } : {},\n );\n accepted = result.kind === 'accepted' || result.kind === 'already-known';\n } catch (error) {\n // The code only: an error message may carry detail that logs must not.\n this.deps.log.debug('rebroadcast of a dropped attempt failed', {\n operationId: op.id,\n code: errorCode(error),\n });\n }\n await writeObservation(this.observationDeps, attempt, op.id, (stored) => ({\n lastBroadcastAt: now,\n ...(accepted ? { firstSeenAt: stored?.firstSeenAt ?? now } : {}),\n }));\n }\n}\n\n/** Refuses a stored Operation of another chain or network than `selection` (INVALID_INTENT). */\nexport function assertSameNetwork(\n selection: Pick<ResolvedSelection, 'chain' | 'network'>,\n record: OperationRecord,\n): void {\n const { chain, network } = selection;\n if (record.context.chain !== chain.id || record.context.network !== network.id) {\n throw new ValidationError(\n 'INVALID_INTENT',\n `operation '${record.id}' belongs to ${record.context.chain}:${record.context.network}, not ${chain.id}:${network.id}`,\n );\n }\n}\n\n/**\n * An unmanaged transaction has no proofs to wait for: its observed finality is the answer,\n * whether it succeeded or reverted (`waitFor` rejects a reverted one with TX_REVERTED).\n */\nfunction unmanagedFinal({ status, record }: Snapshot): boolean {\n return !record && status.finality === 'final';\n}\n\nfunction depth(head: bigint, height: bigint): number {\n const d = head - height + 1n;\n return d > 0n ? Number(d) : 0;\n}\n\n/**\n * A proven failure's fixed reason; a success clears any earlier reason. Drivers give a\n * fixed text because a node's own text can carry addresses or amounts; the stored reason\n * is sensitive data, and no event carries it.\n */\nfunction failureReason(proof: {\n readonly success: boolean;\n readonly reason?: string;\n}): string | undefined {\n return proof.success ? undefined : proof.reason;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../../src/core/lifecycle/monitor.ts"],"names":[],"mappings":"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","sourcesContent":["import { statusFromObservation } from '../blockchain/mapping';\nimport type { ResolvedSelection } from '../config/types';\nimport type { ProofSource } from '../driver/types';\nimport {\n ChainError,\n StateError,\n TimeoutError,\n ValidationError,\n isCryptoAioError,\n type SerializedError,\n} from '../errors/error';\nimport type { EventBus } from '../events/bus';\nimport type { Logger } from '../events/logger';\nimport type { TxFailure, TxStatus } from '../model/transaction';\nimport {\n isTerminal,\n type AttemptObservation,\n type AttemptRecord,\n type ClearableField,\n type Fence,\n type OperationPatch,\n type OperationRecord,\n type Stores,\n} from '../store/types';\nimport { isStaleView } from '../transport/stale-view';\nimport type { Clock } from '../util/clock';\nimport {\n PRE_SIGNING_STATES,\n errorCode,\n rehydrateError,\n type OperationEngine,\n type OperationTarget,\n type ReadTarget,\n type ResolvedLifecycle,\n} from './engine';\nimport { evaluateOperation } from './evaluate';\nimport {\n loadObservations,\n writeObservation,\n type ObservationDeps,\n type ObservationPatch,\n} from './observations';\nimport { statusOf, type OperationView } from './views';\nimport { Workers, type RecoveryReport, type WorkerOptions } from './workers';\n\nexport interface WaitOptions {\n /** Default: the handle's `confirmations`. Ignored when `finality: 'final'`. */\n readonly confirmations?: number;\n readonly finality?: 'included' | 'final';\n readonly timeoutMs?: number;\n readonly pollIntervalMs?: number;\n readonly signal?: AbortSignal;\n}\n\nexport interface ConfirmationResult {\n readonly status: TxStatus;\n readonly operation?: OperationView;\n}\n\nexport interface TxStatusEvent {\n readonly status: TxStatus;\n readonly operation?: OperationView;\n}\n\nexport type { RecoveryReport, WorkerOptions } from './workers';\n\n/**\n * Rebuilds the wallet-bound target of a stored Operation (from its `context`); `undefined`\n * (or a rejection) when it cannot be resolved any more, e.g. its wallet config is gone.\n */\nexport type TargetResolver = (\n op: OperationRecord,\n) => Promise<OperationTarget | undefined>;\n\n/** Rebuilds the signer-free read target of a stored Operation; see `TargetResolver`. */\nexport type ReadResolver = (op: OperationRecord) => Promise<ReadTarget | undefined>;\n\nexport interface MonitorDeps {\n readonly engine: OperationEngine;\n readonly stores: Stores;\n readonly events: EventBus;\n readonly clock: Clock;\n readonly log: Logger;\n readonly namespace: string;\n readonly lifecycle: () => ResolvedLifecycle;\n /**\n * Every check, worker pass and recovery read runs on this target (no wallet), so a\n * signer rotated out of config or a hung `getPublicKey` never stalls monitoring.\n */\n readonly resolveRead: ReadResolver;\n /**\n * Resolved lazily, only for the writes that need a wallet-bound target: the\n * all-rejected verdict, nonce reconciliation and recovery's resend (none of them signs).\n * Known gap: for the all-rejected verdict this resolution is bounded neither by the\n * pass `signal` nor by a per-pass cache, so each such Operation of a pass can wait up\n * to `lifecycle.signTimeoutMs` for a wallet whose resolution keeps failing.\n */\n readonly resolveTarget: TargetResolver;\n}\n\ninterface Snapshot {\n readonly status: TxStatus;\n readonly record?: OperationRecord;\n}\n\nconst SETTLED = new Set(['final', 'failed', 'rejected', 'replaced', 'expired']);\nconst UNKNOWN: TxStatus = {\n state: 'unknown',\n evidence: 'observed',\n confirmations: 0,\n finality: 'none',\n};\n\n/** Proven and settled: nothing observed later may overwrite it. */\nfunction isSettled(observation: AttemptObservation | null | undefined): boolean {\n return observation?.evidence === 'proven' && SETTLED.has(observation.state);\n}\n\n/**\n * Watches Attempts on chain and moves their Operation on evidence.\n * Observed data (a single endpoint's view, absence, `dropped`, `refused`, an unfinalized\n * block) only ever produces non-terminal states; a terminal state needs `proven` evidence\n * (finalized data confirmed by quorum proof reads). A stale view decides nothing.\n */\nexport class Monitor {\n /** The worker loop and recovery, over this monitor's checks. */\n readonly #workers: Workers;\n\n constructor(private readonly deps: MonitorDeps) {\n this.#workers = new Workers(deps, {\n checkPass: (target, op, fence, signal) =>\n this.#checkPass(target, op, fence, signal),\n check: (target, op, fence, signal) => this.check(target, op, fence, signal),\n find: (ref) => this.find(ref),\n });\n }\n\n private get observationDeps(): ObservationDeps {\n return {\n operations: this.deps.stores.operations,\n events: this.deps.events,\n namespace: this.deps.namespace,\n };\n }\n\n /** Finds a managed Operation by id, Attempt ref or observed canonical tx hash. */\n async find(ref: string): Promise<OperationRecord | null> {\n const store = this.deps.stores.operations;\n return (\n (await store.get(this.deps.namespace, ref)) ??\n (await store.findByRef(this.deps.namespace, ref))\n );\n }\n\n /**\n * One evaluation pass: observe live Attempts, persist observations, apply the transition.\n * `signal` is checked before every read, so an aborted pass stops after at most the\n * read in flight; it then throws the signal's reason and decides nothing further.\n */\n async check(\n target: ReadTarget,\n op: OperationRecord,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<OperationRecord> {\n return (await this.#checkPass(target, op, fence, signal)).record;\n }\n\n /** `check`, also telling whether the view was stale (it then decided nothing). */\n async #checkPass(\n target: ReadTarget,\n op: OperationRecord,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<{ readonly record: OperationRecord; readonly stale: boolean }> {\n if (isTerminal(op.state) || PRE_SIGNING_STATES.has(op.state))\n return { record: op, stale: false };\n const { pooled } = target;\n signal?.throwIfAborted();\n await pooled.transport.ensureFreshHealth(signal);\n signal?.throwIfAborted();\n const [head, finalized] = await Promise.all([\n pooled.driver.reader.getBlockHeight(),\n pooled.driver.reader.getFinalizedHeight(),\n ]);\n if (isStaleView(pooled.transport, head)) return { record: op, stale: true };\n const observations = new Map<string, AttemptObservation>();\n for (const attempt of op.attempts) {\n try {\n observations.set(\n attempt.id,\n await this.observeAttempt(target, op, attempt, head, finalized, signal),\n );\n } catch (error) {\n if (signal?.aborted || !isCryptoAioError(error) || !error.retryable) throw error;\n const current = await this.deps.stores.operations.getObservation(attempt.id);\n if (current) observations.set(attempt.id, current);\n }\n }\n return {\n record: await this.applyEvaluation(op, observations, fence, signal),\n stale: false,\n };\n }\n\n /** Current status of a managed Operation (after a check) or of an arbitrary transaction id. */\n async status(target: ReadTarget, ref: string, signal?: AbortSignal): Promise<Snapshot> {\n let record = await this.find(ref);\n if (!record) return { status: await this.rawStatus(target, ref) };\n assertSameNetwork(target.selection, record);\n if (!isTerminal(record.state) && !PRE_SIGNING_STATES.has(record.state)) {\n try {\n record = await this.check(target, record, undefined, signal);\n } catch (error) {\n if (signal?.aborted || !isCryptoAioError(error) || !error.retryable) throw error;\n }\n }\n const observations = await loadObservations(this.deps.stores.operations, record);\n return { status: this.bestStatus(record, observations), record };\n }\n\n /**\n * Polls until the wanted status: `confirmations` (default: the handle's) or, with\n * `finality: 'final'`, proven finality for a managed Operation and observed finality for\n * a transaction it does not manage. The caller's `signal` and the deadline bound\n * every pass and sleep; a pass stops after at most the read in flight.\n */\n async waitFor(\n target: ReadTarget,\n ref: string,\n options: WaitOptions = {},\n ): Promise<Snapshot> {\n const { signal } = options;\n if (signal?.aborted) throw signal.reason;\n const lifecycle = this.deps.lifecycle();\n const deadline =\n this.deps.clock.now() + (options.timeoutMs ?? lifecycle.waitTimeoutMs);\n const poll = options.pollIntervalMs ?? lifecycle.pollIntervalMs;\n const wanted = options.confirmations ?? target.selection.confirmations;\n const wantFinal = options.finality === 'final';\n let last: Snapshot | undefined;\n const stopped = (): unknown =>\n signal?.aborted\n ? signal.reason\n : new TimeoutError(\n 'TIMEOUT',\n 'the transaction was not confirmed before the timeout',\n {\n context: last?.record ? { operationId: last.record.id } : {},\n },\n );\n // One signal for every pass and sleep: the caller's abort or the deadline.\n const bound = new AbortController();\n const finished = new AbortController();\n const onAbort = () => bound.abort();\n signal?.addEventListener('abort', onAbort, { once: true });\n this.deps.clock\n .sleep(Math.max(0, deadline - this.deps.clock.now()), finished.signal)\n .then(onAbort, () => undefined);\n try {\n for (;;) {\n if (bound.signal.aborted || this.deps.clock.now() >= deadline) throw stopped();\n let snapshot: Snapshot | undefined;\n try {\n snapshot = await this.status(target, ref, bound.signal);\n } catch (error) {\n if (bound.signal.aborted) throw stopped();\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n }\n if (snapshot) {\n last = snapshot;\n const { status, record } = snapshot;\n if (record?.state === 'final') return snapshot;\n if (record && (record.state === 'failed' || record.state === 'expired')) {\n throw rehydrateError(record.error ?? this.defaultError(record), record.id);\n }\n if (record?.state === 'abandoned') {\n throw new StateError(\n 'INVALID_TRANSITION',\n `operation '${record.id}' was abandoned`,\n );\n }\n if (!record && status.state === 'failed' && status.finality === 'final') {\n throw new ChainError(\n 'TX_REVERTED',\n 'the transaction was included but failed on chain',\n );\n }\n const reached = wantFinal\n ? status.state === 'final' || unmanagedFinal(snapshot)\n : status.state === 'final' ||\n (status.state === 'included' && status.confirmations >= wanted);\n if (reached) return snapshot;\n }\n try {\n await this.deps.clock.sleep(poll, bound.signal);\n } catch {\n throw stopped();\n }\n }\n } finally {\n finished.abort();\n signal?.removeEventListener('abort', onAbort);\n }\n }\n\n /**\n * Yields each status change until the Operation is terminal, or until a transaction\n * it does not manage reaches observed finality, whether it succeeded or reverted. Ends\n * quietly when `signal` aborts.\n */\n async *watch(\n target: ReadTarget,\n ref: string,\n options: { readonly pollIntervalMs?: number; readonly signal?: AbortSignal } = {},\n ): AsyncGenerator<Snapshot> {\n const { signal } = options;\n const poll = options.pollIntervalMs ?? this.deps.lifecycle().pollIntervalMs;\n let last = '';\n while (!signal?.aborted) {\n let snapshot: Snapshot | undefined;\n try {\n snapshot = await this.status(target, ref, signal);\n } catch (error) {\n if (signal?.aborted) return;\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n }\n if (snapshot) {\n const { status, record } = snapshot;\n const key = [\n status.state,\n status.evidence,\n status.confirmations,\n status.blockHash ?? '',\n record?.state ?? '',\n ].join('|');\n if (key !== last) {\n last = key;\n yield snapshot;\n }\n if (record ? isTerminal(record.state) : unmanagedFinal(snapshot)) return;\n }\n try {\n await this.deps.clock.sleep(poll, signal);\n } catch {\n return;\n }\n }\n }\n\n // ---- workers and recovery ------------------------------------------------------------\n\n /** One worker pass (see `Workers.runOnce`); resolves to how many Operations it claimed. */\n runOnce(options: {\n readonly workerId: string;\n readonly batch?: number;\n readonly signal?: AbortSignal;\n }): Promise<number> {\n return this.#workers.runOnce(options);\n }\n\n /** Runs worker passes until `signal` aborts (see `Workers.start`). */\n start(options: WorkerOptions = {}): Promise<void> {\n return this.#workers.start(options);\n }\n\n /** Startup recovery for this namespace; it never signs (see `Workers.recover`). */\n recover(options: { readonly signal?: AbortSignal } = {}): Promise<RecoveryReport> {\n return this.#workers.recover(options);\n }\n\n // ---- observation ---------------------------------------------------------------------\n\n private async observeAttempt(\n target: ReadTarget,\n op: OperationRecord,\n attempt: AttemptRecord,\n head: bigint,\n finalized: bigint,\n signal?: AbortSignal,\n ): Promise<AttemptObservation> {\n const current = await this.deps.stores.operations.getObservation(attempt.id);\n if (current && isSettled(current)) return current;\n const { driver } = target.pooled;\n const from = op.intent.from;\n const now = this.deps.clock.now();\n signal?.throwIfAborted();\n const seen = await driver.reader.observe(attempt.ref, attempt.ordering, from);\n signal?.throwIfAborted();\n let reorgedFrom: string | undefined;\n let patch: ObservationPatch;\n if (seen.seen === 'block' && seen.blockHeight !== undefined) {\n // The transaction is in another block than recorded: its old block was orphaned, once\n // the quorum confirms it; one endpoint's other block alone decides nothing.\n if (\n current?.blockHash !== undefined &&\n seen.blockHash !== undefined &&\n current.blockHash !== seen.blockHash\n ) {\n if (!(await this.orphaned(target, current))) return current;\n signal?.throwIfAborted();\n reorgedFrom = current.blockHash;\n }\n patch = {\n state: seen.success === false ? 'failed' : 'included',\n evidence: 'observed',\n confirmations: depth(head, seen.blockHeight),\n blockHeight: seen.blockHeight,\n blockHash: seen.blockHash,\n ...(seen.txHash !== undefined ? { txHash: seen.txHash } : {}),\n // Why an included transaction failed, as the driver's fixed text; any earlier\n // reason (a refusal, an old failure) is cleared otherwise.\n reason: seen.success === false ? seen.reason : undefined,\n failure: seen.success === false ? (seen.failure ?? 'reverted') : undefined,\n firstSeenAt: current?.firstSeenAt ?? now,\n lastSeenAt: now,\n };\n if (seen.blockHeight <= finalized)\n patch = await this.proveFinal(target, op, attempt, patch, head, signal);\n } else {\n if (current?.blockHash !== undefined) {\n // Absence (or a mempool sighting) of an included transaction is not evidence of a\n // reorg by itself: a lagging or inconsistent endpoint shows the same. Only a\n // quorum-served different block at the recorded height proves it; otherwise decide\n // nothing.\n if (!(await this.orphaned(target, current))) return current;\n signal?.throwIfAborted();\n reorgedFrom = current.blockHash;\n }\n // Out of a block, an earlier failure's reason no longer applies (a refusal keeps\n // its own, below). Clearing relies on `putObservation` replacing the whole record,\n // a key set to `undefined` being absent.\n const cleared: ObservationPatch = {\n blockHash: undefined,\n blockHeight: undefined,\n confirmations: 0,\n reason: undefined,\n failure: undefined,\n };\n patch =\n seen.seen === 'mempool'\n ? {\n ...cleared,\n state: 'mempool',\n evidence: 'observed',\n firstSeenAt: current?.firstSeenAt ?? now,\n lastSeenAt: now,\n }\n : {\n ...cleared,\n ...(await this.whenAbsent(target, op, attempt, current, now, signal)),\n };\n }\n // This patch was derived from `current`; when another writer changed the\n // observation meanwhile (possibly with stronger evidence), keep theirs and decide nothing.\n let applied = false;\n const saved = await writeObservation(\n this.observationDeps,\n attempt,\n op.id,\n (stored) => {\n applied = (stored?.version ?? null) === (current?.version ?? null);\n return applied ? patch : undefined;\n },\n );\n if (!applied) return saved;\n if (reorgedFrom !== undefined) this.#reorged(op, attempt, reorgedFrom);\n if (\n saved.state === 'dropped' &&\n attempt.id === op.activeAttemptId &&\n op.state !== 'stalled'\n ) {\n signal?.throwIfAborted();\n await this.#rebroadcastDropped(target, op, attempt, saved, now, signal);\n }\n return saved;\n }\n\n /**\n * A block at or below the finalized height becomes `final`/`failed` + `proven` only when\n * the quorum proof confirms it. A retryable proof failure (e.g. PROVIDER_INCONSISTENT)\n * decides nothing: the observed patch is kept.\n */\n private async proveFinal(\n target: ReadTarget,\n op: OperationRecord,\n attempt: AttemptRecord,\n patch: ObservationPatch,\n head: bigint,\n signal?: AbortSignal,\n ): Promise<ObservationPatch> {\n let proof: Awaited<ReturnType<ProofSource['includedFinal']>>;\n signal?.throwIfAborted();\n try {\n proof = await target.pooled.driver.proofs.includedFinal(\n attempt.ref,\n attempt.ordering,\n op.intent.from,\n );\n } catch (error) {\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n return patch;\n }\n if (!proof.included) return patch;\n return {\n ...patch,\n state: proof.success ? 'final' : 'failed',\n evidence: 'proven',\n blockHeight: proof.blockHeight,\n blockHash: proof.blockHash,\n txHash: proof.txHash,\n confirmations: depth(head, proof.blockHeight),\n ...failureOf(proof),\n };\n }\n\n /**\n * Whether the block recorded for `observation` is no longer the one at its height.\n * Only the quorum-served hash decides; a disagreement or other retryable failure, or no\n * block at that height yet, decides nothing (`false`).\n */\n private async orphaned(\n target: ReadTarget,\n observation: AttemptObservation,\n ): Promise<boolean> {\n const { blockHeight, blockHash } = observation;\n if (blockHeight === undefined || blockHash === undefined) return false;\n let canonical: string | null;\n try {\n canonical = await target.pooled.driver.proofs.blockHash(blockHeight, 'latest');\n } catch (error) {\n if (!isCryptoAioError(error) || !error.retryable) throw error;\n return false;\n }\n return canonical !== null && canonical !== blockHash;\n }\n\n /** The transaction is not visible anywhere we can see: only finalized proofs may declare it dead. */\n private async whenAbsent(\n target: ReadTarget,\n op: OperationRecord,\n attempt: AttemptRecord,\n current: AttemptObservation | null,\n now: number,\n signal?: AbortSignal,\n ): Promise<ObservationPatch> {\n const { proofs } = target.pooled.driver;\n const read = <T>(work: () => Promise<T>): Promise<T> => {\n signal?.throwIfAborted();\n return work();\n };\n // The built ordering (never the reservation, whose seqno `validUntil`\n // the driver may have replaced while building).\n const ordering = attempt.ordering;\n const from = op.intent.from;\n const slotted =\n ordering.kind === 'nonce' ||\n ordering.kind === 'seqno' ||\n ordering.kind === 'inputs';\n const expiring = ordering.kind === 'expiry' || ordering.kind === 'seqno';\n const deadSlot =\n slotted && (await read(() => proofs.slotConsumed(ordering, from, 'finalized')));\n const deadExpiry =\n !deadSlot && expiring && (await read(() => proofs.expired(ordering)));\n if (deadSlot || deadExpiry) {\n const proof = await read(() => proofs.includedFinal(attempt.ref, ordering, from));\n if (proof.included) {\n return {\n state: proof.success ? 'final' : 'failed',\n evidence: 'proven',\n blockHeight: proof.blockHeight,\n blockHash: proof.blockHash,\n txHash: proof.txHash,\n ...failureOf(proof),\n };\n }\n return { state: deadSlot ? 'replaced' : 'expired', evidence: 'proven' };\n }\n if (slotted && (await read(() => proofs.slotConsumed(ordering, from, 'latest')))) {\n return { state: 'replaced', evidence: 'observed' };\n }\n if (current?.state === 'refused') {\n return {\n state: 'refused',\n evidence: 'observed',\n reason: current.reason,\n failure: undefined,\n };\n }\n const since = current?.lastSeenAt ?? current?.lastBroadcastAt ?? attempt.createdAt;\n const dropped = now - since >= this.deps.lifecycle().droppedGracePeriodMs;\n return { state: dropped ? 'dropped' : 'pending', evidence: 'observed' };\n }\n\n private async applyEvaluation(\n op: OperationRecord,\n observations: ReadonlyMap<string, AttemptObservation>,\n fence?: Fence,\n signal?: AbortSignal,\n ): Promise<OperationRecord> {\n const evaluation = evaluateOperation(op, observations);\n const { winner } = evaluation;\n if (winner) {\n // The winner consumed the ordering slot: every other Attempt is proven replaced by it.\n // As in `whenAbsent`, a proven `replaced` carries no reason: a refusal's no longer\n // applies.\n const linked = (o: AttemptObservation | null | undefined) =>\n isSettled(o) && !(o?.state === 'replaced' && o.replacedBy === undefined);\n for (const attempt of op.attempts) {\n if (attempt.id === winner.id || linked(observations.get(attempt.id))) continue;\n await writeObservation(this.observationDeps, attempt, op.id, (stored) =>\n linked(stored)\n ? undefined\n : {\n state: 'replaced',\n evidence: 'proven',\n replacedBy: winner.ref.id,\n reason: undefined,\n failure: undefined,\n },\n );\n }\n }\n // Failing an all-rejected Operation releases its nonce, so the engine applies it\n // under the address lease; the monitor never makes a reservation-holding transition.\n if (evaluation.error?.code === 'TX_REJECTED')\n return this.failRejected(op, signal, fence);\n const terminal = isTerminal(evaluation.state);\n // A read-only pass (no fence) writes the Operation only when its state, outcome\n // or error changes, never just to schedule it: a version bump would make a concurrent\n // engine write (e.g. right after a broadcast) lose its compare-and-set. Scheduling\n // (`nextCheckAt`) belongs to fenced workers and to engine transitions.\n const changed =\n evaluation.state !== op.state ||\n (evaluation.outcome !== undefined && evaluation.outcome !== op.outcome) ||\n (evaluation.error !== undefined && evaluation.error.code !== op.error?.code);\n if (!changed && !fence) return op;\n const clear: ClearableField[] = [];\n if (terminal) clear.push('nextCheckAt');\n if (op.state === 'stalled' && evaluation.state !== 'stalled' && !evaluation.error)\n clear.push('error');\n const patch: OperationPatch = {\n ...(evaluation.state !== op.state ? { state: evaluation.state } : {}),\n ...(evaluation.outcome ? { outcome: evaluation.outcome } : {}),\n ...(evaluation.error\n ? {\n error: new ChainError(evaluation.error.code, evaluation.error.message, {\n context: { operationId: op.id },\n }).toJSON(),\n }\n : {}),\n ...(fence && !terminal\n ? { nextCheckAt: this.deps.clock.now() + this.deps.lifecycle().pollIntervalMs }\n : {}),\n ...(clear.length > 0 ? { clear } : {}),\n };\n return this.deps.engine.update(op, patch, fence);\n }\n\n /**\n * Hands the all-rejected verdict to the engine: an unfenced pass (`tryOnce`) tries the\n * lease once, a fenced one waits `acquireTimeoutMs`, and either wait is bounded by the\n * pass `signal` (the caller's abort and, in `waitFor`, its deadline). A fenced pass's\n * terminal write carries its claim `fence`, so a worker whose claim was taken over writes\n * nothing. An unresolvable target leaves the Operation non-terminal.\n */\n private async failRejected(\n op: OperationRecord,\n signal: AbortSignal | undefined,\n fence: Fence | undefined,\n ): Promise<OperationRecord> {\n let target: OperationTarget | undefined;\n let failure: unknown;\n try {\n target = await this.deps.resolveTarget(op);\n } catch (error) {\n failure = error;\n }\n if (!target) {\n this.deps.log.warn('cannot resolve the target to fail a rejected operation', {\n operationId: op.id,\n code: errorCode(failure),\n });\n return op;\n }\n // Every unfenced pass (`getTransactionStatus`, `watch`, `waitFor`), signalled or not,\n // tries the lease once: a busy lease leaves the Operation for a later pass. Only a\n // fenced worker pass waits `acquireTimeoutMs`.\n return this.deps.engine.failRejected(target, op, {\n signal,\n ...(fence ? { fence } : { acquireTimeoutMs: 0 }),\n });\n }\n\n private bestStatus(\n record: OperationRecord,\n observations: ReadonlyMap<string, AttemptObservation>,\n ): TxStatus {\n const all = record.attempts\n .map((a) => observations.get(a.id))\n .filter((o): o is AttemptObservation => o !== undefined);\n const chosen =\n all.find(\n (o) => o.state === 'final' || (o.state === 'failed' && o.evidence === 'proven'),\n ) ??\n all\n .filter((o) => o.state === 'included' || o.state === 'failed')\n .sort((a, b) => b.confirmations - a.confirmations)[0] ??\n (record.activeAttemptId ? observations.get(record.activeAttemptId) : undefined);\n return chosen ? statusOf(chosen) : UNKNOWN;\n }\n\n private async rawStatus(target: ReadTarget, id: string): Promise<TxStatus> {\n const { reader } = target.pooled.driver;\n const [observation, head, finalized] = await Promise.all([\n reader.observe({ id, idKind: 'tx-hash', canonical: true }, undefined, undefined),\n reader.getBlockHeight(),\n reader.getFinalizedHeight(),\n ]);\n return statusFromObservation(observation, head, finalized);\n }\n\n private defaultError(record: OperationRecord): SerializedError {\n const code = record.state === 'expired' ? 'TX_EXPIRED' : 'TX_REJECTED';\n return new ChainError(code, `operation ended in state '${record.state}'`).toJSON();\n }\n\n #reorged(op: OperationRecord, attempt: AttemptRecord, previousBlockHash: string): void {\n this.deps.events.emit('tx.reorged', {\n namespace: this.deps.namespace,\n operationId: op.id,\n attemptId: attempt.id,\n previousBlockHash,\n });\n }\n\n /**\n * Resends the stored raw bytes of a dropped active Attempt, at most once per\n * `rebroadcastIntervalMs`. The answer decides nothing: `dropped` is never terminal,\n * and a refusal or rejection of bytes a node once held says nothing about them. An\n * acceptance is remembered (`firstSeenAt`) like the engine's broadcast path does.\n */\n async #rebroadcastDropped(\n target: ReadTarget,\n op: OperationRecord,\n attempt: AttemptRecord,\n observation: AttemptObservation,\n now: number,\n signal?: AbortSignal,\n ): Promise<void> {\n if (\n now - (observation.lastBroadcastAt ?? 0) <\n this.deps.lifecycle().rebroadcastIntervalMs\n )\n return;\n let accepted = false;\n try {\n const result = await target.pooled.driver.broadcaster.broadcast(\n { raw: attempt.raw, ref: attempt.ref },\n signal ? { signal } : {},\n );\n accepted = result.kind === 'accepted' || result.kind === 'already-known';\n } catch (error) {\n // The code only: an error message may carry detail that logs must not.\n this.deps.log.debug('rebroadcast of a dropped attempt failed', {\n operationId: op.id,\n code: errorCode(error),\n });\n }\n await writeObservation(this.observationDeps, attempt, op.id, (stored) => ({\n lastBroadcastAt: now,\n ...(accepted ? { firstSeenAt: stored?.firstSeenAt ?? now } : {}),\n }));\n }\n}\n\n/** Refuses a stored Operation of another chain or network than `selection` (INVALID_INTENT). */\nexport function assertSameNetwork(\n selection: Pick<ResolvedSelection, 'chain' | 'network'>,\n record: OperationRecord,\n): void {\n const { chain, network } = selection;\n if (record.context.chain !== chain.id || record.context.network !== network.id) {\n throw new ValidationError(\n 'INVALID_INTENT',\n `operation '${record.id}' belongs to ${record.context.chain}:${record.context.network}, not ${chain.id}:${network.id}`,\n );\n }\n}\n\n/**\n * An unmanaged transaction has no proofs to wait for: its observed finality is the answer,\n * whether it succeeded or reverted (`waitFor` rejects a reverted one with TX_REVERTED).\n */\nfunction unmanagedFinal({ status, record }: Snapshot): boolean {\n return !record && status.finality === 'final';\n}\n\nfunction depth(head: bigint, height: bigint): number {\n const d = head - height + 1n;\n return d > 0n ? Number(d) : 0;\n}\n\n/**\n * A proven failure's fixed reason and what failed; a success clears both. Drivers give a\n * fixed text because a node's own text can carry addresses or amounts; the stored reason\n * is sensitive data, and no event carries it.\n */\nfunction failureOf(proof: {\n readonly success: boolean;\n readonly reason?: string;\n readonly failure?: TxFailure;\n}): { readonly reason: string | undefined; readonly failure: TxFailure | undefined } {\n return proof.success\n ? { reason: undefined, failure: undefined }\n : { reason: proof.reason, failure: proof.failure ?? 'reverted' };\n}\n"]}
|
|
@@ -41,7 +41,7 @@ export declare function reclaimLeaked(engine: Reconciler, op: OperationRecord, l
|
|
|
41
41
|
/**
|
|
42
42
|
* The lowest value reconciliation may reclaim: `chainPending` (a lagging endpoint can
|
|
43
43
|
* under-report it), raised above every nonce the chain consumed at finality, i.e. those
|
|
44
|
-
* of `final` Operations and of failures proven on chain (`TX_REVERTED`, `TX_REPLACED`).
|
|
44
|
+
* of `final` Operations and of failures proven on chain (`TX_REVERTED`, `TX_UNEVIDENCED`, `TX_REPLACED`).
|
|
45
45
|
* A rejection, a failure before signing or an abandoned Operation consumed nothing.
|
|
46
46
|
*/
|
|
47
47
|
export declare function consumedFloor(engine: Reconciler, wallet: Omit<OperationFilter, 'states' | 'limit'>, chainPending: bigint): Promise<bigint>;
|
|
@@ -69,7 +69,7 @@ async function reclaimLeaked(engine, op, lease, chainPending, preparing) {
|
|
|
69
69
|
/**
|
|
70
70
|
* The lowest value reconciliation may reclaim: `chainPending` (a lagging endpoint can
|
|
71
71
|
* under-report it), raised above every nonce the chain consumed at finality, i.e. those
|
|
72
|
-
* of `final` Operations and of failures proven on chain (`TX_REVERTED`, `TX_REPLACED`).
|
|
72
|
+
* of `final` Operations and of failures proven on chain (`TX_REVERTED`, `TX_UNEVIDENCED`, `TX_REPLACED`).
|
|
73
73
|
* A rejection, a failure before signing or an abandoned Operation consumed nothing.
|
|
74
74
|
*/
|
|
75
75
|
async function consumedFloor(engine, wallet, chainPending) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../../src/core/lifecycle/reconcile.ts"],"names":[],"mappings":"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","sourcesContent":["import { isCryptoAioError } from '../errors/error';\nimport type { LeaseHandle } from '../ordering/sequence';\nimport {\n NON_TERMINAL_STATES,\n type OperationFilter,\n type OperationPatch,\n type OperationRecord,\n} from '../store/types';\nimport type { EngineDeps, OperationTarget, ReadTarget } from './engine';\nimport { CONSUMED_FAILURES, hasReclaimable, heldNonces } from './engine-rules';\n\n/*\n * Nonce reconciliation, as functions over the engine's deps. The\n * engine hands in its deps and the few steps of its own these need (`Reconciler`).\n */\n\n/** What reconciliation needs from `OperationEngine`: its deps and a few of its steps. */\nexport interface Reconciler {\n readonly deps: EngineDeps;\n update(op: OperationRecord, patch: OperationPatch): Promise<OperationRecord>;\n require(operationId: string): Promise<OperationRecord>;\n sequenceKeyOf(op: OperationRecord): string;\n assertOwnedBy(target: OperationTarget, op: OperationRecord): void;\n withAddressLease<T>(\n target: ReadTarget,\n op: OperationRecord,\n fn: (lease: LeaseHandle | undefined) => Promise<T>,\n signal?: AbortSignal,\n options?: { readonly acquireTimeoutMs?: number },\n ): Promise<T>;\n}\n\n/**\n * Nonce reconciliation, never a filler transaction. Under the address lease,\n * returns to `released` every value in [floor, next) that no live Operation of\n * `op`'s wallet reserves, so the next allocation reuses it and the transfers waiting\n * behind the gap can land; `floor` is `consumedFloor` (never below a nonce the chain\n * consumed at finality), and the wallet's history is read only when some value is\n * reclaimable at all. It closes the leaks a release cannot: a crash between\n * allocation and the `prepared` write, a store failure inside a release after a terminal\n * write, and a failure recorded without a release. Every live `created` Operation\n * without a reservation is fenced first (`fenceStalePrepare`), so a `prepared` write\n * still in flight from a lapsed lease can never land on a released value (a legitimate\n * transfer re-reads its Operation under the lease). Returns the reclaimed values. The\n * lease wait is bounded by `signal` and `acquireTimeoutMs` (`0` tries once); a busy lease\n * rejects with SEQUENCE_BUSY. A target whose wallet does not own `op` is refused\n * (INVALID_INTENT): its lease guards another sequence.\n */\nexport async function reconcileNonces(\n engine: Reconciler,\n target: OperationTarget,\n op: OperationRecord,\n options: { readonly signal?: AbortSignal; readonly acquireTimeoutMs?: number } = {},\n): Promise<readonly bigint[]> {\n const { driver } = target.pooled;\n const sequence = driver.sequence;\n if (driver.ordering !== 'nonce' || !sequence) return [];\n engine.assertOwnedBy(target, op);\n const { signal, acquireTimeoutMs } = options;\n return engine.withAddressLease(\n target,\n op,\n async (lease) =>\n reclaimLeaked(\n engine,\n op,\n lease as LeaseHandle,\n await sequence.pending(op.intent.from),\n ),\n signal,\n acquireTimeoutMs === undefined ? undefined : { acquireTimeoutMs },\n );\n}\n\n/**\n * The body of `reconcileNonces`, under the held address lease of `op`'s wallet, with the\n * chain's pending nonce already read. `preparing` is an Operation this lease is preparing\n * right now (`prepareStage`): it is never fenced, since its own write follows.\n */\nexport async function reclaimLeaked(\n engine: Reconciler,\n op: OperationRecord,\n lease: LeaseHandle,\n chainPending: bigint,\n preparing?: string,\n): Promise<readonly bigint[]> {\n const wallet = {\n namespace: engine.deps.namespace,\n chain: op.context.chain,\n network: op.context.network,\n from: op.intent.from,\n };\n const key = engine.sequenceKeyOf(op);\n // Cheap first: with nothing reclaimable, neither the fencing writes nor the wallet's\n // history are needed (fencing only ever adds held values), and with no value at or\n // above `chainPending` ever allocated, not even the live Operations.\n const state = await engine.deps.stores.sequences.get(key);\n if (!state || state.next <= chainPending) return [];\n const live = await engine.deps.stores.operations.list({\n ...wallet,\n states: NON_TERMINAL_STATES,\n });\n if (!hasReclaimable(state, chainPending, live.flatMap(heldNonces))) return [];\n const held: bigint[] = [];\n for (const record of live) {\n const current =\n record.id === preparing ? record : await fenceStalePrepare(engine, record);\n held.push(...heldNonces(current));\n }\n const floor = await consumedFloor(engine, wallet, chainPending);\n await lease.renew();\n return engine.deps.sequences.reclaim(lease, key, floor, held);\n}\n\n/**\n * The lowest value reconciliation may reclaim: `chainPending` (a lagging endpoint can\n * under-report it), raised above every nonce the chain consumed at finality, i.e. those\n * of `final` Operations and of failures proven on chain (`TX_REVERTED`, `TX_REPLACED`).\n * A rejection, a failure before signing or an abandoned Operation consumed nothing.\n */\nexport async function consumedFloor(\n engine: Reconciler,\n wallet: Omit<OperationFilter, 'states' | 'limit'>,\n chainPending: bigint,\n): Promise<bigint> {\n let floor = chainPending;\n const history = await engine.deps.stores.operations.list({\n ...wallet,\n states: ['final', 'failed'],\n });\n for (const record of history) {\n if (record.state === 'failed' && !CONSUMED_FAILURES.has(record.error?.code ?? ''))\n continue;\n for (const nonce of heldNonces(record)) if (nonce >= floor) floor = nonce + 1n;\n }\n return floor;\n}\n\n/**\n * A `created` Operation without a reservation may still have a `prepared` write in\n * flight from a process whose lease lapsed (it allocated a nonce, renewed, then stalled).\n * A no-effect compare-and-set at the listed version makes that stale write lose its own\n * compare-and-set, so it can never land a reservation on a value this reconciliation\n * releases. This relies on the store bumping `version` on every `update`, a no-op one\n * included (the store contract pins it). After a lost compare-and-set the re-read\n * Operation is returned, and any reservation it now shows counts as held. Other\n * Operations are returned as listed.\n */\nexport async function fenceStalePrepare(\n engine: Reconciler,\n record: OperationRecord,\n): Promise<OperationRecord> {\n if (record.state !== 'created' || record.reservation !== undefined) return record;\n try {\n return await engine.update(record, { clear: ['error'] });\n } catch (error) {\n if (!isCryptoAioError(error, 'VERSION_CONFLICT')) throw error;\n return engine.require(record.id);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../../src/core/lifecycle/reconcile.ts"],"names":[],"mappings":"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","sourcesContent":["import { isCryptoAioError } from '../errors/error';\nimport type { LeaseHandle } from '../ordering/sequence';\nimport {\n NON_TERMINAL_STATES,\n type OperationFilter,\n type OperationPatch,\n type OperationRecord,\n} from '../store/types';\nimport type { EngineDeps, OperationTarget, ReadTarget } from './engine';\nimport { CONSUMED_FAILURES, hasReclaimable, heldNonces } from './engine-rules';\n\n/*\n * Nonce reconciliation, as functions over the engine's deps. The\n * engine hands in its deps and the few steps of its own these need (`Reconciler`).\n */\n\n/** What reconciliation needs from `OperationEngine`: its deps and a few of its steps. */\nexport interface Reconciler {\n readonly deps: EngineDeps;\n update(op: OperationRecord, patch: OperationPatch): Promise<OperationRecord>;\n require(operationId: string): Promise<OperationRecord>;\n sequenceKeyOf(op: OperationRecord): string;\n assertOwnedBy(target: OperationTarget, op: OperationRecord): void;\n withAddressLease<T>(\n target: ReadTarget,\n op: OperationRecord,\n fn: (lease: LeaseHandle | undefined) => Promise<T>,\n signal?: AbortSignal,\n options?: { readonly acquireTimeoutMs?: number },\n ): Promise<T>;\n}\n\n/**\n * Nonce reconciliation, never a filler transaction. Under the address lease,\n * returns to `released` every value in [floor, next) that no live Operation of\n * `op`'s wallet reserves, so the next allocation reuses it and the transfers waiting\n * behind the gap can land; `floor` is `consumedFloor` (never below a nonce the chain\n * consumed at finality), and the wallet's history is read only when some value is\n * reclaimable at all. It closes the leaks a release cannot: a crash between\n * allocation and the `prepared` write, a store failure inside a release after a terminal\n * write, and a failure recorded without a release. Every live `created` Operation\n * without a reservation is fenced first (`fenceStalePrepare`), so a `prepared` write\n * still in flight from a lapsed lease can never land on a released value (a legitimate\n * transfer re-reads its Operation under the lease). Returns the reclaimed values. The\n * lease wait is bounded by `signal` and `acquireTimeoutMs` (`0` tries once); a busy lease\n * rejects with SEQUENCE_BUSY. A target whose wallet does not own `op` is refused\n * (INVALID_INTENT): its lease guards another sequence.\n */\nexport async function reconcileNonces(\n engine: Reconciler,\n target: OperationTarget,\n op: OperationRecord,\n options: { readonly signal?: AbortSignal; readonly acquireTimeoutMs?: number } = {},\n): Promise<readonly bigint[]> {\n const { driver } = target.pooled;\n const sequence = driver.sequence;\n if (driver.ordering !== 'nonce' || !sequence) return [];\n engine.assertOwnedBy(target, op);\n const { signal, acquireTimeoutMs } = options;\n return engine.withAddressLease(\n target,\n op,\n async (lease) =>\n reclaimLeaked(\n engine,\n op,\n lease as LeaseHandle,\n await sequence.pending(op.intent.from),\n ),\n signal,\n acquireTimeoutMs === undefined ? undefined : { acquireTimeoutMs },\n );\n}\n\n/**\n * The body of `reconcileNonces`, under the held address lease of `op`'s wallet, with the\n * chain's pending nonce already read. `preparing` is an Operation this lease is preparing\n * right now (`prepareStage`): it is never fenced, since its own write follows.\n */\nexport async function reclaimLeaked(\n engine: Reconciler,\n op: OperationRecord,\n lease: LeaseHandle,\n chainPending: bigint,\n preparing?: string,\n): Promise<readonly bigint[]> {\n const wallet = {\n namespace: engine.deps.namespace,\n chain: op.context.chain,\n network: op.context.network,\n from: op.intent.from,\n };\n const key = engine.sequenceKeyOf(op);\n // Cheap first: with nothing reclaimable, neither the fencing writes nor the wallet's\n // history are needed (fencing only ever adds held values), and with no value at or\n // above `chainPending` ever allocated, not even the live Operations.\n const state = await engine.deps.stores.sequences.get(key);\n if (!state || state.next <= chainPending) return [];\n const live = await engine.deps.stores.operations.list({\n ...wallet,\n states: NON_TERMINAL_STATES,\n });\n if (!hasReclaimable(state, chainPending, live.flatMap(heldNonces))) return [];\n const held: bigint[] = [];\n for (const record of live) {\n const current =\n record.id === preparing ? record : await fenceStalePrepare(engine, record);\n held.push(...heldNonces(current));\n }\n const floor = await consumedFloor(engine, wallet, chainPending);\n await lease.renew();\n return engine.deps.sequences.reclaim(lease, key, floor, held);\n}\n\n/**\n * The lowest value reconciliation may reclaim: `chainPending` (a lagging endpoint can\n * under-report it), raised above every nonce the chain consumed at finality, i.e. those\n * of `final` Operations and of failures proven on chain (`TX_REVERTED`, `TX_UNEVIDENCED`, `TX_REPLACED`).\n * A rejection, a failure before signing or an abandoned Operation consumed nothing.\n */\nexport async function consumedFloor(\n engine: Reconciler,\n wallet: Omit<OperationFilter, 'states' | 'limit'>,\n chainPending: bigint,\n): Promise<bigint> {\n let floor = chainPending;\n const history = await engine.deps.stores.operations.list({\n ...wallet,\n states: ['final', 'failed'],\n });\n for (const record of history) {\n if (record.state === 'failed' && !CONSUMED_FAILURES.has(record.error?.code ?? ''))\n continue;\n for (const nonce of heldNonces(record)) if (nonce >= floor) floor = nonce + 1n;\n }\n return floor;\n}\n\n/**\n * A `created` Operation without a reservation may still have a `prepared` write in\n * flight from a process whose lease lapsed (it allocated a nonce, renewed, then stalled).\n * A no-effect compare-and-set at the listed version makes that stale write lose its own\n * compare-and-set, so it can never land a reservation on a value this reconciliation\n * releases. This relies on the store bumping `version` on every `update`, a no-op one\n * included (the store contract pins it). After a lost compare-and-set the re-read\n * Operation is returned, and any reservation it now shows counts as held. Other\n * Operations are returned as listed.\n */\nexport async function fenceStalePrepare(\n engine: Reconciler,\n record: OperationRecord,\n): Promise<OperationRecord> {\n if (record.state !== 'created' || record.reservation !== undefined) return record;\n try {\n return await engine.update(record, { clear: ['error'] });\n } catch (error) {\n if (!isCryptoAioError(error, 'VERSION_CONFLICT')) throw error;\n return engine.require(record.id);\n }\n}\n"]}
|
|
@@ -16,6 +16,12 @@ export interface RecoveryReport {
|
|
|
16
16
|
readonly checked: number;
|
|
17
17
|
/** Operations that need a caller (see `recovery.skipped`); never resent or checked. */
|
|
18
18
|
readonly skipped: number;
|
|
19
|
+
/**
|
|
20
|
+
* `signed` or ambiguously `submitted` Operations whose wallet no longer resolves (its
|
|
21
|
+
* configuration or signer was removed): checked on chain, but their stored bytes were not
|
|
22
|
+
* sent again. Restore the wallet and recover again to resend them.
|
|
23
|
+
*/
|
|
24
|
+
readonly unresent: number;
|
|
19
25
|
/** Operations whose target could not be rebuilt, or whose resend or check threw. */
|
|
20
26
|
readonly failed: number;
|
|
21
27
|
/** Leaked nonce values that reconciliation returned for reuse (across all wallets). */
|
|
@@ -72,9 +78,9 @@ export declare class Workers {
|
|
|
72
78
|
* a caller and are reported through `recovery.skipped` (codes and states only). Then each
|
|
73
79
|
* wallet with a live Operation has its nonces reconciled under its address lease. A
|
|
74
80
|
* failure is logged by code and counted, and the rest go on. `signal` stops recovery
|
|
75
|
-
* between Operations and bounds each check and lease wait.
|
|
76
|
-
*
|
|
77
|
-
*
|
|
81
|
+
* between Operations and bounds each check and lease wait. A `signed` or ambiguous
|
|
82
|
+
* Operation whose wallet no longer resolves is still checked, since the check needs no
|
|
83
|
+
* wallet, and counted `unresent`: only its resend needs the wallet.
|
|
78
84
|
*/
|
|
79
85
|
recover(options?: {
|
|
80
86
|
readonly signal?: AbortSignal;
|
|
@@ -114,9 +114,9 @@ class Workers {
|
|
|
114
114
|
* a caller and are reported through `recovery.skipped` (codes and states only). Then each
|
|
115
115
|
* wallet with a live Operation has its nonces reconciled under its address lease. A
|
|
116
116
|
* failure is logged by code and counted, and the rest go on. `signal` stops recovery
|
|
117
|
-
* between Operations and bounds each check and lease wait.
|
|
118
|
-
*
|
|
119
|
-
*
|
|
117
|
+
* between Operations and bounds each check and lease wait. A `signed` or ambiguous
|
|
118
|
+
* Operation whose wallet no longer resolves is still checked, since the check needs no
|
|
119
|
+
* wallet, and counted `unresent`: only its resend needs the wallet.
|
|
120
120
|
*/
|
|
121
121
|
async recover(options = {}) {
|
|
122
122
|
const { signal } = options;
|
|
@@ -130,6 +130,7 @@ class Workers {
|
|
|
130
130
|
let rebroadcast = 0;
|
|
131
131
|
let checked = 0;
|
|
132
132
|
let skipped = 0;
|
|
133
|
+
let unresent = 0;
|
|
133
134
|
let failed = 0;
|
|
134
135
|
let reconciled = 0;
|
|
135
136
|
const skip = (op, reason) => {
|
|
@@ -157,18 +158,30 @@ class Workers {
|
|
|
157
158
|
let current = op;
|
|
158
159
|
if (op.state === 'signed' ||
|
|
159
160
|
(op.state === 'submitted' && op.ambiguous === true)) {
|
|
160
|
-
const writer = await this.#resolved(writes, op)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
// A refusal or an unknown outcome is recorded on the Operation: check it next.
|
|
166
|
-
if (!(0, error_1.isCryptoAioError)(error) ||
|
|
167
|
-
(error.category !== 'chain' && error.ambiguous !== true))
|
|
161
|
+
const writer = await this.#resolved(writes, op).catch((error) => {
|
|
162
|
+
// A wallet whose configuration or signer is gone rules out the resend only.
|
|
163
|
+
if (!walletUnresolved(error))
|
|
168
164
|
throw error;
|
|
169
|
-
|
|
165
|
+
unresent += 1;
|
|
166
|
+
this.deps.log.warn('recovery checks an operation it cannot resend', {
|
|
167
|
+
operationId: op.id,
|
|
168
|
+
code: (0, engine_rules_1.errorCode)(error),
|
|
169
|
+
});
|
|
170
|
+
return undefined;
|
|
171
|
+
});
|
|
172
|
+
if (writer) {
|
|
173
|
+
try {
|
|
174
|
+
current = await this.deps.engine.rebroadcast(writer, op.id, signal);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
// A refusal or an unknown outcome is recorded on the Operation: check it next.
|
|
178
|
+
if (!(0, error_1.isCryptoAioError)(error) ||
|
|
179
|
+
(error.category !== 'chain' && error.ambiguous !== true))
|
|
180
|
+
throw error;
|
|
181
|
+
current = (await this.monitor.find(op.id)) ?? op;
|
|
182
|
+
}
|
|
183
|
+
rebroadcast += 1;
|
|
170
184
|
}
|
|
171
|
-
rebroadcast += 1;
|
|
172
185
|
}
|
|
173
186
|
await this.monitor.check(target, current, undefined, signal);
|
|
174
187
|
checked += 1;
|
|
@@ -202,7 +215,7 @@ class Workers {
|
|
|
202
215
|
});
|
|
203
216
|
}
|
|
204
217
|
}
|
|
205
|
-
return { rebroadcast, checked, skipped, failed, reconciled };
|
|
218
|
+
return { rebroadcast, checked, skipped, unresent, failed, reconciled };
|
|
206
219
|
}
|
|
207
220
|
/**
|
|
208
221
|
* `resolve` for one pass: each execution context's target is rebuilt at most once, and
|
|
@@ -326,4 +339,9 @@ class Workers {
|
|
|
326
339
|
}
|
|
327
340
|
}
|
|
328
341
|
exports.Workers = Workers;
|
|
342
|
+
/** A wallet that cannot be resolved for writes: its configuration or its signer is gone. */
|
|
343
|
+
function walletUnresolved(error) {
|
|
344
|
+
return ((0, error_1.isCryptoAioError)(error) &&
|
|
345
|
+
(error.category === 'config' || error.category === 'signing'));
|
|
346
|
+
}
|
|
329
347
|
//# sourceMappingURL=workers.js.map
|