@xyo-network/xl1-protocol-sdk 1.26.23 → 1.26.25
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/neutral/CreatableProvider/AbstractCreatableProvider.d.ts +2 -0
- package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts.map +1 -1
- package/dist/neutral/config/Actor.d.ts +12 -0
- package/dist/neutral/config/Actor.d.ts.map +1 -1
- package/dist/neutral/config/Actors.d.ts +2 -0
- package/dist/neutral/config/Actors.d.ts.map +1 -1
- package/dist/neutral/config/Base.d.ts +2 -0
- package/dist/neutral/config/Base.d.ts.map +1 -1
- package/dist/neutral/config/Config.d.ts +8 -0
- package/dist/neutral/config/Config.d.ts.map +1 -1
- package/dist/neutral/config/HostActor.d.ts +12 -0
- package/dist/neutral/config/HostActor.d.ts.map +1 -1
- package/dist/neutral/config/Validation.d.ts +2 -0
- package/dist/neutral/config/Validation.d.ts.map +1 -1
- package/dist/neutral/context/Actor.d.ts +12 -0
- package/dist/neutral/context/Actor.d.ts.map +1 -1
- package/dist/neutral/context/HostActor.d.ts +12 -0
- package/dist/neutral/context/HostActor.d.ts.map +1 -1
- package/dist/neutral/getFileConfig.d.ts +4 -0
- package/dist/neutral/getFileConfig.d.ts.map +1 -1
- package/dist/neutral/getFileConfig.mjs +19 -1
- package/dist/neutral/getFileConfig.mjs.map +1 -1
- package/dist/neutral/index.mjs +1980 -1929
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/neutral/isInternetAvailable.d.ts.map +1 -1
- package/dist/neutral/model/CreatableProviderContext.zod.d.ts +12 -0
- package/dist/neutral/model/CreatableProviderContext.zod.d.ts.map +1 -1
- package/dist/neutral/primitives/uncle/findBestUncle.d.ts +15 -34
- package/dist/neutral/primitives/uncle/findBestUncle.d.ts.map +1 -1
- package/dist/neutral/primitives/uncle/getProducerKey.d.ts +4 -0
- package/dist/neutral/primitives/uncle/getProducerKey.d.ts.map +1 -0
- package/dist/neutral/primitives/uncle/index.d.ts +1 -0
- package/dist/neutral/primitives/uncle/index.d.ts.map +1 -1
- package/dist/neutral/primitives/uncle/scoreUncle.d.ts +3 -1
- package/dist/neutral/primitives/uncle/scoreUncle.d.ts.map +1 -1
- package/dist/neutral/test/index.mjs +427 -411
- package/dist/neutral/test/index.mjs.map +1 -1
- package/package.json +8 -12
|
@@ -634,130 +634,210 @@ var TelemetryConfigZod = z14.object({
|
|
|
634
634
|
// src/config/Validation.ts
|
|
635
635
|
import { AddressZod as AddressZod2, asAddress } from "@xylabs/sdk-js";
|
|
636
636
|
import { globalRegistry as globalRegistry11, z as z15 } from "zod";
|
|
637
|
-
var ValidationConfigZod = z15.object({
|
|
638
|
-
allowedRewardRedeemers: z15.preprocess((val) => {
|
|
639
|
-
if (typeof val === "string") {
|
|
640
|
-
return val.split(",").map((s) => asAddress(s.trim()));
|
|
641
|
-
}
|
|
642
|
-
return val;
|
|
643
|
-
}, z15.array(AddressZod2).optional().register(globalRegistry11, {
|
|
644
|
-
description: "List of allowed reward redeemer addresses, if undefined anyone can participate",
|
|
645
|
-
title: "allowedRewardRedeemers",
|
|
646
|
-
type: "array"
|
|
647
|
-
})),
|
|
648
|
-
allowedRewardEscrowAccountSigners: z15.preprocess((val) => {
|
|
649
|
-
if (typeof val === "string") {
|
|
650
|
-
return val.split(",").map((s) => asAddress(s.trim()));
|
|
651
|
-
}
|
|
652
|
-
return val;
|
|
653
|
-
}, z15.array(AddressZod2).optional().register(globalRegistry11, {
|
|
654
|
-
description: "List of allowed reward escrow account signer addresses, if undefined anyone can participate",
|
|
655
|
-
title: "allowedRewardEscrowAccountSigners",
|
|
656
|
-
type: "array"
|
|
657
|
-
}))
|
|
658
|
-
});
|
|
659
637
|
|
|
660
|
-
// src/
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
dataLake: DataLakeConfigZod.optional().describe("Configuration for data lakes"),
|
|
664
|
-
evm: EvmConfigZod.default(EvmConfigZod.parse({})).describe("Configuration for EVM-backed services"),
|
|
665
|
-
log: LogConfigZod.default(LogConfigZod.parse({})).describe("Configuration for logging"),
|
|
666
|
-
providers: ProvidersConfigZod.default(ProvidersConfigZod.parse([])).describe("Configuration for providers"),
|
|
667
|
-
remote: RemoteConfigZod.default(RemoteConfigZod.parse({})).describe("Configuration for remote services"),
|
|
668
|
-
storage: StorageConfigZod.default(StorageConfigZod.parse({})).describe("Configuration for the storage"),
|
|
669
|
-
telemetry: TelemetryConfigZod.default(TelemetryConfigZod.parse({})).describe("Configuration for telemetry"),
|
|
670
|
-
validation: ValidationConfigZod.default(ValidationConfigZod.parse({})).describe("Configuration for validation")
|
|
671
|
-
});
|
|
638
|
+
// src/primitives/block/rate/blockRate.ts
|
|
639
|
+
import { isDefined as isDefined3, isFalsy } from "@xylabs/sdk-js";
|
|
640
|
+
import { asXL1BlockRange } from "@xyo-network/xl1-protocol-lib";
|
|
672
641
|
|
|
673
|
-
// src/
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
642
|
+
// src/primitives/block/rate/timeHelpers.ts
|
|
643
|
+
import { assertEx as assertEx4, isDefined as isDefined2 } from "@xylabs/sdk-js";
|
|
644
|
+
var rateMultipliers = {
|
|
645
|
+
millis: 1,
|
|
646
|
+
seconds: 1e3,
|
|
647
|
+
minutes: 1e3 * 60,
|
|
648
|
+
hours: 1e3 * 60 * 60,
|
|
649
|
+
days: 1e3 * 60 * 60 * 24,
|
|
650
|
+
weeks: 1e3 * 60 * 60 * 24 * 7
|
|
651
|
+
};
|
|
652
|
+
var timeDurations = (timeInMs) => ({
|
|
653
|
+
millis: timeInMs,
|
|
654
|
+
seconds: timeInMs / 1e3,
|
|
655
|
+
minutes: timeInMs / (1e3 * 60),
|
|
656
|
+
hours: timeInMs / (1e3 * 60 * 60),
|
|
657
|
+
days: timeInMs / (1e3 * 60 * 60 * 24),
|
|
658
|
+
weeks: timeInMs / (1e3 * 60 * 60 * 24 * 7)
|
|
686
659
|
});
|
|
687
|
-
var
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
660
|
+
var getTimeConfigInMilliseconds = (timeConfig) => {
|
|
661
|
+
const assertedTimeConfig = assertEx4(isDefined2(timeConfig) ? timeConfig : void 0, () => "Time configuration must be provided");
|
|
662
|
+
let totalMilliseconds = 0;
|
|
663
|
+
if ("years" in assertedTimeConfig) {
|
|
664
|
+
totalMilliseconds += assertedTimeConfig.years * 31536e6;
|
|
665
|
+
return totalMilliseconds;
|
|
666
|
+
}
|
|
667
|
+
if ("months" in assertedTimeConfig) {
|
|
668
|
+
totalMilliseconds += assertedTimeConfig.months * 2592e6;
|
|
669
|
+
return totalMilliseconds;
|
|
670
|
+
}
|
|
671
|
+
if ("weeks" in assertedTimeConfig) {
|
|
672
|
+
totalMilliseconds += assertedTimeConfig.weeks * 6048e5;
|
|
673
|
+
return totalMilliseconds;
|
|
674
|
+
}
|
|
675
|
+
if ("days" in assertedTimeConfig) {
|
|
676
|
+
totalMilliseconds += assertedTimeConfig.days * 864e5;
|
|
677
|
+
return totalMilliseconds;
|
|
678
|
+
}
|
|
679
|
+
if ("hours" in assertedTimeConfig) {
|
|
680
|
+
totalMilliseconds += assertedTimeConfig.hours * 36e5;
|
|
681
|
+
return totalMilliseconds;
|
|
682
|
+
}
|
|
683
|
+
if ("minutes" in assertedTimeConfig) {
|
|
684
|
+
totalMilliseconds += assertedTimeConfig.minutes * 6e4;
|
|
685
|
+
return totalMilliseconds;
|
|
686
|
+
}
|
|
687
|
+
return totalMilliseconds;
|
|
709
688
|
};
|
|
710
689
|
|
|
711
|
-
// src/block/
|
|
712
|
-
var
|
|
690
|
+
// src/primitives/block/rate/blockRate.ts
|
|
691
|
+
var blockRate = (startBlock, endBlock, timeUnit) => {
|
|
692
|
+
const startingBlock = startBlock[0];
|
|
693
|
+
const endingBlock = endBlock[0];
|
|
694
|
+
const heightDifference = endingBlock.block - startingBlock.block;
|
|
695
|
+
const timeDifference = endingBlock.$epoch - startingBlock.$epoch;
|
|
696
|
+
if (timeDifference === 0) {
|
|
697
|
+
throw new Error("Time difference must be greater than 0");
|
|
698
|
+
}
|
|
699
|
+
const rate = heightDifference / timeDifference;
|
|
700
|
+
const timeUnitValue = isDefined3(timeUnit) ? timeUnit : "millis";
|
|
701
|
+
const returnedTimeDifference = isDefined3(timeUnit) ? timeDurations(timeDifference)[timeUnit] : timeDifference;
|
|
702
|
+
const timePerBlock = returnedTimeDifference / heightDifference;
|
|
703
|
+
return {
|
|
704
|
+
range: asXL1BlockRange([startingBlock.block, endingBlock.block], true),
|
|
705
|
+
span: heightDifference,
|
|
706
|
+
rate: isDefined3(timeUnit) ? rate * rateMultipliers[timeUnit] : rate,
|
|
707
|
+
timeUnit: timeUnitValue,
|
|
708
|
+
timeDifference: returnedTimeDifference,
|
|
709
|
+
timePerBlock
|
|
710
|
+
};
|
|
711
|
+
};
|
|
712
|
+
var getBlockRateBlocks = async (viewer, startBlockHeight, endBlockHeight) => {
|
|
713
|
+
if (endBlockHeight <= startBlockHeight) {
|
|
714
|
+
console.error("startBlockHeight", startBlockHeight);
|
|
715
|
+
console.error("endBlockHeight", endBlockHeight);
|
|
716
|
+
throw new Error("End block height must be greater than start block height");
|
|
717
|
+
}
|
|
718
|
+
const startingBlock = await viewer.blockByNumber(startBlockHeight);
|
|
719
|
+
const endingBlock = await viewer.blockByNumber(endBlockHeight);
|
|
720
|
+
if (isFalsy(startingBlock) || isFalsy(endingBlock)) {
|
|
721
|
+
throw new Error("Could not retrieve blocks for speed calculation");
|
|
722
|
+
}
|
|
723
|
+
return { startingBlock, endingBlock };
|
|
724
|
+
};
|
|
725
|
+
var calculateBlockRate = async (viewer, range, timeUnit) => {
|
|
726
|
+
const [startBlockHeight, endBlockHeight] = range;
|
|
727
|
+
const { startingBlock, endingBlock } = await getBlockRateBlocks(
|
|
728
|
+
viewer,
|
|
729
|
+
startBlockHeight,
|
|
730
|
+
endBlockHeight
|
|
731
|
+
);
|
|
732
|
+
return blockRate(startingBlock, endingBlock, timeUnit);
|
|
733
|
+
};
|
|
713
734
|
|
|
714
|
-
// src/block/
|
|
715
|
-
import { assertEx as
|
|
716
|
-
import {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
const
|
|
723
|
-
const
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
if (maxDepth === 1) return [bw, blkPayloads];
|
|
731
|
-
const transactions = blkPayloads.filter(isTransactionBoundWitnessWithStorageMeta);
|
|
732
|
-
const transactionsPayloadHashes = transactions.flatMap((tx) => tx.payload_hashes);
|
|
733
|
-
const transactionsPayloads = (await chainMap.get(transactionsPayloadHashes)).map((p) => asAnyPayload(p, true));
|
|
734
|
-
assertEx4(allHashesPresent(transactionsPayloadHashes, transactionsPayloads), () => `Unable to find all payloads for transactions in block ${hash}`);
|
|
735
|
-
const allPayloadsHashes = new Set([...blkPayloads, ...transactionsPayloads].flatMap((p) => p._hash));
|
|
736
|
-
const allPayloads = (await chainMap.get([...allPayloadsHashes])).map((p) => asAnyPayload(p, true));
|
|
737
|
-
const allPayloadsFiltered = allPayloads.filter((p) => allPayloadsHashes.has(p._hash));
|
|
738
|
-
if (maxDepth === 2) assertEx4(allHashesPresent(
|
|
739
|
-
[...allPayloadsHashes],
|
|
740
|
-
allPayloadsFiltered
|
|
741
|
-
), () => `Unable to find all payloads for transactions in block ${hash}`);
|
|
742
|
-
return [bw, allPayloadsFiltered];
|
|
735
|
+
// src/primitives/block/rate/stepRate.ts
|
|
736
|
+
import { assertEx as assertEx5 } from "@xylabs/sdk-js";
|
|
737
|
+
import {
|
|
738
|
+
asXL1BlockRange as asXL1BlockRange2,
|
|
739
|
+
isValidStep,
|
|
740
|
+
StepSizes
|
|
741
|
+
} from "@xyo-network/xl1-protocol-lib";
|
|
742
|
+
var stepRate = async (viewer, start, step, count = 1, timeUnit) => {
|
|
743
|
+
const end = start + step * count;
|
|
744
|
+
const range = asXL1BlockRange2([start, end], true);
|
|
745
|
+
return await calculateBlockRate(viewer, range, timeUnit);
|
|
746
|
+
};
|
|
747
|
+
var calculateStepSizeRate = async (viewer, start, stepIndex, count = 1, timeUnit) => {
|
|
748
|
+
assertEx5(isValidStep(stepIndex), () => `Invalid step index: ${stepIndex}`);
|
|
749
|
+
const step = StepSizes[stepIndex];
|
|
750
|
+
return await stepRate(viewer, start, step, count, timeUnit);
|
|
743
751
|
};
|
|
744
752
|
|
|
745
|
-
// src/block/
|
|
753
|
+
// src/primitives/block/rate/timeRate.ts
|
|
746
754
|
import {
|
|
747
|
-
|
|
755
|
+
assertEx as assertEx6,
|
|
748
756
|
isDefined as isDefined4,
|
|
749
|
-
|
|
757
|
+
isDefinedNotNull
|
|
750
758
|
} from "@xylabs/sdk-js";
|
|
751
|
-
import {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
759
|
+
import { asXL1BlockNumber, asXL1BlockRange as asXL1BlockRange3 } from "@xyo-network/xl1-protocol-lib";
|
|
760
|
+
var DEFAULT_TOLERANCE_MS = 3e4;
|
|
761
|
+
var DEFAULT_MAX_ATTEMPTS = 10;
|
|
762
|
+
var calculateTimeRate = async (viewer, timeConfig, startBlockNumber, timeUnit, toleranceMs = DEFAULT_TOLERANCE_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS) => {
|
|
763
|
+
assertEx6(Object.keys(timeConfig ?? {}).length === 1, () => "Only one time unit should be specified in timeConfig");
|
|
764
|
+
const startBlock = isDefinedNotNull(startBlockNumber) ? await viewer.blockByNumber(startBlockNumber) : null;
|
|
765
|
+
const resolvedStartBlock = isDefinedNotNull(startBlock) ? startBlock[0] : (await viewer.currentBlock())[0];
|
|
766
|
+
const timeInMilliseconds = getTimeConfigInMilliseconds(timeConfig);
|
|
767
|
+
assertEx6(timeInMilliseconds > 0, () => "Time duration must be greater than zero");
|
|
768
|
+
const blocksPerMillisecondRate = 1 / (12 * 1e3);
|
|
769
|
+
const initialBlocksInDuration = Math.floor(blocksPerMillisecondRate * timeInMilliseconds);
|
|
770
|
+
const endBlockNumber = await findEndBlockRecursive(
|
|
771
|
+
viewer,
|
|
772
|
+
resolvedStartBlock,
|
|
773
|
+
timeInMilliseconds,
|
|
774
|
+
initialBlocksInDuration,
|
|
775
|
+
toleranceMs,
|
|
776
|
+
maxAttempts
|
|
777
|
+
);
|
|
778
|
+
return await calculateBlockRate(
|
|
779
|
+
viewer,
|
|
780
|
+
asXL1BlockRange3([endBlockNumber, resolvedStartBlock.block], true),
|
|
781
|
+
timeUnit
|
|
782
|
+
);
|
|
783
|
+
};
|
|
784
|
+
var findEndBlockRecursive = async (viewer, startBlock, targetTimeMs, estimatedBlocksBack, toleranceMs, attemptsRemaining) => {
|
|
785
|
+
console.log(`Attempts remaining: ${attemptsRemaining}, Estimated blocks back: ${estimatedBlocksBack}`);
|
|
786
|
+
assertEx6(attemptsRemaining >= 0, () => "Maximum attempts reached while searching for end block");
|
|
787
|
+
const startBlockEpoch = startBlock.$epoch;
|
|
788
|
+
const estimatedEndBlockNumber = asXL1BlockNumber(startBlock.block - estimatedBlocksBack, true);
|
|
789
|
+
if (estimatedEndBlockNumber < 0) {
|
|
790
|
+
throw new Error("Estimated end block number is less than zero");
|
|
791
|
+
}
|
|
792
|
+
const endBlock = await viewer.blockByNumber(estimatedEndBlockNumber);
|
|
793
|
+
const resolvedEndBlock = assertEx6(
|
|
794
|
+
isDefined4(endBlock?.[0]) ? endBlock[0] : void 0,
|
|
795
|
+
() => `Could not retrieve block ${estimatedEndBlockNumber} for time rate calculation`
|
|
796
|
+
);
|
|
797
|
+
const endBlockEpoch = resolvedEndBlock.$epoch;
|
|
798
|
+
if (!Number.isFinite(startBlockEpoch) || !Number.isFinite(endBlockEpoch)) {
|
|
799
|
+
throw new TypeError("Block has missing or invalid $epoch");
|
|
800
|
+
}
|
|
801
|
+
const actualTimeDifference = startBlockEpoch - endBlockEpoch;
|
|
802
|
+
if (actualTimeDifference === 0) {
|
|
803
|
+
throw new Error("Start and end blocks have identical timestamps");
|
|
804
|
+
}
|
|
805
|
+
const timeDelta = Math.abs(actualTimeDifference - targetTimeMs);
|
|
806
|
+
if (timeDelta <= toleranceMs) {
|
|
807
|
+
return resolvedEndBlock.block;
|
|
808
|
+
}
|
|
809
|
+
let adjustedBlocksBack;
|
|
810
|
+
if (actualTimeDifference < targetTimeMs) {
|
|
811
|
+
const adjustmentFactor = targetTimeMs / actualTimeDifference;
|
|
812
|
+
adjustedBlocksBack = Math.floor(estimatedBlocksBack * adjustmentFactor);
|
|
813
|
+
} else {
|
|
814
|
+
const adjustmentFactor = actualTimeDifference / targetTimeMs;
|
|
815
|
+
adjustedBlocksBack = Math.floor(estimatedBlocksBack / adjustmentFactor);
|
|
816
|
+
}
|
|
817
|
+
adjustedBlocksBack = Number.isFinite(adjustedBlocksBack) && adjustedBlocksBack >= 1 ? adjustedBlocksBack : 1;
|
|
818
|
+
return await findEndBlockRecursive(
|
|
819
|
+
viewer,
|
|
820
|
+
startBlock,
|
|
821
|
+
targetTimeMs,
|
|
822
|
+
adjustedBlocksBack,
|
|
823
|
+
toleranceMs,
|
|
824
|
+
attemptsRemaining - 1
|
|
825
|
+
);
|
|
826
|
+
};
|
|
827
|
+
|
|
828
|
+
// src/primitives/step/completedStepRewardAddress.ts
|
|
829
|
+
import { toAddress } from "@xylabs/sdk-js";
|
|
830
|
+
import { StepSizes as StepSizes2 } from "@xyo-network/xl1-protocol-lib";
|
|
831
|
+
import { keccak256 } from "ethers";
|
|
832
|
+
function completedStepRewardAddress({ block, step }) {
|
|
833
|
+
const resolvedStepSize = step < StepSizes2.length ? StepSizes2[step] : step;
|
|
834
|
+
const addressKey = new TextEncoder().encode(`${block}|${resolvedStepSize}`);
|
|
835
|
+
return toAddress(keccak256(addressKey).slice(-40), { prefix: false });
|
|
836
|
+
}
|
|
757
837
|
|
|
758
838
|
// src/ChainContextHelpers.ts
|
|
759
839
|
import {
|
|
760
|
-
isDefined as
|
|
840
|
+
isDefined as isDefined6,
|
|
761
841
|
isObject,
|
|
762
842
|
isUndefined as isUndefined2,
|
|
763
843
|
timeBudget
|
|
@@ -803,7 +883,7 @@ var LruCacheMap = class {
|
|
|
803
883
|
};
|
|
804
884
|
|
|
805
885
|
// src/driver/memory/MemoryMap.ts
|
|
806
|
-
import { isDefined as
|
|
886
|
+
import { isDefined as isDefined5 } from "@xylabs/sdk-js";
|
|
807
887
|
var MemoryMap = class {
|
|
808
888
|
map;
|
|
809
889
|
constructor() {
|
|
@@ -822,7 +902,7 @@ var MemoryMap = class {
|
|
|
822
902
|
const results = [];
|
|
823
903
|
for (const id of ids) {
|
|
824
904
|
const data = this.map.get(id);
|
|
825
|
-
if (
|
|
905
|
+
if (isDefined5(data)) {
|
|
826
906
|
results.push(data);
|
|
827
907
|
}
|
|
828
908
|
}
|
|
@@ -859,7 +939,7 @@ async function withContextCacheResponse(context, name, key, func, { max = 1e4 }
|
|
|
859
939
|
);
|
|
860
940
|
const { timeBudgetLimit = 0 } = context;
|
|
861
941
|
const cacheResult = await cache.get(key);
|
|
862
|
-
if (
|
|
942
|
+
if (isDefined6(cacheResult)) {
|
|
863
943
|
return cacheResult;
|
|
864
944
|
}
|
|
865
945
|
const result = timeBudgetLimit > 0 ? timeBudget(name, context.logger, func, timeBudgetLimit) : func();
|
|
@@ -867,317 +947,160 @@ async function withContextCacheResponse(context, name, key, func, { max = 1e4 }
|
|
|
867
947
|
return result;
|
|
868
948
|
}
|
|
869
949
|
|
|
870
|
-
// src/block/
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
const { chainMap, head } = context;
|
|
875
|
-
return await withContextCacheResponse(context, "blockFromBlockNumber", cacheKey, async () => {
|
|
876
|
-
const [result] = await chainMap.get([head._hash]);
|
|
877
|
-
if (!isDefined4(result)) {
|
|
878
|
-
throw new Error(`Head block not found for hash: ${head._hash}`);
|
|
879
|
-
}
|
|
880
|
-
let currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
|
|
881
|
-
result,
|
|
882
|
-
() => `Found Payload is not a Signed<BlockBoundWitness>: ${JSON.stringify(result, null, 2)}`
|
|
883
|
-
);
|
|
884
|
-
if (currentBlock.block < blockNumber) {
|
|
885
|
-
throw new Error(`Block number ${blockNumber} is greater than head ${currentBlock.block}.`);
|
|
886
|
-
}
|
|
887
|
-
while (currentBlock.block > blockNumber) {
|
|
888
|
-
let jumpHash = currentBlock.previous;
|
|
889
|
-
let jumpBlockNumber = currentBlock.block - 1;
|
|
890
|
-
for (const [step, stepSize] of StepSizes.entries()) {
|
|
891
|
-
const possibleJumpBlockNumber = currentBlock.block - currentBlock.block % stepSize - 1;
|
|
892
|
-
if (possibleJumpBlockNumber >= blockNumber && possibleJumpBlockNumber <= jumpBlockNumber) {
|
|
893
|
-
jumpBlockNumber = possibleJumpBlockNumber;
|
|
894
|
-
jumpHash = asHash(currentBlock.step_hashes?.at(step), () => `Step hash not found for step ${step} in block ${currentBlock.block}`);
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
const [newBlock] = await chainMap.get([
|
|
898
|
-
asHash(jumpHash, () => `Jump hash not found for block number [${blockNumber}]: ${jumpBlockNumber} ${toSafeJsonString(currentBlock, 10)}`)
|
|
899
|
-
]);
|
|
900
|
-
if (!isDefined4(newBlock)) {
|
|
901
|
-
throw new Error(`Block not found for jump hash: ${jumpHash}`);
|
|
902
|
-
}
|
|
903
|
-
currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
|
|
904
|
-
newBlock,
|
|
905
|
-
() => {
|
|
906
|
-
const result2 = SignedBlockBoundWitnessWithHashMetaZod.safeParse(newBlock);
|
|
907
|
-
return `Found Payload [jump hash] is not a Signed<BlockBoundWitness>: ${result2.error}`;
|
|
908
|
-
}
|
|
909
|
-
);
|
|
910
|
-
if (currentBlock.block === blockNumber) {
|
|
911
|
-
break;
|
|
912
|
-
}
|
|
913
|
-
if (currentBlock.block < blockNumber) {
|
|
914
|
-
throw new Error(`Block number ${blockNumber} is not a valid step block number for block ${head._hash}.`);
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
return currentBlock;
|
|
918
|
-
});
|
|
919
|
-
}, { ...context, timeBudgetLimit: 500 });
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
// src/block/primitives/validateTransactionOpcodes.ts
|
|
923
|
-
import {
|
|
924
|
-
assertEx as assertEx5,
|
|
925
|
-
isHash,
|
|
926
|
-
toSafeJsonString as toSafeJsonString2
|
|
927
|
-
} from "@xylabs/sdk-js";
|
|
928
|
-
import {
|
|
929
|
-
PayloadBuilder
|
|
930
|
-
} from "@xyo-network/sdk-js";
|
|
931
|
-
import { isExecutable } from "@xyo-network/xl1-protocol-lib";
|
|
932
|
-
async function validateTransactionsOpcodes(txs) {
|
|
933
|
-
const txElevatedPayloads = [];
|
|
934
|
-
for (const [txBw, txPayloads] of txs) {
|
|
935
|
-
if (isExecutable(txBw)) {
|
|
936
|
-
const operations = txBw.script.map((op) => op.split("|"));
|
|
937
|
-
for (const [opCode, ...args] of operations) {
|
|
938
|
-
switch (opCode) {
|
|
939
|
-
case "elevate": {
|
|
940
|
-
const [hash, ...rest] = args;
|
|
941
|
-
const txPayloadsWithStorageMeta = await PayloadBuilder.addStorageMeta(txPayloads);
|
|
942
|
-
assertEx5(rest.length === 0, () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Too many Arguments`);
|
|
943
|
-
if (isHash(hash)) {
|
|
944
|
-
assertEx5(
|
|
945
|
-
txBw.payload_hashes.includes(hash),
|
|
946
|
-
() => `Invalid elevate operation ${opCode} ${args.join(", ")} - Hash not in payload hashes => ${toSafeJsonString2(txBw, 20)}`
|
|
947
|
-
);
|
|
948
|
-
const txPayload = assertEx5(
|
|
949
|
-
txPayloadsWithStorageMeta.find((p) => p._hash === hash),
|
|
950
|
-
() => `Invalid elevate operation ${opCode} ${args.join(", ")} - Payload not found`
|
|
951
|
-
);
|
|
952
|
-
txElevatedPayloads.push(txPayload);
|
|
953
|
-
} else {
|
|
954
|
-
throw new Error(`Invalid elevate operation ${opCode} ${args.join(", ")} - Invalid hash`);
|
|
955
|
-
}
|
|
956
|
-
break;
|
|
957
|
-
}
|
|
958
|
-
default: {
|
|
959
|
-
throw new Error(`Invalid opCode ${opCode}`);
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
return txElevatedPayloads;
|
|
950
|
+
// src/block/hydrate/allHashesPresent.ts
|
|
951
|
+
function allHashesPresent(hashes, payloads) {
|
|
952
|
+
const payloadHashes = new Set(payloads.map((p) => p._hash));
|
|
953
|
+
return hashes.every((hash) => payloadHashes.has(hash));
|
|
966
954
|
}
|
|
967
955
|
|
|
968
|
-
// src/
|
|
969
|
-
import {
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
} from "@xylabs/sdk-js";
|
|
974
|
-
import {
|
|
975
|
-
asSignedHydratedBlockWithHashMeta,
|
|
976
|
-
asSignedHydratedBlockWithStorageMeta,
|
|
977
|
-
asXL1BlockNumber as asXL1BlockNumber2,
|
|
978
|
-
BlockViewerMoniker,
|
|
979
|
-
DataLakeViewerMoniker,
|
|
980
|
-
FinalizationViewerMoniker
|
|
981
|
-
} from "@xyo-network/xl1-protocol-lib";
|
|
982
|
-
|
|
983
|
-
// src/primitives/block/rate/blockRate.ts
|
|
984
|
-
import { isDefined as isDefined6, isFalsy } from "@xylabs/sdk-js";
|
|
985
|
-
import { asXL1BlockRange } from "@xyo-network/xl1-protocol-lib";
|
|
986
|
-
|
|
987
|
-
// src/primitives/block/rate/timeHelpers.ts
|
|
988
|
-
import { assertEx as assertEx6, isDefined as isDefined5 } from "@xylabs/sdk-js";
|
|
989
|
-
var rateMultipliers = {
|
|
990
|
-
millis: 1,
|
|
991
|
-
seconds: 1e3,
|
|
992
|
-
minutes: 1e3 * 60,
|
|
993
|
-
hours: 1e3 * 60 * 60,
|
|
994
|
-
days: 1e3 * 60 * 60 * 24,
|
|
995
|
-
weeks: 1e3 * 60 * 60 * 24 * 7
|
|
996
|
-
};
|
|
997
|
-
var timeDurations = (timeInMs) => ({
|
|
998
|
-
millis: timeInMs,
|
|
999
|
-
seconds: timeInMs / 1e3,
|
|
1000
|
-
minutes: timeInMs / (1e3 * 60),
|
|
1001
|
-
hours: timeInMs / (1e3 * 60 * 60),
|
|
1002
|
-
days: timeInMs / (1e3 * 60 * 60 * 24),
|
|
1003
|
-
weeks: timeInMs / (1e3 * 60 * 60 * 24 * 7)
|
|
1004
|
-
});
|
|
1005
|
-
var getTimeConfigInMilliseconds = (timeConfig) => {
|
|
1006
|
-
const assertedTimeConfig = assertEx6(isDefined5(timeConfig) ? timeConfig : void 0, () => "Time configuration must be provided");
|
|
1007
|
-
let totalMilliseconds = 0;
|
|
1008
|
-
if ("years" in assertedTimeConfig) {
|
|
1009
|
-
totalMilliseconds += assertedTimeConfig.years * 31536e6;
|
|
1010
|
-
return totalMilliseconds;
|
|
1011
|
-
}
|
|
1012
|
-
if ("months" in assertedTimeConfig) {
|
|
1013
|
-
totalMilliseconds += assertedTimeConfig.months * 2592e6;
|
|
1014
|
-
return totalMilliseconds;
|
|
1015
|
-
}
|
|
1016
|
-
if ("weeks" in assertedTimeConfig) {
|
|
1017
|
-
totalMilliseconds += assertedTimeConfig.weeks * 6048e5;
|
|
1018
|
-
return totalMilliseconds;
|
|
1019
|
-
}
|
|
1020
|
-
if ("days" in assertedTimeConfig) {
|
|
1021
|
-
totalMilliseconds += assertedTimeConfig.days * 864e5;
|
|
1022
|
-
return totalMilliseconds;
|
|
1023
|
-
}
|
|
1024
|
-
if ("hours" in assertedTimeConfig) {
|
|
1025
|
-
totalMilliseconds += assertedTimeConfig.hours * 36e5;
|
|
1026
|
-
return totalMilliseconds;
|
|
1027
|
-
}
|
|
1028
|
-
if ("minutes" in assertedTimeConfig) {
|
|
1029
|
-
totalMilliseconds += assertedTimeConfig.minutes * 6e4;
|
|
1030
|
-
return totalMilliseconds;
|
|
1031
|
-
}
|
|
1032
|
-
return totalMilliseconds;
|
|
956
|
+
// src/block/hydrate/flattenHydratedBlock.ts
|
|
957
|
+
import { toHydratedBlock } from "@xyo-network/xl1-protocol-lib";
|
|
958
|
+
var flattenHydratedBlock = (hydratedBlock) => {
|
|
959
|
+
const [blk, blkPayloads] = hydratedBlock;
|
|
960
|
+
return [...blkPayloads, blk];
|
|
1033
961
|
};
|
|
1034
962
|
|
|
1035
|
-
// src/
|
|
1036
|
-
var
|
|
1037
|
-
const startingBlock = startBlock[0];
|
|
1038
|
-
const endingBlock = endBlock[0];
|
|
1039
|
-
const heightDifference = endingBlock.block - startingBlock.block;
|
|
1040
|
-
const timeDifference = endingBlock.$epoch - startingBlock.$epoch;
|
|
1041
|
-
if (timeDifference === 0) {
|
|
1042
|
-
throw new Error("Time difference must be greater than 0");
|
|
1043
|
-
}
|
|
1044
|
-
const rate = heightDifference / timeDifference;
|
|
1045
|
-
const timeUnitValue = isDefined6(timeUnit) ? timeUnit : "millis";
|
|
1046
|
-
const returnedTimeDifference = isDefined6(timeUnit) ? timeDurations(timeDifference)[timeUnit] : timeDifference;
|
|
1047
|
-
const timePerBlock = returnedTimeDifference / heightDifference;
|
|
1048
|
-
return {
|
|
1049
|
-
range: asXL1BlockRange([startingBlock.block, endingBlock.block], true),
|
|
1050
|
-
span: heightDifference,
|
|
1051
|
-
rate: isDefined6(timeUnit) ? rate * rateMultipliers[timeUnit] : rate,
|
|
1052
|
-
timeUnit: timeUnitValue,
|
|
1053
|
-
timeDifference: returnedTimeDifference,
|
|
1054
|
-
timePerBlock
|
|
1055
|
-
};
|
|
1056
|
-
};
|
|
1057
|
-
var getBlockRateBlocks = async (viewer, startBlockHeight, endBlockHeight) => {
|
|
1058
|
-
if (endBlockHeight <= startBlockHeight) {
|
|
1059
|
-
console.error("startBlockHeight", startBlockHeight);
|
|
1060
|
-
console.error("endBlockHeight", endBlockHeight);
|
|
1061
|
-
throw new Error("End block height must be greater than start block height");
|
|
1062
|
-
}
|
|
1063
|
-
const startingBlock = await viewer.blockByNumber(startBlockHeight);
|
|
1064
|
-
const endingBlock = await viewer.blockByNumber(endBlockHeight);
|
|
1065
|
-
if (isFalsy(startingBlock) || isFalsy(endingBlock)) {
|
|
1066
|
-
throw new Error("Could not retrieve blocks for speed calculation");
|
|
1067
|
-
}
|
|
1068
|
-
return { startingBlock, endingBlock };
|
|
1069
|
-
};
|
|
1070
|
-
var calculateBlockRate = async (viewer, range, timeUnit) => {
|
|
1071
|
-
const [startBlockHeight, endBlockHeight] = range;
|
|
1072
|
-
const { startingBlock, endingBlock } = await getBlockRateBlocks(
|
|
1073
|
-
viewer,
|
|
1074
|
-
startBlockHeight,
|
|
1075
|
-
endBlockHeight
|
|
1076
|
-
);
|
|
1077
|
-
return blockRate(startingBlock, endingBlock, timeUnit);
|
|
1078
|
-
};
|
|
963
|
+
// src/block/hydrate/flattenHydratedBlocks.ts
|
|
964
|
+
var flattenHydratedBlocks = (hydratedBlocks) => hydratedBlocks.flatMap((blk) => flattenHydratedBlock(blk));
|
|
1079
965
|
|
|
1080
|
-
// src/
|
|
966
|
+
// src/block/hydrate/hydrateBlock.ts
|
|
1081
967
|
import { assertEx as assertEx7 } from "@xylabs/sdk-js";
|
|
968
|
+
import { asAnyPayload } from "@xyo-network/sdk-js";
|
|
969
|
+
import { asBlockBoundWitnessWithStorageMeta, isTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol-lib";
|
|
970
|
+
var hydrateBlock = async (context, hash, maxDepth = 1, minDepth = maxDepth) => {
|
|
971
|
+
assertEx7(maxDepth >= 0, () => "maxDepth must be greater than or equal to 0");
|
|
972
|
+
assertEx7(minDepth >= 0, () => "minDepth must be greater than or equal to 0");
|
|
973
|
+
assertEx7(maxDepth >= minDepth, () => "maxDepth must be greater than or equal to minDepth");
|
|
974
|
+
const { chainMap } = context;
|
|
975
|
+
const [block] = await chainMap.get([hash]);
|
|
976
|
+
const bw = assertEx7(asBlockBoundWitnessWithStorageMeta(
|
|
977
|
+
assertEx7(block, () => `block ${hash} not found`)
|
|
978
|
+
), () => `hash ${hash} is not a BlockBoundWitness`);
|
|
979
|
+
if (maxDepth === 0) return [bw, []];
|
|
980
|
+
const blkPayloads = (await chainMap.get(bw.payload_hashes)).map((p) => asAnyPayload(p, true));
|
|
981
|
+
if (minDepth === 1) assertEx7(allHashesPresent(bw.payload_hashes, blkPayloads), () => `Unable to find all payloads for block ${hash}`);
|
|
982
|
+
if (maxDepth === 1) return [bw, blkPayloads];
|
|
983
|
+
const transactions = blkPayloads.filter(isTransactionBoundWitnessWithStorageMeta);
|
|
984
|
+
const transactionsPayloadHashes = transactions.flatMap((tx) => tx.payload_hashes);
|
|
985
|
+
const transactionsPayloads = (await chainMap.get(transactionsPayloadHashes)).map((p) => asAnyPayload(p, true));
|
|
986
|
+
assertEx7(allHashesPresent(transactionsPayloadHashes, transactionsPayloads), () => `Unable to find all payloads for transactions in block ${hash}`);
|
|
987
|
+
const allPayloadsHashes = new Set([...blkPayloads, ...transactionsPayloads].flatMap((p) => p._hash));
|
|
988
|
+
const allPayloads = (await chainMap.get([...allPayloadsHashes])).map((p) => asAnyPayload(p, true));
|
|
989
|
+
const allPayloadsFiltered = allPayloads.filter((p) => allPayloadsHashes.has(p._hash));
|
|
990
|
+
if (maxDepth === 2) assertEx7(allHashesPresent(
|
|
991
|
+
[...allPayloadsHashes],
|
|
992
|
+
allPayloadsFiltered
|
|
993
|
+
), () => `Unable to find all payloads for transactions in block ${hash}`);
|
|
994
|
+
return [bw, allPayloadsFiltered];
|
|
995
|
+
};
|
|
996
|
+
|
|
997
|
+
// src/block/primitives/blockFromBlockNumber.ts
|
|
1082
998
|
import {
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
999
|
+
asHash,
|
|
1000
|
+
isDefined as isDefined7,
|
|
1001
|
+
spanAsync
|
|
1002
|
+
} from "@xylabs/sdk-js";
|
|
1003
|
+
import { toSafeJsonString } from "@xylabs/sdk-js";
|
|
1004
|
+
import {
|
|
1005
|
+
asSignedBlockBoundWitnessWithStorageMeta,
|
|
1006
|
+
SignedBlockBoundWitnessWithHashMetaZod,
|
|
1007
|
+
StepSizes as StepSizes3
|
|
1086
1008
|
} from "@xyo-network/xl1-protocol-lib";
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1009
|
+
async function blockFromBlockNumber(context, blockNumber) {
|
|
1010
|
+
return await spanAsync("blockFromBlockNumber", async () => {
|
|
1011
|
+
const cacheKey = `${blockNumber}`;
|
|
1012
|
+
const { chainMap, head } = context;
|
|
1013
|
+
return await withContextCacheResponse(context, "blockFromBlockNumber", cacheKey, async () => {
|
|
1014
|
+
const [result] = await chainMap.get([head._hash]);
|
|
1015
|
+
if (!isDefined7(result)) {
|
|
1016
|
+
throw new Error(`Head block not found for hash: ${head._hash}`);
|
|
1017
|
+
}
|
|
1018
|
+
let currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
|
|
1019
|
+
result,
|
|
1020
|
+
() => `Found Payload is not a Signed<BlockBoundWitness>: ${JSON.stringify(result, null, 2)}`
|
|
1021
|
+
);
|
|
1022
|
+
if (currentBlock.block < blockNumber) {
|
|
1023
|
+
throw new Error(`Block number ${blockNumber} is greater than head ${currentBlock.block}.`);
|
|
1024
|
+
}
|
|
1025
|
+
while (currentBlock.block > blockNumber) {
|
|
1026
|
+
let jumpHash = currentBlock.previous;
|
|
1027
|
+
let jumpBlockNumber = currentBlock.block - 1;
|
|
1028
|
+
for (const [step, stepSize] of StepSizes3.entries()) {
|
|
1029
|
+
const possibleJumpBlockNumber = currentBlock.block - currentBlock.block % stepSize - 1;
|
|
1030
|
+
if (possibleJumpBlockNumber >= blockNumber && possibleJumpBlockNumber <= jumpBlockNumber) {
|
|
1031
|
+
jumpBlockNumber = possibleJumpBlockNumber;
|
|
1032
|
+
jumpHash = asHash(currentBlock.step_hashes?.at(step), () => `Step hash not found for step ${step} in block ${currentBlock.block}`);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
const [newBlock] = await chainMap.get([
|
|
1036
|
+
asHash(jumpHash, () => `Jump hash not found for block number [${blockNumber}]: ${jumpBlockNumber} ${toSafeJsonString(currentBlock, 10)}`)
|
|
1037
|
+
]);
|
|
1038
|
+
if (!isDefined7(newBlock)) {
|
|
1039
|
+
throw new Error(`Block not found for jump hash: ${jumpHash}`);
|
|
1040
|
+
}
|
|
1041
|
+
currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
|
|
1042
|
+
newBlock,
|
|
1043
|
+
() => {
|
|
1044
|
+
const result2 = SignedBlockBoundWitnessWithHashMetaZod.safeParse(newBlock);
|
|
1045
|
+
return `Found Payload [jump hash] is not a Signed<BlockBoundWitness>: ${result2.error}`;
|
|
1046
|
+
}
|
|
1047
|
+
);
|
|
1048
|
+
if (currentBlock.block === blockNumber) {
|
|
1049
|
+
break;
|
|
1050
|
+
}
|
|
1051
|
+
if (currentBlock.block < blockNumber) {
|
|
1052
|
+
throw new Error(`Block number ${blockNumber} is not a valid step block number for block ${head._hash}.`);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
return currentBlock;
|
|
1056
|
+
});
|
|
1057
|
+
}, { ...context, timeBudgetLimit: 500 });
|
|
1058
|
+
}
|
|
1097
1059
|
|
|
1098
|
-
// src/
|
|
1060
|
+
// src/block/primitives/validateTransactionOpcodes.ts
|
|
1099
1061
|
import {
|
|
1100
1062
|
assertEx as assertEx8,
|
|
1101
|
-
|
|
1102
|
-
|
|
1063
|
+
isHash,
|
|
1064
|
+
toSafeJsonString as toSafeJsonString2
|
|
1103
1065
|
} from "@xylabs/sdk-js";
|
|
1104
|
-
import {
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
const
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
() => `Could not retrieve block ${estimatedEndBlockNumber} for time rate calculation`
|
|
1141
|
-
);
|
|
1142
|
-
const endBlockEpoch = resolvedEndBlock.$epoch;
|
|
1143
|
-
if (!Number.isFinite(startBlockEpoch) || !Number.isFinite(endBlockEpoch)) {
|
|
1144
|
-
throw new TypeError("Block has missing or invalid $epoch");
|
|
1145
|
-
}
|
|
1146
|
-
const actualTimeDifference = startBlockEpoch - endBlockEpoch;
|
|
1147
|
-
if (actualTimeDifference === 0) {
|
|
1148
|
-
throw new Error("Start and end blocks have identical timestamps");
|
|
1149
|
-
}
|
|
1150
|
-
const timeDelta = Math.abs(actualTimeDifference - targetTimeMs);
|
|
1151
|
-
if (timeDelta <= toleranceMs) {
|
|
1152
|
-
return resolvedEndBlock.block;
|
|
1153
|
-
}
|
|
1154
|
-
let adjustedBlocksBack;
|
|
1155
|
-
if (actualTimeDifference < targetTimeMs) {
|
|
1156
|
-
const adjustmentFactor = targetTimeMs / actualTimeDifference;
|
|
1157
|
-
adjustedBlocksBack = Math.floor(estimatedBlocksBack * adjustmentFactor);
|
|
1158
|
-
} else {
|
|
1159
|
-
const adjustmentFactor = actualTimeDifference / targetTimeMs;
|
|
1160
|
-
adjustedBlocksBack = Math.floor(estimatedBlocksBack / adjustmentFactor);
|
|
1066
|
+
import {
|
|
1067
|
+
PayloadBuilder
|
|
1068
|
+
} from "@xyo-network/sdk-js";
|
|
1069
|
+
import { isExecutable } from "@xyo-network/xl1-protocol-lib";
|
|
1070
|
+
async function validateTransactionsOpcodes(txs) {
|
|
1071
|
+
const txElevatedPayloads = [];
|
|
1072
|
+
for (const [txBw, txPayloads] of txs) {
|
|
1073
|
+
if (isExecutable(txBw)) {
|
|
1074
|
+
const operations = txBw.script.map((op) => op.split("|"));
|
|
1075
|
+
for (const [opCode, ...args] of operations) {
|
|
1076
|
+
switch (opCode) {
|
|
1077
|
+
case "elevate": {
|
|
1078
|
+
const [hash, ...rest] = args;
|
|
1079
|
+
const txPayloadsWithStorageMeta = await PayloadBuilder.addStorageMeta(txPayloads);
|
|
1080
|
+
assertEx8(rest.length === 0, () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Too many Arguments`);
|
|
1081
|
+
if (isHash(hash)) {
|
|
1082
|
+
assertEx8(
|
|
1083
|
+
txBw.payload_hashes.includes(hash),
|
|
1084
|
+
() => `Invalid elevate operation ${opCode} ${args.join(", ")} - Hash not in payload hashes => ${toSafeJsonString2(txBw, 20)}`
|
|
1085
|
+
);
|
|
1086
|
+
const txPayload = assertEx8(
|
|
1087
|
+
txPayloadsWithStorageMeta.find((p) => p._hash === hash),
|
|
1088
|
+
() => `Invalid elevate operation ${opCode} ${args.join(", ")} - Payload not found`
|
|
1089
|
+
);
|
|
1090
|
+
txElevatedPayloads.push(txPayload);
|
|
1091
|
+
} else {
|
|
1092
|
+
throw new Error(`Invalid elevate operation ${opCode} ${args.join(", ")} - Invalid hash`);
|
|
1093
|
+
}
|
|
1094
|
+
break;
|
|
1095
|
+
}
|
|
1096
|
+
default: {
|
|
1097
|
+
throw new Error(`Invalid opCode ${opCode}`);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1161
1102
|
}
|
|
1162
|
-
|
|
1163
|
-
return await findEndBlockRecursive(
|
|
1164
|
-
viewer,
|
|
1165
|
-
startBlock,
|
|
1166
|
-
targetTimeMs,
|
|
1167
|
-
adjustedBlocksBack,
|
|
1168
|
-
toleranceMs,
|
|
1169
|
-
attemptsRemaining - 1
|
|
1170
|
-
);
|
|
1171
|
-
};
|
|
1172
|
-
|
|
1173
|
-
// src/primitives/step/completedStepRewardAddress.ts
|
|
1174
|
-
import { toAddress } from "@xylabs/sdk-js";
|
|
1175
|
-
import { StepSizes as StepSizes3 } from "@xyo-network/xl1-protocol-lib";
|
|
1176
|
-
import { keccak256 } from "ethers";
|
|
1177
|
-
function completedStepRewardAddress({ block, step }) {
|
|
1178
|
-
const resolvedStepSize = step < StepSizes3.length ? StepSizes3[step] : step;
|
|
1179
|
-
const addressKey = new TextEncoder().encode(`${block}|${resolvedStepSize}`);
|
|
1180
|
-
return toAddress(keccak256(addressKey).slice(-40), { prefix: false });
|
|
1103
|
+
return txElevatedPayloads;
|
|
1181
1104
|
}
|
|
1182
1105
|
|
|
1183
1106
|
// src/primitives/datalake/addDataLakePayloadsToPayloads.ts
|
|
@@ -1249,6 +1172,99 @@ async function hydratedBlockByNumber(context, blockNumber) {
|
|
|
1249
1172
|
}, { ...context, timeBudgetLimit: 500 });
|
|
1250
1173
|
}
|
|
1251
1174
|
|
|
1175
|
+
// src/primitives/uncle/findBestUncle.ts
|
|
1176
|
+
var DEFAULT_MIN_CANDIDATES = 2;
|
|
1177
|
+
var DEFAULT_BACKOFF_MS = 12e4;
|
|
1178
|
+
|
|
1179
|
+
// src/config/Validation.ts
|
|
1180
|
+
var ValidationConfigZod = z15.object({
|
|
1181
|
+
allowedRewardRedeemers: z15.preprocess((val) => {
|
|
1182
|
+
if (typeof val === "string") {
|
|
1183
|
+
return val.split(",").map((s) => asAddress(s.trim()));
|
|
1184
|
+
}
|
|
1185
|
+
return val;
|
|
1186
|
+
}, z15.array(AddressZod2).optional().register(globalRegistry11, {
|
|
1187
|
+
description: "List of allowed reward redeemer addresses, if undefined anyone can participate",
|
|
1188
|
+
title: "allowedRewardRedeemers",
|
|
1189
|
+
type: "array"
|
|
1190
|
+
})),
|
|
1191
|
+
allowedRewardEscrowAccountSigners: z15.preprocess((val) => {
|
|
1192
|
+
if (typeof val === "string") {
|
|
1193
|
+
return val.split(",").map((s) => asAddress(s.trim()));
|
|
1194
|
+
}
|
|
1195
|
+
return val;
|
|
1196
|
+
}, z15.array(AddressZod2).optional().register(globalRegistry11, {
|
|
1197
|
+
description: "List of allowed reward escrow account signer addresses, if undefined anyone can participate",
|
|
1198
|
+
title: "allowedRewardEscrowAccountSigners",
|
|
1199
|
+
type: "array"
|
|
1200
|
+
})),
|
|
1201
|
+
minCandidates: z15.coerce.number().default(DEFAULT_MIN_CANDIDATES).register(globalRegistry11, {
|
|
1202
|
+
default: DEFAULT_MIN_CANDIDATES,
|
|
1203
|
+
description: "Minimum number of uncle candidates before selecting the best uncle",
|
|
1204
|
+
title: "validation.minCandidates",
|
|
1205
|
+
type: "number"
|
|
1206
|
+
}),
|
|
1207
|
+
backoffMs: z15.coerce.number().default(DEFAULT_BACKOFF_MS).register(globalRegistry11, {
|
|
1208
|
+
default: DEFAULT_BACKOFF_MS,
|
|
1209
|
+
description: "Back-off timeout in ms. If head age exceeds this, minCandidates is ignored",
|
|
1210
|
+
title: "validation.backoffMs",
|
|
1211
|
+
type: "number"
|
|
1212
|
+
})
|
|
1213
|
+
});
|
|
1214
|
+
|
|
1215
|
+
// src/config/Base.ts
|
|
1216
|
+
var BaseConfigZod = z16.object({
|
|
1217
|
+
chain: ChainConfigZod.default(ChainConfigZod.parse({})).describe("Configuration for the chain"),
|
|
1218
|
+
dataLake: DataLakeConfigZod.optional().describe("Configuration for data lakes"),
|
|
1219
|
+
evm: EvmConfigZod.default(EvmConfigZod.parse({})).describe("Configuration for EVM-backed services"),
|
|
1220
|
+
log: LogConfigZod.default(LogConfigZod.parse({})).describe("Configuration for logging"),
|
|
1221
|
+
providers: ProvidersConfigZod.default(ProvidersConfigZod.parse([])).describe("Configuration for providers"),
|
|
1222
|
+
remote: RemoteConfigZod.default(RemoteConfigZod.parse({})).describe("Configuration for remote services"),
|
|
1223
|
+
storage: StorageConfigZod.default(StorageConfigZod.parse({})).describe("Configuration for the storage"),
|
|
1224
|
+
telemetry: TelemetryConfigZod.default(TelemetryConfigZod.parse({})).describe("Configuration for telemetry"),
|
|
1225
|
+
validation: ValidationConfigZod.default(ValidationConfigZod.parse({})).describe("Configuration for validation")
|
|
1226
|
+
});
|
|
1227
|
+
|
|
1228
|
+
// src/config/Actor.ts
|
|
1229
|
+
var ActorConfigZod = BaseConfigZod.extend({
|
|
1230
|
+
name: z17.string(),
|
|
1231
|
+
mnemonic: MnemonicStringZod.optional().register(globalRegistry12, {
|
|
1232
|
+
description: "Mnemonic for the Actor wallet",
|
|
1233
|
+
title: "mnemonic",
|
|
1234
|
+
type: "string"
|
|
1235
|
+
}),
|
|
1236
|
+
healthCheckPort: z17.coerce.number().optional().register(globalRegistry12, {
|
|
1237
|
+
description: "Port for the Producer health checks",
|
|
1238
|
+
title: "producer.healthCheckPort",
|
|
1239
|
+
type: "number"
|
|
1240
|
+
})
|
|
1241
|
+
});
|
|
1242
|
+
var isActorConfig = zodIsFactory2(ActorConfigZod);
|
|
1243
|
+
var asActorConfig = zodAsFactory2(ActorConfigZod, "asActorConfig");
|
|
1244
|
+
var toActorConfig = zodToFactory2(ActorConfigZod, "toActorConfig");
|
|
1245
|
+
|
|
1246
|
+
// src/config/Actors.ts
|
|
1247
|
+
import z18 from "zod";
|
|
1248
|
+
var ActorsConfigZod = z18.array(ActorConfigZod.loose()).describe("Actor-specific configurations that override the base configuration when the actor is running").default([]);
|
|
1249
|
+
|
|
1250
|
+
// src/config/Config.ts
|
|
1251
|
+
var ConfigZod = BaseConfigZod.extend({ actors: ActorsConfigZod }).describe("The complete configuration for the protocol, including global settings and actor-specific overrides");
|
|
1252
|
+
|
|
1253
|
+
// src/simple/block/SimpleBlockViewer.ts
|
|
1254
|
+
import {
|
|
1255
|
+
assertEx as assertEx10,
|
|
1256
|
+
exists,
|
|
1257
|
+
isUndefined as isUndefined4
|
|
1258
|
+
} from "@xylabs/sdk-js";
|
|
1259
|
+
import {
|
|
1260
|
+
asSignedHydratedBlockWithHashMeta,
|
|
1261
|
+
asSignedHydratedBlockWithStorageMeta,
|
|
1262
|
+
asXL1BlockNumber as asXL1BlockNumber2,
|
|
1263
|
+
BlockViewerMoniker,
|
|
1264
|
+
DataLakeViewerMoniker,
|
|
1265
|
+
FinalizationViewerMoniker
|
|
1266
|
+
} from "@xyo-network/xl1-protocol-lib";
|
|
1267
|
+
|
|
1252
1268
|
// src/utils/HydratedCache.ts
|
|
1253
1269
|
import { LRUCache as LRUCache2 } from "lru-cache";
|
|
1254
1270
|
var HydratedCache = class {
|