Merge pull request #27 from vacp2p/Pravdyvyi/sequencer-transaction-submit-process

First sequencer main version
This commit is contained in:
tyshko-rostyslav 2024-11-30 18:29:42 -05:00 committed by GitHub
commit 5df163de74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 548 additions and 24 deletions

149
Cargo.lock generated
View File

@ -569,6 +569,17 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi 0.1.19",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.4.0"
@ -925,6 +936,45 @@ dependencies = [
"libloading",
]
[[package]]
name = "clap"
version = "3.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
dependencies = [
"atty",
"bitflags 1.3.2",
"clap_derive",
"clap_lex",
"indexmap 1.9.3",
"once_cell",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_derive"
version = "3.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "consensus"
version = "0.1.0"
@ -1719,7 +1769,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http 0.2.12",
"indexmap",
"indexmap 2.6.0",
"slab",
"tokio",
"tokio-util",
@ -1766,6 +1816,15 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.3.9"
@ -2066,6 +2125,16 @@ dependencies = [
"icu_properties",
]
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
]
[[package]]
name = "indexmap"
version = "2.6.0"
@ -2739,6 +2808,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "os_str_bytes"
version = "6.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
[[package]]
name = "parking_lot"
version = "0.12.3"
@ -2885,7 +2960,7 @@ version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
dependencies = [
"toml_edit",
"toml_edit 0.22.22",
]
[[package]]
@ -3671,7 +3746,9 @@ version = "0.1.0"
dependencies = [
"accounts",
"anyhow",
"elliptic-curve",
"env_logger",
"k256",
"log",
"mempool",
"rand 0.8.5",
@ -3698,6 +3775,8 @@ dependencies = [
"sequencer_core",
"serde",
"serde_json",
"storage",
"tokio",
]
[[package]]
@ -3707,6 +3786,7 @@ dependencies = [
"actix",
"actix-web",
"anyhow",
"clap",
"consensus",
"env_logger",
"log",
@ -3718,6 +3798,7 @@ dependencies = [
"serde",
"serde_json",
"tokio",
"toml",
]
[[package]]
@ -3752,6 +3833,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -3942,6 +4032,12 @@ dependencies = [
"thiserror",
]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "subtle"
version = "1.0.0"
@ -4031,6 +4127,12 @@ dependencies = [
"risc0-build",
]
[[package]]
name = "textwrap"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]]
name = "thiserror"
version = "1.0.68"
@ -4148,11 +4250,39 @@ dependencies = [
"tokio",
]
[[package]]
name = "toml"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.19.15",
]
[[package]]
name = "toml_datetime"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap 2.6.0",
"serde",
"serde_spanned",
"toml_datetime",
"winnow 0.5.40",
]
[[package]]
name = "toml_edit"
@ -4160,9 +4290,9 @@ version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
"indexmap",
"indexmap 2.6.0",
"toml_datetime",
"winnow",
"winnow 0.6.20",
]
[[package]]
@ -4718,6 +4848,15 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
dependencies = [
"memchr",
]
[[package]]
name = "winnow"
version = "0.6.20"
@ -4873,7 +5012,7 @@ dependencies = [
"crossbeam-utils",
"displaydoc",
"flate2",
"indexmap",
"indexmap 2.6.0",
"memchr",
"thiserror",
"zopfli",

View File

@ -37,13 +37,12 @@ sha2 = "0.10.8"
monotree = "0.1.5"
hex = "0.4.3"
aes-gcm = "0.10.3"
toml = "0.7.4"
rocksdb = { version = "0.21.0", default-features = false, features = [
"snappy",
] }
#ToDo: Add necessary risc0 submodules for zkvm module
[workspace.dependencies.rand]
features = ["std", "std_rng", "getrandom"]
version = "0.8.5"

View File

@ -10,6 +10,8 @@ env_logger.workspace = true
log.workspace = true
serde.workspace = true
rand.workspace = true
elliptic-curve.workspace = true
k256.workspace = true
[dependencies.storage]
path = "../storage"

View File

@ -1,4 +1,4 @@
use std::path::PathBuf;
use std::{path::PathBuf, time::Duration};
use serde::{Deserialize, Serialize};
@ -6,10 +6,14 @@ use serde::{Deserialize, Serialize};
pub struct SequencerConfig {
///Home dir of sequencer storage
pub home: PathBuf,
///Override rust log (env var logging level)
pub override_rust_log: Option<String>,
///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,
///Interval in which blocks produced
pub block_create_timeout_millis: Duration,
}

View File

@ -1,8 +1,17 @@
use std::fmt::Display;
use anyhow::Result;
use config::SequencerConfig;
use mempool::MemPool;
use sequecer_store::SequecerChainStore;
use storage::block::{Block, HashableBlockData};
use sequecer_store::{accounts_store::AccountPublicData, SequecerChainStore};
use serde::{Deserialize, Serialize};
use storage::{
block::{Block, HashableBlockData},
merkle_tree_public::TreeHashType,
nullifier::UTXONullifier,
transaction::{Transaction, TxKind},
utxo_commitment::UTXOCommitment,
};
use transaction_mempool::TransactionMempool;
pub mod config;
@ -16,6 +25,24 @@ pub struct SequencerCore {
pub chain_height: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TransactionMalformationErrorKind {
PublicTransactionChangedPrivateData { tx: TreeHashType },
PrivateTransactionChangedPublicData { tx: TreeHashType },
TxHashAlreadyPresentInTree { tx: TreeHashType },
NullifierAlreadyPresentInTree { tx: TreeHashType },
UTXOCommitmentAlreadyPresentInTree { tx: TreeHashType },
FailedToInsert { tx: TreeHashType, details: String },
}
impl Display for TransactionMalformationErrorKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:#?}")
}
}
impl std::error::Error for TransactionMalformationErrorKind {}
impl SequencerCore {
pub fn start_from_config(config: SequencerConfig) -> Self {
Self {
@ -30,16 +57,138 @@ impl SequencerCore {
}
}
///Produces new block from transaction outputs in mempool
pub fn produce_new_block_simple(&mut self) -> Result<()> {
fn execute_check_transaction_on_state(
&mut self,
tx: TransactionMempool,
) -> Result<(), TransactionMalformationErrorKind> {
let Transaction {
hash,
tx_kind,
ref execution_input,
ref execution_output,
ref utxo_commitments_created_hashes,
ref nullifier_created_hashes,
..
} = tx.tx;
//Sanity check
match tx_kind {
TxKind::Public => {
if !utxo_commitments_created_hashes.is_empty()
|| !nullifier_created_hashes.is_empty()
{
//Public transactions can not make private operations.
return Err(
TransactionMalformationErrorKind::PublicTransactionChangedPrivateData {
tx: hash,
},
);
}
}
TxKind::Private => {
if !execution_input.is_empty() || !execution_output.is_empty() {
//Not entirely necessary, but useful simplification for a future.
//This way only shielded and deshielded transactions can be used for interaction
//between public and private state.
return Err(
TransactionMalformationErrorKind::PrivateTransactionChangedPublicData {
tx: hash,
},
);
}
}
_ => {}
};
//Tree checks
let tx_tree_check = self.store.pub_tx_store.get_tx(hash).is_some();
let nullifier_tree_check = nullifier_created_hashes
.iter()
.map(|nullifier_hash| {
self.store
.nullifier_store
.search_item_inclusion(*nullifier_hash)
.unwrap_or(false)
})
.any(|check| check);
let utxo_commitments_check = utxo_commitments_created_hashes
.iter()
.map(|utxo_commitment_hash| {
self.store
.utxo_commitments_store
.get_tx(*utxo_commitment_hash)
.is_some()
})
.any(|check| check);
if tx_tree_check {
return Err(TransactionMalformationErrorKind::TxHashAlreadyPresentInTree { tx: hash });
}
if nullifier_tree_check {
return Err(
TransactionMalformationErrorKind::NullifierAlreadyPresentInTree { tx: hash },
);
}
if utxo_commitments_check {
return Err(
TransactionMalformationErrorKind::UTXOCommitmentAlreadyPresentInTree { tx: hash },
);
}
for utxo_comm in utxo_commitments_created_hashes {
self.store
.utxo_commitments_store
.add_tx(UTXOCommitment { hash: *utxo_comm });
}
for nullifier in nullifier_created_hashes {
self.store
.nullifier_store
.insert_item(UTXONullifier {
utxo_hash: *nullifier,
})
.map_err(|err| TransactionMalformationErrorKind::FailedToInsert {
tx: hash,
details: format!("{err:?}"),
})?;
}
self.store.pub_tx_store.add_tx(tx.tx);
Ok(())
}
pub fn register_account(&mut self, acc_data: AccountPublicData) {
self.store
.acc_store
.accounts
.insert(acc_data.address, acc_data);
}
///Produces new block from transactions in mempool
pub fn produce_new_block_with_mempool_transactions(&mut self) -> Result<u64> {
let transactions = self
.mempool
.pop_size(self.sequencer_config.max_num_tx_in_block);
for tx in transactions.clone() {
self.execute_check_transaction_on_state(tx)?;
}
let prev_block_hash = self
.store
.block_store
.get_block_at_id(self.chain_height)?
.prev_block_hash;
let hashable_data = HashableBlockData {
block_id: self.chain_height + 1,
prev_block_id: self.chain_height,
transactions: transactions.into_iter().map(|tx_mem| tx_mem.tx).collect(),
data: vec![],
prev_block_hash,
};
let block = Block::produce_block_from_hashable_data(hashable_data);
@ -48,6 +197,6 @@ impl SequencerCore {
self.chain_height += 1;
Ok(())
Ok(self.chain_height - 1)
}
}

View File

@ -1,6 +1,6 @@
use std::collections::HashMap;
use accounts::account_core::{AccountAddress, PublicKey};
use elliptic_curve::group::GroupEncoding;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct AccountPublicData {
@ -9,6 +9,22 @@ pub struct AccountPublicData {
pub address: AccountAddress,
}
impl AccountPublicData {
pub fn from_raw(
address: AccountAddress,
nullifier_public_key: Vec<u8>,
viewing_public_key: Vec<u8>,
) -> Self {
Self {
nullifier_public_key: PublicKey::from_bytes(nullifier_public_key.as_slice().into())
.unwrap(),
viewing_public_key: PublicKey::from_bytes(viewing_public_key.as_slice().into())
.unwrap(),
address,
}
}
}
#[derive(Debug, Clone)]
pub struct SequencerAccountsStore {
pub accounts: HashMap<AccountAddress, AccountPublicData>,

View File

@ -28,15 +28,19 @@ impl SequecerChainStore {
let pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
let mut data = [0; 32];
let mut prev_block_hash = [0; 32];
if is_genesis_random {
OsRng.fill_bytes(&mut data);
OsRng.fill_bytes(&mut prev_block_hash);
}
let hashable_data = HashableBlockData {
block_id: genesis_id,
prev_block_id: genesis_id.saturating_sub(1),
transactions: vec![],
data: data.to_vec(),
prev_block_hash,
};
let genesis_block = Block::produce_block_from_hashable_data(hashable_data);

View File

@ -2,7 +2,7 @@ use mempool::mempoolitem::MemPoolItem;
use serde::{Deserialize, Serialize};
use storage::{merkle_tree_public::TreeHashType, transaction::Transaction};
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct TransactionMempool {
pub tx: Transaction,
}

View File

@ -14,6 +14,7 @@ actix-cors.workspace = true
futures.workspace = true
actix-web.workspace = true
tokio.workspace = true
[dependencies.mempool]
path = "../mempool"
@ -27,5 +28,8 @@ path = "../networking"
[dependencies.sequencer_core]
path = "../sequencer_core"
[dependencies.storage]
path = "../storage"
[dependencies.rpc_primitives]
path = "../rpc_primitives"

View File

@ -2,20 +2,25 @@ pub mod net_utils;
pub mod process;
pub mod types;
use std::sync::Arc;
use rpc_primitives::{
errors::{RpcError, RpcErrorKind},
RpcPollingConfig,
};
use sequencer_core::SequencerCore;
use serde::Serialize;
use serde_json::Value;
pub use net_utils::*;
use tokio::sync::Mutex;
use self::types::err_rpc::RpcErr;
//ToDo: Add necessary fields
pub struct JsonHandler {
pub polling_config: RpcPollingConfig,
pub sequencer_state: Arc<Mutex<SequencerCore>>,
}
fn respond<T: Serialize>(val: T) -> Result<Value, RpcErr> {

View File

@ -1,4 +1,5 @@
use std::io;
use std::sync::Arc;
use actix_cors::Cors;
use actix_web::{http, middleware, web, App, Error as HttpError, HttpResponse, HttpServer};
@ -8,6 +9,8 @@ use log::info;
use rpc_primitives::message::Message;
use rpc_primitives::RpcConfig;
use sequencer_core::SequencerCore;
use tokio::sync::Mutex;
use super::JsonHandler;
@ -38,7 +41,10 @@ fn get_cors(cors_allowed_origins: &[String]) -> Cors {
}
#[allow(clippy::too_many_arguments)]
pub fn new_http_server(config: RpcConfig) -> io::Result<actix_web::dev::Server> {
pub fn new_http_server(
config: RpcConfig,
seuquencer_core: Arc<Mutex<SequencerCore>>,
) -> io::Result<actix_web::dev::Server> {
let RpcConfig {
addr,
cors_allowed_origins,
@ -46,7 +52,10 @@ pub fn new_http_server(config: RpcConfig) -> io::Result<actix_web::dev::Server>
limits_config,
} = config;
info!(target:"network", "Starting http server at {}", addr);
let handler = web::Data::new(JsonHandler { polling_config });
let handler = web::Data::new(JsonHandler {
polling_config,
sequencer_state: seuquencer_core.clone(),
});
// HTTP server
Ok(HttpServer::new(move || {

View File

@ -1,4 +1,5 @@
use actix_web::Error as HttpError;
use sequencer_core::sequecer_store::accounts_store::AccountPublicData;
use serde_json::Value;
use rpc_primitives::{
@ -9,7 +10,10 @@ use rpc_primitives::{
use crate::{
rpc_error_responce_inverter,
types::rpc_structs::{HelloRequest, HelloResponse},
types::rpc_structs::{
GetBlockDataRequest, GetBlockDataResponse, HelloRequest, HelloResponse,
RegisterAccountRequest, RegisterAccountResponse, SendTxRequest, SendTxResponse,
},
};
use super::{respond, types::err_rpc::RpcErr, JsonHandler};
@ -43,10 +47,65 @@ impl JsonHandler {
respond(helperstruct)
}
async fn process_register_account_request(&self, request: Request) -> Result<Value, RpcErr> {
let acc_req = RegisterAccountRequest::parse(Some(request.params))?;
{
let mut acc_store = self.sequencer_state.lock().await;
acc_store.register_account(AccountPublicData::from_raw(
acc_req.address,
acc_req.nullifier_public_key,
acc_req.viewing_public_key,
));
}
let helperstruct = RegisterAccountResponse {
status: "Success".to_string(),
};
respond(helperstruct)
}
async fn process_send_tx(&self, request: Request) -> Result<Value, RpcErr> {
let send_tx_req = SendTxRequest::parse(Some(request.params))?;
{
let mut state = self.sequencer_state.lock().await;
state.mempool.push_item(send_tx_req.transaction);
}
let helperstruct = SendTxResponse {
status: "Success".to_string(),
};
respond(helperstruct)
}
async fn process_get_block_data(&self, request: Request) -> Result<Value, RpcErr> {
let get_block_req = GetBlockDataRequest::parse(Some(request.params))?;
let block = {
let state = self.sequencer_state.lock().await;
state
.store
.block_store
.get_block_at_id(get_block_req.block_id)?
};
let helperstruct = GetBlockDataResponse { block };
respond(helperstruct)
}
pub async fn process_request_internal(&self, request: Request) -> Result<Value, RpcErr> {
match request.method.as_ref() {
//Todo : Add handling of more JSON RPC methods
"hello" => self.process_temp_hello(request).await,
"register_account" => self.process_register_account_request(request).await,
"send_tx" => self.process_send_tx(request).await,
"get_block" => self.process_get_block_data(request).await,
_ => Err(RpcErr(RpcError::method_not_found(request.method))),
}
}

View File

@ -2,15 +2,52 @@ use rpc_primitives::errors::RpcParseError;
use rpc_primitives::parse_request;
use rpc_primitives::parser::parse_params;
use rpc_primitives::parser::RpcRequest;
use sequencer_core::transaction_mempool::TransactionMempool;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use storage::block::Block;
#[derive(Serialize, Deserialize, Debug)]
pub struct HelloRequest {}
#[derive(Serialize, Deserialize, Debug)]
pub struct RegisterAccountRequest {
pub nullifier_public_key: Vec<u8>,
pub viewing_public_key: Vec<u8>,
pub address: [u8; 32],
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SendTxRequest {
pub transaction: TransactionMempool,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetBlockDataRequest {
pub block_id: u64,
}
parse_request!(HelloRequest);
parse_request!(RegisterAccountRequest);
parse_request!(SendTxRequest);
parse_request!(GetBlockDataRequest);
#[derive(Serialize, Deserialize, Debug)]
pub struct HelloResponse {
pub greeting: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct RegisterAccountResponse {
pub status: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SendTxResponse {
pub status: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetBlockDataResponse {
pub block: Block,
}

View File

@ -13,6 +13,11 @@ actix.workspace = true
actix-web.workspace = true
tokio.workspace = true
toml.workspace = true
[dependencies.clap]
features = ["derive", "env"]
workspace = true
[dependencies.mempool]
path = "../mempool"

View File

@ -0,0 +1,8 @@
{
"home": ".",
"override_rust_log": null,
"genesis_id": 1,
"is_genesis_random": true,
"max_num_tx_in_block": 20,
"block_create_timeout_millis": 10000
}

View File

@ -0,0 +1,14 @@
use std::path::PathBuf;
use anyhow::Result;
use sequencer_core::config::SequencerConfig;
use std::fs::File;
use std::io::BufReader;
pub fn from_file(config_home: PathBuf) -> Result<SequencerConfig> {
let file = File::open(config_home)?;
let reader = BufReader::new(file);
Ok(serde_json::from_reader(reader)?)
}

View File

@ -1,18 +1,65 @@
use std::{path::PathBuf, sync::Arc};
use anyhow::Result;
use clap::Parser;
use log::info;
use rpc_primitives::RpcConfig;
use sequencer_core::SequencerCore;
use sequencer_rpc::new_http_server;
use tokio::sync::Mutex;
pub mod config;
#[derive(Parser, Debug)]
#[clap(version)]
struct Args {
/// Path to configs
home_dir: PathBuf,
}
pub async fn main_runner() -> Result<()> {
let args = Args::parse();
let Args { home_dir } = args;
let app_config = config::from_file(home_dir.join("sequencer_config.json"))?;
let block_timeout = app_config.block_create_timeout_millis;
if let Some(ref rust_log) = app_config.override_rust_log {
info!("RUST_LOG env var set to {rust_log:?}");
std::env::set_var("RUST_LOG", rust_log);
}
env_logger::init();
let http_server = new_http_server(RpcConfig::default())?;
let sequencer_core = SequencerCore::start_from_config(app_config);
info!("Sequncer core set up");
let seq_core_wrapped = Arc::new(Mutex::new(sequencer_core));
let http_server = new_http_server(RpcConfig::default(), seq_core_wrapped.clone())?;
info!("HTTP server started");
let _http_server_handle = http_server.handle();
tokio::spawn(http_server);
info!("Starting main sequencer loop");
#[allow(clippy::empty_loop)]
loop {
//ToDo: Insert activity into main loop
tokio::time::sleep(block_timeout).await;
info!("Collecting transactions from mempool, block creation");
let id = {
let mut state = seq_core_wrapped.lock().await;
state.produce_new_block_with_mempool_transactions()?
};
info!("Block with id {id} created");
info!("Waiting for new transactions");
}
}

View File

@ -7,10 +7,11 @@ pub type BlockHash = [u8; 32];
pub type Data = Vec<u8>;
pub type BlockId = u64;
//ToDo: Add fields to block when model is clear
#[derive(Debug, Serialize, Deserialize)]
pub struct Block {
pub block_id: BlockId,
pub prev_block_id: BlockId,
pub prev_block_hash: BlockHash,
pub hash: BlockHash,
pub transactions: Vec<Transaction>,
pub data: Data,
@ -19,6 +20,8 @@ pub struct Block {
#[derive(Debug, Serialize, Deserialize)]
pub struct HashableBlockData {
pub block_id: BlockId,
pub prev_block_id: BlockId,
pub prev_block_hash: BlockHash,
pub transactions: Vec<Transaction>,
pub data: Data,
}
@ -31,9 +34,11 @@ impl Block {
Self {
block_id: hashable_data.block_id,
prev_block_id: hashable_data.prev_block_id,
hash,
transactions: hashable_data.transactions,
data: hashable_data.data,
prev_block_hash: hashable_data.prev_block_hash,
}
}
}

View File

@ -2,9 +2,27 @@ use serde::{Deserialize, Serialize};
use crate::merkle_tree_public::TreeHashType;
//ToDo: Update Tx model, when it is clear
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
pub enum TxKind {
Public,
Private,
Shielded,
Deshielded,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
///General transaction object
pub struct Transaction {
pub hash: TreeHashType,
pub tx_kind: TxKind,
///Tx input data (public part)
pub execution_input: Vec<u8>,
///Tx output data (public_part)
pub execution_output: Vec<u8>,
///Tx output utxo commitments
pub utxo_commitments_created_hashes: Vec<TreeHashType>,
///Tx output nullifiers
pub nullifier_created_hashes: Vec<TreeHashType>,
///Execution proof (private part)
pub execution_proof_private: String,
}