Skip to content

Commit

Permalink
change signer to enum
Browse files Browse the repository at this point in the history
  • Loading branch information
noot committed Mar 5, 2025
1 parent b47767c commit 65033c4
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 60 deletions.
29 changes: 20 additions & 9 deletions crates/astria-bridge-withdrawer/src/bridge_withdrawer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,19 +288,21 @@ async fn make_signer(
frost_participant_endpoints: Vec<String>,
sequencer_key_path: String,
sequencer_address_prefix: String,
) -> eyre::Result<Arc<dyn Signer>> {
let signer: Arc<dyn Signer> = if frost_threshold_signing_enabled {
let public_key_package_str = std::fs::read_to_string(frost_public_key_package_path)
.wrap_err("failed to read frost public key package")?;
) -> eyre::Result<Signer> {
let signer = if frost_threshold_signing_enabled {
let public_key_package =
serde_json::from_str::<frost_ed25519::keys::PublicKeyPackage>(&public_key_package_str)
.wrap_err("failed to deserialize public key package")?;
read_frost_key(&frost_public_key_package_path).wrap_err_with(|| {
format!(
"failed reading frost public key package from file \
`{frost_public_key_package_path}`"
)
})?;

let participant_clients =
initialize_frost_participant_clients(frost_participant_endpoints, &public_key_package)
.await
.wrap_err("failed to initialize frost participant clients")?;
Arc::new(
Signer::Threshold(
FrostSignerBuilder::new()
.min_signers(frost_min_signers)
.public_key_package(public_key_package)
Expand All @@ -310,17 +312,26 @@ async fn make_signer(
.wrap_err("failed to initialize frost signer")?,
)
} else {
Arc::new(
Signer::Single(Box::new(
crate::bridge_withdrawer::submitter::signer::SequencerKey::builder()
.path(sequencer_key_path)
.prefix(sequencer_address_prefix)
.try_build()
.wrap_err("failed to load sequencer private key")?,
)
))
};
Ok(signer)
}

fn read_frost_key<P: AsRef<std::path::Path>>(
path: P,
) -> eyre::Result<frost_ed25519::keys::PublicKeyPackage> {
let key_str =
std::fs::read_to_string(path).wrap_err("failed to read frost public key package")?;
serde_json::from_str::<frost_ed25519::keys::PublicKeyPackage>(&key_str)
.wrap_err("failed to deserialize public key package")
}

#[expect(
clippy::struct_field_names,
reason = "for parity with the `Shutdown` struct"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl Handle {
pub(crate) struct Builder {
pub(crate) shutdown_token: CancellationToken,
pub(crate) startup_handle: startup::InfoHandle,
pub(crate) signer: Arc<dyn Signer>,
pub(crate) signer: Signer,
pub(crate) sequencer_cometbft_client: sequencer_client::HttpClient,
pub(crate) sequencer_grpc_client: SequencerServiceClient<tonic::transport::Channel>,
pub(crate) state: Arc<State>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use astria_eyre::eyre::{
self,
ensure,
eyre,
Context,
WrapErr as _,
};
use frost_ed25519::{
keys::{
Expand All @@ -39,8 +39,6 @@ use prost::{
Name as _,
};

use super::Signer;

pub(crate) async fn initialize_frost_participant_clients(
endpoints: Vec<String>,
public_key_package: &PublicKeyPackage,
Expand Down Expand Up @@ -172,9 +170,8 @@ pub(crate) struct FrostSigner {
HashMap<Identifier, FrostParticipantServiceClient<tonic::transport::Channel>>,
}

#[tonic::async_trait]
impl Signer for FrostSigner {
async fn sign(&self, tx: TransactionBody) -> eyre::Result<Transaction> {
impl FrostSigner {
pub(crate) async fn sign(&self, tx: TransactionBody) -> eyre::Result<Transaction> {
// part 1: gather commitments from participants
let (commitments, signing_package_commitments) = self.frost_part_1().await;
ensure!(
Expand Down Expand Up @@ -222,7 +219,7 @@ impl Signer for FrostSigner {
Ok(transaction)
}

fn address(&self) -> &Address {
pub(crate) fn address(&self) -> &Address {
&self.address
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub(super) struct Submitter {
batches_rx: mpsc::Receiver<Batch>,
sequencer_cometbft_client: sequencer_client::HttpClient,
sequencer_grpc_client: SequencerServiceClient<Channel>,
signer: Arc<dyn Signer>,
signer: Signer,
metrics: &'static Metrics,
}

Expand Down Expand Up @@ -238,39 +238,6 @@ fn report_exit(reason: eyre::Result<&str>) {
}
}

#[instrument(name = "sign_tx", skip_all, err)]
async fn sign_tx(signer: Arc<dyn Signer>, body: TransactionBody) -> eyre::Result<Transaction> {
let span = Span::current();
let retry_config = tryhard::RetryFutureConfig::new(1024)
.exponential_backoff(Duration::from_millis(200))
.max_delay(Duration::from_secs(60))
.on_retry(
|attempt, next_delay: Option<Duration>, err: &eyre::Report| {
let wait_duration = next_delay
.map(humantime::format_duration)
.map(tracing::field::display);
warn!(
parent: span.clone(),
attempt,
wait_duration,
error = err.as_ref() as &dyn std::error::Error,
"failed signingstart transaction body; retrying after backoff",
);
async move {}
},
);
let signed = tryhard::retry_fn(|| {
let body = body.clone();
let signer = signer.clone();
let span = info_span!(parent: span.clone(), "attempt sign");
async move { signer.sign(body).await }.instrument(span)
})
.with_config(retry_config)
.await
.wrap_err("failed to sign transaction after 1024 attempts")?;
Ok(signed)
}

/// Submits a transaction to the sequencer with exponential backoff.
#[instrument(
name = "submit_tx",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,28 @@ use astria_eyre::eyre::{
eyre,
Context,
};
use tonic::async_trait;

#[async_trait]
pub(crate) trait Signer: Send + Sync {
fn address(&self) -> &Address;
async fn sign(&self, tx: TransactionBody) -> eyre::Result<Transaction>;
use super::frost_signer::FrostSigner;

pub(crate) enum Signer {
Single(Box<SequencerKey>),
Threshold(FrostSigner),
}

impl Signer {
pub(crate) fn address(&self) -> &Address {
match self {
Self::Single(signer) => signer.address(),
Self::Threshold(signer) => signer.address(),
}
}

pub(crate) async fn sign(&self, tx: TransactionBody) -> eyre::Result<Transaction> {
match self {
Self::Single(signer) => Ok(signer.sign(tx)),
Self::Threshold(signer) => signer.sign(tx).await,
}
}
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -110,13 +126,12 @@ impl SequencerKey {
}
}

#[async_trait]
impl Signer for SequencerKey {
impl SequencerKey {
fn address(&self) -> &Address {
&self.address
}

async fn sign(&self, tx: TransactionBody) -> eyre::Result<Transaction> {
Ok(tx.sign(&self.signing_key))
fn sign(&self, tx: TransactionBody) -> Transaction {
tx.sign(&self.signing_key)
}
}

0 comments on commit 65033c4

Please sign in to comment.