This commit is contained in:
Sergio Chouhy 2026-01-27 10:09:34 -03:00
parent fe4a89191c
commit d7cac557af
9 changed files with 61 additions and 118 deletions

View File

@ -73,11 +73,6 @@ pub struct GetProofForCommitmentRequest {
#[derive(Serialize, Deserialize, Debug)]
pub struct GetProgramIdsRequest {}
#[derive(Serialize, Deserialize, Debug)]
pub struct DeleteFinalizedBlockRequest {
pub block_id: u64,
}
parse_request!(HelloRequest);
parse_request!(RegisterAccountRequest);
parse_request!(SendTxRequest);
@ -92,7 +87,6 @@ parse_request!(GetAccountsNoncesRequest);
parse_request!(GetProofForCommitmentRequest);
parse_request!(GetAccountRequest);
parse_request!(GetProgramIdsRequest);
parse_request!(DeleteFinalizedBlockRequest);
#[derive(Serialize, Deserialize, Debug)]
pub struct HelloResponse {
@ -222,6 +216,3 @@ pub struct GetInitialTestnetAccountsResponse {
pub account_id: String,
pub balance: u64,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct DeleteFinalizedBlockResponse;

View File

@ -15,13 +15,12 @@ use crate::{
rpc_primitives::{
self,
requests::{
DeleteFinalizedBlockRequest, GetAccountRequest, GetAccountResponse,
GetAccountsNoncesRequest, GetAccountsNoncesResponse, GetBlockRangeDataRequest,
GetBlockRangeDataResponse, GetInitialTestnetAccountsResponse, GetLastBlockRequest,
GetLastBlockResponse, GetProgramIdsRequest, GetProgramIdsResponse,
GetProofForCommitmentRequest, GetProofForCommitmentResponse,
GetTransactionByHashRequest, GetTransactionByHashResponse, SendTxRequest,
SendTxResponse,
GetAccountRequest, GetAccountResponse, GetAccountsNoncesRequest,
GetAccountsNoncesResponse, GetBlockRangeDataRequest, GetBlockRangeDataResponse,
GetInitialTestnetAccountsResponse, GetLastBlockRequest, GetLastBlockResponse,
GetProgramIdsRequest, GetProgramIdsResponse, GetProofForCommitmentRequest,
GetProofForCommitmentResponse, GetTransactionByHashRequest,
GetTransactionByHashResponse, SendTxRequest, SendTxResponse,
},
},
transaction::{EncodedTransaction, NSSATransaction},
@ -348,24 +347,4 @@ impl SequencerClient {
Ok(resp_deser)
}
pub async fn delete_finalized_block(
&self,
block_id: u64,
) -> Result<HashMap<String, ProgramId>, SequencerClientError> {
let acc_req = DeleteFinalizedBlockRequest { block_id };
let req = serde_json::to_value(acc_req).unwrap();
let resp = self
.call_method_with_payload("delete_finalized_block", req)
.await
.unwrap();
let resp_deser = serde_json::from_value::<GetProgramIdsResponse>(resp)
.unwrap()
.program_ids;
Ok(resp_deser)
}
}

View File

@ -5,7 +5,10 @@ use serde::{Deserialize, Serialize};
use crate::{NullifierPublicKey, account::Account};
#[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
#[cfg_attr(any(feature = "host", test), derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord))]
#[cfg_attr(
any(feature = "host", test),
derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)
)]
pub struct Commitment(pub(super) [u8; 32]);
/// A commitment to all zero data.

View File

@ -42,7 +42,10 @@ impl From<&NullifierSecretKey> for NullifierPublicKey {
pub type NullifierSecretKey = [u8; 32];
#[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
#[cfg_attr(any(feature = "host", test), derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash))]
#[cfg_attr(
any(feature = "host", test),
derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)
)]
pub struct Nullifier(pub(super) [u8; 32]);
impl Nullifier {

View File

@ -39,7 +39,6 @@ impl BlockSettlementClient {
self.last_message_id = msg_id;
}
pub fn last_message_id(&self) -> MsgId {
self.last_message_id
}

View File

@ -1,15 +1,11 @@
use std::{collections::HashMap, path::Path};
use anyhow::Result;
use common::{
HashType,
block::{Block, BlockHash},
transaction::EncodedTransaction,
};
use common::{HashType, block::Block, transaction::EncodedTransaction};
use nssa::V02State;
use storage::RocksDBIO;
pub struct SequencerBlockStore {
pub struct SequencerStore {
dbio: RocksDBIO,
// TODO: Consider adding the hashmap to the database for faster recovery.
tx_hash_to_block_map: HashMap<HashType, u64>,
@ -17,7 +13,7 @@ pub struct SequencerBlockStore {
signing_key: nssa::PrivateKey,
}
impl SequencerBlockStore {
impl SequencerStore {
/// Starting database at the start of new chain.
/// Creates files if necessary.
///
@ -47,7 +43,7 @@ impl SequencerBlockStore {
/// Reopening existing database
pub fn open_db_restart(location: &Path, signing_key: nssa::PrivateKey) -> Result<Self> {
SequencerBlockStore::open_db_with_genesis(location, None, signing_key)
SequencerStore::open_db_with_genesis(location, None, signing_key)
}
pub fn get_block_at_id(&self, id: u64) -> Result<Block> {
@ -88,8 +84,11 @@ impl SequencerBlockStore {
self.dbio.get_all_blocks().map(|res| Ok(res?))
}
pub(crate) fn update(&self, block: Block, state: &V02State) -> Result<()> {
Ok(self.dbio.atomic_update(block, state)?)
pub(crate) fn update(&mut self, block: Block, state: &V02State) -> Result<()> {
let new_transactions_map = block_to_transactions_map(&block);
self.dbio.atomic_update(block, state)?;
self.tx_hash_to_block_map.extend(new_transactions_map);
Ok(())
}
}
@ -128,8 +127,7 @@ mod tests {
genesis_block_hashable_data.into_pending_block(&signing_key, MsgId::from([0; 32]));
// Start an empty node store
let mut node_store =
SequencerBlockStore::open_db_with_genesis(path, Some(genesis_block), signing_key)
.unwrap();
SequencerStore::open_db_with_genesis(path, Some(genesis_block), signing_key).unwrap();
let tx = common::test_utils::produce_dummy_empty_transaction();
let block = common::test_utils::produce_dummy_block(1, None, vec![tx.clone()]);

View File

@ -14,7 +14,7 @@ use logos_blockchain_core::mantle::ops::channel::MsgId;
use mempool::{MemPool, MemPoolHandle};
use serde::{Deserialize, Serialize};
use crate::{block_settlement_client::BlockSettlementClient, block_store::SequencerBlockStore};
use crate::{block_settlement_client::BlockSettlementClient, block_store::SequencerStore};
mod block_settlement_client;
pub mod block_store;
@ -22,7 +22,7 @@ pub mod config;
pub struct SequencerCore {
state: nssa::V02State,
block_store: SequencerBlockStore,
store: SequencerStore,
mempool: MemPool<EncodedTransaction>,
sequencer_config: SequencerConfig,
chain_height: u64,
@ -59,7 +59,7 @@ impl SequencerCore {
// Sequencer should panic if unable to open db,
// as fixing this issue may require actions non-native to program scope
let block_store = SequencerBlockStore::open_db_with_genesis(
let block_store = SequencerStore::open_db_with_genesis(
&config.home.join("rocksdb"),
Some(genesis_block),
signing_key,
@ -98,7 +98,7 @@ impl SequencerCore {
let mut this = Self {
state,
block_store,
store: block_store,
mempool,
chain_height: config.genesis_id,
sequencer_config: config,
@ -115,14 +115,14 @@ impl SequencerCore {
/// accordingly.
fn sync_state_with_stored_blocks(&mut self) {
let mut next_block_id = self.sequencer_config.genesis_id + 1;
while let Ok(block) = self.block_store.get_block_at_id(next_block_id) {
while let Ok(block) = self.store.get_block_at_id(next_block_id) {
for encoded_transaction in block.body.transactions {
let transaction = NSSATransaction::try_from(&encoded_transaction).unwrap();
// Process transaction and update state
self.execute_check_transaction_on_state(transaction)
.unwrap();
// Update the tx hash to block id map.
self.block_store.insert(&encoded_transaction, next_block_id);
self.store.insert(&encoded_transaction, next_block_id);
}
self.chain_height = next_block_id;
next_block_id += 1;
@ -150,12 +150,11 @@ impl SequencerCore {
pub async fn produce_new_block_and_post_to_settlement_layer(&mut self) -> Result<u64> {
let block_data = self.produce_new_block_with_mempool_transactions()?;
if let Some(block_settlement) = self.block_settlement_client.as_mut() {
let last_message_id = block_settlement.last_message_id();
let block =
block_data.into_pending_block(self.block_store.signing_key(), last_message_id);
let msg_id = block_settlement.submit_block_to_bedrock(&block).await?;
block_settlement.set_last_message_id(msg_id);
if let Some(client) = self.block_settlement_client.as_mut() {
let last_message_id = client.last_message_id();
let block = block_data.into_pending_block(self.store.signing_key(), last_message_id);
let msg_id = client.submit_block_to_bedrock(&block).await?;
client.set_last_message_id(msg_id);
log::info!("Posted block data to Bedrock");
}
@ -185,11 +184,7 @@ impl SequencerCore {
}
}
let prev_block_hash = self
.block_store
.get_block_at_id(self.chain_height)?
.header
.hash;
let prev_block_hash = self.store.get_block_at_id(self.chain_height)?.header.hash;
let curr_time = chrono::Utc::now().timestamp_millis() as u64;
@ -208,9 +203,9 @@ impl SequencerCore {
let block = hashable_data
.clone()
.into_pending_block(self.block_store.signing_key(), bedrock_parent_id);
.into_pending_block(self.store.signing_key(), bedrock_parent_id);
self.block_store.update(block, &self.state)?;
self.store.update(block, &self.state)?;
self.chain_height = new_block_height;
@ -236,8 +231,8 @@ impl SequencerCore {
&self.state
}
pub fn block_store(&self) -> &SequencerBlockStore {
&self.block_store
pub fn block_store(&self) -> &SequencerStore {
&self.store
}
pub fn chain_height(&self) -> u64 {
@ -248,17 +243,19 @@ impl SequencerCore {
&self.sequencer_config
}
pub fn delete_finalized_block_from_db(&mut self, block_id: u64) -> Result<()> {
self.block_store.delete_block_at_id(block_id)
pub fn delete_finalized_blocks_from_db(&mut self, block_ids: &[u64]) -> Result<()> {
block_ids
.iter()
.try_for_each(|&id| self.store.delete_block_at_id(id))
}
pub async fn resubmit_pending_blocks(&self) -> Result<()> {
for res in self.block_store.get_pending_blocks() {
for res in self.store.get_pending_blocks() {
let block = res?;
match block.bedrock_status {
BedrockStatus::Pending => {
if let Some(block_settlement) = self.block_settlement_client.as_ref() {
block_settlement.submit_block_to_bedrock(&block).await?;
if let Some(client) = self.block_settlement_client.as_ref() {
client.submit_block_to_bedrock(&block).await?;
log::info!("Posted block data to Bedrock");
}
}
@ -712,10 +709,7 @@ mod tests {
.produce_new_block_with_mempool_transactions()
.unwrap()
.block_id;
let block = sequencer
.block_store
.get_block_at_id(current_height)
.unwrap();
let block = sequencer.store.get_block_at_id(current_height).unwrap();
// Only one should be included in the block
assert_eq!(block.body.transactions, vec![tx.clone()]);
@ -752,10 +746,7 @@ mod tests {
.produce_new_block_with_mempool_transactions()
.unwrap()
.block_id;
let block = sequencer
.block_store
.get_block_at_id(current_height)
.unwrap();
let block = sequencer.store.get_block_at_id(current_height).unwrap();
assert_eq!(block.body.transactions, vec![tx.clone()]);
// Add same transaction should fail
@ -764,10 +755,7 @@ mod tests {
.produce_new_block_with_mempool_transactions()
.unwrap()
.block_id;
let block = sequencer
.block_store
.get_block_at_id(current_height)
.unwrap();
let block = sequencer.store.get_block_at_id(current_height).unwrap();
assert!(block.body.transactions.is_empty());
}
@ -800,10 +788,7 @@ mod tests {
.produce_new_block_with_mempool_transactions()
.unwrap()
.block_id;
let block = sequencer
.block_store
.get_block_at_id(current_height)
.unwrap();
let block = sequencer.store.get_block_at_id(current_height).unwrap();
assert_eq!(block.body.transactions, vec![tx.clone()]);
}

View File

@ -11,15 +11,15 @@ use common::{
message::{Message, Request},
parser::RpcRequest,
requests::{
DeleteFinalizedBlockRequest, DeleteFinalizedBlockResponse, GetAccountBalanceRequest,
GetAccountBalanceResponse, GetAccountRequest, GetAccountResponse,
GetAccountsNoncesRequest, GetAccountsNoncesResponse, GetBlockDataRequest,
GetBlockDataResponse, GetBlockRangeDataRequest, GetBlockRangeDataResponse,
GetGenesisIdRequest, GetGenesisIdResponse, GetInitialTestnetAccountsRequest,
GetLastBlockRequest, GetLastBlockResponse, GetProgramIdsRequest, GetProgramIdsResponse,
GetProofForCommitmentRequest, GetProofForCommitmentResponse,
GetTransactionByHashRequest, GetTransactionByHashResponse, HelloRequest, HelloResponse,
SendTxRequest, SendTxResponse,
GetAccountBalanceRequest, GetAccountBalanceResponse, GetAccountRequest,
GetAccountResponse, GetAccountsNoncesRequest, GetAccountsNoncesResponse,
GetBlockDataRequest, GetBlockDataResponse, GetBlockRangeDataRequest,
GetBlockRangeDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
GetInitialTestnetAccountsRequest, GetLastBlockRequest, GetLastBlockResponse,
GetProgramIdsRequest, GetProgramIdsResponse, GetProofForCommitmentRequest,
GetProofForCommitmentResponse, GetTransactionByHashRequest,
GetTransactionByHashResponse, HelloRequest, HelloResponse, SendTxRequest,
SendTxResponse,
},
},
transaction::{EncodedTransaction, NSSATransaction},
@ -44,7 +44,6 @@ pub const GET_ACCOUNTS_NONCES: &str = "get_accounts_nonces";
pub const GET_ACCOUNT: &str = "get_account";
pub const GET_PROOF_FOR_COMMITMENT: &str = "get_proof_for_commitment";
pub const GET_PROGRAM_IDS: &str = "get_program_ids";
pub const DELETE_FINALIZED_BLOCK: &str = "delete_finalized_block";
pub const HELLO_FROM_SEQUENCER: &str = "HELLO_FROM_SEQUENCER";
@ -315,19 +314,6 @@ impl JsonHandler {
respond(response)
}
async fn delete_finalized_block(&self, request: Request) -> Result<Value, RpcErr> {
let delete_finalized_block_req = DeleteFinalizedBlockRequest::parse(Some(request.params))?;
let block_id = delete_finalized_block_req.block_id;
self.sequencer_state
.lock()
.await
.delete_finalized_block_from_db(block_id)?;
let response = DeleteFinalizedBlockResponse;
respond(response)
}
pub async fn process_request_internal(&self, request: Request) -> Result<Value, RpcErr> {
match request.method.as_ref() {
HELLO => self.process_temp_hello(request).await,
@ -343,7 +329,6 @@ impl JsonHandler {
GET_TRANSACTION_BY_HASH => self.process_get_transaction_by_hash(request).await,
GET_PROOF_FOR_COMMITMENT => self.process_get_proof_by_commitment(request).await,
GET_PROGRAM_IDS => self.process_get_program_ids(request).await,
DELETE_FINALIZED_BLOCK => self.delete_finalized_block(request).await,
_ => Err(RpcErr(RpcError::method_not_found(request.method))),
}
}

View File

@ -238,7 +238,7 @@ impl RocksDBIO {
rerr,
Some("Failed to write first block in db".to_string()),
)
});
})?;
Ok(())
}