mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-03-23 18:53:13 +00:00
Merge branch 'main' into Pravdyvy/block-parsing-validation
This commit is contained in:
commit
516feee101
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -99,7 +99,7 @@ jobs:
|
|||||||
run: rustup install
|
run: rustup install
|
||||||
|
|
||||||
- name: Install nextest
|
- name: Install nextest
|
||||||
run: cargo install cargo-nextest
|
run: cargo install --locked cargo-nextest
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
env:
|
env:
|
||||||
|
|||||||
1086
Cargo.lock
generated
1086
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -82,10 +82,9 @@ itertools = "0.14.0"
|
|||||||
url = "2.5.4"
|
url = "2.5.4"
|
||||||
tokio-retry = "0.3.0"
|
tokio-retry = "0.3.0"
|
||||||
|
|
||||||
common-http-client = { git = "https://github.com/logos-blockchain/logos-blockchain.git" }
|
logos-blockchain-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" }
|
logos-blockchain-key-management-system-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git" }
|
||||||
nomos-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git" }
|
logos-blockchain-core = { git = "https://github.com/logos-blockchain/logos-blockchain.git" }
|
||||||
broadcast-service = { git = "https://github.com/logos-blockchain/logos-blockchain.git" }
|
|
||||||
|
|
||||||
rocksdb = { version = "0.24.0", default-features = false, features = [
|
rocksdb = { version = "0.24.0", default-features = false, features = [
|
||||||
"snappy",
|
"snappy",
|
||||||
|
|||||||
@ -6,10 +6,5 @@ edition = "2024"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest.workspace = true
|
reqwest.workspace = true
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
common-http-client.workspace = true
|
logos-blockchain-common-http-client.workspace = true
|
||||||
nomos-core.workspace = true
|
logos-blockchain-core.workspace = true
|
||||||
broadcast-service.workspace = true
|
|
||||||
url.workspace = true
|
|
||||||
futures.workspace = true
|
|
||||||
tokio-retry.workspace = true
|
|
||||||
log.workspace = true
|
|
||||||
|
|||||||
@ -1,28 +1,33 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use broadcast_service::BlockInfo;
|
pub use logos_blockchain_common_http_client::{BasicAuthCredentials, CommonHttpClient, Error};
|
||||||
use common_http_client::CommonHttpClient;
|
use logos_blockchain_core::mantle::SignedMantleTx;
|
||||||
pub use common_http_client::{BasicAuthCredentials, Error};
|
use reqwest::{Client, Url};
|
||||||
use futures::{Stream, TryFutureExt};
|
|
||||||
use log::warn;
|
|
||||||
use nomos_core::{block::Block, header::HeaderId, mantle::SignedMantleTx};
|
|
||||||
use reqwest::Client;
|
|
||||||
use tokio_retry::Retry;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
// Simple wrapper
|
// Simple wrapper
|
||||||
// maybe extend in the future for our purposes
|
// maybe extend in the future for our purposes
|
||||||
pub struct BedrockClient(pub CommonHttpClient);
|
pub struct BedrockClient {
|
||||||
|
http_client: CommonHttpClient,
|
||||||
|
node_url: Url,
|
||||||
|
}
|
||||||
|
|
||||||
impl BedrockClient {
|
impl BedrockClient {
|
||||||
pub fn new(auth: Option<BasicAuthCredentials>) -> Result<Self> {
|
pub fn new(auth: Option<BasicAuthCredentials>, node_url: Url) -> Result<Self> {
|
||||||
let client = Client::builder()
|
let client = Client::builder()
|
||||||
//Add more fiedls if needed
|
//Add more fields if needed
|
||||||
.timeout(std::time::Duration::from_secs(60))
|
.timeout(std::time::Duration::from_secs(60))
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
Ok(BedrockClient(CommonHttpClient::new_with_client(
|
let http_client = CommonHttpClient::new_with_client(client, auth);
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_lib_stream(&self, url: Url) -> Result<impl Stream<Item = BlockInfo>, Error> {
|
pub async fn get_lib_stream(&self, url: Url) -> Result<impl Stream<Item = BlockInfo>, Error> {
|
||||||
|
|||||||
@ -23,7 +23,7 @@ pub type BlockHash = [u8; 32];
|
|||||||
pub type BlockId = u64;
|
pub type BlockId = u64;
|
||||||
pub type TimeStamp = u64;
|
pub type TimeStamp = u64;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
|
||||||
pub struct BlockHeader {
|
pub struct BlockHeader {
|
||||||
pub block_id: BlockId,
|
pub block_id: BlockId,
|
||||||
pub prev_block_hash: BlockHash,
|
pub prev_block_hash: BlockHash,
|
||||||
@ -32,15 +32,23 @@ pub struct BlockHeader {
|
|||||||
pub signature: nssa::Signature,
|
pub signature: nssa::Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
|
||||||
pub struct BlockBody {
|
pub struct BlockBody {
|
||||||
pub transactions: Vec<EncodedTransaction>,
|
pub transactions: Vec<EncodedTransaction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
|
||||||
|
pub enum BedrockStatus {
|
||||||
|
Pending,
|
||||||
|
Safe,
|
||||||
|
Finalized,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, BorshSerialize, BorshDeserialize)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub header: BlockHeader,
|
pub header: BlockHeader,
|
||||||
pub body: BlockBody,
|
pub body: BlockBody,
|
||||||
|
pub bedrock_status: BedrockStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
|
||||||
@ -52,7 +60,7 @@ pub struct HashableBlockData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HashableBlockData {
|
impl HashableBlockData {
|
||||||
pub fn into_block(self, signing_key: &nssa::PrivateKey) -> Block {
|
pub fn into_pending_block(self, signing_key: &nssa::PrivateKey) -> Block {
|
||||||
let data_bytes = borsh::to_vec(&self).unwrap();
|
let data_bytes = borsh::to_vec(&self).unwrap();
|
||||||
let signature = nssa::Signature::new(signing_key, &data_bytes);
|
let signature = nssa::Signature::new(signing_key, &data_bytes);
|
||||||
let hash = OwnHasher::hash(&data_bytes);
|
let hash = OwnHasher::hash(&data_bytes);
|
||||||
@ -67,6 +75,7 @@ impl HashableBlockData {
|
|||||||
body: BlockBody {
|
body: BlockBody {
|
||||||
transactions: self.transactions,
|
transactions: self.transactions,
|
||||||
},
|
},
|
||||||
|
bedrock_status: BedrockStatus::Pending,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ pub fn produce_dummy_block(
|
|||||||
transactions,
|
transactions,
|
||||||
};
|
};
|
||||||
|
|
||||||
block_data.into_block(&sequencer_sign_key_for_testing())
|
block_data.into_pending_block(&sequencer_sign_key_for_testing())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn produce_dummy_empty_transaction() -> EncodedTransaction {
|
pub fn produce_dummy_empty_transaction() -> EncodedTransaction {
|
||||||
|
|||||||
@ -19,8 +19,8 @@ chrono.workspace = true
|
|||||||
log.workspace = true
|
log.workspace = true
|
||||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
||||||
bedrock_client.workspace = true
|
bedrock_client.workspace = true
|
||||||
key-management-system-service.workspace = true
|
logos-blockchain-key-management-system-service.workspace = true
|
||||||
nomos-core.workspace = true
|
logos-blockchain-core.workspace = true
|
||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
reqwest.workspace = true
|
reqwest.workspace = true
|
||||||
borsh.workspace = true
|
borsh.workspace = true
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
use std::{fs, path::Path};
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{Context, Result, anyhow};
|
||||||
use bedrock_client::BedrockClient;
|
use bedrock_client::BedrockClient;
|
||||||
use common::block::HashableBlockData;
|
use common::block::HashableBlockData;
|
||||||
use key_management_system_service::keys::{ED25519_SECRET_KEY_SIZE, Ed25519Key, Ed25519PublicKey};
|
use logos_blockchain_core::mantle::{
|
||||||
use nomos_core::mantle::{
|
|
||||||
MantleTx, Op, OpProof, SignedMantleTx, Transaction, TxHash, ledger,
|
MantleTx, Op, OpProof, SignedMantleTx, Transaction, TxHash, ledger,
|
||||||
ops::channel::{ChannelId, MsgId, inscribe::InscriptionOp},
|
ops::channel::{ChannelId, MsgId, inscribe::InscriptionOp},
|
||||||
};
|
};
|
||||||
use reqwest::Url;
|
use logos_blockchain_key_management_system_service::keys::{
|
||||||
|
ED25519_SECRET_KEY_SIZE, Ed25519Key, Ed25519PublicKey,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::config::BedrockConfig;
|
use crate::config::BedrockConfig;
|
||||||
|
|
||||||
/// A component that posts block data to logos blockchain
|
/// A component that posts block data to logos blockchain
|
||||||
pub struct BlockSettlementClient {
|
pub struct BlockSettlementClient {
|
||||||
bedrock_node_url: Url,
|
|
||||||
bedrock_client: BedrockClient,
|
bedrock_client: BedrockClient,
|
||||||
bedrock_signing_key: Ed25519Key,
|
bedrock_signing_key: Ed25519Key,
|
||||||
bedrock_channel_id: ChannelId,
|
bedrock_channel_id: ChannelId,
|
||||||
@ -22,25 +22,23 @@ pub struct BlockSettlementClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BlockSettlementClient {
|
impl BlockSettlementClient {
|
||||||
pub fn new(home: &Path, config: &BedrockConfig) -> Self {
|
pub fn try_new(home: &Path, config: &BedrockConfig) -> Result<Self> {
|
||||||
let bedrock_signing_key = load_or_create_signing_key(&home.join("bedrock_signing_key"))
|
let bedrock_signing_key = load_or_create_signing_key(&home.join("bedrock_signing_key"))
|
||||||
.expect("Signing key should load or be created successfully");
|
.context("Failed to load or create signing key")?;
|
||||||
let bedrock_node_url =
|
let bedrock_channel_id = ChannelId::from(config.channel_id);
|
||||||
Url::parse(&config.node_url).expect("Bedrock URL should be a valid URL");
|
let bedrock_client = BedrockClient::new(None, config.node_url.clone())
|
||||||
let bedrock_channel_id = config.channel_id;
|
.context("Failed to initialize bedrock client")?;
|
||||||
let bedrock_client =
|
let channel_genesis_msg = MsgId::from([0; 32]);
|
||||||
BedrockClient::new(None).expect("Bedrock client should be able to initialize");
|
Ok(Self {
|
||||||
Self {
|
|
||||||
bedrock_node_url,
|
|
||||||
bedrock_client,
|
bedrock_client,
|
||||||
bedrock_signing_key,
|
bedrock_signing_key,
|
||||||
bedrock_channel_id,
|
bedrock_channel_id,
|
||||||
last_message_id: MsgId::from([0; 32]),
|
last_message_id: channel_genesis_msg,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create and sign a transaction for inscribing data
|
/// Create and sign a transaction for inscribing data
|
||||||
pub fn create_inscribe_tx(&self, data: Vec<u8>) -> SignedMantleTx {
|
pub fn create_inscribe_tx(&self, data: Vec<u8>) -> (SignedMantleTx, MsgId) {
|
||||||
let verifying_key_bytes = self.bedrock_signing_key.public_key().to_bytes();
|
let verifying_key_bytes = self.bedrock_signing_key.public_key().to_bytes();
|
||||||
let verifying_key =
|
let verifying_key =
|
||||||
Ed25519PublicKey::from_bytes(&verifying_key_bytes).expect("valid ed25519 public key");
|
Ed25519PublicKey::from_bytes(&verifying_key_bytes).expect("valid ed25519 public key");
|
||||||
@ -51,12 +49,14 @@ impl BlockSettlementClient {
|
|||||||
parent: self.last_message_id,
|
parent: self.last_message_id,
|
||||||
signer: verifying_key,
|
signer: verifying_key,
|
||||||
};
|
};
|
||||||
|
let inscribe_op_id = inscribe_op.id();
|
||||||
|
|
||||||
let ledger_tx = ledger::Tx::new(vec![], vec![]);
|
let ledger_tx = ledger::Tx::new(vec![], vec![]);
|
||||||
|
|
||||||
let inscribe_tx = MantleTx {
|
let inscribe_tx = MantleTx {
|
||||||
ops: vec![Op::ChannelInscribe(inscribe_op)],
|
ops: vec![Op::ChannelInscribe(inscribe_op)],
|
||||||
ledger_tx,
|
ledger_tx,
|
||||||
|
// Altruistic test config
|
||||||
storage_gas_price: 0,
|
storage_gas_price: 0,
|
||||||
execution_gas_price: 0,
|
execution_gas_price: 0,
|
||||||
};
|
};
|
||||||
@ -67,54 +67,51 @@ impl BlockSettlementClient {
|
|||||||
.sign_payload(tx_hash.as_signing_bytes().as_ref())
|
.sign_payload(tx_hash.as_signing_bytes().as_ref())
|
||||||
.to_bytes();
|
.to_bytes();
|
||||||
let signature =
|
let signature =
|
||||||
key_management_system_service::keys::Ed25519Signature::from_bytes(&signature_bytes);
|
logos_blockchain_key_management_system_service::keys::Ed25519Signature::from_bytes(
|
||||||
|
&signature_bytes,
|
||||||
|
);
|
||||||
|
|
||||||
SignedMantleTx {
|
let signed_mantle_tx = SignedMantleTx {
|
||||||
ops_proofs: vec![OpProof::Ed25519Sig(signature)],
|
ops_proofs: vec![OpProof::Ed25519Sig(signature)],
|
||||||
ledger_tx_proof: empty_ledger_signature(&tx_hash),
|
ledger_tx_proof: empty_ledger_signature(&tx_hash),
|
||||||
mantle_tx: inscribe_tx,
|
mantle_tx: inscribe_tx,
|
||||||
}
|
};
|
||||||
|
(signed_mantle_tx, inscribe_op_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Post a transaction to the node and wait for inclusion
|
/// Post a transaction to the node and wait for inclusion
|
||||||
pub async fn post_and_wait(&mut self, block_data: &HashableBlockData) -> Result<u64> {
|
pub async fn post_and_wait(&mut self, block_data: &HashableBlockData) -> Result<u64> {
|
||||||
let inscription_data = borsh::to_vec(&block_data)?;
|
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
|
// Post the transaction
|
||||||
self.bedrock_client
|
self.bedrock_client.post_transaction(tx).await?;
|
||||||
.0
|
|
||||||
.post_transaction(self.bedrock_node_url.clone(), tx.clone())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if let Some(Op::ChannelInscribe(inscribe)) = tx.mantle_tx.ops.first() {
|
self.last_message_id = new_msg_id;
|
||||||
self.last_message_id = inscribe.id()
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(block_data.block_id)
|
Ok(block_data.block_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load signing key from file or generate a new one if it doesn't exist
|
/// Load signing key from file or generate a new one if it doesn't exist
|
||||||
fn load_or_create_signing_key(path: &Path) -> Result<Ed25519Key, ()> {
|
fn load_or_create_signing_key(path: &Path) -> Result<Ed25519Key> {
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
let key_bytes = fs::read(path).map_err(|_| ())?;
|
let key_bytes = fs::read(path)?;
|
||||||
if key_bytes.len() != ED25519_SECRET_KEY_SIZE {
|
let key_array: [u8; ED25519_SECRET_KEY_SIZE] = key_bytes
|
||||||
// TODO: proper error
|
.try_into()
|
||||||
return Err(());
|
.map_err(|_| anyhow!("Found key with incorrect length"))?;
|
||||||
}
|
|
||||||
let key_array: [u8; ED25519_SECRET_KEY_SIZE] =
|
|
||||||
key_bytes.try_into().expect("length already checked");
|
|
||||||
Ok(Ed25519Key::from_bytes(&key_array))
|
Ok(Ed25519Key::from_bytes(&key_array))
|
||||||
} else {
|
} else {
|
||||||
let mut key_bytes = [0u8; ED25519_SECRET_KEY_SIZE];
|
let mut key_bytes = [0u8; ED25519_SECRET_KEY_SIZE];
|
||||||
rand::RngCore::fill_bytes(&mut rand::thread_rng(), &mut key_bytes);
|
rand::RngCore::fill_bytes(&mut rand::thread_rng(), &mut key_bytes);
|
||||||
fs::write(path, key_bytes).map_err(|_| ())?;
|
fs::write(path, key_bytes)?;
|
||||||
Ok(Ed25519Key::from_bytes(&key_bytes))
|
Ok(Ed25519Key::from_bytes(&key_bytes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn empty_ledger_signature(tx_hash: &TxHash) -> key_management_system_service::keys::ZkSignature {
|
fn empty_ledger_signature(
|
||||||
key_management_system_service::keys::ZkKey::multi_sign(&[], tx_hash.as_ref())
|
tx_hash: &TxHash,
|
||||||
|
) -> logos_blockchain_key_management_system_service::keys::ZkSignature {
|
||||||
|
logos_blockchain_key_management_system_service::keys::ZkKey::multi_sign(&[], tx_hash.as_ref())
|
||||||
.expect("multi-sign with empty key set works")
|
.expect("multi-sign with empty key set works")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,7 +46,7 @@ impl SequencerBlockStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_block_at_id(&self, id: u64) -> Result<Block> {
|
pub fn get_block_at_id(&self, id: u64) -> Result<Block> {
|
||||||
Ok(self.dbio.get_block(id)?.into_block(&self.signing_key))
|
Ok(self.dbio.get_block(id)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put_block_at_id(&mut self, block: Block) -> Result<()> {
|
pub fn put_block_at_id(&mut self, block: Block) -> Result<()> {
|
||||||
@ -113,7 +113,7 @@ mod tests {
|
|||||||
transactions: vec![],
|
transactions: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let genesis_block = genesis_block_hashable_data.into_block(&signing_key);
|
let genesis_block = genesis_block_hashable_data.into_pending_block(&signing_key);
|
||||||
// Start an empty node store
|
// Start an empty node store
|
||||||
let mut node_store =
|
let mut node_store =
|
||||||
SequencerBlockStore::open_db_with_genesis(path, Some(genesis_block), signing_key)
|
SequencerBlockStore::open_db_with_genesis(path, Some(genesis_block), signing_key)
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use nomos_core::mantle::ops::channel::ChannelId;
|
use reqwest::Url;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
@ -57,11 +57,7 @@ pub struct BedrockConfig {
|
|||||||
/// Bedrock channel ID
|
/// Bedrock channel ID
|
||||||
pub channel_id: ChannelId,
|
pub channel_id: ChannelId,
|
||||||
/// Bedrock Url
|
/// Bedrock Url
|
||||||
pub node_url: String,
|
pub node_url: Url,
|
||||||
/// Bedrock user
|
|
||||||
pub user: String,
|
|
||||||
/// Bedrock password(optional)
|
|
||||||
pub password: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SequencerConfig {
|
impl SequencerConfig {
|
||||||
|
|||||||
@ -53,7 +53,7 @@ impl SequencerCore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let signing_key = nssa::PrivateKey::try_new(config.signing_key).unwrap();
|
let signing_key = nssa::PrivateKey::try_new(config.signing_key).unwrap();
|
||||||
let genesis_block = hashable_data.into_block(&signing_key);
|
let genesis_block = hashable_data.into_pending_block(&signing_key);
|
||||||
|
|
||||||
// Sequencer should panic if unable to open db,
|
// Sequencer should panic if unable to open db,
|
||||||
// as fixing this issue may require actions non-native to program scope
|
// as fixing this issue may require actions non-native to program scope
|
||||||
@ -89,10 +89,10 @@ impl SequencerCore {
|
|||||||
state.add_pinata_program(PINATA_BASE58.parse().unwrap());
|
state.add_pinata_program(PINATA_BASE58.parse().unwrap());
|
||||||
|
|
||||||
let (mempool, mempool_handle) = MemPool::new(config.mempool_max_size);
|
let (mempool, mempool_handle) = MemPool::new(config.mempool_max_size);
|
||||||
let block_settlement = config
|
let block_settlement_client = config.bedrock_config.as_ref().map(|bedrock_config| {
|
||||||
.bedrock_config
|
BlockSettlementClient::try_new(&config.home, bedrock_config)
|
||||||
.as_ref()
|
.expect("Block settlement client should be constructible")
|
||||||
.map(|bedrock_config| BlockSettlementClient::new(&config.home, bedrock_config));
|
});
|
||||||
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
state,
|
state,
|
||||||
@ -100,7 +100,7 @@ impl SequencerCore {
|
|||||||
mempool,
|
mempool,
|
||||||
chain_height: config.genesis_id,
|
chain_height: config.genesis_id,
|
||||||
sequencer_config: config,
|
sequencer_config: config,
|
||||||
block_settlement_client: block_settlement,
|
block_settlement_client,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.sync_state_with_stored_blocks();
|
this.sync_state_with_stored_blocks();
|
||||||
@ -196,14 +196,14 @@ impl SequencerCore {
|
|||||||
|
|
||||||
let block = hashable_data
|
let block = hashable_data
|
||||||
.clone()
|
.clone()
|
||||||
.into_block(self.block_store.signing_key());
|
.into_pending_block(self.block_store.signing_key());
|
||||||
|
|
||||||
self.block_store.put_block_at_id(block)?;
|
self.block_store.put_block_at_id(block)?;
|
||||||
|
|
||||||
self.chain_height = new_block_height;
|
self.chain_height = new_block_height;
|
||||||
|
|
||||||
// TODO: Consider switching to `tracing` crate to have more structured and consistent logs
|
// TODO: Consider switching to `tracing` crate to have more structured and consistent logs
|
||||||
// // e.g.
|
// e.g.
|
||||||
//
|
//
|
||||||
// ```
|
// ```
|
||||||
// info!(
|
// info!(
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::{path::Path, sync::Arc};
|
use std::{path::Path, sync::Arc};
|
||||||
|
|
||||||
use common::block::{Block, HashableBlockData};
|
use common::block::Block;
|
||||||
use error::DbError;
|
use error::DbError;
|
||||||
use rocksdb::{
|
use rocksdb::{
|
||||||
BoundColumnFamily, ColumnFamilyDescriptor, DBWithThreadMode, MultiThreaded, Options,
|
BoundColumnFamily, ColumnFamilyDescriptor, DBWithThreadMode, MultiThreaded, Options,
|
||||||
@ -26,6 +26,8 @@ pub const DB_META_FIRST_BLOCK_IN_DB_KEY: &str = "first_block_in_db";
|
|||||||
pub const DB_META_LAST_BLOCK_IN_DB_KEY: &str = "last_block_in_db";
|
pub const DB_META_LAST_BLOCK_IN_DB_KEY: &str = "last_block_in_db";
|
||||||
/// Key base for storing metainformation which describe if first block has been set
|
/// Key base for storing metainformation which describe if first block has been set
|
||||||
pub const DB_META_FIRST_BLOCK_SET_KEY: &str = "first_block_set";
|
pub const DB_META_FIRST_BLOCK_SET_KEY: &str = "first_block_set";
|
||||||
|
/// Key base for storing metainformation about the last finalized block on Bedrock
|
||||||
|
pub const DB_META_LAST_FINALIZED_BLOCK_ID: &str = "last_finalized_block_id";
|
||||||
|
|
||||||
/// Key base for storing snapshot which describe block id
|
/// Key base for storing snapshot which describe block id
|
||||||
pub const DB_SNAPSHOT_BLOCK_ID_KEY: &str = "block_id";
|
pub const DB_SNAPSHOT_BLOCK_ID_KEY: &str = "block_id";
|
||||||
@ -75,6 +77,7 @@ impl RocksDBIO {
|
|||||||
dbio.put_meta_first_block_in_db(block)?;
|
dbio.put_meta_first_block_in_db(block)?;
|
||||||
dbio.put_meta_is_first_block_set()?;
|
dbio.put_meta_is_first_block_set()?;
|
||||||
dbio.put_meta_last_block_in_db(block_id)?;
|
dbio.put_meta_last_block_in_db(block_id)?;
|
||||||
|
dbio.put_meta_last_finalized_block_id(None)?;
|
||||||
|
|
||||||
Ok(dbio)
|
Ok(dbio)
|
||||||
} else {
|
} else {
|
||||||
@ -232,6 +235,28 @@ impl RocksDBIO {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn put_meta_last_finalized_block_id(&self, block_id: Option<u64>) -> DbResult<()> {
|
||||||
|
let cf_meta = self.meta_column();
|
||||||
|
self.db
|
||||||
|
.put_cf(
|
||||||
|
&cf_meta,
|
||||||
|
borsh::to_vec(&DB_META_LAST_FINALIZED_BLOCK_ID).map_err(|err| {
|
||||||
|
DbError::borsh_cast_message(
|
||||||
|
err,
|
||||||
|
Some("Failed to serialize DB_META_LAST_FINALIZED_BLOCK_ID".to_string()),
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
borsh::to_vec(&block_id).map_err(|err| {
|
||||||
|
DbError::borsh_cast_message(
|
||||||
|
err,
|
||||||
|
Some("Failed to serialize last block id".to_string()),
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
)
|
||||||
|
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn put_meta_is_first_block_set(&self) -> DbResult<()> {
|
pub fn put_meta_is_first_block_set(&self) -> DbResult<()> {
|
||||||
let cf_meta = self.meta_column();
|
let cf_meta = self.meta_column();
|
||||||
self.db
|
self.db
|
||||||
@ -269,7 +294,7 @@ impl RocksDBIO {
|
|||||||
Some("Failed to serialize block id".to_string()),
|
Some("Failed to serialize block id".to_string()),
|
||||||
)
|
)
|
||||||
})?,
|
})?,
|
||||||
borsh::to_vec(&HashableBlockData::from(block)).map_err(|err| {
|
borsh::to_vec(&block).map_err(|err| {
|
||||||
DbError::borsh_cast_message(
|
DbError::borsh_cast_message(
|
||||||
err,
|
err,
|
||||||
Some("Failed to serialize block data".to_string()),
|
Some("Failed to serialize block data".to_string()),
|
||||||
@ -280,7 +305,7 @@ impl RocksDBIO {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_block(&self, block_id: u64) -> DbResult<HashableBlockData> {
|
pub fn get_block(&self, block_id: u64) -> DbResult<Block> {
|
||||||
let cf_block = self.block_column();
|
let cf_block = self.block_column();
|
||||||
let res = self
|
let res = self
|
||||||
.db
|
.db
|
||||||
@ -296,14 +321,12 @@ impl RocksDBIO {
|
|||||||
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?;
|
.map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?;
|
||||||
|
|
||||||
if let Some(data) = res {
|
if let Some(data) = res {
|
||||||
Ok(
|
Ok(borsh::from_slice::<Block>(&data).map_err(|serr| {
|
||||||
borsh::from_slice::<HashableBlockData>(&data).map_err(|serr| {
|
DbError::borsh_cast_message(
|
||||||
DbError::borsh_cast_message(
|
serr,
|
||||||
serr,
|
Some("Failed to deserialize block data".to_string()),
|
||||||
Some("Failed to deserialize block data".to_string()),
|
)
|
||||||
)
|
})?)
|
||||||
})?,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
Err(DbError::db_interaction_error(
|
Err(DbError::db_interaction_error(
|
||||||
"Block on this id not found".to_string(),
|
"Block on this id not found".to_string(),
|
||||||
|
|||||||
@ -19,7 +19,7 @@ pub enum ChainSubcommand {
|
|||||||
/// Get transaction at hash from sequencer
|
/// Get transaction at hash from sequencer
|
||||||
Transaction {
|
Transaction {
|
||||||
/// hash - valid 32 byte hex string
|
/// hash - valid 32 byte hex string
|
||||||
#[arg(short, long)]
|
#[arg(short = 't', long)]
|
||||||
hash: String,
|
hash: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user