Overview
Thesubmit command creates a new block containing election results from a polling station and submits it to a submission node via HTTP. The block is cryptographically signed and includes a Merkle tree root for result verification.
Syntax
Parameters
The HTTP address of the submission node to send the block to. Include the protocol and port.Example:
http://localhost:3000 or https://node.example.comThe unique identifier of the polling station where votes were cast. This should match a station ID in your database.Example:
022113056303301The unique identifier of the candidate receiving votes. This should match a candidate ID in your database.Example:
1The number of votes the candidate received at this station. Must be a positive integer.Example:
66How It Works
Retrieve Chain State
The command connects to your local blockchain database and retrieves:
- Current blockchain height
- Hash of the most recent block
- Your private signing key
Build Merkle Tree
Constructs a Merkle tree from the election results to enable efficient verification:
- Each result is hashed
- Hashes are combined into a tree structure
- Root hash is calculated
Create Block
Generates a new block with:
- Previous block hash (chain linkage)
- Height (current height + 1)
- Election results
- Merkle root hash
- Cryptographic signature
Examples
Submit Single Result
Submit to Remote Node
Submit Multiple Results
To submit results for multiple candidates at the same station, run the command multiple times:Each submission creates a separate block. Currently, the CLI submits one result per block. For batch submissions, consider using the REST API directly.
Block Structure
Each submitted block contains:Submission Node Validation
When the submission node receives your block, it validates:- Signature: Verifies the block is signed by an authorized key
- Chain Continuity: Ensures
prev_hashmatches the latest block - Height: Confirms height is current height + 1
- Merkle Root: Validates the Merkle tree root matches the results
- Result Format: Checks that station_id, candidate_id exist and votes are valid
- Consensus: May require consensus from other nodes depending on configuration
Error Responses
Failed to Submit Block
- Invalid station_id or candidate_id
- Malformed block data
- Block already exists at this height
Connection Error
- Submission node is not running
- Incorrect node address
- Network connectivity issues
- Firewall blocking connection
Unauthorized
- Your public key is not registered with the submission node
- Signature validation failed
- You don’t have permission to submit to this node
Prerequisites
Initialized Blockchain
Initialized Blockchain
You must have a blockchain initialized with
ubu-block init before submitting results.Valid Station and Candidate IDs
Valid Station and Candidate IDs
The
station_id and candidate_id must exist in your local database schema.Running Submission Node
Running Submission Node
A submission node must be running and accessible at the specified address.
Network Access
Network Access
Your machine must have network access to reach the submission node.
Security Considerations
- Authentication: Only nodes with registered public keys can submit blocks
- Non-repudiation: Each block is cryptographically signed and cannot be forged
- Audit Trail: All submissions (accepted and rejected) are logged by submission nodes
- Tamper Evidence: Any modification to block data invalidates the signature
Best Practices
- Verify Before Submitting: Ensure data accuracy before submission
- Check Node Status: Confirm the submission node is operational
- Monitor Responses: Watch for error messages and handle them appropriately
- Batch Operations: For multiple results, consider scripting submissions
- Backup Keys: Always maintain secure backups of your private database
- Test Locally: Test submissions on a local node before using production nodes
Troubleshooting
Can’t Find Private Key
init to generate keys, and the private database path in your config is correct.
Invalid Block Height
Station/Candidate Not Found
If the submission succeeds but node validation fails:- Verify station_id exists in the stations table
- Verify candidate_id exists in the candidates table
- Check that IDs match the format expected by the node
Implementation Details
The submit command is implemented inapps/cli/src/main.rs:74-131 and:
- Uses Ed25519 signatures for block signing
- Constructs Merkle trees with SHA-256 hashing
- Sends blocks via HTTP POST with JSON encoding
- Retrieves chain state from local SQLite databases
- Validates result format before creating blocks
Next Steps
Query Results
Query submitted results from the blockchain
Validate Chain
Verify blockchain integrity after submission
Submission Nodes
Learn more about running submission nodes
REST API
Submit via the REST API for batch operations