Merge branch 'main' into Pravdyvy/fixed-error-propagation

This commit is contained in:
Oleksandr Pravdyvyi 2025-02-14 10:49:34 +02:00
commit 620aefec23
17 changed files with 127 additions and 212 deletions

2
Cargo.lock generated
View File

@ -3839,8 +3839,10 @@ dependencies = [
"anyhow", "anyhow",
"env_logger", "env_logger",
"log", "log",
"sequencer_core",
"serde", "serde",
"serde_json", "serde_json",
"storage",
] ]
[[package]] [[package]]

View File

@ -110,7 +110,7 @@ impl Account {
privacy_flag, privacy_flag,
}; };
let asset_utxo = UTXO::create_utxo_from_payload(payload_with_asset); let asset_utxo = UTXO::create_utxo_from_payload(payload_with_asset)?;
self.utxo_tree.insert_item(asset_utxo)?; self.utxo_tree.insert_item(asset_utxo)?;
@ -138,7 +138,7 @@ mod tests {
UTXONullifier::default() UTXONullifier::default()
} }
fn generate_dummy_utxo(address: TreeHashType, amount: u128) -> UTXO { fn generate_dummy_utxo(address: TreeHashType, amount: u128) -> anyhow::Result<UTXO> {
let payload = UTXOPayload { let payload = UTXOPayload {
owner: address, owner: address,
asset: vec![], asset: vec![],
@ -159,7 +159,7 @@ mod tests {
#[test] #[test]
fn test_mark_spent_utxo() { fn test_mark_spent_utxo() {
let mut account = Account::new(); let mut account = Account::new();
let utxo = generate_dummy_utxo(account.address, 100); let utxo = generate_dummy_utxo(account.address, 100).unwrap();
account.add_new_utxo_outputs(vec![utxo]).unwrap(); account.add_new_utxo_outputs(vec![utxo]).unwrap();
let mut utxo_nullifier_map = HashMap::new(); let mut utxo_nullifier_map = HashMap::new();
@ -174,8 +174,8 @@ mod tests {
#[test] #[test]
fn test_add_new_utxo_outputs() { fn test_add_new_utxo_outputs() {
let mut account = Account::new(); let mut account = Account::new();
let utxo1 = generate_dummy_utxo(account.address, 100); let utxo1 = generate_dummy_utxo(account.address, 100).unwrap();
let utxo2 = generate_dummy_utxo(account.address, 200); let utxo2 = generate_dummy_utxo(account.address, 200).unwrap();
let result = account.add_new_utxo_outputs(vec![utxo1.clone(), utxo2.clone()]); let result = account.add_new_utxo_outputs(vec![utxo1.clone(), utxo2.clone()]);

View File

@ -8,7 +8,7 @@ use k256::elliptic_curve::group::GroupEncoding;
use ::storage::transaction::{Transaction, TransactionPayload, TxKind}; use ::storage::transaction::{Transaction, TransactionPayload, TxKind};
use accounts::account_core::{Account, AccountAddress}; use accounts::account_core::{Account, AccountAddress};
use anyhow::Result; use anyhow::{anyhow, Result};
use config::NodeConfig; use config::NodeConfig;
use executions::{ use executions::{
private_exec::{generate_commitments, generate_nullifiers}, private_exec::{generate_commitments, generate_nullifiers},
@ -476,7 +476,8 @@ impl NodeCore {
.to_bytes() .to_bytes()
.to_vec(), .to_vec(),
) )
.unwrap(), .map_err(|err| anyhow!("{:?}", err))
.map_err(ExecutionFailureKind::write_error)?,
generator_blinding_factor: Tweak::new(&mut thread_rng()), generator_blinding_factor: Tweak::new(&mut thread_rng()),
}; };
@ -782,11 +783,7 @@ impl NodeCore {
let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap(); let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap();
acc.utxo_tree acc.utxo_tree.get_item(new_utxo_hash)?.unwrap().clone()
.get_item(new_utxo_hash)
.unwrap()
.unwrap()
.clone()
}; };
new_utxo.log(); new_utxo.log();
@ -963,11 +960,7 @@ impl NodeCore {
let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap(); let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap();
acc.log(); acc.log();
acc.utxo_tree acc.utxo_tree.get_item(new_utxo_hash)?.unwrap().clone()
.get_item(new_utxo_hash)
.unwrap()
.unwrap()
.clone()
}; };
new_utxo.log(); new_utxo.log();
info!( info!(
@ -1007,11 +1000,7 @@ impl NodeCore {
let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap(); let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap();
acc.log(); acc.log();
acc.utxo_tree acc.utxo_tree.get_item(new_utxo_hash)?.unwrap().clone()
.get_item(new_utxo_hash)
.unwrap()
.unwrap()
.clone()
}; };
new_utxo.log(); new_utxo.log();
info!( info!(
@ -1056,12 +1045,7 @@ impl NodeCore {
let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap(); let acc = write_guard.acc_map.get_mut(&acc_addr_rec).unwrap();
acc.log(); acc.log();
let new_utxo = acc let new_utxo = acc.utxo_tree.get_item(new_utxo_hash)?.unwrap().clone();
.utxo_tree
.get_item(new_utxo_hash)
.unwrap()
.unwrap()
.clone();
new_utxo.log(); new_utxo.log();
info!( info!(
@ -1081,12 +1065,7 @@ impl NodeCore {
let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap(); let acc = write_guard.acc_map.get_mut(&acc_addr).unwrap();
acc.log(); acc.log();
let new_utxo = acc let new_utxo = acc.utxo_tree.get_item(new_utxo_hash)?.unwrap().clone();
.utxo_tree
.get_item(new_utxo_hash)
.unwrap()
.unwrap()
.clone();
new_utxo.log(); new_utxo.log();
info!( info!(

View File

@ -1,15 +1,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use storage::{block::Block, transaction::Transaction}; use storage::transaction::Transaction;
//Requests //Requests
#[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)] #[derive(Serialize, Deserialize, Debug)]
pub struct SendTxRequest { pub struct SendTxRequest {
pub transaction: Transaction, pub transaction: Transaction,
@ -17,37 +10,14 @@ pub struct SendTxRequest {
pub tx_roots: [[u8; 32]; 3], pub tx_roots: [[u8; 32]; 3],
} }
#[derive(Serialize, Deserialize, Debug)]
pub struct GetBlockDataRequest {
pub block_id: u64,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetGenesisIdRequest {}
//Responses //Responses
#[derive(Serialize, Deserialize, Debug)]
pub struct RegisterAccountResponse {
pub status: String,
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct SendTxResponse { pub struct SendTxResponse {
pub status: String, pub status: String,
pub additional_data: Option<String>, pub additional_data: Option<String>,
} }
#[derive(Serialize, Deserialize, Debug)]
pub struct GetBlockDataResponse {
pub block: Block,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetGenesisIdResponse {
pub genesis_id: u64,
}
//General //General
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]

View File

@ -8,6 +8,10 @@ use json::{
}; };
use k256::elliptic_curve::group::GroupEncoding; use k256::elliptic_curve::group::GroupEncoding;
use reqwest::Client; use reqwest::Client;
use rpc_primitives::requests::{
GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
RegisterAccountRequest, RegisterAccountResponse,
};
use serde_json::Value; use serde_json::Value;
use storage::transaction::Transaction; use storage::transaction::Transaction;

View File

@ -11,23 +11,23 @@ use rpc_primitives::{
}; };
use storage::transaction::ActionData; use storage::transaction::ActionData;
use crate::types::{ use rpc_primitives::requests::{
err_rpc::cast_common_execution_error_into_rpc_error, GetBlockDataRequest, GetBlockDataResponse, GetLastBlockRequest, GetLastBlockResponse,
rpc_structs::{ RegisterAccountRequest, RegisterAccountResponse,
ExecuteScenarioMultipleSendRequest, ExecuteScenarioMultipleSendResponse, };
ExecuteScenarioSplitRequest, ExecuteScenarioSplitResponse, ExecuteSubscenarioRequest,
ExecuteSubscenarioResponse, GetBlockDataRequest, GetBlockDataResponse, GetLastBlockRequest, use crate::types::rpc_structs::{
GetLastBlockResponse, RegisterAccountRequest, RegisterAccountResponse, ExecuteScenarioMultipleSendRequest, ExecuteScenarioMultipleSendResponse,
ShowAccountPublicBalanceRequest, ShowAccountPublicBalanceResponse, ShowAccountUTXORequest, ExecuteScenarioSplitRequest, ExecuteScenarioSplitResponse, ExecuteSubscenarioRequest,
ShowAccountUTXOResponse, ShowTransactionRequest, ShowTransactionResponse, ExecuteSubscenarioResponse, ShowAccountPublicBalanceRequest, ShowAccountPublicBalanceResponse,
UTXOShortEssentialStruct, WriteDepositPublicBalanceRequest, ShowAccountUTXORequest, ShowAccountUTXOResponse, ShowTransactionRequest,
WriteDepositPublicBalanceResponse, WriteMintPrivateUTXOMultipleAssetsRequest, ShowTransactionResponse, UTXOShortEssentialStruct, WriteDepositPublicBalanceRequest,
WriteMintPrivateUTXOMultipleAssetsResponse, WriteMintPrivateUTXORequest, WriteDepositPublicBalanceResponse, WriteMintPrivateUTXOMultipleAssetsRequest,
WriteMintPrivateUTXOResponse, WriteSendDeshieldedBalanceRequest, WriteMintPrivateUTXOMultipleAssetsResponse, WriteMintPrivateUTXORequest,
WriteSendDeshieldedUTXOResponse, WriteSendPrivateUTXORequest, WriteSendPrivateUTXOResponse, WriteMintPrivateUTXOResponse, WriteSendDeshieldedBalanceRequest,
WriteSendShieldedUTXORequest, WriteSendShieldedUTXOResponse, WriteSendSplitUTXOResponse, WriteSendDeshieldedUTXOResponse, WriteSendPrivateUTXORequest, WriteSendPrivateUTXOResponse,
WriteSplitUTXORequest, WriteSendShieldedUTXORequest, WriteSendShieldedUTXOResponse, WriteSendSplitUTXOResponse,
}, WriteSplitUTXORequest,
}; };
use super::{respond, types::err_rpc::RpcErr, JsonHandler}; use super::{respond, types::err_rpc::RpcErr, JsonHandler};

View File

@ -1,3 +1,2 @@
pub mod err_rpc; pub mod err_rpc;
pub mod parse;
pub mod rpc_structs; pub mod rpc_structs;

View File

@ -1 +0,0 @@

View File

@ -4,23 +4,8 @@ use rpc_primitives::parser::parse_params;
use rpc_primitives::parser::RpcRequest; use rpc_primitives::parser::RpcRequest;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use storage::block::Block;
use storage::transaction::Transaction;
use storage::transaction::TxKind; use storage::transaction::TxKind;
#[derive(Serialize, Deserialize, Debug)]
pub struct RegisterAccountRequest {}
#[derive(Serialize, Deserialize, Debug)]
pub struct SendTxRequest {
pub transaction: Transaction,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetBlockDataRequest {
pub block_id: u64,
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ExecuteSubscenarioRequest { pub struct ExecuteSubscenarioRequest {
pub scenario_id: u64, pub scenario_id: u64,
@ -38,12 +23,6 @@ pub struct ExecuteScenarioMultipleSendRequest {
pub number_to_send: usize, pub number_to_send: usize,
} }
#[derive(Serialize, Deserialize, Debug)]
pub struct GetGenesisIdRequest {}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetLastBlockRequest {}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ShowAccountPublicBalanceRequest { pub struct ShowAccountPublicBalanceRequest {
pub account_addr: String, pub account_addr: String,
@ -111,14 +90,11 @@ pub struct WriteSplitUTXORequest {
pub utxo_commitment: String, pub utxo_commitment: String,
} }
parse_request!(RegisterAccountRequest); // parse_request!(GetGenesisIdRequest);
parse_request!(SendTxRequest);
parse_request!(GetBlockDataRequest);
parse_request!(GetGenesisIdRequest);
parse_request!(ExecuteSubscenarioRequest); parse_request!(ExecuteSubscenarioRequest);
parse_request!(ExecuteScenarioSplitRequest); parse_request!(ExecuteScenarioSplitRequest);
parse_request!(ExecuteScenarioMultipleSendRequest); parse_request!(ExecuteScenarioMultipleSendRequest);
parse_request!(GetLastBlockRequest); // parse_request!(GetLastBlockRequest);
parse_request!(ShowAccountPublicBalanceRequest); parse_request!(ShowAccountPublicBalanceRequest);
parse_request!(ShowAccountUTXORequest); parse_request!(ShowAccountUTXORequest);
@ -132,26 +108,6 @@ parse_request!(WriteSendShieldedUTXORequest);
parse_request!(WriteSendDeshieldedBalanceRequest); parse_request!(WriteSendDeshieldedBalanceRequest);
parse_request!(WriteSplitUTXORequest); parse_request!(WriteSplitUTXORequest);
#[derive(Serialize, Deserialize, Debug)]
pub struct HelloResponse {
pub greeting: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct RegisterAccountResponse {
pub status: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SendTxResponse {
pub status: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetBlockDataResponse {
pub block: Block,
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ExecuteSubscenarioResponse { pub struct ExecuteSubscenarioResponse {
pub scenario_result: String, pub scenario_result: String,
@ -167,16 +123,6 @@ pub struct ExecuteScenarioMultipleSendResponse {
pub scenario_result: String, pub scenario_result: String,
} }
#[derive(Serialize, Deserialize, Debug)]
pub struct GetGenesisIdResponse {
pub genesis_id: u64,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetLastBlockResponse {
pub last_block: u64,
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ShowAccountPublicBalanceResponse { pub struct ShowAccountPublicBalanceResponse {
pub addr: String, pub addr: String,

View File

@ -9,3 +9,9 @@ serde_json.workspace = true
env_logger.workspace = true env_logger.workspace = true
log.workspace = true log.workspace = true
serde.workspace = true serde.workspace = true
[dependencies.storage]
path = "../storage"
[dependencies.sequencer_core]
path = "../sequencer_core"

View File

@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
pub mod errors; pub mod errors;
pub mod message; pub mod message;
pub mod parser; pub mod parser;
pub mod requests;
#[derive(Serialize, Deserialize, Clone, Copy, Debug)] #[derive(Serialize, Deserialize, Clone, Copy, Debug)]
pub struct RpcPollingConfig { pub struct RpcPollingConfig {

View File

@ -1,7 +1,7 @@
use rpc_primitives::errors::RpcParseError; use crate::errors::RpcParseError;
use rpc_primitives::parse_request; use crate::parse_request;
use rpc_primitives::parser::parse_params; use crate::parser::parse_params;
use rpc_primitives::parser::RpcRequest; use crate::parser::RpcRequest;
use sequencer_core::transaction_mempool::TransactionMempool; use sequencer_core::transaction_mempool::TransactionMempool;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;

View File

@ -8,7 +8,7 @@ use rpc_primitives::{
parser::RpcRequest, parser::RpcRequest,
}; };
use crate::types::rpc_structs::{ use rpc_primitives::requests::{
GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse, GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
GetLastBlockRequest, GetLastBlockResponse, HelloRequest, HelloResponse, RegisterAccountRequest, GetLastBlockRequest, GetLastBlockResponse, HelloRequest, HelloResponse, RegisterAccountRequest,
RegisterAccountResponse, SendTxRequest, SendTxResponse, RegisterAccountResponse, SendTxRequest, SendTxResponse,

View File

@ -1,3 +1,2 @@
pub mod err_rpc; pub mod err_rpc;
pub mod parse; pub mod parse;
pub mod rpc_structs;

View File

@ -29,8 +29,8 @@ pub struct UTXOPayload {
} }
impl UTXO { impl UTXO {
pub fn create_utxo_from_payload(payload_with_asset: UTXOPayload) -> Self { pub fn create_utxo_from_payload(payload_with_asset: UTXOPayload) -> anyhow::Result<Self> {
let raw_payload = serde_json::to_vec(&payload_with_asset).unwrap(); let raw_payload = serde_json::to_vec(&payload_with_asset)?;
let mut hasher = sha2::Sha256::new(); let mut hasher = sha2::Sha256::new();
@ -38,14 +38,14 @@ impl UTXO {
let hash = <TreeHashType>::from(hasher.finalize_fixed()); let hash = <TreeHashType>::from(hasher.finalize_fixed());
Self { Ok(Self {
hash, hash,
owner: payload_with_asset.owner, owner: payload_with_asset.owner,
nullifier: None, nullifier: None,
asset: payload_with_asset.asset, asset: payload_with_asset.asset,
amount: payload_with_asset.amount, amount: payload_with_asset.amount,
privacy_flag: payload_with_asset.privacy_flag, privacy_flag: payload_with_asset.privacy_flag,
} })
} }
pub fn consume_utxo(&mut self, nullifier: UTXONullifier) -> Result<()> { pub fn consume_utxo(&mut self, nullifier: UTXONullifier) -> Result<()> {
@ -123,7 +123,7 @@ mod tests {
#[test] #[test]
fn test_create_utxo_from_payload() { fn test_create_utxo_from_payload() {
let payload = sample_payload(); let payload = sample_payload();
let utxo = UTXO::create_utxo_from_payload(payload.clone()); let utxo = UTXO::create_utxo_from_payload(payload.clone()).unwrap();
// Ensure hash is created and the UTXO fields are correctly assigned // Ensure hash is created and the UTXO fields are correctly assigned
assert_eq!(utxo.owner, payload.owner); assert_eq!(utxo.owner, payload.owner);
@ -134,7 +134,7 @@ mod tests {
#[test] #[test]
fn test_consume_utxo() { fn test_consume_utxo() {
let payload = sample_payload(); let payload = sample_payload();
let mut utxo = UTXO::create_utxo_from_payload(payload); let mut utxo = UTXO::create_utxo_from_payload(payload).unwrap();
let nullifier = sample_nullifier(); let nullifier = sample_nullifier();
@ -150,7 +150,7 @@ mod tests {
#[test] #[test]
fn test_interpret_asset() { fn test_interpret_asset() {
let payload = sample_payload(); let payload = sample_payload();
let utxo = UTXO::create_utxo_from_payload(payload); let utxo = UTXO::create_utxo_from_payload(payload).unwrap();
// Interpret asset as TestAsset // Interpret asset as TestAsset
let interpreted: TestAsset = utxo.interpret_asset().unwrap(); let interpreted: TestAsset = utxo.interpret_asset().unwrap();
@ -168,7 +168,7 @@ mod tests {
fn test_interpret_invalid_asset() { fn test_interpret_invalid_asset() {
let mut payload = sample_payload(); let mut payload = sample_payload();
payload.asset = vec![0, 1, 2, 3]; // Invalid data for deserialization payload.asset = vec![0, 1, 2, 3]; // Invalid data for deserialization
let utxo = UTXO::create_utxo_from_payload(payload); let utxo = UTXO::create_utxo_from_payload(payload).unwrap();
// This should fail because the asset is not valid JSON for TestAsset // This should fail because the asset is not valid JSON for TestAsset
let result: Result<TestAsset> = utxo.interpret_asset(); let result: Result<TestAsset> = utxo.interpret_asset();

View File

@ -88,7 +88,7 @@ mod tests {
} }
} }
fn sample_utxo() -> UTXO { fn sample_utxo() -> anyhow::Result<UTXO> {
UTXO::create_utxo_from_payload(sample_utxo_payload()) UTXO::create_utxo_from_payload(sample_utxo_payload())
} }
@ -102,7 +102,7 @@ mod tests {
#[test] #[test]
fn test_insert_item() { fn test_insert_item() {
let mut smt = UTXOSparseMerkleTree::new(); let mut smt = UTXOSparseMerkleTree::new();
let utxo = sample_utxo(); let utxo = sample_utxo().unwrap();
let result = smt.insert_item(utxo.clone()); let result = smt.insert_item(utxo.clone());
@ -119,8 +119,8 @@ mod tests {
#[test] #[test]
fn test_insert_items() { fn test_insert_items() {
let mut smt = UTXOSparseMerkleTree::new(); let mut smt = UTXOSparseMerkleTree::new();
let utxo1 = sample_utxo(); let utxo1 = sample_utxo().unwrap();
let utxo2 = sample_utxo(); let utxo2 = sample_utxo().unwrap();
let result = smt.insert_items(vec![utxo1.clone(), utxo2.clone()]); let result = smt.insert_items(vec![utxo1.clone(), utxo2.clone()]);
@ -138,7 +138,7 @@ mod tests {
#[test] #[test]
fn test_get_item_exists() { fn test_get_item_exists() {
let mut smt = UTXOSparseMerkleTree::new(); let mut smt = UTXOSparseMerkleTree::new();
let utxo = sample_utxo(); let utxo = sample_utxo().unwrap();
smt.insert_item(utxo.clone()).unwrap(); smt.insert_item(utxo.clone()).unwrap();
@ -151,7 +151,7 @@ mod tests {
#[test] #[test]
fn test_get_item_not_exists() { fn test_get_item_not_exists() {
let mut smt = UTXOSparseMerkleTree::new(); let mut smt = UTXOSparseMerkleTree::new();
let utxo = sample_utxo(); let utxo = sample_utxo().unwrap();
// Insert one UTXO and try to fetch a different hash // Insert one UTXO and try to fetch a different hash
smt.insert_item(utxo).unwrap(); smt.insert_item(utxo).unwrap();
@ -166,7 +166,7 @@ mod tests {
#[test] #[test]
fn test_get_membership_proof() { fn test_get_membership_proof() {
let mut smt = UTXOSparseMerkleTree::new(); let mut smt = UTXOSparseMerkleTree::new();
let utxo = sample_utxo(); let utxo = sample_utxo().unwrap();
smt.insert_item(utxo.clone()).unwrap(); smt.insert_item(utxo.clone()).unwrap();

View File

@ -29,7 +29,10 @@ pub fn prove_mint_utxo(
let digest: UTXOPayload = receipt.journal.decode()?; let digest: UTXOPayload = receipt.journal.decode()?;
Ok((UTXO::create_utxo_from_payload(digest), receipt)) Ok((
UTXO::create_utxo_from_payload(digest).map_err(ExecutionFailureKind::write_error)?,
receipt,
))
} }
pub fn prove_send_utxo( pub fn prove_send_utxo(
@ -68,8 +71,9 @@ pub fn prove_send_utxo(
Ok(( Ok((
digest digest
.into_iter() .into_iter()
.map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr)) .map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload).map(|sel| (sel, addr))))
.collect(), .collect::<anyhow::Result<Vec<(UTXO, [u8; 32])>>>()
.map_err(ExecutionFailureKind::write_error)?,
receipt, receipt,
)) ))
} }
@ -117,12 +121,14 @@ pub fn prove_send_utxo_multiple_assets_one_receiver(
.0 .0
.into_iter() .into_iter()
.map(|payload| UTXO::create_utxo_from_payload(payload)) .map(|payload| UTXO::create_utxo_from_payload(payload))
.collect(), .collect::<anyhow::Result<Vec<UTXO>>>()
.map_err(ExecutionFailureKind::write_error)?,
digest digest
.1 .1
.into_iter() .into_iter()
.map(|payload| UTXO::create_utxo_from_payload(payload)) .map(|payload| UTXO::create_utxo_from_payload(payload))
.collect(), .collect::<anyhow::Result<Vec<UTXO>>>()
.map_err(ExecutionFailureKind::write_error)?,
receipt, receipt,
)) ))
} }
@ -143,7 +149,8 @@ pub fn prove_send_utxo_shielded(
asset: vec![], asset: vec![],
amount, amount,
privacy_flag: true, privacy_flag: true,
}); })
.map_err(ExecutionFailureKind::write_error)?;
let utxo_payload = temp_utxo_to_spend.into_payload(); let utxo_payload = temp_utxo_to_spend.into_payload();
let mut builder = ExecutorEnv::builder(); let mut builder = ExecutorEnv::builder();
@ -171,8 +178,9 @@ pub fn prove_send_utxo_shielded(
Ok(( Ok((
digest digest
.into_iter() .into_iter()
.map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr)) .map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload).map(|sel| (sel, addr))))
.collect(), .collect::<anyhow::Result<Vec<(UTXO, [u8; 32])>>>()
.map_err(ExecutionFailureKind::write_error)?,
receipt, receipt,
)) ))
} }
@ -253,24 +261,25 @@ pub fn prove_mint_utxo_multiple_assets(
digest digest
.into_iter() .into_iter()
.map(UTXO::create_utxo_from_payload) .map(UTXO::create_utxo_from_payload)
.collect(), .collect::<anyhow::Result<Vec<UTXO>>>()
.map_err(ExecutionFailureKind::write_error)?,
receipt, receipt,
)) ))
} }
pub fn execute_mint_utxo(amount_to_mint: u128, owner: AccountAddress) -> UTXO { pub fn execute_mint_utxo(amount_to_mint: u128, owner: AccountAddress) -> anyhow::Result<UTXO> {
let mut builder = ExecutorEnv::builder(); let mut builder = ExecutorEnv::builder();
builder.write(&amount_to_mint).unwrap(); builder.write(&amount_to_mint)?;
builder.write(&owner).unwrap(); builder.write(&owner)?;
let env = builder.build().unwrap(); let env = builder.build()?;
let executor = default_executor(); let executor = default_executor();
let receipt = executor.execute(env, test_methods::MINT_UTXO_ELF).unwrap(); let receipt = executor.execute(env, test_methods::MINT_UTXO_ELF)?;
let digest: UTXOPayload = receipt.journal.decode().unwrap(); let digest: UTXOPayload = receipt.journal.decode()?;
UTXO::create_utxo_from_payload(digest) UTXO::create_utxo_from_payload(digest)
} }
@ -278,76 +287,77 @@ pub fn execute_mint_utxo(amount_to_mint: u128, owner: AccountAddress) -> UTXO {
pub fn execute_send_utxo( pub fn execute_send_utxo(
spent_utxo: UTXO, spent_utxo: UTXO,
owners_parts: Vec<(u128, AccountAddress)>, owners_parts: Vec<(u128, AccountAddress)>,
) -> (UTXO, Vec<(UTXO, AccountAddress)>) { ) -> anyhow::Result<(UTXO, Vec<(UTXO, AccountAddress)>)> {
let mut builder = ExecutorEnv::builder(); let mut builder = ExecutorEnv::builder();
let utxo_payload = spent_utxo.into_payload(); let utxo_payload = spent_utxo.into_payload();
builder.write(&utxo_payload).unwrap(); builder.write(&utxo_payload)?;
builder.write(&owners_parts).unwrap(); builder.write(&owners_parts)?;
let env = builder.build().unwrap(); let env = builder.build()?;
let executor = default_executor(); let executor = default_executor();
let receipt = executor.execute(env, test_methods::SEND_UTXO_ELF).unwrap(); let receipt = executor.execute(env, test_methods::SEND_UTXO_ELF)?;
let digest: (UTXOPayload, Vec<(UTXOPayload, AccountAddress)>) = let digest: (UTXOPayload, Vec<(UTXOPayload, AccountAddress)>) = receipt.journal.decode()?;
receipt.journal.decode().unwrap();
( Ok((
UTXO::create_utxo_from_payload(digest.0), UTXO::create_utxo_from_payload(digest.0)?,
digest digest
.1 .1
.into_iter() .into_iter()
.map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr)) .map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload).map(|sel| (sel, addr))))
.collect(), .collect::<anyhow::Result<Vec<(UTXO, [u8; 32])>>>()
) .map_err(ExecutionFailureKind::write_error)?,
))
} }
pub fn prove<T: serde::ser::Serialize>(input_vec: Vec<T>, elf: &[u8]) -> (u64, Receipt) { pub fn prove<T: serde::ser::Serialize>(
input_vec: Vec<T>,
elf: &[u8],
) -> anyhow::Result<(u64, Receipt)> {
let mut builder = ExecutorEnv::builder(); let mut builder = ExecutorEnv::builder();
for input in input_vec { for input in input_vec {
builder.write(&input).unwrap(); builder.write(&input)?;
} }
let env = builder.build().unwrap(); let env = builder.build()?;
let prover = default_prover(); let prover = default_prover();
let receipt = prover.prove(env, elf).unwrap().receipt; let receipt = prover.prove(env, elf)?.receipt;
let digest = receipt.journal.decode().unwrap(); let digest = receipt.journal.decode()?;
(digest, receipt) Ok((digest, receipt))
} }
// This only executes the program and does not generate a receipt. // This only executes the program and does not generate a receipt.
pub fn execute<T: serde::ser::Serialize + for<'de> serde::Deserialize<'de>>( pub fn execute<T: serde::ser::Serialize + for<'de> serde::Deserialize<'de>>(
input_vec: Vec<T>, input_vec: Vec<T>,
elf: &[u8], elf: &[u8],
) -> T { ) -> anyhow::Result<T> {
let mut builder = ExecutorEnv::builder(); let mut builder = ExecutorEnv::builder();
for input in input_vec { for input in input_vec {
builder.write(&input).unwrap(); builder.write(&input)?;
} }
let env = builder.build().unwrap(); let env = builder.build()?;
let exec = default_executor(); let exec = default_executor();
let session = exec.execute(env, elf).unwrap(); let session = exec.execute(env, elf)?;
// We read the result committed to the journal by the guest code. // We read the result committed to the journal by the guest code.
let result: T = session.journal.decode().unwrap(); let result: T = session.journal.decode()?;
result Ok(result)
} }
pub fn verify(receipt: Receipt, image_id: impl Into<Digest>) { pub fn verify(receipt: Receipt, image_id: impl Into<Digest>) -> anyhow::Result<()> {
receipt Ok(receipt.verify(image_id)?)
.verify(image_id)
.expect("receipt verification failed");
} }
#[cfg(test)] #[cfg(test)]
@ -362,7 +372,7 @@ mod tests {
let message = 1; let message = 1;
let message_2 = 2; let message_2 = 2;
let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF); let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap();
verify(receipt, SUMMATION_ID); verify(receipt, SUMMATION_ID);
assert_eq!(digest, message + message_2); assert_eq!(digest, message + message_2);
@ -373,7 +383,7 @@ mod tests {
let message = 123476; let message = 123476;
let message_2 = 2342384; let message_2 = 2342384;
let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF); let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap();
verify(receipt, SUMMATION_ID); verify(receipt, SUMMATION_ID);
assert_eq!(digest, message + message_2); assert_eq!(digest, message + message_2);
@ -384,7 +394,7 @@ mod tests {
let message = 1; let message = 1;
let message_2 = 2; let message_2 = 2;
let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF); let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap();
verify(receipt, MULTIPLICATION_ID); verify(receipt, MULTIPLICATION_ID);
assert_eq!(digest, message * message_2); assert_eq!(digest, message * message_2);
@ -395,7 +405,7 @@ mod tests {
let message = 3498; let message = 3498;
let message_2 = 438563; let message_2 = 438563;
let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF); let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap();
verify(receipt, MULTIPLICATION_ID); verify(receipt, MULTIPLICATION_ID);
assert_eq!(digest, message * message_2); assert_eq!(digest, message * message_2);
@ -406,7 +416,7 @@ mod tests {
let message: u64 = 1; let message: u64 = 1;
let message_2: u64 = 2; let message_2: u64 = 2;
let result = execute(vec![message, message_2], SUMMATION_ELF); let result = execute(vec![message, message_2], SUMMATION_ELF).unwrap();
assert_eq!(result, message + message_2); assert_eq!(result, message + message_2);
} }
@ -415,7 +425,7 @@ mod tests {
let message: u64 = 123476; let message: u64 = 123476;
let message_2: u64 = 2342384; let message_2: u64 = 2342384;
let result = execute(vec![message, message_2], SUMMATION_ELF); let result = execute(vec![message, message_2], SUMMATION_ELF).unwrap();
assert_eq!(result, message + message_2); assert_eq!(result, message + message_2);
} }
@ -424,7 +434,7 @@ mod tests {
let message: u128 = 1; let message: u128 = 1;
let message_2: u128 = 2; let message_2: u128 = 2;
let result = execute(vec![message, message_2], BIG_CALCULATION_ELF); let result = execute(vec![message, message_2], BIG_CALCULATION_ELF).unwrap();
assert_eq!(result, big_calculation(message, message_2)); assert_eq!(result, big_calculation(message, message_2));
} }
@ -433,7 +443,7 @@ mod tests {
let message: u128 = 20; let message: u128 = 20;
let message_2: u128 = 10; let message_2: u128 = 10;
let result = execute(vec![message, message_2], BIG_CALCULATION_ELF); let result = execute(vec![message, message_2], BIG_CALCULATION_ELF).unwrap();
assert_eq!(result, big_calculation(message, message_2)); assert_eq!(result, big_calculation(message, message_2));
} }