Skip to content

Commit

Permalink
bundle stream
Browse files Browse the repository at this point in the history
  • Loading branch information
itamarreif committed Nov 1, 2024
1 parent b264b5a commit 1baddf2
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/astria-auctioneer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ async-trait = { workspace = true }
axum = { workspace = true }
bytes = { workspace = true }
futures = { workspace = true }
hex = { workspace = true }
humantime = { workspace = true }
itertools = { workspace = true }
pbjson-types = { workspace = true }
Expand Down
25 changes: 19 additions & 6 deletions crates/astria-auctioneer/src/auction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ mod builder;
use std::time::Duration;

use allocation_rule::FirstPrice;
use astria_core::protocol::transaction::v1::Transaction;
use astria_core::{
primitive::v1::{
asset,
RollupId,
},
protocol::transaction::v1::Transaction,
};
use astria_eyre::eyre::{
self,
eyre,
Expand All @@ -21,6 +27,7 @@ use tokio_util::sync::CancellationToken;

use crate::{
bundle::Bundle,
sequencer_key::SequencerKey,
Metrics,
};

Expand Down Expand Up @@ -114,17 +121,21 @@ struct Auction {
latency_margin: Duration,
/// The ID of the auction
auction_id: Id,
/// The key used to sign transactions on the sequencer
sequencer_key: SequencerKey,
/// Fee asset for submitting transactions
fee_asset: asset::Denom,
/// Rollup ID to submit the auction result to
rollup_id: RollupId,
}

impl Auction {
// TODO: document auction as a state machine here
pub(crate) async fn run(mut self) -> eyre::Result<()> {
// TODO: should the timer be inside the auction so that we only have one option?
let mut latency_margin_timer = None;
let allocation_rule = FirstPrice::new();
let mut auction_is_open = false;

let mut nonce_fetch: Option<tokio::task::JoinHandle<eyre::Result<u64>>> = None;
let mut nonce_fetch: Option<tokio::task::JoinHandle<eyre::Result<u32>>> = None;

let auction_result = loop {
select! {
Expand Down Expand Up @@ -187,10 +198,12 @@ impl Auction {
.wrap_err("failed to fetch nonce")?;

// handle auction result
let transaction = auction_result
let transaction_body = auction_result
.wrap_err("")?
.ok_or_eyre("auction ended with no winning bid")?
.into_transaction_body(nonce);
.into_transaction_body(nonce, self.rollup_id, self.fee_asset.clone());

let transaction = transaction_body.sign(self.sequencer_key.signing_key());

let submission_result = select! {
biased;
Expand Down
15 changes: 7 additions & 8 deletions crates/astria-auctioneer/src/bundle/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use astria_core::{
generated::{
bundle::v1alpha1::{
self as raw,
},
primitive::v1::RollupId,
generated::bundle::v1alpha1::{
self as raw,
},
primitive::v1::{
asset,
RollupId,
},
primitive::v1::asset,
protocol::transaction::v1::{
action::RollupDataSubmission,
Transaction,
TransactionBody,
},
};
Expand Down Expand Up @@ -78,7 +77,7 @@ impl Bundle {
.actions(vec![
RollupDataSubmission {
rollup_id,
data,
data: data.into(),
fee_asset,
}
.into(),
Expand Down
1 change: 1 addition & 0 deletions crates/astria-auctioneer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub(crate) mod metrics;
mod optimistic_execution_client;
mod optimistic_executor;
mod sequencer_grpc_client;
mod sequencer_key;

use astria_eyre::{
eyre,
Expand Down
8 changes: 4 additions & 4 deletions crates/astria-auctioneer/src/optimistic_executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,6 @@ impl Running {
Ok(())
}

async fn shutdown(self) {
self.shutdown_token.cancel();
}

#[instrument(skip(self), fields(auction.old_id = %base64(self.current_block.sequencer_block_hash())))]
fn optimistic_block_handler(
&mut self,
Expand Down Expand Up @@ -241,4 +237,8 @@ impl Running {

Ok(())
}

async fn shutdown(self) {
self.shutdown_token.cancel();
}
}
107 changes: 107 additions & 0 deletions crates/astria-auctioneer/src/sequencer_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use std::{
fs,
path::{
Path,
PathBuf,
},
};

use astria_core::{
crypto::SigningKey,
primitive::v1::Address,
};
use astria_eyre::eyre::{
self,
bail,
eyre,
Context,
};

pub(crate) struct SequencerKey {
address: Address,
signing_key: SigningKey,
}

pub(crate) struct SequencerKeyBuilder {
path: Option<PathBuf>,
prefix: Option<String>,
}

impl SequencerKeyBuilder {
/// Sets the path from which the sequencey key is read.
///
/// The file at `path` should contain a hex-encoded ed25519 secret key.
pub(crate) fn path<P: AsRef<Path>>(self, path: P) -> Self {
Self {
path: Some(path.as_ref().to_path_buf()),
..self
}
}

/// Sets the prefix for constructing a bech32m sequencer address.
///
/// The prefix must be a valid bech32 human-readable-prefix (Hrp).
pub(crate) fn prefix<S: AsRef<str>>(self, prefix: S) -> Self {
Self {
prefix: Some(prefix.as_ref().to_string()),
..self
}
}

pub(crate) fn try_build(self) -> eyre::Result<SequencerKey> {
let Some(path) = self.path else {
bail!("path to sequencer key file must be set");
};
let Some(prefix) = self.prefix else {
bail!(
"a prefix to construct bech32m complicant astria addresses from the signing key \
must be set"
);
};
let hex = fs::read_to_string(&path).wrap_err_with(|| {
format!("failed to read sequencer key from path: {}", path.display())
})?;
let bytes: [u8; 32] = hex::decode(hex.trim())
.wrap_err_with(|| format!("failed to decode hex: {}", path.display()))?
.try_into()
.map_err(|_| {
eyre!(
"invalid private key length; must be 32 bytes: {}",
path.display()
)
})?;
let signing_key = SigningKey::from(bytes);
let address = Address::builder()
.array(signing_key.address_bytes())
.prefix(&prefix)
.try_build()
.wrap_err_with(|| {
format!(
"failed constructing valid sequencer address using the provided prefix \
`{prefix}`"
)
})?;

Ok(SequencerKey {
address,
signing_key,
})
}
}

impl SequencerKey {
pub(crate) fn builder() -> SequencerKeyBuilder {
SequencerKeyBuilder {
path: None,
prefix: None,
}
}

pub(crate) fn address(&self) -> &Address {
&self.address
}

pub(crate) fn signing_key(&self) -> &SigningKey {
&self.signing_key
}
}

0 comments on commit 1baddf2

Please sign in to comment.