NOXYDocs
GitHub
Docs/Protocol/Protocol Architecture

Protocol Architecture

NOXY internals: transaction envelope, DAG consensus with checkpoint finality, state commitments, cryptographic primitives, and validator lifecycle.

Updated 2026-08-03Status ReferenceSource content/wiki/protocol/architecture.mdx

Protocol Architecture

NOXY is a post-quantum Layer 1 blockchain built around a canonical transaction envelope, a Merkle-committed ledger, and a DAG consensus core with checkpoint finality. This page documents what is implemented in the Rust codebase.

Hashing

All consensus-critical digests use BLAKE3 with domain separation:

NOXY-L0/v0.1/<domain>\0 || data

Examples of domain strings used in the codebase:

| Domain | Used for | |--------|----------| | tx-signing | Transaction signing digest | | tx-root | Merkle root over transaction hashes | | state-root | Merkle root over state key-value leaves | | event-root | Merkle root over event hashes |

Transaction envelope

Every user action is submitted as a TransactionEnvelope:

TransactionEnvelope {
  version:   u16          // wire version
  chain_id:  ChainId      // must match node's chain_id
  account_id: AccountId   // 32-byte account identifier
  nonce:     u64          // per-account sequence number
  fee: {
    fee_asset_id:           AssetId
    max_fee:                u64
    witness_byte_fee_limit: u64
  }
  payload:   TransactionPayload
  auth: {
    key_id:                    KeyId
    algorithm_id:              SignatureAlgorithmId
    signature:                 bytes  // ML-DSA-44 signature
    optional_hybrid_signature: bytes? // optional Ed25519 second signature
  }
}

The signing digest is computed over the canonical encoding of the envelope body (everything except auth.signature).

Transaction types

| Type | Description | |------|-------------| | CreateAccount | Create a new account with an initial ML-DSA-44 key | | RegisterKey | Register an additional key on an existing account | | Transfer | Transfer a fungible asset between accounts | | RegisterValidator | Register a validator record bound to an operator account | | Batch | Sequence of BatchAction items in one atomic envelope | | ActivateValidator | (Admin) Schedule validator activation at a given epoch | | DeactivateValidator | (Admin) Schedule validator deactivation | | RegisterServiceDefinition | Register a service definition | | RegisterServiceChain | Register a service chain | | SubmitCheckpoint | Submit a checkpoint | | SubmitMessageEnvelope | Cross-chain message envelope |

Batch is the composable variant: it wraps a Vec<BatchAction> where each action is one of RegisterKey, RegisterValidator, Transfer, ActivateValidator, DeactivateValidator, and others.

Consensus

Consensus is a single pipeline with three stages; there are no consensus modes to select in config.

  1. Availability. A DAG availability layer collects transaction batches and certifies them across the validator set.
  2. Ordering. An ordering layer sequences certified batches into one continuous transaction log.
  3. Finality. Checkpoint certificates make the ordered prefix durably final.

Once a transaction is covered by a checkpoint certificate it is final: there are no forks, no probabilistic settlement, and no reorgs. There is no view-based pacemaker to tune; ordering runs continuously rather than in leader-driven rounds.

Equivocation is handled inside the availability layer by an anti-equivocation collector. It is a liveness mechanism, not a punishment mechanism; there is no slashing.

Blocks and checkpoints

Batches and checkpoints commit Merkle roots over transactions, state, and events. A checkpoint pins a position in the ordered transaction log together with the state that results from executing everything up to that position:

Checkpoint {
  height:               u64      // checkpoint height
  ordered_sequence_end: u64      // end of the ordered prefix this checkpoint covers
  state_root:           Hash32   // state commitment after executing the covered prefix
  ordered_log_root:     Hash32   // Merkle root over the ordered transaction log
}

A checkpoint certificate over these fields, signed by the validator set, makes the covered prefix durably final.

State

State is committed to a sparse Merkle tree (SMT) over 256-bit BLAKE3 paths. Tree commits are batched per checkpoint window: each checkpoint's state_root covers all state changes since the previous checkpoint.

Any account, balance, or transaction is provable against a committed checkpoint with a compact proof. Transaction proofs are served over the public RPC:

GET /v0/tx/{hash}/proof?level=inclusion|finality|checkpoint

At finality and above the response adds the checkpoint and its certificate (checkpoint_hex, checkpoint_cert_hex), so the proof chains up to a validator-signed checkpoint.

Persistence is atomic: state writes, tree nodes, and indexes land in RocksDB atomically per commit batch.

Cryptography

Accounts

ML-DSA-44

Account keys are ML-DSA-44 (FIPS 204). Transaction envelopes are signed with the account's primary key. Additional keys can be registered via RegisterKey. ML-DSA-44 public keys are approximately 1312 bytes; signatures approximately 2420 bytes.

Consensus

Strict hybrid

Consensus certificates are signed with a hybrid scheme: ML-DSA-44 plus Ed25519. Verification requires both signatures to pass; there is no fallback to one signature alone.

Validator lifecycle

Candidate → Active → Inactive | Exiting → Exited

| Status | Description | |--------|-------------| | Candidate | Registered but not yet scheduled for activation | | Active | In the current active set, certifying batches and signing checkpoints | | Inactive | Deactivated, not in active set | | Exiting | Scheduled for removal at active_until_epoch | | Exited | Fully removed from the validator set |

A validator record binds:

  • operator_account_id: the account that owns lifecycle actions
  • pq_consensus_key_id: ML-DSA-44 key for consensus certificate signatures
  • classical_consensus_key_id: Ed25519 key paired with it for the hybrid scheme
  • voting_power: the validator's weight when certifying
  • active_from_epoch / active_until_epoch: epoch-bounded membership

The active set at each height is derived from committed state, not from local config.

Epoch transitions

Epochs advance deterministically based on height. At each epoch boundary:

  1. The execution layer derives a new active set from the current validator records.
  2. Validators scheduled for activation at this epoch move from CandidateActive.
  3. Validators with a matching active_until_epoch move to Exiting or Inactive.