mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-02 13:23:10 +00:00
Merge pull request #24 from vacp2p/Pravdyvy/sequencer-core
Sequencer core
This commit is contained in:
commit
e7323466f3
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -3669,10 +3669,12 @@ dependencies = [
|
||||
name = "sequencer_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"accounts",
|
||||
"anyhow",
|
||||
"env_logger",
|
||||
"log",
|
||||
"mempool",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"storage",
|
||||
|
||||
@ -15,9 +15,12 @@ use crate::key_management::{
|
||||
AddressKeyHolder,
|
||||
};
|
||||
|
||||
pub type PublicKey = AffinePoint;
|
||||
pub type AccountAddress = TreeHashType;
|
||||
|
||||
pub struct Account {
|
||||
pub key_holder: AddressKeyHolder,
|
||||
pub address: TreeHashType,
|
||||
pub address: AccountAddress,
|
||||
pub balance: u64,
|
||||
pub utxo_tree: UTXOSparseMerkleTree,
|
||||
}
|
||||
|
||||
@ -6,6 +6,8 @@ use k256::AffinePoint;
|
||||
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
|
||||
use storage::merkle_tree_public::TreeHashType;
|
||||
|
||||
use crate::account_core::PublicKey;
|
||||
|
||||
pub mod constants_types;
|
||||
pub mod ephemeral_key_holder;
|
||||
pub mod secret_holders;
|
||||
@ -18,8 +20,8 @@ pub struct AddressKeyHolder {
|
||||
top_secret_key_holder: TopSecretKeyHolder,
|
||||
utxo_secret_key_holder: UTXOSecretKeyHolder,
|
||||
pub address: TreeHashType,
|
||||
pub nullifer_public_key: AffinePoint,
|
||||
pub viewing_public_key: AffinePoint,
|
||||
pub nullifer_public_key: PublicKey,
|
||||
pub viewing_public_key: PublicKey,
|
||||
}
|
||||
|
||||
impl AddressKeyHolder {
|
||||
|
||||
@ -9,9 +9,13 @@ serde_json.workspace = true
|
||||
env_logger.workspace = true
|
||||
log.workspace = true
|
||||
serde.workspace = true
|
||||
rand.workspace = true
|
||||
|
||||
[dependencies.storage]
|
||||
path = "../storage"
|
||||
|
||||
[dependencies.mempool]
|
||||
path = "../mempool"
|
||||
|
||||
[dependencies.accounts]
|
||||
path = "../accounts"
|
||||
|
||||
15
sequencer_core/src/config.rs
Normal file
15
sequencer_core/src/config.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SequencerConfig {
|
||||
///Home dir of sequencer storage
|
||||
pub home: PathBuf,
|
||||
///Genesis id
|
||||
pub genesis_id: u64,
|
||||
///If `True`, then adds random sequence of bytes to genesis block
|
||||
pub is_genesis_random: bool,
|
||||
///Maximum number of transactions in block
|
||||
pub max_num_tx_in_block: usize,
|
||||
}
|
||||
@ -1 +1,53 @@
|
||||
use anyhow::Result;
|
||||
use config::SequencerConfig;
|
||||
use mempool::MemPool;
|
||||
use sequecer_store::SequecerChainStore;
|
||||
use storage::block::{Block, HashableBlockData};
|
||||
use transaction_mempool::TransactionMempool;
|
||||
|
||||
pub mod config;
|
||||
pub mod sequecer_store;
|
||||
pub mod transaction_mempool;
|
||||
|
||||
pub struct SequencerCore {
|
||||
pub store: SequecerChainStore,
|
||||
pub mempool: MemPool<TransactionMempool>,
|
||||
pub sequencer_config: SequencerConfig,
|
||||
pub chain_height: u64,
|
||||
}
|
||||
|
||||
impl SequencerCore {
|
||||
pub fn start_from_config(config: SequencerConfig) -> Self {
|
||||
Self {
|
||||
store: SequecerChainStore::new_with_genesis(
|
||||
&config.home,
|
||||
config.genesis_id,
|
||||
config.is_genesis_random,
|
||||
),
|
||||
mempool: MemPool::<TransactionMempool>::default(),
|
||||
chain_height: config.genesis_id,
|
||||
sequencer_config: config,
|
||||
}
|
||||
}
|
||||
|
||||
///Produces new block from transaction outputs in mempool
|
||||
pub fn produce_new_block_simple(&mut self) -> Result<()> {
|
||||
let transactions = self
|
||||
.mempool
|
||||
.pop_size(self.sequencer_config.max_num_tx_in_block);
|
||||
|
||||
let hashable_data = HashableBlockData {
|
||||
block_id: self.chain_height + 1,
|
||||
transactions: transactions.into_iter().map(|tx_mem| tx_mem.tx).collect(),
|
||||
data: vec![],
|
||||
};
|
||||
|
||||
let block = Block::produce_block_from_hashable_data(hashable_data);
|
||||
|
||||
self.store.block_store.put_block_at_id(block)?;
|
||||
|
||||
self.chain_height += 1;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
38
sequencer_core/src/sequecer_store/accounts_store.rs
Normal file
38
sequencer_core/src/sequecer_store/accounts_store.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use accounts::account_core::{AccountAddress, PublicKey};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AccountPublicData {
|
||||
pub nullifier_public_key: PublicKey,
|
||||
pub viewing_public_key: PublicKey,
|
||||
pub address: AccountAddress,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SequencerAccountsStore {
|
||||
pub accounts: HashMap<AccountAddress, AccountPublicData>,
|
||||
}
|
||||
|
||||
impl SequencerAccountsStore {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
accounts: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_account(&mut self, account_pub_data: AccountPublicData) {
|
||||
self.accounts
|
||||
.insert(account_pub_data.address, account_pub_data);
|
||||
}
|
||||
|
||||
pub fn unregister_account(&mut self, account_addr: AccountAddress) {
|
||||
self.accounts.remove(&account_addr);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SequencerAccountsStore {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
33
sequencer_core/src/sequecer_store/block_store.rs
Normal file
33
sequencer_core/src/sequecer_store/block_store.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use storage::{block::Block, RocksDBIO};
|
||||
|
||||
pub struct SequecerBlockStore {
|
||||
dbio: RocksDBIO,
|
||||
}
|
||||
|
||||
impl SequecerBlockStore {
|
||||
///Starting database at the start of new chain.
|
||||
/// Creates files if necessary.
|
||||
///
|
||||
/// ATTENTION: Will overwrite genesis block.
|
||||
pub fn open_db_with_genesis(location: &Path, genesis_block: Option<Block>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
dbio: RocksDBIO::new(location, genesis_block)?,
|
||||
})
|
||||
}
|
||||
|
||||
///Reopening existing database
|
||||
pub fn open_db_restart(location: &Path) -> Result<Self> {
|
||||
SequecerBlockStore::open_db_with_genesis(location, None)
|
||||
}
|
||||
|
||||
pub fn get_block_at_id(&self, id: u64) -> Result<Block> {
|
||||
Ok(self.dbio.get_block(id)?)
|
||||
}
|
||||
|
||||
pub fn put_block_at_id(&self, block: Block) -> Result<()> {
|
||||
Ok(self.dbio.put_block(block)?)
|
||||
}
|
||||
}
|
||||
60
sequencer_core/src/sequecer_store/mod.rs
Normal file
60
sequencer_core/src/sequecer_store/mod.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use std::path::Path;
|
||||
|
||||
use accounts_store::SequencerAccountsStore;
|
||||
use block_store::SequecerBlockStore;
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
use storage::{
|
||||
block::{Block, HashableBlockData},
|
||||
merkle_tree_public::merkle_tree::{PublicTransactionMerkleTree, UTXOCommitmentsMerkleTree},
|
||||
nullifier_sparse_merkle_tree::NullifierSparseMerkleTree,
|
||||
};
|
||||
|
||||
pub mod accounts_store;
|
||||
pub mod block_store;
|
||||
|
||||
pub struct SequecerChainStore {
|
||||
pub acc_store: SequencerAccountsStore,
|
||||
pub block_store: SequecerBlockStore,
|
||||
pub nullifier_store: NullifierSparseMerkleTree,
|
||||
pub utxo_commitments_store: UTXOCommitmentsMerkleTree,
|
||||
pub pub_tx_store: PublicTransactionMerkleTree,
|
||||
}
|
||||
|
||||
impl SequecerChainStore {
|
||||
pub fn new_with_genesis(home_dir: &Path, genesis_id: u64, is_genesis_random: bool) -> Self {
|
||||
let acc_store = SequencerAccountsStore::default();
|
||||
let nullifier_store = NullifierSparseMerkleTree::default();
|
||||
let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
||||
let pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
|
||||
|
||||
let mut data = [0; 32];
|
||||
|
||||
if is_genesis_random {
|
||||
OsRng.fill_bytes(&mut data);
|
||||
}
|
||||
|
||||
let hashable_data = HashableBlockData {
|
||||
block_id: genesis_id,
|
||||
transactions: vec![],
|
||||
data: data.to_vec(),
|
||||
};
|
||||
|
||||
let genesis_block = Block::produce_block_from_hashable_data(hashable_data);
|
||||
|
||||
//Sequencer should panic if unable to open db,
|
||||
//as fixing this issue may require actions non-native to program scope
|
||||
let block_store = SequecerBlockStore::open_db_with_genesis(
|
||||
&home_dir.join("rocksdb"),
|
||||
Some(genesis_block),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Self {
|
||||
acc_store,
|
||||
block_store,
|
||||
nullifier_store,
|
||||
utxo_commitments_store,
|
||||
pub_tx_store,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
use rs_merkle::Hasher;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::transaction::Transaction;
|
||||
use crate::{merkle_tree_public::hasher::OwnHasher, transaction::Transaction};
|
||||
|
||||
pub type BlockHash = [u8; 32];
|
||||
pub type Data = Vec<u8>;
|
||||
@ -14,3 +15,25 @@ pub struct Block {
|
||||
pub transactions: Vec<Transaction>,
|
||||
pub data: Data,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct HashableBlockData {
|
||||
pub block_id: BlockId,
|
||||
pub transactions: Vec<Transaction>,
|
||||
pub data: Data,
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub fn produce_block_from_hashable_data(hashable_data: HashableBlockData) -> Self {
|
||||
let data = serde_json::to_vec(&hashable_data).unwrap();
|
||||
|
||||
let hash = OwnHasher::hash(&data);
|
||||
|
||||
Self {
|
||||
block_id: hashable_data.block_id,
|
||||
hash,
|
||||
transactions: hashable_data.transactions,
|
||||
data: hashable_data.data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user