164 lines
6.1 KiB
Rust
Raw Normal View History

2025-04-04 12:11:54 +03:00
use std::{
collections::{BTreeMap, HashMap},
path::Path,
};
2024-12-03 09:32:35 +02:00
use accounts::account_core::{Account, AccountAddress};
2024-12-05 13:05:58 +02:00
use anyhow::Result;
2024-12-03 09:32:35 +02:00
use block_store::NodeBlockStore;
2024-12-25 09:50:54 +02:00
use k256::AffinePoint;
2025-04-04 12:11:54 +03:00
use public_context::PublicSCContext;
2024-12-03 09:32:35 +02:00
use storage::{
2024-12-05 13:05:58 +02:00
block::Block,
2025-01-03 10:44:06 +02:00
merkle_tree_public::merkle_tree::{PublicTransactionMerkleTree, UTXOCommitmentsMerkleTree},
2024-12-05 13:05:58 +02:00
nullifier::UTXONullifier,
2024-12-03 09:32:35 +02:00
nullifier_sparse_merkle_tree::NullifierSparseMerkleTree,
2024-12-05 13:05:58 +02:00
utxo_commitment::UTXOCommitment,
2024-12-03 09:32:35 +02:00
};
2024-12-25 09:50:54 +02:00
use utxo::utxo_core::UTXO;
2024-12-03 09:32:35 +02:00
2024-12-30 08:00:24 +02:00
use crate::ActionData;
2024-12-03 09:32:35 +02:00
pub mod accounts_store;
pub mod block_store;
2025-04-04 12:11:54 +03:00
pub mod public_context;
2024-12-03 09:32:35 +02:00
pub struct NodeChainStore {
2024-12-25 09:50:54 +02:00
pub acc_map: HashMap<AccountAddress, Account>,
2024-12-03 09:32:35 +02:00
pub block_store: NodeBlockStore,
pub nullifier_store: NullifierSparseMerkleTree,
pub utxo_commitments_store: UTXOCommitmentsMerkleTree,
pub pub_tx_store: PublicTransactionMerkleTree,
}
impl NodeChainStore {
2024-12-05 13:05:58 +02:00
pub fn new_with_genesis(home_dir: &Path, genesis_block: Block) -> Self {
2024-12-25 09:50:54 +02:00
let acc_map = HashMap::new();
2024-12-03 09:32:35 +02:00
let nullifier_store = NullifierSparseMerkleTree::default();
let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
let pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
//Sequencer should panic if unable to open db,
//as fixing this issue may require actions non-native to program scope
let block_store =
NodeBlockStore::open_db_with_genesis(&home_dir.join("rocksdb"), Some(genesis_block))
.unwrap();
Self {
2024-12-25 09:50:54 +02:00
acc_map,
2024-12-03 09:32:35 +02:00
block_store,
nullifier_store,
utxo_commitments_store,
pub_tx_store,
}
}
2024-12-05 13:05:58 +02:00
pub fn dissect_insert_block(&mut self, block: Block) -> Result<()> {
for tx in &block.transactions {
2024-12-30 08:00:24 +02:00
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;
}
2024-12-30 09:10:04 +02:00
}
2024-12-30 08:00:24 +02:00
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;
}
}
2024-12-30 09:10:04 +02:00
}
2024-12-30 08:00:24 +02:00
ActionData::SendMoneyShieldedTx(action) => {
let acc_mut = self.acc_map.get_mut(&action.acc_sender);
if let Some(acc_mut) = acc_mut {
2024-12-30 09:10:04 +02:00
acc_mut.balance =
acc_mut.balance.saturating_sub(action.amount as u64);
2024-12-30 08:00:24 +02:00
}
}
2025-01-03 10:44:06 +02:00
_ => {}
2024-12-30 08:00:24 +02:00
}
}
}
2024-12-30 07:43:27 +02:00
2024-12-05 13:05:58 +02:00
self.utxo_commitments_store.add_tx_multiple(
tx.utxo_commitments_created_hashes
.clone()
.into_iter()
.map(|hash| UTXOCommitment { hash })
.collect(),
);
self.nullifier_store.insert_items(
tx.nullifier_created_hashes
.clone()
.into_iter()
.map(|hash| UTXONullifier { utxo_hash: hash })
.collect(),
)?;
let eph_key_compressed = serde_json::to_vec(&tx.ephemeral_pub_key);
2024-12-25 09:50:54 +02:00
if let Ok(eph_key_compressed) = eph_key_compressed {
2025-04-04 14:14:04 -04:00
let ephemeral_public_key_sender =
serde_json::from_slice::<AffinePoint>(&eph_key_compressed)?;
for (ciphertext, nonce, tag) in tx.encoded_data.clone() {
let slice = nonce.as_slice();
let nonce =
2025-04-04 14:14:04 -04:00
accounts::key_management::constants_types::Nonce::clone_from_slice(slice);
for (acc_id, acc) in self.acc_map.iter_mut() {
if acc_id[0] == tag {
let decoded_data_curr_acc = acc.decrypt_data(
ephemeral_public_key_sender,
ciphertext.clone(),
nonce,
2024-12-26 11:38:00 +02:00
);
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)?;
2024-12-30 09:10:04 +02:00
}
2024-12-25 09:50:54 +02:00
}
}
2024-12-26 11:38:00 +02:00
}
2024-12-25 09:50:54 +02:00
}
}
}
2024-12-05 13:05:58 +02:00
self.pub_tx_store.add_tx(tx.clone());
}
self.block_store.put_block_at_id(block)?;
Ok(())
}
2025-04-04 12:11:54 +03:00
pub fn produce_context(&self, caller: AccountAddress) -> PublicSCContext {
let mut account_masks = BTreeMap::new();
for (acc_addr, acc) in &self.acc_map {
account_masks.insert(*acc_addr, acc.make_account_public_mask());
}
PublicSCContext {
caller_address: caller,
caller_balance: self.acc_map.get(&caller).unwrap().balance,
account_masks,
nullifier_store_root: self.nullifier_store.curr_root.unwrap_or([0; 32]),
comitment_store_root: self.utxo_commitments_store.get_root().unwrap_or([0; 32]),
pub_tx_store_root: self.pub_tx_store.get_root().unwrap_or([0; 32]),
}
}
2024-12-03 09:32:35 +02:00
}