@parmanasystems/core 1.71.22 → 1.71.26
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/dist/index.js +111 -29
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -10499,8 +10499,7 @@ import {
|
|
|
10499
10499
|
evaluatePolicy,
|
|
10500
10500
|
loadPolicy,
|
|
10501
10501
|
canonicalizeForSigning,
|
|
10502
|
-
validateSignalsStrict
|
|
10503
|
-
violate
|
|
10502
|
+
validateSignalsStrict
|
|
10504
10503
|
} from "@parmanasystems/execution";
|
|
10505
10504
|
import crypto from "crypto";
|
|
10506
10505
|
import {
|
|
@@ -10536,20 +10535,23 @@ async function executeFromSignals(input, signer, verifier, replayStore) {
|
|
|
10536
10535
|
signals: input.signals
|
|
10537
10536
|
})
|
|
10538
10537
|
).digest("hex");
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10538
|
+
if (replayStore.reserve) {
|
|
10539
|
+
await replayStore.reserve(
|
|
10540
|
+
execution_fingerprint
|
|
10541
|
+
);
|
|
10542
|
+
} else {
|
|
10543
|
+
const alreadyExecuted = await replayStore.hasExecuted(
|
|
10544
|
+
execution_fingerprint
|
|
10545
|
+
);
|
|
10546
|
+
if (alreadyExecuted) {
|
|
10547
|
+
throw new Error(
|
|
10548
|
+
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
10549
|
+
);
|
|
10550
|
+
}
|
|
10551
|
+
await replayStore.markExecuted(
|
|
10547
10552
|
execution_fingerprint
|
|
10548
10553
|
);
|
|
10549
10554
|
}
|
|
10550
|
-
await replayStore.markExecuted(
|
|
10551
|
-
execution_fingerprint
|
|
10552
|
-
);
|
|
10553
10555
|
const runtimeManifest = getRuntimeManifest();
|
|
10554
10556
|
const token = issueToken({
|
|
10555
10557
|
executionId: execution_fingerprint,
|
|
@@ -10565,7 +10567,7 @@ async function executeFromSignals(input, signer, verifier, replayStore) {
|
|
|
10565
10567
|
token
|
|
10566
10568
|
)
|
|
10567
10569
|
);
|
|
10568
|
-
|
|
10570
|
+
const attestation = await executeDecision({
|
|
10569
10571
|
token,
|
|
10570
10572
|
execution_fingerprint,
|
|
10571
10573
|
token_signature,
|
|
@@ -10579,16 +10581,34 @@ async function executeFromSignals(input, signer, verifier, replayStore) {
|
|
|
10579
10581
|
supported_schemaVersions: runtimeManifest.supported_schemaVersions
|
|
10580
10582
|
}
|
|
10581
10583
|
});
|
|
10584
|
+
if (replayStore.confirm) {
|
|
10585
|
+
try {
|
|
10586
|
+
await replayStore.confirm(
|
|
10587
|
+
execution_fingerprint
|
|
10588
|
+
);
|
|
10589
|
+
} catch (err) {
|
|
10590
|
+
console.warn(
|
|
10591
|
+
"[PARMANA WARNING] Failed to confirm execution fingerprint after successful execution:",
|
|
10592
|
+
err
|
|
10593
|
+
);
|
|
10594
|
+
}
|
|
10595
|
+
}
|
|
10596
|
+
return attestation;
|
|
10582
10597
|
}
|
|
10583
10598
|
var RedisReplayStore = class {
|
|
10584
10599
|
constructor(url) {
|
|
10585
10600
|
this.client = new import_ioredis.default(url);
|
|
10586
10601
|
}
|
|
10587
10602
|
async hasExecuted(execution_fingerprint) {
|
|
10588
|
-
const
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10603
|
+
const [confirmed, pending] = await Promise.all([
|
|
10604
|
+
this.client.exists(
|
|
10605
|
+
`exec:${execution_fingerprint}`
|
|
10606
|
+
),
|
|
10607
|
+
this.client.exists(
|
|
10608
|
+
`exec:pending:${execution_fingerprint}`
|
|
10609
|
+
)
|
|
10610
|
+
]);
|
|
10611
|
+
return confirmed === 1 || pending === 1;
|
|
10592
10612
|
}
|
|
10593
10613
|
async markExecuted(execution_fingerprint) {
|
|
10594
10614
|
const result = await this.client.set(
|
|
@@ -10602,6 +10622,35 @@ var RedisReplayStore = class {
|
|
|
10602
10622
|
);
|
|
10603
10623
|
}
|
|
10604
10624
|
}
|
|
10625
|
+
async reserve(execution_fingerprint) {
|
|
10626
|
+
const alreadyConfirmed = await this.client.exists(
|
|
10627
|
+
`exec:${execution_fingerprint}`
|
|
10628
|
+
);
|
|
10629
|
+
if (alreadyConfirmed === 1) {
|
|
10630
|
+
throw new Error(
|
|
10631
|
+
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
10632
|
+
);
|
|
10633
|
+
}
|
|
10634
|
+
const result = await this.client.set(
|
|
10635
|
+
`exec:pending:${execution_fingerprint}`,
|
|
10636
|
+
"1",
|
|
10637
|
+
"NX"
|
|
10638
|
+
);
|
|
10639
|
+
if (result !== "OK") {
|
|
10640
|
+
throw new Error(
|
|
10641
|
+
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
10642
|
+
);
|
|
10643
|
+
}
|
|
10644
|
+
}
|
|
10645
|
+
async confirm(execution_fingerprint) {
|
|
10646
|
+
await this.client.set(
|
|
10647
|
+
`exec:${execution_fingerprint}`,
|
|
10648
|
+
"1"
|
|
10649
|
+
);
|
|
10650
|
+
await this.client.del(
|
|
10651
|
+
`exec:pending:${execution_fingerprint}`
|
|
10652
|
+
);
|
|
10653
|
+
}
|
|
10605
10654
|
async get(key) {
|
|
10606
10655
|
return this.client.get(key);
|
|
10607
10656
|
}
|
|
@@ -10618,27 +10667,60 @@ var RedisReplayStore = class {
|
|
|
10618
10667
|
await this.client.quit();
|
|
10619
10668
|
}
|
|
10620
10669
|
};
|
|
10670
|
+
var DEFAULT_MAX_SIZE = 1e6;
|
|
10621
10671
|
var MemoryReplayStore = class {
|
|
10622
|
-
constructor() {
|
|
10623
|
-
this.
|
|
10672
|
+
constructor(options = {}) {
|
|
10673
|
+
this.reserved = /* @__PURE__ */ new Set();
|
|
10674
|
+
this.confirmed = /* @__PURE__ */ new Set();
|
|
10675
|
+
const {
|
|
10676
|
+
warnInProduction = true,
|
|
10677
|
+
maxSize = DEFAULT_MAX_SIZE
|
|
10678
|
+
} = options;
|
|
10679
|
+
this.maxSize = maxSize;
|
|
10680
|
+
if (warnInProduction && process.env["NODE_ENV"] === "production") {
|
|
10681
|
+
console.warn(
|
|
10682
|
+
"[PARMANA WARNING] MemoryReplayStore is not suitable for production. It loses all replay protection on process restart and does not work across multiple processes. Use RedisReplayStore in production."
|
|
10683
|
+
);
|
|
10684
|
+
}
|
|
10624
10685
|
}
|
|
10625
|
-
async
|
|
10626
|
-
if (this.
|
|
10627
|
-
execution_fingerprint
|
|
10628
|
-
)) {
|
|
10686
|
+
async reserve(execution_fingerprint) {
|
|
10687
|
+
if (this.reserved.has(execution_fingerprint) || this.confirmed.has(execution_fingerprint)) {
|
|
10629
10688
|
throw new Error(
|
|
10630
10689
|
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
10631
10690
|
);
|
|
10632
10691
|
}
|
|
10633
|
-
this.
|
|
10692
|
+
this.checkMaxSize();
|
|
10693
|
+
this.reserved.add(
|
|
10634
10694
|
execution_fingerprint
|
|
10635
10695
|
);
|
|
10636
10696
|
}
|
|
10637
|
-
async
|
|
10638
|
-
|
|
10697
|
+
async confirm(execution_fingerprint) {
|
|
10698
|
+
this.reserved.delete(
|
|
10699
|
+
execution_fingerprint
|
|
10700
|
+
);
|
|
10701
|
+
this.confirmed.add(
|
|
10702
|
+
execution_fingerprint
|
|
10703
|
+
);
|
|
10704
|
+
}
|
|
10705
|
+
async markExecuted(execution_fingerprint) {
|
|
10706
|
+
await this.reserve(
|
|
10707
|
+
execution_fingerprint
|
|
10708
|
+
);
|
|
10709
|
+
await this.confirm(
|
|
10639
10710
|
execution_fingerprint
|
|
10640
10711
|
);
|
|
10641
10712
|
}
|
|
10713
|
+
async hasExecuted(execution_fingerprint) {
|
|
10714
|
+
return this.reserved.has(execution_fingerprint) || this.confirmed.has(execution_fingerprint);
|
|
10715
|
+
}
|
|
10716
|
+
checkMaxSize() {
|
|
10717
|
+
const total = this.reserved.size + this.confirmed.size;
|
|
10718
|
+
if (total >= this.maxSize) {
|
|
10719
|
+
throw new Error(
|
|
10720
|
+
`MemoryReplayStore has reached maximum size of ${this.maxSize} entries. Switch to RedisReplayStore for production use.`
|
|
10721
|
+
);
|
|
10722
|
+
}
|
|
10723
|
+
}
|
|
10642
10724
|
};
|
|
10643
10725
|
|
|
10644
10726
|
// src/index.ts
|
|
@@ -10652,7 +10734,7 @@ import {
|
|
|
10652
10734
|
import {
|
|
10653
10735
|
INVARIANT_REGISTRY,
|
|
10654
10736
|
InvariantViolation,
|
|
10655
|
-
violate
|
|
10737
|
+
violate,
|
|
10656
10738
|
hashInput
|
|
10657
10739
|
} from "@parmanasystems/execution";
|
|
10658
10740
|
|
|
@@ -10889,6 +10971,6 @@ export {
|
|
|
10889
10971
|
verifyRuntime,
|
|
10890
10972
|
verifyRuntimeCompatibility,
|
|
10891
10973
|
verifyRuntimeManifest,
|
|
10892
|
-
|
|
10974
|
+
violate
|
|
10893
10975
|
};
|
|
10894
10976
|
//# sourceMappingURL=index.js.map
|