Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests for rust crates #26

Merged
merged 37 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
cd52ecd
test(relayer): add comprehensive unit tests
ametel01 Jan 13, 2025
06ea0a9
test: add unit tests for StarknetAccount
ametel01 Jan 13, 2025
24316be
test(starknet-handler): add unit tests for StarknetProvider and Stark…
ametel01 Jan 13, 2025
2c7a9ec
test: add integration tests for state-proof-api
ametel01 Jan 13, 2025
ea2b097
test: add unit tests for common crate
ametel01 Jan 14, 2025
3be8688
feat(client): add basic unit tests for LightClient
ametel01 Jan 14, 2025
829e714
test(publisher): implement basic tests for AccumulatorBuilder
ametel01 Jan 14, 2025
a701edf
feat(publisher): implement unit tests for batch processor
ametel01 Jan 14, 2025
82b45f6
test(publisher): add unit tests for MMRStateManager
ametel01 Jan 14, 2025
6863dd8
test(publisher): improve hex validation tests
ametel01 Jan 14, 2025
a4b2a81
refactor(guest-types): remove risc0 Receipt test
ametel01 Jan 14, 2025
2981549
test(publisher): fix proof generator tests
ametel01 Jan 14, 2025
4df08cd
test(ipfs-utils): add comprehensive test suite
ametel01 Jan 14, 2025
d815bfc
test(ipfs-utils): improve test coverage with error cases
ametel01 Jan 14, 2025
9271f52
feat: add state-proof-api service
ametel01 Jan 15, 2025
8910783
feat(db): add hourly block header fetching
ametel01 Jan 15, 2025
5442522
feat(state-proof-api): add detailed request logging for block verific…
ametel01 Jan 15, 2025
619fe57
feat: enhance Docker configurations and add new services
ametel01 Jan 15, 2025
9411482
fix: resolve PyO3 version conflicts and improve Python linking
ametel01 Jan 16, 2025
808e1c7
test(publisher): add unit tests for validator module
ametel01 Jan 16, 2025
d60177f
refactor(starknet-handler): improve hex validation and tests
ametel01 Jan 16, 2025
8682d03
Merge remote-tracking branch 'origin/main' into tests-for-rust-crates
ametel01 Jan 16, 2025
a96c00a
refactor: move build_mmr business logic to cli module
ametel01 Jan 16, 2025
5bcf525
test: add unit tests for build_mmr cli module
ametel01 Jan 16, 2025
0b60483
refactor(publisher): improve update_mmr module organization and testing
ametel01 Jan 16, 2025
1c505f0
refactor(publisher): improve extract_fees module and fix tests
ametel01 Jan 16, 2025
6c09249
test(publisher): improve error handling tests
ametel01 Jan 16, 2025
bd9f48d
test/ fixed failing
ametel01 Jan 16, 2025
6659344
fix: update L2_MSG_PROXY validation for Starknet address format
ametel01 Jan 17, 2025
84eaafe
fix: ensure client updates are saved to IPFS
ametel01 Jan 17, 2025
5bcdf5b
docker images for osx
ametel01 Jan 17, 2025
9865f73
Merge branch 'main' into tests-for-rust-crates
ametel01 Jan 17, 2025
0721b0f
build.rs for publisher
ametel01 Jan 17, 2025
7d3bc79
Merge branch 'dockerization-updates' into tests-for-rust-crates
ametel01 Jan 17, 2025
e76f117
Merge branch 'main' into tests-for-rust-crates
ametel01 Jan 17, 2025
c387fdb
refactor(publisher): restrict Python configuration to Apple platforms…
ametel01 Jan 17, 2025
da20f20
Merge branch 'tests-for-rust-crates' of github.com:OilerNetwork/fossi…
ametel01 Jan 17, 2025
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion config/.env.docker.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ FORK_URL=http://209.127.228.66:8545
BONSAI_API_KEY=XXX
BONSAI_API_URL=https://api.bonsai.xyz/

DATABASE_URL=XXX
DATABASE_URL=postgresql://public_user:1234@fossil-eth-blockheaders.cnc4gyc2mcb3.us-east-1.rds.amazonaws.com:5432/fossil.sepolia

ETH_ACCOUNT_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
ACCOUNT_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
Expand Down
5 changes: 4 additions & 1 deletion config/.env.example
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
DATABASE_URL=XXX
DATABASE_URL=postgresql://public_user:1234@fossil-eth-blockheaders.cnc4gyc2mcb3.us-east-1.rds.amazonaws.com:5432/fossil.sepolia
export LIBRARY_PATH=$(python3-config --prefix)/lib
export LDFLAGS="-L$(python3-config --prefix)/lib"
export CPPFLAGS="-I$(python3-config --prefix)/include"
2 changes: 1 addition & 1 deletion config/.env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ FORK_URL=http://209.127.228.66:8545
BONSAI_API_KEY=XXX
BONSAI_API_URL=https://api.bonsai.xyz/

DATABASE_URL=XXX
DATABASE_URL=postgresql://public_user:1234@fossil-eth-blockheaders.cnc4gyc2mcb3.us-east-1.rds.amazonaws.com:5432/fossil.sepolia

ETH_ACCOUNT_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
ACCOUNT_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
Expand Down
4 changes: 2 additions & 2 deletions config/anvil.messaging.docker.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"chain": "ethereum",
"rpc_url": "http://anvil:8545",
"contract_address": "0x06fAdf55c689Da5d17472FE604302e595Bd257c0",
"contract_address": "0x5150f9d8009E2aFc0c09DB336A8BeD658b35E774",
"sender_address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"private_key": "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
"interval": 2,
"from_block": 7508506
"from_block": 7505882
}
4 changes: 2 additions & 2 deletions crates/methods/validate_blocks_and_extract_fees/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// main.rs
use eth_rlp_verify::are_blocks_and_chain_valid;
use eth_rlp_verify::are_blocks_valid;
use risc0_zkvm::guest::env;
use guest_mmr::core::GuestMMR;
use guest_types::BlocksValidityInput;
Expand All @@ -9,7 +9,7 @@ fn main() {
let input: BlocksValidityInput = env::read();

// Verify block headers
if !are_blocks_and_chain_valid(&input.headers(), input.chain_id()) {
if !are_blocks_valid(&input.headers(), input.chain_id()) {
env::commit(&false);
}
// Initialize MMR with previous state
Expand Down
50 changes: 24 additions & 26 deletions crates/publisher/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,37 @@ name = "extract-fees"
path = "bin/extract_fees.rs"

[dependencies]
guest-types = { path = "../guest-types" }
methods = { path = "../methods" }
clap = { workspace = true, features = ["derive"] }
common = { path = "../common" }
dotenv = { workspace = true }
eth-rlp-types = { workspace = true }
ethereum = { path = "../ethereum" }
mmr-utils = { path = "../mmr-utils" }
starknet-handler = { path = "../starknet-handler" }
garaga_rs = { git = "https://github.com/keep-starknet-strange/garaga.git", branch = "main", default-features = false }
guest-types = { path = "../guest-types" }
ipfs-utils = { path = "../ipfs-utils" }

eth-rlp-types = { workspace = true }
# eth-rlp-verify = { workspace = true }

garaga_rs = { git = "https://github.com/keep-starknet-strange/garaga.git",branch = "main" }
methods = { path = "../methods" }
mmr = { git = "https://github.com/ametel01/rust-accumulators.git", branch = "feat/sha2-hasher" }
store = { git = "https://github.com/ametel01/rust-accumulators.git", branch = "feat/sha2-hasher" }

thiserror = { workspace = true }
tracing = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread"] }
mmr-utils = { path = "../mmr-utils" }
pyo3 = { version = "0.23.3", features = ["extension-module"] }
risc0-ethereum-contracts = { git = "https://github.com/risc0/risc0-ethereum", tag = "v1.2.0" }
risc0-zkvm = { version = "1.2.0" }
serde = "1.0"
sqlx = { workspace = true }
starknet-crypto = { workspace = true }
starknet = { workspace = true }
clap = { workspace = true, features = ["derive"] }
dotenv = { workspace = true }

risc0-zkvm = { version = "1.2.0" }
starknet-crypto = { workspace = true }
starknet-handler = { path = "../starknet-handler" }
starknet-types-core = "0.1.7"
serde = "1.0"
risc0-ethereum-contracts = { git = "https://github.com/risc0/risc0-ethereum", tag = "v1.2.0" }
store = { git = "https://github.com/ametel01/rust-accumulators.git", branch = "feat/sha2-hasher" }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread"] }
tracing = { workspace = true }

[dev-dependencies]
hasher = { git = "https://github.com/ametel01/rust-accumulators.git", branch = "feat/sha2-hasher", features = [
"sha256",
] }
mockall = "0.13"
tokio = { version = "1.0", features = ["full"] }
starknet-handler = { path = "../starknet-handler" }
hasher = { git = "https://github.com/ametel01/rust-accumulators.git", branch = "feat/sha2-hasher", features = ["sha256"] }
store = { git = "https://github.com/ametel01/rust-accumulators.git", branch = "feat/sha2-hasher" }
# tempfile = "3.2"

[lib]
name = "publisher"
crate-type = ["cdylib", "rlib"]
54 changes: 54 additions & 0 deletions crates/publisher/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
fn main() {
// Only run Python configuration on Apple platforms
#[cfg(target_vendor = "apple")]
configure_python();

// Tell cargo to invalidate the built crate whenever the wrapper changes
println!("cargo:rerun-if-changed=wrapper.h");
}

#[cfg(target_vendor = "apple")]
fn configure_python() {
// Get Python library path
let output = std::process::Command::new("python3-config")
.arg("--prefix")
.output()
.expect("Failed to execute python3-config");
let python_prefix = String::from_utf8(output.stdout)
.expect("Invalid UTF-8")
.trim()
.to_string();

// Get Python version
let python_version = std::process::Command::new("python3")
.args([
"-c",
"import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')",
])
.output()
.expect("Failed to get Python version")
.stdout;
let python_version = String::from_utf8(python_version)
.expect("Invalid UTF-8")
.trim()
.to_string();

// Add Python library directory to search path
println!("cargo:rustc-link-search={}/lib", python_prefix);
println!("cargo:rustc-link-search=/opt/homebrew/lib");

// Link against specific Python version
println!("cargo:rustc-link-lib=python{}", python_version);

// Additional required libraries from python3-config --ldflags
println!("cargo:rustc-link-lib=intl");
println!("cargo:rustc-link-lib=dl");

// Include macOS-specific frameworks
println!("cargo:rustc-link-lib=framework=CoreFoundation");
println!("cargo:rustc-link-lib=framework=System");

// Add rpath
println!("cargo:rustc-link-arg=-Wl,-rpath,{}/lib", python_prefix);
println!("cargo:rustc-link-arg=-Wl,-rpath,/opt/homebrew/lib");
}
42 changes: 42 additions & 0 deletions crates/publisher/src/db/db_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,48 @@ impl DbConnection {

Ok(header)
}

pub async fn get_hourly_block_headers_in_range(
&self,
start_block: u64,
end_block: u64,
) -> Result<Vec<BlockHeader>, DbError> {
if start_block > end_block {
return Err(DbError::InvalidBlockRange {
start_block,
end_block,
});
}

let temp_headers = sqlx::query_as!(
TempBlockHeader,
r#"
WITH hourly_blocks AS (
SELECT DISTINCT ON (date_trunc('hour', to_timestamp("timestamp")))
block_hash, number, gas_limit, gas_used, nonce,
transaction_root, receipts_root, state_root,
base_fee_per_gas, parent_hash, miner, logs_bloom,
difficulty, totaldifficulty, sha3_uncles, "timestamp",
extra_data, mix_hash, withdrawals_root,
blob_gas_used, excess_blob_gas, parent_beacon_block_root
FROM blockheaders
WHERE number BETWEEN $1 AND $2
ORDER BY date_trunc('hour', to_timestamp("timestamp")), number ASC
)
SELECT * FROM hourly_blocks
ORDER BY number ASC
"#,
start_block as i64,
end_block as i64
)
.fetch_all(&self.pool)
.await?;

let headers: Vec<BlockHeader> =
temp_headers.into_iter().map(temp_to_block_header).collect();

Ok(headers)
}
}

#[derive(sqlx::FromRow, Debug)]
Expand Down
1 change: 1 addition & 0 deletions crates/publisher/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![deny(unused_crate_dependencies)]
use clap as _;
use dotenv as _;
use pyo3 as _;

pub mod api;
pub mod cli;
Expand Down
2 changes: 1 addition & 1 deletion crates/publisher/src/validator/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl<'a> ValidatorBuilder<'a> {
e
})?;
let headers: Vec<eth_rlp_types::BlockHeader> = db_connection
.get_block_headers_by_block_range(start_block, end_block)
.get_hourly_block_headers_in_range(start_block, end_block)
.await
.map_err(|e| {
error!(error = %e, "Failed to fetch block headers");
Expand Down
13 changes: 11 additions & 2 deletions crates/state-proof-api/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use axum::{
};
use publisher::extract_fees;
use serde::{Deserialize, Serialize};
use tracing::{error, info};

#[derive(Deserialize)]
pub struct BlockRangeParams {
Expand Down Expand Up @@ -35,6 +36,14 @@ pub async fn verify_blocks(
State(state): State<Arc<AppState>>,
Query(params): Query<BlockRangeParams>,
) -> impl IntoResponse {
// Log request details
info!(
"Processing block range request: from_block={}, to_block={}, total_blocks={}",
params.from_block,
params.to_block,
params.to_block.saturating_sub(params.from_block) + 1,
);

// Use query parameter if provided, otherwise use CLI default
let skip_proof = params
.skip_proof_verification
Expand Down Expand Up @@ -65,7 +74,7 @@ pub async fn verify_blocks(
.unwrap()
}
Err(e) => {
tracing::error!("Failed to serialize response: {}", e);
error!("Failed to serialize response: {}", e);
let error_json = serde_json::to_vec(&ErrorResponse {
error: format!("Failed to serialize response: {}", e),
})
Expand All @@ -78,7 +87,7 @@ pub async fn verify_blocks(
}
},
Err(e) => {
tracing::error!("Error verifying blocks: {}", e);
error!("Error verifying blocks: {}", e);
let error_json = serde_json::to_vec(&ErrorResponse {
error: e.to_string(),
})
Expand Down
26 changes: 26 additions & 0 deletions docker-compose.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,32 @@ services:
- fossil
command: ["client", "-e", ".env.docker"]

state-proof-api:
image: fossil-state-proof-api:latest
env_file:
- ${ENV_FILE:-.env.docker}
volumes:
- ./config:/app/config
- ./.env.docker:/app/.env.docker
networks:
- fossil
ports:
- "3000:3000"
command: ["state-proof-api", "-b", "4", "-e", ".env.docker"]

fetch-fees-proof:
image: fossil-fetch-fees-proof:latest
env_file:
- ${ENV_FILE:-.env.docker}
volumes:
- ./config:/app/config
- ./.env.docker:/app/.env.docker
networks:
- fossil
depends_on:
- state-proof-api
command: ["fetch-fees-proof", "-e", ".env.docker"]

networks:
fossil:
name: fossil-network
Expand Down
59 changes: 59 additions & 0 deletions docker/Dockerfile.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
FROM rust:latest AS builder

ARG BINARY

WORKDIR /app

# Install build dependencies
RUN apt-get update && apt-get install -y \
curl \
build-essential \
pkg-config \
libssl-dev \
git \
&& rm -rf /var/lib/apt/lists/*

# Configure cargo to use git CLI for fetching
RUN mkdir -p /root/.cargo && \
echo '[net]\ngit-fetch-with-cli = true' > /root/.cargo/config.toml

# Copy .env file
COPY .env .

# Install the RISC Zero toolchain
RUN curl -L https://risczero.com/install | bash && \
/root/.risc0/bin/rzup install || true && \
mkdir -p /root/.cargo/bin && \
(ln -sf /root/.risc0/bin/cargo-risczero /root/.cargo/bin/cargo-risczero || echo "Symlink creation failed, checking directories..." && ls -la /root/.risc0/bin && ls -la /root/.cargo)

ENV PATH="/root/.risc0/bin:/root/.cargo/bin:$PATH"

# Copy only the necessary files
COPY Cargo.toml Cargo.lock ./
COPY crates ./crates

# Build the specified binary
RUN set -a && \
. ./.env && \
set +a && \
echo "DATABASE_URL is: $DATABASE_URL" && \
cargo build --release --bin ${BINARY}

# Stage 2: Create a minimal runtime image
FROM debian:bookworm-slim

ARG BINARY

WORKDIR /app

# Install runtime dependencies
RUN apt-get update && apt-get install -y \
ca-certificates \
libssl3 \
&& rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/target/release/${BINARY} /usr/local/bin/

RUN chmod +x /usr/local/bin/${BINARY}

CMD ["/usr/local/bin/${BINARY}"]
Loading
Loading