Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e832452
feat: add BerachainArgs with optional PoG flags
camembera Feb 23, 2026
5521591
feat: add Proof of Gossip service
camembera Feb 23, 2026
0b4f577
chore: add dependencies for Proof of Gossip
camembera Feb 23, 2026
d032bb2
feat: integrate Proof of Gossip service
camembera Feb 23, 2026
de1bf45
feat: PoG reputation scoring with configurable penalty
camembera Feb 23, 2026
a595748
style: cargo fmt
camembera Feb 23, 2026
cdaac8c
fix: use internal provider for PoG
camembera Feb 23, 2026
3286ee9
fix: set sqlite journal mode via pragma_update
camembera Feb 23, 2026
81f30a6
fix: gate PoG on sync and reconcile nonce
camembera Feb 23, 2026
06e889f
fix: fail loud on nonce/base-fee lookup, add startup delay
camembera Feb 23, 2026
91a8804
fix PoG canary fee cap and remove startup delay
camembera Feb 24, 2026
44a6b1a
chore: revert fmt-only changes in non-PoG files
camembera Feb 24, 2026
f315976
feat: add pog telemetry metrics
camembera Feb 24, 2026
968071f
fix: run pog with graceful shutdown
camembera Feb 24, 2026
cfcb7d0
fix: resolve clippy warnings in proof_of_gossip
camembera Feb 24, 2026
b3787aa
cargo fmt
camembera Feb 24, 2026
612a7c6
refactor: address CodeRabbit review (PoG args, metrics, tests)
camembera Feb 24, 2026
7b03a36
cargo fmt
camembera Feb 24, 2026
733d99e
refactor: add PogError result type for PoG
camembera Feb 24, 2026
0d15b69
fix: resolve clippy and advisory failures
camembera Feb 24, 2026
b1e335f
style: apply CI rustfmt output
camembera Feb 24, 2026
5f53b4f
feat: use PoG private key file
camembera Feb 24, 2026
00c9f34
fix: harden PoG nonce and penalty logic
camembera Feb 24, 2026
6ca0435
style: fix args import ordering
camembera Feb 24, 2026
cb0d0fe
fix: preserve confirmed active canary state
camembera Feb 24, 2026
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
59 changes: 52 additions & 7 deletions Cargo.lock

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

8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ alloy-rlp = "0.3.10"
alloy-rpc-types = "1.0.41"
alloy-rpc-types-eth = "1.0.41"
alloy-serde = "1.0.41"
alloy-signer = "1.0.41"
alloy-signer-local = "1.0.41"
alloy-sol-macro = "1.4.1"
alloy-sol-types = "1.4.1"
bytes = "1.10.1"
clap = { version = "4.5.40", features = ["derive"] }
derive_more = "2.0.1"
eyre = "0.6.12"
rand = "0.8"
rusqlite = { version = "0.32", features = ["bundled"] }
sha2 = "0.10"

# rpc
Expand All @@ -43,12 +46,16 @@ reth-db-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-engine-local = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-engine-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-errors = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-eth-wire-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-ethereum-cli = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-ethereum-engine-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-ethereum-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-ethereum-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-evm = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-evm-ethereum = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-metrics = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-network = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-network-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-network-peers = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-node-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-node-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
Expand Down Expand Up @@ -77,6 +84,7 @@ reth-e2e-test-utils = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9
reth-rpc-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
revm-inspectors = "0.32.0"
serde_json = "1.0"
tempfile = "3"
test-fuzz = "7"

[build-dependencies]
Expand Down
96 changes: 96 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use clap::Args;
use std::path::PathBuf;

const DEFAULT_POG_TIMEOUT_SECS: u64 = 120;
const DEFAULT_POG_REPUTATION_PENALTY: i32 = -25600;

#[derive(Debug, Clone, Default, Args)]
#[command(next_help_heading = "Proof of Gossip")]
pub struct BerachainArgs {
#[arg(long = "pog.private-key-file")]
pub pog_private_key_file: Option<PathBuf>,

#[arg(long = "pog.timeout", default_value_t = DEFAULT_POG_TIMEOUT_SECS)]
pub pog_timeout: u64,

#[arg(
long = "pog.reputation-penalty",
default_value_t = DEFAULT_POG_REPUTATION_PENALTY,
allow_hyphen_values = true
)]
pub pog_reputation_penalty: i32,
}

#[cfg(test)]
mod tests {
use super::*;
use clap::{Parser, error::ErrorKind};
use std::path::PathBuf;

#[derive(Parser)]
struct TestCli {
#[command(flatten)]
args: BerachainArgs,
}

#[test]
fn test_defaults() {
let cli = TestCli::parse_from(["test"]);
assert_eq!(cli.args.pog_private_key_file, None);
assert_eq!(cli.args.pog_timeout, DEFAULT_POG_TIMEOUT_SECS);
assert_eq!(cli.args.pog_reputation_penalty, DEFAULT_POG_REPUTATION_PENALTY);
}

#[test]
fn test_with_private_key_file() {
let key_file = "/tmp/pog.key";
let cli = TestCli::parse_from(["test", "--pog.private-key-file", key_file]);
assert_eq!(
cli.args.pog_private_key_file.as_deref(),
Some(PathBuf::from(key_file).as_path())
);
assert_eq!(cli.args.pog_timeout, DEFAULT_POG_TIMEOUT_SECS);
}

#[test]
fn test_with_all_flags() {
let key_file = "/tmp/pog.key";
let cli = TestCli::parse_from([
"test",
"--pog.private-key-file",
key_file,
"--pog.timeout",
"300",
"--pog.reputation-penalty",
"-50000",
]);
assert_eq!(
cli.args.pog_private_key_file.as_deref(),
Some(PathBuf::from(key_file).as_path())
);
assert_eq!(cli.args.pog_timeout, 300);
assert_eq!(cli.args.pog_reputation_penalty, -50000);
}

#[test]
fn test_with_explicit_reputation_penalty() {
let cli = TestCli::parse_from(["test", "--pog.reputation-penalty", "-10000"]);
assert_eq!(cli.args.pog_reputation_penalty, -10000);
}

#[test]
fn test_feature_off_when_flag_absent() {
let cli = TestCli::parse_from(["test", "--pog.timeout", "60"]);
assert_eq!(cli.args.pog_private_key_file, None);
assert_eq!(cli.args.pog_timeout, 60);
}

#[test]
fn test_rejects_old_private_key_flag() {
let key = format!("0x{:064x}", 1u64);
let parsed = TestCli::try_parse_from(["test", "--pog.private-key", &key]);
assert!(parsed.is_err());
let err = parsed.err().expect("old flag should be rejected");
assert_eq!(err.kind(), ErrorKind::UnknownArgument);
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//! Built on Reth SDK with Ethereum compatibility plus Prague1 hardfork for minimum base fee.

pub mod args;
pub mod chainspec;
pub mod consensus;
pub mod engine;
Expand All @@ -11,6 +12,7 @@ pub mod hardforks;
pub mod node;
pub mod pool;
pub mod primitives;
pub mod proof_of_gossip;
pub mod rpc;
pub mod transaction;
pub mod version;
Expand Down
25 changes: 20 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
static ALLOC: reth_cli_util::allocator::Allocator = reth_cli_util::allocator::new_allocator();

use bera_reth::{
args::BerachainArgs,
chainspec::{BerachainChainSpec, BerachainChainSpecParser},
consensus::BerachainBeaconConsensus,
evm::BerachainEvmFactory,
node::{BerachainNode, evm::config::BerachainEvmConfig},
proof_of_gossip::new_pog_service,
version::init_bera_version,
};
use clap::Parser;
use reth::CliRunner;
use reth_cli_commands::node::NoArgs;
use reth::{
CliRunner,
chainspec::{ChainSpecProvider, EthChainSpec},
};
use reth_ethereum_cli::Cli;
use reth_node_builder::NodeHandle;
use std::sync::Arc;
Expand All @@ -37,15 +41,26 @@ fn main() {
)
};

if let Err(err) = Cli::<BerachainChainSpecParser, NoArgs>::parse()
if let Err(err) = Cli::<BerachainChainSpecParser, BerachainArgs>::parse()
.with_runner_and_components::<BerachainNode>(
CliRunner::try_default_runtime().expect("Failed to create default runtime"),
cli_components_builder,
async move |builder, _| {
async move |builder, args| {
info!(target: "reth::cli", "Launching Berachain node");
let NodeHandle { node: _node, node_exit_future } =
let NodeHandle { node, node_exit_future } =
builder.node(BerachainNode::default()).launch_with_debug_capabilities().await?;

if let Some(service) = new_pog_service(
node.network.clone(),
node.provider.clone(),
node.provider.chain_spec().chain().id(),
node.config.datadir().data_dir().to_path_buf(),
&args,
)? {
node.task_executor
.spawn_with_graceful_shutdown_signal(|shutdown| service.run(shutdown));
}

node_exit_future.await
},
)
Expand Down
Loading