fix: final subcenario version

This commit is contained in:
Oleksandr Pravdyvyi 2024-12-26 11:38:00 +02:00
parent 9905acfb45
commit faa782b982
7 changed files with 218 additions and 155 deletions

2
Cargo.lock generated
View File

@ -145,6 +145,7 @@ version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208"
dependencies = [
"actix-macros",
"futures-core",
"tokio",
]
@ -2670,6 +2671,7 @@ name = "node_core"
version = "0.1.0"
dependencies = [
"accounts",
"actix-rt",
"anyhow",
"bincode",
"elliptic-curve",

View File

@ -27,6 +27,7 @@ serde_json = "1.0.81"
actix = "0.13.0"
actix-cors = "0.6.1"
futures = "0.3"
actix-rt = "*"
env_logger = "0.10"
log = "0.4"

View File

@ -21,6 +21,7 @@ tokio.workspace = true
tempfile.workspace = true
risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-1.2" }
hex.workspace = true
actix-rt.workspace = true
[dependencies.accounts]
path = "../accounts"

View File

@ -142,8 +142,13 @@ impl NodeCore {
addr
}
pub async fn mint_utxo_private(&self, acc: AccountAddress, amount: u128) -> Transaction {
pub async fn mint_utxo_private(
&self,
acc: AccountAddress,
amount: u128,
) -> (Transaction, [u8; 32]) {
let (utxo, receipt) = prove_mint_utxo(amount, acc);
let result_hash = utxo.hash;
let acc_map_read_guard = self.storage.read().await;
@ -161,21 +166,24 @@ impl NodeCore {
let comm = generate_commitments(&vec![utxo]);
TransactionPayload {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
utxo_commitments_spent_hashes: vec![],
utxo_commitments_created_hashes: comm
.into_iter()
.map(|hash_data| hash_data.try_into().unwrap())
.collect(),
nullifier_created_hashes: vec![],
execution_proof_private: serde_json::to_string(&receipt).unwrap(),
encoded_data: vec![(encoded_data.0, encoded_data.1.to_vec())],
ephemeral_pub_key: eph_pub_key.to_vec(),
}
.into()
(
TransactionPayload {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
utxo_commitments_spent_hashes: vec![],
utxo_commitments_created_hashes: comm
.into_iter()
.map(|hash_data| hash_data.try_into().unwrap())
.collect(),
nullifier_created_hashes: vec![],
execution_proof_private: serde_json::to_string(&receipt).unwrap(),
encoded_data: vec![(encoded_data.0, encoded_data.1.to_vec())],
ephemeral_pub_key: eph_pub_key.to_vec(),
}
.into(),
result_hash,
)
}
pub fn deposit_money_public(&self, acc: AccountAddress, amount: u128) -> Transaction {
@ -200,7 +208,7 @@ impl NodeCore {
&self,
utxo: UTXO,
receivers: Vec<(u128, AccountAddress)>,
) -> Transaction {
) -> (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();
@ -222,6 +230,10 @@ impl NodeCore {
);
let (resulting_utxos, receipt) = prove_send_utxo(utxo, receivers);
let utxo_hashes = resulting_utxos
.iter()
.map(|(utxo, addr)| (addr.clone(), utxo.hash))
.collect();
let utxos: Vec<UTXO> = resulting_utxos
.iter()
@ -249,21 +261,24 @@ impl NodeCore {
let commitments = generate_commitments(&utxos);
TransactionPayload {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
utxo_commitments_spent_hashes: vec![commitment_in],
utxo_commitments_created_hashes: commitments
.into_iter()
.map(|hash_data| hash_data.try_into().unwrap())
.collect(),
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
execution_proof_private: serde_json::to_string(&receipt).unwrap(),
encoded_data,
ephemeral_pub_key: eph_pub_key.to_vec(),
}
.into()
(
TransactionPayload {
tx_kind: TxKind::Private,
execution_input: vec![],
execution_output: vec![],
utxo_commitments_spent_hashes: vec![commitment_in],
utxo_commitments_created_hashes: commitments
.into_iter()
.map(|hash_data| hash_data.try_into().unwrap())
.collect(),
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
execution_proof_private: serde_json::to_string(&receipt).unwrap(),
encoded_data,
ephemeral_pub_key: eph_pub_key.to_vec(),
}
.into(),
utxo_hashes,
)
}
pub async fn transfer_balance_shielded(
@ -271,7 +286,7 @@ impl NodeCore {
acc: AccountAddress,
balance: u64,
receivers: Vec<(u128, AccountAddress)>,
) -> Transaction {
) -> (Transaction, Vec<(AccountAddress, [u8; 32])>) {
let acc_map_read_guard = self.storage.read().await;
let accout = acc_map_read_guard.acc_map.get(&acc).unwrap();
@ -304,6 +319,10 @@ impl NodeCore {
);
let (resulting_utxos, receipt) = prove_send_utxo_shielded(acc, balance as u128, receivers);
let utxo_hashes = resulting_utxos
.iter()
.map(|(utxo, addr)| (addr.clone(), utxo.hash))
.collect();
let utxos: Vec<UTXO> = resulting_utxos
.iter()
@ -331,27 +350,30 @@ impl NodeCore {
let commitments = generate_commitments(&utxos);
TransactionPayload {
tx_kind: TxKind::Private,
execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx(
SendMoneyShieldedTx {
acc_sender: acc,
amount: balance as u128,
},
))
.unwrap(),
execution_output: vec![],
utxo_commitments_spent_hashes: vec![],
utxo_commitments_created_hashes: commitments
.into_iter()
.map(|hash_data| hash_data.try_into().unwrap())
.collect(),
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
execution_proof_private: serde_json::to_string(&receipt).unwrap(),
encoded_data,
ephemeral_pub_key: eph_pub_key.to_vec(),
}
.into()
(
TransactionPayload {
tx_kind: TxKind::Private,
execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx(
SendMoneyShieldedTx {
acc_sender: acc,
amount: balance as u128,
},
))
.unwrap(),
execution_output: vec![],
utxo_commitments_spent_hashes: vec![],
utxo_commitments_created_hashes: commitments
.into_iter()
.map(|hash_data| hash_data.try_into().unwrap())
.collect(),
nullifier_created_hashes: vec![nullifier.try_into().unwrap()],
execution_proof_private: serde_json::to_string(&receipt).unwrap(),
encoded_data,
ephemeral_pub_key: eph_pub_key.to_vec(),
}
.into(),
utxo_hashes,
)
}
pub async fn transfer_utxo_deshielded(
@ -379,14 +401,14 @@ impl NodeCore {
.to_vec(),
);
let (resulting_utxos, receipt) = prove_send_utxo_deshielded(utxo, receivers);
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(
SendMoneyDeshieldedTx {
receiver_data: resulting_utxos,
receiver_data: resulting_balances,
},
))
.unwrap(),
@ -404,11 +426,15 @@ impl NodeCore {
&self,
acc: AccountAddress,
amount: u128,
) -> Result<SendTxResponse> {
Ok(self
.sequencer_client
.send_tx(self.mint_utxo_private(acc, amount).await)
.await?)
) -> Result<(SendTxResponse, [u8; 32])> {
let point_before_prove = std::time::Instant::now();
let (tx, utxo_hash) = self.mint_utxo_private(acc, amount).await;
let point_after_prove = std::time::Instant::now();
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))
}
pub async fn send_public_deposit(
@ -426,11 +452,15 @@ impl NodeCore {
&self,
utxo: UTXO,
receivers: Vec<(u128, AccountAddress)>,
) -> Result<SendTxResponse> {
Ok(self
.sequencer_client
.send_tx(self.transfer_utxo_private(utxo, receivers).await)
.await?)
) -> 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 point_after_prove = std::time::Instant::now();
let timedelta = (point_after_prove - point_before_prove).as_millis();
info!("Send private utxo proof spent {timedelta:?} milliseconds");
Ok((self.sequencer_client.send_tx(tx).await?, utxo_hashes))
}
pub async fn send_shielded_send_tx(
@ -438,11 +468,15 @@ impl NodeCore {
acc: AccountAddress,
amount: u64,
receivers: Vec<(u128, AccountAddress)>,
) -> Result<SendTxResponse> {
Ok(self
.sequencer_client
.send_tx(self.transfer_balance_shielded(acc, amount, receivers).await)
.await?)
) -> 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;
let point_after_prove = std::time::Instant::now();
let timedelta = (point_after_prove - point_before_prove).as_millis();
info!("Send balance shielded proof spent {timedelta:?} milliseconds");
Ok((self.sequencer_client.send_tx(tx).await?, utxo_hashes))
}
pub async fn send_deshielded_send_tx(
@ -450,24 +484,23 @@ impl NodeCore {
utxo: UTXO,
receivers: Vec<(u128, AccountAddress)>,
) -> Result<SendTxResponse> {
Ok(self
.sequencer_client
.send_tx(self.transfer_utxo_deshielded(utxo, receivers).await)
.await?)
let point_before_prove = std::time::Instant::now();
let tx = self.transfer_utxo_deshielded(utxo, receivers).await;
let point_after_prove = std::time::Instant::now();
let timedelta = (point_after_prove - point_before_prove).as_millis();
info!("Send deshielded utxo proof spent {timedelta:?} milliseconds");
Ok(self.sequencer_client.send_tx(tx).await?)
}
///Mint utxo, make it public
pub async fn subscenario_1(&mut self) {
let acc_addr = self.create_new_account().await;
let resp = self.send_private_mint_tx(acc_addr, 100).await.unwrap();
let (resp, new_utxo_hash) = self.send_private_mint_tx(acc_addr, 100).await.unwrap();
info!("Response for mint private is {resp:?}");
let new_utxo_hash: [u8; 32] = hex::decode(resp.additional_data.unwrap())
.unwrap()
.try_into()
.unwrap();
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
@ -512,16 +545,13 @@ impl NodeCore {
info!("New acconut public balance is {:?}", acc.balance);
let resp = self
let (resp, new_utxo_hashes) = self
.send_shielded_send_tx(acc_addr, 100, vec![(100, acc_addr)])
.await
.unwrap();
info!("Response for send shielded is {resp:?}");
let new_utxo_hash: [u8; 32] = hex::decode(resp.additional_data.unwrap())
.unwrap()
.try_into()
.unwrap();
let new_utxo_hash = new_utxo_hashes[0].1;
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
@ -545,14 +575,9 @@ impl NodeCore {
let acc_addr = self.create_new_account().await;
let acc_addr_rec = self.create_new_account().await;
let resp = self.send_private_mint_tx(acc_addr, 100).await.unwrap();
let (resp, new_utxo_hash) = self.send_private_mint_tx(acc_addr, 100).await.unwrap();
info!("Response for mint private is {resp:?}");
let new_utxo_hash: [u8; 32] = hex::decode(resp.additional_data.unwrap())
.unwrap()
.try_into()
.unwrap();
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
@ -568,16 +593,13 @@ impl NodeCore {
.clone()
};
let resp = self
let (resp, new_utxo_hashes) = self
.send_private_send_tx(new_utxo, vec![(100, acc_addr_rec)])
.await
.unwrap();
info!("Response for send deshielded is {resp:?}");
let new_utxo_hash: [u8; 32] = hex::decode(resp.additional_data.unwrap())
.unwrap()
.try_into()
.unwrap();
let new_utxo_hash = new_utxo_hashes[0].1;
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
@ -613,16 +635,13 @@ impl NodeCore {
info!("New acconut public balance is {:?}", acc.balance);
let resp = self
let (resp, new_utxo_hashes) = self
.send_shielded_send_tx(acc_addr, 100, vec![(100, acc_addr_rec)])
.await
.unwrap();
info!("Response for send shielded is {resp:?}");
let new_utxo_hash: [u8; 32] = hex::decode(resp.additional_data.unwrap())
.unwrap()
.try_into()
.unwrap();
let new_utxo_hash = new_utxo_hashes[0].1;
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
@ -642,46 +661,41 @@ impl NodeCore {
info!("User {acc_addr_rec:?} received new utxo {new_utxo:?}");
}
///Mint utxo, deshielded send it to another user
pub async fn subscenario_5(&mut self) {
let acc_addr = self.create_new_account().await;
let acc_addr_rec = self.create_new_account().await;
let resp = self.send_private_mint_tx(acc_addr, 100).await.unwrap();
info!("Response for mint private is {resp:?}");
let new_utxo_hash: [u8; 32] = hex::decode(resp.additional_data.unwrap())
///Mint utxo, deshielded send it to another user
pub async fn subscenario_5(&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();
info!("Response for mint private is {resp:?}");
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
let new_utxo = {
let mut write_guard = self.storage.write().await;
let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap();
acc.utxo_tree
.get_item(new_utxo_hash)
.unwrap()
.try_into()
.unwrap();
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
let new_utxo = {
let mut write_guard = self.storage.write().await;
let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap();
acc.utxo_tree
.get_item(new_utxo_hash)
.unwrap()
.unwrap()
.clone()
};
let resp = self
.send_deshielded_send_tx(new_utxo, vec![(100, acc_addr_rec)])
.await
.unwrap();
info!("Response for send deshielded is {resp:?}");
info!("Awaiting new blocks");
tokio::time::sleep(std::time::Duration::from_secs(BLOCK_GEN_DELAY_SECS)).await;
.unwrap()
.clone()
};
let read_guard = self.storage.read().await;
let acc_rec = read_guard.acc_map.get(&acc_addr_rec).unwrap();
let resp = self
.send_deshielded_send_tx(new_utxo, vec![(100, acc_addr_rec)])
.await
.unwrap();
info!("Response for send deshielded is {resp:?}");
info!("New account public balance is {:?}", acc_rec.balance);
}
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();
info!("New account public balance is {:?}", acc_rec.balance);
}
}

View File

@ -70,8 +70,9 @@ impl NodeChainStore {
.collect(),
)?;
let slice_try: Result<[u8; 33],_> = tx.ephemeral_pub_key.clone().try_into();
let eph_key_compressed = slice_try.and_then(|inner| Ok(<AffinePoint as GroupEncoding>::Repr::from(inner)));
let slice_try: Result<[u8; 33], _> = tx.ephemeral_pub_key.clone().try_into();
let eph_key_compressed =
slice_try.and_then(|inner| Ok(<AffinePoint as GroupEncoding>::Repr::from(inner)));
if let Ok(eph_key_compressed) = eph_key_compressed {
let ephemeral_public_key_sender = AffinePoint::from_bytes(&eph_key_compressed);
@ -80,22 +81,28 @@ impl NodeChainStore {
let ephemeral_public_key_sender = ephemeral_public_key_sender.unwrap();
for (ciphertext, nonce) in tx.encoded_data.clone() {
let slice = nonce.as_slice();
let nonce =
accounts::key_management::constants_types::Nonce::clone_from_slice(
slice,
);
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() {
let decoded_data_curr_acc = acc.decrypt_data(
ephemeral_public_key_sender,
ciphertext.clone(),
nonce,
);
for (acc_id, acc) in self.acc_map.iter_mut() {
let decoded_data_curr_acc =
acc.decrypt_data(ephemeral_public_key_sender, ciphertext.clone(), nonce);
let decoded_utxo_try = serde_json::from_slice::<UTXO>(&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

@ -11,7 +11,10 @@ use crate::{
rpc_error_responce_inverter,
types::{
err_rpc::cast_seq_client_error_into_rpc_error,
rpc_structs::{RegisterAccountRequest, RegisterAccountResponse, SendTxRequest},
rpc_structs::{
ExecuteSubscenarioRequest, ExecuteSubscenarioResponse, RegisterAccountRequest,
RegisterAccountResponse, SendTxRequest,
},
},
};
@ -34,6 +37,29 @@ 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,
2 => store.subscenario_2().await,
3 => store.subscenario_3().await,
4 => store.subscenario_4().await,
5 => store.subscenario_5().await,
_ => return Err(RpcErr(RpcError::invalid_params("Scenario id not found"))),
}
}
let helperstruct = ExecuteSubscenarioResponse {
scenario_result: "success".to_string(),
};
respond(helperstruct)
}
async fn process_register_account(&self, request: Request) -> Result<Value, RpcErr> {
let _req = RegisterAccountRequest::parse(Some(request.params))?;
@ -74,6 +100,7 @@ impl JsonHandler {
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,
_ => Err(RpcErr(RpcError::method_not_found(request.method))),
}

View File

@ -20,6 +20,11 @@ pub struct GetBlockDataRequest {
pub block_id: u64,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct ExecuteSubscenarioRequest {
pub scenario_id: u64,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetGenesisIdRequest {}
@ -27,6 +32,7 @@ parse_request!(RegisterAccountRequest);
parse_request!(SendTxRequest);
parse_request!(GetBlockDataRequest);
parse_request!(GetGenesisIdRequest);
parse_request!(ExecuteSubscenarioRequest);
#[derive(Serialize, Deserialize, Debug)]
pub struct HelloResponse {
@ -48,6 +54,11 @@ pub struct GetBlockDataResponse {
pub block: Block,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct ExecuteSubscenarioResponse {
pub scenario_result: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetGenesisIdResponse {
pub genesis_id: u64,