OverviewFilesCommitsIssuesDocsReleasesPeers

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

237 lines · javascript ref:
import b4a from 'b4a'
import {
  DISPATCH_LIMITS,
  FORWARD_CIRCUIT_CLASS,
  STREAM_WIRE_CLASS,
  forwardRouteScopeGenesisHash,
  forwardRouteScopeHopHash
} from '@hiverelay/blind-protocol'

const KiB = 1024
const MiB = 1024 * KiB

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

export function fixtureAdmission (seed = 0xa0) {
  return {
    profileId: 7,
    schemeId: 9,
    parameterHash: fixtureBytes(32, seed),
    token: fixtureBytes(8, seed + 1)
  }
}

export function fixtureReadiness (overrides = {}) {
  return {
    descriptorSequence: 9n,
    descriptorHash: fixtureBytes(32, 0x22),
    expiresMonotonicMillis: 1_000_000n,
    ...overrides
  }
}

export function fixtureRelayBinding (relayPublicKey, overrides = {}) {
  return {
    version: 1,
    relayPublicKey: b4a.from(relayPublicKey),
    storeId: fixtureBytes(32, 0x71),
    descriptorSequence: 9n,
    descriptorHash: fixtureBytes(32, 0x22),
    durabilityProfileId: 1,
    durabilityContinuityHash: fixtureBytes(32, 0x72),
    durabilityProfileHash: fixtureBytes(32, 0x73),
    restoreEvidenceHeadSequence: 0n,
    restoreEvidenceHeadHash: fixtureBytes(32, 0),
    externalCommitWitness: null,
    ...overrides
  }
}

export function fixtureCoreOpen (wireProfileHash, overrides = {}) {
  return {
    version: 1,
    wireProfileHash: b4a.from(wireProfileHash),
    sessionClass: 1,
    controlChannelId: 17n,
    parentChannelBinding: fixtureBytes(32, 0x33),
    clientNonce: fixtureBytes(32, 0x34),
    admission: fixtureAdmission(),
    ...overrides
  }
}

export function fixtureCoreResult (relayPublicKey, fields, overrides = {}) {
  return {
    version: 1,
    relayBinding: fixtureRelayBinding(relayPublicKey),
    wireProfileHash: b4a.from(fields.request.wireProfileHash),
    sessionClass: fields.request.sessionClass,
    controlChannelId: fields.request.controlChannelId,
    parentChannelBinding: b4a.from(fields.request.parentChannelBinding),
    streamId: fields.streamId,
    maxSessionBytes: fields.maxSessionBytes,
    idleMillis: fields.idleMillis,
    lifetimeMillis: fields.lifetimeMillis,
    openedAtEpoch: fields.openedAtEpoch,
    requestNonce: b4a.from(fields.request.clientNonce),
    requestCommitment: b4a.from(fields.requestCommitment),
    signature: fixtureBytes(64, 0x35),
    ...overrides
  }
}

export function fixtureForwardOpen (overrides = {}) {
  return {
    version: 1,
    routeId: fixtureBytes(16, 0x41),
    nextDescriptorSequence: 10n,
    nextDescriptorHash: fixtureBytes(32, 0x42),
    requestedWireClass: 1,
    circuitClass: 1,
    circuitNonce: fixtureBytes(32, 0x43),
    parentRouteScopeHash: fixtureBytes(32, 0),
    hopAdmission: fixtureAdmission(0xb0),
    innerHandshake: fixtureBytes(32, 0x44),
    ...overrides
  }
}

export function fixtureRoute (relayPublicKey, request, overrides = {}) {
  return {
    version: 1,
    routeKind: 2,
    routeId: b4a.from(request.routeId),
    previousRelayKey: b4a.from(relayPublicKey),
    previousEndpointId: 1,
    nextRelayKey: fixtureBytes(32, 0x51),
    nextDescriptorSequence: request.nextDescriptorSequence,
    nextDescriptorHash: b4a.from(request.nextDescriptorHash),
    nextEndpointId: 2,
    envelopeClassBits: 0,
    wireClassBits: 0x0e,
    maxCanonicalDispatchBytes: DISPATCH_LIMITS.MAX_WIRE_BYTES,
    maxEncapsulatedRequestBytes: 0,
    maxOpenBytes: 128 * KiB,
    maxCircuitBytes: 256n * BigInt(MiB),
    maxConcurrentStreams: 16,
    maxRelayCount: 4,
    hopAdmissionProfileId: 7,
    issuedEpoch: 20,
    expiresEpoch: 24,
    routeNonce: fixtureBytes(32, 0x52),
    previousSignature: fixtureBytes(64, 0x53),
    ...overrides
  }
}

export function fixtureRouteScope (relayPublicKey, route, requestCommitment, request, overrides = {}) {
  const root = {
    version: 1,
    rootRouteId: b4a.from(route.routeId),
    rootCircuitNonce: b4a.from(request.circuitNonce),
    rootRequestCommitment: b4a.from(requestCommitment),
    maxRelayCount: route.maxRelayCount,
    expiresEpoch: route.expiresEpoch
  }
  const genesisHash = forwardRouteScopeGenesisHash(root)
  const hop = {
    hopIndex: 0,
    relayPublicKey: b4a.from(relayPublicKey),
    descriptorSequence: 9n,
    descriptorHash: fixtureBytes(32, 0x22),
    previousScopeHash: fixtureBytes(32, 0)
  }
  hop.scopeHash = forwardRouteScopeHopHash({ ...hop, previousScopeHash: genesisHash })
  hop.relaySignature = fixtureBytes(64, 0x60)
  return { ...root, hops: [hop], ...overrides }
}

export function fixtureHopOpen (fields, overrides = {}) {
  const routeScope = fields.routeScope || fixtureRouteScope(fields.route.previousRelayKey,
    fields.route, fields.clientRequestCommitment, fields.request)
  return {
    version: 1,
    route: fields.route,
    routeScope,
    previousDescriptorSequence: 9n,
    previousDescriptorHash: fixtureBytes(32, 0x22),
    circuitNonce: b4a.from(fields.request.circuitNonce),
    requestedWireClass: fields.request.requestedWireClass,
    circuitClass: fields.request.circuitClass,
    grantedInitialWindow: fields.grantedInitialWindow,
    maxDataBytes: fields.maxDataBytes,
    maxCircuitBytes: fields.maxCircuitBytes,
    idleMillis: fields.idleMillis,
    lifetimeMillis: fields.lifetimeMillis,
    clientRequestCommitment: b4a.from(fields.clientRequestCommitment),
    handshakeFlight1: fixtureBytes(32, 0x54),
    forwarderSignature: fixtureBytes(64, 0x55),
    ...overrides
  }
}

export function fixtureHopAccept (relayPublicKey, route, request, overrides = {}) {
  const limits = FORWARD_CIRCUIT_CLASS[request.circuitClass]
  const openedAtEpoch = 100
  return {
    version: 1,
    previousRelayKey: b4a.from(relayPublicKey),
    previousDescriptorSequence: 9n,
    previousDescriptorHash: fixtureBytes(32, 0x22),
    nextRelayKey: b4a.from(route.nextRelayKey),
    nextDescriptorSequence: route.nextDescriptorSequence,
    nextDescriptorHash: b4a.from(route.nextDescriptorHash),
    nextRelayBinding: fixtureRelayBinding(route.nextRelayKey, {
      descriptorSequence: route.nextDescriptorSequence,
      descriptorHash: b4a.from(route.nextDescriptorHash)
    }),
    routeId: b4a.from(route.routeId),
    circuitNonce: b4a.from(request.circuitNonce),
    nextStreamId: 91n,
    grantedWireClass: request.requestedWireClass,
    circuitClass: request.circuitClass,
    grantedInitialWindow: limits.grantedInitialWindow,
    maxDataBytes: STREAM_WIRE_CLASS[request.requestedWireClass],
    maxCircuitBytes: BigInt(limits.maxCircuitBytes),
    idleMillis: limits.idleMillis,
    lifetimeMillis: limits.lifetimeMillis,
    openedAtEpoch,
    hopOpenCommitment: fixtureBytes(32, 0x56),
    acceptedRouteScopeHash: fixtureBytes(32, 0x5a),
    acceptedRelayCount: 1,
    handshakeFlight2: fixtureBytes(96, 0x57),
    nextSignature: fixtureBytes(64, 0x58),
    ...overrides
  }
}

export function fixtureForwardResult (relayPublicKey, fields, overrides = {}) {
  const accept = fields.hopAccept
  return {
    version: 1,
    relayBinding: fixtureRelayBinding(relayPublicKey, {
      descriptorSequence: accept.previousDescriptorSequence,
      descriptorHash: b4a.from(accept.previousDescriptorHash)
    }),
    routeId: b4a.from(fields.request.routeId),
    nextDescriptorSequence: fields.request.nextDescriptorSequence,
    nextDescriptorHash: b4a.from(fields.request.nextDescriptorHash),
    circuitNonce: b4a.from(fields.request.circuitNonce),
    grantedWireClass: fields.request.requestedWireClass,
    circuitClass: fields.request.circuitClass,
    streamId: fields.callerStreamId,
    grantedInitialWindow: fields.grantedInitialWindow,
    maxDataBytes: fields.maxDataBytes,
    maxCircuitBytes: fields.maxCircuitBytes,
    idleMillis: fields.idleMillis,
    lifetimeMillis: fields.lifetimeMillis,
    openedAtEpoch: accept.openedAtEpoch,
    requestCommitment: b4a.from(fields.requestCommitment),
    acceptedRouteScopeHash: b4a.from(accept.acceptedRouteScopeHash),
    acceptedRelayCount: accept.acceptedRelayCount,
    nextHopAccept: accept,
    signature: fixtureBytes(64, 0x59),
    ...overrides
  }
}