add errors

This commit is contained in:
Sergio Chouhy 2025-07-19 23:40:02 -03:00
parent 7f43adfa1c
commit 9e3c9b3ae8
9 changed files with 47 additions and 30 deletions

View File

@ -38,7 +38,7 @@ impl MockedClient {
// Execute and generate proof of the outer program
let (receipt, private_outputs) =
nssa::execute_offchain::<P>(input_accounts, instruction_data, visibilities, commitment_tree_root)
.map_err(|_| Error::Generic)?;
.map_err(|_| Error::BadInput)?;
// Send proof to the sequencer
sequencer.process_privacy_execution(receipt)?;

View File

@ -2,7 +2,10 @@ use core::types::Address;
use nssa::program::TransferProgram;
use crate::mocked_components::{client::MockedClient, sequencer::MockedSequencer};
use crate::mocked_components::{
client::MockedClient,
sequencer::{error::Error, MockedSequencer},
};
impl MockedClient {
pub fn transfer_public(
@ -10,8 +13,10 @@ impl MockedClient {
to_address: &Address,
amount_to_transfer: u128,
sequencer: &mut MockedSequencer,
) -> Result<(), nssa::Error> {
) -> Result<(), Error> {
// Submit a public (on-chain) execution of the Transfer program to the sequencer
sequencer.process_public_execution::<TransferProgram>(&[self.user_address(), *to_address], amount_to_transfer)
sequencer
.process_public_execution::<TransferProgram>(&[self.user_address(), *to_address], amount_to_transfer)
.map_err(|_| Error::BadInput)
}
}

View File

@ -18,7 +18,7 @@ impl MockedClient {
let commitment_tree_root = sequencer.get_commitment_tree_root();
// Fetch sender account from the sequencer
let from_account = sequencer.get_account(&self.user_address()).ok_or(Error::Generic)?;
let from_account = sequencer.get_account(&self.user_address()).ok_or(Error::NotFound)?;
// Create a new default private account for the receiver
let to_account = Self::fresh_account_for_mint(*to_address);

View File

@ -1,13 +1,14 @@
#[derive(Debug)]
pub enum Error {
/// For simplicity, this POC uses a generic error
Generic,
NotFound,
BadInput,
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::Generic => write!(f, "An unexpected error occurred"),
Error::NotFound => write!(f, "Not found"),
Error::BadInput => write!(f, "Bad input"),
}
}
}

View File

@ -14,20 +14,20 @@ impl MockedSequencer {
// Reject in case the root used in the privacy execution is not the current root.
if output.commitment_tree_root != self.get_commitment_tree_root() {
return Err(Error::Generic);
return Err(Error::BadInput);
}
// Reject in case the number of accounts pre states is different from the post states
if output.public_accounts_pre.len() != output.public_accounts_post.len() {
return Err(Error::Generic);
return Err(Error::BadInput);
}
// Reject if the states of the public input accounts used in the inner execution do not
// coincide with the on-chain state.
for account in output.public_accounts_pre.iter() {
let current_account = self.get_account(&account.address).ok_or(Error::Generic)?;
let current_account = self.get_account(&account.address).ok_or(Error::NotFound)?;
if &current_account != account {
return Err(Error::Generic);
return Err(Error::BadInput);
}
}
@ -37,7 +37,7 @@ impl MockedSequencer {
.iter()
.any(|nullifier| self.nullifier_set.contains(nullifier))
{
return Err(Error::Generic);
return Err(Error::BadInput);
}
// Reject if the commitments have already been seen.
@ -46,7 +46,7 @@ impl MockedSequencer {
.iter()
.any(|commitment| self.commitment_tree.values().contains(commitment))
{
return Err(Error::Generic);
return Err(Error::BadInput);
}
// Verify the proof of the privacy execution.
@ -56,7 +56,7 @@ impl MockedSequencer {
// - The given nullifiers correctly correspond to commitments that currently belong to
// the commitment tree.
// - The given commitments are correctly computed from valid accounts.
nssa::verify_privacy_execution(receipt).map_err(|_| Error::Generic)?;
nssa::verify_privacy_execution(receipt).map_err(|_| Error::BadInput)?;
// At this point the privacy execution is considered valid.
//

View File

@ -1,5 +1,7 @@
use core::{account::Account, types::Address};
use crate::mocked_components::sequencer::error::Error;
use super::MockedSequencer;
impl MockedSequencer {
@ -8,19 +10,20 @@ impl MockedSequencer {
&mut self,
input_account_addresses: &[Address],
instruction_data: P::InstructionData,
) -> Result<(), nssa::Error> {
) -> Result<(), Error> {
// Fetch the current state of the input accounts.
let input_accounts: Vec<Account> = input_account_addresses
.iter()
.map(|address| self.get_account(address).ok_or(nssa::Error::Generic))
.map(|address| self.get_account(address).ok_or(Error::NotFound))
.collect::<Result<_, _>>()?;
// Execute the program
let program_output = nssa::execute_onchain::<P>(&input_accounts, instruction_data)?;
let program_output =
nssa::execute_onchain::<P>(&input_accounts, instruction_data).map_err(|_| Error::BadInput)?;
// Perform consistency checks
if !self.program_output_is_valid(&input_accounts, &program_output.accounts_post) {
return Err(nssa::Error::Generic);
return Err(Error::BadInput);
}
// Update the accounts states

View File

@ -1,13 +1,14 @@
#[derive(Debug)]
pub enum Error {
/// For simplicity, this POC uses a generic error
Generic,
BadInput,
Risc0(String),
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::Generic => write!(f, "An unexpected error occurred"),
Error::BadInput => write!(f, "Bad input"),
Error::Risc0(_) => write!(f, "Risc0 error"),
}
}
}

View File

@ -25,8 +25,8 @@ fn write_inputs<P: Program>(
env_builder: &mut ExecutorEnvBuilder,
) -> Result<(), Error> {
let input_accounts = input_accounts.to_vec();
env_builder.write(&input_accounts).map_err(|_| Error::Generic)?;
env_builder.write(&instruction_data).map_err(|_| Error::Generic)?;
env_builder.write(&input_accounts).map_err(|_| Error::BadInput)?;
env_builder.write(&instruction_data).map_err(|_| Error::BadInput)?;
Ok(())
}
@ -43,7 +43,9 @@ fn execute_and_prove_inner<P: Program>(
// Prove the program
let prover = default_prover();
let prove_info = prover.prove(env, P::PROGRAM_ELF).map_err(|_| Error::Generic)?;
let prove_info = prover
.prove(env, P::PROGRAM_ELF)
.map_err(|e| Error::Risc0(e.to_string()))?;
Ok(prove_info.receipt)
}
@ -81,10 +83,12 @@ pub fn execute_onchain<P: Program>(
// Execute the program (without proving)
let executor = default_executor();
let session_info = executor.execute(env, P::PROGRAM_ELF).map_err(|_| Error::Generic)?;
let session_info = executor
.execute(env, P::PROGRAM_ELF)
.map_err(|e| Error::Risc0(e.to_string()))?;
// Get (inputs and) outputs
session_info.journal.decode().map_err(|_| Error::Generic)
session_info.journal.decode().map_err(|e| Error::Risc0(e.to_string()))
}
/// Executes and proves the inner program `P` and executes and proves the outer program on top of it.
@ -98,7 +102,10 @@ pub fn execute_offchain<P: Program>(
) -> Result<(Receipt, Vec<Account>), Error> {
// Prove inner program and get post state of the accounts
let inner_receipt = execute_and_prove_inner::<P>(inputs, instruction_data)?;
let inner_program_output: ProgramOutput = inner_receipt.journal.decode().map_err(|_| Error::Generic)?;
let inner_program_output: ProgramOutput = inner_receipt
.journal
.decode()
.map_err(|e| Error::Risc0(e.to_string()))?;
// Sample fresh random nonces for the outputs of this execution
let output_nonces: Vec<_> = (0..inputs.len()).map(|_| new_random_nonce()).collect();
@ -123,5 +130,5 @@ pub fn execute_offchain<P: Program>(
/// Verifies a proof of the outer program for the given parameters.
pub fn verify_privacy_execution(receipt: Receipt) -> Result<(), Error> {
receipt.verify(OUTER_ID).map_err(|_| Error::Generic)
receipt.verify(OUTER_ID).map_err(|e| Error::Risc0(e.to_string()))
}

View File

@ -30,6 +30,6 @@ pub struct PinataProgram;
impl Program for PinataProgram {
const PROGRAM_ID: ProgramId = PINATA_ID;
const PROGRAM_ELF: &[u8] = PINATA_ELF;
/// Preimage of target hash to win price
/// Preimage of target hash to win prize
type InstructionData = Vec<u32>;
}