Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
name: CI

on:
push:
branches: [ main, master ]
pull_request:
types: [ opened, synchronize, reopened, ready_for_review ]
branches: [ main, master ]

jobs:
lint:
name: Lint Code
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2

- name: Run linting checks
run: |
zig build lint

- name: Run tests
run: |
zig build test

build-linux:
name: Build Linux (x86_64)
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2

- name: Build for Linux x86_64
run: |
zig build -Dtarget=x86_64-linux-gnu

- name: Verify binary exists
run: |
test -f zig-out/bin/sequencer || exit 1
file zig-out/bin/sequencer

build-macos:
name: Build macOS (x86_64)
runs-on: macos-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2

- name: Build for macOS x86_64
run: |
zig build -Dtarget=x86_64-macos

- name: Verify binary exists
run: |
test -f zig-out/bin/sequencer || exit 1
file zig-out/bin/sequencer

build-macos-arm64:
name: Build macOS (ARM64)
runs-on: macos-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2

- name: Build for macOS ARM64
run: |
zig build -Dtarget=aarch64-macos

- name: Verify binary exists
run: |
test -f zig-out/bin/sequencer || exit 1
file zig-out/bin/sequencer

build-windows:
name: Build Windows (x86_64)
runs-on: windows-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2

- name: Build for Windows x86_64
run: |
zig build -Dtarget=x86_64-windows

- name: Verify binary exists
run: |
if (-not (Test-Path "zig-out\bin\sequencer.exe")) { exit 1 }

docker-build:
name: Build Docker Image
runs-on: ubuntu-latest
strategy:
matrix:
include:
- platform: linux/amd64
tag: amd64
- platform: linux/arm64
tag: arm64

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
image=moby/buildkit:latest

- name: Set up QEMU (for cross-platform builds)
uses: docker/setup-qemu-action@v3

- name: Build Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: false
tags: native-sequencer:test-${{ matrix.tag }}
cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
platforms: ${{ matrix.platform }}
load: true

- name: Verify Docker image
run: |
docker images native-sequencer:test-${{ matrix.tag }}
docker inspect native-sequencer:test-${{ matrix.tag }}

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ zig-out/
zig-cache/

# Compiled binaries
sequencer
/sequencer
sequencer.exe
*.o
*.a
*.so
Expand Down
19 changes: 15 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,22 @@ RUN apt-get update && apt-get install -y \
&& rm -rf /var/lib/apt/lists/*

# Install Zig 0.15.2
# Detect architecture and download appropriate Zig binary
ARG TARGETPLATFORM
ARG BUILDPLATFORM
ENV ZIG_VERSION=0.15.2
RUN curl -L "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-x86_64-${ZIG_VERSION}.tar.xz" -o zig.tar.xz \
&& tar -xf zig.tar.xz \
&& mv zig-linux-x86_64-${ZIG_VERSION} /opt/zig \
&& rm zig.tar.xz
RUN ARCH_SUFFIX=$(echo ${TARGETPLATFORM} | cut -d'/' -f2) && \
if [ "${ARCH_SUFFIX}" = "amd64" ]; then \
ZIG_ARCH="x86_64"; \
elif [ "${ARCH_SUFFIX}" = "arm64" ]; then \
ZIG_ARCH="aarch64"; \
else \
echo "Unsupported architecture: ${ARCH_SUFFIX}" && exit 1; \
fi && \
curl -f -L "https://ziglang.org/download/${ZIG_VERSION}/zig-${ZIG_ARCH}-linux-${ZIG_VERSION}.tar.xz" -o zig.tar.xz && \
tar -xf zig.tar.xz && \
mv zig-${ZIG_ARCH}-linux-${ZIG_VERSION} /opt/zig && \
rm zig.tar.xz

# Add Zig to PATH
ENV PATH="/opt/zig:${PATH}"
Expand Down
98 changes: 97 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,14 @@ zig build run
# Run tests
zig build test

# Run linter
# Run linter (format check + AST checks)
zig build lint

# Format code automatically
zig build fmt

# Run lint-fix (alias for fmt)
zig build lint-fix
```

The build output will be in `zig-out/bin/sequencer`.
Expand Down Expand Up @@ -375,6 +381,29 @@ Get the current block number.
}
```

### L1 Client Features

The sequencer includes a full-featured HTTP client for L1 communication:

- **Standard Transaction Submission**: `eth_sendRawTransaction` for submitting batches to L1
- **Conditional Transaction Submission**: `eth_sendRawTransactionConditional` (EIP-7796) for conditional batch submission with block number constraints
- **Transaction Receipt Polling**: `eth_getTransactionReceipt` for tracking batch inclusion
- **Block Number Queries**: `eth_blockNumber` for L1 state synchronization
- **Automatic Confirmation Waiting**: `waitForInclusion()` method for polling transaction confirmations

#### Conditional Transaction Submission

The sequencer supports EIP-7796 conditional transaction submission, allowing batches to be submitted with preconditions:

```zig
const options = l1.Client.ConditionalOptions{
.block_number_max = 1000000, // Only include if block <= 1000000
};
const tx_hash = try l1_client.submitBatchConditional(batch, options);
```

This feature enables more efficient batch submission by allowing the sequencer to specify maximum block numbers for inclusion, reducing the need for extensive simulations.

### Metrics

Access metrics at `http://localhost:9090` (or configured port).
Expand All @@ -396,6 +425,9 @@ This is an initial implementation. Production use requires:
- ✅ Basic state management
- ✅ RLP encoding/decoding (complete implementation with tests)
- ✅ Docker support
- ✅ HTTP server implementation (Zig 0.15 networking APIs)
- ✅ HTTP client for L1 communication (JSON-RPC support)
- ✅ Conditional transaction submission (EIP-7796 support)
- ⏳ Complete ECDSA signature verification and recovery (basic implementation)
- ⏳ Full transaction execution engine
- ⏳ RocksDB/LMDB integration for persistence
Expand All @@ -404,8 +436,72 @@ This is an initial implementation. Production use requires:
- ⏳ Proper error handling and retry logic
- ⏳ Comprehensive testing

## Linting

The repository includes comprehensive linting checks to ensure code quality:

- **Format Check**: Validates code formatting using `zig fmt --check`
- **AST Checks**: Validates syntax and type correctness using `zig ast-check` for key modules
- **Format Fix**: Automatically formats code using `zig fmt`

### Linting Commands

```bash
# Run all linting checks (format + AST)
# Exit code 1 if formatting issues are found
zig build lint

# Format code automatically (fixes formatting issues)
zig build fmt

# Run lint-fix (alias for fmt)
zig build lint-fix
```

**Note**: If `zig build lint` fails, run `zig build fmt` to automatically fix formatting issues, then commit the changes.

### CI/CD Integration

A comprehensive GitHub Actions workflow (`.github/workflows/ci.yml`) automatically runs on:
- Push to main/master/develop branches
- Pull requests targeting main/master/develop branches

The CI pipeline includes:

#### Linting & Testing
- **Code formatting validation** (`zig fmt --check`)
- **AST syntax checks** for key modules (`zig ast-check`)
- **Unit tests** (`zig build test`)

#### Multi-Platform Builds
- **Linux (x86_64)**: Builds and verifies binary for Linux
- **macOS (x86_64)**: Builds and verifies binary for Intel Macs
- **macOS (ARM64)**: Builds and verifies binary for Apple Silicon
- **Windows (x86_64)**: Builds and verifies binary for Windows

#### Docker Build Validation
- **Multi-architecture Docker builds**: Tests Docker image builds for both `linux/amd64` and `linux/arm64`
- **Image verification**: Validates Docker image structure and metadata
- **Runtime testing**: Verifies that the Docker image can start and contains the expected binary

The workflow will fail if:
- Code is not properly formatted
- AST checks reveal syntax or type errors
- Unit tests fail
- Build fails on any platform
- Docker image build or validation fails

## Technical Details

### Networking Implementation

The sequencer uses Zig 0.15.2's standard library networking APIs:

- **HTTP Server**: Built on `std.net.Server` and `std.net.Stream` for accepting JSON-RPC connections
- **HTTP Client**: Uses `std.net.tcpConnectToAddress` for L1 RPC communication
- **Connection Handling**: Thread-based concurrent request handling with proper resource cleanup
- **RLP Transaction Parsing**: Full RLP decoding support for transaction deserialization

### Custom U256 Implementation

Due to a compiler bug in Zig 0.15.2's HashMap implementation with native `u256` types, we use a custom `U256` struct implementation. This struct:
Expand Down
38 changes: 31 additions & 7 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("vendor/zig-eth-secp256k1/secp256k1_wrapper.zig"),
.target = target,
});

const libsecp256k1 = b.addLibrary(.{
.name = "secp256k1",
.linkage = .static,
Expand Down Expand Up @@ -69,7 +69,7 @@ pub fn build(b: *std.Build) void {
// Link secp256k1 library
exe.linkLibrary(libsecp256k1);
exe.linkLibC();

b.installArtifact(exe);

// Run step
Expand Down Expand Up @@ -98,10 +98,34 @@ pub fn build(b: *std.Build) void {
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);

// Lint
const lint_cmd = b.addSystemCommand(&.{ "zig", "fmt", "--check", "src" });
const lint_step = b.step("lint", "Run lint (zig fmt --check)");
lint_step.dependOn(&lint_cmd.step);
}
// Linting steps
// Format check
const fmt_check_cmd = b.addSystemCommand(&.{ "zig", "fmt", "--check", "src", "build.zig" });
const lint_step = b.step("lint", "Run all linting checks (format + AST)");
lint_step.dependOn(&fmt_check_cmd.step);

// Format fix
const fmt_fix_cmd = b.addSystemCommand(&.{ "zig", "fmt", "src", "build.zig" });
const fmt_fix_step = b.step("fmt", "Format source code");
fmt_fix_step.dependOn(&fmt_fix_cmd.step);

// AST check for main source files
const ast_check_main = b.addSystemCommand(&.{ "zig", "ast-check", "src/main.zig" });
lint_step.dependOn(&ast_check_main.step);

// AST check for core modules
const ast_check_core = b.addSystemCommand(&.{ "zig", "ast-check", "src/core/root.zig" });
lint_step.dependOn(&ast_check_core.step);

// AST check for API modules
const ast_check_api = b.addSystemCommand(&.{ "zig", "ast-check", "src/api/root.zig" });
lint_step.dependOn(&ast_check_api.step);

// AST check for L1 client
const ast_check_l1 = b.addSystemCommand(&.{ "zig", "ast-check", "src/l1/client.zig" });
lint_step.dependOn(&ast_check_l1.step);

// Lint-fix: format code automatically
const lint_fix_step = b.step("lint-fix", "Run lint-fix (format code)");
lint_fix_step.dependOn(&fmt_fix_cmd.step);
}
Loading
Loading