Shekyl Stats

Refreshing...

Network

Connected
Seed Nodes Active
--

Chain

Current Block
0
Target Height
0
Top Block Hash
--
Block Time Target
2 min

Rewards

Last Block Reward
0.000000 SKL
Difficulty
0
Estimated Hash Rate
0 H/s

Supply

Circulating Supply
--
Remaining Supply
--
Total Burned
0.000000 SKL

Economics

Release Multiplier
0
Burn Rate %
0

Staking

Stake Ratio
0
Staker Pool
0.000000 SKL
Staker Emission Share
0
Total Staked
N/A
Staking Height
N/A
Tier 0 Lock Blocks
N/A
Tier 1 Lock Blocks
N/A
Tier 2 Lock Blocks
N/A

Protocol

Transaction Format
TransactionV3
Membership Proof
FCMP++
Spend Auth
Ed25519 + ML-DSA-65
Confidentiality
Stealth + BP+

Node

TX Pool Size
0
Database Size
0 B
Node Version
--
Sync Status
Syncing
All Documentation

Daemon RPC (Rust)

Rust-native RPC interface for shekyld: endpoints, types, and usage examples.

Daemon RPC: Rust/Axum Migration

Phase 1 of the epee-to-Rust migration replaces the daemon's HTTP transport layer with Axum while keeping all handler logic in C++.

Architecture

  Client
    │
    ▼
  Axum (Rust)            ◀─ HTTP transport, CORS, body limits, route dispatch
    │
    ▼
  CoreRpc (Rust)         ◀─ FFI wrapper, spawn_blocking for C++ calls
    │
    ▼ C ABI
  core_rpc_ffi.cpp       ◀─ Dispatch tables: URI → handler, epee serialization
    │
    ▼
  core_rpc_server (C++)  ◀─ on_* handlers (unchanged)
    │
    ▼
  cryptonote::core / p2p

The core_rpc_server class retains its on_* methods and still inherits from epee::http_server_impl_base (the legacy server remains available via --no-rust-rpc). The Axum server runs on a dedicated Tokio runtime started from the Rust FFI.

Files

FileRole
src/rpc/core_rpc_ffi.hC API header for the FFI facade
src/rpc/core_rpc_ffi.cppDispatch tables mapping URIs/methods to on_* handlers
rust/shekyl-daemon-rpc/Axum crate: server, routes, handlers, types; produces libshekyl_daemon_rpc.a
rust/shekyl-daemon-rpc/src/ffi_exports.rsshekyl_daemon_rpc_start/stop FFI exports (daemon-only)
src/shekyl/shekyl_ffi.hC++ declarations for Rust FFI functions
src/daemon/daemon.cppDaemon lifecycle: start/stop Rust RPC alongside epee
tests/rpc_comparison/compare_rpc.shValidation harness for dual-server diffing

Endpoint Coverage

  • 33 JSON REST endpoints (/get_info, /send_raw_transaction, etc.)
    • Accept both GET and POST (matching epee behavior)
  • 8 binary endpoints (/get_blocks.bin, /get_o_indexes.bin, etc.)
    • POST-only; return 400 Bad Request on parse failure (matching epee)
  • 48 JSON-RPC 2.0 methods (get_block_count, get_block_template, etc.)
    • POST-only (per JSON-RPC 2.0 spec)
  • 90 total dispatcher registrations (74 unique handlers)

All URI aliases (e.g. /getheight/get_height) are registered.

Restricted Mode

In restricted mode (--restricted-rpc):

  • JSON REST: admin-only routes (/start_mining, /stop_daemon, etc.) are not registered in the Axum router.
  • JSON-RPC: admin-only methods are rejected with code -32601 before reaching the C++ handler.

PQC Readiness

  • Default body limit: 10 MiB (configurable). With FCMP++ and per-input pqc_auths, a typical 2-in/2-out transaction is ~23 KB. The 10 MiB limit is sufficient for all realistic transaction sizes including multisig.
  • No changes needed to the wire format; the FFI boundary passes raw JSON strings and binary blobs without interpretation.
  • get_outs / get_outs.bin endpoints are removed — FCMP++ uses full-chain membership proofs, so there is no ring member fetching.
  • Curve tree RPC endpoints are implemented:
    • get_curve_tree_path — retrieve a Merkle path for a given leaf
    • get_curve_tree_info — retrieve the current curve tree root hash, depth, and leaf count
    • get_curve_tree_checkpoint — retrieve a curve tree snapshot at a given height

Running

# Rust RPC is enabled by default on port = epee_port + 10000
shekyld --testnet              # epee 12029, Axum 22029
shekyld                        # epee 11029, Axum 21029

# Disable Rust RPC (legacy only)
shekyld --no-rust-rpc

# Validation: run both servers and diff responses
./tests/rpc_comparison/compare_rpc.sh 12029 22029

Port Mapping

NetworkP2Pepee RPCAxum RPC
Mainnet110211102921029
Testnet120211202922029
Stagenet130211302923029

Validation Results

Tested on testnet (2026-04-02) with dual-server mode. Test data saved to shekyl-dev/data/rpc_comparison/.

  • 23 PASS across JSON REST, JSON-RPC, and restricted endpoints
  • 2 expected diffs (get_info via both REST and JSON-RPC): rpc_connections_count differs because epee counts its own active HTTP connection while Axum does not go through epee's connection tracker
  • 2 binary SKIP: Both servers return 400 for empty-POST binary requests (matching behavior confirmed); full binary validation requires wallet sync test

Cutover Remaining Work

Before removing the epee HTTP listener entirely:

  1. Wallet sync test -- connect shekyl-cli to Axum-only RPC, verify block sync via /getblocks.bin and curve tree path fetch via /get_curve_tree_path
  2. Standard port binding -- when Axum is sole server, bind to 11029/12029/13029 (not +10000) so existing clients and config files work unchanged

Thread Safety

The C++ core_rpc_server handlers are designed for concurrent access (epee's thread pool model). Axum dispatches each request on a Tokio worker, and the FFI call is offloaded via tokio::task::spawn_blocking to avoid blocking the async runtime. The CoreRpc wrapper is Send + Sync.

Future Work (Phases 2–4)

  • Phase 2: Replace epee KV serialization with a Rust encoding crate.
  • Phase 3: Replace P2P networking (abstract_tcp_server2, Levin) with Rust.
  • Phase 4: Remove contrib/epee/ entirely; strip remaining Boost deps.