From 988bcff5784adabe60ff2a6f60fa7e2029383884 Mon Sep 17 00:00:00 2001 From: 0xgetz <6snzga6@zenvex.edu.pl> Date: Thu, 16 Apr 2026 01:19:38 +0000 Subject: [PATCH 1/4] fix(ci): correct sanitizer flag, pin RandomX SHA, add macOS + ASan/UBSan + functional test jobs - Fix typo: -DSANITIZE -> -DSANITIZER in pr-ci.yml so AddressSanitizer and UBSan are actually enabled in CI (were silently ignored before) - Pin RandomX GIT_TAG from floating origin/master to specific commit SHA 051d4424394cf8d1f8d0bfff581f0729f2753341 to eliminate supply chain risk - Remove GIT_SHALLOW from RandomX fetch (incompatible with pinned SHA) - Add macOS 14 (Apple Silicon) CI job - Add Linux Clang 18 ASan and UBSan matrix jobs - Add functional-tests CI job running Python test suite on every PR - Make nproc call portable for macOS (nproc || sysctl -n hw.logicalcpu) --- .github/workflows/pr-ci.yml | 86 +++++++++++++++++++++++++++++++++++-- CMakeLists.txt | 3 +- 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index 15cb9f4..fff43d2 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -36,6 +36,28 @@ jobs: cxx: g++-11 sanitizer: none + - name: Linux Clang 18 ASan + os: ubuntu-22.04 + compiler: clang + cc: clang-18 + cxx: clang++-18 + sanitizer: address + + - name: Linux Clang 18 UBSan + os: ubuntu-22.04 + compiler: clang + cc: clang-18 + cxx: clang++-18 + sanitizer: undefined + + # macOS builds + - name: macOS Clang (Xcode) + os: macos-14 + compiler: clang + cc: clang + cxx: clang++ + sanitizer: none + steps: - uses: actions/checkout@v4 with: @@ -68,6 +90,13 @@ jobs: sudo apt-get install -y g++-11 gcc-11 fi + # Install dependencies - macOS + - name: Install dependencies (macOS) + if: runner.os == 'macOS' + run: | + brew update + brew install boost miniupnpc + # Configure build - name: Configure CMake run: | @@ -78,7 +107,7 @@ jobs: cmake -B build \ -DCMAKE_CXX_COMPILER=$CXX \ -DCMAKE_C_COMPILER=$CC \ - -DSANITIZE=${{ matrix.sanitizer }} \ + -DSANITIZER=${{ matrix.sanitizer }} \ -DCMAKE_BUILD_TYPE=RelWithDebInfo else cmake -B build \ @@ -89,7 +118,7 @@ jobs: # Build - name: Build - run: cmake --build build -j$(nproc) + run: cmake --build build -j$(nproc 2>/dev/null || sysctl -n hw.logicalcpu) # Run tests # Exclude [real] transport tests (require actual TCP sockets), [rpc] tests @@ -106,10 +135,57 @@ jobs: name: test-logs-${{ matrix.name }} path: build/Testing/Temporary/ + # Functional tests (Linux only — requires Python 3 + built binary) + functional-tests: + name: Functional Tests + runs-on: ubuntu-22.04 + needs: build-test + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + lfs: true + + - name: Cache CMake build + uses: actions/cache@v4 + with: + path: | + build/_deps + key: ${{ runner.os }}-cmake-${{ hashFiles('CMakeLists.txt') }} + restore-keys: | + ${{ runner.os }}-cmake- + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y libboost-system-dev libboost-filesystem-dev libminiupnpc-dev python3 python3-pip + + - name: Configure and build + run: | + cmake -B build \ + -DCMAKE_CXX_COMPILER=g++ \ + -DCMAKE_C_COMPILER=gcc \ + -DCMAKE_BUILD_TYPE=Release + cmake --build build -j$(nproc) + + - name: Run functional tests + run: | + cd test/functional + python3 test_runner.py --timeout 120 2>&1 + timeout-minutes: 15 + + - name: Upload functional test logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: functional-test-logs + path: test/functional/ + # Summary job - required to pass before merge all-checks-passed: name: All Checks Passed - needs: [build-test] + needs: [build-test, functional-tests] runs-on: ubuntu-latest if: always() @@ -120,4 +196,8 @@ jobs: echo "Build/test jobs failed" exit 1 fi + if [ "${{ needs.functional-tests.result }}" != "success" ]; then + echo "Functional tests failed" + exit 1 + fi echo "All checks passed" diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e9b438..3f1d3a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,8 +158,7 @@ target_compile_definitions(asio INTERFACE ASIO_STANDALONE) FetchContent_Declare( randomx GIT_REPOSITORY https://github.com/unicitynetwork/RandomX.git - GIT_TAG origin/master - GIT_SHALLOW TRUE + GIT_TAG 051d4424394cf8d1f8d0bfff581f0729f2753341 ) set(RANDOMX_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(RANDOMX_BUILD_BENCHMARKS OFF CACHE BOOL "" FORCE) From 857e8e2fcecbe673c39f5b3372ca6b5ed4af01d6 Mon Sep 17 00:00:00 2001 From: 0xgetz <6snzga6@zenvex.edu.pl> Date: Thu, 16 Apr 2026 01:19:47 +0000 Subject: [PATCH 2/4] docs: add SECURITY.md, CONTRIBUTING.md, PR template, and issue templates - SECURITY.md: responsible disclosure policy, response timeline (48h ack, 7d assessment, 90d fix), scope definition, node operator best practices - CONTRIBUTING.md: dev setup, build instructions, sanitizer usage, coding standards, test instructions, branch naming, commit message conventions, PR/review process - .github/PULL_REQUEST_TEMPLATE: structured checklist with consensus-impact flag requiring two maintainer reviews for consensus-critical changes - .github/ISSUE_TEMPLATE/bug_report.yml: structured bug report with OS, compiler, reproduction steps, and log fields - .github/ISSUE_TEMPLATE/feature_request.yml: feature proposal with problem/solution/alternatives and codebase area dropdown - .github/ISSUE_TEMPLATE/consensus_issue.yml: dedicated template for consensus-critical bugs with impact assessment - .github/ISSUE_TEMPLATE/config.yml: disable blank issues, link security contact to SECURITY.md --- .github/ISSUE_TEMPLATE/bug_report.yml | 98 ++++++++++ .github/ISSUE_TEMPLATE/config.yml | 8 + .github/ISSUE_TEMPLATE/consensus_issue.yml | 83 +++++++++ .github/ISSUE_TEMPLATE/feature_request.yml | 66 +++++++ .../pull_request_template.md | 51 +++++ CONTRIBUTING.md | 175 ++++++++++++++++++ SECURITY.md | 60 ++++++ 7 files changed, 541 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/consensus_issue.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..4e05335 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,98 @@ +name: Bug Report +description: Report a bug or unexpected behavior in unicity-node +title: "[Bug]: " +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to file a bug report. Please fill out all sections + to help us reproduce and fix the issue quickly. + + **For security vulnerabilities, do NOT use this form.** See [SECURITY.md](../SECURITY.md). + + - type: textarea + id: description + attributes: + label: Description + description: A clear and concise description of the bug. + placeholder: "When I do X, Y happens instead of Z." + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Steps to Reproduce + description: Exact steps to reproduce the behavior. + placeholder: | + 1. Build with ... + 2. Run with flags ... + 3. Send P2P message ... + 4. See error ... + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected Behavior + description: What did you expect to happen? + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual Behavior + description: What actually happened? Include any error messages or logs. + validations: + required: true + + - type: input + id: commit + attributes: + label: Commit / Version + description: Git commit SHA or branch where the bug was observed. + placeholder: "e.g. a1b2c3d or main" + validations: + required: true + + - type: dropdown + id: os + attributes: + label: Operating System + options: + - Ubuntu 22.04 + - Ubuntu 20.04 + - macOS 14 (Sonoma) + - macOS 13 (Ventura) + - Other Linux + - Other + validations: + required: true + + - type: input + id: compiler + attributes: + label: Compiler & Version + placeholder: "e.g. clang-18, g++-11" + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Relevant Log Output + description: Paste any relevant log output here (node logs, sanitizer output, crash traces). + render: shell + + - type: checkboxes + id: checklist + attributes: + label: Checklist + options: + - label: I have searched existing issues and this is not a duplicate + required: true + - label: This is not a security vulnerability (see SECURITY.md for those) + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..618e049 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Security Vulnerability + url: https://github.com/unicitynetwork/unicity-node/blob/main/SECURITY.md + about: Please report security vulnerabilities via the private disclosure process described in SECURITY.md + - name: General Discussion + url: https://github.com/unicitynetwork/unicity-node/discussions + about: For questions and general discussion about unicity-node diff --git a/.github/ISSUE_TEMPLATE/consensus_issue.yml b/.github/ISSUE_TEMPLATE/consensus_issue.yml new file mode 100644 index 0000000..cbc9239 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/consensus_issue.yml @@ -0,0 +1,83 @@ +name: Consensus Issue +description: Report a potential consensus bug, divergence, or rule violation +title: "[Consensus]: " +labels: ["consensus", "critical"] +body: + - type: markdown + attributes: + value: | + Consensus bugs are the most critical category of issues in a blockchain node. + Please provide as much detail as possible. + + **If this could be exploited to attack the network, use the private disclosure + process in [SECURITY.md](../SECURITY.md) instead of this public form.** + + - type: textarea + id: description + attributes: + label: Description + description: Describe the consensus issue clearly. + validations: + required: true + + - type: dropdown + id: category + attributes: + label: Category + options: + - Block validation rule violation + - Difficulty adjustment (ASERT) error + - Fork resolution / chain selection bug + - RandomX PoW verification error + - Timestamp validation issue + - Peer divergence (nodes disagree on chain tip) + - Other + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Steps to Reproduce + description: How can maintainers reproduce this issue? + placeholder: | + 1. Build node at commit ... + 2. Sync to block height ... + 3. Submit block with headers ... + 4. Node accepts/rejects incorrectly + validations: + required: true + + - type: textarea + id: impact + attributes: + label: Impact + description: What is the potential impact? (e.g., chain split, double-spend, node crash) + validations: + required: true + + - type: input + id: commit + attributes: + label: Affected Commit / Version + placeholder: "e.g. a1b2c3d or main" + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Relevant Logs / Chain Data + render: shell + + - type: checkboxes + id: checklist + attributes: + label: Checklist + options: + - label: I have confirmed this is reproducible + required: true + - label: I have checked that this is not a known/documented behavior + required: true + - label: This issue does NOT require private disclosure (not exploitable) + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..718b7c0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,66 @@ +name: Feature Request +description: Propose a new feature or improvement for unicity-node +title: "[Feature]: " +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Thanks for proposing an improvement! Please fill in as much detail as possible + so maintainers can evaluate the proposal efficiently. + + - type: textarea + id: problem + attributes: + label: Problem / Motivation + description: What problem does this feature solve? What use case does it enable? + placeholder: "Currently, there is no way to ... which means ..." + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed Solution + description: Describe the feature you would like to see implemented. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives Considered + description: Have you considered other approaches? Why is your proposed solution preferred? + + - type: dropdown + id: area + attributes: + label: Area of the Codebase + options: + - Chain / Consensus + - P2P Networking + - RPC + - CI / Build System + - Documentation + - Testing + - Performance + - Security + - Other + validations: + required: true + + - type: checkboxes + id: consensus + attributes: + label: Consensus Impact + options: + - label: This feature would change consensus rules (requires broader discussion) + + - type: checkboxes + id: checklist + attributes: + label: Checklist + options: + - label: I have searched existing issues and this is not a duplicate + required: true + - label: I am willing to help implement this feature diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000..a28e6c5 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,51 @@ +## Summary + + + +Fixes # + +## Type of Change + + + +- [ ] Bug fix (non-breaking change that fixes an issue) +- [ ] New feature (non-breaking change that adds functionality) +- [ ] Breaking change (fix or feature that would cause existing behavior to change) +- [ ] CI / tooling improvement +- [ ] Documentation update +- [ ] Refactor (no functional change) +- [ ] Performance improvement + +## Changes Made + + + +- +- +- + +## Testing + + + +- [ ] Unit tests pass locally: `./build/bin/unicity_tests -d yes "~[real]" "~[rpc]" "~[slow]"` +- [ ] Functional tests pass locally: `cd test/functional && python3 test_runner.py` +- [ ] New tests added for new behavior (if applicable) +- [ ] Tested with AddressSanitizer: `cmake -DSANITIZER=address ...` + +## Consensus Impact + + + +- [ ] This PR does NOT affect consensus rules +- [ ] This PR DOES affect consensus rules (requires two maintainer reviews) + +If consensus-affecting, describe the change and any backward-compatibility considerations: + +## Checklist + +- [ ] Code follows the project style (`clang-format` applied) +- [ ] `clang-tidy` warnings addressed +- [ ] Self-reviewed the diff for unintended changes +- [ ] Updated relevant documentation (README, ARCHITECTURE.md, etc.) +- [ ] Commit messages follow Conventional Commits format diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7776097 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,175 @@ +# Contributing to unicity-node + +Thank you for your interest in contributing to the Unicity Node! This document covers +how to get your development environment set up, the coding standards we follow, and +the process for submitting changes. + +## Table of Contents + +- [Getting Started](#getting-started) +- [Development Setup](#development-setup) +- [Coding Standards](#coding-standards) +- [Testing](#testing) +- [Submitting Changes](#submitting-changes) +- [Commit Messages](#commit-messages) +- [Review Process](#review-process) + +--- + +## Getting Started + +1. **Fork** the repository on GitHub +2. **Clone** your fork locally: + ```bash + git clone git@github.com:/unicity-node.git + cd unicity-node + ``` +3. **Add upstream** remote: + ```bash + git remote add upstream https://github.com/unicitynetwork/unicity-node.git + ``` + +--- + +## Development Setup + +### Prerequisites + +- C++20-capable compiler: **Clang 18+** (recommended) or **GCC 11+** +- **CMake 3.20+** +- **Boost** (system, filesystem) +- **libminiupnpc** +- **Python 3.9+** (for functional tests) + +### Build + +```bash +cmake -B build -DCMAKE_BUILD_TYPE=Debug +cmake --build build -j$(nproc) +``` + +### Build with Sanitizers + +```bash +# AddressSanitizer +cmake -B build -DSANITIZER=address -DCMAKE_BUILD_TYPE=RelWithDebInfo +cmake --build build -j$(nproc) + +# ThreadSanitizer +cmake -B build -DSANITIZER=thread -DCMAKE_BUILD_TYPE=RelWithDebInfo +cmake --build build -j$(nproc) + +# UndefinedBehaviorSanitizer +cmake -B build -DSANITIZER=undefined -DCMAKE_BUILD_TYPE=RelWithDebInfo +cmake --build build -j$(nproc) +``` + +--- + +## Coding Standards + +- **C++20** throughout; use modern idioms (ranges, concepts, structured bindings) +- Follow the existing **clang-format** style (run `clang-format -i` before committing) +- Run **clang-tidy** and address all warnings +- Run **cppcheck** for static analysis +- No `assert()` for consensus invariants in release builds — use explicit error handling +- No raw owning pointers; prefer `std::unique_ptr` / `std::shared_ptr` +- Thread safety: the network layer uses a single-threaded Asio reactor — do not introduce + locking without discussion + +### Auto-format + +```bash +find src include -name "*.cpp" -o -name "*.h" | xargs clang-format -i +``` + +--- + +## Testing + +### Unit Tests + +```bash +# Run all fast tests +./build/bin/unicity_tests -d yes "~[real]" "~[rpc]" "~[slow]" + +# Run everything including slow tests +./build/bin/unicity_tests -d yes +``` + +### Functional Tests + +```bash +cd test/functional +python3 test_runner.py +``` + +### Adding Tests + +- Unit tests live in `test/unit/` and use **Catch2** +- Functional tests live in `test/functional/` and use the Python test framework +- New consensus rules **must** have unit tests +- New P2P message handling **must** have functional tests + +--- + +## Submitting Changes + +1. **Create a branch** from `main`: + ```bash + git checkout -b feat/my-feature + ``` +2. **Make your changes**, committing incrementally with clear messages +3. **Run the full test suite** locally before pushing +4. **Push** and open a Pull Request against `main` +5. Fill out the **PR template** completely + +### Branch Naming + +| Type | Pattern | +|-------------|--------------------------| +| Feature | `feat/` | +| Bug fix | `fix/` | +| CI/tooling | `ci/` | +| Docs | `docs/` | +| Refactor | `refactor/` | + +--- + +## Commit Messages + +Follow the [Conventional Commits](https://www.conventionalcommits.org/) format: + +``` +(): + +[optional body] + +[optional footer] +``` + +**Types**: `feat`, `fix`, `ci`, `docs`, `refactor`, `test`, `perf`, `chore` + +**Examples**: +``` +fix(ci): correct SANITIZER flag name in pr-ci.yml +feat(chain): add block timestamp validation +docs(arch): remove stale Orphan Pool references +``` + +--- + +## Review Process + +- All PRs require at least **one approving review** from a maintainer +- CI must be green (all `build-test` and `functional-tests` jobs passing) +- Consensus-critical changes require **two approving reviews** +- Maintainers may request changes; please address all review comments +- Squash or rebase before merge if commit history is noisy + +--- + +## Security Issues + +Please do **not** open public issues for security vulnerabilities. +See [SECURITY.md](SECURITY.md) for the responsible disclosure process. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..b95e59e --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,60 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| main | :white_check_mark: | + +## Reporting a Vulnerability + +**Please do NOT report security vulnerabilities via public GitHub issues.** + +If you discover a security vulnerability in unicity-node, please report it responsibly: + +1. **Email**: Send a detailed report to the maintainers via the contact listed on the + [Unicity Network GitHub organization](https://github.com/unicitynetwork). +2. **Subject line**: Use `[SECURITY] unicity-node - ` +3. **Include in your report**: + - A description of the vulnerability and its potential impact + - Step-by-step reproduction instructions + - Any proof-of-concept code (if applicable) + - Your suggested fix (if you have one) + +## Response Timeline + +- **Acknowledgement**: Within 48 hours of receipt +- **Initial assessment**: Within 7 days +- **Fix + disclosure**: Within 90 days (coordinated disclosure) + +## Scope + +The following are considered in-scope for security reports: + +- Consensus rule bypass or manipulation +- Remote code execution via P2P messages or RPC +- Denial-of-service attacks against node operation +- Memory safety issues (buffer overflows, use-after-free, etc.) +- Supply chain issues in dependencies (especially RandomX) +- Eclipse attack vectors not already mitigated +- Cryptographic weaknesses + +The following are **out of scope**: + +- Issues in third-party dependencies that are already publicly known +- Bugs that require physical access to the machine running the node +- Theoretical attacks with no practical exploit path + +## Security Best Practices for Node Operators + +- Run the node as a non-root user +- Keep the RPC Unix socket (`/tmp/unicity.sock` by default) accessible only to trusted local processes +- Regularly update to the latest `main` branch commit +- Monitor the node process for unexpected resource usage +- If using Docker, use the provided multi-stage image which runs as a non-root user + +## Disclosure Policy + +We follow coordinated disclosure. Once a fix is available and deployed, we will publish a +security advisory on the GitHub repository. Credit will be given to the reporter unless +they prefer to remain anonymous. From eb9fa60ed50b8d29ef7c32caa5662649e129eb1d Mon Sep 17 00:00:00 2001 From: 0xgetz <6snzga6@zenvex.edu.pl> Date: Thu, 16 Apr 2026 01:19:57 +0000 Subject: [PATCH 3/4] docs: update ARCHITECTURE.md, add CHANGELOG.md - ARCHITECTURE.md: remove stale Orphan Pool component from architecture diagram (removed Feb 2026); headers now flow directly into ActiveTipCandidates. Update DoS protection section to reference candidate tip limits instead of orphan header limits. - CHANGELOG.md: add Keep a Changelog-format file documenting all changes in this PR (Unreleased section) plus a pre-release history summary covering the initial development period (Jan-Apr 2026) --- CHANGELOG.md | 70 ++++++++++++++++++++++++++++++++++++++++++++ docs/ARCHITECTURE.md | 16 +++++----- 2 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a1f2807 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,70 @@ +# Changelog + +All notable changes to unicity-node will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +This project does not yet use semantic versioning — entries are tracked by date. + +--- + +## [Unreleased] + +### Added +- `SECURITY.md` — responsible disclosure policy and security best practices for node operators +- `CONTRIBUTING.md` — developer setup guide, coding standards, testing instructions, and PR process +- `.github/PULL_REQUEST_TEMPLATE` — structured PR checklist including consensus-impact flag +- `.github/ISSUE_TEMPLATE/bug_report.yml` — structured bug report form +- `.github/ISSUE_TEMPLATE/feature_request.yml` — structured feature request form +- `.github/ISSUE_TEMPLATE/consensus_issue.yml` — dedicated template for consensus-critical issues +- `.github/ISSUE_TEMPLATE/config.yml` — disables blank issues, links security contact +- `CHANGELOG.md` — this file + +### Changed +- `CMakeLists.txt` — pinned RandomX dependency to a specific commit SHA + (`051d4424394cf8d1f8d0bfff581f0729f2753341`) instead of floating `origin/master`, + eliminating supply chain and reproducibility risk +- `.github/workflows/pr-ci.yml` — fixed sanitizer flag typo (`-DSANITIZE` → `-DSANITIZER`) + so AddressSanitizer and UBSan are now actually enabled in CI +- `.github/workflows/pr-ci.yml` — added macOS 14 (Apple Silicon) CI job +- `.github/workflows/pr-ci.yml` — added dedicated `ASan` and `UBSan` CI jobs (Linux Clang 18) +- `.github/workflows/pr-ci.yml` — added `functional-tests` CI job that runs the Python + functional test suite on every PR +- `.github/workflows/pr-ci.yml` — `nproc` call made portable for macOS + (`nproc 2>/dev/null || sysctl -n hw.logicalcpu`) +- `docs/ARCHITECTURE.md` — removed stale Orphan Pool component from architecture diagram + (Orphan Pool was removed in February 2026; headers now flow directly into ActiveTipCandidates) +- `docs/ARCHITECTURE.md` — updated DoS protection section to reflect current candidate tip limits + +--- + +## [Pre-release] — 2026-01-08 to 2026-04-14 + +_Initial development. No versioned releases yet._ + +### Core Architecture +- Headers-only C++20 blockchain node (no transactions, UTXO, or mempool) +- Single-threaded Asio reactor network layer — no locking required +- Bitcoin Core-inspired P2P protocol (version handshake, headers sync, addr relay) +- RandomX proof-of-work with two-phase verification: + - ~1ms commitment check (fast pre-filter) + - ~50ms full RandomX verification (only after commitment passes) +- ASERT difficulty adjustment algorithm (same as Bitcoin Cash) +- Chain state persistence with reorg support +- RPC via Unix domain socket (no TCP exposure) +- Eclipse attack resistance (diversified peer selection) + +### Dependencies +- RandomX (Unicity fork) — ASIC-resistant PoW +- Asio (standalone) — async I/O +- spdlog + fmt — structured logging +- nlohmann/json — JSON serialization +- miniupnpc — UPnP/NAT traversal +- Catch2 — unit testing + +### CI / Tooling +- GitHub Actions CI: Linux Clang 18, Linux GCC 11 +- Coverity static analysis workflow +- OSS-Fuzz integration (13 fuzz targets) +- clang-format, clang-tidy, cppcheck enforcement +- Docker multi-stage build (Ubuntu 22.04) +- Ansible deployment scripts diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 7b5f869..aeb6657 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -54,13 +54,13 @@ The chain layer validates block headers and maintains the blockchain state: │ │ • GetTip() • IsInitialBlockDownload() │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ ▼ │ -│ ┌──────────────────┐ ┌────────────────────┐ ┌──────────────┐ │ -│ │ BlockManager │ │ ActiveTipCandidates│ │ Orphan Pool │ │ -│ │ │ │ │ │ │ │ -│ │ • Block storage │ │ • Candidate tips │ │ • DoS limits │ │ -│ │ • Active chain │ │ • Best chain │ │ │ │ -│ │ • Persistence │ │ • Pruning │ │ │ │ -│ └──────────────────┘ └────────────────────┘ └──────────────┘ │ +│ ┌──────────────────┐ ┌────────────────────┐ │ +│ │ BlockManager │ │ ActiveTipCandidates│ │ +│ │ │ │ │ │ +│ │ • Block storage │ │ • Candidate tips │ │ +│ │ • Active chain │ │ • Best chain │ │ +│ │ • Persistence │ │ • Pruning │ │ +│ └──────────────────┘ └────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ Validation Layer │ │ @@ -490,7 +490,7 @@ Block Arrives: **Fast Rejection**: - Commitment-only PoW check (~1ms) before expensive validation - Message size limits (8 MB maximum) -- Orphan header limits (1000 total, 50 per peer) +- Candidate tip limits (1000 total, 50 per peer) **Resource Limits**: - Connection limits (10 outbound, 125 inbound) From d269a9ee3d93eb002e6e12eab153663b15401a13 Mon Sep 17 00:00:00 2001 From: 0xgetz <6snzga6@zenvex.edu.pl> Date: Thu, 16 Apr 2026 01:19:57 +0000 Subject: [PATCH 4/4] ci: add release workflow and coverage CI with Codecov upload - release.yml: triggered on v*.*.* tags; builds Linux x86_64 (GCC + Clang) and macOS arm64 binaries with LTO, runs unit tests, packages tar.gz with SHA256 checksums, creates GitHub Release with changelog notes extracted from CHANGELOG.md; pre-release flag set automatically for -alpha/-beta/-rc tags - coverage.yml: runs on push/PR to main; builds with GCC --coverage flags, captures lcov data, filters out system headers and third-party deps, generates HTML report artifact, uploads to Codecov with CODECOV_TOKEN secret; prints coverage summary to CI log --- .github/workflows/coverage.yml | 97 ++++++++++++++++++++++++ .github/workflows/release.yml | 133 +++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 .github/workflows/coverage.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..c552c66 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,97 @@ +name: Coverage + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + coverage: + name: Code Coverage (GCC + lcov) + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + lfs: true + + - name: Cache CMake build + uses: actions/cache@v4 + with: + path: build/_deps + key: ${{ runner.os }}-coverage-cmake-${{ hashFiles('CMakeLists.txt') }} + restore-keys: | + ${{ runner.os }}-coverage-cmake- + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + libboost-system-dev libboost-filesystem-dev libminiupnpc-dev \ + gcc-11 g++-11 lcov + + - name: Configure CMake with coverage flags + run: | + cmake -B build \ + -DCMAKE_CXX_COMPILER=g++-11 \ + -DCMAKE_C_COMPILER=gcc-11 \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_FLAGS="--coverage -fprofile-arcs -ftest-coverage" \ + -DCMAKE_C_FLAGS="--coverage -fprofile-arcs -ftest-coverage" \ + -DCMAKE_EXE_LINKER_FLAGS="--coverage" + + - name: Build + run: cmake --build build -j$(nproc) + + - name: Run unit tests + run: ./build/bin/unicity_tests -d yes "~[real]" "~[rpc]" "~[slow]" + timeout-minutes: 10 + + - name: Capture coverage data + run: | + lcov --capture \ + --directory build \ + --output-file coverage.info \ + --ignore-errors mismatch \ + --rc branch_coverage=1 + + - name: Filter out system headers and third-party deps + run: | + lcov --remove coverage.info \ + '/usr/*' \ + '*/build/_deps/*' \ + '*/test/*' \ + --output-file coverage.filtered.info \ + --rc branch_coverage=1 + + - name: Generate HTML report + run: | + genhtml coverage.filtered.info \ + --output-directory coverage-html \ + --branch-coverage \ + --title "unicity-node coverage" + + - name: Upload HTML report as artifact + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: coverage-html/ + + - name: Upload to Codecov + uses: codecov/codecov-action@v4 + with: + files: coverage.filtered.info + flags: unittests + name: unicity-node-coverage + fail_ci_if_error: false + token: ${{ secrets.CODECOV_TOKEN }} + + - name: Coverage summary + run: | + lcov --summary coverage.filtered.info --rc branch_coverage=1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..93e0a1f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,133 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +permissions: + contents: write + +jobs: + build-release: + name: Build Release (${{ matrix.name }}) + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + include: + - name: linux-x86_64 + os: ubuntu-22.04 + cc: gcc-11 + cxx: g++-11 + artifact: unicity-node-linux-x86_64 + + - name: linux-x86_64-clang + os: ubuntu-22.04 + cc: clang-18 + cxx: clang++-18 + artifact: unicity-node-linux-x86_64-clang + + - name: macos-arm64 + os: macos-14 + cc: clang + cxx: clang++ + artifact: unicity-node-macos-arm64 + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + lfs: true + + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y libboost-system-dev libboost-filesystem-dev libminiupnpc-dev + + if [ "${{ matrix.cc }}" = "clang-18" ]; then + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 18 + sudo apt-get install -y clang-18 clang++-18 + else + sudo apt-get install -y g++-11 gcc-11 + fi + + - name: Install dependencies (macOS) + if: runner.os == 'macOS' + run: | + brew update + brew install boost miniupnpc + + - name: Configure CMake (Release) + run: | + cmake -B build \ + -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} \ + -DCMAKE_C_COMPILER=${{ matrix.cc }} \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON + + - name: Build + run: cmake --build build -j$(nproc 2>/dev/null || sysctl -n hw.logicalcpu) + + - name: Run unit tests + run: ./build/bin/unicity_tests -d yes "~[real]" "~[rpc]" "~[slow]" + timeout-minutes: 10 + + - name: Package binary + run: | + mkdir -p dist + cp build/bin/unicity_node dist/ + cp README.md dist/ + cp CHANGELOG.md dist/ + tar -czf ${{ matrix.artifact }}.tar.gz -C dist . + sha256sum ${{ matrix.artifact }}.tar.gz > ${{ matrix.artifact }}.tar.gz.sha256 + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artifact }} + path: | + ${{ matrix.artifact }}.tar.gz + ${{ matrix.artifact }}.tar.gz.sha256 + + create-release: + name: Create GitHub Release + runs-on: ubuntu-latest + needs: build-release + + steps: + - uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts/ + + - name: Extract changelog for this version + id: changelog + run: | + VERSION="${GITHUB_REF_NAME}" + # Extract the section for this version from CHANGELOG.md + NOTES=$(awk "/^## \[${VERSION}\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md) + if [ -z "$NOTES" ]; then + NOTES="Release ${VERSION}. See CHANGELOG.md for details." + fi + echo "notes<> $GITHUB_OUTPUT + echo "$NOTES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create release + uses: softprops/action-gh-release@v2 + with: + name: "unicity-node ${{ github.ref_name }}" + body: ${{ steps.changelog.outputs.notes }} + draft: false + prerelease: ${{ contains(github.ref_name, '-rc') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-alpha') }} + files: | + artifacts/**/*.tar.gz + artifacts/**/*.sha256 + generate_release_notes: false