Skip to main content
A submission node is a full participant in the Ubu-Block network that can receive, validate, and propagate blocks. It exposes both a P2P interface for blockchain operations and an HTTP API for client interactions.

Overview

Submission nodes:
  • Accept block submissions via HTTP API
  • Validate and add blocks to the blockchain
  • Announce new blocks to connected peers
  • Synchronize with other nodes in the network
  • Serve blockchain data through REST endpoints

Prerequisites

  • Rust toolchain installed (1.70+)
  • SQLite database support
  • Network ports available for P2P and HTTP traffic

Setup Instructions

1
Clone the Repository
2
git clone https://github.com/your-org/ubu-block.git
cd ubu-block
3
Create Configuration File
4
Create a config.toml file with your node settings:
5
main_db = "sqlite://../../data/blockchain.db"
private_db = "sqlite://../../data/private.db"
http_addr = "127.0.0.1:9091"
node_addr = "127.0.0.1:9090"

[peers]
default = "127.0.0.1:9090"
6
See the Configuration page for detailed options.
7
Build the Submission Node
8
cd nodes/submission
cargo build --release
9
Start the Node
10
RUST_LOG=info cargo run --release -- --config config.toml
11
The node starts two services:
12
  • P2P server on the node_addr (default: 127.0.0.1:9090)
  • HTTP API server on the http_addr (default: 127.0.0.1:9091)
  • Command Line Options

    OptionDescriptionRequired
    --config <FILE>Path to configuration fileYes
    Example:
    cargo run -- --config ./config.toml
    

    HTTP API Endpoints

    The submission node exposes the following REST API endpoints at /api/v1:

    Submit Block

    POST /api/v1/submit
    Content-Type: application/json
    
    {
      // Block data
    }
    

    Query Endpoints

    EndpointMethodDescription
    /api/v1/block/{height}GETGet block by height
    /api/v1/positionsGETList all positions
    /api/v1/partiesGETList all political parties
    /api/v1/countiesGETList all counties
    /api/v1/counties/{county}/constituenciesGETList constituencies by county
    /api/v1/constituencies/{constituency}/wardsGETList wards by constituency
    /api/v1/wards/{ward}/stationsGETList polling stations by ward
    /api/v1/candidates/{position_type}/{area_id}GETList candidates by position and area
    API implementation: apps/api/src/lib.rs:110-131

    Environment Variables

    VariableDescriptionDefault
    RUST_LOGLogging level (trace, debug, info, warn, error)info

    Network Architecture

    The submission node operates on two network interfaces:

    P2P Interface

    • Handles blockchain protocol messages
    • Connects to peer nodes for synchronization
    • Announces new blocks to the network
    • Default port: 9090

    HTTP Interface

    • Serves REST API for client applications
    • Accepts block submissions
    • Provides query endpoints for blockchain data
    • Default port: 9091

    Peer Management

    Submission nodes automatically connect to configured peers on startup. Each peer connection is established asynchronously. From nodes/submission/src/main.rs:44-54:
    if let Some(peers) = config.peers {
        for peer in peers {
            tokio::spawn(async move {
                blockchain.connect_to_peer(peer.1.parse().unwrap())
                    .await
                    .unwrap();
            });
        }
    }
    

    Running Multiple Nodes

    To run multiple submission nodes on the same machine, create separate configuration files: config1.toml:
    main_db = "sqlite://data/blockchain1.db"
    private_db = "sqlite://data/private1.db"
    http_addr = "127.0.0.1:9091"
    node_addr = "127.0.0.1:9090"
    
    config2.toml:
    main_db = "sqlite://data/blockchain2.db"
    private_db = "sqlite://data/private2.db"
    http_addr = "127.0.0.1:9092"
    node_addr = "127.0.0.1:9093"
    
    [peers]
    default = "127.0.0.1:9090"
    
    Start each node in a separate terminal:
    # Terminal 1
    cargo run --release -- --config config1.toml
    
    # Terminal 2
    cargo run --release -- --config config2.toml
    

    Monitoring

    Monitor your submission node:
    # Enable detailed logging
    RUST_LOG=debug cargo run --release -- --config config.toml
    
    # Check API health
    curl http://127.0.0.1:9091/api/v1/positions
    
    # View database
    sqlite3 data/blockchain.db "SELECT * FROM blocks LIMIT 10;"
    

    Troubleshooting

    Port Already in Use

    If you see “Address already in use” errors:
    • Change the http_addr and node_addr in your config file
    • Ensure no other processes are using those ports
    • Check with: lsof -i :9090 or lsof -i :9091

    Database Connection Failed

    • Verify database paths in config file are correct
    • Ensure the data directory exists and has write permissions
    • Create the directory: mkdir -p data

    Peer Connection Failed

    • Verify peer addresses are reachable
    • Check firewall settings
    • Ensure peer nodes are running before starting your node

    Next Steps

    Observer Node

    Learn about observer nodes

    Configuration

    Advanced configuration options

    Build docs developers (and LLMs) love