Skip to content
Closed
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ test-infra/sszfixtures/sszfixtures

.claude/worktrees/
.claude/scheduled_tasks.lock
.claude/notes/
test-cluster
36 changes: 33 additions & 3 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ members = [
"crates/cli",
"crates/cluster",
"crates/core",
"crates/core-utils",
"crates/crypto",
"crates/dkg",
"crates/eth2api",
"crates/eth2util",
"crates/eth1wrap",
"crates/eth2wrap",
"crates/featureset",
"crates/k1util",
"crates/relay-server",
Expand Down Expand Up @@ -131,6 +133,8 @@ pluto-tracing = { path = "crates/tracing" }
pluto-p2p = { path = "crates/p2p" }
pluto-peerinfo = { path = "crates/peerinfo" }
pluto-frost = { path = "crates/frost" }
pluto-eth2wrap = { path = "crates/eth2wrap" }
pluto-core-utils = { path = "crates/core-utils"}

[workspace.lints.rust]
missing_docs = "deny"
Expand Down
2 changes: 0 additions & 2 deletions crates/app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ publish.workspace = true
[dependencies]
backon.workspace = true
chrono.workspace = true
pluto-core.workspace = true
pluto-eth2api.workspace = true
tokio.workspace = true
tokio-util.workspace = true
prost.workspace = true
prost-types.workspace = true
regex.workspace = true
thiserror.workspace = true
tracing.workspace = true
url.workspace = true
Expand Down
5 changes: 0 additions & 5 deletions crates/app/src/eth2wrap/mod.rs

This file was deleted.

3 changes: 0 additions & 3 deletions crates/app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ pub mod retry;
/// Obol API client for interacting with the Obol network API.
pub mod obolapi;

/// Ethereum CL RPC client management.
pub mod eth2wrap;

/// Private key locking service.
pub mod privkeylock;

Expand Down
22 changes: 22 additions & 0 deletions crates/core-utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "pluto-core-utils"
version.workspace = true
edition.workspace = true
repository.workspace = true
license.workspace = true
publish.workspace = true

[dependencies]
chrono.workspace = true
regex.workspace = true
thiserror.workspace = true
tracing.workspace = true
pluto-crypto.workspace = true
serde.workspace = true
hex.workspace = true

[build-dependencies]
built.workspace = true

[lints]
workspace = true
12 changes: 12 additions & 0 deletions crates/core-utils/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! # Charon Core Build Script
//!
//! This build script compiles the protobuf files.

use std::io::Result;

fn main() -> Result<()> {
built::write_built_file()?;
println!("cargo:rerun-if-changed=../../Cargo.lock");

Ok(())
}
7 changes: 7 additions & 0 deletions crates/core-utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//! Dependency-free core utilies

/// Semver version parsing utilities.
pub mod version;

/// PubKey type
pub mod pubkey;
112 changes: 112 additions & 0 deletions crates/core-utils/src/pubkey.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// In golang implementation they use pk_len = 98, which is 0x + [48 bytes]
// We use pk_len = 48, which is [48 bytes], the main difference is that we store
// the pub key as [u8; 48] instead of string.
// [original implementation](https://github.com/ObolNetwork/charon/blob/b3008103c5429b031b63518195f4c49db4e9a68d/core/types.go#L264)
/// Public key length
pub const PK_LEN: usize = 48;

use std::fmt::Display;

pub use pluto_crypto::types::{SIGNATURE_LENGTH, Signature};
use serde::{Deserialize, Serialize};

/// Public key struct
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PubKey(pub(crate) [u8; PK_LEN]);

impl Serialize for PubKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}

impl TryFrom<&str> for PubKey {
type Error = PubKeyError;

fn try_from(value: &str) -> Result<Self, Self::Error> {
let value = value.strip_prefix("0x").unwrap_or(value);
let hex_value = hex::decode(value).map_err(|_| PubKeyError::InvalidString)?;
PubKey::try_from(hex_value.as_slice())
}
}

impl<'de> Deserialize<'de> for PubKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let hex_str = String::deserialize(deserializer)?;
let hex_str = hex_str.strip_prefix("0x").unwrap_or(&hex_str);

let bytes = hex::decode(hex_str).map_err(serde::de::Error::custom)?;

if bytes.len() != PK_LEN {
return Err(serde::de::Error::custom(format!(
"invalid public key length: got {}, want {}",
bytes.len(),
PK_LEN
)));
}

let mut pk = [0u8; PK_LEN];
pk.copy_from_slice(&bytes);
Ok(PubKey(pk))
}
}

impl From<[u8; PK_LEN]> for PubKey {
fn from(pk: [u8; PK_LEN]) -> Self {
PubKey(pk)
}
}

/// Public key error type
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PubKeyError {
/// Invalid public key length.
InvalidLength,
/// Invalid public key string.
InvalidString,
}

impl PubKey {
/// Create a new public key.
pub fn new(pk: [u8; PK_LEN]) -> Self {
PubKey(pk)
}

/// Returns logging-friendly abbreviated form: "b82_97f"
pub fn abbreviated(&self) -> String {
let hex = hex::encode(self.0);
format!("{}_{}", &hex[0..3], &hex[93..96])
}
}

impl TryFrom<&[u8]> for PubKey {
type Error = PubKeyError;

fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
if bytes.len() != PK_LEN {
return Err(PubKeyError::InvalidLength);
}
let mut arr = [0u8; PK_LEN];
arr.copy_from_slice(bytes);
Ok(PubKey(arr))
}
}

impl Display for PubKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "0x{}", hex::encode(self.0))
}
}

/// Implement AsRef<[u8]> for PubKey to allow for easy conversion to bytes.
impl AsRef<[u8]> for PubKey {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
File renamed without changes.
3 changes: 2 additions & 1 deletion crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ k256.workspace = true
libp2p.workspace = true
vise.workspace = true
pluto-crypto.workspace = true
pluto-core-utils.workspace = true
pluto-eth2api.workspace = true
pluto-eth2wrap.workspace = true
pluto-k1util.workspace = true
prost.workspace = true
prost-types.workspace = true
regex.workspace = true
serde.workspace = true
serde_json.workspace = true
base64.workspace = true
Expand Down
5 changes: 2 additions & 3 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ pub mod consensus;
/// Protobuf definitions.
pub mod corepb;

/// Semver version parsing utilities.
pub mod version;

/// Duty deadline tracking and notification.
pub mod deadline;

Expand Down Expand Up @@ -53,6 +50,8 @@ pub use parsigex_codec::ParSigExCodecError;
/// participation.
pub mod tracker;

pub use pluto_core_utils::version;

/// Test utilities.
#[cfg(test)]
pub mod testutils;
Loading
Loading