mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-09 08:43:12 +00:00
breaking: initial cuts
This commit is contained in:
parent
ebec84b3c0
commit
6565e0af18
@ -2,24 +2,18 @@ use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
|
||||
use accounts::account_core::{address::AccountAddress, Account};
|
||||
use anyhow::Result;
|
||||
use block_store::NodeBlockStore;
|
||||
use common::{
|
||||
block::Block,
|
||||
execution_input::PublicNativeTokenSend,
|
||||
merkle_tree_public::merkle_tree::{PublicTransactionMerkleTree, UTXOCommitmentsMerkleTree},
|
||||
nullifier::UTXONullifier,
|
||||
utxo_commitment::UTXOCommitment,
|
||||
};
|
||||
use k256::AffinePoint;
|
||||
use log::{info, warn};
|
||||
use sc_core::public_context::PublicSCContext;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utxo::utxo_core::UTXO;
|
||||
|
||||
use crate::{config::NodeConfig, ActionData};
|
||||
use crate::config::NodeConfig;
|
||||
|
||||
pub mod accounts_store;
|
||||
pub mod block_store;
|
||||
//pub mod block_store;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct AccMap {
|
||||
@ -49,7 +43,6 @@ impl From<AccMap> for HashMap<[u8; 32], Account> {
|
||||
|
||||
pub struct NodeChainStore {
|
||||
pub acc_map: HashMap<AccountAddress, Account>,
|
||||
pub block_store: NodeBlockStore,
|
||||
pub nullifier_store: HashSet<UTXONullifier>,
|
||||
pub utxo_commitments_store: UTXOCommitmentsMerkleTree,
|
||||
pub pub_tx_store: PublicTransactionMerkleTree,
|
||||
@ -58,30 +51,15 @@ pub struct NodeChainStore {
|
||||
|
||||
impl NodeChainStore {
|
||||
pub fn new(config: NodeConfig, genesis_block: Block) -> Result<(Self, u64)> {
|
||||
let mut acc_map = HashMap::new();
|
||||
let mut nullifier_store = HashSet::new();
|
||||
let mut utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
||||
let mut pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
|
||||
let mut block_id = genesis_block.block_id;
|
||||
|
||||
//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(&config.home.join("rocksdb"), Some(genesis_block))
|
||||
.unwrap();
|
||||
|
||||
if let Ok(temp_block_id) = block_store.get_snapshot_block_id() {
|
||||
utxo_commitments_store = block_store.get_snapshot_commitment()?;
|
||||
nullifier_store = block_store.get_snapshot_nullifier()?;
|
||||
acc_map = block_store.get_snapshot_account()?;
|
||||
pub_tx_store = block_store.get_snapshot_transaction()?;
|
||||
block_id = temp_block_id;
|
||||
}
|
||||
let acc_map = HashMap::new();
|
||||
let nullifier_store = HashSet::new();
|
||||
let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
||||
let pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
|
||||
let block_id = genesis_block.block_id;
|
||||
|
||||
Ok((
|
||||
Self {
|
||||
acc_map,
|
||||
block_store,
|
||||
nullifier_store,
|
||||
utxo_commitments_store,
|
||||
pub_tx_store,
|
||||
@ -91,184 +69,6 @@ impl NodeChainStore {
|
||||
))
|
||||
}
|
||||
|
||||
pub fn new_after_restart(config: NodeConfig, genesis_block: Block) -> Result<(Self, u64)> {
|
||||
let mut acc_map = HashMap::new();
|
||||
let mut nullifier_store = HashSet::new();
|
||||
let mut utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
||||
let mut pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
|
||||
let mut block_id = genesis_block.block_id;
|
||||
|
||||
//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_reload(&config.home.join("rocksdb")).unwrap();
|
||||
|
||||
if let Ok(temp_block_id) = block_store.get_snapshot_block_id() {
|
||||
utxo_commitments_store = block_store.get_snapshot_commitment()?;
|
||||
nullifier_store = block_store.get_snapshot_nullifier()?;
|
||||
acc_map = block_store.get_snapshot_account()?;
|
||||
pub_tx_store = block_store.get_snapshot_transaction()?;
|
||||
block_id = temp_block_id;
|
||||
}
|
||||
|
||||
Ok((
|
||||
Self {
|
||||
acc_map,
|
||||
block_store,
|
||||
nullifier_store,
|
||||
utxo_commitments_store,
|
||||
pub_tx_store,
|
||||
node_config: config,
|
||||
},
|
||||
block_id,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn dissect_insert_block(&mut self, block: Block) -> Result<()> {
|
||||
let block_id = block.block_id;
|
||||
|
||||
for tx in &block.transactions {
|
||||
if !tx.body().execution_input.is_empty() {
|
||||
let public_action =
|
||||
serde_json::from_slice::<ActionData>(&tx.body().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);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
let native_transfer =
|
||||
serde_json::from_slice::<PublicNativeTokenSend>(&tx.body().execution_input);
|
||||
|
||||
if let Ok(transfer) = native_transfer {
|
||||
if let Some(acc_sender) = self.acc_map.get_mut(&transfer.from) {
|
||||
//Can panic, we depend on sequencer maintaining chain consistency here
|
||||
acc_sender.balance -= transfer.balance_to_move;
|
||||
|
||||
if let Some(acc_rec) = self.acc_map.get_mut(&transfer.to) {
|
||||
acc_rec.balance += transfer.balance_to_move;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.utxo_commitments_store.add_tx_multiple(
|
||||
tx.body()
|
||||
.utxo_commitments_created_hashes
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|hash| UTXOCommitment { hash })
|
||||
.collect(),
|
||||
);
|
||||
|
||||
for nullifier in tx.body().nullifier_created_hashes.iter() {
|
||||
self.nullifier_store.insert(UTXONullifier {
|
||||
utxo_hash: *nullifier,
|
||||
});
|
||||
}
|
||||
|
||||
if !tx.body().encoded_data.is_empty() {
|
||||
let ephemeral_public_key_sender =
|
||||
serde_json::from_slice::<AffinePoint>(&tx.body().ephemeral_pub_key)?;
|
||||
|
||||
for (ciphertext, nonce, tag) in tx.body().encoded_data.clone() {
|
||||
let slice = nonce.as_slice();
|
||||
let nonce =
|
||||
accounts::key_management::constants_types::Nonce::clone_from_slice(slice);
|
||||
for (acc_id, acc) in self.acc_map.iter_mut() {
|
||||
if hex::decode(acc_id).unwrap()[0] == tag {
|
||||
let decoded_data_curr_acc = acc.decrypt_data(
|
||||
ephemeral_public_key_sender,
|
||||
ciphertext.clone(),
|
||||
nonce,
|
||||
);
|
||||
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.utxos.insert(utxo.hash, utxo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.pub_tx_store.add_tx(tx);
|
||||
}
|
||||
|
||||
self.block_store.put_block_at_id(block)?;
|
||||
|
||||
//Snapshot
|
||||
if block_id.is_multiple_of(self.node_config.shapshot_frequency_in_blocks) {
|
||||
//Serializing all important data structures
|
||||
|
||||
//If we fail serialization, it is not the reason to stop running
|
||||
//Logging on warn level in this cases
|
||||
let acc_map: AccMap = self.acc_map.clone().into();
|
||||
|
||||
if let Ok(accounts_ser) = serde_json::to_vec(&acc_map).inspect_err(|err| {
|
||||
warn!("Failed to serialize accounts data {err:#?}");
|
||||
}) {
|
||||
if let Ok(comm_ser) =
|
||||
serde_json::to_vec(&self.utxo_commitments_store).inspect_err(|err| {
|
||||
warn!("Failed to serialize commitments {err:#?}");
|
||||
})
|
||||
{
|
||||
if let Ok(txs_ser) = serde_json::to_vec(&self.pub_tx_store).inspect_err(|err| {
|
||||
warn!("Failed to serialize transactions {err:#?}");
|
||||
}) {
|
||||
if let Ok(nullifiers_ser) = serde_json::to_vec(&self.nullifier_store)
|
||||
.inspect_err(|err| {
|
||||
warn!("Failed to serialize nullifiers {err:#?}");
|
||||
})
|
||||
{
|
||||
let snapshot_trace = self.block_store.put_snapshot_at_block_id(
|
||||
block_id,
|
||||
accounts_ser,
|
||||
comm_ser,
|
||||
txs_ser,
|
||||
nullifiers_ser,
|
||||
);
|
||||
|
||||
info!(
|
||||
"Snapshot executed at {block_id:?} with results {snapshot_trace:#?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn produce_context(&self, caller: AccountAddress) -> PublicSCContext {
|
||||
let mut account_masks = BTreeMap::new();
|
||||
|
||||
@ -298,7 +98,6 @@ mod tests {
|
||||
use crate::config::GasConfig;
|
||||
use accounts::account_core::Account;
|
||||
use common::block::{Block, Data};
|
||||
use common::merkle_tree_public::TreeHashType;
|
||||
use common::transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind};
|
||||
use secp256k1_zkp::Tweak;
|
||||
use std::path::PathBuf;
|
||||
@ -489,6 +288,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
//ToDo: Continue refactor
|
||||
fn create_dummy_transaction(
|
||||
nullifier_created_hashes: Vec<[u8; 32]>,
|
||||
utxo_commitments_spent_hashes: Vec<[u8; 32]>,
|
||||
@ -515,6 +315,7 @@ mod tests {
|
||||
Transaction::new(body, SignaturePrivateKey::random(&mut rng))
|
||||
}
|
||||
|
||||
//ToDo: Continue refactor
|
||||
fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block {
|
||||
Block {
|
||||
block_id,
|
||||
@ -551,10 +352,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_dummy_utxo(address: TreeHashType, amount: u128) -> UTXO {
|
||||
UTXO::new(address, vec![], amount, false)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_initializes_correctly() {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
@ -574,59 +371,4 @@ mod tests {
|
||||
[0; 32]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_recovers_from_snapshot() {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let path = temp_dir.path().to_path_buf();
|
||||
|
||||
let config = create_sample_node_config(path);
|
||||
|
||||
let nullifier_secret_const =
|
||||
"261d61d294ac4bdc24f91b6f490efa263757a4a95f65871cd4f16b2ea23c3b5d";
|
||||
std::env::set_var("NULLIFIER_SECRET_CONST", nullifier_secret_const);
|
||||
|
||||
let viewing_secret_const =
|
||||
"6117af750b30d7a296672ec3b3b25d3489beca3cfe5770fa39f275cec395d5ce";
|
||||
std::env::set_var("VIEWING_SECRET_CONST", viewing_secret_const);
|
||||
|
||||
let genesis_block = create_genesis_block();
|
||||
|
||||
// Initialize once to create DB and store fake snapshot
|
||||
{
|
||||
let (mut store, _) =
|
||||
NodeChainStore::new(config.clone(), genesis_block.clone()).unwrap();
|
||||
|
||||
// Insert state
|
||||
let mut account = Account::new();
|
||||
account
|
||||
.add_new_utxo_outputs(vec![generate_dummy_utxo(account.address, 100)])
|
||||
.unwrap();
|
||||
store.acc_map.insert(account.address, account);
|
||||
store.nullifier_store.insert(UTXONullifier {
|
||||
utxo_hash: [2u8; 32],
|
||||
});
|
||||
store
|
||||
.utxo_commitments_store
|
||||
.add_tx_multiple(vec![UTXOCommitment { hash: [3u8; 32] }]);
|
||||
store.pub_tx_store.add_tx(&create_dummy_transaction(
|
||||
vec![[9; 32]],
|
||||
vec![[7; 32]],
|
||||
vec![[8; 32]],
|
||||
));
|
||||
|
||||
// Put block snapshot to trigger snapshot recovery on next load
|
||||
let dummy_block = create_sample_block(1, 0);
|
||||
|
||||
store.dissect_insert_block(dummy_block).unwrap();
|
||||
}
|
||||
|
||||
// Now reload and verify snapshot is used
|
||||
let (recovered_store, block_id) =
|
||||
NodeChainStore::new_after_restart(config.clone(), genesis_block).unwrap();
|
||||
|
||||
assert_eq!(block_id, 1);
|
||||
assert_eq!(recovered_store.acc_map.len(), 1);
|
||||
assert!(recovered_store.utxo_commitments_store.get_root().is_some());
|
||||
}
|
||||
}
|
||||
|
||||
1561
node_core/src/lib.rs
1561
node_core/src/lib.rs
File diff suppressed because it is too large
Load Diff
@ -1,71 +0,0 @@
|
||||
use anyhow::Result;
|
||||
use log::info;
|
||||
|
||||
use crate::chain_storage::NodeChainStore;
|
||||
|
||||
///Addres of public fund transfer account, as no such binary exists for zkVM
|
||||
pub const PUBLIC_DEPOSIT_ID: [u8; 32] = [0; 32];
|
||||
|
||||
///Setups public states of default smart conracts as empty
|
||||
pub async fn setup_empty_sc_states(node: &NodeChainStore) -> Result<()> {
|
||||
info!("Filling up public states of default smart contracts");
|
||||
|
||||
let empty_state = vec![];
|
||||
|
||||
let public_deposit_addr = hex::encode(PUBLIC_DEPOSIT_ID);
|
||||
node.block_store.put_sc_sc_state(
|
||||
&public_deposit_addr,
|
||||
empty_state.len(),
|
||||
empty_state.clone(),
|
||||
)?;
|
||||
info!("Public transfer state set");
|
||||
|
||||
let mint_utxo_addr_bytes: Vec<u8> = zkvm::test_methods::MINT_UTXO_ID
|
||||
.iter()
|
||||
.flat_map(|num| num.to_le_bytes())
|
||||
.collect();
|
||||
let mint_utxo_addr = hex::encode(mint_utxo_addr_bytes);
|
||||
node.block_store
|
||||
.put_sc_sc_state(&mint_utxo_addr, empty_state.len(), empty_state.clone())?;
|
||||
info!("Mint UTXO state set");
|
||||
|
||||
let single_utxo_transfer_addr_bytes: Vec<u8> = zkvm::test_methods::SEND_UTXO_ID
|
||||
.iter()
|
||||
.flat_map(|num| num.to_le_bytes())
|
||||
.collect();
|
||||
let single_utxo_transfer_addr = hex::encode(single_utxo_transfer_addr_bytes);
|
||||
node.block_store.put_sc_sc_state(
|
||||
&single_utxo_transfer_addr,
|
||||
empty_state.len(),
|
||||
empty_state.clone(),
|
||||
)?;
|
||||
info!("Single UTXO transfer state set");
|
||||
|
||||
let mint_utxo_multiple_assets_addr_bytes: Vec<u8> =
|
||||
zkvm::test_methods::MINT_UTXO_MULTIPLE_ASSETS_ID
|
||||
.iter()
|
||||
.flat_map(|num| num.to_le_bytes())
|
||||
.collect();
|
||||
let mint_utxo_multiple_assets_addr = hex::encode(mint_utxo_multiple_assets_addr_bytes);
|
||||
node.block_store.put_sc_sc_state(
|
||||
&mint_utxo_multiple_assets_addr,
|
||||
empty_state.len(),
|
||||
empty_state.clone(),
|
||||
)?;
|
||||
info!("Mint UTXO multiple assets state set");
|
||||
|
||||
let multiple_assets_utxo_transfer_addr_bytes: Vec<u8> =
|
||||
zkvm::test_methods::SEND_UTXO_MULTIPLE_ASSETS_ID
|
||||
.iter()
|
||||
.flat_map(|num| num.to_le_bytes())
|
||||
.collect();
|
||||
let multiple_assets_utxo_transfer_addr = hex::encode(multiple_assets_utxo_transfer_addr_bytes);
|
||||
node.block_store.put_sc_sc_state(
|
||||
&multiple_assets_utxo_transfer_addr,
|
||||
empty_state.len(),
|
||||
empty_state.clone(),
|
||||
)?;
|
||||
info!("Multiple_assets UTXO transfer state set");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use actix_web::Error as HttpError;
|
||||
use node_core::generate_commitments_helper;
|
||||
use serde_json::Value;
|
||||
|
||||
use common::rpc_primitives::{
|
||||
@ -11,25 +10,12 @@ use common::rpc_primitives::{
|
||||
};
|
||||
use common::transaction::ActionData;
|
||||
|
||||
use common::rpc_primitives::requests::{
|
||||
GetBlockDataRequest, GetBlockDataResponse, GetLastBlockRequest, GetLastBlockResponse,
|
||||
};
|
||||
use common::rpc_primitives::requests::{GetLastBlockRequest, GetLastBlockResponse};
|
||||
|
||||
use crate::types::{
|
||||
err_rpc::cast_common_execution_error_into_rpc_error,
|
||||
rpc_structs::{
|
||||
CreateAccountRequest, CreateAccountResponse, ExecuteScenarioMultipleSendRequest,
|
||||
ExecuteScenarioMultipleSendResponse, ExecuteScenarioSplitRequest,
|
||||
ExecuteScenarioSplitResponse, ExecuteSubscenarioRequest, ExecuteSubscenarioResponse,
|
||||
ShowAccountPublicBalanceRequest, ShowAccountPublicBalanceResponse, ShowAccountUTXORequest,
|
||||
ShowAccountUTXOResponse, ShowTransactionRequest, ShowTransactionResponse,
|
||||
UTXOShortEssentialStruct, WriteMintPrivateUTXOMultipleAssetsRequest,
|
||||
WriteMintPrivateUTXOMultipleAssetsResponse, WriteMintPrivateUTXORequest,
|
||||
WriteMintPrivateUTXOResponse, WriteSendDeshieldedBalanceRequest,
|
||||
WriteSendDeshieldedUTXOResponse, WriteSendPrivateUTXORequest, WriteSendPrivateUTXOResponse,
|
||||
WriteSendShieldedUTXORequest, WriteSendShieldedUTXOResponse, WriteSendSplitUTXOResponse,
|
||||
WriteSplitUTXORequest,
|
||||
},
|
||||
use crate::types::rpc_structs::{
|
||||
CreateAccountRequest, CreateAccountResponse, ShowAccountPublicBalanceRequest,
|
||||
ShowAccountPublicBalanceResponse, ShowAccountUTXORequest, ShowAccountUTXOResponse,
|
||||
ShowTransactionRequest, ShowTransactionResponse,
|
||||
};
|
||||
|
||||
pub const CREATE_ACCOUNT: &str = "create_account";
|
||||
@ -71,80 +57,6 @@ impl JsonHandler {
|
||||
}
|
||||
}
|
||||
|
||||
async fn process_request_execute_subscenario(&self, request: Request) -> Result<Value, RpcErr> {
|
||||
let req = ExecuteSubscenarioRequest::parse(Some(request.params))?;
|
||||
|
||||
{
|
||||
let mut store = self.node_chain_store.lock().await;
|
||||
|
||||
match req.scenario_id {
|
||||
1 => store
|
||||
.subscenario_1()
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?,
|
||||
2 => store
|
||||
.subscenario_2()
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?,
|
||||
3 => store
|
||||
.subscenario_3()
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?,
|
||||
_ => return Err(RpcErr(RpcError::invalid_params("Scenario id not found"))),
|
||||
}
|
||||
}
|
||||
|
||||
let helperstruct = ExecuteSubscenarioResponse {
|
||||
scenario_result: SUCCESS.to_string(),
|
||||
};
|
||||
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
async fn process_request_execute_scenario_split(
|
||||
&self,
|
||||
request: Request,
|
||||
) -> Result<Value, RpcErr> {
|
||||
let req = ExecuteScenarioSplitRequest::parse(Some(request.params))?;
|
||||
|
||||
{
|
||||
let mut store = self.node_chain_store.lock().await;
|
||||
|
||||
store
|
||||
.scenario_1(req.visibility_list, req.publication_index)
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?;
|
||||
}
|
||||
|
||||
let helperstruct = ExecuteScenarioSplitResponse {
|
||||
scenario_result: SUCCESS.to_string(),
|
||||
};
|
||||
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
async fn process_request_execute_scenario_multiple_send(
|
||||
&self,
|
||||
request: Request,
|
||||
) -> Result<Value, RpcErr> {
|
||||
let req = ExecuteScenarioMultipleSendRequest::parse(Some(request.params))?;
|
||||
|
||||
{
|
||||
let mut store = self.node_chain_store.lock().await;
|
||||
|
||||
store
|
||||
.scenario_2(req.number_of_assets, req.number_to_send)
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?;
|
||||
}
|
||||
|
||||
let helperstruct = ExecuteScenarioMultipleSendResponse {
|
||||
scenario_result: SUCCESS.to_string(),
|
||||
};
|
||||
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
async fn process_create_account(&self, request: Request) -> Result<Value, RpcErr> {
|
||||
let _req = CreateAccountRequest::parse(Some(request.params))?;
|
||||
|
||||
@ -161,24 +73,6 @@ 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))?;
|
||||
|
||||
@ -349,406 +243,14 @@ impl JsonHandler {
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
pub async fn process_write_mint_utxo(&self, request: Request) -> Result<Value, RpcErr> {
|
||||
let req = WriteMintPrivateUTXORequest::parse(Some(request.params))?;
|
||||
|
||||
let acc_addr_hex_dec = hex::decode(req.account_addr.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode account address from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse account address from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let (utxo, commitment_hash) = {
|
||||
let mut cover_guard = self.node_chain_store.lock().await;
|
||||
|
||||
cover_guard
|
||||
.operate_account_mint_private(acc_addr, req.amount as u128)
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?
|
||||
};
|
||||
|
||||
let helperstruct = WriteMintPrivateUTXOResponse {
|
||||
status: SUCCESS.to_string(),
|
||||
utxo: UTXOShortEssentialStruct {
|
||||
hash: hex::encode(utxo.hash),
|
||||
commitment_hash: hex::encode(commitment_hash),
|
||||
asset: utxo.asset,
|
||||
},
|
||||
};
|
||||
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
pub async fn process_write_mint_utxo_multiple_assets(
|
||||
&self,
|
||||
request: Request,
|
||||
) -> Result<Value, RpcErr> {
|
||||
let req = WriteMintPrivateUTXOMultipleAssetsRequest::parse(Some(request.params))?;
|
||||
|
||||
let acc_addr_hex_dec = hex::decode(req.account_addr.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode account address from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse account address from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let (utxos, commitment_hashes) = {
|
||||
let mut cover_guard = self.node_chain_store.lock().await;
|
||||
|
||||
cover_guard
|
||||
.operate_account_mint_multiple_assets_private(
|
||||
acc_addr,
|
||||
req.amount as u128,
|
||||
req.num_of_assets,
|
||||
)
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?
|
||||
};
|
||||
|
||||
let helperstruct = WriteMintPrivateUTXOMultipleAssetsResponse {
|
||||
status: SUCCESS.to_string(),
|
||||
utxos: utxos
|
||||
.into_iter()
|
||||
.zip(commitment_hashes)
|
||||
.map(|(utxo, comm_hash)| UTXOShortEssentialStruct {
|
||||
hash: hex::encode(utxo.hash),
|
||||
commitment_hash: hex::encode(comm_hash),
|
||||
asset: utxo.asset,
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
pub async fn process_write_send_private_utxo(&self, request: Request) -> Result<Value, RpcErr> {
|
||||
let req = WriteSendPrivateUTXORequest::parse(Some(request.params))?;
|
||||
|
||||
let acc_addr_hex_dec_sender =
|
||||
hex::decode(req.account_addr_sender.clone()).map_err(|_| {
|
||||
RpcError::parse_error(
|
||||
"Failed to decode account address from hex string".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let acc_addr_sender: [u8; 32] = acc_addr_hex_dec_sender.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse account address from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let acc_addr_hex_dec = hex::decode(req.account_addr_receiver.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode account address from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse account address from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let utxo_hash_hex_dec = hex::decode(req.utxo_hash.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode utxo hash from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let utxo_hash: [u8; 32] = utxo_hash_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse utxo hash from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let comm_hash_hex_dec = hex::decode(req.utxo_commitment.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode commitment hash from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let comm_hash: [u8; 32] = comm_hash_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse commitment hash from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let new_utxo_rec = {
|
||||
let mut cover_guard = self.node_chain_store.lock().await;
|
||||
|
||||
let utxo_to_send = {
|
||||
let mut under_guard = cover_guard.storage.write().await;
|
||||
|
||||
let acc = under_guard
|
||||
.acc_map
|
||||
.get_mut(&acc_addr_sender)
|
||||
.ok_or(RpcError::new_internal_error(None, ACCOUNT_NOT_FOUND))?;
|
||||
|
||||
acc.utxos
|
||||
.get(&utxo_hash)
|
||||
.ok_or(RpcError::new_internal_error(
|
||||
None,
|
||||
"UTXO does not exist in tree",
|
||||
))?
|
||||
.clone()
|
||||
};
|
||||
|
||||
cover_guard
|
||||
.operate_account_send_private_one_receiver(acc_addr, utxo_to_send, comm_hash)
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?
|
||||
};
|
||||
|
||||
let helperstruct = WriteSendPrivateUTXOResponse {
|
||||
status: SUCCESS.to_string(),
|
||||
utxo_result: UTXOShortEssentialStruct {
|
||||
hash: hex::encode(new_utxo_rec.hash),
|
||||
asset: new_utxo_rec.asset.clone(),
|
||||
commitment_hash: hex::encode(generate_commitments_helper(&[new_utxo_rec])[0]),
|
||||
},
|
||||
};
|
||||
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
pub async fn process_write_send_shielded_utxo(
|
||||
&self,
|
||||
request: Request,
|
||||
) -> Result<Value, RpcErr> {
|
||||
let req = WriteSendShieldedUTXORequest::parse(Some(request.params))?;
|
||||
|
||||
let acc_addr_hex_dec_sender =
|
||||
hex::decode(req.account_addr_sender.clone()).map_err(|_| {
|
||||
RpcError::parse_error(
|
||||
"Failed to decode account address sender from hex string".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let acc_addr_sender: [u8; 32] = acc_addr_hex_dec_sender.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse account address sender from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let acc_addr_hex_dec_rec =
|
||||
hex::decode(req.account_addr_receiver.clone()).map_err(|_| {
|
||||
RpcError::parse_error(
|
||||
"Failed to decode account address receiver from hex string".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let acc_addr_rec: [u8; 32] = acc_addr_hex_dec_rec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse account address receiver from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let new_utxo_rec = {
|
||||
let mut cover_guard = self.node_chain_store.lock().await;
|
||||
|
||||
cover_guard
|
||||
.operate_account_send_shielded_one_receiver(
|
||||
acc_addr_sender,
|
||||
acc_addr_rec,
|
||||
req.amount as u128,
|
||||
)
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?
|
||||
};
|
||||
|
||||
let helperstruct = WriteSendShieldedUTXOResponse {
|
||||
status: SUCCESS.to_string(),
|
||||
utxo_result: UTXOShortEssentialStruct {
|
||||
hash: hex::encode(new_utxo_rec.hash),
|
||||
asset: new_utxo_rec.asset.clone(),
|
||||
commitment_hash: hex::encode(generate_commitments_helper(&[new_utxo_rec])[0]),
|
||||
},
|
||||
};
|
||||
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
pub async fn process_write_send_deshielded_utxo(
|
||||
&self,
|
||||
request: Request,
|
||||
) -> Result<Value, RpcErr> {
|
||||
let req = WriteSendDeshieldedBalanceRequest::parse(Some(request.params))?;
|
||||
|
||||
let acc_addr_hex_dec_sender =
|
||||
hex::decode(req.account_addr_sender.clone()).map_err(|_| {
|
||||
RpcError::parse_error(
|
||||
"Failed to decode account address from hex string".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let acc_addr_sender: [u8; 32] = acc_addr_hex_dec_sender.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse account address from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let acc_addr_hex_dec = hex::decode(req.account_addr_receiver.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode account address from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let acc_addr: [u8; 32] = acc_addr_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse account address from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let utxo_hash_hex_dec = hex::decode(req.utxo_hash.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode utxo hash from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let utxo_hash: [u8; 32] = utxo_hash_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse utxo hash from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let comm_hash_hex_dec = hex::decode(req.utxo_commitment.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode commitment hash from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let comm_hash: [u8; 32] = comm_hash_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse commitment hash from bytes".to_string())
|
||||
})?;
|
||||
|
||||
{
|
||||
let mut cover_guard = self.node_chain_store.lock().await;
|
||||
|
||||
let utxo_to_send = {
|
||||
let mut under_guard = cover_guard.storage.write().await;
|
||||
|
||||
let acc = under_guard
|
||||
.acc_map
|
||||
.get_mut(&acc_addr_sender)
|
||||
.ok_or(RpcError::new_internal_error(None, ACCOUNT_NOT_FOUND))?;
|
||||
|
||||
acc.utxos
|
||||
.get(&utxo_hash)
|
||||
.ok_or(RpcError::new_internal_error(
|
||||
None,
|
||||
"UTXO does not exist in tree",
|
||||
))?
|
||||
.clone()
|
||||
};
|
||||
|
||||
cover_guard
|
||||
.operate_account_send_deshielded_one_receiver(acc_addr, utxo_to_send, comm_hash)
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?
|
||||
};
|
||||
|
||||
let helperstruct = WriteSendDeshieldedUTXOResponse {
|
||||
status: SUCCESS.to_string(),
|
||||
};
|
||||
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
pub async fn process_write_send_split_utxo(&self, request: Request) -> Result<Value, RpcErr> {
|
||||
let req = WriteSplitUTXORequest::parse(Some(request.params))?;
|
||||
|
||||
let acc_addr_hex_dec_sender =
|
||||
hex::decode(req.account_addr_sender.clone()).map_err(|_| {
|
||||
RpcError::parse_error(
|
||||
"Failed to decode account address from hex string".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let acc_addr_sender: [u8; 32] = acc_addr_hex_dec_sender.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse account address from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let acc_addresses = {
|
||||
let mut res_addrs = vec![];
|
||||
|
||||
for item in req.account_addr_receivers {
|
||||
let hex_dec_item = hex::decode(item).map_err(|_| {
|
||||
RpcError::parse_error(
|
||||
"Failed to decode account address from hex string".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let dec_item = hex_dec_item.try_into().map_err(|_| {
|
||||
RpcError::parse_error(
|
||||
"Failed to decode account address from hex string".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
res_addrs.push(dec_item);
|
||||
}
|
||||
|
||||
res_addrs.try_into().unwrap()
|
||||
};
|
||||
|
||||
let utxo_hash_hex_dec = hex::decode(req.utxo_hash.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode utxo hash from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let utxo_hash: [u8; 32] = utxo_hash_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse utxo hash from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let comm_hash_hex_dec = hex::decode(req.utxo_commitment.clone()).map_err(|_| {
|
||||
RpcError::parse_error("Failed to decode commitment hash from hex string".to_string())
|
||||
})?;
|
||||
|
||||
let comm_hash: [u8; 32] = comm_hash_hex_dec.try_into().map_err(|_| {
|
||||
RpcError::parse_error("Failed to parse commitment hash from bytes".to_string())
|
||||
})?;
|
||||
|
||||
let (new_utxos, commitment_hashes) = {
|
||||
let mut cover_guard = self.node_chain_store.lock().await;
|
||||
|
||||
let utxo_to_send = {
|
||||
let mut under_guard = cover_guard.storage.write().await;
|
||||
|
||||
let acc = under_guard
|
||||
.acc_map
|
||||
.get_mut(&acc_addr_sender)
|
||||
.ok_or(RpcError::new_internal_error(None, ACCOUNT_NOT_FOUND))?;
|
||||
|
||||
acc.utxos
|
||||
.get(&utxo_hash)
|
||||
.ok_or(RpcError::new_internal_error(
|
||||
None,
|
||||
"UTXO does not exist in tree",
|
||||
))?
|
||||
.clone()
|
||||
};
|
||||
|
||||
cover_guard
|
||||
.operate_account_send_split_utxo(
|
||||
acc_addresses,
|
||||
utxo_to_send,
|
||||
comm_hash,
|
||||
req.visibility_list,
|
||||
)
|
||||
.await
|
||||
.map_err(cast_common_execution_error_into_rpc_error)?
|
||||
};
|
||||
|
||||
let helperstruct = WriteSendSplitUTXOResponse {
|
||||
status: SUCCESS.to_string(),
|
||||
utxo_results: new_utxos
|
||||
.into_iter()
|
||||
.zip(commitment_hashes)
|
||||
.map(|(utxo, comm_hash)| UTXOShortEssentialStruct {
|
||||
hash: hex::encode(utxo.hash),
|
||||
commitment_hash: hex::encode(comm_hash),
|
||||
asset: utxo.asset,
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
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
|
||||
CREATE_ACCOUNT => self.process_create_account(request).await,
|
||||
EXECUTE_SUBSCENARIO => self.process_request_execute_subscenario(request).await,
|
||||
GET_BLOCK => self.process_get_block_data(request).await,
|
||||
GET_LAST_BLOCK => self.process_get_last_block(request).await,
|
||||
EXECUTE_SCENARIO_SPLIT => self.process_request_execute_scenario_split(request).await,
|
||||
EXECUTE_SCENARIO_MULTIPLE_SEND => {
|
||||
self.process_request_execute_scenario_multiple_send(request)
|
||||
.await
|
||||
}
|
||||
SHOW_ACCOUNT_PUBLIC_BALANCE => self.process_show_account_public_balance(request).await,
|
||||
SHOW_ACCOUNT_UTXO => self.process_show_account_utxo_request(request).await,
|
||||
SHOW_TRANSACTION => self.process_show_transaction(request).await,
|
||||
WRITE_MINT_UTXO => self.process_write_mint_utxo(request).await,
|
||||
WRITE_MINT_UTXO_MULTIPLE_ASSETS => {
|
||||
self.process_write_mint_utxo_multiple_assets(request).await
|
||||
}
|
||||
WRITE_SEND_UTXO_PRIVATE => self.process_write_send_private_utxo(request).await,
|
||||
WRITE_SEND_UTXO_SHIELDED => self.process_write_send_shielded_utxo(request).await,
|
||||
WRITE_SEND_UTXO_DESHIELDED => self.process_write_send_deshielded_utxo(request).await,
|
||||
WRITE_SPLIT_UTXO => self.process_write_send_split_utxo(request).await,
|
||||
_ => Err(RpcErr(RpcError::method_not_found(request.method))),
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user