API Reference

How to interact with Continuum microsecond sequencer [Testnet]

Continuum Sequencer API Reference

This document provides comprehensive reference for both the gRPC and REST APIs of the Continuum Sequencer.

Overview

The Continuum Sequencer provides dual API access:

  • gRPC API: High-performance binary protocol for production integrations

  • REST API: JSON-based API for web applications and debugging

Both APIs provide access to transaction submission, tick querying, and chain state inspection.

Base URLs

  • gRPC: Default 0.0.0.0:9090

  • REST: Default 0.0.0.0:8080 with base path /api/v1

Authentication

Currently, the APIs are unauthenticated. Authentication and authorization will be added in future phases.


gRPC API

Service Definition

The gRPC service is defined in sequencer.proto:

service SequencerService {
  rpc SubmitTransaction(SubmitTransactionRequest) returns (SubmitTransactionResponse);
  rpc SubmitBatch(SubmitBatchRequest) returns (SubmitBatchResponse);
  rpc GetStatus(GetStatusRequest) returns (GetStatusResponse);
  rpc StreamTicks(StreamTicksRequest) returns (stream Tick);
  rpc GetTransaction(GetTransactionRequest) returns (GetTransactionResponse);
  rpc GetTick(GetTickRequest) returns (GetTickResponse);
  rpc GetChainState(GetChainStateRequest) returns (GetChainStateResponse);
}

Transaction Submission

SubmitTransaction

Submit a single transaction for ordering.

Request:

message SubmitTransactionRequest {
  Transaction transaction = 1;
}

message Transaction {
  string tx_id = 1;                    // Unique transaction identifier
  bytes payload = 2;                   // Application-specific data
  bytes signature = 3;                 // Client signature
  bytes public_key = 4;                // Client public key
  uint64 nonce = 5;                    // Replay protection nonce
  uint64 timestamp = 6;                // Client timestamp (microseconds)
}

Response:

message SubmitTransactionResponse {
  uint64 sequence_number = 1;          // Assigned sequence number
  uint64 expected_tick = 2;            // Expected inclusion tick
  string tx_hash = 3;                  // Transaction hash (8-char hex)
}

Example (grpcurl):

grpcurl -plaintext -d '{
  "transaction": {
    "tx_id": "tx_001",
    "payload": "SGVsbG8gV29ybGQ=",
    "signature": "c2lnbmF0dXJl",
    "public_key": "cHVibGljX2tleQ==",
    "nonce": 1,
    "timestamp": 1672531200000000
  }
}' localhost:9090 continuum.sequencer.v1.SequencerService/SubmitTransaction

SubmitBatch

Submit multiple transactions in a single request.

Request:

message SubmitBatchRequest {
  repeated Transaction transactions = 1;
}

Response:

message SubmitBatchResponse {
  repeated SubmitTransactionResponse responses = 1;
}

Status and Monitoring

GetStatus

Get current sequencer status and metrics.

Request:

message GetStatusRequest {}

Response:

message GetStatusResponse {
  uint64 current_tick = 1;             // Current tick number
  uint64 total_transactions = 2;       // Total transactions processed
  uint64 pending_transactions = 3;     // Transactions in queue
  uint64 uptime_seconds = 4;           // Sequencer uptime
  double transactions_per_second = 5;  // Current TPS rate
}

StreamTicks

Stream live ticks as they are produced.

Request:

message StreamTicksRequest {
  uint64 start_tick = 1;               // Start from this tick (0 = latest)
}

Response Stream:

message Tick {
  uint64 tick_number = 1;
  VdfProof vdf_proof = 2;
  repeated OrderedTransaction transactions = 3;
  string transaction_batch_hash = 4;
  uint64 timestamp = 5;
  string previous_output = 6;           // Previous VDF output (hex)
}

Data Queries

GetTransaction

Lookup a transaction by its hash.

Request:

message GetTransactionRequest {
  string tx_hash = 1;                  // 8-character hex hash
}

Response:

message GetTransactionResponse {
  OrderedTransaction transaction = 1;   // Transaction details
  uint64 tick_number = 2;              // Inclusion tick
  bool found = 3;                      // Whether transaction exists
}

GetTick

Retrieve a specific tick by number. The sequencer maintains 1 million ticks in memory for fast access. Older ticks are automatically archived to disk and can still be retrieved, though with slightly higher latency.

Request:

message GetTickRequest {
  uint64 tick_number = 1;
}

Response:

message GetTickResponse {
  Tick tick = 1;                       // Tick details
  bool found = 2;                      // Whether tick exists
}

Archive Behavior:

  • Recent ticks (up to 1M) are served from memory

  • Older ticks are automatically archived to disk at data/archive/

  • Archived ticks are organized in subdirectories (10k ticks per directory)

  • Both memory and archived ticks are transparently accessible via the same API

GetChainState

Get chain state summary with recent ticks.

Request:

message GetChainStateRequest {
  uint32 tick_limit = 1;               // Max recent ticks to return
}

Response:

message GetChainStateResponse {
  uint64 chain_height = 1;             // Latest tick number
  uint64 total_transactions = 2;       // Total processed transactions
  repeated Tick recent_ticks = 3;      // Recent ticks
  map<string, uint64> tx_to_tick_sample = 4;  // Sample mappings
}

REST API

All REST endpoints return JSON responses with appropriate HTTP status codes.

Base Response Format

Success responses follow this structure:

{
  "found": true,
  "data": { ... }
}

Error responses:

{
  "error": "Error description"
}

Status Endpoint

GET /api/v1/status

Get sequencer status and metrics.

Response:

{
  "chain_height": 1234,
  "total_transactions": 5678,
  "latest_tick": 1234,
  "status": "running"
}

Example:

curl http://localhost:8080/api/v1/status

Transaction Submission

Note: Transaction submission via REST API is not yet implemented. Currently, transactions must be submitted through the gRPC API. REST submission will be added in a future release.

To submit transactions, use the gRPC SubmitTransaction or SubmitBatch endpoints as documented in the gRPC API section above.

Transaction Queries

GET /api/v1/tx/{hash}

Lookup transaction by 8-character hex hash.

Parameters:

  • hash: 8-character hexadecimal transaction hash

Response:

{
  "tx_hash": "deadbeef",
  "tick_number": 123,
  "sequence_number": 456,
  "found": true,
  "transaction": {
    "tx_id": "tx_001",
    "nonce": 1,
    "ingestion_timestamp": 1672531200000000,
    "payload_size": 256
  }
}

Example:

curl http://localhost:8080/api/v1/tx/deadbeef

How Transaction Hashes Work:

  • Transaction hashes are 8-character hexadecimal strings (32 bits)

  • They represent the first 4 bytes of the SHA256 hash of the transaction data

  • The hash is computed from the serialized transaction including: tx_id, payload, signature, public_key, nonce, and timestamp

  • Due to the shortened hash, collisions are possible but rare in practice

Tick Queries

GET /api/v1/tick/{number}

Retrieve tick by number. Transparently serves from memory (recent 1M ticks) or disk archive (older ticks).

Parameters:

  • number: Tick number (integer)

Response:

{
  "tick_number": 123,
  "found": true,
  "tick": {
    "tick_number": 123,
    "timestamp": 1672531200000000,
    "transaction_count": 50,
    "transaction_batch_hash": "abcd1234...",
    "vdf_iterations": 27,
    "previous_output": "efgh5678..."
  }
}

Example:

curl http://localhost:8080/api/v1/tick/123

Archive Notes:

  • Memory buffer: 1,000,000 most recent ticks

  • Older ticks archived to: data/archive/{subdir}/tick_{number}.json

  • Archive lookup adds ~10-50ms latency vs memory access

GET /api/v1/ticks/recent

Get recent ticks with pagination.

Query Parameters:

  • limit (optional): Maximum ticks to return (default: 20, max: 100)

  • offset (optional): Offset for pagination (default: 0)

Response:

{
  "ticks": [
    {
      "tick_number": 125,
      "timestamp": 1672531200000000,
      "transaction_count": 42
    },
    {
      "tick_number": 124,
      "timestamp": 1672531199900000,
      "transaction_count": 38
    }
  ],
  "total": 2
}

Example:

curl "http://localhost:8080/api/v1/ticks/recent?limit=10"

Health Check

GET /api/v1/health

Simple health check endpoint.

Response:

{
  "status": "healthy",
  "timestamp": 1672531200
}

Example:

curl http://localhost:8080/api/v1/health

Error Handling

HTTP Status Codes

  • 200 OK: Request successful

  • 400 Bad Request: Invalid request format or parameters

  • 404 Not Found: Resource not found (transaction, tick)

  • 500 Internal Server Error: Server error

  • 503 Service Unavailable: Service temporarily unavailable

gRPC Status Codes

  • OK: Request successful

  • INVALID_ARGUMENT: Invalid request parameters

  • NOT_FOUND: Resource not found

  • RESOURCE_EXHAUSTED: Queue full or rate limited

  • INTERNAL: Internal server error


Rate Limiting

Current implementation includes basic backpressure:

  • Transaction queue has configurable limits

  • Batch submissions continue processing even if individual transactions fail

  • gRPC streaming has channel-based backpressure


Data Types

Transaction Hash Format

Transaction hashes are 8-character hexadecimal strings representing the first 32 bits of the SHA256 hash of transaction data.

Example: deadbeef

Timestamps

All timestamps are in microseconds since Unix epoch (UTC).

Example: 1672531200000000 = 2023-01-01 00:00:00 UTC

VDF Proofs

VDF proofs contain:

  • input: Hex-encoded input bytes

  • output: Hex-encoded output bytes

  • proof: Hex-encoded proof bytes

  • iterations: Number of iterations performed

Tick Numbering

Ticks are numbered sequentially starting from 1. Tick 0 is reserved for genesis.


Security Considerations

  1. No Authentication: Current APIs are unauthenticated

  2. Input Validation: All inputs are validated for format and size

  3. Rate Limiting: Basic queue-based limiting prevents resource exhaustion

  4. Cryptographic Integrity: VDF proofs ensure tick authenticity


Performance Characteristics

  • Target Tick Time: ≤100 microseconds

  • Transaction Throughput: 100k+ tx/s ingestion capacity

  • VDF Verification: Batch verification provides 10x+ speedup

  • Memory Usage: Configurable tick retention (default: 1,000,000 ticks)


Complete Transaction Flow Example

Here's a complete example of submitting a transaction via gRPC and then querying it via REST:

1. Submit Transaction (gRPC)

# Submit a transaction using grpcurl
grpcurl -plaintext -d '{
  "transaction": {
    "tx_id": "my_unique_tx_001",
    "payload": "SGVsbG8gQ29udGludXVtIQ==",
    "signature": "c2lnbmF0dXJlX2RhdGE=",
    "public_key": "cHVibGljX2tleV9kYXRh",
    "nonce": 12345,
    "timestamp": 1672531200000000
  }
}' localhost:9090 continuum.sequencer.v1.SequencerService/SubmitTransaction

# Response:
{
  "sequence_number": "789",
  "expected_tick": "150",
  "tx_hash": "a1b2c3d4"
}

2. Query Transaction Status (REST)

# Use the tx_hash from the response to query the transaction
curl http://localhost:8080/api/v1/tx/a1b2c3d4

# Response:
{
  "tx_hash": "a1b2c3d4",
  "tick_number": 150,
  "sequence_number": 789,
  "found": true,
  "transaction": {
    "tx_id": "6d795f756e697175655f74785f303031",
    "nonce": 12345,
    "ingestion_timestamp": 1672531200000000,
    "payload_size": 17
  }
}

3. Verify Inclusion in Tick (REST)

# Query the tick that contains the transaction
curl http://localhost:8080/api/v1/tick/150

# Response shows the tick with your transaction included
{
  "tick_number": 150,
  "found": true,
  "tick": {
    "tick_number": 150,
    "timestamp": 1672531200100000,
    "transaction_count": 42,
    "transaction_batch_hash": "f5e6d7c8b9a0...",
    "vdf_iterations": 27,
    "previous_output": "a1b2c3d4e5f6..."
  }
}

Client Libraries

Rust

The sequencer crate can be used directly as a library:

use sequencer::{SequencerConfig, Sequencer};

let config = SequencerConfig::default();
let sequencer = Sequencer::new(config)?;

gRPC Clients

Generate clients from the protobuf definition for any language:

  • Go: protoc-gen-go-grpc

  • Python: grpcio-tools

  • JavaScript: grpc-web

  • Java: protoc-gen-grpc-java

REST Clients

Standard HTTP clients work with the REST API:

# curl
curl -X GET http://localhost:8080/api/v1/status

# wget
wget -qO- http://localhost:8080/api/v1/health

# HTTPie
http GET localhost:8080/api/v1/tick/123

Data Storage and Archiving

In-Memory Storage

The sequencer maintains a configurable number of recent ticks in memory for fast access:

  • Default: 1,000,000 ticks

  • Configurable: Via max_ticks parameter in ChainState::new()

  • Access time: Sub-millisecond

Disk Archiving

Older ticks are automatically archived to disk when pruned from memory:

  • Archive location: data/archive/

  • Directory structure: {tick_number / 10000}/tick_{10-digit-number}.json

  • Format: JSON for easy inspection and debugging

  • Automatic: Archiving happens transparently during pruning

  • Access: All APIs (GetTick, GetTransaction) automatically check archives

Archive File Example

{
  "tick_number": 123456,
  "vdf_proof": {
    "input": "0x...",
    "output": "0x...",
    "proof": "0x...",
    "iterations": 27
  },
  "transactions": [
    {
      "tx_id": "tx_001",
      "tx_hash": [/* 32 bytes */],
      "sequence_number": 789,
      "payload": [/* bytes */],
      "signature": [/* bytes */],
      "public_key": [/* bytes */],
      "nonce": 12345,
      "ingestion_timestamp": 1672531200000000
    }
  ],
  "batch_hash": [/* 32 bytes */],
  "timestamp": 1672531200000000,
  "previous_vdf_output": [/* bytes */]
}

Monitoring and Observability

Metrics Endpoints

Currently available through:

  • gRPC GetStatus call

  • REST /api/v1/status endpoint

Future releases will include:

  • Prometheus metrics exposition

  • OpenTelemetry tracing

  • Structured logging

Log Levels

Configure with RUST_LOG environment variable:

RUST_LOG=sequencer=info,vdf=debug ./target/release/sequencer

Available levels: trace, debug, info, warn, error

Last updated