OverviewFilesCommitsIssuesDocsReleasesPeers

P2P-Hiverelay / packages / blind-daemon / test / coordinator-fixtures.js

149 lines · javascript ref:
import fs from 'node:fs'
import b4a from 'b4a'
import {
  STORE_LIFECYCLE_STATE,
  admissionParametersHash,
  admissionParametersV1,
  blindServiceDescriptorV1,
  blindStoreManifestV1,
  decodeCanonical,
  durabilityContinuityBindingV1,
  durabilityContinuityHash,
  durabilityProfileHash,
  durabilityProfileV1,
  encodeCanonical,
  serviceDescriptorHash
} from '@hiverelay/blind-protocol'
import { ADVERTISED_OPERATION_BITS } from '@hiverelay/blind-protocol/wire-runtime-authority'

const descriptorVector = fs.readFileSync(new URL(
  '../../blind-protocol/vectors/draft/describe/service-descriptor.bin', import.meta.url))
const parameterVector = fs.readFileSync(new URL(
  '../../blind-protocol/vectors/draft/describe/admission-parameters.bin', import.meta.url))

export const fixtureBytes = (length, value) => b4a.alloc(length, value)

function clone (codec, value) {
  return decodeCanonical(codec, encodeCanonical(codec, value), { copyBytes: true })
}

export function bindDurability (descriptor) {
  descriptor.durabilityProfileHash = durabilityProfileHash(
    encodeCanonical(durabilityProfileV1, descriptor.durability))
  descriptor.durabilityContinuityHash = durabilityContinuityHash(
    encodeCanonical(durabilityContinuityBindingV1, {
      version: 1,
      profileId: descriptor.durability.profileId,
      externalJournalId: descriptor.durability.externalJournalId,
      externalWitnessPublicKey: descriptor.durability.externalWitnessPublicKey,
      externalJournalReplicationClass: descriptor.durability.externalJournalReplicationClass,
      externalJournalFailureGroupId: descriptor.durability.externalJournalFailureGroupId,
      restoreEvidenceFeedId: descriptor.durability.restoreEvidenceFeedId
    }))
  return descriptor
}

export function descriptorValue (overrides = {}) {
  const value = decodeCanonical(blindServiceDescriptorV1, descriptorVector, { copyBytes: true })
  value.endpoints[0].envelopeClassBits = 0x7e
  value.enabledOperationBits = ADVERTISED_OPERATION_BITS
  Object.assign(value, overrides)
  bindDurability(value)
  return value
}

export function descriptorBytes (overrides = {}) {
  return encodeCanonical(blindServiceDescriptorV1, descriptorValue(overrides))
}

export function successorValue (snapshot, overrides = {}) {
  const previous = snapshot.descriptor
  const next = clone(blindServiceDescriptorV1, previous)
  next.descriptorSequence = previous.descriptorSequence + 1n
  next.previousDescriptorHash = b4a.from(snapshot.hash)
  next.issuedEpoch = previous.issuedEpoch + 1
  next.expiresEpoch = previous.expiresEpoch + 1
  next.descriptorNonce = fixtureBytes(32, Number(0x30n + next.descriptorSequence))
  next.signature = fixtureBytes(64, Number(0x50n + next.descriptorSequence))
  Object.assign(next, overrides)
  bindDurability(next)
  return next
}

export function successorBytes (snapshot, overrides = {}) {
  return encodeCanonical(blindServiceDescriptorV1, successorValue(snapshot, overrides))
}

export function parameterValue (relayPublicKey, overrides = {}) {
  const value = decodeCanonical(admissionParametersV1, parameterVector, { copyBytes: true })
  value.relayPublicKey = b4a.from(relayPublicKey)
  Object.assign(value, overrides)
  return value
}

export function parameterBytes (relayPublicKey, overrides = {}) {
  return encodeCanonical(admissionParametersV1, parameterValue(relayPublicKey, overrides))
}

export function descriptorAndParameters (overrides = {}) {
  const relayPublicKey = overrides.relayPublicKey || fixtureBytes(32, 0x71)
  const parameters = parameterBytes(relayPublicKey, overrides.parameters || {})
  const base = descriptorValue({
    relayPublicKey,
    ...(overrides.descriptor || {})
  })
  base.admissionProfiles[0].parameterHash = admissionParametersHash(parameters)
  base.admissionProfiles[0].profileId = 7
  base.admissionProfiles[0].schemeId = 9
  base.admissionProfiles[0].conformanceClass = 1
  base.admissionProfiles[0].roleBits = 1
  bindDurability(base)
  return { descriptor: encodeCanonical(blindServiceDescriptorV1, base), parameters }
}

export function manifestBytes (snapshot, overrides = {}) {
  const descriptor = snapshot.descriptor
  const zero = fixtureBytes(32, 0)
  return encodeCanonical(blindStoreManifestV1, {
    magic: b4a.from('HRBLIND1', 'ascii'),
    manifestVersion: 1,
    storeId: b4a.from(descriptor.storeId),
    relayPublicKey: b4a.from(descriptor.relayPublicKey),
    durabilityProfileId: descriptor.durability.profileId,
    durabilityContinuityHash: b4a.from(descriptor.durabilityContinuityHash),
    durabilityProfileHash: b4a.from(descriptor.durabilityProfileHash),
    formatMajor: descriptor.durability.storeFormatMajor,
    formatMinor: descriptor.durability.storeFormatMinor,
    storeFormatHash: b4a.from(descriptor.durability.storeFormatHash),
    specHash: b4a.from(descriptor.build.specHash),
    abiHash: b4a.from(descriptor.build.abiHash),
    mapGeneration: 1n,
    bucketMapHash: fixtureBytes(32, 0x81),
    checkpointWalSequence: 1n,
    checkpointHash: fixtureBytes(32, 0x82),
    epochFloor: descriptor.issuedEpoch,
    writerEpoch: 1n,
    writerFenceTokenHash: fixtureBytes(32, 0x83),
    externalLeaseRevision: 0n,
    externalJournalId: zero,
    externalWitnessPublicKey: zero,
    restoreEvidenceFeedId: zero,
    lastAckWalSequence: 0n,
    lastAckWalHash: zero,
    externalCheckpointRevision: 0n,
    externalCheckpointHash: zero,
    descriptorSequenceFloor: descriptor.descriptorSequence,
    descriptorHashFloor: serviceDescriptorHash(snapshot.canonicalBytes),
    migrationState: 0,
    sourceFormatMajor: 0,
    targetFormatMajor: 0,
    migrationCursorHash: zero,
    previousManifestHash: null,
    manifestRevision: 0n,
    mac: fixtureBytes(32, 0x84),
    ...overrides
  })
}

export { STORE_LIFECYCLE_STATE }