diff --git a/Cargo.lock b/Cargo.lock index dee037a6..d16d9793 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1107,7 +1107,7 @@ dependencies = [ [[package]] name = "broadcast-service" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "async-trait", "derivative", @@ -1279,7 +1279,7 @@ dependencies = [ [[package]] name = "chain-service" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "async-trait", "broadcast-service", @@ -1332,7 +1332,7 @@ dependencies = [ [[package]] name = "circuits-prover" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "circuits-utils", "tempfile", @@ -1341,7 +1341,7 @@ dependencies = [ [[package]] name = "circuits-utils" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "dirs", ] @@ -1433,7 +1433,7 @@ dependencies = [ [[package]] name = "common-http-client" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "broadcast-service", "chain-service", @@ -1578,7 +1578,7 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "cryptarchia-engine" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "cfg_eval", "nomos-utils", @@ -1592,7 +1592,7 @@ dependencies = [ [[package]] name = "cryptarchia-sync" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "bytes", "cryptarchia-engine", @@ -1772,7 +1772,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.111", ] [[package]] @@ -2409,7 +2409,7 @@ dependencies = [ [[package]] name = "groth16" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "ark-bn254 0.4.0", "ark-ec 0.4.2", @@ -2718,7 +2718,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2 0.5.10", "system-configuration", "tokio", "tower-service", @@ -3113,7 +3113,7 @@ dependencies = [ [[package]] name = "key-management-system-keys" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "async-trait", "bytes", @@ -3138,13 +3138,28 @@ dependencies = [ [[package]] name = "key-management-system-macros" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "proc-macro2", "quote", "syn 2.0.111", ] +[[package]] +name = "key-management-system-service" +version = "0.1.0" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" +dependencies = [ + "async-trait", + "key-management-system-keys", + "log", + "overwatch", + "serde", + "thiserror 2.0.17", + "tokio", + "tracing", +] + [[package]] name = "key_protocol" version = "0.1.0" @@ -3169,7 +3184,7 @@ dependencies = [ [[package]] name = "kzgrs" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "ark-bls12-381", "ark-ec 0.4.2", @@ -3188,7 +3203,7 @@ dependencies = [ [[package]] name = "kzgrs-backend" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "ark-ff 0.4.2", "ark-poly 0.4.2", @@ -3476,7 +3491,7 @@ dependencies = [ [[package]] name = "mmr" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "ark-ff 0.4.2", "groth16", @@ -3594,7 +3609,7 @@ dependencies = [ [[package]] name = "nomos-blend-crypto" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "blake2", "groth16", @@ -3612,7 +3627,7 @@ dependencies = [ [[package]] name = "nomos-blend-message" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "blake2", "derivative", @@ -3634,7 +3649,7 @@ dependencies = [ [[package]] name = "nomos-blend-proofs" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "ed25519-dalek", "generic-array 1.3.5", @@ -3649,7 +3664,7 @@ dependencies = [ [[package]] name = "nomos-core" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "ark-ff 0.4.2", "async-trait", @@ -3679,7 +3694,7 @@ dependencies = [ [[package]] name = "nomos-da-messages" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "blake2", "futures", @@ -3692,7 +3707,7 @@ dependencies = [ [[package]] name = "nomos-http-api-common" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "axum", "governor", @@ -3707,7 +3722,7 @@ dependencies = [ [[package]] name = "nomos-ledger" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "cryptarchia-engine", "groth16", @@ -3730,7 +3745,7 @@ dependencies = [ [[package]] name = "nomos-network" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "async-trait", "cryptarchia-sync", @@ -3746,7 +3761,7 @@ dependencies = [ [[package]] name = "nomos-storage" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "async-trait", "bytes", @@ -3765,7 +3780,7 @@ dependencies = [ [[package]] name = "nomos-utils" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "async-trait", "blake2", @@ -4143,7 +4158,7 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "pol" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "circuits-prover", "circuits-utils", @@ -4171,7 +4186,7 @@ dependencies = [ [[package]] name = "poq" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "circuits-prover", "circuits-utils", @@ -4193,7 +4208,7 @@ checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "poseidon2" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "ark-bn254 0.4.0", "ark-ff 0.4.2", @@ -4381,7 +4396,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.6.1", + "socket2 0.5.10", "thiserror 2.0.17", "tokio", "tracing", @@ -4418,7 +4433,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.1", + "socket2 0.5.10", "tracing", "windows-sys 0.60.2", ] @@ -5174,14 +5189,19 @@ version = "0.1.0" dependencies = [ "anyhow", "base58", + "bedrock_client", + "borsh", "chrono", "common", "futures", - "indexer", + "key-management-system-service", "log", "mempool", + "nomos-core", "nssa", "nssa_core", + "rand 0.8.5", + "reqwest", "serde", "serde_json", "storage", @@ -5361,7 +5381,7 @@ dependencies = [ [[package]] name = "services-utils" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "async-trait", "futures", @@ -6147,10 +6167,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "utxotree" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "ark-ff 0.4.2", "groth16", + "nomos-core", "num-bigint", "poseidon2", "rpds", @@ -6605,7 +6626,7 @@ checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "witness-generator" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "circuits-utils", "tempfile", @@ -6760,7 +6781,7 @@ dependencies = [ [[package]] name = "zksign" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git?branch=marbella-offsite-2025-12#b47525f893353b0441a34a62b87c85ad27fb8519" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#b89238be3ad8111b9975e1023b87d8672d0edd74" dependencies = [ "circuits-prover", "circuits-utils", diff --git a/Cargo.toml b/Cargo.toml index b010b08f..4a4dc2ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,8 +81,9 @@ base58 = "0.2.0" itertools = "0.14.0" url = "2.5.4" -common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git", branch = "marbella-offsite-2025-12" } -nomos-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git", branch = "marbella-offsite-2025-12" } +common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git" } +key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git" } +nomos-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git" } rocksdb = { version = "0.24.0", default-features = false, features = [ "snappy", diff --git a/common/src/block.rs b/common/src/block.rs index 346c2126..8cc5be89 100644 --- a/common/src/block.rs +++ b/common/src/block.rs @@ -43,7 +43,7 @@ pub struct Block { pub body: BlockBody, } -#[derive(Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)] +#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] pub struct HashableBlockData { pub block_id: BlockId, pub prev_block_hash: BlockHash, diff --git a/integration_tests/configs/sequencer/sequencer_config.json b/integration_tests/configs/sequencer/sequencer_config.json index dd6ce12d..5f36c0d5 100644 --- a/integration_tests/configs/sequencer/sequencer_config.json +++ b/integration_tests/configs/sequencer/sequencer_config.json @@ -164,4 +164,4 @@ "resubscribe_interval": 1000, "channel_id": "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" } -} \ No newline at end of file +} diff --git a/integration_tests/tests/tps.rs b/integration_tests/tests/tps.rs index 6c2de6d9..e03dc5de 100644 --- a/integration_tests/tests/tps.rs +++ b/integration_tests/tests/tps.rs @@ -192,6 +192,7 @@ impl TpsTestManager { resubscribe_interval: 100, channel_id: [42; 32].into(), }, + bedrock_config: None, } } } diff --git a/sequencer_core/Cargo.toml b/sequencer_core/Cargo.toml index 71fe0e16..85e36632 100644 --- a/sequencer_core/Cargo.toml +++ b/sequencer_core/Cargo.toml @@ -19,6 +19,12 @@ tempfile.workspace = true chrono.workspace = true log.workspace = true tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } +bedrock_client.workspace = true +key-management-system-service.workspace = true +nomos-core.workspace=true +rand.workspace = true +reqwest.workspace = true +borsh.workspace = true [features] default = [] diff --git a/sequencer_core/src/block_settlement_client.rs b/sequencer_core/src/block_settlement_client.rs new file mode 100644 index 00000000..1964f37f --- /dev/null +++ b/sequencer_core/src/block_settlement_client.rs @@ -0,0 +1,120 @@ +use std::{fs, path::Path}; + +use anyhow::Result; +use bedrock_client::BedrockClient; +use common::block::HashableBlockData; +use key_management_system_service::keys::{ED25519_SECRET_KEY_SIZE, Ed25519Key, Ed25519PublicKey}; +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, +} + +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 = + Url::parse(&config.node_url).expect("Bedrock URL should be a valid URL"); + 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, + bedrock_client, + bedrock_signing_key, + bedrock_channel_id, + } + } + + /// Create and sign a transaction for inscribing data + pub fn create_inscribe_tx(&self, data: Vec, parent: MsgId) -> SignedMantleTx { + 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"); + + let inscribe_op = InscriptionOp { + channel_id: self.bedrock_channel_id, + inscription: data, + parent, + signer: verifying_key, + }; + + let ledger_tx = ledger::Tx::new(vec![], vec![]); + + let inscribe_tx = MantleTx { + ops: vec![Op::ChannelInscribe(inscribe_op)], + ledger_tx, + storage_gas_price: 0, + execution_gas_price: 0, + }; + + let tx_hash = inscribe_tx.hash(); + let signature_bytes = self + .bedrock_signing_key + .sign_payload(tx_hash.as_signing_bytes().as_ref()) + .to_bytes(); + let signature = + key_management_system_service::keys::Ed25519Signature::from_bytes(&signature_bytes); + + SignedMantleTx { + ops_proofs: vec![OpProof::Ed25519Sig(signature)], + ledger_tx_proof: empty_ledger_signature(&tx_hash), + mantle_tx: inscribe_tx, + } + } + + /// Post a transaction to the node and wait for inclusion + pub async fn post_and_wait(&self, block_data: &HashableBlockData) -> Result { + let msg_id: MsgId = { + let mut this = [0; 32]; + this[0..8].copy_from_slice(&block_data.block_id.to_le_bytes()); + this.into() + }; + + let inscription_data = borsh::to_vec(&block_data)?; + let tx = self.create_inscribe_tx(inscription_data, msg_id); + + // Post the transaction + self.bedrock_client + .0 + .post_transaction(self.bedrock_node_url.clone(), tx.clone()) + .await?; + + Ok(block_data.block_id) + } +} + +/// Load signing key from file or generate a new one if it doesn't exist +fn load_or_create_signing_key(path: &Path) -> Result { + if path.exists() { + let key_bytes = fs::read(path).map_err(|_| ())?; + if key_bytes.len() != ED25519_SECRET_KEY_SIZE { + // TODO: proper error + return Err(()); + } + let key_array: [u8; ED25519_SECRET_KEY_SIZE] = + key_bytes.try_into().expect("length already checked"); + Ok(Ed25519Key::from_bytes(&key_array)) + } else { + let mut key_bytes = [0u8; ED25519_SECRET_KEY_SIZE]; + rand::RngCore::fill_bytes(&mut rand::thread_rng(), &mut key_bytes); + fs::write(path, key_bytes).map_err(|_| ())?; + Ok(Ed25519Key::from_bytes(&key_bytes)) + } +} + +fn empty_ledger_signature(tx_hash: &TxHash) -> key_management_system_service::keys::ZkSignature { + key_management_system_service::keys::ZkKey::multi_sign(&[], tx_hash.as_ref()) + .expect("multi-sign with empty key set works") +} diff --git a/sequencer_core/src/config.rs b/sequencer_core/src/config.rs index 785c5328..396a89e9 100644 --- a/sequencer_core/src/config.rs +++ b/sequencer_core/src/config.rs @@ -54,6 +54,16 @@ pub struct SequencerConfig { pub bedrock_auth: (String, String), /// Indexer config pub indexer_config: IndexerConfig, + /// Bedrock configuration options + pub bedrock_config: Option, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct BedrockConfig { + /// Bedrock channel ID + pub channel_id: [u8; 32], + /// Bedrock Url + pub node_url: String, } impl SequencerConfig { diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 2c57a765..245990ad 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -14,8 +14,9 @@ use mempool::{MemPool, MemPoolHandle}; use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::Receiver; -use crate::block_store::SequencerBlockStore; +use crate::{block_settlement_client::BlockSettlementClient, block_store::SequencerBlockStore}; +mod block_settlement_client; pub mod block_store; pub mod config; @@ -28,6 +29,7 @@ pub struct SequencerCore { // No logic here for now #[allow(unused)] receiver: Receiver, + block_settlement_client: Option, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -94,6 +96,11 @@ 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 mut this = Self { state, block_store, @@ -101,6 +108,7 @@ impl SequencerCore { chain_height: config.genesis_id, sequencer_config: config, receiver, + block_settlement_client: block_settlement, }; this.sync_state_with_stored_blocks(); @@ -145,9 +153,21 @@ impl SequencerCore { Ok(tx) } + pub async fn produce_new_block_and_post_to_settlement_layer(&mut self) -> Result { + let block_data = self.produce_new_block_with_mempool_transactions()?; + + if let Some(block_settlement) = &self.block_settlement_client { + block_settlement.post_and_wait(&block_data).await?; + log::info!("Posted block data to Bedrock"); + } + + Ok(self.chain_height) + } + /// Produces new block from transactions in mempool - pub fn produce_new_block_with_mempool_transactions(&mut self) -> Result { + pub fn produce_new_block_with_mempool_transactions(&mut self) -> Result { let now = Instant::now(); + let new_block_height = self.chain_height + 1; let mut valid_transactions = vec![]; @@ -175,8 +195,6 @@ impl SequencerCore { let curr_time = chrono::Utc::now().timestamp_millis() as u64; - let num_txs_in_block = valid_transactions.len(); - let hashable_data = HashableBlockData { block_id: new_block_height, transactions: valid_transactions, @@ -184,14 +202,16 @@ impl SequencerCore { timestamp: curr_time, }; - let block = hashable_data.into_block(self.block_store.signing_key()); + let block = hashable_data + .clone() + .into_block(self.block_store.signing_key()); self.block_store.put_block_at_id(block)?; self.chain_height = new_block_height; // TODO: Consider switching to `tracing` crate to have more structured and consistent logs - // e.g. + // // e.g. // // ``` // info!( @@ -202,11 +222,10 @@ impl SequencerCore { // ``` log::info!( "Created block with {} transactions in {} seconds", - num_txs_in_block, + hashable_data.transactions.len(), now.elapsed().as_secs() ); - - Ok(self.chain_height) + Ok(hashable_data) } pub fn state(&self) -> &nssa::V02State { @@ -292,6 +311,7 @@ mod tests { resubscribe_interval: 100, channel_id: [42; 32].into(), }, + bedrock_config: None, } } @@ -640,9 +660,9 @@ mod tests { let tx = common::test_utils::produce_dummy_empty_transaction(); mempool_handle.push(tx).await.unwrap(); - let block_id = sequencer.produce_new_block_with_mempool_transactions(); - assert!(block_id.is_ok()); - assert_eq!(block_id.unwrap(), genesis_height + 1); + let block = sequencer.produce_new_block_with_mempool_transactions(); + assert!(block.is_ok()); + assert_eq!(block.unwrap().block_id, genesis_height + 1); } #[tokio::test] @@ -679,7 +699,8 @@ mod tests { // Create block let current_height = sequencer .produce_new_block_with_mempool_transactions() - .unwrap(); + .unwrap() + .block_id; let block = sequencer .block_store .get_block_at_id(current_height) @@ -718,7 +739,8 @@ mod tests { mempool_handle.push(tx.clone()).await.unwrap(); let current_height = sequencer .produce_new_block_with_mempool_transactions() - .unwrap(); + .unwrap() + .block_id; let block = sequencer .block_store .get_block_at_id(current_height) @@ -729,7 +751,8 @@ mod tests { mempool_handle.push(tx.clone()).await.unwrap(); let current_height = sequencer .produce_new_block_with_mempool_transactions() - .unwrap(); + .unwrap() + .block_id; let block = sequencer .block_store .get_block_at_id(current_height) @@ -766,7 +789,8 @@ mod tests { mempool_handle.push(tx.clone()).await.unwrap(); let current_height = sequencer .produce_new_block_with_mempool_transactions() - .unwrap(); + .unwrap() + .block_id; let block = sequencer .block_store .get_block_at_id(current_height) diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index 51fba4c0..6f89d9e6 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -396,6 +396,7 @@ mod tests { resubscribe_interval: 100, channel_id: [42; 32].into(), }, + bedrock_config: None, } } diff --git a/sequencer_runner/configs/debug/sequencer_config.json b/sequencer_runner/configs/debug/sequencer_config.json index 58348f68..ab65ea70 100644 --- a/sequencer_runner/configs/debug/sequencer_config.json +++ b/sequencer_runner/configs/debug/sequencer_config.json @@ -154,5 +154,9 @@ 37, 37, 37 - ] -} \ No newline at end of file + ], + "bedrock_config": { + "channel_id": [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + "node_url": "http://localhost:45403" + } +} diff --git a/sequencer_runner/src/lib.rs b/sequencer_runner/src/lib.rs index 35a60e4d..72929c4a 100644 --- a/sequencer_runner/src/lib.rs +++ b/sequencer_runner/src/lib.rs @@ -69,7 +69,9 @@ pub async fn startup_sequencer( let id = { let mut state = seq_core_wrapped.lock().await; - state.produce_new_block_with_mempool_transactions()? + state + .produce_new_block_and_post_to_settlement_layer() + .await? }; info!("Block with id {id} created"); diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index 0f88af26..bef25007 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -14,7 +14,7 @@ serde_json.workspace = true env_logger.workspace = true log.workspace = true serde.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["macros"] } clap.workspace = true base64.workspace = true bytemuck.workspace = true diff --git a/wallet/src/cli/config.rs b/wallet/src/cli/config.rs index 15467160..b2d4aa93 100644 --- a/wallet/src/cli/config.rs +++ b/wallet/src/cli/config.rs @@ -10,7 +10,13 @@ use crate::{ #[derive(Subcommand, Debug, Clone)] pub enum ConfigSubcommand { /// Getter of config fields - Get { key: String }, + Get { + /// Print all config fields + #[arg(short, long)] + all: bool, + /// Config field key to get + key: Option, + }, /// Setter of config fields Set { key: String, value: String }, /// Prints description of corresponding field @@ -23,58 +29,66 @@ impl WalletSubcommand for ConfigSubcommand { wallet_core: &mut WalletCore, ) -> Result { match self { - ConfigSubcommand::Get { key } => match key.as_str() { - "all" => { + ConfigSubcommand::Get { all, key } => { + if all { let config_str = serde_json::to_string_pretty(&wallet_core.storage.wallet_config)?; println!("{config_str}"); - } - "override_rust_log" => { - if let Some(value) = &wallet_core.storage.wallet_config.override_rust_log { - println!("{value}"); - } else { - println!("Not set"); + } else if let Some(key) = key { + match key.as_str() { + "override_rust_log" => { + if let Some(value) = + &wallet_core.storage.wallet_config.override_rust_log + { + println!("{value}"); + } else { + println!("Not set"); + } + } + "sequencer_addr" => { + println!("{}", wallet_core.storage.wallet_config.sequencer_addr); + } + "seq_poll_timeout_millis" => { + println!( + "{}", + wallet_core.storage.wallet_config.seq_poll_timeout_millis + ); + } + "seq_tx_poll_max_blocks" => { + println!( + "{}", + wallet_core.storage.wallet_config.seq_tx_poll_max_blocks + ); + } + "seq_poll_max_retries" => { + println!("{}", wallet_core.storage.wallet_config.seq_poll_max_retries); + } + "seq_block_poll_max_amount" => { + println!( + "{}", + wallet_core.storage.wallet_config.seq_block_poll_max_amount + ); + } + "initial_accounts" => { + println!("{:#?}", wallet_core.storage.wallet_config.initial_accounts); + } + "basic_auth" => { + if let Some(basic_auth) = &wallet_core.storage.wallet_config.basic_auth + { + println!("{basic_auth}"); + } else { + println!("Not set"); + } + } + _ => { + println!("Unknown field"); + } } + } else { + println!("Please provide a key or use --all flag"); } - "sequencer_addr" => { - println!("{}", wallet_core.storage.wallet_config.sequencer_addr); - } - "seq_poll_timeout_millis" => { - println!( - "{}", - wallet_core.storage.wallet_config.seq_poll_timeout_millis - ); - } - "seq_tx_poll_max_blocks" => { - println!( - "{}", - wallet_core.storage.wallet_config.seq_tx_poll_max_blocks - ); - } - "seq_poll_max_retries" => { - println!("{}", wallet_core.storage.wallet_config.seq_poll_max_retries); - } - "seq_block_poll_max_amount" => { - println!( - "{}", - wallet_core.storage.wallet_config.seq_block_poll_max_amount - ); - } - "initial_accounts" => { - println!("{:#?}", wallet_core.storage.wallet_config.initial_accounts); - } - "basic_auth" => { - if let Some(basic_auth) = &wallet_core.storage.wallet_config.basic_auth { - println!("{basic_auth}"); - } else { - println!("Not set"); - } - } - _ => { - println!("Unknown field"); - } - }, + } ConfigSubcommand::Set { key, value } => { match key.as_str() { "override_rust_log" => {