Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 0 additions & 12 deletions packages/jam/block/gp-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ import { MAX_NUMBER_OF_WORK_ITEMS } from "./work-package.js";
/** `G_I`: The gas allocated to invoke a work-package’s Is-Authorized logic. */
export const G_I = 50_000_000;

/** `G_R`: The gas allocated to invoke a work-package’s Refine logic. */
export const G_R = 5_000_000_000;

/** `I`: Maximum number of work items in a package. */
export const I = MAX_NUMBER_OF_WORK_ITEMS;

Expand Down Expand Up @@ -50,21 +47,12 @@ export const W_B = 13_794_305;
/** `W_C`: The maximum size of service code in octets. */
export const W_C = 4_000_000;

/** `W_E`: The basic size of erasure-coded pieces in octets. */
export const W_E = 684;

/** `W_M`: The maximum number of imports in a work-package. */
export const W_M = 3_072;

/** `W_P`: The number of erasure-coded pieces in a segment. */
export const W_P = 6;

/** `W_R`: The maximum total size of all output blobs in a work-report, in octets. */
export const W_R = 49_152;

/** `W_G`: W_P * W_E = 4104 The size of a segment in octets. */
export const W_G = W_P * W_E;

/** `W_T`: The size of a transfer memo in octets. */
export const W_T = 128;

Expand Down
105 changes: 62 additions & 43 deletions packages/jam/config/chain-spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { type U8, type U16, type U32, type U64, tryAsU8, tryAsU16, tryAsU32, tryAsU64 } from "@typeberry/numbers";
import { Compatibility, GpVersion, TestSuite, WithDebug } from "@typeberry/utils";

/**
Expand Down Expand Up @@ -31,50 +32,58 @@ export const EST_CORES = 341;
*/
export const EST_EPOCH_LENGTH = 600;

/** `W_G`: W_P * W_E = 4104 The size of a segment in octets. */
export const EC_SEGMENT_SIZE = 4104;

/**
* Additional data that has to be passed to the codec to correctly parse incoming bytes.
*/
export class ChainSpec extends WithDebug {
/** Number of validators. */
readonly validatorsCount: number;
readonly validatorsCount: U16;
/** 1/3 of number of validators */
readonly thirdOfValidators: number;
readonly thirdOfValidators: U16;
/** 2/3 of number of validators + 1 */
readonly validatorsSuperMajority: number;
readonly validatorsSuperMajority: U16;
/** Number of cores. */
readonly coresCount: number;
/** Duration of a timeslot in seconds. */
readonly slotDuration: number;
/** Length of the epoch in time slots. */
readonly epochLength: number;
readonly coresCount: U16;
/**
* `R`: The rotation period of validator-core assignments, in timeslots.
* `D`: Period in timeslots after which an unreferenced preimage may be expunged.
*
* https://graypaper.fluffylabs.dev/#/5f542d7/417f00417f00
* https://graypaper.fluffylabs.dev/#/9a08063/445800445800?v=0.6.6
*/
readonly rotationPeriod: number;
readonly preimageExpungePeriod: U32;
/** Duration of a timeslot in seconds. */
readonly slotDuration: U16;
/** Length of the epoch in time slots. */
readonly epochLength: U32;
/** Length of the ticket contest in time slots. */
readonly contestLength: number;
readonly contestLength: U32;
/** The maximum number of tickets each validator can submit. */
readonly ticketsPerValidator: number;
readonly ticketsPerValidator: U8;
/** The maximum number of tickets that can be included in a single block. */
readonly maxTicketsPerExtrinsic: number;
/** Number of erasure coding pieces per segment. */
readonly numberECPiecesPerSegment: number;

readonly maxTicketsPerExtrinsic: U8;
/**
* `D`: Period in timeslots after which an unreferenced preimage may be expunged.
* `R`: The rotation period of validator-core assignments, in timeslots.
*
* https://graypaper.fluffylabs.dev/#/9a08063/445800445800?v=0.6.6
* https://graypaper.fluffylabs.dev/#/5f542d7/417f00417f00
*/
readonly preimageExpungePeriod: number;
readonly rotationPeriod: U16;
/** `W_P`: The number of erasure-coded pieces in a segment. */
readonly numberECPiecesPerSegment: U32;
/** `W_E`: The basic size of erasure-coded pieces in octets. Computed from `W_E = W_G / W_P`. */
readonly erasureCodedPieceSize: U32;
/** `G_T`: The total gas allocated across all Accumulation. */
readonly maxBlockGas: U64;
/** `G_R`: The gas allocated to invoke a work-package’s Refine logic. */
readonly maxRefineGas: U64;

constructor(data: Omit<ChainSpec, "validatorsSuperMajority" | "thirdOfValidators">) {
constructor(data: Omit<ChainSpec, "validatorsSuperMajority" | "thirdOfValidators" | "erasureCodedPieceSize">) {
super();

this.validatorsCount = data.validatorsCount;
this.thirdOfValidators = Math.floor(data.validatorsCount / 3);
this.validatorsSuperMajority = Math.floor(data.validatorsCount / 3) * 2 + 1;
this.thirdOfValidators = tryAsU16(Math.floor(data.validatorsCount / 3));
this.validatorsSuperMajority = tryAsU16(Math.floor(data.validatorsCount / 3) * 2 + 1);
this.coresCount = data.coresCount;
Comment thread
tomusdrw marked this conversation as resolved.
this.slotDuration = data.slotDuration;
this.epochLength = data.epochLength;
Expand All @@ -84,36 +93,46 @@ export class ChainSpec extends WithDebug {
this.maxTicketsPerExtrinsic = data.maxTicketsPerExtrinsic;
this.numberECPiecesPerSegment = data.numberECPiecesPerSegment;
this.preimageExpungePeriod = data.preimageExpungePeriod;
this.erasureCodedPieceSize = tryAsU32(EC_SEGMENT_SIZE / data.numberECPiecesPerSegment);
this.maxBlockGas = data.maxBlockGas;
this.maxRefineGas = data.maxRefineGas;
}
}

/** Set of values for "tiny" chain as defined in JAM test vectors. */
export const tinyChainSpec = new ChainSpec({
contestLength: 10,
coresCount: 2,
epochLength: 12,
maxTicketsPerExtrinsic: 3,
rotationPeriod: 4,
slotDuration: 6,
ticketsPerValidator: 3,
validatorsCount: 6,
numberECPiecesPerSegment: 1026,
preimageExpungePeriod: Compatibility.isSuite(TestSuite.JAMDUNA) && Compatibility.is(GpVersion.V0_6_4) ? 6 : 32, // why 32: https://github.com/davxy/jam-test-vectors/tree/v0.6.6/traces#preimage-expunge-delay
validatorsCount: tryAsU16(6),
coresCount: tryAsU16(2),
epochLength: tryAsU32(12),
contestLength: tryAsU32(10),
maxTicketsPerExtrinsic: tryAsU8(3),
rotationPeriod: tryAsU16(4),
slotDuration: tryAsU16(6),
ticketsPerValidator: tryAsU8(3),
numberECPiecesPerSegment: tryAsU32(1026),
// why 32: https://github.com/davxy/jam-test-vectors/tree/v0.6.6/traces#preimage-expunge-delay
preimageExpungePeriod: tryAsU32(
Compatibility.isSuite(TestSuite.JAMDUNA) && Compatibility.is(GpVersion.V0_6_4) ? 6 : 32,
),
maxBlockGas: tryAsU64(20_000_000),
maxRefineGas: tryAsU64(1_000_000_000),
});

/**
* Set of values for "full" chain as defined in JAM test vectors.
* Please note that only validatorsCount and epochLength are "full", the rest is copied from "tiny".
*/
export const fullChainSpec = new ChainSpec({
contestLength: 500,
coresCount: 341,
epochLength: 600,
maxTicketsPerExtrinsic: 16,
rotationPeriod: 10,
slotDuration: 6,
ticketsPerValidator: 2,
validatorsCount: 1023,
numberECPiecesPerSegment: 6,
preimageExpungePeriod: 19_200,
validatorsCount: tryAsU16(1023),
coresCount: tryAsU16(341),
epochLength: tryAsU32(600),
contestLength: tryAsU32(500),
maxTicketsPerExtrinsic: tryAsU8(16),
rotationPeriod: tryAsU16(10),
slotDuration: tryAsU16(6),
ticketsPerValidator: tryAsU8(2),
numberECPiecesPerSegment: tryAsU32(6),
preimageExpungePeriod: tryAsU32(19_200),
maxBlockGas: tryAsU64(3_500_000_000),
maxRefineGas: tryAsU64(5_000_000_000),
});
1 change: 1 addition & 0 deletions packages/jam/config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"test": "tsx --test $(find . -type f -name '*.test.ts' | tr '\\n' ' ')"
},
"dependencies": {
"@typeberry/numbers": "0.0.1",
Comment thread
tomusdrw marked this conversation as resolved.
"@typeberry/utils": "0.0.1"
},
"author": "Fluffy Labs",
Expand Down
7 changes: 2 additions & 5 deletions packages/jam/transition/accumulate/accumulate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ enum PvmInvocationError {
/** `G_A`: The gas allocated to invoke a work-report’s Accumulation logic. */
export const GAS_TO_INVOKE_WORK_REPORT = 10_000_000n;

/** `G_T`: The total gas allocated across all Accumulation. */
export const ACCUMULATE_TOTAL_GAS = 3_500_000_000n;

const logger = Logger.new(import.meta.filename, "accumulate");

const ARGS_CODEC_0_6_4 = codec.object({
Expand Down Expand Up @@ -432,7 +429,7 @@ export class Accumulate {
/**
* A method that calculates the initial gas limit.
*
* Please note it cannot overflow because we use `BigInt`, and the final result is clamped to `ACCUMULATE_TOTAL_GAS`.
* Please note it cannot overflow because we use `BigInt`, and the final result is clamped to `maxBlockGas` (W_G).
*
* https://graypaper.fluffylabs.dev/#/7e6ff6a/18f40118f401?v=0.6.7
*/
Expand All @@ -441,7 +438,7 @@ export class Accumulate {
GAS_TO_INVOKE_WORK_REPORT * BigInt(this.chainSpec.coresCount) +
this.state.privilegedServices.autoAccumulateServices.reduce((acc, { gasLimit }) => acc + gasLimit, 0n);
const gasLimit = tryAsServiceGas(
ACCUMULATE_TOTAL_GAS > calculatedGasLimit ? ACCUMULATE_TOTAL_GAS : calculatedGasLimit,
this.chainSpec.maxBlockGas > calculatedGasLimit ? this.chainSpec.maxBlockGas : calculatedGasLimit,
);

return tryAsServiceGas(gasLimit);
Expand Down
15 changes: 6 additions & 9 deletions packages/jam/transition/externalities/fetch-externalities.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { EntropyHash } from "@typeberry/block";
import {
G_I,
G_R,
K,
MAX_REPORT_DEPENDENCIES,
N,
Expand All @@ -11,9 +10,7 @@ import {
W_A,
W_B,
W_C,
W_E,
W_M,
W_P,
W_R,
W_T,
W_X,
Expand All @@ -32,7 +29,7 @@ import {
MAX_RECENT_HISTORY,
} from "@typeberry/state";
import { Compatibility, GpVersion } from "@typeberry/utils";
import { ACCUMULATE_TOTAL_GAS, GAS_TO_INVOKE_WORK_REPORT } from "../accumulate/accumulate.js";
import { GAS_TO_INVOKE_WORK_REPORT } from "../accumulate/accumulate.js";
import { Operand, Operand_0_6_4 } from "../accumulate/operand.js";
import { REPORT_TIMEOUT_GRACE_PERIOD } from "../assurances.js";
import { L } from "../reports/verify-contextual.js";
Expand Down Expand Up @@ -92,8 +89,8 @@ function getEncodedConstants(chainSpec: ChainSpec) {
E: tryAsU32(chainSpec.epochLength),
G_A: tryAsU64(GAS_TO_INVOKE_WORK_REPORT),
G_I: tryAsU64(G_I),
G_R: tryAsU64(G_R),
G_T: tryAsU64(ACCUMULATE_TOTAL_GAS),
G_R: tryAsU64(chainSpec.maxRefineGas),
G_T: tryAsU64(chainSpec.maxBlockGas),
H: tryAsU16(MAX_RECENT_HISTORY),
Comment thread
tomusdrw marked this conversation as resolved.
I: tryAsU16(MAX_NUMBER_OF_WORK_ITEMS),
J: tryAsU16(MAX_REPORT_DEPENDENCIES),
Expand All @@ -106,13 +103,13 @@ function getEncodedConstants(chainSpec: ChainSpec) {
R: tryAsU16(chainSpec.rotationPeriod),
T: tryAsU16(T),
U: tryAsU16(REPORT_TIMEOUT_GRACE_PERIOD),
V: tryAsU16(chainSpec.validatorsCount),
V: chainSpec.validatorsCount,
W_A: tryAsU32(W_A),
W_B: tryAsU32(W_B),
W_C: tryAsU32(W_C),
W_E: tryAsU32(W_E),
W_E: tryAsU32(chainSpec.erasureCodedPieceSize),
W_M: tryAsU32(W_M),
W_P: tryAsU32(W_P),
W_P: tryAsU32(chainSpec.numberECPiecesPerSegment),
W_R: tryAsU32(W_R),
W_T: tryAsU32(W_T),
W_X: tryAsU32(W_X),
Expand Down
6 changes: 3 additions & 3 deletions packages/jam/transition/statistics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
tryAsValidatorIndex,
} from "@typeberry/block";
import { type AssurancesExtrinsic, AvailabilityAssurance } from "@typeberry/block/assurances.js";
import { I, T, W_G, W_M, W_R, W_X } from "@typeberry/block/gp-constants.js";
import { I, T, W_M, W_R, W_X } from "@typeberry/block/gp-constants.js";
import type { GuaranteesExtrinsic } from "@typeberry/block/guarantees.js";
import type { PreimagesExtrinsic } from "@typeberry/block/preimage.js";
import { testWorkReportHex } from "@typeberry/block/test-helpers.js";
Expand All @@ -20,7 +20,7 @@ import { WorkReport } from "@typeberry/block/work-report.js";
import { BitVec, Bytes, BytesBlob } from "@typeberry/bytes";
import { Decoder } from "@typeberry/codec";
import { FixedSizeArray, asKnownSize } from "@typeberry/collections";
import { tinyChainSpec } from "@typeberry/config";
import { EC_SEGMENT_SIZE, tinyChainSpec } from "@typeberry/config";
import { ED25519_SIGNATURE_BYTES } from "@typeberry/crypto";
import { HASH_SIZE } from "@typeberry/hash";
import { isU16, isU32, tryAsU32 } from "@typeberry/numbers";
Expand Down Expand Up @@ -48,7 +48,7 @@ describe("Statistics", () => {
});

it("max data availability score formula should fit into U32", () => {
assert.strictEqual(isU32(W_R + W_G * ((W_M * 65) / 64)), true);
assert.strictEqual(isU32(W_R + EC_SEGMENT_SIZE * ((W_M * 65) / 64)), true);
});
});

Expand Down
5 changes: 2 additions & 3 deletions packages/jam/transition/statistics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import {
tryAsPerValidator,
tryAsServiceGas,
} from "@typeberry/block";
import { W_G } from "@typeberry/block/gp-constants.js";
import type { Preimage, PreimagesExtrinsic } from "@typeberry/block/preimage.js";
import type { WorkReport } from "@typeberry/block/work-report.js";
import type { WorkResult } from "@typeberry/block/work-result.js";
import type { ChainSpec } from "@typeberry/config";
import { type ChainSpec, EC_SEGMENT_SIZE } from "@typeberry/config";
import { type U32, tryAsU16, tryAsU32 } from "@typeberry/numbers";
import { ServiceStatistics, type State, StatisticsData } from "@typeberry/state";
import { ValidatorStatistics } from "@typeberry/state";
Expand Down Expand Up @@ -109,7 +108,7 @@ export class Statistics {

const workPackageLength = availableWorkReports.workPackageSpec.length;
const workPackageSegment = Math.ceil((availableWorkReports.workPackageSpec.exportsCount * 65) / 64);
sum += workPackageLength + W_G * workPackageSegment;
sum += workPackageLength + EC_SEGMENT_SIZE * workPackageSegment;

/** Available work report score can be up to `W_R + W_G * ((W_M * 65) / 64) = 0x00C4_2180` */
return tryAsU32(sum);
Expand Down
Loading