FlatBuffer-scheman

TensorCash använder tre FlatBuffers-scheman som binärt kontrakt för två gränssnitt: anropsinnehållet för slutpunkterna /v1/verify/* i Verifier REST-API, och ZMQ-kanalen PUSH/PULL mellan nod och verifierare. Sidan ZMQ-ämnen beskriver det separata pub/sub-gränssnittet som ärvts från Bitcoin Core.

Varje fil publiceras oförändrad under /schemas/ för flatc, och som JSON Schema under /schemas/json/ för verktyg som föredrar det. Samma JSON-scheman fogas in i verifierarens OpenAPI-components.schemas, som typar JSON-spegelslutpunkterna (/v1/verify/*/json).

3 filer · 12 typer

proof.fbs

Rottyp Proof

Inferensbeviset. Det bär proof-of-work-vittnet (target, VDF, blockhash), samplingsparametrarna (temperature, top_p, top_k) samt de modell- och tokenutskrifter som en verifierare kör om. Miner-pipelinen och ZMQ-kanalen mellan nod och verifierare använder samma överföringsformat.

Deklarerar Proof, FloatArray, UIntArray

// proof.fbs
// FlatBuffers schema for PoW proof with C++ and Python compatibility
namespace proof;

// Wrapper for 1D float arrays (for 2D tensors)
table FloatArray {
  values:[float];      // float32 vector
}

// Wrapper for 1D uint arrays
table UIntArray {
  values:[uint32];     // uint32 vector
}

// Root table representing a single proof
table Proof {
  version:uint8;                 // schema version identifier
  tick:uint64;                 // monotonic tick count
  timestamp:uint64;            // UNIX timestamp

  // Binary fields as raw bytes (more compact than hex strings)
  target:[ubyte];              // target bytes
  vdf:[ubyte];                 // VDF output bytes
  hash:[ubyte];                // proof hash bytes
  block_hash:[ubyte];                // prior block hash bytes
  header_prefix:[ubyte];       // optional, if provided

  is_solution:bool;
  model_identifier : string;    // e.g. "gpt-4"
  compute_precision: string;    // e.g. "fp16"
  ipfs_cid         : string;    // e.g. "cdcdcd"
  extra_flags      : string;    // e.g. ""
  temperature      : float;     // sampling temperature
  top_p            : float;     // nucleus‐sampling p
  top_k            : uint32;    // top‐k sampling
  repetition_penalty: float;    // repetition penalty
  
  // 1D arrays
  chosen_tokens:[uint32];      // selected token IDs
  chosen_probs:[float];        // probabilities
  sampling_u:[float];          // random sampling values
  softmax_normalizers:[float]; // softmax normalizers
  prompt_tokens:[uint32];      // prompt token IDs
  pad_mask:[bool];           // pad mask (0/1)

  // 2D tensors implemented via wrapper tables
  topk_logits:[FloatArray];    // vector of FloatArray
  topk_indices:[UIntArray];    // vector of UIntArray
  logsumexp_stats:[FloatArray]; // vector of FloatArray (2D tensor)
}

root_type Proof;
file_identifier "PROF";  // optional 4-byte identifier

validation.fbs

Rottyp ValidationRequest

Verifierarens kuvert för anrop och svar. De fem ValidationType-värdena motsvarar nivåerna i verifierarens kontrollstege (Quick, Quick_Smell, Full, Model, Challenge), och ResponseValue listar de 13 utfall som verifieraren returnerar. ValidationRequest är innehållet i varje binär /v1/verify/*-slutpunkt och speglas ett till ett av /v1/verify/*/json.

Deklarerar ValidationType, ResponseValue, ValidationUnion, BlockValidation, ModelValidation, ValidationRequest, ValidationResponse

include "proof.fbs";

namespace proof;

enum ValidationType : uint8 {
  Quick = 0,
  Quick_Smell = 1,
  Full = 2,
  Model = 3,
  Challenge = 4,
  // Audit/logits verification: sequence + logits replay only, no block
  // sanity and no mining parameter envelope. Append-only addition —
  // wire-compatible with older readers (they warn on the unknown value).
  Logits = 5,
  // Batched ADVISORY triage of N shares in one request. NOT consensus: the
  // worker answers "which of these are worth a full verify", never a verdict.
  // Append-only addition — wire-compatible with older readers.
  BatchTriage = 6
}

enum ResponseValue : uint8 {
  Quick_OK = 0,
  Quick_Fail = 1,
  Quick_OK_Smell_OK = 2,
  Quick_OK_Smell_Fail = 3,
  Quick_Fail_Smell_OK = 4,
  Quick_Fail_Smell_Fail = 5,
  Full_Green = 6,
  Full_Amber = 7,
  Full_Red = 8,
  Model_OK = 9,
  Model_Fail = 10,
  Challenge_OK = 11,
  Challenge_Fail = 12,
  Model_Pending_Review = 13,
  Logits_OK = 14,
  Logits_Fail = 15,
  // Batch triage outcomes, one response emitted per share in the batch.
  // Triage_Clear means "deprioritised", NOT "verified good".
  Triage_Check = 16,
  Triage_Clear = 17,
  Triage_Error = 18
}

table BlockValidation {
  version: uint32;
  hash: [ubyte];             // 32 bytes
  prev_block_hash: [ubyte];  // 32 bytes
  merkle_root: [ubyte];      // 32 bytes
  timestamp: uint32;
  bits: uint32;
  nonce: uint32;
  pow_blob_hash: [ubyte];
  adjusted_bits: uint32;
  pow_blob: Proof;
  // Registered model difficulty from the ModelRecord active at the block's
  // height. Appended field: wire-compatible with old readers/writers.
  //
  // Option 2 (PROMPT BINDING.md §6) — this field doubles as the verifier's
  // v3-ACTIVE signal, so there is NO separate v3_active field:
  //   difficulty == 0  => v3 admission inactive/unavailable at this height;
  //                       a version>=3 proof is replayed under v2 rules
  //                       (admission nonce NOT folded into the u preimage),
  //                       byte-identical to consensus.
  //   difficulty  > 0  => v3 is ACTIVE; the verifier applies the v3
  //                       nonce/tier/admission semantics and derives the
  //                       admission target from this value.
  // bcore MUST send difficulty > 0 only when Consensus::IsV3Active(height)
  // is true, and remains authoritative for the admission check itself.
  difficulty: int64;
  // ---- Ruleset dispatch (appended fields, wire-compatible) ----
  // The candidate block's OWN height: parent height + 1, taken by the writer
  // from the indexed parent (pindex->pprev), never from the chain tip or from
  // any time proxy. Together with `ruleset` this is the validated chain
  // context the verifier dispatches on. 0 is not a valid height for a mined
  // block on any TensorCash chain, so a reader that sees height == 0 must
  // treat the context as absent (see the presence rule below).
  height: uint32;
  // Ruleset the verifier MUST apply to this request:
  //   0 = legacy  (pre-v3 rules; also the value an old writer implies)
  //   1 = v3      (TIP-0003: Consensus::IsV3Active(height), v4 not active)
  //   2 = v4-strict (X <= height < Y)
  //   3 = v4-priced (Y <= height < Z; both v3 and v4 priced)
  //   4 = v4-only (height >= Z)
  // The verifier selects its checks by `ruleset` ONLY -- never by the presence
  // of `difficulty`, the proof version, wall-clock time, or its own idea of
  // the tip. Presence rules:
  //   * Both fields ABSENT is permitted only for explicitly supported legacy
  //     request kinds, i.e. writers that predate these fields. A writer that
  //     knows the candidate's parent MUST populate both; a writer that cannot
  //     place the candidate (parent not indexed) MUST omit both rather than
  //     write 0 -- readers must be able to distinguish "absent" from an
  //     explicit 0 via the field-presence check (vtable offset), and an
  //     explicit ruleset 0 is only ever written by a writer that verified
  //     the height is below V3 activation.
  //   * A request that claims a strict ruleset (1 through 4) but is missing any
  //     context that ruleset requires (height, difficulty, prev_block_hash,
  //     the proof carrier fields the ruleset needs) MUST be answered with
  //     `defer` / context_error -- NEVER replayed under a lower ruleset and
  //     NEVER turned into a RED verdict. Downgrading is not a reader option.
  //   * Result-cache keys include `ruleset`, so a verdict obtained under one
  //     ruleset can never satisfy a request made under another.
  ruleset: uint8;
}

table ModelValidation {
  model_name: string;
  model_commit: string;
  difficulty: int64;
  cid: string;
  extra: string;
  txid: [ubyte];             // 32 bytes
  block_hash: [ubyte];        // 32 bytes
  block_height: int32;
}

// One share inside a batch. Carries its own hash_id so each response can be
// correlated back by the caller, exactly like a single-share request, plus the
// share's COMPLETE serialized ValidationRequest bytes. Embedding the encoded
// request (rather than a nested BlockValidation) means both sides reuse the
// existing single-share encode/decode path unchanged -- no cross-buffer table
// copying, and pfunpack parses each share exactly as it always has.
table BatchShare {
  hash_id: [ubyte];            // 32 bytes
  request: [ubyte];            // a complete serialized ValidationRequest
}

// Batched advisory triage request. Appended to ValidationUnion (append-only,
// so existing readers keep their tag numbering).
table BatchValidation {
  shares: [BatchShare];
  chunk: uint32;               // shares per forward pass; 0 = worker default
  rank_ratio: float;           // flag above this x cohort median; 0 = default
  bootstrap: uint32;           // 0 = worker default
}

union ValidationUnion {
  BlockValidation,
  ModelValidation,
  BatchValidation
}

table ValidationRequest {
  hash_id: [ubyte];        // 32 bytes
  validation_type: ValidationType;
  request: ValidationUnion;
}

table ValidationResponse {
  hash_identifier: [ubyte];   
  enum_response: ResponseValue;
}

root_type ValidationRequest;

blockheader.fbs

Rottyp BlockHeader

Mining-headern och minarens svar. BlockHeader är den nedbantade header som noden skickar till minaren; MiningResponse är det minaren returnerar när den har en kandidatlösning (nonce plus pow_blob, som refererar till tabellen Proof i proof.fbs).

Deklarerar BlockHeader, MiningResponse

include "proof.fbs";

namespace proof;

table BlockHeader {
  req_id: uint32;
  version: uint32;
  prev_block_hash: [ubyte];  // 32 bytes
  merkle_root: [ubyte];      // 32 bytes
  timestamp: uint32;
  bits: uint32;
  // ---- Job chain context (appended fields, wire-compatible) ----
  // Height of the block this job would produce: parent height + 1, where the
  // parent is `prev_block_hash` as indexed by the publishing node. This is
  // the job's own height on the node's network, not the node's tip height
  // (they coincide for a fresh template, but the field is bound to the
  // parent so a stale or re-issued job still carries the right context).
  // 0 = not provided (old writer, or the publisher could not index the
  // parent); a miner must not derive a height from it in that case.
  height: uint32;
  // Whether the effective step-binding nonce (Consensus::StepBindHeight) is
  // in force for THIS job, as decided by the publishing node from the job's
  // parent/height on its network:
  //   0 = field absent / unknown -- an old writer, or the publisher could not
  //       index the parent. NOT "legacy": a miner must fall back to its own
  //       configured policy (e.g. ZMQ_ASSUME_STEPBIND), never assume legacy.
  //   1 = legacy   -- StepBind is NOT active at `height` on this network.
  //   2 = stepbind -- StepBind IS active at `height`; the proof must use the
  //       effective step nonce. Any legacy grace window (StepBindGraceEndTime,
  //       judged by the node on the parent's median-time-past) is NOT encoded
  //       here: 2 states what the network requires, the node alone decides
  //       whether a flagless legacy proof is still tolerated.
  // The three values exist so that "absent" and "explicitly legacy" are
  // distinguishable on the wire without a field-presence check.
  stepbind: uint8;
}

table MiningResponse {
  req_id: uint32;
  nonce: uint32;
  adjusted_bits: uint32;
  pow_blob_hash: [ubyte];
  difficulty: uint32;
  pow_blob: Proof;
  completion_id: string;  // OpenAI-style completion ID (e.g., "cmpl-xxxxx")
}

root_type BlockHeader;

Använda dem från en klient

Generera typade bindningar med FlatBuffers-kompilatorn:

# C++
flatc --cpp -o gen/ proof.fbs validation.fbs blockheader.fbs

# Python
flatc --python -o gen/ proof.fbs validation.fbs blockheader.fbs

# Rust
flatc --rust -o gen/ proof.fbs validation.fbs blockheader.fbs

# TypeScript
flatc --ts -o gen/ proof.fbs validation.fbs blockheader.fbs

# JSON Schema (prebuilt files are under /schemas/json/)
flatc --jsonschema -o gen/ proof.fbs validation.fbs blockheader.fbs

För JSON-anrop till /v1/verify/*/json motsvarar fältnamnen i det som skickas tabellfälten direkt. För binära anrop till /v1/verify/* bygger du en ValidationRequest och skickar byten med POST som application/octet-stream.