mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-04 06:13:10 +00:00
fix: transaction submitting+rpc+main loop
This commit is contained in:
parent
e7323466f3
commit
2ac149d162
148
Cargo.lock
generated
148
Cargo.lock
generated
@ -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",
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>,
|
||||||
|
|||||||
@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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> {
|
||||||
|
|||||||
@ -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 || {
|
||||||
|
|||||||
@ -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))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
}
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
8
sequencer_runner/configs/debug/sequencer_config.json
Normal file
8
sequencer_runner/configs/debug/sequencer_config.json
Normal 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
|
||||||
|
}
|
||||||
14
sequencer_runner/src/config.rs
Normal file
14
sequencer_runner/src/config.rs
Normal 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)?)
|
||||||
|
}
|
||||||
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user