import fs from 'fs'
import path from 'path'
import process from 'process'
import b4a from 'b4a'
import {
ADMISSION_CONFORMANCE_CLASS,
ADMISSION_COST_RULES,
ADVERTISED_OPERATION_BITS,
ADVERTISED_OPERATION_PROFILE_ROWS,
AUXILIARY_SIGNATURE_DOMAIN_ID,
ABI_STATUS,
CELL_RECEIPT_RESULT,
CELL_SIZE_CLASS,
CLOCK_UNSAFE_OPERATION_BITS,
CORE_ACK_RESULT,
CORE_SESSION_CLASS,
DISPATCH_LIMITS,
DOMAIN_PURPOSE,
DOMAIN_RECIPE,
DOMAIN_REGISTRY,
ENDPOINT_LIMITS,
ERROR_PROFILE_ID,
ERROR_RETRY_AFTER_MODE,
ERROR_PROFILE_ROWS,
EXECUTABLE_SCHEMA_CODEC_STATUS,
FAMILY,
FAMILY_ROUTES,
FORWARD_CIRCUIT_CLASS,
FORWARD_CLOSE_KIND,
FRAME_KIND,
HEALTH_CLOCK_STATE,
HEALTH_INTEGRITY_STATE,
HEALTH_REBALANCE_STATE,
INBOX_APPEND_AUTH_MODE,
INBOX_APPEND_RESULT,
INBOX_FRAME_CLASS,
INBOX_MANAGE_OPERATION,
INBOX_RECEIPT_RESULT,
OPERATION,
OUTER_CLASS,
PROTOCOL,
OPERATION_PROFILE_ROWS,
RESERVED_OPERATION_BITS,
RESERVED_OPERATION_PAIRS,
PUBLIC_PROFILE_LIMITS,
REQUEST_COMMITMENT_DOMAIN_ID,
RESULT_SIGNATURE_DOMAIN_ID,
SCHEMA_CATEGORY,
SCHEMA_NAMES_BY_CATEGORY,
STORE_LIFECYCLE_STATE,
STREAM_TRANSITION,
STORE_FORMAT_AUTHORITY_V1,
STREAM_WIRE_CLASS,
TRANSPORT_ID,
TRANSPORT_SUPPORT,
WIRE_EXECUTABLE_SCHEMA_CODEC_STATUS,
assertMasterSchemaInventory,
admissionParametersV1,
admissionProfileV1,
admissionCostRuleV1,
batchGetEntriesCommitment,
batchGetResultV1,
batchGetSignaturePayloadV1,
batchGetV1,
blindCoreAckV1,
blindBackupChunkManifestV1,
blindBackupEncryptionProfileV1,
blindBackupManifestV1,
blindBackupRetentionTransitionV1,
blindCleanRestoreEvidenceV1,
blindControlStateSnapshotV1,
blindDhtPointerV1,
blindExternalJournalTopologyV1,
blindExternalCommitWitnessV1,
blindForwardCloseV1,
blindForwardDataV1,
blindForwardOpenResultV1,
blindForwardOpenV1,
blindForwardWindowV1,
blindHealthChallengeV1,
blindHealthResultV1,
blindLocalCheckpointV1,
blindOhttpKeyConfigV1,
blindRestoreEvidenceBundleV1,
blindRestoreEvidenceHeadV1,
blindServiceDescriptorV1,
blindStreamChunkPlainV1,
blindWalHeaderV2,
blake2b256,
cellPutRequestCommitment,
cellStorageSlot,
coreMirrorRequestV1,
coreMirrorRequestCommitment,
coreServeChallengeV1,
coreServeRequestCommitment,
coreServeResultV1,
compileMasterSchemaCatalog,
compileMasterSchemaCatalogForCategory,
controlSnapshotHash,
domainRegistryEntryV1,
durabilityContinuityBindingV1,
encodeCanonical,
encodeDispatchFrame,
encodeWireAbiRegistry,
encodeOuterEnvelope,
encodeSchemaCatalog,
encodeStoreFormatAuthorityV1,
encodeVectorManifest,
errorProfileEntryV1,
forwardOpenRequestCommitment,
getCellResultV1,
hashAbi,
hashEvidenceFormat,
hashEvidenceVectorSet,
hashImplementationSpec,
hashOwnerDecisions,
hashReleaseClosure,
hashSpec,
hashStoreFormat,
hashStoreVectorSet,
hashVectorSet,
inboxAppendV1,
inboxPhysicalTopic,
inboxReadEntriesCommitment,
inboxReadRequestCommitment,
inboxReadResultV1,
inboxReadSignaturePayloadV1,
operationProfileV1,
persistentResultCommitment,
putCellV1,
relayResultBindingV1,
relayIdentityTransitionV1,
schemaCatalogEntryV1
} from '@hiverelay/blind-protocol'
const root = process.cwd()
const check = process.argv.includes('--check')
const wireOnly = process.argv.includes('--wire-only')
const forbidNonWireFixtures = process.argv.includes('--forbid-non-wire-fixtures')
function nonWireFixture (label, buildFixture) {
if (forbidNonWireFixtures) throw new Error(`WIRE-only generation evaluated non-WIRE fixture: ${label}`)
return buildFixture()
}
function canonicalTextBytes (relative) {
const file = path.join(root, ...relative)
const bytes = fs.readFileSync(file)
if (bytes.length === 0 || bytes[bytes.length - 1] !== 0x0a || bytes.includes(0x0d) ||
(bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf)) {
throw new Error('canonical protocol text is not UTF-8/LF/no-BOM/exact-final-LF form')
}
return bytes
}
const canonicalWireSpecBytes = canonicalTextBytes(['docs', 'protocol', 'HIVERELAY-BLIND-WIRE-V1.md'])
const canonicalImplementationSpecBytes = canonicalTextBytes(['docs', 'protocol', 'BLIND-SUBSTRATE-IMPLEMENTATION-SPEC.md'])
const canonicalOwnerDecisionsBytes = canonicalTextBytes(['docs', 'protocol', 'HIVERELAY-BLIND-OWNER-DECISIONS-V1.json'])
const canonicalProfileBindingBytes = canonicalTextBytes(['docs', 'protocol', 'HIVERELAY-BLIND-RC1-PROFILE-BINDING-V1.json'])
const ownerDecisions = JSON.parse(b4a.toString(canonicalOwnerDecisionsBytes, 'utf8'))
const profileBinding = JSON.parse(b4a.toString(canonicalProfileBindingBytes, 'utf8'))
const canonicalMasterBytes = canonicalTextBytes([
'docs', 'protocol', 'BLIND-APP-AGNOSTIC-HIVERELAY-MASTER-SPEC.md'
])
const canonicalMasterText = b4a.toString(canonicalMasterBytes, 'utf8')
const wireSchemaCatalog = compileMasterSchemaCatalogForCategory(canonicalMasterText, SCHEMA_CATEGORY.WIRE)
const masterInventoryAudit = wireOnly ? wireSchemaCatalog.inventoryAudit : assertMasterSchemaInventory(canonicalMasterText)
const masterSchemaCatalog = wireOnly ? null : compileMasterSchemaCatalog(canonicalMasterText)
if (!WIRE_EXECUTABLE_SCHEMA_CODEC_STATUS.complete ||
WIRE_EXECUTABLE_SCHEMA_CODEC_STATUS.nonWireLeakNames.length !== 0 ||
EXECUTABLE_SCHEMA_CODEC_STATUS.privateIpcLeakNames.length !== 0) {
throw new Error('public WIRE catalog does not have exact executable codec coverage')
}
if (!wireOnly && !EXECUTABLE_SCHEMA_CODEC_STATUS.complete) {
throw new Error('stable-master catalog does not have exact package-owned executable codec coverage')
}
function sameBytes (a, b) {
return a.byteLength === b.byteLength && b4a.equals(b4a.from(a), b4a.from(b))
}
function emit (relative, bytes) {
const file = path.join(root, relative)
if (check) {
if (!fs.existsSync(file)) throw new Error(`missing generated artifact: ${relative}`)
const current = fs.readFileSync(file)
if (!sameBytes(current, bytes)) throw new Error(`generated artifact drift: ${relative}`)
return
}
fs.mkdirSync(path.dirname(file), { recursive: true })
fs.writeFileSync(file, bytes)
}
function listedFiles (directory, prefix = '') {
const output = []
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
const relative = prefix === '' ? entry.name : `${prefix}/${entry.name}`
if (entry.isDirectory()) output.push(...listedFiles(path.join(directory, entry.name), relative))
else if (entry.isFile()) output.push(relative)
else throw new Error(`generated vector tree contains a non-file entry: ${relative}`)
}
return output
}
const cellGet = encodeDispatchFrame({
frameKind: FRAME_KIND.REQUEST,
familyId: FAMILY.CELL,
operationId: OPERATION.CELL.GET,
requestId: b4a.from('00112233445566778899aabbccddeeff', 'hex'),
body: b4a.from('01020304', 'hex')
})
const forwardData = encodeDispatchFrame({
frameKind: FRAME_KIND.STREAM,
familyId: FAMILY.FORWARD,
operationId: OPERATION.FORWARD.DATA,
requestId: b4a.alloc(16),
streamId: 0x0102030405060708n,
sequence: 9n,
body: b4a.from('a0a1a2a3', 'hex')
})
const outerCellGet = encodeOuterEnvelope({ outerClass: 1, innerDispatch: cellGet }, {
randomFill: padding => padding.fill(0xa5)
})
const invalidFlags = b4a.from(cellGet)
invalidFlags[8] = 1
const invalidOperation = b4a.from(cellGet)
invalidOperation[7] = 0xff
const bytes = (length, value) => b4a.alloc(length, value)
function relayBinding (seed, overrides = {}) {
return {
version: 1,
relayPublicKey: bytes(32, seed),
storeId: bytes(32, seed + 1),
descriptorSequence: 9n,
descriptorHash: bytes(32, seed + 2),
durabilityProfileId: 1,
durabilityContinuityHash: bytes(32, seed + 3),
durabilityProfileHash: bytes(32, seed + 4),
restoreEvidenceHeadSequence: 0n,
restoreEvidenceHeadHash: bytes(32, 0),
externalCommitWitness: null,
...overrides
}
}
const admission = {
profileId: 7,
schemeId: 9,
parameterHash: bytes(32, 0xa1),
token: bytes(3, 0xa2)
}
const allocationEpoch = 0x01020304
const createPublicKey = bytes(32, 0x11)
const cellBlob = bytes(4096, 0x51)
const storageSlot = cellStorageSlot({ allocationEpoch, createPublicKey })
const cellPutBody = encodeCanonical(putCellV1, {
version: 1,
storageSlot,
allocationEpoch,
sizeClass: 1,
leaseClass: 2,
clientNonce: bytes(32, 0x12),
createPublicKey,
renewPublicKey: bytes(32, 0x13),
dropPublicKey: bytes(32, 0x14),
declaredBlobHash: blake2b256(cellBlob),
createSignature: bytes(64, 0x15),
admission,
cellBlob
})
const cellPutCommitment = cellPutRequestCommitment({
allocationCommitment: bytes(32, 0x16),
clientNonce: bytes(32, 0x12)
})
const batchSlots = [bytes(32, 0x21), bytes(32, 0x22)]
const batchRequestBody = encodeCanonical(batchGetV1, {
version: 1,
clientNonce: bytes(32, 0x23),
slots: batchSlots,
admission: null
})
const duplicateBatchSlots = b4a.from(batchRequestBody)
b4a.copy(duplicateBatchSlots.subarray(34, 66), duplicateBatchSlots, 66)
const batchEntries = [{ status: 0 }, { status: 1, sizeClass: 1, cellBlob }]
const batchResultBody = encodeCanonical(batchGetResultV1, {
version: 1,
relayBinding: relayBinding(0x24),
requestNonce: bytes(32, 0x23),
requestCommitment: bytes(32, 0x25),
entries: batchEntries,
entriesCommitment: batchGetEntriesCommitment(batchEntries),
signature: bytes(64, 0x26)
})
const batchPersistentResultCommitment = persistentResultCommitment(
FAMILY.CELL,
OPERATION.CELL.BATCH_GET,
batchResultBody.subarray(0, batchResultBody.byteLength - 64)
)
const invalidBatchTag = b4a.from(batchResultBody)
invalidBatchTag[277] = 2
const getResultBody = encodeCanonical(getCellResultV1, { version: 1, sizeClass: 1, cellBlob })
const invalidGetClass = b4a.from(getResultBody)
invalidGetClass[1] = 0
const inboxAllocationEpoch = 0x05060708
const inboxCreatePublicKey = bytes(32, 0x31)
const physicalTopic = inboxPhysicalTopic({
allocationEpoch: inboxAllocationEpoch,
createPublicKey: inboxCreatePublicKey
})
const inboxFrame = bytes(4096, 0x32)
const inboxAppendBody = encodeCanonical(inboxAppendV1, {
version: 1,
physicalTopic,
frameClass: 1,
frameHash: blake2b256(inboxFrame),
clientNonce: bytes(32, 0x33),
appendSignature: null,
admission,
frame: inboxFrame
})
const emptyInboxEntries = []
const inboxReadResultBody = encodeCanonical(inboxReadResultV1, {
version: 1,
relayBinding: relayBinding(0x34),
requestNonce: bytes(32, 0x35),
requestCommitment: bytes(32, 0x36),
snapshotRevision: 0n,
entries: emptyInboxEntries,
entriesCommitment: inboxReadEntriesCommitment(emptyInboxEntries),
nextCursor: null,
signature: bytes(64, 0x37)
})
const inboxReadCommitment = inboxReadRequestCommitment({
relayPublicKey: bytes(32, 0x34),
physicalTopic,
cursor: b4a.from('a0a1a2', 'hex'),
limit: 64,
clientNonce: bytes(32, 0x35)
})
const invalidInboxCursor = b4a.concat([
b4a.from([1]),
physicalTopic,
b4a.from([129]),
bytes(129, 0x38),
b4a.from([0, 1]),
bytes(32, 0x39),
b4a.from([0])
])
const admissionProfile = {
profileId: 7,
schemeId: 9,
conformanceClass: 1,
roleBits: 1,
parameterUrl: b4a.from('https://evidence.example:443/admission.cenc'),
parameterHash: bytes(32, 0x40)
}
const admissionProfileBody = encodeCanonical(admissionProfileV1, admissionProfile)
const admissionParametersBody = encodeCanonical(admissionParametersV1, {
version: 1,
relayPublicKey: bytes(32, 0x41),
profileId: 7,
schemeId: 9,
conformanceClass: 1,
roleBits: 1,
verifierKey: bytes(3, 0x42),
resourceCosts: [
{ familyId: 2, operationId: 1, resourceClass: 1, leaseClass: 1, costUnits: 10n },
{ familyId: 4, operationId: 1, resourceClass: 1, leaseClass: 1, costUnits: 20n }
],
tokenMaxBytes: 4096,
issuanceUrl: b4a.from('https://issuer.example:443/token'),
issuerRelayKey: bytes(32, 0x43),
validFromEpoch: 100,
expiresEpoch: 104,
nonce: bytes(32, 0x44),
signature: bytes(64, 0x45)
})
const identityTransitionBody = encodeCanonical(relayIdentityTransitionV1, {
version: 1,
oldRelayKey: bytes(32, 0x46),
newRelayKey: bytes(32, 0x47),
oldIdentitySequence: 5n,
newIdentitySequence: 6n,
validFromEpoch: 100,
reasonCode: 1,
transitionNonce: bytes(32, 0x48),
oldSignature: bytes(64, 0x49),
newSignature: bytes(64, 0x4a)
})
const dhtPointerBody = encodeCanonical(blindDhtPointerV1, {
version: 1,
relayPublicKey: bytes(32, 0x4b),
descriptorSequence: 9n,
descriptorHash: bytes(32, 0x4c),
descriptorUrl: b4a.from('https://relay.example:443/descriptor.cenc'),
transportBits: 0x0002,
issuedEpoch: 100,
expiresEpoch: 104,
nonce: bytes(32, 0x4d),
signature: bytes(64, 0x4e)
})
const healthChallengeBody = encodeCanonical(blindHealthChallengeV1, {
version: 1,
descriptorSequence: 9n,
descriptorHash: bytes(32, 0x4f),
endpointId: 1,
transportSupportBit: 1,
requestedRoleBits: 0x0003,
requestedOperationBits: 0x00000007,
clientNonce: bytes(32, 0x50)
})
const healthResultBody = encodeCanonical(blindHealthResultV1, {
version: 1,
relayPublicKey: bytes(32, 0x51),
storeId: bytes(32, 0x52),
descriptorSequence: 9n,
descriptorHash: bytes(32, 0x4f),
endpointId: 1,
transportSupportBit: 1,
durabilityContinuityHash: bytes(32, 0x53),
durabilityProfileHash: bytes(32, 0x54),
clientNonce: bytes(32, 0x50),
readyRoleBits: 0x0003,
readyOperationBits: 0x00000007,
clockState: 1,
effectiveEpochFloor: 100,
integrityState: 1,
checkpointAgeBand: 1,
scrubAgeBand: 2,
rebalanceState: 0,
capacityBand: 5,
challengeEpoch: 100,
signature: bytes(64, 0x55)
})
const ohttpKeyConfigBody = encodeCanonical(blindOhttpKeyConfigV1, {
version: 1,
gatewayRelayKey: bytes(32, 0x56),
gatewayDescriptorSequence: 9n,
configId: 17,
kemId: 0x0020,
kdfId: 0x0001,
aeadId: 0x0001,
encodedPublicKey: bytes(32, 0x57),
notBeforeEpoch: 100,
notAfterEpoch: 104,
previousConfigHash: null,
signature: bytes(64, 0x58)
})
const externalTopologyBody = encodeCanonical(blindExternalJournalTopologyV1, {
version: 1,
relayPublicKey: bytes(32, 0x59),
storeId: bytes(32, 0x5a),
externalJournalId: bytes(32, 0x5b),
durabilityContinuityHash: bytes(32, 0x5c),
topologySequence: 0n,
previousTopologyHash: null,
replicationClass: 1,
commitQuorum: 2,
sharedFailureGroupId: bytes(32, 0x5d),
liveStoreFailureGroupId: bytes(32, 0x5e),
backupFailureGroups: [
{ backupFailureGroupId: bytes(32, 0x60), operatorGroupId: bytes(32, 0x61) }
],
nodes: [
{ nodePublicKey: bytes(32, 0x62), operatorGroupId: bytes(32, 0x72), failureDomainId: bytes(32, 0x82), roleConflictBits: 0 },
{ nodePublicKey: bytes(32, 0x63), operatorGroupId: bytes(32, 0x73), failureDomainId: bytes(32, 0x83), roleConflictBits: 0 },
{ nodePublicKey: bytes(32, 0x64), operatorGroupId: bytes(32, 0x74), failureDomainId: bytes(32, 0x84), roleConflictBits: 0 }
],
issuedEpoch: 100,
expiresEpoch: 104,
witnessPublicKey: bytes(32, 0x65),
signature: bytes(64, 0x66)
})
const coreAck = {
version: 1,
relayBinding: relayBinding(0x67),
corePublicKey: bytes(32, 0x68),
fork: 2n,
length: 16n,
signedHeadHash: bytes(32, 0x69),
observedAtEpoch: 100,
leaseEpoch: 104,
result: 2,
requestNonce: bytes(32, 0x6a),
requestCommitment: bytes(32, 0x6b),
signature: bytes(64, 0x6c)
}
const coreAckBody = encodeCanonical(blindCoreAckV1, coreAck)
const coreMirror = {
version: 1,
corePublicKey: coreAck.corePublicKey,
fork: 2n,
length: 16n,
signedHeadHash: coreAck.signedHeadHash,
leaseClass: 2,
clientNonce: bytes(32, 0x6d),
admission
}
const coreMirrorBody = encodeCanonical(coreMirrorRequestV1, coreMirror)
const coreMirrorCommitment = coreMirrorRequestCommitment({
relayPublicKey: coreAck.relayBinding.relayPublicKey,
...coreMirror
})
const coreServeChallenge = {
version: 1,
corePublicKey: coreAck.corePublicKey,
fork: 2n,
length: 16n,
signedHeadHash: coreAck.signedHeadHash,
blockIndices: [0n, 7n, 15n],
clientNonce: coreAck.requestNonce,
admission: null
}
const coreServeChallengeBody = encodeCanonical(coreServeChallengeV1, coreServeChallenge)
const coreServeCommitment = coreServeRequestCommitment({
relayPublicKey: coreAck.relayBinding.relayPublicKey,
...coreServeChallenge
})
const coreServeResultBody = encodeCanonical(coreServeResultV1, {
version: 1,
acknowledgement: coreAck,
proofsAndBlocks: b4a.from('0102030405', 'hex')
})
const forwardOpenBody = encodeCanonical(blindForwardOpenV1, {
version: 1,
routeId: bytes(16, 0x6e),
nextDescriptorSequence: 10n,
nextDescriptorHash: bytes(32, 0x6f),
requestedWireClass: 1,
circuitClass: 1,
circuitNonce: bytes(32, 0x70),
parentRouteScopeHash: bytes(32, 0),
hopAdmission: admission,
innerHandshake: bytes(32, 0x71)
})
const forwardOpenCommitment = forwardOpenRequestCommitment({
previousRelayKey: bytes(32, 0x72),
routeId: bytes(16, 0x6e),
nextDescriptorSequence: 10n,
nextDescriptorHash: bytes(32, 0x6f),
requestedWireClass: 1,
circuitClass: 1,
circuitNonce: bytes(32, 0x70),
parentRouteScopeHash: bytes(32, 0),
innerHandshake: bytes(32, 0x71)
})
const nextHopAccept = {
version: 1,
previousRelayKey: bytes(32, 0x72),
previousDescriptorSequence: 9n,
previousDescriptorHash: bytes(32, 0x73),
nextRelayKey: bytes(32, 0x74),
nextDescriptorSequence: 10n,
nextDescriptorHash: bytes(32, 0x6f),
nextRelayBinding: relayBinding(0x74, {
relayPublicKey: bytes(32, 0x74),
descriptorSequence: 10n,
descriptorHash: bytes(32, 0x6f)
}),
routeId: bytes(16, 0x6e),
circuitNonce: bytes(32, 0x70),
nextStreamId: 21n,
grantedWireClass: 1,
circuitClass: 1,
grantedInitialWindow: 64 * 1024,
maxDataBytes: 4096,
maxCircuitBytes: 16n * 1024n * 1024n,
idleMillis: 30000,
lifetimeMillis: 600000,
openedAtEpoch: 100,
hopOpenCommitment: bytes(32, 0x75),
acceptedRouteScopeHash: bytes(32, 0x7a),
acceptedRelayCount: 1,
handshakeFlight2: bytes(96, 0x76),
nextSignature: bytes(64, 0x77)
}
const forwardOpenResultBody = encodeCanonical(blindForwardOpenResultV1, {
version: 1,
relayBinding: relayBinding(0x72, {
relayPublicKey: nextHopAccept.previousRelayKey,
descriptorSequence: nextHopAccept.previousDescriptorSequence,
descriptorHash: nextHopAccept.previousDescriptorHash
}),
routeId: nextHopAccept.routeId,
nextDescriptorSequence: nextHopAccept.nextDescriptorSequence,
nextDescriptorHash: nextHopAccept.nextDescriptorHash,
circuitNonce: nextHopAccept.circuitNonce,
grantedWireClass: 1,
circuitClass: 1,
streamId: 20n,
grantedInitialWindow: nextHopAccept.grantedInitialWindow,
maxDataBytes: nextHopAccept.maxDataBytes,
maxCircuitBytes: nextHopAccept.maxCircuitBytes,
idleMillis: nextHopAccept.idleMillis,
lifetimeMillis: nextHopAccept.lifetimeMillis,
openedAtEpoch: nextHopAccept.openedAtEpoch,
requestCommitment: bytes(32, 0x78),
acceptedRouteScopeHash: nextHopAccept.acceptedRouteScopeHash,
acceptedRelayCount: nextHopAccept.acceptedRelayCount,
nextHopAccept,
signature: bytes(64, 0x79)
})
const forwardDataBody = encodeCanonical(blindForwardDataV1, {
version: 1,
circuitNonce: nextHopAccept.circuitNonce,
offset: 0n,
bytes: b4a.from('deadbeef', 'hex')
})
const forwardWindowBody = encodeCanonical(blindForwardWindowV1, {
version: 1,
circuitNonce: nextHopAccept.circuitNonce,
consumedThrough: 4n,
creditIncrement: 4096
})
const forwardCloseBody = encodeCanonical(blindForwardCloseV1, {
version: 1,
circuitNonce: nextHopAccept.circuitNonce,
closeKind: 1,
finalSendOffset: 4n,
reasonCode: 0
})
const streamContent = b4a.from('010203', 'hex')
const streamChunkBody = encodeCanonical(blindStreamChunkPlainV1, {
version: 1,
wireClass: 1,
flags: 0,
contentLength: streamContent.byteLength,
content: streamContent,
randomPadding: bytes(4070, 0x7a)
})
const invalidStreamClass = b4a.from(streamChunkBody)
invalidStreamClass[1] = 0
const serviceDescriptorBody = encodeCanonical(blindServiceDescriptorV1, {
version: 1,
relayPublicKey: bytes(32, 0x7b),
storeId: bytes(32, 0x7c),
descriptorSequence: 0n,
previousDescriptorHash: null,
identitySequence: 0n,
previousRelayKey: null,
identityTransition: null,
build: {
specHash: bytes(32, 0x01),
abiHash: bytes(32, 0x02),
vectorSetHash: bytes(32, 0x03),
evidenceFormatHash: bytes(32, 0x04),
evidenceVectorSetHash: bytes(32, 0x05),
storeFormatHash: bytes(32, 0x06),
storeVectorSetHash: bytes(32, 0x07),
privateIpcFormatHash: bytes(32, 0x14),
privateIpcVectorSetHash: bytes(32, 0x15),
buildArtifactHash: bytes(32, 0x08),
buildArtifactUrl: b4a.from('https://evidence.example:443/artifact.cenc'),
buildManifestUrl: b4a.from('https://evidence.example:443/build.cenc'),
buildManifestHash: bytes(32, 0x09),
releaseEvidenceBundleUrl: b4a.from('https://evidence.example:443/release.cenc'),
releaseEvidenceBundleHash: bytes(32, 0x16),
releaseSupportHorizonHash: bytes(32, 0x17),
runtimeBoundaryEvidenceUrl: b4a.from('https://evidence.example:443/runtime-boundary.cenc'),
runtimeBoundaryEvidenceHash: bytes(32, 0x18)
},
protocols: [{ protocolId: 1, major: 1, minor: 0, featureBits: 0n, profileHash: bytes(32, 0x0a) }],
endpoints: [{
endpointId: 1,
transportId: 1,
transportProfileHash: bytes(32, 0x0b),
roleBits: 1,
privacyProfileBits: 1,
canonicalUrl: b4a.from('https://relay.example:443/api/blind/v1/describe'),
endpointKey: null,
envelopeClassBits: 0x02,
wireClassBits: 0,
maxStreams: 0,
auxiliaryUrl: null,
auxiliaryHash: null
}],
cellSizeClassBits: 0x3e,
leaseClassBits: 0x1e,
maxBatchCount: 64,
maxResponseBytes: 4 * 1024 * 1024,
maxSponsoredCoreLength: 1024n,
enabledOperationBits: 0x003fffff,
admissionProfiles: [admissionProfile],
durability: {
profileId: 1,
storeFormatMajor: 1,
storeFormatMinor: 1,
storeFormatHash: bytes(32, 0x0c),
externalJournalId: bytes(32, 0),
externalWitnessPublicKey: bytes(32, 0),
externalJournalReplicationClass: 0,
externalJournalFailureGroupId: bytes(32, 0),
externalCheckpointAgeBand: 0,
externalJournalTopologyUrl: null,
externalJournalTopologyHash: bytes(32, 0),
restoreEvidenceFeedUrl: null,
restoreEvidenceFeedId: bytes(32, 0),
restoreEvidenceCheckpointSequence: 0n,
restoreEvidenceCheckpointHash: bytes(32, 0),
acknowledgedRpoBand: 0,
targetRtoBand: 0,
redundancyClass: 0,
restoreDrillAgeBand: 0
},
durabilityContinuityHash: bytes(32, 0x10),
durabilityProfileHash: bytes(32, 0x11),
storeLifecycleState: 1,
drainStartedEpoch: null,
capacityBand: 5,
issuedEpoch: 100,
expiresEpoch: 104,
descriptorNonce: bytes(32, 0x12),
signature: bytes(64, 0x13)
})
const schemaCatalogBody = encodeCanonical(schemaCatalogEntryV1, wireSchemaCatalog.entries[0])
const externalCommitWitness = {
version: 1,
relayPublicKey: bytes(32, 0x81),
storeId: bytes(32, 0x82),
externalJournalId: bytes(32, 0x83),
durabilityContinuityHash: bytes(32, 0x84),
durabilityProfileHash: bytes(32, 0x85),
restoreEvidenceHeadSequence: 1n,
restoreEvidenceHeadHash: bytes(32, 0x86),
familyId: FAMILY.CELL,
operationId: OPERATION.CELL.PUT,
requestCommitment: bytes(32, 0x87),
resultCommitment: bytes(32, 0x88),
commitWalSequence: 9n,
commitWalHash: bytes(32, 0x89),
coveringFloorRevision: 10n,
coveringFloorHash: bytes(32, 0x8a),
coveringFloorWalSequence: 9n,
coveringFloorWalHash: bytes(32, 0x8b),
writerEpoch: 11n,
writerFenceTokenHash: bytes(32, 0x8c),
externalLeaseRevision: 12n,
witnessedUnixMillis: 13n,
witnessPublicKey: bytes(32, 0x8d),
signature: bytes(64, 0x8e)
}
const externalCommitWitnessBody = encodeCanonical(blindExternalCommitWitnessV1, externalCommitWitness)
const persistentRelayBinding = {
version: 1,
relayPublicKey: externalCommitWitness.relayPublicKey,
storeId: externalCommitWitness.storeId,
descriptorSequence: 14n,
descriptorHash: bytes(32, 0x8f),
durabilityProfileId: 2,
durabilityContinuityHash: externalCommitWitness.durabilityContinuityHash,
durabilityProfileHash: externalCommitWitness.durabilityProfileHash,
restoreEvidenceHeadSequence: externalCommitWitness.restoreEvidenceHeadSequence,
restoreEvidenceHeadHash: externalCommitWitness.restoreEvidenceHeadHash,
externalCommitWitness
}
const persistentRelayBindingBody = encodeCanonical(relayResultBindingV1, persistentRelayBinding)
const batchSignaturePayloadBody = encodeCanonical(batchGetSignaturePayloadV1, {
version: 1,
relayBinding: persistentRelayBinding,
requestNonce: bytes(32, 0x90),
requestCommitment: bytes(32, 0x91),
entriesCommitment: bytes(32, 0x92)
})
const inboxSignaturePayloadBody = encodeCanonical(inboxReadSignaturePayloadV1, {
version: 1,
relayBinding: persistentRelayBinding,
requestNonce: bytes(32, 0x93),
requestCommitment: bytes(32, 0x94),
snapshotRevision: 15n,
entriesCommitment: bytes(32, 0x95),
nextCursor: null
})
const durabilityContinuityBody = encodeCanonical(durabilityContinuityBindingV1, {
version: 1,
profileId: 2,
externalJournalId: bytes(32, 0xa1),
externalWitnessPublicKey: bytes(32, 0xa2),
externalJournalReplicationClass: 1,
externalJournalFailureGroupId: bytes(32, 0xa3),
restoreEvidenceFeedId: bytes(32, 0xa4)
})
const backupEncryptionProfile = {
version: 1,
algorithmId: 1,
keyDerivationId: 1,
recoveryKeyId: bytes(32, 0xa5),
keyEpoch: 1
}
const backupEncryptionProfileBody = encodeCanonical(blindBackupEncryptionProfileV1, backupEncryptionProfile)
const backupChunkManifest = {
version: 1,
backupId: bytes(32, 0xa6),
encryptionProfile: backupEncryptionProfile,
encryptionManifestHash: bytes(32, 0xa7),
entries: [{
path: b4a.from('store/manifest', 'ascii'),
fileOffset: 0n,
plaintextByteLength: 1024,
ciphertextByteLength: 1040,
chunkObjectId: bytes(32, 0xa8),
chunkSalt: bytes(32, 0xa9),
nonce: bytes(24, 0xaa),
ciphertextHash: bytes(32, 0xab)
}],
totalPlaintextByteLength: 1024n,
totalCiphertextByteLength: 1040n
}
const backupChunkManifestBody = encodeCanonical(blindBackupChunkManifestV1, backupChunkManifest)
const backupManifest = {
version: 1,
relayPublicKey: bytes(32, 0xac),
storeId: bytes(32, 0xad),
externalJournalId: bytes(32, 0xae),
durabilityContinuityHash: bytes(32, 0xaf),
backupId: backupChunkManifest.backupId,
backupFailureGroupId: bytes(32, 0xb0),
storeManifestRevision: 1n,
storeManifestHash: bytes(32, 0xb1),
storeFormatHash: bytes(32, 0xb2),
coverageCutoffExternalUnixMillis: 1n,
coveredWalSequence: 2n,
coveredWalHash: bytes(32, 0xb3),
externalFloorRevision: 3n,
externalFloorHash: bytes(32, 0xb4),
externalCheckpointRevision: 4n,
externalCheckpointHash: bytes(32, 0xb5),
baseFloorRevision: 3n,
baseFloorHash: bytes(32, 0xb6),
controlSnapshotHash: bytes(32, 0xb7),
backupEncryptionProfileHash: bytes(32, 0xb8),
encryptionManifestHash: backupChunkManifest.encryptionManifestHash,
chunkManifestByteLength: BigInt(backupChunkManifestBody.byteLength),
chunkManifestHash: bytes(32, 0xb9),
totalPlaintextByteLength: 1024n,
totalCiphertextByteLength: 1040n,
restoreVerifierPublicKey: bytes(32, 0xba),
cleanRestoreEvidenceHash: bytes(32, 0xbb),
createdExternalUnixMillis: 100n,
restoreSupportExpiresUnixMillis: 200n,
witnessPublicKey: bytes(32, 0xbc),
signature: bytes(64, 0xbd)
}
const backupManifestBody = encodeCanonical(blindBackupManifestV1, backupManifest)
const cleanRestoreBody = encodeCanonical(blindCleanRestoreEvidenceV1, {
version: 1,
backupId: backupManifest.backupId,
backupCandidateCommitment: bytes(32, 0xbe),
restoredStoreManifestHash: bytes(32, 0xbf),
verifiedWalSequence: 2n,
verifiedWalHash: backupManifest.coveredWalHash,
verifiedExternalFloorRevision: 3n,
verifiedExternalFloorHash: backupManifest.externalFloorHash,
verifiedCheckpointRevision: 4n,
verifiedCheckpointHash: backupManifest.externalCheckpointHash,
scrubbedObjectCount: 5n,
scrubFailureCount: 0,
startedExternalUnixMillis: 101n,
completedExternalUnixMillis: 102n,
verifierPublicKey: backupManifest.restoreVerifierPublicKey,
signature: bytes(64, 0xc0)
})
const retentionTransitionBody = encodeCanonical(blindBackupRetentionTransitionV1, {
version: 1,
relayPublicKey: backupManifest.relayPublicKey,
storeId: backupManifest.storeId,
externalJournalId: backupManifest.externalJournalId,
durabilityContinuityHash: backupManifest.durabilityContinuityHash,
backupId: backupManifest.backupId,
backupManifestHash: bytes(32, 0xc1),
transitionRevision: 1n,
previousTransitionHash: null,
operation: 1,
supportExpiresUnixMillis: 200n,
replacementBackupId: null,
effectiveExternalTimeFloorMillis: 103n,
witnessPublicKey: backupManifest.witnessPublicKey,
signature: bytes(64, 0xc2)
})
const restoreIssued = 21600000n * 10n
const restoreHead = {
version: 1,
relayPublicKey: bytes(32, 0xc3),
storeId: bytes(32, 0xc4),
externalJournalId: bytes(32, 0xc5),
durabilityContinuityHash: bytes(32, 0xc6),
restoreEvidenceFeedId: bytes(32, 0xc7),
evidenceSequence: 1n,
previousEvidenceHeadHash: null,
currentBackupManifestHash: bytes(32, 0xc8),
currentRetentionTransitionHash: bytes(32, 0xc9),
currentCoveredWalSequence: 1n,
currentExternalFloorRevision: 1n,
currentChunkObjectCount: 1n,
currentAvailabilityAuditHash: bytes(32, 0xca),
currentSupportExpiresUnixMillis: restoreIssued + 1000n,
drillBackupManifestHash: bytes(32, 0xcb),
drillCleanRestoreEvidenceHash: bytes(32, 0xcc),
drillRetentionTransitionHash: bytes(32, 0xcd),
restoreDrillCompletedUnixMillis: restoreIssued - 1n,
drillSupportExpiresUnixMillis: restoreIssued + 1000n,
issuedExternalUnixMillis: restoreIssued,
expiresExternalUnixMillis: restoreIssued + 2000n,
issuedEpoch: 10,
witnessPublicKey: bytes(32, 0xce),
signature: bytes(64, 0xcf)
}
const restoreHeadBody = encodeCanonical(blindRestoreEvidenceHeadV1, restoreHead)
const restoreBundleBody = encodeCanonical(blindRestoreEvidenceBundleV1, {
version: 1,
heads: [restoreHead],
currentBackupManifestBytes: bytes(1, 1),
currentRetentionTransitionBytes: bytes(1, 2),
drillBackupManifestBytes: bytes(1, 3),
drillCleanRestoreEvidenceBytes: bytes(1, 4),
drillRetentionTransitionBytes: bytes(1, 5)
})
const cellPutOperationRow = OPERATION_PROFILE_ROWS.find(row =>
row.familyId === FAMILY.CELL && row.operationId === OPERATION.CELL.PUT)
const cellPutOperationProfile = encodeCanonical(operationProfileV1, cellPutOperationRow)
const invalidOperationDomain = b4a.from(cellPutOperationProfile)
invalidOperationDomain[20] = 0
invalidOperationDomain[21] = 104
const cellPutDomainEntry = encodeCanonical(domainRegistryEntryV1, {
...DOMAIN_REGISTRY[0],
exactAsciiBytes: b4a.from(DOMAIN_REGISTRY[0].exactAsciiBytes, 'ascii')
})
const invalidDomainPurpose = b4a.from(cellPutDomainEntry)
invalidDomainPurpose[2] = 2
const renewNotDueErrorProfile = encodeCanonical(errorProfileEntryV1, ERROR_PROFILE_ROWS[17])
const invalidErrorProfileRetryable = b4a.from(renewNotDueErrorProfile)
invalidErrorProfileRetryable[6] = 0
const cellPutCostRule = encodeCanonical(admissionCostRuleV1, { costClassRuleId: 1, ruleKind: 1 })
const publicOperationProfileVectors = [
['describe-get', FAMILY.DESCRIBE, OPERATION.DESCRIBE.GET],
['describe-challenge', FAMILY.DESCRIBE, OPERATION.DESCRIBE.CHALLENGE],
['describe-admission-parameters', FAMILY.DESCRIBE, OPERATION.DESCRIBE.ADMISSION_PARAMETERS],
['core-mirror', FAMILY.CORE, OPERATION.CORE.MIRROR],
['core-prove', FAMILY.CORE, OPERATION.CORE.PROVE],
['core-open-replication', FAMILY.CORE, OPERATION.CORE.OPEN_REPLICATION],
['forward-open', FAMILY.FORWARD, OPERATION.FORWARD.OPEN],
['forward-data', FAMILY.FORWARD, OPERATION.FORWARD.DATA],
['forward-window', FAMILY.FORWARD, OPERATION.FORWARD.WINDOW],
['forward-close', FAMILY.FORWARD, OPERATION.FORWARD.CLOSE]
].map(([name, familyId, operationId]) => {
const row = OPERATION_PROFILE_ROWS.find(row => row.familyId === familyId && row.operationId === operationId)
if (!row) throw new Error(`missing operation profile vector row: ${name}`)
return [`registry/${name}-operation-profile.bin`, encodeCanonical(operationProfileV1, row)]
})
function registryName (registry, id, label) {
const match = Object.entries(registry).find(([, value]) => value === id)
if (!match) throw new Error(`missing ${label} registry name for ${id}`)
return match[0].toLowerCase().replaceAll('_', '-')
}
const completeOperationProfileVectors = OPERATION_PROFILE_ROWS.map(row => {
const familyName = registryName(FAMILY, row.familyId, 'family')
const familyRegistryName = Object.entries(FAMILY).find(([, id]) => id === row.familyId)[0]
const operationName = registryName(OPERATION[familyRegistryName], row.operationId, 'operation')
const prefix = `${String(row.familyId).padStart(2, '0')}-${String(row.operationId).padStart(2, '0')}`
return [`registry/operations/${prefix}-${familyName}-${operationName}.bin`,
encodeCanonical(operationProfileV1, row)]
})
const releaseOperationProfile = {
schema: 'hiverelay.blind.release-operation-profile.v1',
profile: ABI_STATUS.profile,
advertisedOperationBits: ADVERTISED_OPERATION_BITS,
reservedOperationBits: RESERVED_OPERATION_BITS,
advertisedOperations: ADVERTISED_OPERATION_PROFILE_ROWS.map(({ familyId, operationId }) => ({ familyId, operationId })),
reservedOperations: RESERVED_OPERATION_PAIRS
}
const releaseOperationProfileBytes = b4a.from(JSON.stringify(releaseOperationProfile, null, 2) + '\n')
const completeDomainVectors = DOMAIN_REGISTRY.map(row => [
`registry/domains/${String(row.domainId).padStart(3, '0')}.bin`,
encodeCanonical(domainRegistryEntryV1, {
...row,
exactAsciiBytes: b4a.from(row.exactAsciiBytes, 'ascii')
})
])
const completeErrorVectors = ERROR_PROFILE_ROWS.map(row => [
`registry/errors/${String(row.code).padStart(2, '0')}.bin`,
encodeCanonical(errorProfileEntryV1, row)
])
const completeCostRuleVectors = ADMISSION_COST_RULES.map(row => [
`registry/admission-costs/${String(row.costClassRuleId).padStart(2, '0')}.bin`,
encodeCanonical(admissionCostRuleV1, row)
])
const completeWireSchemaVectors = wireSchemaCatalog.entries
.map(entry => {
const name = b4a.toString(entry.schemaName, 'ascii')
const prefix = String(entry.categoryLocalSchemaId).padStart(3, '0')
return [`registry/schemas/${prefix}-${name}.bin`, encodeCanonical(schemaCatalogEntryV1, entry)]
})
const wireSchemaCatalogVector = ['registry/wire-schema-catalog.bin',
encodeSchemaCatalog(wireSchemaCatalog.entries)]
const nonWireSchemaCatalogVectors = wireOnly
? []
: [
['registry/master-schema-catalog.bin', masterSchemaCatalog.entries],
['registry/evidence-schema-catalog.bin', masterSchemaCatalog.entries.filter(entry => entry.category === SCHEMA_CATEGORY.EVIDENCE)],
['registry/client-example-schema-catalog.bin', masterSchemaCatalog.entries.filter(entry => entry.category === SCHEMA_CATEGORY.CLIENT_EXAMPLE)],
['registry/internal-store-schema-catalog.bin', masterSchemaCatalog.entries.filter(entry => entry.category === SCHEMA_CATEGORY.INTERNAL_STORE)]
].map(([name, entries]) => [name, encodeSchemaCatalog(entries)])
const schemaCatalogVectors = [wireSchemaCatalogVector, ...nonWireSchemaCatalogVectors]
const walHeaderV2 = wireOnly
? null
: nonWireFixture('BlindWalHeaderV2', () => encodeCanonical(blindWalHeaderV2, {
magic: b4a.from('HRWL', 'ascii'),
walVersion: 2,
recordType: 9,
totalLength: 224 + 17,
walSequence: 1n,
transactionId: bytes(32, 0xc1),
virtualBucket: 0x1234,
mapGeneration: 1n,
writerFenceTokenHash: bytes(32, 0xc2),
payloadLength: 17,
previousWalHash: bytes(32, 0),
durabilityContinuityHash: bytes(32, 0xc3),
payloadHash: bytes(32, 0xc4)
}))
const controlStateSnapshotV1 = wireOnly
? null
: nonWireFixture('BlindControlStateSnapshotV1', () =>
encodeCanonical(blindControlStateSnapshotV1, {
version: 1,
relayPublicKey: bytes(32, 0xd1),
storeId: bytes(32, 0xd2),
durabilityContinuityHash: bytes(32, 0xd3),
walSequence: 9n,
walHash: bytes(32, 0xda),
entries: [
{
entryKind: 1,
key: b4a.from('spend/0001', 'ascii'),
value: b4a.from('committed', 'ascii')
},
{
entryKind: 6,
key: b4a.from('global/accounting', 'ascii'),
value: bytes(8, 0xa6)
},
{
entryKind: 8,
key: b4a.from('retry/0001', 'ascii'),
value: b4a.alloc(0)
}
]
}))
const localCheckpointV1 = wireOnly
? null
: nonWireFixture('BlindLocalCheckpointV1', () =>
encodeCanonical(blindLocalCheckpointV1, {
magic: b4a.from('HRBCKP01', 'ascii'),
checkpointVersion: 1,
relayPublicKey: bytes(32, 0xd1),
storeId: bytes(32, 0xd2),
durabilityProfileId: 1,
durabilityContinuityHash: bytes(32, 0xd3),
durabilityProfileHash: bytes(32, 0xd4),
formatMajor: 1,
formatMinor: 2,
storeFormatHash: bytes(32, 0xd5),
specHash: bytes(32, 0xd6),
abiHash: bytes(32, 0xd7),
mapGeneration: 1n,
bucketMapHash: bytes(32, 0xd8),
writerEpoch: 1n,
writerFenceTokenHash: bytes(32, 0xd9),
checkpointRevision: 1n,
previousCheckpointHash: null,
coveredWalSequence: 9n,
coveredWalHash: bytes(32, 0xda),
epochFloor: 10,
descriptorSequenceFloor: 2n,
descriptorHashFloor: bytes(32, 0xdb),
snapshotByteLength: BigInt(controlStateSnapshotV1.byteLength),
snapshotHash: controlSnapshotHash(controlStateSnapshotV1)
}))
const vectorFiles = [
['registry/release-operation-profile-v1.json', releaseOperationProfileBytes],
['dispatch/cell-get-request.bin', cellGet],
['dispatch/forward-data.bin', forwardData],
['invalid/dispatch-nonzero-flags.bin', invalidFlags],
['invalid/dispatch-unknown-operation.bin', invalidOperation],
['outer/cell-get-class-1.bin', outerCellGet],
['cell/put-class-1.bin', cellPutBody],
['cell/batch-get-result.bin', batchResultBody],
['inbox/append-class-1.bin', inboxAppendBody],
['inbox/read-result-empty.bin', inboxReadResultBody],
['describe/admission-profile.bin', admissionProfileBody],
['describe/admission-parameters.bin', admissionParametersBody],
['describe/dht-pointer.bin', dhtPointerBody],
['describe/external-journal-topology.bin', externalTopologyBody],
['describe/health-challenge.bin', healthChallengeBody],
['describe/health-result.bin', healthResultBody],
['describe/identity-transition.bin', identityTransitionBody],
['describe/ohttp-key-config.bin', ohttpKeyConfigBody],
['describe/schema-catalog-entry.bin', schemaCatalogBody],
['describe/service-descriptor.bin', serviceDescriptorBody],
['durability/external-commit-witness.bin', externalCommitWitnessBody],
['durability/relay-result-binding.bin', persistentRelayBindingBody],
['durability/batch-signature-payload.bin', batchSignaturePayloadBody],
['durability/inbox-signature-payload.bin', inboxSignaturePayloadBody],
['durability/continuity-binding.bin', durabilityContinuityBody],
['durability/backup-encryption-profile.bin', backupEncryptionProfileBody],
['durability/backup-chunk-manifest.bin', backupChunkManifestBody],
['durability/backup-manifest.bin', backupManifestBody],
['durability/clean-restore.bin', cleanRestoreBody],
['durability/retention-transition.bin', retentionTransitionBody],
['durability/restore-head.bin', restoreHeadBody],
['durability/restore-bundle.bin', restoreBundleBody],
['core/ack.bin', coreAckBody],
['core/mirror-request.bin', coreMirrorBody],
['core/serve-challenge.bin', coreServeChallengeBody],
['core/serve-result.bin', coreServeResultBody],
['forward/open.bin', forwardOpenBody],
['forward/open-result.bin', forwardOpenResultBody],
['forward/data-body.bin', forwardDataBody],
['forward/window.bin', forwardWindowBody],
['forward/close.bin', forwardCloseBody],
['forward/stream-chunk-class-1.bin', streamChunkBody],
['commitment/cell-put.bin', cellPutCommitment],
['commitment/inbox-read.bin', inboxReadCommitment],
['commitment/core-mirror.bin', coreMirrorCommitment],
['commitment/core-serve.bin', coreServeCommitment],
['commitment/forward-open.bin', forwardOpenCommitment],
['commitment/persistent-batch-get.bin', batchPersistentResultCommitment],
['registry/cell-put-operation-profile.bin', cellPutOperationProfile],
['registry/cell-put-domain.bin', cellPutDomainEntry],
['registry/renew-not-due-error-profile.bin', renewNotDueErrorProfile],
['registry/cell-put-cost-rule.bin', cellPutCostRule],
['store/control-state-snapshot-v1.bin', controlStateSnapshotV1],
['store/local-checkpoint-v1.bin', localCheckpointV1],
['store/wal-header-v2.bin', walHeaderV2],
...publicOperationProfileVectors,
...completeOperationProfileVectors,
...completeDomainVectors,
...completeErrorVectors,
...completeCostRuleVectors,
...completeWireSchemaVectors,
...schemaCatalogVectors,
['invalid/cell-get-unknown-class.bin', invalidGetClass],
['invalid/batch-get-duplicate-slots.bin', duplicateBatchSlots],
['invalid/batch-get-unknown-entry-tag.bin', invalidBatchTag],
['invalid/inbox-read-cursor-129.bin', invalidInboxCursor],
['invalid/operation-profile-wrong-domain-purpose.bin', invalidOperationDomain],
['invalid/domain-entry-wrong-purpose.bin', invalidDomainPurpose],
['invalid/error-profile-wrong-retryable.bin', invalidErrorProfileRetryable],
['invalid/stream-chunk-unknown-class.bin', invalidStreamClass]
]
const nonWireVectorPaths = new Set([
'registry/master-schema-catalog.bin',
'registry/evidence-schema-catalog.bin',
'registry/client-example-schema-catalog.bin',
'registry/internal-store-schema-catalog.bin'
])
const wireVectorFiles = vectorFiles.filter(([vectorPath]) =>
!vectorPath.startsWith('store/') && !nonWireVectorPaths.has(vectorPath))
for (const [name, bytes] of (wireOnly ? wireVectorFiles : vectorFiles)) {
emit(path.join('packages', 'blind-protocol', 'vectors', 'draft', name), bytes)
}
for (const [name, bytes] of wireVectorFiles) {
emit(path.join('packages', 'blind-protocol', 'vectors', name), bytes)
}
const vectorRoot = path.join(root, 'packages', 'blind-protocol', 'vectors')
const reservedNonWireRoots = new Set(['client-composition', 'draft', 'evidence', 'store'])
const actualWireVectorPaths = listedFiles(vectorRoot)
.filter(relative => !reservedNonWireRoots.has(relative.split('/')[0]))
.sort()
const expectedWireVectorPaths = wireVectorFiles.map(([vectorPath]) => vectorPath).sort()
if (actualWireVectorPaths.length !== expectedWireVectorPaths.length ||
actualWireVectorPaths.some((value, index) => value !== expectedWireVectorPaths[index])) {
throw new Error(`final WIRE vector directory contains missing or unmanifested package files: actual-only=${actualWireVectorPaths.filter(value => !expectedWireVectorPaths.includes(value)).join(',')} expected-only=${expectedWireVectorPaths.filter(value => !actualWireVectorPaths.includes(value)).join(',')}`)
}
const abiBytes = encodeWireAbiRegistry(wireSchemaCatalog.entries)
const vectorManifestBytes = encodeVectorManifest(
wireVectorFiles.map(([vectorPath, bytes]) => ({ path: vectorPath, bytes }))
)
const hashes = {
profile: ABI_STATUS.profile,
releaseReady: ABI_STATUS.releaseReady,
missingSchemaCount: ABI_STATUS.wireMissingSchemaNames.length,
specHash: b4a.toString(hashSpec(canonicalWireSpecBytes), 'hex'),
abiHash: b4a.toString(hashAbi(abiBytes), 'hex'),
vectorSetHash: b4a.toString(hashVectorSet(vectorManifestBytes), 'hex')
}
const wireAuthority = {
profile: ABI_STATUS.profile,
protocolFamily: 'hiverelay-blind',
protocolMajor: 1,
protocolMinor: 0,
specArtifact: 'docs/protocol/HIVERELAY-BLIND-WIRE-V1.md',
abiArtifact: 'packages/blind-protocol/hiverelay-blind-abi-v1.cenc',
vectorManifestArtifact: 'packages/blind-protocol/vector-manifest-v1.cenc',
specHash: hashes.specHash,
abiHash: hashes.abiHash,
vectorSetHash: hashes.vectorSetHash,
wireSchemaCount: ABI_STATUS.wireRequiredSchemaNames.length,
operationCount: ABI_STATUS.operationProfileStatus.requiredPairs.length,
advertisedOperationCount: ADVERTISED_OPERATION_PROFILE_ROWS.length,
reservedOperationCount: RESERVED_OPERATION_PAIRS.length,
advertisedOperationBits: ADVERTISED_OPERATION_BITS,
reservedOperationBits: RESERVED_OPERATION_BITS,
errorCount: ERROR_PROFILE_ROWS.length,
domainCount: DOMAIN_REGISTRY.length,
vectorCount: wireVectorFiles.length
}
const wireAuthorityBytes = b4a.from(JSON.stringify(wireAuthority, null, 2) + '\n')
const schemaCatalogNameHashesByCategory = Object.fromEntries(
Object.entries(SCHEMA_NAMES_BY_CATEGORY).map(([category, names]) => [
category,
names.map(name => b4a.toString(blake2b256(b4a.from(name, 'ascii')), 'hex'))
])
)
const schemaCatalogRuntimeAuthorityBytes = b4a.from(`/* eslint-disable */
// Generated by scripts/generate-blind-protocol-draft.mjs. Do not edit.
// This import-free table commits SchemaCatalogEntryV1 category/id positions
// without exposing category names or package-internal schema vocabulary.
export const SCHEMA_CATALOG_NAME_HASHES_BY_CATEGORY = Object.freeze(
Object.fromEntries(Object.entries(${JSON.stringify(schemaCatalogNameHashesByCategory, null, 2)})
.map(([category, hashes]) => [category, Object.freeze(hashes)]))
)
`)
const wireRuntimeAuthorityBytes = b4a.from(`/* eslint-disable */
// Generated by scripts/generate-blind-protocol-draft.mjs. Do not edit.
function deepFreeze (value) {
if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value
for (const child of Object.values(value)) deepFreeze(child)
return Object.freeze(value)
}
export const PROTOCOL = deepFreeze(${JSON.stringify(PROTOCOL, null, 2)})
export const FRAME_KIND = deepFreeze(${JSON.stringify(FRAME_KIND, null, 2)})
export const FAMILY = deepFreeze(${JSON.stringify(FAMILY, null, 2)})
export const FAMILY_ROUTES = deepFreeze(${JSON.stringify(FAMILY_ROUTES, null, 2)})
export const OPERATION = deepFreeze(${JSON.stringify(OPERATION, null, 2)})
export const TRANSPORT_ID = deepFreeze(${JSON.stringify(TRANSPORT_ID, null, 2)})
export const TRANSPORT_SUPPORT = deepFreeze(${JSON.stringify(TRANSPORT_SUPPORT, null, 2)})
export const ENDPOINT_LIMITS = deepFreeze(${JSON.stringify(ENDPOINT_LIMITS, null, 2)})
export const PUBLIC_PROFILE_LIMITS = deepFreeze(${JSON.stringify(PUBLIC_PROFILE_LIMITS, null, 2)})
export const ADMISSION_CONFORMANCE_CLASS = deepFreeze(${JSON.stringify(ADMISSION_CONFORMANCE_CLASS, null, 2)})
export const CELL_RECEIPT_RESULT = deepFreeze(${JSON.stringify(CELL_RECEIPT_RESULT, null, 2)})
export const INBOX_MANAGE_OPERATION = deepFreeze(${JSON.stringify(INBOX_MANAGE_OPERATION, null, 2)})
export const INBOX_APPEND_AUTH_MODE = deepFreeze(${JSON.stringify(INBOX_APPEND_AUTH_MODE, null, 2)})
export const INBOX_RECEIPT_RESULT = deepFreeze(${JSON.stringify(INBOX_RECEIPT_RESULT, null, 2)})
export const INBOX_APPEND_RESULT = deepFreeze(${JSON.stringify(INBOX_APPEND_RESULT, null, 2)})
export const CORE_ACK_RESULT = deepFreeze(${JSON.stringify(CORE_ACK_RESULT, null, 2)})
export const FORWARD_CLOSE_KIND = deepFreeze(${JSON.stringify(FORWARD_CLOSE_KIND, null, 2)})
export const STORE_LIFECYCLE_STATE = deepFreeze(${JSON.stringify(STORE_LIFECYCLE_STATE, null, 2)})
export const HEALTH_CLOCK_STATE = deepFreeze(${JSON.stringify(HEALTH_CLOCK_STATE, null, 2)})
export const HEALTH_INTEGRITY_STATE = deepFreeze(${JSON.stringify(HEALTH_INTEGRITY_STATE, null, 2)})
export const HEALTH_REBALANCE_STATE = deepFreeze(${JSON.stringify(HEALTH_REBALANCE_STATE, null, 2)})
export const STREAM_TRANSITION = deepFreeze(${JSON.stringify(STREAM_TRANSITION, null, 2)})
export const DOMAIN_PURPOSE = deepFreeze(${JSON.stringify(DOMAIN_PURPOSE, null, 2)})
export const DOMAIN_RECIPE = deepFreeze(${JSON.stringify(DOMAIN_RECIPE, null, 2)})
export const REQUEST_COMMITMENT_DOMAIN_ID = deepFreeze(${JSON.stringify(REQUEST_COMMITMENT_DOMAIN_ID, null, 2)})
export const RESULT_SIGNATURE_DOMAIN_ID = deepFreeze(${JSON.stringify(RESULT_SIGNATURE_DOMAIN_ID, null, 2)})
export const AUXILIARY_SIGNATURE_DOMAIN_ID = deepFreeze(${JSON.stringify(AUXILIARY_SIGNATURE_DOMAIN_ID, null, 2)})
export const ERROR_PROFILE_ID = deepFreeze(${JSON.stringify(ERROR_PROFILE_ID, null, 2)})
export const ERROR_RETRY_AFTER_MODE = deepFreeze(${JSON.stringify(ERROR_RETRY_AFTER_MODE, null, 2)})
export const DOMAIN_REGISTRY = deepFreeze(${JSON.stringify(DOMAIN_REGISTRY, null, 2)})
export const ADMISSION_COST_RULES = deepFreeze(${JSON.stringify(ADMISSION_COST_RULES, null, 2)})
export const ERROR_PROFILE_ROWS = deepFreeze(${JSON.stringify(ERROR_PROFILE_ROWS, null, 2)})
export const CELL_SIZE_CLASS = deepFreeze(${JSON.stringify(CELL_SIZE_CLASS, null, 2)})
export const INBOX_FRAME_CLASS = deepFreeze(${JSON.stringify(INBOX_FRAME_CLASS, null, 2)})
export const OUTER_CLASS = deepFreeze(${JSON.stringify(OUTER_CLASS, null, 2)})
export const STREAM_WIRE_CLASS = deepFreeze(${JSON.stringify(STREAM_WIRE_CLASS, null, 2)})
export const FORWARD_CIRCUIT_CLASS = deepFreeze(${JSON.stringify(FORWARD_CIRCUIT_CLASS, null, 2)})
export const CORE_SESSION_CLASS = deepFreeze(${JSON.stringify(CORE_SESSION_CLASS, null, 2)})
export const DISPATCH_LIMITS = deepFreeze(${JSON.stringify(DISPATCH_LIMITS, null, 2)})
export const OPERATION_PROFILE_ROWS = deepFreeze(${JSON.stringify(OPERATION_PROFILE_ROWS, null, 2)})
export const ADVERTISED_OPERATION_PROFILE_ROWS = deepFreeze(${JSON.stringify(ADVERTISED_OPERATION_PROFILE_ROWS, null, 2)})
export const RESERVED_OPERATION_PAIRS = deepFreeze(${JSON.stringify(RESERVED_OPERATION_PAIRS, null, 2)})
export const ADVERTISED_OPERATION_BITS = ${JSON.stringify(ADVERTISED_OPERATION_BITS)}
export const RESERVED_OPERATION_BITS = ${JSON.stringify(RESERVED_OPERATION_BITS)}
export const CLOCK_UNSAFE_OPERATION_BITS = ${JSON.stringify(CLOCK_UNSAFE_OPERATION_BITS)}
export function domainRegistryEntry (domainId) {
return DOMAIN_REGISTRY.find(entry => entry.domainId === domainId) || null
}
export function admissionCostRule (costClassRuleId) {
return ADMISSION_COST_RULES.find(entry => entry.costClassRuleId === costClassRuleId) || null
}
export function errorProfileEntry (errorProfileId, code) {
return ERROR_PROFILE_ROWS.find(entry =>
entry.errorProfileId === errorProfileId && entry.code === code) || null
}
export function operationOrdinal (familyId, operationId) {
return OPERATION_PROFILE_ROWS.findIndex(row =>
row.familyId === familyId && row.operationId === operationId)
}
export function operationBit (familyId, operationId) {
const ordinal = operationOrdinal(familyId, operationId)
return ordinal < 0 ? 0 : 1 << ordinal
}
export function operationProfile (familyId, operationId) {
return OPERATION_PROFILE_ROWS.find(row =>
row.familyId === familyId && row.operationId === operationId) || null
}
export function isKnownOperation (familyId, operationId) {
return operationProfile(familyId, operationId) !== null
}
export function isReservedOperation (familyId, operationId) {
return RESERVED_OPERATION_PAIRS.some(row => row.familyId === familyId && row.operationId === operationId)
}
export function isAdvertisedOperation (familyId, operationId) {
return isKnownOperation(familyId, operationId) && !isReservedOperation(familyId, operationId)
}
export function assertAdvertisedOperation (familyId, operationId) {
const profile = operationProfile(familyId, operationId)
if (profile && !isReservedOperation(familyId, operationId)) return profile
const error = new Error('operation is unknown or reserved by the active release profile')
error.code = 'UNSUPPORTED_OPERATION'
throw error
}
export function familyName (familyId) {
return Object.entries(FAMILY).find(([, id]) => id === familyId)?.[0] || null
}
export function routeForFamily (familyId) {
return FAMILY_ROUTES[familyId] || null
}
export const WIRE_RUNTIME_AUTHORITY = deepFreeze(${JSON.stringify(wireAuthority, null, 2)})
export const WIRE_RUNTIME_AUTHORITY_STATUS = deepFreeze({
profile: WIRE_RUNTIME_AUTHORITY.profile,
specHash: WIRE_RUNTIME_AUTHORITY.specHash,
abiHash: WIRE_RUNTIME_AUTHORITY.abiHash,
vectorSetHash: WIRE_RUNTIME_AUTHORITY.vectorSetHash,
wireSchemaCount: WIRE_RUNTIME_AUTHORITY.wireSchemaCount,
operationCount: WIRE_RUNTIME_AUTHORITY.operationCount,
advertisedOperationCount: WIRE_RUNTIME_AUTHORITY.advertisedOperationCount,
reservedOperationCount: WIRE_RUNTIME_AUTHORITY.reservedOperationCount,
advertisedOperationBits: WIRE_RUNTIME_AUTHORITY.advertisedOperationBits,
reservedOperationBits: WIRE_RUNTIME_AUTHORITY.reservedOperationBits,
errorCount: WIRE_RUNTIME_AUTHORITY.errorCount,
domainCount: WIRE_RUNTIME_AUTHORITY.domainCount,
vectorCount: WIRE_RUNTIME_AUTHORITY.vectorCount,
releaseBlockers: ${JSON.stringify(ABI_STATUS.releaseBlockers)},
releaseReady: ${JSON.stringify(ABI_STATUS.releaseReady)}
})
export function assertWireAuthorityReady () {
if (WIRE_RUNTIME_AUTHORITY_STATUS.releaseReady &&
WIRE_RUNTIME_AUTHORITY_STATUS.releaseBlockers.length === 0) {
return WIRE_RUNTIME_AUTHORITY_STATUS
}
const error = new Error('blind public WIRE authority is incomplete')
error.code = 'BLIND_WIRE_AUTHORITY_INCOMPLETE'
error.releaseBlockers = [...WIRE_RUNTIME_AUTHORITY_STATUS.releaseBlockers]
throw error
}
export const assertReleaseReady = assertWireAuthorityReady
`)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-abi-v1.cenc'), abiBytes)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-abi-v1.draft.cenc'), abiBytes)
emit(path.join('packages', 'blind-protocol', 'vector-manifest-v1.cenc'), vectorManifestBytes)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-wire-authority-v1.json'), wireAuthorityBytes)
emit(path.join('packages', 'blind-protocol', 'schema-catalog-runtime-authority.js'),
schemaCatalogRuntimeAuthorityBytes)
emit(path.join('packages', 'blind-protocol', 'wire-runtime-authority.js'), wireRuntimeAuthorityBytes)
emit(path.join('packages', 'blind-protocol', 'vectors', 'draft', 'vector-manifest-v1.draft.cenc'), vectorManifestBytes)
if (!wireOnly) {
const evidenceRegistryBytes = schemaCatalogVectors[2][1]
const clientExampleRegistryBytes = schemaCatalogVectors[3][1]
const storeRegistryBytes = schemaCatalogVectors[4][1]
const storeFormatAuthorityBytes = encodeStoreFormatAuthorityV1(
storeRegistryBytes,
STORE_FORMAT_AUTHORITY_V1
)
const evidenceVectorManifestBytes = encodeVectorManifest([
{ path: 'registry/evidence-schema-catalog.bin', bytes: evidenceRegistryBytes }
])
const storeVectorManifestBytes = encodeVectorManifest([
{ path: 'registry/internal-store-schema-catalog.bin', bytes: storeRegistryBytes },
...vectorFiles.filter(([vectorPath]) => vectorPath.startsWith('store/'))
.map(([vectorPath, bytes]) => ({ path: vectorPath, bytes }))
])
const completeHashes = {
...hashes,
evidenceFormatHash: b4a.toString(hashEvidenceFormat(evidenceRegistryBytes), 'hex'),
evidenceVectorSetHash: b4a.toString(hashEvidenceVectorSet(evidenceVectorManifestBytes), 'hex'),
storeFormatHash: b4a.toString(hashStoreFormat(storeFormatAuthorityBytes), 'hex'),
storeVectorSetHash: b4a.toString(hashStoreVectorSet(storeVectorManifestBytes), 'hex')
}
const privateIpcAuthority = JSON.parse(fs.readFileSync(path.join(root,
'packages', 'blind-ipc', 'hiverelay-blind-private-ipc-authority-v1.json'), 'utf8'))
const closure = {
schema: 'hiverelay.blind.release-closure.v1',
profile: {
artifact: 'docs/protocol/HIVERELAY-BLIND-RC1-PROFILE-BINDING-V1.json',
...profileBinding
},
wire: {
artifact: 'packages/blind-protocol/hiverelay-blind-wire-authority-v1.json',
specHash: completeHashes.specHash,
abiHash: completeHashes.abiHash,
vectorSetHash: completeHashes.vectorSetHash
},
implementation: {
artifact: 'docs/protocol/BLIND-SUBSTRATE-IMPLEMENTATION-SPEC.md',
implementationSpecHash: b4a.toString(hashImplementationSpec(canonicalImplementationSpecBytes), 'hex')
},
store: {
artifact: 'packages/blind-protocol/hiverelay-blind-store-format-authority-v1.draft.cenc',
storeFormatHash: completeHashes.storeFormatHash,
storeVectorSetHash: completeHashes.storeVectorSetHash
},
privateIpc: {
artifact: 'packages/blind-ipc/hiverelay-blind-private-ipc-authority-v1.json',
importedWireAbiHash: privateIpcAuthority.importedWireAbiHash,
privateIpcFormatHash: privateIpcAuthority.privateIpcFormatHash,
privateIpcVectorSetHash: privateIpcAuthority.privateIpcVectorSetHash
},
decisions: {
artifact: 'docs/protocol/HIVERELAY-BLIND-OWNER-DECISIONS-V1.json',
decisionsHash: b4a.toString(hashOwnerDecisions(canonicalOwnerDecisionsBytes), 'hex'),
ids: ownerDecisions.decisions.map(decision => decision.id)
},
operationProfile: {
advertisedOperationBits: ADVERTISED_OPERATION_BITS,
advertisedOperationCount: ADVERTISED_OPERATION_PROFILE_ROWS.length,
reservedOperationBits: RESERVED_OPERATION_BITS,
reservedOperationCount: RESERVED_OPERATION_PAIRS.length,
reservedOperations: RESERVED_OPERATION_PAIRS
},
compatibilityBlockers: [
'BLIND_DAEMON_MUST_ENFORCE_RESERVED_OPERATION_PROFILE',
'BLIND_EDGE_MUST_ENFORCE_RESERVED_OPERATION_PROFILE',
'BLIND_STORAGE_MUST_MIGRATE_TO_FORMAT_1_2_DETERMINISTIC_BUCKETS',
'PEERIT_MUST_CONSUME_THIS_CLOSURE'
],
contractReady: true,
productReleaseReady: false
}
const closurePayloadBytes = b4a.from(JSON.stringify(closure, null, 2) + '\n')
const closureBytes = b4a.from(JSON.stringify({
...closure,
closureHash: b4a.toString(hashReleaseClosure(closurePayloadBytes), 'hex')
}, null, 2) + '\n')
const hashesBytes = b4a.from(JSON.stringify(completeHashes, null, 2) + '\n')
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-schema-catalog-v1.draft.cenc'),
encodeSchemaCatalog(masterSchemaCatalog.entries))
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-evidence-v1.draft.cenc'), evidenceRegistryBytes)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-client-example-v1.draft.cenc'), clientExampleRegistryBytes)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-store-v1.draft.cenc'), storeRegistryBytes)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-store-format-authority-v1.draft.cenc'),
storeFormatAuthorityBytes)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-evidence-schema-catalog-v1.draft.cenc'),
evidenceRegistryBytes)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-client-example-schema-catalog-v1.draft.cenc'),
clientExampleRegistryBytes)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-store-schema-catalog-v1.draft.cenc'),
storeRegistryBytes)
emit(path.join('packages', 'blind-protocol', 'vectors', 'evidence', 'vector-manifest-v1.draft.cenc'),
evidenceVectorManifestBytes)
emit(path.join('packages', 'blind-protocol', 'vectors', 'store', 'vector-manifest-v1.draft.cenc'),
storeVectorManifestBytes)
emit(path.join('packages', 'blind-protocol', 'vectors', 'draft', 'hashes.draft.json'), hashesBytes)
emit(path.join('packages', 'blind-protocol', 'hiverelay-blind-release-closure-v1.json'), closureBytes)
}
if (check) {
process.stdout.write(`blind public WIRE authority verified (${wireVectorFiles.length} WIRE vectors; ${masterInventoryAudit.catalogSchemaCount} classified schemas; wireReleaseReady=${ABI_STATUS.releaseReady})\n`)
} else {
process.stdout.write(`blind public WIRE authority generated (${wireVectorFiles.length} WIRE vectors; ${masterInventoryAudit.catalogSchemaCount} classified schemas; wireReleaseReady=${ABI_STATUS.releaseReady})\n`)
}