28
.dockerignore
Normal file
28
.dockerignore
Normal file
@@ -0,0 +1,28 @@
|
||||
# Rust build artifacts
|
||||
/target/
|
||||
**/*.rs.bk
|
||||
|
||||
# Git directory
|
||||
.git/
|
||||
.github/
|
||||
.gitignore
|
||||
|
||||
# Editor files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Node.js files (from packages directory)
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
|
||||
# Other unnecessary files
|
||||
*.md
|
||||
LICENSE
|
||||
*.log
|
||||
.DS_Store
|
||||
|
||||
# Keep necessary files
|
||||
!Cargo.toml
|
||||
!Cargo.lock
|
73
Dockerfile
Normal file
73
Dockerfile
Normal file
@@ -0,0 +1,73 @@
|
||||
# Multistage Dockerfile for gsio-node
|
||||
|
||||
# Build stage
|
||||
FROM rust:slim as builder
|
||||
|
||||
# Install build dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
pkg-config \
|
||||
libssl-dev \
|
||||
build-essential \
|
||||
git \
|
||||
ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create a new empty project
|
||||
WORKDIR /app
|
||||
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY crates/gsio-node/Cargo.toml ./crates/gsio-node/
|
||||
COPY crates/gsio-relay/Cargo.toml ./crates/gsio-relay/
|
||||
COPY crates/gsio-client/Cargo.toml ./crates/gsio-client/
|
||||
COPY crates/gsio-wallet/Cargo.toml ./crates/gsio-wallet/
|
||||
|
||||
# Create dummy source files to build dependencies
|
||||
RUN mkdir -p crates/gsio-node/src && \
|
||||
echo 'fn main() { println!("Dummy!"); }' > crates/gsio-node/src/main.rs && \
|
||||
mkdir -p crates/gsio-relay/src && \
|
||||
echo 'fn main() { println!("Dummy!"); }' > crates/gsio-relay/src/lib.rs && \
|
||||
mkdir -p crates/gsio-client/src && \
|
||||
echo 'fn main() { println!("Dummy!"); }' > crates/gsio-client/src/main.rs && \
|
||||
mkdir -p crates/gsio-wallet/src && \
|
||||
echo 'pub fn dummy() {}' > crates/gsio-wallet/src/lib.rs
|
||||
|
||||
# Create dummy source files to build dependencies
|
||||
|
||||
|
||||
# Build dependencies - this will be cached if dependencies don't change
|
||||
RUN cargo build --release --bin gsio-node
|
||||
|
||||
# Remove the dummy source files
|
||||
RUN rm -rf crates/*/src
|
||||
|
||||
# Copy the actual source code
|
||||
COPY crates ./crates
|
||||
|
||||
# Build the application
|
||||
RUN cargo build --release --bin gsio-node
|
||||
|
||||
# Runtime stage
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
libssl3 \
|
||||
wget \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create a non-root user to run the application
|
||||
RUN useradd -m appuser
|
||||
USER appuser
|
||||
WORKDIR /home/appuser
|
||||
|
||||
# Copy the binary from the builder stage
|
||||
COPY --from=builder --chown=appuser:appuser /app/target/release/gsio-node .
|
||||
|
||||
# Expose the port the app runs on
|
||||
EXPOSE 3000
|
||||
|
||||
# Command to run the application
|
||||
CMD ["./gsio-node"]
|
@@ -2,6 +2,14 @@
|
||||
[](https://github.com/seemueller-io/gsio-net/actions/workflows/main.yml)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
Warning: This API is unstable.
|
||||
|
||||
## run a network
|
||||
```yaml
|
||||
docker compose build
|
||||
docker compose up
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
@@ -195,6 +195,7 @@ async fn on_peer_message(
|
||||
/// ---- Individual peer-message helpers ----
|
||||
async fn handle_peer_discovered(socket: SocketRef, p2p: Arc<P2PManager>, data: &JsonValue) {
|
||||
if let Some(peer_id) = data.get("peer_id").and_then(|id| id.as_str()) {
|
||||
info!(peer_id = peer_id, "Peer discovered, initiating peering");
|
||||
p2p.ledger.add_known_node(peer_id.to_owned());
|
||||
socket
|
||||
.emit(
|
||||
@@ -207,10 +208,12 @@ async fn handle_peer_discovered(socket: SocketRef, p2p: Arc<P2PManager>, data: &
|
||||
|
||||
async fn handle_advertise(socket: SocketRef, p2p: Arc<P2PManager>, data: &JsonValue) {
|
||||
if let Some(peer_id) = data.get("peer_id").and_then(|id| id.as_str()) {
|
||||
info!(peer_id = peer_id, "Received peer advertisement, establishing connection");
|
||||
p2p.ledger.add_known_node(peer_id.to_owned());
|
||||
socket
|
||||
.emit("peer_ack", &json!({ "type": "ack", "peer_id": p2p.node_id() }))
|
||||
.ok();
|
||||
info!(peer_id = peer_id, "Sent acknowledgment to peer, connection established");
|
||||
socket
|
||||
.emit(
|
||||
"peer_sync_request",
|
||||
@@ -235,6 +238,10 @@ async fn handle_sync_request(socket: SocketRef, p2p: Arc<P2PManager>, _data: &Js
|
||||
}
|
||||
|
||||
async fn handle_sync_response(_socket: SocketRef, p2p: Arc<P2PManager>, data: &JsonValue) {
|
||||
if let Some(peer_id) = data.get("peer_id").and_then(|id| id.as_str()) {
|
||||
info!(peer_id = peer_id, "Received sync response from peer, peering active");
|
||||
}
|
||||
|
||||
if let Some(entries_val) = data.get("entries") {
|
||||
if let Ok(entries) = serde_json::from_value::<Vec<LedgerEntry>>(entries_val.clone()) {
|
||||
for e in entries {
|
||||
|
@@ -123,18 +123,19 @@ impl P2PManager {
|
||||
|
||||
/// Handle a new connection from another node
|
||||
pub fn handle_connection(&self, socket: SocketRef, data: JsonValue) {
|
||||
info!(ns = socket.ns(), ?socket.id, "P2P node connected");
|
||||
|
||||
// Extract the node ID from the connection data
|
||||
let node_id = match data.get("node_id") {
|
||||
Some(id) => id.as_str().unwrap_or("unknown").to_string(),
|
||||
None => "unknown".to_string(),
|
||||
};
|
||||
|
||||
info!(ns = socket.ns(), ?socket.id, node_id = node_id, "P2P node connected, establishing peering");
|
||||
|
||||
// Add the node to the connected nodes
|
||||
{
|
||||
let mut connected_nodes = self.connected_nodes.lock().unwrap();
|
||||
connected_nodes.insert(node_id.clone(), socket.clone());
|
||||
info!(peer_id = node_id, "Successfully peered with node");
|
||||
}
|
||||
|
||||
// Add the node to the known nodes in the ledger
|
||||
|
86
docker-compose.yml
Normal file
86
docker-compose.yml
Normal file
@@ -0,0 +1,86 @@
|
||||
version: '3.8'
|
||||
# GSIO-Net Docker Compose Configuration
|
||||
#
|
||||
# This file defines a network of GSIO-Net nodes that can communicate with each other.
|
||||
# It creates three nodes, each exposing the API on a different host port:
|
||||
# - node1: http://localhost:3001
|
||||
# - node2: http://localhost:3002
|
||||
# - node3: http://localhost:3003
|
||||
#
|
||||
# Usage:
|
||||
# - Start the network: docker-compose up -d
|
||||
# - View logs: docker-compose logs -f
|
||||
# - Stop the network: docker-compose down
|
||||
# - Stop and remove volumes: docker-compose down -v
|
||||
|
||||
services:
|
||||
# Node 1
|
||||
node1:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: gsio-node1
|
||||
ports:
|
||||
- "3001:3000" # Map to different host ports to avoid conflicts
|
||||
volumes:
|
||||
- node1-data:/home/appuser/data
|
||||
networks:
|
||||
- gsio-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# Node 2
|
||||
node2:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: gsio-node2
|
||||
ports:
|
||||
- "3002:3000"
|
||||
volumes:
|
||||
- node2-data:/home/appuser/data
|
||||
networks:
|
||||
- gsio-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# Node 3
|
||||
node3:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: gsio-node3
|
||||
ports:
|
||||
- "3003:3000"
|
||||
volumes:
|
||||
- node3-data:/home/appuser/data
|
||||
networks:
|
||||
- gsio-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# Define volumes for persistent storage
|
||||
volumes:
|
||||
node1-data:
|
||||
node2-data:
|
||||
node3-data:
|
||||
|
||||
# Define a custom network for the nodes to communicate
|
||||
networks:
|
||||
gsio-network:
|
||||
driver: bridge
|
Reference in New Issue
Block a user