Skip to content

fix: remove stale NonceTooLow txs from retry loop #601

fix: remove stale NonceTooLow txs from retry loop

fix: remove stale NonceTooLow txs from retry loop #601

Workflow file for this run

name: CI
on:
push:
branches: [main, 001-cipherbft-implementation]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
# Detect which files/crates have changed
changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
rust: ${{ steps.filter.outputs.rust }}
rust_files: ${{ steps.filter.outputs.rust_files }}
types: ${{ steps.filter.outputs.types }}
crypto: ${{ steps.filter.outputs.crypto }}
data-chain: ${{ steps.filter.outputs.data-chain }}
storage: ${{ steps.filter.outputs.storage }}
consensus: ${{ steps.filter.outputs.consensus }}
execution: ${{ steps.filter.outputs.execution }}
mempool: ${{ steps.filter.outputs.mempool }}
rpc: ${{ steps.filter.outputs.rpc }}
node: ${{ steps.filter.outputs.node }}
metrics: ${{ steps.filter.outputs.metrics }}
cargo: ${{ steps.filter.outputs.cargo }}
ci: ${{ steps.filter.outputs.ci }}
# Derived: crates that need checking (including dependents)
affected_crates: ${{ steps.affected.outputs.crates }}
any_crate: ${{ steps.affected.outputs.any_crate }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Detect file changes
uses: dorny/paths-filter@v3
id: filter
with:
list-files: shell
filters: |
rust:
- '**/*.rs'
- 'Cargo.toml'
- 'Cargo.lock'
- 'crates/**/Cargo.toml'
types:
- 'crates/types/**'
crypto:
- 'crates/crypto/**'
data-chain:
- 'crates/data-chain/**'
storage:
- 'crates/storage/**'
consensus:
- 'crates/consensus/**'
execution:
- 'crates/execution/**'
mempool:
- 'crates/mempool/**'
rpc:
- 'crates/rpc/**'
node:
- 'crates/node/**'
metrics:
- 'crates/metrics/**'
cargo:
- 'Cargo.toml'
- 'Cargo.lock'
- 'crates/**/Cargo.toml'
ci:
- '.github/workflows/**'
- name: Compute affected crates
id: affected
run: |
# Crate dependency graph (simplified):
# types -> crypto, data-chain, storage, consensus, execution, mempool, rpc, node, metrics
# crypto -> data-chain, consensus, node
# data-chain -> consensus, node
# storage -> execution, node
# consensus -> node
# execution -> rpc, node
# mempool -> node
# rpc -> node
# metrics -> node
CRATES=""
# If root Cargo.toml or CI changed, check everything
if [[ "${{ steps.filter.outputs.cargo }}" == "true" ]] || [[ "${{ steps.filter.outputs.ci }}" == "true" ]]; then
CRATES="types crypto data-chain storage consensus execution mempool rpc node metrics"
else
# Build list of affected crates based on changes and dependencies
# types is a foundation - if it changes, most crates need rechecking
if [[ "${{ steps.filter.outputs.types }}" == "true" ]]; then
CRATES="types crypto data-chain storage consensus execution mempool rpc node metrics"
fi
# crypto affects data-chain, consensus, node
if [[ "${{ steps.filter.outputs.crypto }}" == "true" ]]; then
CRATES="$CRATES crypto data-chain consensus node"
fi
# data-chain affects consensus, node
if [[ "${{ steps.filter.outputs.data-chain }}" == "true" ]]; then
CRATES="$CRATES data-chain consensus node"
fi
# storage affects execution, node
if [[ "${{ steps.filter.outputs.storage }}" == "true" ]]; then
CRATES="$CRATES storage execution node"
fi
# consensus affects node
if [[ "${{ steps.filter.outputs.consensus }}" == "true" ]]; then
CRATES="$CRATES consensus node"
fi
# execution affects rpc, node
if [[ "${{ steps.filter.outputs.execution }}" == "true" ]]; then
CRATES="$CRATES execution rpc node"
fi
# mempool affects node
if [[ "${{ steps.filter.outputs.mempool }}" == "true" ]]; then
CRATES="$CRATES mempool node"
fi
# rpc affects node
if [[ "${{ steps.filter.outputs.rpc }}" == "true" ]]; then
CRATES="$CRATES rpc node"
fi
# node is the top-level binary
if [[ "${{ steps.filter.outputs.node }}" == "true" ]]; then
CRATES="$CRATES node"
fi
# metrics is utility, only affects itself and node
if [[ "${{ steps.filter.outputs.metrics }}" == "true" ]]; then
CRATES="$CRATES metrics node"
fi
fi
# Deduplicate and sort
CRATES=$(echo "$CRATES" | tr ' ' '\n' | sort -u | tr '\n' ' ' | xargs)
echo "Affected crates: $CRATES"
echo "crates=$CRATES" >> $GITHUB_OUTPUT
if [[ -n "$CRATES" ]]; then
echo "any_crate=true" >> $GITHUB_OUTPUT
else
echo "any_crate=false" >> $GITHUB_OUTPUT
fi
fmt:
name: Rustfmt
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.rust == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Check formatting (changed files only)
env:
CHANGED_FILES: ${{ needs.changes.outputs.rust_files }}
run: |
if [[ -n "$CHANGED_FILES" ]]; then
# Filter to only .rs files
RS_FILES=$(echo "$CHANGED_FILES" | tr ' ' '\n' | grep '\.rs$' || true)
if [[ -n "$RS_FILES" ]]; then
echo "Checking formatting for changed files:"
echo "$RS_FILES"
echo "$RS_FILES" | xargs rustfmt --check --edition 2021
else
echo "No .rs files changed, skipping format check"
fi
else
# Fallback: check all files if file list not available
cargo fmt --all -- --check
fi
check:
name: Check
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.any_crate == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Run cargo check (affected crates)
env:
AFFECTED_CRATES: ${{ needs.changes.outputs.affected_crates }}
run: |
if [[ -n "$AFFECTED_CRATES" ]]; then
echo "Checking crates: $AFFECTED_CRATES"
# Build package flags (node crate is named 'cipherd')
PKG_FLAGS=""
for crate in $AFFECTED_CRATES; do
if [[ "$crate" == "node" ]]; then
PKG_FLAGS="$PKG_FLAGS -p cipherd"
else
PKG_FLAGS="$PKG_FLAGS -p cipherbft-$crate"
fi
done
cargo check --all-targets --all-features $PKG_FLAGS
else
echo "No crates to check"
fi
clippy:
name: Clippy
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.any_crate == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Run clippy (affected crates)
env:
AFFECTED_CRATES: ${{ needs.changes.outputs.affected_crates }}
run: |
if [[ -n "$AFFECTED_CRATES" ]]; then
echo "Running clippy on crates: $AFFECTED_CRATES"
# Build package flags (node crate is named 'cipherd')
PKG_FLAGS=""
for crate in $AFFECTED_CRATES; do
if [[ "$crate" == "node" ]]; then
PKG_FLAGS="$PKG_FLAGS -p cipherd"
else
PKG_FLAGS="$PKG_FLAGS -p cipherbft-$crate"
fi
done
cargo clippy --all-targets --all-features $PKG_FLAGS -- -D warnings
else
echo "No crates to lint"
fi
test:
name: Test Suite
needs: changes
if: needs.changes.outputs.any_crate == 'true'
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
name: Linux x86_64
- os: macos-latest
target: aarch64-apple-darwin
name: macOS ARM64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Run tests (affected crates)
env:
AFFECTED_CRATES: ${{ needs.changes.outputs.affected_crates }}
run: |
if [[ -n "$AFFECTED_CRATES" ]]; then
echo "Testing crates: $AFFECTED_CRATES"
# Build package flags (node crate is named 'cipherd')
PKG_FLAGS=""
for crate in $AFFECTED_CRATES; do
if [[ "$crate" == "node" ]]; then
PKG_FLAGS="$PKG_FLAGS -p cipherd"
else
PKG_FLAGS="$PKG_FLAGS -p cipherbft-$crate"
fi
done
cargo test --all-features --verbose $PKG_FLAGS
else
echo "No crates to test"
fi
coverage:
name: Code Coverage
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.rust == 'true'
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Generate coverage (affected crates)
env:
AFFECTED_CRATES: ${{ needs.changes.outputs.affected_crates }}
run: |
if [[ -n "$AFFECTED_CRATES" ]]; then
echo "Generating coverage for crates: $AFFECTED_CRATES"
# Build package flags (node crate is named 'cipherd')
PKG_FLAGS=""
for crate in $AFFECTED_CRATES; do
if [[ "$crate" == "node" ]]; then
PKG_FLAGS="$PKG_FLAGS -p cipherd"
else
PKG_FLAGS="$PKG_FLAGS -p cipherbft-$crate"
fi
done
cargo llvm-cov --all-features $PKG_FLAGS --lcov --output-path lcov.info
else
# If no specific crates, run on all (shouldn't happen given the if condition)
cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
fi
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./lcov.info
fail_ci_if_error: false
verbose: true
# SECURITY: Always run cargo-deny regardless of changes
# This ensures license compliance and security advisory checks
deny:
name: Cargo Deny (Security)
runs-on: ubuntu-latest
# No 'needs: changes' - always runs for security
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run cargo deny
uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check
arguments: --all-features
build:
name: Build Release
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.rust == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Build release
run: cargo build --release --verbose