Skip to content
Open
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
71 changes: 67 additions & 4 deletions lean_client/Cargo.lock

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

6 changes: 5 additions & 1 deletion lean_client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,15 @@ libp2p = { version = "0.56.0", default-features = false, features = [
] }
libp2p-identity = { version = "0.2", features = ["secp256k1"] }
libp2p-mplex = "0.39"
dedicated_executor = { git = "https://github.com/bomanaps/dedicated_executor", rev = "e39afad2959e6ae3f55ed56f6117dfe12ec07359" }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is better to use the grandinetech/dedicated_executor fork, instead of your own one - just add it as a submodule to git repo, and it should work perfectly

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to remove prometheus_metrics dep for standalone use

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, but you can just add it as a submodule, then add it to workspace & have it working the same as main grandine repo does this:
https://github.com/grandinetech/grandine/blob/eeb33a92284751b71a0f44f410308235657c55f3/Cargo.toml#L318

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to submodule grandinetech/dedicated_executor and switch to dedicated_executor = {path = "dedicated_executor" } as you suggested one thing prometheus_metrics only lives inside the grandine monorepo, so easiest is to pull it via git = "grandinetech/grandine" matching how features and http_api_utils are already done here good with that

num-bigint = "0.4"
num-traits = "0.2"
num_cpus = "1"
once_cell = "1.21"
parking_lot = "0.12"
paste = "1.0.15"
pretty_assertions = "1.4"
prometheus = "0.14"
prometheus = { version = "0.14", features = ["process"] }
rand = "0.10"
rand_chacha = "0.10"
rayon = "1"
Expand Down Expand Up @@ -309,6 +311,7 @@ bls = { workspace = true }
chain = { workspace = true }
clap = { workspace = true }
containers = { workspace = true }
dedicated_executor = { workspace = true }
ethereum-types = { workspace = true }
features = { workspace = true }
fork_choice = { workspace = true }
Expand All @@ -317,6 +320,7 @@ http_api = { workspace = true }
libp2p-identity = { workspace = true }
metrics = { workspace = true }
networking = { workspace = true }
num_cpus = { workspace = true }
parking_lot = { workspace = true }
ssz = { workspace = true }
tokio = { workspace = true }
Expand Down
16 changes: 16 additions & 0 deletions lean_client/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::process::Command;

fn main() {
let hash = Command::new("git")
.args(["rev-parse", "--short=8", "HEAD"])
.output()
.ok()
.filter(|o| o.status.success())
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())
.filter(|s| !s.is_empty())
.unwrap_or_else(|| "unknown".to_string());

println!("cargo:rustc-env=GRANDINE_GIT_COMMIT_HASH={hash}");
println!("cargo:rerun-if-changed=../.git/HEAD");
println!("cargo:rerun-if-changed=../.git/refs/heads");
}
40 changes: 40 additions & 0 deletions lean_client/containers/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,46 @@ impl AggregatedSignatureProof {
) -> Result<()> {
self.proof_data.verify(public_keys, message, slot)
}

/// Greedy set-cover over a slice of proofs, returning indices of the proofs
/// to admit in priority order. Repeatedly picks the proof covering the
/// most uncovered validators; stops when no remaining proof adds coverage.
/// Mirrors leanSpec `AggregatedSignatureProof.select_greedily`.
pub fn select_greedily(proofs: &[AggregatedSignatureProof]) -> Vec<usize> {
let mut selected: Vec<usize> = Vec::new();
let mut covered: HashSet<u64> = HashSet::new();
let mut remaining: HashSet<usize> = (0..proofs.len()).collect();

while !remaining.is_empty() {
let best = remaining
.iter()
.copied()
.map(|idx| {
let new_count = proofs[idx]
.get_participant_indices()
.into_iter()
.filter(|vid| !covered.contains(vid))
.count();
(idx, new_count)
})
.max_by_key(|(_, n)| *n);

let Some((best_idx, best_count)) = best else {
break;
};
if best_count == 0 {
break;
}

for vid in proofs[best_idx].get_participant_indices() {
covered.insert(vid);
}
selected.push(best_idx);
remaining.remove(&best_idx);
}

selected
}
}

/// Bitlist representing validator participation in an attestation.
Expand Down
Loading
Loading