diff --git a/Cargo.lock b/Cargo.lock index 4c543c49..2b5e93cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -957,6 +957,7 @@ version = "0.1.0" dependencies = [ "anyhow", "common-http-client", + "nomos-core", "reqwest", ] diff --git a/bedrock_client/Cargo.toml b/bedrock_client/Cargo.toml index 034a093e..e6f6f02a 100644 --- a/bedrock_client/Cargo.toml +++ b/bedrock_client/Cargo.toml @@ -7,3 +7,4 @@ edition = "2024" reqwest.workspace = true anyhow.workspace = true common-http-client.workspace = true +nomos-core.workspace = true diff --git a/bedrock_client/src/lib.rs b/bedrock_client/src/lib.rs index 9315f083..a5e0a049 100644 --- a/bedrock_client/src/lib.rs +++ b/bedrock_client/src/lib.rs @@ -1,21 +1,33 @@ use anyhow::Result; use common_http_client::CommonHttpClient; pub use common_http_client::{BasicAuthCredentials, Error}; -use reqwest::Client; +use nomos_core::mantle::SignedMantleTx; +use reqwest::{Client, Url}; // Simple wrapper // maybe extend in the future for our purposes -pub struct BedrockClient(pub CommonHttpClient); +pub struct BedrockClient { + http_client: CommonHttpClient, + node_url: Url, +} impl BedrockClient { - pub fn new(auth: Option) -> Result { + pub fn new(auth: Option, node_url: Url) -> Result { let client = Client::builder() //Add more fiedls if needed .timeout(std::time::Duration::from_secs(60)) .build()?; - Ok(BedrockClient(CommonHttpClient::new_with_client( - client, auth, - ))) + let http_client = CommonHttpClient::new_with_client(client, auth); + Ok(Self { + http_client, + node_url, + }) + } + + pub async fn post_transaction(&self, tx: SignedMantleTx) -> Result<(), Error> { + self.http_client + .post_transaction(self.node_url.clone(), tx) + .await } } diff --git a/sequencer_core/src/block_settlement_client.rs b/sequencer_core/src/block_settlement_client.rs index e14b1b47..58f4d7f4 100644 --- a/sequencer_core/src/block_settlement_client.rs +++ b/sequencer_core/src/block_settlement_client.rs @@ -8,13 +8,11 @@ use nomos_core::mantle::{ MantleTx, Op, OpProof, SignedMantleTx, Transaction, TxHash, ledger, ops::channel::{ChannelId, MsgId, inscribe::InscriptionOp}, }; -use reqwest::Url; use crate::config::BedrockConfig; /// A component that posts block data to logos blockchain pub struct BlockSettlementClient { - bedrock_node_url: Url, bedrock_client: BedrockClient, bedrock_signing_key: Ed25519Key, bedrock_channel_id: ChannelId, @@ -22,24 +20,21 @@ pub struct BlockSettlementClient { } impl BlockSettlementClient { - pub fn new(home: &Path, config: &BedrockConfig) -> Self { - let bedrock_signing_key = load_or_create_signing_key(&home.join("bedrock_signing_key")) - .expect("Signing key should load or be created successfully"); - let bedrock_node_url = config.node_url.clone(); + pub fn try_new(home: &Path, config: &BedrockConfig) -> Result { + let bedrock_signing_key = load_or_create_signing_key(&home.join("bedrock_signing_key"))?; let bedrock_channel_id = ChannelId::from(config.channel_id); - let bedrock_client = - BedrockClient::new(None).expect("Bedrock client should be able to initialize"); - Self { - bedrock_node_url, + let bedrock_client = BedrockClient::new(None, config.node_url.clone())?; + let channel_genesis_msg = MsgId::from([0; 32]); + Ok(Self { bedrock_client, bedrock_signing_key, bedrock_channel_id, - last_message_id: MsgId::from([0; 32]), - } + last_message_id: channel_genesis_msg, + }) } /// Create and sign a transaction for inscribing data - pub fn create_inscribe_tx(&self, data: Vec) -> SignedMantleTx { + pub fn create_inscribe_tx(&self, data: Vec) -> (SignedMantleTx, MsgId) { let verifying_key_bytes = self.bedrock_signing_key.public_key().to_bytes(); let verifying_key = Ed25519PublicKey::from_bytes(&verifying_key_bytes).expect("valid ed25519 public key"); @@ -50,12 +45,14 @@ impl BlockSettlementClient { parent: self.last_message_id, signer: verifying_key, }; + let inscribe_op_id = inscribe_op.id(); let ledger_tx = ledger::Tx::new(vec![], vec![]); let inscribe_tx = MantleTx { ops: vec![Op::ChannelInscribe(inscribe_op)], ledger_tx, + // Altruistic test config storage_gas_price: 0, execution_gas_price: 0, }; @@ -68,27 +65,23 @@ impl BlockSettlementClient { let signature = key_management_system_service::keys::Ed25519Signature::from_bytes(&signature_bytes); - SignedMantleTx { + let signed_mantle_tx = SignedMantleTx { ops_proofs: vec![OpProof::Ed25519Sig(signature)], ledger_tx_proof: empty_ledger_signature(&tx_hash), mantle_tx: inscribe_tx, - } + }; + (signed_mantle_tx, inscribe_op_id) } /// Post a transaction to the node and wait for inclusion pub async fn post_and_wait(&mut self, block_data: &HashableBlockData) -> Result { let inscription_data = borsh::to_vec(&block_data)?; - let tx = self.create_inscribe_tx(inscription_data); + let (tx, new_msg_id) = self.create_inscribe_tx(inscription_data); // Post the transaction - self.bedrock_client - .0 - .post_transaction(self.bedrock_node_url.clone(), tx.clone()) - .await?; + self.bedrock_client.post_transaction(tx).await?; - if let Some(Op::ChannelInscribe(inscribe)) = tx.mantle_tx.ops.first() { - self.last_message_id = inscribe.id(); - } + self.last_message_id = new_msg_id; Ok(block_data.block_id) } diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index a7a16826..89cafc4c 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -89,10 +89,10 @@ impl SequencerCore { state.add_pinata_program(PINATA_BASE58.parse().unwrap()); let (mempool, mempool_handle) = MemPool::new(config.mempool_max_size); - let block_settlement = config - .bedrock_config - .as_ref() - .map(|bedrock_config| BlockSettlementClient::new(&config.home, bedrock_config)); + let block_settlement_client = config.bedrock_config.as_ref().map(|bedrock_config| { + BlockSettlementClient::try_new(&config.home, bedrock_config) + .expect("Block settlement client should be constructible") + }); let mut this = Self { state, @@ -100,7 +100,7 @@ impl SequencerCore { mempool, chain_height: config.genesis_id, sequencer_config: config, - block_settlement_client: block_settlement, + block_settlement_client, }; this.sync_state_with_stored_blocks(); @@ -203,7 +203,7 @@ impl SequencerCore { self.chain_height = new_block_height; // TODO: Consider switching to `tracing` crate to have more structured and consistent logs - // // e.g. + // e.g. // // ``` // info!(