2025-08-12 22:35:07 -03:00
|
|
|
use std::io;
|
|
|
|
|
|
2026-04-07 00:03:01 +03:00
|
|
|
use nssa_core::{
|
|
|
|
|
account::{Account, AccountId},
|
|
|
|
|
program::ProgramId,
|
|
|
|
|
};
|
2025-08-09 19:49:07 -03:00
|
|
|
use thiserror::Error;
|
|
|
|
|
|
2026-02-25 15:32:31 -05:00
|
|
|
#[macro_export]
|
|
|
|
|
macro_rules! ensure {
|
|
|
|
|
($cond:expr, $err:expr) => {
|
|
|
|
|
if !$cond {
|
2026-04-07 00:03:01 +03:00
|
|
|
return Err($err.into());
|
2026-02-25 15:32:31 -05:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-09 19:49:07 -03:00
|
|
|
#[derive(Error, Debug)]
|
|
|
|
|
pub enum NssaError {
|
|
|
|
|
#[error("Invalid input: {0}")]
|
|
|
|
|
InvalidInput(String),
|
|
|
|
|
|
|
|
|
|
#[error("Program violated execution rules")]
|
2026-04-07 00:03:01 +03:00
|
|
|
InvalidProgramBehavior(#[from] InvalidProgramBehaviorError),
|
2025-08-10 18:51:55 -03:00
|
|
|
|
|
|
|
|
#[error("Serialization error: {0}")]
|
2025-08-11 12:07:30 -03:00
|
|
|
InstructionSerializationError(String),
|
2025-08-11 19:14:12 -03:00
|
|
|
|
|
|
|
|
#[error("Invalid private key")]
|
|
|
|
|
InvalidPrivateKey,
|
2025-08-12 22:35:07 -03:00
|
|
|
|
|
|
|
|
#[error("IO error: {0}")]
|
|
|
|
|
Io(#[from] io::Error),
|
2025-08-13 01:33:11 -03:00
|
|
|
|
|
|
|
|
#[error("Invalid Public Key")]
|
2026-03-30 17:15:25 -04:00
|
|
|
InvalidPublicKey(#[source] k256::schnorr::Error),
|
|
|
|
|
|
|
|
|
|
#[error("Invalid hex for public key")]
|
2026-04-07 00:03:01 +03:00
|
|
|
InvalidHexPublicKey(#[source] hex::FromHexError),
|
2025-08-14 13:28:23 -03:00
|
|
|
|
2026-04-07 00:03:01 +03:00
|
|
|
#[error("Failed to write program input: {0}")]
|
2025-08-14 13:28:23 -03:00
|
|
|
ProgramWriteInputFailed(String),
|
|
|
|
|
|
2026-04-07 00:03:01 +03:00
|
|
|
#[error("Failed to execute program: {0}")]
|
2025-08-14 13:28:23 -03:00
|
|
|
ProgramExecutionFailed(String),
|
|
|
|
|
|
2026-04-07 00:03:01 +03:00
|
|
|
#[error("Failed to prove program: {0}")]
|
2025-08-14 13:28:23 -03:00
|
|
|
ProgramProveFailed(String),
|
|
|
|
|
|
2025-08-18 14:28:26 -03:00
|
|
|
#[error("Invalid transaction: {0}")]
|
|
|
|
|
TransactionDeserializationError(String),
|
|
|
|
|
|
|
|
|
|
#[error("Core error")]
|
|
|
|
|
Core(#[from] nssa_core::error::NssaCoreError),
|
2025-08-18 19:57:21 -03:00
|
|
|
|
|
|
|
|
#[error("Program output deserialization error: {0}")]
|
|
|
|
|
ProgramOutputDeserializationError(String),
|
|
|
|
|
|
|
|
|
|
#[error("Circuit output deserialization error: {0}")]
|
|
|
|
|
CircuitOutputDeserializationError(String),
|
2025-08-19 12:52:52 -03:00
|
|
|
|
|
|
|
|
#[error("Invalid privacy preserving execution circuit proof")]
|
|
|
|
|
InvalidPrivacyPreservingProof,
|
2025-09-02 12:38:31 -03:00
|
|
|
|
|
|
|
|
#[error("Circuit proving error")]
|
|
|
|
|
CircuitProvingError(String),
|
2025-10-15 17:25:26 -03:00
|
|
|
|
|
|
|
|
#[error("Invalid program bytecode")]
|
2026-03-04 18:42:33 +03:00
|
|
|
InvalidProgramBytecode(#[source] anyhow::Error),
|
2025-10-15 17:25:26 -03:00
|
|
|
|
|
|
|
|
#[error("Program already exists")]
|
|
|
|
|
ProgramAlreadyExists,
|
2025-11-12 19:55:02 -03:00
|
|
|
|
2025-11-27 09:56:52 -03:00
|
|
|
#[error("Chain of calls is too long")]
|
2025-11-12 19:55:02 -03:00
|
|
|
MaxChainedCallsDepthExceeded,
|
2026-03-04 18:42:33 +03:00
|
|
|
|
|
|
|
|
#[error("Max account nonce reached")]
|
|
|
|
|
MaxAccountNonceReached,
|
2026-03-19 15:03:45 -03:00
|
|
|
|
|
|
|
|
#[error("Execution outside of the validity window")]
|
|
|
|
|
OutOfValidityWindow,
|
2025-08-09 19:49:07 -03:00
|
|
|
}
|
2026-03-09 12:21:44 -04:00
|
|
|
|
2026-04-07 00:03:01 +03:00
|
|
|
#[derive(Error, Debug)]
|
|
|
|
|
pub enum InvalidProgramBehaviorError {
|
|
|
|
|
#[error(
|
|
|
|
|
"Inconsistent pre-state for account {account_id} : expected {expected:?}, actual {actual:?}"
|
|
|
|
|
)]
|
|
|
|
|
InconsistentAccountPreState {
|
|
|
|
|
account_id: AccountId,
|
|
|
|
|
// Boxed to reduce the size of the error type
|
|
|
|
|
expected: Box<Account>,
|
|
|
|
|
actual: Box<Account>,
|
|
|
|
|
},
|
|
|
|
|
|
2026-05-14 02:01:12 +03:00
|
|
|
#[error("Unauthorized account marked as authorized")]
|
|
|
|
|
InvalidAccountAuthorization { account_id: AccountId },
|
2026-04-07 00:03:01 +03:00
|
|
|
|
|
|
|
|
#[error("Program ID mismatch: expected {expected:?}, actual {actual:?}")]
|
|
|
|
|
MismatchedProgramId {
|
|
|
|
|
expected: ProgramId,
|
|
|
|
|
actual: ProgramId,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
#[error("Caller program ID mismatch: expected {expected:?}, actual {actual:?}")]
|
|
|
|
|
MismatchedCallerProgramId {
|
|
|
|
|
expected: Option<ProgramId>,
|
|
|
|
|
actual: Option<ProgramId>,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
#[error(transparent)]
|
|
|
|
|
ExecutionValidationFailed(#[from] nssa_core::program::ExecutionValidationError),
|
|
|
|
|
|
|
|
|
|
#[error("Trying to claim account {account_id} which is not default")]
|
|
|
|
|
ClaimedNonDefaultAccount { account_id: AccountId },
|
|
|
|
|
|
|
|
|
|
#[error("Trying to claim account {account_id} which is not authorized")]
|
|
|
|
|
ClaimedUnauthorizedAccount { account_id: AccountId },
|
|
|
|
|
|
|
|
|
|
#[error("PDA claim mismatch: expected {expected:?}, actual {actual:?}")]
|
|
|
|
|
MismatchedPdaClaim {
|
|
|
|
|
expected: AccountId,
|
|
|
|
|
actual: AccountId,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
#[error("Default account {account_id} was modified without being claimed")]
|
|
|
|
|
DefaultAccountModifiedWithoutClaim { account_id: AccountId },
|
|
|
|
|
|
|
|
|
|
#[error("Called program {program_id:?} which is not listed in dependencies")]
|
|
|
|
|
UndeclaredProgramDependency { program_id: ProgramId },
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-09 13:05:29 -04:00
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
2026-03-09 12:21:44 -04:00
|
|
|
|
2026-03-09 13:05:29 -04:00
|
|
|
#[derive(Debug)]
|
|
|
|
|
enum TestError {
|
|
|
|
|
TestErr,
|
|
|
|
|
}
|
2026-03-09 12:21:44 -04:00
|
|
|
|
2026-03-16 09:12:29 -04:00
|
|
|
fn test_function_ensure(cond: bool) -> Result<(), TestError> {
|
2026-03-09 13:05:29 -04:00
|
|
|
ensure!(cond, TestError::TestErr);
|
2026-03-09 12:21:44 -04:00
|
|
|
|
2026-03-09 13:05:29 -04:00
|
|
|
Ok(())
|
|
|
|
|
}
|
2026-03-09 12:21:44 -04:00
|
|
|
|
2026-03-09 13:05:29 -04:00
|
|
|
#[test]
|
2026-03-04 18:42:33 +03:00
|
|
|
fn ensure_works() {
|
2026-03-09 13:05:29 -04:00
|
|
|
assert!(test_function_ensure(true).is_ok());
|
|
|
|
|
assert!(test_function_ensure(false).is_err());
|
|
|
|
|
}
|
|
|
|
|
}
|