Skip to content
Draft
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
87 changes: 87 additions & 0 deletions .github/workflows/compact.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Compact Codec Compatibility

on:
push:
branches: [main]
pull_request:
branches: [main]
merge_group:

env:
CARGO_TERM_COLOR: always

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
compact-codec:
name: Test Compact Codec Compatibility
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true

# First, generate test vectors on main branch to establish baseline
- name: Checkout main branch
run: git checkout ${{ github.event.repository.default_branch }}

- name: Generate test vectors on main branch
run: |
echo "🔧 Generating test vectors on main branch..."
cargo run --bin compact_write
echo "✅ Test vectors generated"

# Switch to the current branch (PR or push)
- name: Checkout current branch
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
git checkout ${{ github.event.pull_request.head.sha }}
else
git checkout ${{ github.sha }}
fi

- name: Test compact codec compatibility
run: |
echo "📖 Testing compact codec compatibility..."
echo "Current branch: $(git rev-parse --abbrev-ref HEAD)"
echo "Current commit: $(git rev-parse --short HEAD)"

# Try to read the test vectors generated on main branch
# This will fail if there are breaking changes in the Compact implementation
cargo run --bin compact_read

echo "✅ Compact codec compatibility verified!"

# Optional: Show diff if there are any changes to test vector files
- name: Show test vector changes (if any)
run: |
if ! git diff --quiet testdata/; then
echo "⚠️ Test vector files have changes:"
git diff --stat testdata/
echo ""
echo "This indicates potential changes in compact serialization format."
echo "Review carefully to ensure backward compatibility is maintained."
else
echo "ℹ️ No changes to test vector files"
fi
continue-on-error: true

# Archive test vectors for debugging if needed
- name: Archive test vectors
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-vectors-${{ github.sha }}
path: testdata/micro/compact/
retention-days: 7
16 changes: 16 additions & 0 deletions Cargo.lock

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

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jsonrpsee-proc-macros = "0.25.1"

async-trait = "0.1.88"
modular-bitfield = "0.11.2"
arbitrary = { version = "1.3" }
proptest = { version = "1.7" }
reth = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
reth-chainspec = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
Expand All @@ -41,7 +43,7 @@ reth-db = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
reth-db-api = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
reth-engine-local = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
reth-engine-primitives = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
reth-ethereum-cli = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
reth-ethereum-cli = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6", features = ["dev"] }
reth-ethereum-engine-primitives = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
reth-ethereum-payload-builder = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
reth-ethereum-primitives = { git = "https://github.com/paradigmxyz/reth", rev = "48941e6" }
Expand Down Expand Up @@ -81,6 +83,7 @@ jemalloc = ["reth/jemalloc"]
asm-keccak = ["reth/asm-keccak"]
min-debug-logs = ["reth/min-debug-logs"]
client = []
arbitrary = []

[profile.maxperf]
inherits = "release"
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ pub mod primitives;
pub mod rpc;
pub mod transaction;

pub mod test_vectors;

#[cfg(test)]
pub mod test_utils;
10 changes: 7 additions & 3 deletions src/primitives/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub type BlsPublicKey = FixedBytes<48>;

/// Berachain block header with additional fields for consensus
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
#[cfg_attr(any(test, feature = "arbitrary"), derive(::arbitrary::Arbitrary))]
#[serde(rename_all = "camelCase")]
pub struct BerachainHeader {
/// The Keccak 256-bit hash of the parent block's header, in its entirety.
Expand Down Expand Up @@ -484,6 +485,7 @@ impl BerachainHeader {
/// The pattern is used because some field types (like B64) cannot derive Compact directly,
/// so we create an internal struct with compatible types (u64 for nonce) and bridge between them.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Compact, Serialize, Deserialize)]
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
struct CompactBerachainHeader {
parent_hash: B256,
ommers_hash: B256,
Expand All @@ -505,10 +507,11 @@ struct CompactBerachainHeader {
excess_blob_gas: Option<u64>,
parent_beacon_block_root: Option<B256>,
extra_fields: Option<BerachainHeaderExt>,
extra_data: Bytes,
// extra_data: Bytes,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Compact, Serialize, Deserialize)]
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
pub(crate) struct BerachainHeaderExt {
requests_hash: Option<B256>,
prev_proposer_pubkey: Option<BlsPublicKey>,
Expand Down Expand Up @@ -559,7 +562,7 @@ impl Compact for BerachainHeader {
excess_blob_gas: self.excess_blob_gas,
parent_beacon_block_root: self.parent_beacon_block_root,
extra_fields: extra_fields.into_option(),
extra_data: self.extra_data.clone(),
// extra_data: self.extra_data.clone(),
};
compact_header.to_compact(buf)
}
Expand Down Expand Up @@ -593,7 +596,8 @@ impl Compact for BerachainHeader {
parent_beacon_block_root: header.parent_beacon_block_root,
requests_hash: header.extra_fields.as_ref().and_then(|h| h.requests_hash),
prev_proposer_pubkey: header.extra_fields.as_ref().and_then(|h| h.prev_proposer_pubkey),
extra_data: header.extra_data,
extra_data: Bytes::new(),
// extra_data: header.extra_data,
};

(berachain_header, buf)
Expand Down
47 changes: 47 additions & 0 deletions src/test_vectors/compact.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//! Compact test vectors for Berachain custom types
//!
//! This module provides functions to read and validate Berachain-specific compact test vectors.

use crate::primitives::BerachainHeader;
use eyre::Result;
use proptest::test_runner::TestRunner;
use reth_cli_commands::{
compact_types,
test_vectors::compact::{
generate_vector, generate_vectors_with, read_vector, read_vectors_with,
},
};

/// Generates test vectors for both reth standard types and Berachain extensions
pub fn generate_berachain_vectors() -> Result<()> {
println!("Generating test vectors for berachain types...");

generate_vectors_with(GENERATE_VECTORS)?;
Ok(())
}

/// Reads and validates test vectors for BerachainHeader using reth's infrastructure
pub fn read_berachain_vectors() -> Result<()> {
read_vectors_with(READ_VECTORS)?;
Ok(())
}

compact_types!(
regular: [BerachainHeader],
identifier: []
);

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_berachain_header_test_vectors() {
// Test that we can generate and read back BerachainHeader
// let result = generate_berachain_vectors();
// assert!(result.is_ok(), "Failed to generate BerachainHeader test vectors: {:?}", result);
// generate_berachain_vectors().unwrap();

read_berachain_vectors().unwrap();
}
}
1 change: 1 addition & 0 deletions src/test_vectors/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod compact;
1 change: 1 addition & 0 deletions src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub enum TxConversionError {
}

#[derive(Debug, Default, Clone, Hash, Eq, PartialEq, Compact)]
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
pub struct PoLTx {
pub chain_id: ChainId,
pub from: Address, // system address - serde skip as from is derived from recover_signer in RPC
Expand Down
1 change: 1 addition & 0 deletions testdata/micro/compact/BerachainHeader.json

Large diffs are not rendered by default.

Loading