Merge pull request #35 from vacp2p/Pravdyvy/debug-udpates

Debug updates
This commit is contained in:
tyshko-rostyslav 2024-12-30 11:05:28 -05:00 committed by GitHub
commit c712bb146a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 442 additions and 103 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ deps/
data/
.idea/
.vscode/
rocksdb

4
Cargo.lock generated
View File

@ -2729,6 +2729,7 @@ dependencies = [
"actix",
"actix-web",
"anyhow",
"clap",
"consensus",
"env_logger",
"log",
@ -4083,6 +4084,7 @@ dependencies = [
"consensus",
"env_logger",
"futures",
"hex",
"log",
"mempool",
"networking",
@ -4347,6 +4349,7 @@ dependencies = [
"anyhow",
"elliptic-curve",
"env_logger",
"hex",
"log",
"lru",
"monotree",
@ -4815,6 +4818,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"env_logger",
"hex",
"log",
"monotree",
"serde",

View File

@ -2,6 +2,7 @@ use std::collections::HashMap;
use anyhow::Result;
use k256::AffinePoint;
use log::info;
use serde::Serialize;
use storage::{merkle_tree_public::TreeHashType, nullifier::UTXONullifier};
use utxo::{
@ -70,7 +71,7 @@ impl Account {
ephemeral_public_key_sender: AffinePoint,
ciphertext: CipherText,
nonce: Nonce,
) -> Vec<u8> {
) -> Result<Vec<u8>, aes_gcm::Error> {
self.key_holder
.decrypt_data(ephemeral_public_key_sender, ciphertext, nonce)
}
@ -115,6 +116,12 @@ impl Account {
Ok(())
}
pub fn log(&self) {
self.key_holder.log();
info!("Account address is {:?}", hex::encode(self.address));
info!("Account balance is {:?}", self.balance);
}
}
impl Default for Account {

View File

@ -40,8 +40,9 @@ impl EphemeralKeyHolder {
data: &[u8],
) -> (CipherText, Nonce) {
let key_point = self.calculate_shared_secret_sender(viewing_public_key_receiver);
let key_raw = key_point.to_bytes();
let key_raw_adjust: [u8; 32] = key_raw.as_slice().try_into().unwrap();
let binding = key_point.to_bytes();
let key_raw = &binding.as_slice()[..32];
let key_raw_adjust: [u8; 32] = key_raw.try_into().unwrap();
let key: Key<Aes256Gcm> = key_raw_adjust.into();

View File

@ -3,6 +3,7 @@ use constants_types::{CipherText, Nonce};
use elliptic_curve::group::GroupEncoding;
use ephemeral_key_holder::EphemeralKeyHolder;
use k256::AffinePoint;
use log::info;
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
use storage::merkle_tree_public::TreeHashType;
@ -62,7 +63,7 @@ impl AddressKeyHolder {
ephemeral_public_key_sender: AffinePoint,
ciphertext: CipherText,
nonce: Nonce,
) -> Vec<u8> {
) -> Result<Vec<u8>, aes_gcm::Error> {
let key_point = self.calculate_shared_secret_receiver(ephemeral_public_key_sender);
let binding = key_point.to_bytes();
let key_raw = &binding.as_slice()[..32];
@ -72,7 +73,27 @@ impl AddressKeyHolder {
let cipher = Aes256Gcm::new(&key);
cipher.decrypt(&nonce, ciphertext.as_slice()).unwrap()
cipher.decrypt(&nonce, ciphertext.as_slice())
}
pub fn log(&self) {
info!(
"AddressKeyHolder top_secret_key_holder is {:?}",
self.top_secret_key_holder
);
info!(
"AddressKeyHolder utxo_secret_key_holder is {:?}",
self.utxo_secret_key_holder
);
info!("AddressKeyHolder address is {:?}", self.address);
info!(
"AddressKeyHolder nullifer_public_key is {:?}",
self.nullifer_public_key
);
info!(
"AddressKeyHolder viewing_public_key is {:?}",
self.viewing_public_key
);
}
}
@ -149,11 +170,13 @@ mod tests {
.expect("encryption failure");
// Attempt decryption
let decrypted_data: Vec<u8> = address_key_holder.decrypt_data(
ephemeral_public_key_sender,
CipherText::from(ciphertext),
nonce.clone(),
);
let decrypted_data: Vec<u8> = address_key_holder
.decrypt_data(
ephemeral_public_key_sender,
CipherText::from(ciphertext),
nonce.clone(),
)
.unwrap();
// Verify decryption is successful and matches original plaintext
assert_eq!(decrypted_data, plaintext);
@ -216,11 +239,13 @@ mod tests {
// Attempt decryption with an incorrect nonce
let incorrect_nonce = Nonce::from_slice(b"wrong nonce");
let decrypted_data = address_key_holder.decrypt_data(
ephemeral_public_key_sender,
CipherText::from(ciphertext.clone()),
incorrect_nonce.clone(),
);
let decrypted_data = address_key_holder
.decrypt_data(
ephemeral_public_key_sender,
CipherText::from(ciphertext.clone()),
incorrect_nonce.clone(),
)
.unwrap();
// The decryption should fail or produce incorrect output due to nonce mismatch
assert_ne!(decrypted_data, plaintext);
@ -257,11 +282,13 @@ mod tests {
corrupted_ciphertext[0] ^= 1; // Flip a bit in the ciphertext
// Attempt decryption
let result = address_key_holder.decrypt_data(
ephemeral_public_key_sender,
CipherText::from(corrupted_ciphertext),
nonce.clone(),
);
let result = address_key_holder
.decrypt_data(
ephemeral_public_key_sender,
CipherText::from(corrupted_ciphertext),
nonce.clone(),
)
.unwrap();
// The decryption should fail or produce incorrect output due to tampered ciphertext
assert_ne!(result, plaintext);
@ -293,11 +320,13 @@ mod tests {
.expect("encryption failure");
// Decrypt the data using the `AddressKeyHolder` instance
let decrypted_data = address_key_holder.decrypt_data(
ephemeral_public_key_sender,
CipherText::from(ciphertext),
nonce.clone(),
);
let decrypted_data = address_key_holder
.decrypt_data(
ephemeral_public_key_sender,
CipherText::from(ciphertext),
nonce.clone(),
)
.unwrap();
// Verify the decrypted data matches the original plaintext
assert_eq!(decrypted_data, plaintext);

View File

@ -12,4 +12,6 @@ pub struct NodeConfig {
pub sequencer_addr: String,
///Sequencer polling duration for new blocks in seconds
pub seq_poll_timeout_secs: u64,
///Port to listen
pub port: u16,
}

View File

@ -72,6 +72,8 @@ impl NodeCore {
let client = Arc::new(SequencerClient::new(config.clone())?);
let genesis_id = client.get_genesis_id().await?;
info!("Gesesis id is {genesis_id:?}");
let genesis_block = client.get_block(genesis_id.genesis_id).await?.block;
let mut storage = NodeChainStore::new_with_genesis(&config.home, genesis_block);
@ -84,6 +86,7 @@ impl NodeCore {
if let Ok(block) = client.get_block(next_block).await {
storage.dissect_insert_block(block.block)?;
info!("Preprocessed block with id {next_block:?}");
} else {
break;
}
@ -106,7 +109,15 @@ impl NodeCore {
{
let mut storage_guard = wrapped_storage_thread.write().await;
storage_guard.dissect_insert_block(block.block)?;
let block_insertion_result =
storage_guard.dissect_insert_block(block.block);
if block_insertion_result.is_err() {
info!("Block insertion failed due to {block_insertion_result:?}");
block_insertion_result?;
}
info!("Processed block with id {next_block:?}");
}
wrapped_chain_height_thread.store(next_block, Ordering::Relaxed);
@ -130,6 +141,7 @@ impl NodeCore {
pub async fn create_new_account(&mut self) -> AccountAddress {
let account = Account::new();
account.log();
let addr = account.address;
@ -153,6 +165,7 @@ impl NodeCore {
let acc_map_read_guard = self.storage.read().await;
let accout = acc_map_read_guard.acc_map.get(&acc).unwrap();
accout.log();
let ephm_key_holder = &accout.produce_ephemeral_key_holder();
@ -207,17 +220,13 @@ impl NodeCore {
pub async fn transfer_utxo_private(
&self,
utxo: UTXO,
commitment_in: [u8; 32],
receivers: Vec<(u128, AccountAddress)>,
) -> (Transaction, Vec<(AccountAddress, [u8; 32])>) {
let acc_map_read_guard = self.storage.read().await;
let accout = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap();
let commitment_in = {
let guard = self.storage.write().await;
guard.utxo_commitments_store.get_tx(utxo.hash).unwrap().hash
};
accout.log();
let nullifier = generate_nullifiers(
&utxo,
@ -290,6 +299,7 @@ impl NodeCore {
let acc_map_read_guard = self.storage.read().await;
let accout = acc_map_read_guard.acc_map.get(&acc).unwrap();
accout.log();
let commitment_secrets = CommitmentSecrets {
value: balance,
@ -352,7 +362,7 @@ impl NodeCore {
(
TransactionPayload {
tx_kind: TxKind::Private,
tx_kind: TxKind::Shielded,
execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx(
SendMoneyShieldedTx {
acc_sender: acc,
@ -379,17 +389,19 @@ impl NodeCore {
pub async fn transfer_utxo_deshielded(
&self,
utxo: UTXO,
comm_gen_hash: [u8; 32],
receivers: Vec<(u128, AccountAddress)>,
) -> Transaction {
let acc_map_read_guard = self.storage.read().await;
let commitment_in = acc_map_read_guard
.utxo_commitments_store
.get_tx(comm_gen_hash)
.unwrap()
.hash;
let accout = acc_map_read_guard.acc_map.get(&utxo.owner).unwrap();
let commitment_in = {
let guard = self.storage.write().await;
guard.utxo_commitments_store.get_tx(utxo.hash).unwrap().hash
};
accout.log();
let nullifier = generate_nullifiers(
&utxo,
@ -404,14 +416,14 @@ impl NodeCore {
let (resulting_balances, receipt) = prove_send_utxo_deshielded(utxo, receivers);
TransactionPayload {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx(
tx_kind: TxKind::Deshielded,
execution_input: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx(
SendMoneyDeshieldedTx {
receiver_data: resulting_balances,
},
))
.unwrap(),
execution_output: vec![],
utxo_commitments_spent_hashes: vec![commitment_in],
utxo_commitments_created_hashes: vec![],
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
@ -426,15 +438,22 @@ impl NodeCore {
&self,
acc: AccountAddress,
amount: u128,
) -> Result<(SendTxResponse, [u8; 32])> {
) -> Result<(SendTxResponse, [u8; 32], [u8; 32])> {
let point_before_prove = std::time::Instant::now();
let (tx, utxo_hash) = self.mint_utxo_private(acc, amount).await;
tx.log();
let point_after_prove = std::time::Instant::now();
let commitment_generated_hash = tx.utxo_commitments_created_hashes[0];
let timedelta = (point_after_prove - point_before_prove).as_millis();
info!("Mint utxo proof spent {timedelta:?} milliseconds");
Ok((self.sequencer_client.send_tx(tx).await?, utxo_hash))
Ok((
self.sequencer_client.send_tx(tx).await?,
utxo_hash,
commitment_generated_hash,
))
}
pub async fn send_public_deposit(
@ -451,10 +470,12 @@ impl NodeCore {
pub async fn send_private_send_tx(
&self,
utxo: UTXO,
comm_hash: [u8; 32],
receivers: Vec<(u128, AccountAddress)>,
) -> Result<(SendTxResponse, Vec<([u8; 32], [u8; 32])>)> {
let point_before_prove = std::time::Instant::now();
let (tx, utxo_hashes) = self.transfer_utxo_private(utxo, receivers).await;
let (tx, utxo_hashes) = self.transfer_utxo_private(utxo, comm_hash, receivers).await;
tx.log();
let point_after_prove = std::time::Instant::now();
let timedelta = (point_after_prove - point_before_prove).as_millis();
@ -471,6 +492,7 @@ impl NodeCore {
) -> Result<(SendTxResponse, Vec<([u8; 32], [u8; 32])>)> {
let point_before_prove = std::time::Instant::now();
let (tx, utxo_hashes) = self.transfer_balance_shielded(acc, amount, receivers).await;
tx.log();
let point_after_prove = std::time::Instant::now();
let timedelta = (point_after_prove - point_before_prove).as_millis();
@ -482,10 +504,14 @@ impl NodeCore {
pub async fn send_deshielded_send_tx(
&self,
utxo: UTXO,
comm_gen_hash: [u8; 32],
receivers: Vec<(u128, AccountAddress)>,
) -> Result<SendTxResponse> {
let point_before_prove = std::time::Instant::now();
let tx = self.transfer_utxo_deshielded(utxo, receivers).await;
let tx = self
.transfer_utxo_deshielded(utxo, comm_gen_hash, receivers)
.await;
tx.log();
let point_after_prove = std::time::Instant::now();
let timedelta = (point_after_prove - point_before_prove).as_millis();
@ -497,8 +523,10 @@ impl NodeCore {
///Mint utxo, make it public
pub async fn subscenario_1(&mut self) {
let acc_addr = self.create_new_account().await;
info!("Account created {acc_addr:?}");
let (resp, new_utxo_hash) = self.send_private_mint_tx(acc_addr, 100).await.unwrap();
let (resp, new_utxo_hash, comm_gen_hash) =
self.send_private_mint_tx(acc_addr, 100).await.unwrap();
info!("Response for mint private is {resp:?}");
info!("Awaiting new blocks");
@ -508,6 +536,7 @@ impl NodeCore {
let mut write_guard = self.storage.write().await;
let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap();
acc.log();
acc.utxo_tree
.get_item(new_utxo_hash)
@ -516,10 +545,10 @@ impl NodeCore {
.clone()
};
let acc_map_read_guard = self.storage.read().await;
let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
new_utxo.log();
let resp = self
.send_deshielded_send_tx(new_utxo, vec![(100, acc_addr)])
.send_deshielded_send_tx(new_utxo, comm_gen_hash, vec![(100, acc_addr)])
.await
.unwrap();
info!("Response for send deshielded is {resp:?}");
@ -527,7 +556,16 @@ impl NodeCore {
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
info!("New account public balance is {:?}", acc.balance);
let new_balance = {
let acc_map_read_guard = self.storage.read().await;
let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
acc.log();
acc.balance
};
info!("New account public balance is {new_balance:?}");
}
///Deposit balance, make it private
@ -540,10 +578,14 @@ impl NodeCore {
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
let acc_map_read_guard = self.storage.read().await;
let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
{
let acc_map_read_guard = self.storage.read().await;
info!("New acconut public balance is {:?}", acc.balance);
let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
acc.log();
info!("New acconut public balance is {:?}", acc.balance);
};
let (resp, new_utxo_hashes) = self
.send_shielded_send_tx(acc_addr, 100, vec![(100, acc_addr)])
@ -560,6 +602,7 @@ impl NodeCore {
let mut write_guard = self.storage.write().await;
let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap();
acc.log();
acc.utxo_tree
.get_item(new_utxo_hash)
@ -567,15 +610,17 @@ impl NodeCore {
.unwrap()
.clone()
};
new_utxo.log();
info!("User received new utxo {new_utxo:?}");
}
///Mint utxo, privately send it to another user
pub async fn subscenario_3(&mut self) {
let acc_addr = self.create_new_account().await;
let acc_addr_rec = self.create_new_account().await;
let (resp, new_utxo_hash) = self.send_private_mint_tx(acc_addr, 100).await.unwrap();
let (resp, new_utxo_hash, comm_gen_hash) =
self.send_private_mint_tx(acc_addr, 100).await.unwrap();
info!("Response for mint private is {resp:?}");
info!("Awaiting new blocks");
@ -585,6 +630,7 @@ impl NodeCore {
let mut write_guard = self.storage.write().await;
let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap();
acc.log();
acc.utxo_tree
.get_item(new_utxo_hash)
@ -592,9 +638,12 @@ impl NodeCore {
.unwrap()
.clone()
};
new_utxo.log();
let acc_addr_rec = self.create_new_account().await;
let (resp, new_utxo_hashes) = self
.send_private_send_tx(new_utxo, vec![(100, acc_addr_rec)])
.send_private_send_tx(new_utxo, comm_gen_hash, vec![(100, acc_addr_rec)])
.await
.unwrap();
info!("Response for send deshielded is {resp:?}");
@ -608,6 +657,7 @@ impl NodeCore {
let mut write_guard = self.storage.write().await;
let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap();
acc.log();
acc.utxo_tree
.get_item(new_utxo_hash)
@ -630,10 +680,13 @@ impl NodeCore {
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
let acc_map_read_guard = self.storage.read().await;
let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
{
let acc_map_read_guard = self.storage.read().await;
let acc = acc_map_read_guard.acc_map.get(&acc_addr).unwrap();
acc.log();
info!("New acconut public balance is {:?}", acc.balance);
info!("New acconut public balance is {:?}", acc.balance);
}
let (resp, new_utxo_hashes) = self
.send_shielded_send_tx(acc_addr, 100, vec![(100, acc_addr_rec)])
@ -650,6 +703,7 @@ impl NodeCore {
let mut write_guard = self.storage.write().await;
let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap();
acc.log();
acc.utxo_tree
.get_item(new_utxo_hash)
@ -666,7 +720,8 @@ impl NodeCore {
let acc_addr = self.create_new_account().await;
let acc_addr_rec = self.create_new_account().await;
let (resp, new_utxo_hash) = self.send_private_mint_tx(acc_addr, 100).await.unwrap();
let (resp, new_utxo_hash, comm_gen_hash) =
self.send_private_mint_tx(acc_addr, 100).await.unwrap();
info!("Response for mint private is {resp:?}");
info!("Awaiting new blocks");
@ -676,6 +731,7 @@ impl NodeCore {
let mut write_guard = self.storage.write().await;
let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap();
acc.log();
acc.utxo_tree
.get_item(new_utxo_hash)
@ -683,9 +739,10 @@ impl NodeCore {
.unwrap()
.clone()
};
new_utxo.log();
let resp = self
.send_deshielded_send_tx(new_utxo, vec![(100, acc_addr_rec)])
.send_deshielded_send_tx(new_utxo, comm_gen_hash, vec![(100, acc_addr_rec)])
.await
.unwrap();
info!("Response for send deshielded is {resp:?}");
@ -693,9 +750,12 @@ impl NodeCore {
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
let read_guard = self.storage.read().await;
let acc_rec = read_guard.acc_map.get(&acc_addr_rec).unwrap();
{
let read_guard = self.storage.read().await;
let acc_rec = read_guard.acc_map.get(&acc_addr_rec).unwrap();
acc_rec.log();
info!("New account public balance is {:?}", acc_rec.balance);
info!("New account public balance is {:?}", acc_rec.balance);
}
}
}

View File

@ -67,3 +67,10 @@ impl SequencerRpcRequest {
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct SequencerRpcResponse {
pub jsonrpc: String,
pub result: serde_json::Value,
pub id: u64,
}

View File

@ -3,7 +3,7 @@ use anyhow::Result;
use json::{
GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
RegisterAccountRequest, RegisterAccountResponse, SendTxRequest, SendTxResponse,
SequencerRpcRequest,
SequencerRpcRequest, SequencerRpcResponse,
};
use k256::elliptic_curve::group::GroupEncoding;
use reqwest::Client;
@ -62,9 +62,9 @@ impl SequencerClient {
let call_res = call_builder.json(&request).send().await?;
let response = call_res.json::<Value>().await?;
let response = call_res.json::<SequencerRpcResponse>().await?;
Ok(response)
Ok(response.result)
}
pub async fn get_block(
@ -121,11 +121,14 @@ impl SequencerClient {
pub async fn get_genesis_id(&self) -> Result<GetGenesisIdResponse, SequencerClientError> {
let genesis_req = GetGenesisIdRequest {};
let req = serde_json::to_value(genesis_req)?;
let req = serde_json::to_value(genesis_req).unwrap();
let resp = self.call_method_with_payload("get_genesis", req).await?;
let resp = self
.call_method_with_payload("get_genesis", req)
.await
.unwrap();
let resp_deser = serde_json::from_value(resp)?;
let resp_deser = serde_json::from_value(resp).unwrap();
Ok(resp_deser)
}

View File

@ -19,6 +19,8 @@ use storage::{
};
use utxo::utxo_core::UTXO;
use crate::ActionData;
pub mod accounts_store;
pub mod block_store;
@ -54,6 +56,39 @@ impl NodeChainStore {
pub fn dissect_insert_block(&mut self, block: Block) -> Result<()> {
for tx in &block.transactions {
if !tx.execution_input.is_empty() {
let public_action = serde_json::from_slice::<ActionData>(&tx.execution_input);
if let Ok(public_action) = public_action {
match public_action {
ActionData::MintMoneyPublicTx(action) => {
let acc_mut = self.acc_map.get_mut(&action.acc);
if let Some(acc_mut) = acc_mut {
acc_mut.balance += action.amount as u64;
}
}
ActionData::SendMoneyDeshieldedTx(action) => {
for (balance, acc_addr) in action.receiver_data {
let acc_mut = self.acc_map.get_mut(&acc_addr);
if let Some(acc_mut) = acc_mut {
acc_mut.balance += balance as u64;
}
}
}
ActionData::SendMoneyShieldedTx(action) => {
let acc_mut = self.acc_map.get_mut(&action.acc_sender);
if let Some(acc_mut) = acc_mut {
acc_mut.balance =
acc_mut.balance.saturating_sub(action.amount as u64);
}
}
}
}
}
self.utxo_commitments_store.add_tx_multiple(
tx.utxo_commitments_created_hashes
.clone()
@ -94,12 +129,14 @@ impl NodeChainStore {
nonce,
);
let decoded_utxo_try =
serde_json::from_slice::<UTXO>(&decoded_data_curr_acc);
if let Ok(decoded_data_curr_acc) = decoded_data_curr_acc {
let decoded_utxo_try =
serde_json::from_slice::<UTXO>(&decoded_data_curr_acc);
if let Ok(utxo) = decoded_utxo_try {
if &utxo.owner == acc_id {
acc.utxo_tree.insert_item(utxo)?;
if let Ok(utxo) = decoded_utxo_try {
if &utxo.owner == acc_id {
acc.utxo_tree.insert_item(utxo)?;
}
}
}
}

View File

@ -1,3 +1,5 @@
use std::sync::atomic::Ordering;
use actix_web::Error as HttpError;
use serde_json::Value;
@ -12,8 +14,9 @@ use crate::{
types::{
err_rpc::cast_seq_client_error_into_rpc_error,
rpc_structs::{
ExecuteSubscenarioRequest, ExecuteSubscenarioResponse, RegisterAccountRequest,
RegisterAccountResponse, SendTxRequest,
ExecuteSubscenarioRequest, ExecuteSubscenarioResponse, GetBlockDataRequest,
GetBlockDataResponse, GetLastBlockRequest, GetLastBlockResponse,
RegisterAccountRequest, RegisterAccountResponse, SendTxRequest,
},
},
};
@ -96,12 +99,46 @@ impl JsonHandler {
respond(helperstruct)
}
async fn process_get_block_data(&self, request: Request) -> Result<Value, RpcErr> {
let req = GetBlockDataRequest::parse(Some(request.params))?;
let block = {
let guard = self.node_chain_store.lock().await;
{
let read_guard = guard.storage.read().await;
read_guard.block_store.get_block_at_id(req.block_id)?
}
};
let helperstruct = GetBlockDataResponse { block };
respond(helperstruct)
}
async fn process_get_last_block(&self, request: Request) -> Result<Value, RpcErr> {
let _req = GetLastBlockRequest::parse(Some(request.params))?;
let last_block = {
let guard = self.node_chain_store.lock().await;
guard.curr_height.load(Ordering::Relaxed)
};
let helperstruct = GetLastBlockResponse { last_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
"register_account" => self.process_register_account(request).await,
"execute_subscenario" => self.process_request_execute_subscenario(request).await,
"send_tx" => self.process_send_tx(request).await,
"get_block" => self.process_get_block_data(request).await,
"get_last_block" => self.process_get_last_block(request).await,
_ => Err(RpcErr(RpcError::method_not_found(request.method))),
}
}

View File

@ -28,11 +28,15 @@ pub struct ExecuteSubscenarioRequest {
#[derive(Serialize, Deserialize, Debug)]
pub struct GetGenesisIdRequest {}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetLastBlockRequest {}
parse_request!(RegisterAccountRequest);
parse_request!(SendTxRequest);
parse_request!(GetBlockDataRequest);
parse_request!(GetGenesisIdRequest);
parse_request!(ExecuteSubscenarioRequest);
parse_request!(GetLastBlockRequest);
#[derive(Serialize, Deserialize, Debug)]
pub struct HelloResponse {
@ -63,3 +67,8 @@ pub struct ExecuteSubscenarioResponse {
pub struct GetGenesisIdResponse {
pub genesis_id: u64,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetLastBlockResponse {
pub last_block: u64,
}

View File

@ -14,6 +14,10 @@ actix.workspace = true
actix-web.workspace = true
tokio.workspace = true
[dependencies.clap]
features = ["derive", "env"]
workspace = true
[dependencies.accounts]
path = "../accounts"

View File

@ -0,0 +1,7 @@
{
"home": ".",
"override_rust_log": null,
"sequencer_addr": "http://127.0.0.1:3040",
"seq_poll_timeout_secs": 10,
"port": 3041
}

14
node_runner/src/config.rs Normal file
View File

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

View File

@ -1,31 +1,40 @@
use std::{path::PathBuf, sync::Arc};
use anyhow::Result;
use clap::Parser;
use consensus::ConsensusManager;
use log::info;
use networking::peer_manager::PeerManager;
use node_core::{config::NodeConfig, NodeCore};
use node_core::NodeCore;
use node_rpc::new_http_server;
use rpc_primitives::RpcConfig;
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<()> {
env_logger::init();
//ToDo: Change it
let node_config = NodeConfig {
home: PathBuf::new(),
override_rust_log: None,
sequencer_addr: "addr".to_string(),
seq_poll_timeout_secs: 1,
};
let args = Args::parse();
let Args { home_dir } = args;
let node_core = NodeCore::start_from_config_update_chain(node_config.clone()).await?;
let app_config = config::from_file(home_dir.join("node_config.json"))?;
let port = app_config.port;
let node_core = NodeCore::start_from_config_update_chain(app_config.clone()).await?;
let wrapped_node_core = Arc::new(Mutex::new(node_core));
let http_server = new_http_server(
RpcConfig::default(),
node_config.clone(),
RpcConfig::with_port(port),
app_config.clone(),
wrapped_node_core.clone(),
)?;
info!("HTTP server started");

View File

@ -1,4 +1,4 @@
use std::{path::PathBuf, time::Duration};
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
@ -15,5 +15,7 @@ pub struct SequencerConfig {
///Maximum number of transactions in block
pub max_num_tx_in_block: usize,
///Interval in which blocks produced
pub block_create_timeout_millis: Duration,
pub block_create_timeout_millis: u64,
///Port to listen
pub port: u16,
}

View File

@ -181,7 +181,7 @@ impl SequencerCore {
.store
.block_store
.get_block_at_id(self.chain_height)?
.prev_block_hash;
.hash;
let hashable_data = HashableBlockData {
block_id: self.chain_height + 1,

View File

@ -12,6 +12,7 @@ serde.workspace = true
actix.workspace = true
actix-cors.workspace = true
futures.workspace = true
hex.workspace = true
actix-web.workspace = true
tokio.workspace = true

View File

@ -12,8 +12,8 @@ use crate::{
rpc_error_responce_inverter,
types::rpc_structs::{
GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
HelloRequest, HelloResponse, RegisterAccountRequest, RegisterAccountResponse,
SendTxRequest, SendTxResponse,
GetLastBlockRequest, GetLastBlockResponse, HelloRequest, HelloResponse,
RegisterAccountRequest, RegisterAccountResponse, SendTxRequest, SendTxResponse,
},
};
@ -115,6 +115,20 @@ impl JsonHandler {
respond(helperstruct)
}
async fn process_get_last_block(&self, request: Request) -> Result<Value, RpcErr> {
let _get_last_block_req = GetLastBlockRequest::parse(Some(request.params))?;
let last_block = {
let state = self.sequencer_state.lock().await;
state.chain_height
};
let helperstruct = GetLastBlockResponse { last_block };
respond(helperstruct)
}
pub async fn process_request_internal(&self, request: Request) -> Result<Value, RpcErr> {
match request.method.as_ref() {
"hello" => self.process_temp_hello(request).await,
@ -122,6 +136,7 @@ impl JsonHandler {
"send_tx" => self.process_send_tx(request).await,
"get_block" => self.process_get_block_data(request).await,
"get_genesis" => self.process_get_genesis(request).await,
"get_last_block" => self.process_get_last_block(request).await,
_ => Err(RpcErr(RpcError::method_not_found(request.method))),
}
}

View File

@ -6,6 +6,8 @@ use sequencer_core::transaction_mempool::TransactionMempool;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use storage::block::Block;
use storage::block::BlockId;
use storage::transaction::Transaction;
#[derive(Serialize, Deserialize, Debug)]
pub struct HelloRequest {}
@ -30,11 +32,15 @@ pub struct GetBlockDataRequest {
#[derive(Serialize, Deserialize, Debug)]
pub struct GetGenesisIdRequest {}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetLastBlockRequest {}
parse_request!(HelloRequest);
parse_request!(RegisterAccountRequest);
parse_request!(SendTxRequest);
parse_request!(GetBlockDataRequest);
parse_request!(GetGenesisIdRequest);
parse_request!(GetLastBlockRequest);
#[derive(Serialize, Deserialize, Debug)]
pub struct HelloResponse {
@ -60,3 +66,8 @@ pub struct GetBlockDataResponse {
pub struct GetGenesisIdResponse {
pub genesis_id: u64,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetLastBlockResponse {
pub last_block: u64,
}

View File

@ -4,5 +4,6 @@
"genesis_id": 1,
"is_genesis_random": true,
"max_num_tx_in_block": 20,
"block_create_timeout_millis": 10000
"block_create_timeout_millis": 10000,
"port": 3040
}

View File

@ -24,6 +24,7 @@ pub async fn main_runner() -> Result<()> {
let app_config = config::from_file(home_dir.join("sequencer_config.json"))?;
let block_timeout = app_config.block_create_timeout_millis;
let port = app_config.port;
if let Some(ref rust_log) = app_config.override_rust_log {
info!("RUST_LOG env var set to {rust_log:?}");
@ -39,7 +40,7 @@ pub async fn main_runner() -> Result<()> {
let seq_core_wrapped = Arc::new(Mutex::new(sequencer_core));
let http_server = new_http_server(RpcConfig::default(), seq_core_wrapped.clone())?;
let http_server = new_http_server(RpcConfig::with_port(port), seq_core_wrapped.clone())?;
info!("HTTP server started");
let _http_server_handle = http_server.handle();
tokio::spawn(http_server);
@ -48,7 +49,7 @@ pub async fn main_runner() -> Result<()> {
#[allow(clippy::empty_loop)]
loop {
tokio::time::sleep(block_timeout).await;
tokio::time::sleep(std::time::Duration::from_millis(block_timeout)).await;
info!("Collecting transactions from mempool, block creation");

View File

@ -12,6 +12,7 @@ serde.workspace = true
lru.workspace = true
thiserror.workspace = true
elliptic-curve.workspace = true
hex.workspace = true
rocksdb.workspace = true
rs_merkle.workspace = true

View File

@ -1,3 +1,4 @@
use log::info;
use serde::{Deserialize, Serialize};
use sha2::{digest::FixedOutput, Digest};
@ -89,3 +90,50 @@ impl From<TransactionPayload> for Transaction {
}
}
}
impl Transaction {
pub fn log(&self) {
info!("Transaction hash is {:?}", hex::encode(self.hash));
info!("Transaction tx_kind is {:?}", self.tx_kind);
info!(
"Transaction execution_input is {:?}",
hex::encode(self.execution_input.clone())
);
info!(
"Transaction execution_output is {:?}",
hex::encode(self.execution_output.clone())
);
info!(
"Transaction utxo_commitments_spent_hashes is {:?}",
self.utxo_commitments_spent_hashes
.iter()
.map(|val| hex::encode(val.clone()))
);
info!(
"Transaction utxo_commitments_created_hashes is {:?}",
self.utxo_commitments_created_hashes
.iter()
.map(|val| hex::encode(val.clone()))
);
info!(
"Transaction nullifier_created_hashes is {:?}",
self.nullifier_created_hashes
.iter()
.map(|val| hex::encode(val.clone()))
);
info!(
"Transaction execution_proof_private is {:?}",
self.execution_proof_private
);
info!(
"Transaction encoded_data is {:?}",
self.encoded_data
.iter()
.map(|val| (hex::encode(val.0.clone()), hex::encode(val.1.clone())))
);
info!(
"Transaction ephemeral_pub_key is {:?}",
hex::encode(self.ephemeral_pub_key.clone())
);
}
}

View File

@ -11,6 +11,7 @@ log.workspace = true
serde.workspace = true
monotree.workspace = true
sha2.workspace = true
hex.workspace = true
[dependencies.storage]
path = "../storage"

View File

@ -1,4 +1,5 @@
use anyhow::Result;
use log::info;
use serde::{Deserialize, Serialize};
use sha2::{digest::FixedOutput, Digest};
use storage::{merkle_tree_public::TreeHashType, nullifier::UTXONullifier, AccountId};
@ -60,6 +61,27 @@ impl UTXO {
pub fn interpret_asset<'de, ToInterpret: Deserialize<'de>>(&'de self) -> Result<ToInterpret> {
Ok(serde_json::from_slice(&self.asset)?)
}
pub fn into_payload(&self) -> UTXOPayload {
UTXOPayload {
owner: self.owner,
asset: self.asset.clone(),
amount: self.amount,
privacy_flag: self.privacy_flag,
}
}
pub fn log(&self) {
info!("UTXO hash is {:?}", hex::encode(self.hash));
info!("UTXO owner is {:?}", self.owner);
info!(
"UTXO nullifier is {:?}",
self.nullifier.clone().map(|val| hex::encode(val.utxo_hash))
);
info!("UTXO asset is {:?}", hex::encode(self.asset.clone()));
info!("UTXO amount is {:?}", self.amount);
info!("UTXO privacy_flag is {:?}", self.privacy_flag);
}
}
#[cfg(test)]

View File

@ -27,8 +27,9 @@ pub fn prove_send_utxo(
owners_parts: Vec<(u128, AccountAddress)>,
) -> (Vec<(UTXO, AccountAddress)>, Receipt) {
let mut builder = ExecutorEnv::builder();
let utxo_payload = spent_utxo.into_payload();
builder.write(&spent_utxo).unwrap();
builder.write(&utxo_payload).unwrap();
builder.write(&owners_parts).unwrap();
let env = builder.build().unwrap();
@ -62,10 +63,11 @@ pub fn prove_send_utxo_shielded(
amount,
privacy_flag: true,
});
let utxo_payload = temp_utxo_to_spend.into_payload();
let mut builder = ExecutorEnv::builder();
builder.write(&temp_utxo_to_spend).unwrap();
builder.write(&utxo_payload).unwrap();
builder.write(&owners_parts).unwrap();
let env = builder.build().unwrap();
@ -93,8 +95,9 @@ pub fn prove_send_utxo_deshielded(
owners_parts: Vec<(u128, AccountAddress)>,
) -> (Vec<(u128, AccountAddress)>, Receipt) {
let mut builder = ExecutorEnv::builder();
let utxo_payload = spent_utxo.into_payload();
builder.write(&spent_utxo).unwrap();
builder.write(&utxo_payload).unwrap();
builder.write(&owners_parts).unwrap();
let env = builder.build().unwrap();
@ -140,7 +143,9 @@ pub fn execute_send_utxo(
) -> (UTXO, Vec<(UTXO, AccountAddress)>) {
let mut builder = ExecutorEnv::builder();
builder.write(&spent_utxo).unwrap();
let utxo_payload = spent_utxo.into_payload();
builder.write(&utxo_payload).unwrap();
builder.write(&owners_parts).unwrap();
let env = builder.build().unwrap();

View File

@ -845,9 +845,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.133"
version = "1.0.134"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
dependencies = [
"itoa",
"memchr",