@parmanasystems/core 1.71.20 → 1.71.24
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 +112 -35
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -10498,9 +10498,7 @@ import {
|
|
|
10498
10498
|
getRuntimeManifest,
|
|
10499
10499
|
evaluatePolicy,
|
|
10500
10500
|
loadPolicy,
|
|
10501
|
-
canonicalizeForSigning
|
|
10502
|
-
validateSignalsStrict,
|
|
10503
|
-
violate
|
|
10501
|
+
canonicalizeForSigning
|
|
10504
10502
|
} from "@parmanasystems/execution";
|
|
10505
10503
|
import crypto from "crypto";
|
|
10506
10504
|
import {
|
|
@@ -10509,17 +10507,13 @@ import {
|
|
|
10509
10507
|
import {
|
|
10510
10508
|
evaluatePolicy as evaluatePolicy2,
|
|
10511
10509
|
loadPolicy as loadPolicy2,
|
|
10512
|
-
validateSignalsStrict
|
|
10510
|
+
validateSignalsStrict
|
|
10513
10511
|
} from "@parmanasystems/execution";
|
|
10514
10512
|
async function executeFromSignals(input, signer, verifier, replayStore) {
|
|
10515
10513
|
const policy = loadPolicy(
|
|
10516
10514
|
input.policyId,
|
|
10517
10515
|
input.policyVersion
|
|
10518
10516
|
);
|
|
10519
|
-
validateSignalsStrict(
|
|
10520
|
-
input.signals,
|
|
10521
|
-
policy
|
|
10522
|
-
);
|
|
10523
10517
|
const decision = evaluatePolicy(
|
|
10524
10518
|
policy,
|
|
10525
10519
|
input.signals
|
|
@@ -10536,20 +10530,23 @@ async function executeFromSignals(input, signer, verifier, replayStore) {
|
|
|
10536
10530
|
signals: input.signals
|
|
10537
10531
|
})
|
|
10538
10532
|
).digest("hex");
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10533
|
+
if (replayStore.reserve) {
|
|
10534
|
+
await replayStore.reserve(
|
|
10535
|
+
execution_fingerprint
|
|
10536
|
+
);
|
|
10537
|
+
} else {
|
|
10538
|
+
const alreadyExecuted = await replayStore.hasExecuted(
|
|
10539
|
+
execution_fingerprint
|
|
10540
|
+
);
|
|
10541
|
+
if (alreadyExecuted) {
|
|
10542
|
+
throw new Error(
|
|
10543
|
+
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
10544
|
+
);
|
|
10545
|
+
}
|
|
10546
|
+
await replayStore.markExecuted(
|
|
10547
10547
|
execution_fingerprint
|
|
10548
10548
|
);
|
|
10549
10549
|
}
|
|
10550
|
-
await replayStore.markExecuted(
|
|
10551
|
-
execution_fingerprint
|
|
10552
|
-
);
|
|
10553
10550
|
const runtimeManifest = getRuntimeManifest();
|
|
10554
10551
|
const token = issueToken({
|
|
10555
10552
|
executionId: execution_fingerprint,
|
|
@@ -10565,7 +10562,7 @@ async function executeFromSignals(input, signer, verifier, replayStore) {
|
|
|
10565
10562
|
token
|
|
10566
10563
|
)
|
|
10567
10564
|
);
|
|
10568
|
-
|
|
10565
|
+
const attestation = await executeDecision({
|
|
10569
10566
|
token,
|
|
10570
10567
|
execution_fingerprint,
|
|
10571
10568
|
token_signature,
|
|
@@ -10579,16 +10576,34 @@ async function executeFromSignals(input, signer, verifier, replayStore) {
|
|
|
10579
10576
|
supported_schemaVersions: runtimeManifest.supported_schemaVersions
|
|
10580
10577
|
}
|
|
10581
10578
|
});
|
|
10579
|
+
if (replayStore.confirm) {
|
|
10580
|
+
try {
|
|
10581
|
+
await replayStore.confirm(
|
|
10582
|
+
execution_fingerprint
|
|
10583
|
+
);
|
|
10584
|
+
} catch (err) {
|
|
10585
|
+
console.warn(
|
|
10586
|
+
"[PARMANA WARNING] Failed to confirm execution fingerprint after successful execution:",
|
|
10587
|
+
err
|
|
10588
|
+
);
|
|
10589
|
+
}
|
|
10590
|
+
}
|
|
10591
|
+
return attestation;
|
|
10582
10592
|
}
|
|
10583
10593
|
var RedisReplayStore = class {
|
|
10584
10594
|
constructor(url) {
|
|
10585
10595
|
this.client = new import_ioredis.default(url);
|
|
10586
10596
|
}
|
|
10587
10597
|
async hasExecuted(execution_fingerprint) {
|
|
10588
|
-
const
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10598
|
+
const [confirmed, pending] = await Promise.all([
|
|
10599
|
+
this.client.exists(
|
|
10600
|
+
`exec:${execution_fingerprint}`
|
|
10601
|
+
),
|
|
10602
|
+
this.client.exists(
|
|
10603
|
+
`exec:pending:${execution_fingerprint}`
|
|
10604
|
+
)
|
|
10605
|
+
]);
|
|
10606
|
+
return confirmed === 1 || pending === 1;
|
|
10592
10607
|
}
|
|
10593
10608
|
async markExecuted(execution_fingerprint) {
|
|
10594
10609
|
const result = await this.client.set(
|
|
@@ -10602,6 +10617,35 @@ var RedisReplayStore = class {
|
|
|
10602
10617
|
);
|
|
10603
10618
|
}
|
|
10604
10619
|
}
|
|
10620
|
+
async reserve(execution_fingerprint) {
|
|
10621
|
+
const alreadyConfirmed = await this.client.exists(
|
|
10622
|
+
`exec:${execution_fingerprint}`
|
|
10623
|
+
);
|
|
10624
|
+
if (alreadyConfirmed === 1) {
|
|
10625
|
+
throw new Error(
|
|
10626
|
+
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
10627
|
+
);
|
|
10628
|
+
}
|
|
10629
|
+
const result = await this.client.set(
|
|
10630
|
+
`exec:pending:${execution_fingerprint}`,
|
|
10631
|
+
"1",
|
|
10632
|
+
"NX"
|
|
10633
|
+
);
|
|
10634
|
+
if (result !== "OK") {
|
|
10635
|
+
throw new Error(
|
|
10636
|
+
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
10637
|
+
);
|
|
10638
|
+
}
|
|
10639
|
+
}
|
|
10640
|
+
async confirm(execution_fingerprint) {
|
|
10641
|
+
await this.client.set(
|
|
10642
|
+
`exec:${execution_fingerprint}`,
|
|
10643
|
+
"1"
|
|
10644
|
+
);
|
|
10645
|
+
await this.client.del(
|
|
10646
|
+
`exec:pending:${execution_fingerprint}`
|
|
10647
|
+
);
|
|
10648
|
+
}
|
|
10605
10649
|
async get(key) {
|
|
10606
10650
|
return this.client.get(key);
|
|
10607
10651
|
}
|
|
@@ -10618,27 +10662,60 @@ var RedisReplayStore = class {
|
|
|
10618
10662
|
await this.client.quit();
|
|
10619
10663
|
}
|
|
10620
10664
|
};
|
|
10665
|
+
var DEFAULT_MAX_SIZE = 1e6;
|
|
10621
10666
|
var MemoryReplayStore = class {
|
|
10622
|
-
constructor() {
|
|
10623
|
-
this.
|
|
10667
|
+
constructor(options = {}) {
|
|
10668
|
+
this.reserved = /* @__PURE__ */ new Set();
|
|
10669
|
+
this.confirmed = /* @__PURE__ */ new Set();
|
|
10670
|
+
const {
|
|
10671
|
+
warnInProduction = true,
|
|
10672
|
+
maxSize = DEFAULT_MAX_SIZE
|
|
10673
|
+
} = options;
|
|
10674
|
+
this.maxSize = maxSize;
|
|
10675
|
+
if (warnInProduction && process.env["NODE_ENV"] === "production") {
|
|
10676
|
+
console.warn(
|
|
10677
|
+
"[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."
|
|
10678
|
+
);
|
|
10679
|
+
}
|
|
10624
10680
|
}
|
|
10625
|
-
async
|
|
10626
|
-
if (this.
|
|
10627
|
-
execution_fingerprint
|
|
10628
|
-
)) {
|
|
10681
|
+
async reserve(execution_fingerprint) {
|
|
10682
|
+
if (this.reserved.has(execution_fingerprint) || this.confirmed.has(execution_fingerprint)) {
|
|
10629
10683
|
throw new Error(
|
|
10630
10684
|
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
10631
10685
|
);
|
|
10632
10686
|
}
|
|
10633
|
-
this.
|
|
10687
|
+
this.checkMaxSize();
|
|
10688
|
+
this.reserved.add(
|
|
10634
10689
|
execution_fingerprint
|
|
10635
10690
|
);
|
|
10636
10691
|
}
|
|
10637
|
-
async
|
|
10638
|
-
|
|
10692
|
+
async confirm(execution_fingerprint) {
|
|
10693
|
+
this.reserved.delete(
|
|
10694
|
+
execution_fingerprint
|
|
10695
|
+
);
|
|
10696
|
+
this.confirmed.add(
|
|
10697
|
+
execution_fingerprint
|
|
10698
|
+
);
|
|
10699
|
+
}
|
|
10700
|
+
async markExecuted(execution_fingerprint) {
|
|
10701
|
+
await this.reserve(
|
|
10702
|
+
execution_fingerprint
|
|
10703
|
+
);
|
|
10704
|
+
await this.confirm(
|
|
10639
10705
|
execution_fingerprint
|
|
10640
10706
|
);
|
|
10641
10707
|
}
|
|
10708
|
+
async hasExecuted(execution_fingerprint) {
|
|
10709
|
+
return this.reserved.has(execution_fingerprint) || this.confirmed.has(execution_fingerprint);
|
|
10710
|
+
}
|
|
10711
|
+
checkMaxSize() {
|
|
10712
|
+
const total = this.reserved.size + this.confirmed.size;
|
|
10713
|
+
if (total >= this.maxSize) {
|
|
10714
|
+
throw new Error(
|
|
10715
|
+
`MemoryReplayStore has reached maximum size of ${this.maxSize} entries. Switch to RedisReplayStore for production use.`
|
|
10716
|
+
);
|
|
10717
|
+
}
|
|
10718
|
+
}
|
|
10642
10719
|
};
|
|
10643
10720
|
|
|
10644
10721
|
// src/index.ts
|
|
@@ -10652,7 +10729,7 @@ import {
|
|
|
10652
10729
|
import {
|
|
10653
10730
|
INVARIANT_REGISTRY,
|
|
10654
10731
|
InvariantViolation,
|
|
10655
|
-
violate
|
|
10732
|
+
violate,
|
|
10656
10733
|
hashInput
|
|
10657
10734
|
} from "@parmanasystems/execution";
|
|
10658
10735
|
|
|
@@ -10889,6 +10966,6 @@ export {
|
|
|
10889
10966
|
verifyRuntime,
|
|
10890
10967
|
verifyRuntimeCompatibility,
|
|
10891
10968
|
verifyRuntimeManifest,
|
|
10892
|
-
|
|
10969
|
+
violate
|
|
10893
10970
|
};
|
|
10894
10971
|
//# sourceMappingURL=index.js.map
|