fix: transaction submitting+rpc+main loop

This commit is contained in:
Oleksandr Pravdyvyi 2024-11-28 22:05:14 +02:00
parent e7323466f3
commit 2ac149d162
17 changed files with 493 additions and 23 deletions

148
Cargo.lock generated
View File

@ -569,6 +569,17 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 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]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.4.0" version = "1.4.0"
@ -925,6 +936,45 @@ dependencies = [
"libloading", "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]] [[package]]
name = "consensus" name = "consensus"
version = "0.1.0" version = "0.1.0"
@ -1719,7 +1769,7 @@ dependencies = [
"futures-sink", "futures-sink",
"futures-util", "futures-util",
"http 0.2.12", "http 0.2.12",
"indexmap", "indexmap 2.6.0",
"slab", "slab",
"tokio", "tokio",
"tokio-util", "tokio-util",
@ -1766,6 +1816,15 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 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]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.3.9" version = "0.3.9"
@ -2066,6 +2125,16 @@ dependencies = [
"icu_properties", "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]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.6.0" version = "2.6.0"
@ -2739,6 +2808,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "os_str_bytes"
version = "6.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.3" version = "0.12.3"
@ -2885,7 +2960,7 @@ version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
dependencies = [ dependencies = [
"toml_edit", "toml_edit 0.22.22",
] ]
[[package]] [[package]]
@ -3671,7 +3746,9 @@ version = "0.1.0"
dependencies = [ dependencies = [
"accounts", "accounts",
"anyhow", "anyhow",
"elliptic-curve",
"env_logger", "env_logger",
"k256",
"log", "log",
"mempool", "mempool",
"rand 0.8.5", "rand 0.8.5",
@ -3698,6 +3775,7 @@ dependencies = [
"sequencer_core", "sequencer_core",
"serde", "serde",
"serde_json", "serde_json",
"tokio",
] ]
[[package]] [[package]]
@ -3707,6 +3785,7 @@ dependencies = [
"actix", "actix",
"actix-web", "actix-web",
"anyhow", "anyhow",
"clap",
"consensus", "consensus",
"env_logger", "env_logger",
"log", "log",
@ -3718,6 +3797,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"tokio", "tokio",
"toml",
] ]
[[package]] [[package]]
@ -3752,6 +3832,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_spanned"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "serde_urlencoded" name = "serde_urlencoded"
version = "0.7.1" version = "0.7.1"
@ -3942,6 +4031,12 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "1.0.0" version = "1.0.0"
@ -4031,6 +4126,12 @@ dependencies = [
"risc0-build", "risc0-build",
] ]
[[package]]
name = "textwrap"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.68" version = "1.0.68"
@ -4148,11 +4249,39 @@ dependencies = [
"tokio", "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]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.8" version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 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]] [[package]]
name = "toml_edit" name = "toml_edit"
@ -4160,9 +4289,9 @@ version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [ dependencies = [
"indexmap", "indexmap 2.6.0",
"toml_datetime", "toml_datetime",
"winnow", "winnow 0.6.20",
] ]
[[package]] [[package]]
@ -4718,6 +4847,15 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.6.20" version = "0.6.20"
@ -4873,7 +5011,7 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
"displaydoc", "displaydoc",
"flate2", "flate2",
"indexmap", "indexmap 2.6.0",
"memchr", "memchr",
"thiserror", "thiserror",
"zopfli", "zopfli",

View File

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

View File

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

View File

@ -1,4 +1,4 @@
use std::path::PathBuf; use std::{path::PathBuf, time::Duration};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -6,10 +6,14 @@ use serde::{Deserialize, Serialize};
pub struct SequencerConfig { pub struct SequencerConfig {
///Home dir of sequencer storage ///Home dir of sequencer storage
pub home: PathBuf, pub home: PathBuf,
///Override rust log (env var logging level)
pub override_rust_log: Option<String>,
///Genesis id ///Genesis id
pub genesis_id: u64, pub genesis_id: u64,
///If `True`, then adds random sequence of bytes to genesis block ///If `True`, then adds random sequence of bytes to genesis block
pub is_genesis_random: bool, pub is_genesis_random: bool,
///Maximum number of transactions in block ///Maximum number of transactions in block
pub max_num_tx_in_block: usize, 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 anyhow::Result;
use config::SequencerConfig; use config::SequencerConfig;
use mempool::MemPool; use mempool::MemPool;
use sequecer_store::SequecerChainStore; use sequecer_store::{accounts_store::AccountPublicData, SequecerChainStore};
use storage::block::{Block, HashableBlockData}; 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; use transaction_mempool::TransactionMempool;
pub mod config; pub mod config;
@ -16,6 +25,24 @@ pub struct SequencerCore {
pub chain_height: u64, 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 { impl SequencerCore {
pub fn start_from_config(config: SequencerConfig) -> Self { pub fn start_from_config(config: SequencerConfig) -> Self {
Self { Self {
@ -30,12 +57,125 @@ impl SequencerCore {
} }
} }
///Produces new block from transaction outputs in mempool fn execute_check_transaction_on_state(
pub fn produce_new_block_simple(&mut self) -> Result<()> { &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 let transactions = self
.mempool .mempool
.pop_size(self.sequencer_config.max_num_tx_in_block); .pop_size(self.sequencer_config.max_num_tx_in_block);
for tx in transactions.clone() {
self.execute_check_transaction_on_state(tx)?;
}
let hashable_data = HashableBlockData { let hashable_data = HashableBlockData {
block_id: self.chain_height + 1, block_id: self.chain_height + 1,
transactions: transactions.into_iter().map(|tx_mem| tx_mem.tx).collect(), transactions: transactions.into_iter().map(|tx_mem| tx_mem.tx).collect(),
@ -48,6 +188,6 @@ impl SequencerCore {
self.chain_height += 1; 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 accounts::account_core::{AccountAddress, PublicKey};
use elliptic_curve::group::GroupEncoding;
use std::collections::HashMap;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct AccountPublicData { pub struct AccountPublicData {
@ -9,6 +9,22 @@ pub struct AccountPublicData {
pub address: AccountAddress, 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)] #[derive(Debug, Clone)]
pub struct SequencerAccountsStore { pub struct SequencerAccountsStore {
pub accounts: HashMap<AccountAddress, AccountPublicData>, pub accounts: HashMap<AccountAddress, AccountPublicData>,

View File

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

View File

@ -14,6 +14,7 @@ actix-cors.workspace = true
futures.workspace = true futures.workspace = true
actix-web.workspace = true actix-web.workspace = true
tokio.workspace = true
[dependencies.mempool] [dependencies.mempool]
path = "../mempool" path = "../mempool"

View File

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

View File

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

View File

@ -1,4 +1,5 @@
use actix_web::Error as HttpError; use actix_web::Error as HttpError;
use sequencer_core::sequecer_store::accounts_store::AccountPublicData;
use serde_json::Value; use serde_json::Value;
use rpc_primitives::{ use rpc_primitives::{
@ -9,7 +10,10 @@ use rpc_primitives::{
use crate::{ use crate::{
rpc_error_responce_inverter, rpc_error_responce_inverter,
types::rpc_structs::{HelloRequest, HelloResponse}, types::rpc_structs::{
HelloRequest, HelloResponse, RegisterAccountRequest, RegisterAccountResponse,
SendTxRequest, SendTxResponse,
},
}; };
use super::{respond, types::err_rpc::RpcErr, JsonHandler}; use super::{respond, types::err_rpc::RpcErr, JsonHandler};
@ -43,10 +47,47 @@ impl JsonHandler {
respond(helperstruct) 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)
}
pub async fn process_request_internal(&self, request: Request) -> Result<Value, RpcErr> { pub async fn process_request_internal(&self, request: Request) -> Result<Value, RpcErr> {
match request.method.as_ref() { match request.method.as_ref() {
//Todo : Add handling of more JSON RPC methods
"hello" => self.process_temp_hello(request).await, "hello" => self.process_temp_hello(request).await,
"register_account" => self.process_register_account_request(request).await,
"send_tx" => self.process_send_tx(request).await,
_ => Err(RpcErr(RpcError::method_not_found(request.method))), _ => Err(RpcErr(RpcError::method_not_found(request.method))),
} }
} }

View File

@ -2,15 +2,40 @@ use rpc_primitives::errors::RpcParseError;
use rpc_primitives::parse_request; use rpc_primitives::parse_request;
use rpc_primitives::parser::parse_params; use rpc_primitives::parser::parse_params;
use rpc_primitives::parser::RpcRequest; use rpc_primitives::parser::RpcRequest;
use sequencer_core::transaction_mempool::TransactionMempool;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HelloRequest {} 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,
}
parse_request!(HelloRequest); parse_request!(HelloRequest);
parse_request!(RegisterAccountRequest);
parse_request!(SendTxRequest);
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HelloResponse { pub struct HelloResponse {
pub greeting: String, pub greeting: String,
} }
#[derive(Serialize, Deserialize, Debug)]
pub struct RegisterAccountResponse {
pub status: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SendTxResponse {
pub status: String,
}

View File

@ -13,6 +13,11 @@ actix.workspace = true
actix-web.workspace = true actix-web.workspace = true
tokio.workspace = true tokio.workspace = true
toml.workspace = true
[dependencies.clap]
features = ["derive", "env"]
workspace = true
[dependencies.mempool] [dependencies.mempool]
path = "../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 anyhow::Result;
use clap::Parser;
use log::info; use log::info;
use rpc_primitives::RpcConfig; use rpc_primitives::RpcConfig;
use sequencer_core::SequencerCore;
use sequencer_rpc::new_http_server; 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<()> { 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(); 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"); info!("HTTP server started");
let _http_server_handle = http_server.handle(); let _http_server_handle = http_server.handle();
tokio::spawn(http_server); tokio::spawn(http_server);
info!("Starting main sequencer loop");
#[allow(clippy::empty_loop)] #[allow(clippy::empty_loop)]
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

@ -2,9 +2,25 @@ use serde::{Deserialize, Serialize};
use crate::merkle_tree_public::TreeHashType; 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)] #[derive(Debug, Serialize, Deserialize, Clone)]
///General transaction object ///General transaction object
pub struct Transaction { pub struct Transaction {
pub hash: TreeHashType, 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>,
} }