From 52efb1ecefa22083cf4d6e07c181db544beab46b Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Fri, 7 Feb 2025 23:42:29 +0100 Subject: [PATCH 01/16] Add pipeline CI/CD --- .github/workflows/ci.yml | 130 +++++++++++++++++++++++++++++++++++++++ Dockerfile | 52 ++++++++++++++++ docker-compose.yml | 17 +++++ 3 files changed, 199 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..31ba609 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,130 @@ +name: Enokiweave CI/CD + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +env: + CARGO_TERM_COLOR: always + DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Install stable toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Set up cargo cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: ${{ runner.os }}-cargo- + + - name: Install LMDB + run: sudo apt-get update && sudo apt-get install -y liblmdb-dev + + - name: Run cargo fmt + run: cargo fmt --all -- --check + + - name: Run cargo clippy + run: cargo clippy -- -D warnings + + test: + name: Test Suite + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Install stable toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Set up cargo cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: ${{ runner.os }}-cargo- + + - name: Install LMDB + run: sudo apt-get update && sudo apt-get install -y liblmdb-dev + + - name: Run cargo test + run: cargo test + + build-and-push: + name: Build and Push Docker Image + needs: [check, test] + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ secrets.DOCKER_HUB_USERNAME }}/enokiweave + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha,format=long + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + release: + name: Create Release + needs: [build-and-push] + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + generate_release_notes: true + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3ee2f62 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,52 @@ +# Build stage +FROM rust:1.75-slim-bullseye as builder + +# Install system dependencies +RUN apt-get update && \ + apt-get install -y \ + pkg-config \ + liblmdb-dev \ + && rm -rf /var/lib/apt/lists/* + +# Create a new empty shell project +WORKDIR /usr/src/enokiweave + +# Copy manifests +COPY Cargo.lock Cargo.toml ./ + +# Copy source code +COPY src ./src +COPY setup ./setup + +# Build for release +RUN cargo build --release + +# Runtime stage +FROM debian:bullseye-slim + +# Install runtime dependencies +RUN apt-get update && \ + apt-get install -y \ + liblmdb0 \ + && rm -rf /var/lib/apt/lists/* + +# Copy the build artifacts from builder +COPY --from=builder /usr/src/enokiweave/target/release/enokiweave /usr/local/bin/ +COPY --from=builder /usr/src/enokiweave/target/release/build-transaction /usr/local/bin/ + +# Copy configuration files +COPY setup/example_genesis_file.json /etc/enokiweave/genesis.json +COPY setup/example_initial_peers_file.txt /etc/enokiweave/peers.txt + +# Create data directory +RUN mkdir -p /var/lib/enokiweave + +# Set working directory +WORKDIR /var/lib/enokiweave + +# Expose ports +EXPOSE 3001 + +# Set entrypoint +ENTRYPOINT ["enokiweave"] +CMD ["--genesis-file-path", "/etc/enokiweave/genesis.json", "--rpc_port", "3001"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..937a294 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + enokiweave: + image: ${DOCKER_HUB_USERNAME}/enokiweave:latest + ports: + - "3001:3001" + volumes: + - enokiweave-data:/var/lib/enokiweave + - ./setup/example_genesis_file.json:/etc/enokiweave/genesis.json + - ./setup/example_initial_peers_file.txt:/etc/enokiweave/peers.txt + environment: + - RUST_LOG=info + restart: unless-stopped + +volumes: + enokiweave-data: \ No newline at end of file From 788f8289f34f714ff0e024764a3330defaf8a7e9 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 00:01:45 +0100 Subject: [PATCH 02/16] update --- .github/workflows/ci.yml | 22 +++------------------- src/main.rs | 5 ++--- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 31ba609..d6d08f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ jobs: check: name: Check runs-on: ubuntu-latest + continue-on-error: true steps: - name: Checkout sources uses: actions/checkout@v4 @@ -74,7 +75,7 @@ jobs: build-and-push: name: Build and Push Docker Image - needs: [check, test] + needs: [test] runs-on: ubuntu-latest steps: - name: Checkout repository @@ -110,21 +111,4 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha - cache-to: type=gha,mode=max - - release: - name: Create Release - needs: [build-and-push] - if: startsWith(github.ref, 'refs/tags/') - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Create Release - uses: softprops/action-gh-release@v1 - with: - generate_release_notes: true - draft: false - prerelease: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e3650ac..ed6373c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -use anyhow::{anyhow, Result}; use clap::Parser; use libp2p::futures::StreamExt; use libp2p::mdns::tokio::Tokio; @@ -17,7 +16,7 @@ use std::error::Error; use std::sync::Arc; use tcp::tokio::Transport as TokioTransport; use tokio::sync::Mutex; -use tracing::{error, info, trace, warn}; +use tracing::{info, trace}; use transaction_manager::TransactionManager; use crate::rpc::run_http_rpc_server; @@ -27,7 +26,7 @@ mod rpc; mod transaction; mod transaction_manager; -const DB_NAME: &'static str = "./local_db/transaction_db"; +const DB_NAME: &str = "./local_db/transaction_db"; #[derive(NetworkBehaviour)] #[behaviour(out_event = "OutEvent")] From 4fbe49df5380dde4f55821e748bd73a096c48260 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 00:10:23 +0100 Subject: [PATCH 03/16] update --- src/address.rs | 4 ++++ src/main.rs | 2 +- src/rpc.rs | 2 +- src/transaction.rs | 6 ++---- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/address.rs b/src/address.rs index 8ec491c..3e7da54 100644 --- a/src/address.rs +++ b/src/address.rs @@ -1,20 +1,24 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; +#[allow(dead_code)] pub const ZERO_ADDRESS: Address = Address([0; 32]); #[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Clone, Copy)] pub struct Address(pub [u8; 32]); impl Address { + #[allow(dead_code)] pub fn new(data: [u8; 32]) -> Self { Self(data) } + #[allow(dead_code)] pub fn as_hex(&self) -> String { hex::encode(self.0) } + #[allow(dead_code)] pub fn from_hex(hex_address: &str) -> Result
{ let decoded = hex::decode(hex_address)?; let mut address = [0u8; 32]; diff --git a/src/main.rs b/src/main.rs index ed6373c..98a2ebf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ use std::error::Error; use std::sync::Arc; use tcp::tokio::Transport as TokioTransport; use tokio::sync::Mutex; -use tracing::{info, trace}; +use tracing::{info, trace, warn}; use transaction_manager::TransactionManager; use crate::rpc::run_http_rpc_server; diff --git a/src/rpc.rs b/src/rpc.rs index b63a893..99a7f6d 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpListener; use tokio::sync::{mpsc, oneshot, Mutex}; -use tracing::{error, info, trace, warn}; +use tracing::{error, info, trace}; use crate::address::Address; use crate::transaction::TransactionRequest; diff --git a/src/transaction.rs b/src/transaction.rs index 219f8cc..0d46b38 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -127,14 +127,12 @@ impl Transaction { pub fn calculate_id(&self) -> Result<[u8; 32]> { let mut hasher = Sha256::new(); hasher.update(self.amount.to_be_bytes()); - hasher.update(&self.from); - hasher.update(&self.to); + hasher.update(self.from); + hasher.update(self.to); hasher.update(self.timestamp.to_be_bytes()); let hash = &hasher.finalize()[..]; - let id: [u8; 32] = hash.try_into().expect("Wrong length"); - Ok(id) } } From b2c82fd4671394228f40994eaed872ad6564f9e6 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 00:17:12 +0100 Subject: [PATCH 04/16] update --- src/main.rs | 6 +++--- src/rpc.rs | 6 +++--- src/transaction.rs | 1 + src/transaction_manager.rs | 2 ++ 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 98a2ebf..4cedcce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,13 +42,13 @@ impl From for OutEvent { } impl From for OutEvent { fn from(value: MdnsEvent) -> Self { - OutEvent::Mdns(value) + OutEvent::Mdns(Box::new(value)) } } enum OutEvent { Floodsub(FloodsubEvent), - Mdns(MdnsEvent), + Mdns(Box), } #[derive(Deserialize)] @@ -112,7 +112,7 @@ fn are_all_peers_dead(peers: Vec, swarm: &mut Swarm { + Ok(0) => { trace!("Connection closed by client"); return; } @@ -215,7 +215,7 @@ async fn handle_rpc_request( Some("submitTransaction") => { let params = req["params"] .as_array() - .ok_or_else(|| "Invalid params - expected array")?; + .ok_or("Invalid params - expected array")?; if params.is_empty() { return Err("Empty params array".into()); @@ -248,7 +248,7 @@ async fn handle_rpc_request( Some("addressBalance") => { let params = req["params"] .as_str() - .ok_or_else(|| "Invalid params - expected str")?; + .ok_or("Invalid params - expected str")?; let address = Address::from_hex(params)?; // Create response channel diff --git a/src/transaction.rs b/src/transaction.rs index 0d46b38..e5a37a8 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -115,6 +115,7 @@ pub struct Transaction { } impl Transaction { + #[allow(dead_code)] pub fn new(from: Address, to: Address, amount: u64) -> Result { Ok(Self { from, diff --git a/src/transaction_manager.rs b/src/transaction_manager.rs index b5dc72c..363fbc1 100644 --- a/src/transaction_manager.rs +++ b/src/transaction_manager.rs @@ -231,6 +231,7 @@ impl TransactionManager { Ok(true) } + #[allow(dead_code)] pub fn get_transaction(&self, id: String) -> Result { let reader = self .lmdb_transaction_env @@ -249,6 +250,7 @@ impl TransactionManager { Ok(transaction) } + #[allow(dead_code)] pub fn get_all_transaction_ids(&self) -> Result> { let reader = self .lmdb_transaction_env From cfe6d1c14634fe64a600f7ce5d6844d734903d82 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 00:19:04 +0100 Subject: [PATCH 05/16] update --- src/main.rs | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4cedcce..46f3c5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,22 +76,24 @@ async fn handle_swarm_events(mut swarm: Swarm) { info!("Listening on {:?}", address); } SwarmEvent::Behaviour(OutEvent::Floodsub(FloodsubEvent::Message(_))) => {} - SwarmEvent::Behaviour(OutEvent::Mdns(MdnsEvent::Discovered(list))) => { - for (peer_id, _multiaddr) in list { - swarm - .behaviour_mut() - .floodsub - .add_node_to_partial_view(peer_id); + SwarmEvent::Behaviour(OutEvent::Mdns(mdns_event)) => match *mdns_event { + MdnsEvent::Discovered(list) => { + for (peer_id, _multiaddr) in list { + swarm + .behaviour_mut() + .floodsub + .add_node_to_partial_view(peer_id); + } } - } - SwarmEvent::Behaviour(OutEvent::Mdns(MdnsEvent::Expired(list))) => { - for (peer_id, _multiaddr) in list { - swarm - .behaviour_mut() - .floodsub - .remove_node_from_partial_view(&peer_id); + MdnsEvent::Expired(list) => { + for (peer_id, _multiaddr) in list { + swarm + .behaviour_mut() + .floodsub + .remove_node_from_partial_view(&peer_id); + } } - } + }, _ => {} } } From 81d9b256f8110a8246ff2fd0edd3ed67a247ad78 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 00:22:00 +0100 Subject: [PATCH 06/16] update --- src/rpc.rs | 1 - src/transaction_manager.rs | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/rpc.rs b/src/rpc.rs index b5b9838..3d51fb8 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -49,7 +49,6 @@ pub async fn run_http_rpc_server( match socket.read(&mut buf).await { Ok(0) => { trace!("Connection closed by client"); - return; } Ok(n) => { let request = String::from_utf8_lossy(&buf[..n]); diff --git a/src/transaction_manager.rs b/src/transaction_manager.rs index 363fbc1..f9300e0 100644 --- a/src/transaction_manager.rs +++ b/src/transaction_manager.rs @@ -51,7 +51,9 @@ pub struct TransactionManager { impl TransactionManager { pub fn new() -> Result { let env = LMDB_ENV.clone(); - let db = env.create_db(Some(DB_NAME), lmdb::DatabaseFlags::empty())?; + let db = env + .open(Path::new(DB_NAME)) + .expect("Failed to create LMDB environment"); Ok(TransactionManager { lmdb_transaction_env: env, From 22ac5db2cb30eca90cfcdff453d9edd684fd8ad3 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 00:24:00 +0100 Subject: [PATCH 07/16] update --- src/transaction_manager.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/transaction_manager.rs b/src/transaction_manager.rs index f9300e0..f0a053b 100644 --- a/src/transaction_manager.rs +++ b/src/transaction_manager.rs @@ -52,8 +52,7 @@ impl TransactionManager { pub fn new() -> Result { let env = LMDB_ENV.clone(); let db = env - .open(Path::new(DB_NAME)) - .expect("Failed to create LMDB environment"); + .create_db(None, lmdb::DatabaseFlags::empty())?; Ok(TransactionManager { lmdb_transaction_env: env, From bde9f85cc947ddddfd32801a85eab68f724ebc57 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 00:27:41 +0100 Subject: [PATCH 08/16] updaet --- src/transaction_manager.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/transaction_manager.rs b/src/transaction_manager.rs index f0a053b..e8d8f95 100644 --- a/src/transaction_manager.rs +++ b/src/transaction_manager.rs @@ -51,8 +51,7 @@ pub struct TransactionManager { impl TransactionManager { pub fn new() -> Result { let env = LMDB_ENV.clone(); - let db = env - .create_db(None, lmdb::DatabaseFlags::empty())?; + let db = env.create_db(None, lmdb::DatabaseFlags::empty())?; Ok(TransactionManager { lmdb_transaction_env: env, From feb14699289091f9dc214c86875af3d6148bae60 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 00:31:46 +0100 Subject: [PATCH 09/16] updaet --- src/transaction_manager.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/transaction_manager.rs b/src/transaction_manager.rs index e8d8f95..f0a053b 100644 --- a/src/transaction_manager.rs +++ b/src/transaction_manager.rs @@ -51,7 +51,8 @@ pub struct TransactionManager { impl TransactionManager { pub fn new() -> Result { let env = LMDB_ENV.clone(); - let db = env.create_db(None, lmdb::DatabaseFlags::empty())?; + let db = env + .create_db(None, lmdb::DatabaseFlags::empty())?; Ok(TransactionManager { lmdb_transaction_env: env, From b078ed8720ae981af14f83830e5bfa7757ac23d8 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 01:36:14 +0100 Subject: [PATCH 10/16] updaet --- src/transaction_manager.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/transaction_manager.rs b/src/transaction_manager.rs index f0a053b..e8d8f95 100644 --- a/src/transaction_manager.rs +++ b/src/transaction_manager.rs @@ -51,8 +51,7 @@ pub struct TransactionManager { impl TransactionManager { pub fn new() -> Result { let env = LMDB_ENV.clone(); - let db = env - .create_db(None, lmdb::DatabaseFlags::empty())?; + let db = env.create_db(None, lmdb::DatabaseFlags::empty())?; Ok(TransactionManager { lmdb_transaction_env: env, From 3019f26f983751a8e7d7ea2c1a2e5201a1953bc0 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 01:38:53 +0100 Subject: [PATCH 11/16] updaet --- src/transaction_manager.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transaction_manager.rs b/src/transaction_manager.rs index e8d8f95..aa11d9c 100644 --- a/src/transaction_manager.rs +++ b/src/transaction_manager.rs @@ -23,7 +23,7 @@ static LMDB_ENV: Lazy> = Lazy::new(|| { .set_max_dbs(1) .set_map_size(10 * 1024 * 1024) .set_max_readers(126) - .open(&Path::new(DB_NAME)) + .open(Path::new(DB_NAME)) .expect("Failed to create LMDB environment"), ) }); From 3a60daf142f6a86d1d56023a4d176e9d9237f73e Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 01:42:10 +0100 Subject: [PATCH 12/16] updaet --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d6d08f1..b6106f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,8 +87,8 @@ jobs: - name: Login to Docker Hub uses: docker/login-action@v3 with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta From 90b1c41a995d242a7a4507a4c3a1f63dcc61857d Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 01:51:07 +0100 Subject: [PATCH 13/16] updaet --- .github/workflows/ci.yml | 112 ++++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6106f5..ff5349a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,20 +1,49 @@ name: Enokiweave CI/CD +permissions: {} # Default to no permissions + on: push: - branches: [ main ] + branches: [ '**' ] pull_request: branches: [ main ] + workflow_dispatch: env: CARGO_TERM_COLOR: always - DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + REGISTRY: docker.io + REPOSITORY: myceliumai + IMAGE_NAME: enokiweave jobs: + changes: + runs-on: ubuntu-latest + permissions: + pull-requests: read + contents: read + outputs: + core: ${{ steps.filter.outputs.core }} + steps: + - uses: actions/checkout@v4 + + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + core: + - 'src/**' + - 'Cargo.*' + - '.github/workflows/**' + - 'Dockerfile' + check: + needs: changes + if: ${{ needs.changes.outputs.core == 'true' }} name: Check runs-on: ubuntu-latest continue-on-error: true + permissions: + contents: read steps: - name: Checkout sources uses: actions/checkout@v4 @@ -46,8 +75,12 @@ jobs: run: cargo clippy -- -D warnings test: + needs: changes + if: ${{ needs.changes.outputs.core == 'true' }} name: Test Suite runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Checkout sources uses: actions/checkout@v4 @@ -73,42 +106,71 @@ jobs: - name: Run cargo test run: cargo test - build-and-push: - name: Build and Push Docker Image - needs: [test] + security: + name: Security Checks runs-on: ubuntu-latest + permissions: + contents: read + security-events: write steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - uses: actions/checkout@v4 + - uses: aquasecurity/trivy-action@master + with: + scan-type: 'fs' + scan-ref: '.' + format: 'sarif' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + scanners: 'vuln,secret,config' + - uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: 'trivy-results.sarif' + category: 'trivy' - - name: Login to Docker Hub - uses: docker/login-action@v3 + build: + needs: [changes, security, check, test] + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Check if should build + id: should_build + run: | + if [[ + "${{ github.event_name }}" == "push" && + "${{ needs.changes.outputs.core }}" == "true" + ]]; then + echo "run=true" >> $GITHUB_OUTPUT + fi + + - uses: actions/checkout@v4 + if: steps.should_build.outputs.run == 'true' + + - uses: docker/setup-buildx-action@v3 + if: steps.should_build.outputs.run == 'true' + + - uses: docker/login-action@v3 + if: steps.should_build.outputs.run == 'true' with: + registry: ${{ env.REGISTRY }} username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Extract metadata (tags, labels) for Docker + - uses: docker/metadata-action@v5 + if: steps.should_build.outputs.run == 'true' id: meta - uses: docker/metadata-action@v5 with: - images: ${{ secrets.DOCKER_HUB_USERNAME }}/enokiweave + images: ${{ env.REGISTRY }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }} tags: | - type=raw,value=latest,enable={{is_default_branch}} - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest type=sha,format=long - - name: Build and push Docker image - uses: docker/build-push-action@v5 + - uses: docker/build-push-action@v5 + if: steps.should_build.outputs.run == 'true' with: context: . - push: ${{ github.event_name != 'pull_request' }} + push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max \ No newline at end of file + cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:buildcache + cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.REPOSITORY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max \ No newline at end of file From 1b79da3f21661c671637259f2edc1d084df50d34 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 01:53:31 +0100 Subject: [PATCH 14/16] updaet --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff5349a..98fe8c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,8 +5,6 @@ permissions: {} # Default to no permissions on: push: branches: [ '**' ] - pull_request: - branches: [ main ] workflow_dispatch: env: From 18d3361934ec70f8d77bc30c5fb32fb522675510 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 02:01:20 +0100 Subject: [PATCH 15/16] updaet --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 98fe8c6..9b7b86f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,6 +136,7 @@ jobs: run: | if [[ "${{ github.event_name }}" == "push" && + "${{ github.ref }}" == "refs/heads/main" && "${{ needs.changes.outputs.core }}" == "true" ]]; then echo "run=true" >> $GITHUB_OUTPUT From 7ab80d2c25ce248ff6bb2e6ffba6ff1ee5733601 Mon Sep 17 00:00:00 2001 From: ThomasGraff Date: Sat, 8 Feb 2025 02:04:32 +0100 Subject: [PATCH 16/16] updaet --- Dockerfile | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3ee2f62..6001864 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM rust:1.75-slim-bullseye as builder # Install system dependencies RUN apt-get update && \ - apt-get install -y \ + apt-get install -y --no-install-recommends \ pkg-config \ liblmdb-dev \ && rm -rf /var/lib/apt/lists/* @@ -26,10 +26,17 @@ FROM debian:bullseye-slim # Install runtime dependencies RUN apt-get update && \ - apt-get install -y \ + apt-get install -y --no-install-recommends \ liblmdb0 \ && rm -rf /var/lib/apt/lists/* +# Create non-root user +RUN groupadd -r enoki && useradd -r -g enoki enoki + +# Create necessary directories and set permissions +RUN mkdir -p /var/lib/enokiweave /etc/enokiweave && \ + chown -R enoki:enoki /var/lib/enokiweave /etc/enokiweave + # Copy the build artifacts from builder COPY --from=builder /usr/src/enokiweave/target/release/enokiweave /usr/local/bin/ COPY --from=builder /usr/src/enokiweave/target/release/build-transaction /usr/local/bin/ @@ -38,15 +45,19 @@ COPY --from=builder /usr/src/enokiweave/target/release/build-transaction /usr/lo COPY setup/example_genesis_file.json /etc/enokiweave/genesis.json COPY setup/example_initial_peers_file.txt /etc/enokiweave/peers.txt -# Create data directory -RUN mkdir -p /var/lib/enokiweave - # Set working directory WORKDIR /var/lib/enokiweave +# Switch to non-root user +USER enoki + # Expose ports EXPOSE 3001 +# Add healthcheck +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:3001/health || exit 1 + # Set entrypoint ENTRYPOINT ["enokiweave"] CMD ["--genesis-file-path", "/etc/enokiweave/genesis.json", "--rpc_port", "3001"] \ No newline at end of file