IBC v2 & sharding
IBC v2 experimental
NeuroChain connects to other chains with IBC v2 — the simplified, client-centric version of the Inter-Blockchain Communication protocol (also known as Eureka). The first counterparty is the Cosmos ecosystem, starting with Neutron (CosmWasm).
What NeuroChain adds is post-quantum interoperability: its commits are signed with ML-DSA-65, so the counterparty's light client verifies NeuroChain with a post-quantum signature instead of the ECDSA / Ed25519 schemes classic IBC relies on.
What travels over a channel
| Packet | Wire format | Purpose |
|---|---|---|
| Fungible transfer | `nc-ics20-v1 | denom |
| Security attestation | `nc-ibc-attest-v1 | bytecode_hash |
| Commit header | `nc-pq-lc-v1 | chain_id |
The attestation packet is where the two main bets meet: an AI security proof produced on NeuroChain that another chain can rely on.
Token transfers
Outbound (NeuroChain → counterparty)
POST /api/v1/ibc/transferlocks the amount in the channel's escrow accountneuro:ibc.escrow.<channel>; the packet islocked.- A relayer delivers it; the counterparty mints a voucher.
POST /api/v1/ibc/ackmarks itcommittedand burns the escrow.- No acknowledgement within the timeout → the sender is refunded automatically.
Inbound (counterparty → NeuroChain)
- A relayer submits
POST /api/v1/ibc/recvwith the packet and its commitment. - The receiver is credited an IBC voucher with the denom
ibc/<SHA-256 of the trace path>, as ibc-go does. A packet id can be received only once. POST /api/v1/ibc/redeemburns the voucher and sends the asset back through the channel.
Amounts on the wire are integers in the base denom (unro for NRO).
Who signs what
| Operation | Who may submit | Signature |
|---|---|---|
transfer, redeem | Any account, for its own funds | Covers every field — receiver, channel, chain, denom, amount |
recv, ack, channel/open, channel/pause, client/update, attest | IBC operators only: keys listed in NEUROCHAIN_IBC_OPERATOR_PUBKEYS | Same, by the operator's key |
Authority is the operator's public key, not a claimed address. All IBC operations are applied in consensus and sign for neuro:system.ibc.
Current status and limits
| Piece | Status |
|---|---|
| Escrow, vouchers, denom traces, timeouts, packet records | Implemented in the node, unit-tested |
| PQ commit headers signed every 1 000 blocks | Implemented; served at GET /api/v1/ibc/header/latest |
| Field-binding signatures on every IBC operation | Implemented, with golden test vectors |
Counterparty contract neuro-pq-client (CosmWasm) | Built (neurochain/contracts/neuro_pq_client). Not yet trustless: it checks the relayer's trusted key and a rising height; the ML-DSA-65 signature is verified by the relayer, off-chain |
| Inbound packets | Accepted from IBC operators with a commitment over the credited fields; a Merkle membership proof from the counterparty is proposed, not implemented |
| End-to-end transfer with Neutron testnet | Not done yet — the deployment script is ready (tools/ibc-relayer/deploy_neutron.js) and needs a funded testnet account |
| Full IBC v2 handshake with ibc-go | Planned |
Until the counterparty verifies ML-DSA-65 on chain, an IBC channel trusts its relayer. Keep NEUROCHAIN_IBC_MAX_PACKET_UNRO and NEUROCHAIN_IBC_MAX_CHANNEL_ESCROW_UNRO low on any network with real value.
How it is tested: node unit tests cover locking, acknowledgement, timeout refund, voucher credit and redeem, duplicate packets, reserved packet ids, commitment mismatches, operator authority and the canonical signed messages (cargo test -p neurochain-node ibc). GET /api/v1/ibc/pq/test-vector returns a fixed header, key and signature so a counterparty implementation can check it encodes and verifies the same bytes.
Running a relayer (lab)
# 1. Start the node with your operator key allowed
NEUROCHAIN_IBC_OPERATOR_PUBKEYS=<operator ML-DSA-65 public key hex> ./target/debug/neurochain
# 2. Open a channel (signed by the operator)
# POST /api/v1/ibc/channel/open { from, channel, port, counterparty_chain, allowed_denoms, … }
# 3. After a checkpoint, export the header for the counterparty client
NODE_RPC=http://localhost:9933 node neurochain/tools/ibc-relayer/export_update_client.jsThe script prints the UpdateClient message for neuro-pq-client. Request fields for every IBC endpoint are in the REST reference.
Configuration
| Variable | Default | Meaning |
|---|---|---|
NEUROCHAIN_IBC_OPERATOR_PUBKEYS | empty | Comma-separated public keys allowed to relay and administer channels |
NEUROCHAIN_IBC_TRUSTED_PUBKEYS | empty | ML-DSA-65 keys whose header signatures are accepted on inbound packets; empty accepts any valid signature (lab only) |
NEUROCHAIN_IBC_REQUIRE_HEADER | on mainnet | Inbound packets must come with a verified header |
NEUROCHAIN_IBC_REQUIRE_PACKET_COMMITMENT | on mainnet | Inbound packets must carry the commitment over their fields |
NEUROCHAIN_IBC_TIMEOUT_BLOCKS | 10 | Blocks before an unacknowledged outbound packet is refunded |
NEUROCHAIN_IBC_MAX_PACKET_UNRO | no limit | Largest single transfer |
NEUROCHAIN_IBC_MAX_CHANNEL_ESCROW_UNRO | no limit | Most that one channel may hold in escrow |
NEUROCHAIN_IBC_NATIVE_DENOM | unro | Base denom of NRO on the wire |
Sharding experimental
Each shard runs its own consensus instance with its own validators and height; accounts belong to FNV-1a(address) mod n_shards. How cross-shard transfers settle is described in Consensus → Sharding.
Run one node per shard:
NEUROCHAIN_SHARDS=4 NEUROCHAIN_SHARD_ID=0 NEUROCHAIN_DATA_DIR=./data-s0 NEUROCHAIN_RPC_PORT=9933 … ./target/debug/neurochain
NEUROCHAIN_SHARDS=4 NEUROCHAIN_SHARD_ID=1 NEUROCHAIN_DATA_DIR=./data-s1 NEUROCHAIN_RPC_PORT=9934 … ./target/debug/neurochain- Without
NEUROCHAIN_SHARD_IDa node runs a single shard and creates no cross-shard transfers. - The gateway routes each transaction to the node of the sender's shard.
- Monitor relays with
GET /api/v1/cross-shard/queue?status=lockedand per-shard heights withGET /api/v1/shards.
Internally, cross-shard relays use the same packet engine as IBC v2 — a shard is one kind of channel end, an external chain another.