diff --git a/.gitignore b/.gitignore index 8f6f072..fbe892d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ data/ .idea/ .vscode/ rocksdb +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index b6ecaed..9d31f3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,20 @@ [workspace] resolver = "2" members = [ + "integration_tests", "sequencer_runner", "storage", - "accounts", - "utxo", + "key_protocol", "sequencer_rpc", "mempool", - "zkvm", "wallet", "sequencer_core", "common", - "sc_core", - "integration_tests", + "nssa", ] [workspace.dependencies] -anyhow = "1.0" +anyhow = "1.0.98" num_cpus = "1.13.1" openssl = { version = "0.10", features = ["vendored"] } openssl-probe = { version = "0.1.2" } @@ -29,7 +27,7 @@ lazy_static = "1.5.0" env_logger = "0.10" log = "0.4" lru = "0.7.8" -thiserror = "1.0" +thiserror = "2.0.12" rs_merkle = "1.4" sha2 = "0.10.8" hex = "0.4.3" @@ -42,6 +40,7 @@ light-poseidon = "0.3.0" ark-bn254 = "0.5.0" ark-ff = "0.5.0" tiny-keccak = { version = "2.0.2", features = ["keccak"] } +base64 = "0.22.1" rocksdb = { version = "0.21.0", default-features = false, features = [ "snappy", diff --git a/accounts/src/account_core/address.rs b/accounts/src/account_core/address.rs deleted file mode 100644 index 2fadacd..0000000 --- a/accounts/src/account_core/address.rs +++ /dev/null @@ -1,36 +0,0 @@ -use common::transaction::SignaturePublicKey; -use tiny_keccak::{Hasher, Keccak}; - -// TODO: Consider wrapping `AccountAddress` in a struct. - -pub type AccountAddress = [u8; 32]; - -/// Returns the address associated with a public key -pub fn from_public_key(public_key: &SignaturePublicKey) -> AccountAddress { - let mut address = [0; 32]; - let mut keccak_hasher = Keccak::v256(); - keccak_hasher.update(&public_key.to_sec1_bytes()); - keccak_hasher.finalize(&mut address); - address -} - -#[cfg(test)] -mod tests { - use common::transaction::SignaturePrivateKey; - - use super::*; - use crate::account_core::address; - - #[test] - fn test_address_key_equal_keccak_pub_sign_key() { - let signing_key = SignaturePrivateKey::from_slice(&[1; 32]).unwrap(); - let public_key = signing_key.verifying_key(); - - let mut expected_address = [0; 32]; - let mut keccak_hasher = Keccak::v256(); - keccak_hasher.update(&public_key.to_sec1_bytes()); - keccak_hasher.finalize(&mut expected_address); - - assert_eq!(expected_address, address::from_public_key(public_key)); - } -} diff --git a/accounts/src/account_core/mod.rs b/accounts/src/account_core/mod.rs deleted file mode 100644 index 1926649..0000000 --- a/accounts/src/account_core/mod.rs +++ /dev/null @@ -1,279 +0,0 @@ -use std::collections::HashMap; - -use anyhow::Result; -use common::{merkle_tree_public::TreeHashType, transaction::Tag}; -use k256::AffinePoint; -use log::info; -use serde::{Deserialize, Serialize}; -use utxo::utxo_core::UTXO; - -pub mod address; - -use crate::{ - account_core::address::AccountAddress, - key_management::{ - constants_types::{CipherText, Nonce}, - ephemeral_key_holder::EphemeralKeyHolder, - AddressKeyHolder, - }, -}; - -pub type PublicKey = AffinePoint; - -#[derive(Clone, Debug)] -pub struct Account { - pub key_holder: AddressKeyHolder, - pub address: AccountAddress, - pub balance: u64, - pub utxos: HashMap, -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -pub struct AccountForSerialization { - pub key_holder: AddressKeyHolder, - pub address: AccountAddress, - pub balance: u64, - pub utxos: HashMap, -} - -impl From for AccountForSerialization { - fn from(value: Account) -> Self { - AccountForSerialization { - key_holder: value.key_holder, - address: value.address, - balance: value.balance, - utxos: value - .utxos - .into_iter() - .map(|(key, val)| (hex::encode(key), val)) - .collect(), - } - } -} - -impl From for Account { - fn from(value: AccountForSerialization) -> Self { - Account { - key_holder: value.key_holder, - address: value.address, - balance: value.balance, - utxos: value - .utxos - .into_iter() - .map(|(key, val)| (hex::decode(key).unwrap().try_into().unwrap(), val)) - .collect(), - } - } -} - -impl Serialize for Account { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let account_for_serialization: AccountForSerialization = From::from(self.clone()); - account_for_serialization.serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for Account { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let account_for_serialization = ::deserialize(deserializer)?; - Ok(account_for_serialization.into()) - } -} - -///A strucure, which represents all the visible(public) information -/// -/// known to each node about account `address` -/// -/// Main usage is to encode data for other account -#[derive(Serialize, Clone)] -pub struct AccountPublicMask { - pub nullifier_public_key: AffinePoint, - pub viewing_public_key: AffinePoint, - pub address: AccountAddress, - pub balance: u64, -} - -impl AccountPublicMask { - pub fn encrypt_data( - ephemeral_key_holder: &EphemeralKeyHolder, - viewing_public_key_receiver: AffinePoint, - data: &[u8], - ) -> (CipherText, Nonce) { - //Using of parent Account fuction - Account::encrypt_data(ephemeral_key_holder, viewing_public_key_receiver, data) - } - - pub fn make_tag(&self) -> Tag { - self.address[0] - } -} - -impl Account { - pub fn new() -> Self { - let key_holder = AddressKeyHolder::new_os_random(); - let public_key = *key_holder.get_pub_account_signing_key().verifying_key(); - let address = address::from_public_key(&public_key); - let balance = 0; - let utxos = HashMap::new(); - - Self { - key_holder, - address, - balance, - utxos, - } - } - - pub fn new_with_balance(balance: u64) -> Self { - let key_holder = AddressKeyHolder::new_os_random(); - let public_key = *key_holder.get_pub_account_signing_key().verifying_key(); - let address = address::from_public_key(&public_key); - let utxos = HashMap::new(); - - Self { - key_holder, - address, - balance, - utxos, - } - } - - pub fn encrypt_data( - ephemeral_key_holder: &EphemeralKeyHolder, - viewing_public_key_receiver: AffinePoint, - data: &[u8], - ) -> (CipherText, Nonce) { - ephemeral_key_holder.encrypt_data(viewing_public_key_receiver, data) - } - - pub fn decrypt_data( - &self, - ephemeral_public_key_sender: AffinePoint, - ciphertext: CipherText, - nonce: Nonce, - ) -> Result, aes_gcm::Error> { - self.key_holder - .decrypt_data(ephemeral_public_key_sender, ciphertext, nonce) - } - - pub fn add_new_utxo_outputs(&mut self, utxos: Vec) -> Result<()> { - for utxo in utxos { - if self.utxos.contains_key(&utxo.hash) { - return Err(anyhow::anyhow!("UTXO already exists")); - } - self.utxos.insert(utxo.hash, utxo); - } - Ok(()) - } - - pub fn update_public_balance(&mut self, new_balance: u64) { - self.balance = new_balance; - } - - pub fn add_asset( - &mut self, - asset: Asset, - amount: u128, - privacy_flag: bool, - ) -> Result<()> { - let asset_utxo = UTXO::new( - self.address, - serde_json::to_vec(&asset)?, - amount, - privacy_flag, - ); - - self.utxos.insert(asset_utxo.hash, asset_utxo); - - Ok(()) - } - - pub fn log(&self) { - info!("Keys generated"); - info!("Account address is {:?}", hex::encode(self.address)); - info!("Account balance is {:?}", self.balance); - } - - pub fn make_tag(&self) -> Tag { - self.address[0] - } - - ///Produce account public mask - pub fn make_account_public_mask(&self) -> AccountPublicMask { - AccountPublicMask { - nullifier_public_key: self.key_holder.nullifer_public_key, - viewing_public_key: self.key_holder.viewing_public_key, - address: self.address, - balance: self.balance, - } - } -} - -impl Default for Account { - fn default() -> Self { - Self::new() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn generate_dummy_utxo(address: TreeHashType, amount: u128) -> UTXO { - UTXO::new(address, vec![], amount, false) - } - - #[test] - fn test_new_account() { - let account = Account::new(); - - assert_eq!(account.balance, 0); - } - - #[test] - fn test_add_new_utxo_outputs() { - let mut account = Account::new(); - let utxo1 = generate_dummy_utxo(account.address, 100); - let utxo2 = generate_dummy_utxo(account.address, 200); - - let result = account.add_new_utxo_outputs(vec![utxo1.clone(), utxo2.clone()]); - - assert!(result.is_ok()); - assert_eq!(account.utxos.len(), 2); - } - - #[test] - fn test_update_public_balance() { - let mut account = Account::new(); - account.update_public_balance(500); - - assert_eq!(account.balance, 500); - } - - #[test] - fn test_add_asset() { - let mut account = Account::new(); - let asset = "dummy_asset"; - let amount = 1000u128; - - let result = account.add_asset(asset, amount, false); - - assert!(result.is_ok()); - assert_eq!(account.utxos.len(), 1); - } - - #[test] - fn accounts_accounts_mask_tag_consistency() { - let account = Account::new(); - - let account_mask = account.make_account_public_mask(); - - assert_eq!(account.make_tag(), account_mask.make_tag()); - } -} diff --git a/accounts/src/lib.rs b/accounts/src/lib.rs deleted file mode 100644 index 998d3ec..0000000 --- a/accounts/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod account_core; -pub mod key_management; diff --git a/ci_scripts/lint-ubuntu.sh b/ci_scripts/lint-ubuntu.sh old mode 100644 new mode 100755 diff --git a/common/Cargo.toml b/common/Cargo.toml index 7cf728f..4e29b1e 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -9,7 +9,6 @@ thiserror.workspace = true serde_json.workspace = true serde.workspace = true reqwest.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } k256.workspace = true rand.workspace = true @@ -22,3 +21,6 @@ hex.workspace = true [dependencies.secp256k1-zkp] workspace = true features = ["std", "rand-std", "rand", "serde", "global-context"] + +[dependencies.nssa] +path = "../nssa" diff --git a/common/src/block.rs b/common/src/block.rs index c566075..2e4e9b9 100644 --- a/common/src/block.rs +++ b/common/src/block.rs @@ -1,35 +1,33 @@ -use rs_merkle::Hasher; -use serde::{Deserialize, Serialize}; +use std::io::{Cursor, Read}; -use crate::{merkle_tree_public::hasher::OwnHasher, transaction::Transaction}; +use rs_merkle::Hasher; + +use crate::merkle_tree_public::hasher::OwnHasher; +use nssa; pub type BlockHash = [u8; 32]; -pub type Data = Vec; pub type BlockId = u64; -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Clone)] pub struct Block { pub block_id: BlockId, pub prev_block_id: BlockId, pub prev_block_hash: BlockHash, pub hash: BlockHash, - pub transactions: Vec, - pub data: Data, + pub transactions: Vec, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq)] pub struct HashableBlockData { pub block_id: BlockId, pub prev_block_id: BlockId, pub prev_block_hash: BlockHash, - pub transactions: Vec, - pub data: Data, + pub transactions: Vec, } impl From for Block { fn from(value: HashableBlockData) -> Self { - let data = serde_json::to_vec(&value).unwrap(); - + let data = value.to_bytes(); let hash = OwnHasher::hash(&data); Self { @@ -37,8 +35,88 @@ impl From for Block { prev_block_id: value.prev_block_id, hash, transactions: value.transactions, - data: value.data, prev_block_hash: value.prev_block_hash, } } } + +impl From for HashableBlockData { + fn from(value: Block) -> Self { + Self { + block_id: value.block_id, + prev_block_id: value.prev_block_id, + prev_block_hash: value.prev_block_hash, + transactions: value.transactions, + } + } +} + +impl HashableBlockData { + pub fn to_bytes(&self) -> Vec { + let mut bytes = Vec::new(); + bytes.extend_from_slice(&self.block_id.to_le_bytes()); + bytes.extend_from_slice(&self.prev_block_id.to_le_bytes()); + bytes.extend_from_slice(&self.prev_block_hash); + let num_transactions: u32 = self.transactions.len() as u32; + bytes.extend_from_slice(&num_transactions.to_le_bytes()); + for tx in &self.transactions { + bytes.extend_from_slice(&tx.to_bytes()); + } + bytes + } + + // TODO: Improve error handling. Remove unwraps. + pub fn from_bytes(data: &[u8]) -> Self { + let mut cursor = Cursor::new(data); + + let block_id = u64_from_cursor(&mut cursor); + let prev_block_id = u64_from_cursor(&mut cursor); + + let mut prev_block_hash = [0u8; 32]; + cursor.read_exact(&mut prev_block_hash).unwrap(); + + let num_transactions = u32_from_cursor(&mut cursor) as usize; + + let mut transactions = Vec::with_capacity(num_transactions); + for _ in 0..num_transactions { + let tx = nssa::PublicTransaction::from_cursor(&mut cursor).unwrap(); + transactions.push(tx); + } + + Self { + block_id, + prev_block_id, + prev_block_hash, + transactions, + } + } +} + +// TODO: Improve error handling. Remove unwraps. +fn u32_from_cursor(cursor: &mut Cursor<&[u8]>) -> u32 { + let mut word_buf = [0u8; 4]; + cursor.read_exact(&mut word_buf).unwrap(); + u32::from_le_bytes(word_buf) +} + +// TODO: Improve error handling. Remove unwraps. +fn u64_from_cursor(cursor: &mut Cursor<&[u8]>) -> u64 { + let mut word_buf = [0u8; 8]; + cursor.read_exact(&mut word_buf).unwrap(); + u64::from_le_bytes(word_buf) +} + +#[cfg(test)] +mod tests { + use crate::{block::HashableBlockData, test_utils}; + + #[test] + fn test_encoding_roundtrip() { + let transactions = vec![test_utils::produce_dummy_empty_transaction()]; + let block = test_utils::produce_dummy_block(1, Some([1; 32]), transactions); + let hashable = HashableBlockData::from(block); + let bytes = hashable.to_bytes(); + let block_from_bytes = HashableBlockData::from_bytes(&bytes); + assert_eq!(hashable, block_from_bytes); + } +} diff --git a/common/src/lib.rs b/common/src/lib.rs index 560bcd2..01ae261 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -65,9 +65,11 @@ pub enum ExecutionFailureKind { #[error("Failed prove execution err: {0:?}")] ProveError(anyhow::Error), #[error("Failed to decode data from VM: {0:?}")] - DecodeError(#[from] risc0_zkvm::serde::Error), + DecodeError(String), #[error("Inputs amounts does not match outputs")] AmountMismatchError, + #[error("Accounts key not found")] + KeyNotFoundError, #[error("Sequencer client error: {0:?}")] SequencerClientError(#[from] SequencerClientError), #[error("Insufficient gas for operation")] diff --git a/common/src/rpc_primitives/requests.rs b/common/src/rpc_primitives/requests.rs index f19f6ea..2e67f16 100644 --- a/common/src/rpc_primitives/requests.rs +++ b/common/src/rpc_primitives/requests.rs @@ -1,6 +1,4 @@ -use crate::block::Block; use crate::parse_request; -use crate::transaction::Transaction; use super::errors::RpcParseError; use super::parser::parse_params; @@ -18,7 +16,7 @@ pub struct RegisterAccountRequest { #[derive(Serialize, Deserialize, Debug)] pub struct SendTxRequest { - pub transaction: Transaction, + pub transaction: Vec, } #[derive(Serialize, Deserialize, Debug)] @@ -72,7 +70,7 @@ pub struct SendTxResponse { #[derive(Serialize, Deserialize, Debug)] pub struct GetBlockDataResponse { - pub block: Block, + pub block: Vec, } #[derive(Serialize, Deserialize, Debug)] @@ -87,10 +85,10 @@ pub struct GetLastBlockResponse { #[derive(Serialize, Deserialize, Debug)] pub struct GetAccountBalanceResponse { - pub balance: u64, + pub balance: u128, } #[derive(Serialize, Deserialize, Debug)] pub struct GetTransactionByHashResponse { - pub transaction: Option, + pub transaction: Option, } diff --git a/common/src/sequencer_client/json.rs b/common/src/sequencer_client/json.rs index 5f6798a..71b1719 100644 --- a/common/src/sequencer_client/json.rs +++ b/common/src/sequencer_client/json.rs @@ -1,12 +1,10 @@ use serde::{Deserialize, Serialize}; -use crate::transaction::Transaction; - //Requests #[derive(Serialize, Deserialize, Debug)] pub struct SendTxRequest { - pub transaction: Transaction, + pub transaction: Vec, } //Responses diff --git a/common/src/sequencer_client/mod.rs b/common/src/sequencer_client/mod.rs index d7d3123..a131033 100644 --- a/common/src/sequencer_client/mod.rs +++ b/common/src/sequencer_client/mod.rs @@ -8,7 +8,6 @@ use reqwest::Client; use serde_json::Value; use crate::sequencer_client::json::AccountInitialData; -use crate::transaction::Transaction; use crate::{SequencerClientError, SequencerRpcError}; pub mod json; @@ -90,9 +89,11 @@ impl SequencerClient { ///Send transaction to sequencer pub async fn send_tx( &self, - transaction: Transaction, + transaction: nssa::PublicTransaction, ) -> Result { - let tx_req = SendTxRequest { transaction }; + let tx_req = SendTxRequest { + transaction: transaction.to_bytes(), + }; let req = serde_json::to_value(tx_req)?; diff --git a/common/src/test_utils.rs b/common/src/test_utils.rs index 0e6bf5c..b956cd7 100644 --- a/common/src/test_utils.rs +++ b/common/src/test_utils.rs @@ -1,11 +1,6 @@ -use k256::ecdsa::SigningKey; -use secp256k1_zkp::Tweak; +use nssa; -use crate::{ - block::{Block, HashableBlockData}, - execution_input::PublicNativeTokenSend, - transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind}, -}; +use crate::block::{Block, HashableBlockData}; //Dummy producers @@ -16,100 +11,47 @@ use crate::{ /// `prev_hash` - hash of previous block, provide None for genesis /// /// `transactions` - vector of `Transaction` objects -/// -/// `additional_data` - vector with additional data pub fn produce_dummy_block( id: u64, prev_hash: Option<[u8; 32]>, - transactions: Vec, - additional_data: Vec, + transactions: Vec, ) -> Block { let block_data = HashableBlockData { block_id: id, prev_block_id: id.saturating_sub(1), prev_block_hash: prev_hash.unwrap_or_default(), transactions, - data: additional_data, }; block_data.into() } -pub fn produce_dummy_empty_transaction() -> Transaction { - let body = TransactionBody { - tx_kind: TxKind::Public, - execution_input: Default::default(), - execution_output: Default::default(), - utxo_commitments_spent_hashes: Default::default(), - utxo_commitments_created_hashes: Default::default(), - nullifier_created_hashes: Default::default(), - execution_proof_private: Default::default(), - encoded_data: Default::default(), - ephemeral_pub_key: Default::default(), - commitment: Default::default(), - tweak: Default::default(), - secret_r: Default::default(), - sc_addr: Default::default(), - }; - - Transaction::new(body, SignaturePrivateKey::from_slice(&[1; 32]).unwrap()) +pub fn produce_dummy_empty_transaction() -> nssa::PublicTransaction { + let program_id = nssa::program::Program::authenticated_transfer_program().id(); + let addresses = vec![]; + let nonces = vec![]; + let instruction_data: u128 = 0; + let message = + nssa::public_transaction::Message::try_new(program_id, addresses, nonces, instruction_data) + .unwrap(); + let private_key = nssa::PrivateKey::try_new([1; 32]).unwrap(); + let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[&private_key]); + nssa::PublicTransaction::new(message, witness_set) } -pub fn create_dummy_private_transaction_random_signer( - nullifier_created_hashes: Vec<[u8; 32]>, - utxo_commitments_spent_hashes: Vec<[u8; 32]>, - utxo_commitments_created_hashes: Vec<[u8; 32]>, -) -> Transaction { - let mut rng = rand::thread_rng(); - - let body = TransactionBody { - tx_kind: TxKind::Private, - execution_input: vec![], - execution_output: vec![], - utxo_commitments_spent_hashes, - utxo_commitments_created_hashes, - nullifier_created_hashes, - execution_proof_private: "dummy_proof".to_string(), - encoded_data: vec![], - ephemeral_pub_key: vec![10, 11, 12], - commitment: vec![], - tweak: Tweak::new(&mut rng), - secret_r: [0; 32], - sc_addr: "sc_addr".to_string(), - }; - Transaction::new(body, SignaturePrivateKey::random(&mut rng)) -} - -pub fn create_dummy_transaction_native_token_transfer( +pub fn create_transaction_native_token_transfer( from: [u8; 32], - nonce: u64, + nonce: u128, to: [u8; 32], - balance_to_move: u64, - signing_key: SigningKey, -) -> Transaction { - let mut rng = rand::thread_rng(); - - let native_token_transfer = PublicNativeTokenSend { - from, - nonce, - to, - balance_to_move, - }; - - let body = TransactionBody { - tx_kind: TxKind::Public, - execution_input: serde_json::to_vec(&native_token_transfer).unwrap(), - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: vec![], - nullifier_created_hashes: vec![], - execution_proof_private: "".to_string(), - encoded_data: vec![], - ephemeral_pub_key: vec![10, 11, 12], - commitment: vec![], - tweak: Tweak::new(&mut rng), - secret_r: [0; 32], - sc_addr: "sc_addr".to_string(), - }; - Transaction::new(body, signing_key) + balance_to_move: u128, + signing_key: nssa::PrivateKey, +) -> nssa::PublicTransaction { + let addresses = vec![nssa::Address::new(from), nssa::Address::new(to)]; + let nonces = vec![nonce]; + let program_id = nssa::program::Program::authenticated_transfer_program().id(); + let message = + nssa::public_transaction::Message::try_new(program_id, addresses, nonces, balance_to_move) + .unwrap(); + let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[&signing_key]); + nssa::PublicTransaction::new(message, witness_set) } diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index 10c49fb..df2bad8 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -36,5 +36,5 @@ path = "../wallet" [dependencies.common] path = "../common" -[dependencies.accounts] -path = "../accounts" +[dependencies.key_protocol] +path = "../key_protocol" diff --git a/integration_tests/configs/debug/sequencer/sequencer_config.json b/integration_tests/configs/debug/sequencer/sequencer_config.json index 9eb086a..37bfd0a 100644 --- a/integration_tests/configs/debug/sequencer/sequencer_config.json +++ b/integration_tests/configs/debug/sequencer/sequencer_config.json @@ -8,12 +8,12 @@ "port": 3040, "initial_accounts": [ { - "addr": "0d96dfcc414019380c9dde0cd3dce5aac90fb5443bf871108741aeafde552ad7", + "addr": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", "balance": 10000 }, { - "addr": "974870e9be8d0ac08aa83b3fc7a7a686291d8732508aba98b36080f39c2cf364", + "addr": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766", "balance": 20000 } ] -} \ No newline at end of file +} diff --git a/integration_tests/configs/debug/wallet/wallet_config.json b/integration_tests/configs/debug/wallet/wallet_config.json index e4dc7e9..d888119 100644 --- a/integration_tests/configs/debug/wallet/wallet_config.json +++ b/integration_tests/configs/debug/wallet/wallet_config.json @@ -1,244 +1,113 @@ { - "home": "./wallet", + "home": "./node", "override_rust_log": null, "sequencer_addr": "http://127.0.0.1:3040", "seq_poll_timeout_secs": 10, "initial_accounts": [ { - "address": [ - 13, - 150, - 223, - 204, - 65, - 64, - 25, - 56, - 12, - 157, - 222, - 12, - 211, - 220, - 229, - 170, - 201, - 15, - 181, - 68, - 59, - 248, - 113, - 16, - 135, - 65, - 174, - 175, - 222, - 85, - 42, - 215 + "address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", + "pub_sign_key": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 ], - "balance": 10000, - "nonce": 0, - "key_holder": { - "address": [ - 13, - 150, - 223, - 204, - 65, - 64, - 25, - 56, - 12, - 157, - 222, - 12, - 211, - 220, - 229, - 170, - 201, - 15, - 181, - 68, - 59, - 248, - 113, - 16, - 135, - 65, - 174, - 175, - 222, - 85, - 42, - 215 + "account": { + "program_owner": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 ], - "nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718", - "pub_account_signing_key": [ - 133, - 143, - 177, - 187, - 252, - 66, - 237, - 236, - 234, - 252, - 244, - 138, - 5, - 151, - 3, - 99, - 217, - 231, - 112, - 217, - 77, - 211, - 58, - 218, - 176, - 68, - 99, - 53, - 152, - 228, - 198, - 190 - ], - "top_secret_key_holder": { - "secret_spending_key": "7BC46784DB1BC67825D8F029436846712BFDF9B5D79EA3AB11D39A52B9B229D4" - }, - "utxo_secret_key_holder": { - "nullifier_secret_key": "BB54A8D3C9C51B82C431082D1845A74677B0EF829A11B517E1D9885DE3139506", - "viewing_secret_key": "AD923E92F6A5683E30140CEAB2702AFB665330C1EE4EFA70FAF29767B6B52BAF" - }, - "viewing_public_key": "0361220C5D277E7A1709340FD31A52600C1432B9C45B9BCF88A43581D58824A8B6" - }, - "utxos": {} + "balance": 10000, + "nonce": 0, + "data": [] + } }, { - "address": [ - 151, - 72, - 112, - 233, - 190, - 141, - 10, - 192, - 138, - 168, - 59, - 63, - 199, - 167, - 166, - 134, - 41, - 29, - 135, - 50, - 80, - 138, - 186, - 152, - 179, - 96, - 128, - 243, - 156, - 44, - 243, - 100 + "address": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766", + "pub_sign_key": [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 ], - "balance": 20000, - "nonce": 0, - "key_holder": { - "address": [ - 151, - 72, - 112, - 233, - 190, - 141, - 10, - 192, - 138, - 168, - 59, - 63, - 199, - 167, - 166, - 134, - 41, - 29, - 135, - 50, - 80, - 138, - 186, - 152, - 179, - 96, - 128, - 243, - 156, - 44, - 243, - 100 + "account": { + "program_owner": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 ], - "nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271", - "pub_account_signing_key": [ - 54, - 90, - 62, - 225, - 71, - 225, - 228, - 148, - 143, - 53, - 210, - 23, - 137, - 158, - 171, - 156, - 48, - 7, - 139, - 52, - 117, - 242, - 214, - 7, - 99, - 29, - 122, - 184, - 59, - 116, - 144, - 107 - ], - "top_secret_key_holder": { - "secret_spending_key": "80A186737C8D38B4288A03F0F589957D9C040D79C19F3E0CC4BA80F8494E5179" - }, - "utxo_secret_key_holder": { - "nullifier_secret_key": "746928E63F0984F6F4818933493CE9C067562D9CB932FDC06D82C86CDF6D7122", - "viewing_secret_key": "89176CF4BC9E673807643FD52110EF99D4894335AFB10D881AC0B5041FE1FCB7" - }, - "viewing_public_key": "026072A8F83FEC3472E30CDD4767683F30B91661D25B1040AD9A5FC2E01D659F99" - }, - "utxos": {} + "balance": 20000, + "nonce": 0, + "data": [] + } } ] -} \ No newline at end of file +} + diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index 1f9684d..812e44f 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -20,8 +20,8 @@ struct Args { test_name: String, } -pub const ACC_SENDER: &str = "0d96dfcc414019380c9dde0cd3dce5aac90fb5443bf871108741aeafde552ad7"; -pub const ACC_RECEIVER: &str = "974870e9be8d0ac08aa83b3fc7a7a686291d8732508aba98b36080f39c2cf364"; +pub const ACC_SENDER: &str = "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f"; +pub const ACC_RECEIVER: &str = "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766"; pub const TIME_TO_WAIT_FOR_BLOCK_SECONDS: u64 = 12; @@ -156,7 +156,9 @@ pub async fn test_failure() { let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap(); - wallet::execute_subcommand(command).await.unwrap(); + let failed_send = wallet::execute_subcommand(command).await; + + assert!(failed_send.is_err()); info!("Waiting for next block creation"); tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; diff --git a/accounts/Cargo.toml b/key_protocol/Cargo.toml similarity index 81% rename from accounts/Cargo.toml rename to key_protocol/Cargo.toml index ffd500a..2f2bb07 100644 --- a/accounts/Cargo.toml +++ b/key_protocol/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "accounts" +name = "key_protocol" version = "0.1.0" edition = "2021" @@ -17,9 +17,10 @@ hex.workspace = true aes-gcm.workspace = true lazy_static.workspace = true tiny-keccak.workspace = true - -[dependencies.utxo] -path = "../utxo" +nssa-core = { path = "../nssa/core" } [dependencies.common] path = "../common" + +[dependencies.nssa] +path = "../nssa" diff --git a/accounts/src/key_management/constants_types.rs b/key_protocol/src/key_management/constants_types.rs similarity index 100% rename from accounts/src/key_management/constants_types.rs rename to key_protocol/src/key_management/constants_types.rs diff --git a/accounts/src/key_management/ephemeral_key_holder.rs b/key_protocol/src/key_management/ephemeral_key_holder.rs similarity index 100% rename from accounts/src/key_management/ephemeral_key_holder.rs rename to key_protocol/src/key_management/ephemeral_key_holder.rs diff --git a/accounts/src/key_management/mod.rs b/key_protocol/src/key_management/mod.rs similarity index 79% rename from accounts/src/key_management/mod.rs rename to key_protocol/src/key_management/mod.rs index c1a78fb..bc6d14c 100644 --- a/accounts/src/key_management/mod.rs +++ b/key_protocol/src/key_management/mod.rs @@ -1,13 +1,14 @@ +use std::collections::HashMap; + use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit}; use constants_types::{CipherText, Nonce}; use elliptic_curve::point::AffineCoordinates; -use k256::{ecdsa::SigningKey, AffinePoint, FieldBytes}; +use k256::AffinePoint; use log::info; -use rand::{rngs::OsRng, RngCore}; use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder}; use serde::{Deserialize, Serialize}; -use crate::account_core::PublicKey; +use crate::key_protocol_core::PublicKey; pub type PublicAccountSigningKey = [u8; 32]; pub mod constants_types; @@ -16,15 +17,16 @@ pub mod secret_holders; #[derive(Serialize, Deserialize, Clone, Debug)] ///Entrypoint to key management -pub struct AddressKeyHolder { +pub struct KeyChain { top_secret_key_holder: TopSecretKeyHolder, pub utxo_secret_key_holder: UTXOSecretKeyHolder, - pub_account_signing_key: PublicAccountSigningKey, + ///Map for all users accounts + pub_account_signing_keys: HashMap, pub nullifer_public_key: PublicKey, pub viewing_public_key: PublicKey, } -impl AddressKeyHolder { +impl KeyChain { pub fn new_os_random() -> Self { //Currently dropping SeedHolder at the end of initialization. //Now entirely sure if we need it in the future. @@ -36,26 +38,50 @@ impl AddressKeyHolder { let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key(); let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key(); - let pub_account_signing_key = { - let mut bytes = [0; 32]; - OsRng.fill_bytes(&mut bytes); - bytes - }; + Self { + top_secret_key_holder, + utxo_secret_key_holder, + nullifer_public_key, + viewing_public_key, + pub_account_signing_keys: HashMap::new(), + } + } + + pub fn new_os_random_with_accounts(accounts: HashMap) -> Self { + //Currently dropping SeedHolder at the end of initialization. + //Now entirely sure if we need it in the future. + let seed_holder = SeedHolder::new_os_random(); + let top_secret_key_holder = seed_holder.produce_top_secret_key_holder(); + + let utxo_secret_key_holder = top_secret_key_holder.produce_utxo_secret_holder(); + + let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key(); + let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key(); Self { top_secret_key_holder, utxo_secret_key_holder, nullifer_public_key, viewing_public_key, - pub_account_signing_key, + pub_account_signing_keys: accounts, } } + pub fn generate_new_private_key(&mut self) -> nssa::Address { + let private_key = nssa::PrivateKey::new_os_random(); + let address = nssa::Address::from(&nssa::PublicKey::new_from_private_key(&private_key)); + + self.pub_account_signing_keys.insert(address, private_key); + + address + } + /// Returns the signing key for public transaction signatures - pub fn get_pub_account_signing_key(&self) -> SigningKey { - let field_bytes = FieldBytes::from_slice(&self.pub_account_signing_key); - // TODO: remove unwrap - SigningKey::from_bytes(field_bytes).unwrap() + pub fn get_pub_account_signing_key( + &self, + address: &nssa::Address, + ) -> Option<&nssa::PrivateKey> { + self.pub_account_signing_keys.get(address) } pub fn calculate_shared_secret_receiver( @@ -120,14 +146,14 @@ mod tests { use elliptic_curve::point::AffineCoordinates; use k256::{AffinePoint, ProjectivePoint, Scalar}; - use crate::{account_core::address, key_management::ephemeral_key_holder::EphemeralKeyHolder}; + use crate::key_management::ephemeral_key_holder::EphemeralKeyHolder; use super::*; #[test] fn test_new_os_random() { - // Ensure that a new AddressKeyHolder instance can be created without errors. - let address_key_holder = AddressKeyHolder::new_os_random(); + // Ensure that a new KeyChain instance can be created without errors. + let address_key_holder = KeyChain::new_os_random(); // Check that key holder fields are initialized with expected types assert!(!Into::::into( @@ -140,7 +166,7 @@ mod tests { #[test] fn test_calculate_shared_secret_receiver() { - let address_key_holder = AddressKeyHolder::new_os_random(); + let address_key_holder = KeyChain::new_os_random(); // Generate a random ephemeral public key sender let scalar = Scalar::random(&mut OsRng); @@ -156,7 +182,7 @@ mod tests { #[test] fn test_decrypt_data() { - let address_key_holder = AddressKeyHolder::new_os_random(); + let address_key_holder = KeyChain::new_os_random(); // Generate an ephemeral key and shared secret let ephemeral_public_key_sender = @@ -187,8 +213,8 @@ mod tests { #[test] fn test_new_os_random_initialization() { - // Ensure that AddressKeyHolder is initialized correctly - let address_key_holder = AddressKeyHolder::new_os_random(); + // Ensure that KeyChain is initialized correctly + let address_key_holder = KeyChain::new_os_random(); // Check that key holder fields are initialized with expected types and values assert!(!Into::::into( @@ -201,7 +227,7 @@ mod tests { #[test] fn test_calculate_shared_secret_with_identity_point() { - let address_key_holder = AddressKeyHolder::new_os_random(); + let address_key_holder = KeyChain::new_os_random(); // Use identity point as ephemeral public key let identity_point = AffinePoint::identity(); @@ -216,7 +242,7 @@ mod tests { #[test] #[should_panic] fn test_decrypt_data_with_incorrect_nonce() { - let address_key_holder = AddressKeyHolder::new_os_random(); + let address_key_holder = KeyChain::new_os_random(); // Generate ephemeral public key and shared secret let scalar = Scalar::random(OsRng); @@ -249,7 +275,7 @@ mod tests { #[test] #[should_panic] fn test_decrypt_data_with_incorrect_ciphertext() { - let address_key_holder = AddressKeyHolder::new_os_random(); + let address_key_holder = KeyChain::new_os_random(); // Generate ephemeral public key and shared secret let scalar = Scalar::random(OsRng); @@ -284,7 +310,7 @@ mod tests { #[test] fn test_encryption_decryption_round_trip() { - let address_key_holder = AddressKeyHolder::new_os_random(); + let address_key_holder = KeyChain::new_os_random(); // Generate ephemeral key and shared secret let scalar = Scalar::random(OsRng); @@ -302,7 +328,7 @@ mod tests { .encrypt(nonce, plaintext.as_ref()) .expect("encryption failure"); - // Decrypt the data using the `AddressKeyHolder` instance + // Decrypt the data using the `KeyChain` instance let decrypted_data = address_key_holder .decrypt_data( ephemeral_public_key_sender, @@ -317,12 +343,15 @@ mod tests { #[test] fn test_get_public_account_signing_key() { - let address_key_holder = AddressKeyHolder::new_os_random(); - let signing_key = address_key_holder.get_pub_account_signing_key(); - assert_eq!( - signing_key.to_bytes().as_slice(), - address_key_holder.pub_account_signing_key - ); + let mut address_key_holder = KeyChain::new_os_random(); + + let address = address_key_holder.generate_new_private_key(); + + let is_private_key_generated = address_key_holder + .get_pub_account_signing_key(&address) + .is_some(); + + assert!(is_private_key_generated); } #[test] @@ -335,19 +364,11 @@ mod tests { let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key(); let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key(); - let pub_account_signing_key = { - let mut bytes = [0; 32]; - OsRng.fill_bytes(&mut bytes); - bytes - }; + let pub_account_signing_key = nssa::PrivateKey::new_os_random(); - //Address is a Keccak(verification_key) - let field_bytes = FieldBytes::from_slice(&pub_account_signing_key); - let signing_key = SigningKey::from_bytes(field_bytes).unwrap(); + let public_key = nssa::PublicKey::new_from_private_key(&pub_account_signing_key); - let verifying_key = signing_key.verifying_key(); - - let address = address::from_public_key(verifying_key); + let address = nssa::Address::from(&public_key); println!("======Prerequisites======"); println!(); @@ -373,7 +394,7 @@ mod tests { println!("======Public data======"); println!(); - println!("Address{:?}", hex::encode(address)); + println!("Address{:?}", hex::encode(address.value())); println!( "Nulifier public key {:?}", hex::encode(serde_json::to_vec(&nullifer_public_key).unwrap()) diff --git a/accounts/src/key_management/secret_holders.rs b/key_protocol/src/key_management/secret_holders.rs similarity index 100% rename from accounts/src/key_management/secret_holders.rs rename to key_protocol/src/key_management/secret_holders.rs diff --git a/key_protocol/src/key_protocol_core/mod.rs b/key_protocol/src/key_protocol_core/mod.rs new file mode 100644 index 0000000..3b8092e --- /dev/null +++ b/key_protocol/src/key_protocol_core/mod.rs @@ -0,0 +1,171 @@ +use std::collections::HashMap; + +use anyhow::Result; +use k256::AffinePoint; +use serde::{Deserialize, Serialize}; + +use crate::key_management::{ + constants_types::{CipherText, Nonce}, + ephemeral_key_holder::EphemeralKeyHolder, + KeyChain, +}; + +pub type PublicKey = AffinePoint; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct NSSAUserData { + pub key_holder: KeyChain, + pub accounts: HashMap, +} + +///A strucure, which represents all the visible(public) information +/// +/// known to each node about account `address` +/// +/// Main usage is to encode data for other account +#[derive(Serialize, Clone)] +pub struct NSSAUserDataPublicMask { + pub nullifier_public_key: AffinePoint, + pub viewing_public_key: AffinePoint, +} + +impl NSSAUserDataPublicMask { + pub fn encrypt_data( + ephemeral_key_holder: &EphemeralKeyHolder, + viewing_public_key_receiver: AffinePoint, + data: &[u8], + ) -> (CipherText, Nonce) { + //Using of parent NSSAUserData fuction + NSSAUserData::encrypt_data(ephemeral_key_holder, viewing_public_key_receiver, data) + } + + //ToDo: Part of a private keys update + // pub fn make_tag(&self) -> Tag { + // self.address.value()[0] + // } +} + +impl NSSAUserData { + pub fn new() -> Self { + let key_holder = KeyChain::new_os_random(); + + Self { + key_holder, + accounts: HashMap::new(), + } + } + + pub fn new_with_accounts( + accounts_keys: HashMap, + accounts: HashMap, + ) -> Self { + let key_holder = KeyChain::new_os_random_with_accounts(accounts_keys); + + Self { + key_holder, + accounts, + } + } + + pub fn generate_new_account(&mut self) -> nssa::Address { + let address = self.key_holder.generate_new_private_key(); + self.accounts + .insert(address, nssa_core::account::Account::default()); + + address + } + + pub fn get_account_balance(&self, address: &nssa::Address) -> u128 { + self.accounts + .get(address) + .map(|acc| acc.balance) + .unwrap_or(0) + } + + pub fn get_account(&self, address: &nssa::Address) -> Option<&nssa_core::account::Account> { + self.accounts.get(address) + } + + pub fn get_account_signing_key(&self, address: &nssa::Address) -> Option<&nssa::PrivateKey> { + self.key_holder.get_pub_account_signing_key(address) + } + + pub fn encrypt_data( + ephemeral_key_holder: &EphemeralKeyHolder, + viewing_public_key_receiver: AffinePoint, + data: &[u8], + ) -> (CipherText, Nonce) { + ephemeral_key_holder.encrypt_data(viewing_public_key_receiver, data) + } + + pub fn decrypt_data( + &self, + ephemeral_public_key_sender: AffinePoint, + ciphertext: CipherText, + nonce: Nonce, + ) -> Result, aes_gcm::Error> { + self.key_holder + .decrypt_data(ephemeral_public_key_sender, ciphertext, nonce) + } + + pub fn update_account_balance(&mut self, address: nssa::Address, new_balance: u128) { + self.accounts + .entry(address) + .and_modify(|acc| acc.balance = new_balance) + .or_default(); + } + + //ToDo: Part of a private keys update + // pub fn make_tag(&self) -> Tag { + // self.address.value()[0] + // } + + ///Produce account public mask + pub fn make_account_public_mask(&self) -> NSSAUserDataPublicMask { + NSSAUserDataPublicMask { + nullifier_public_key: self.key_holder.nullifer_public_key, + viewing_public_key: self.key_holder.viewing_public_key, + } + } +} + +impl Default for NSSAUserData { + fn default() -> Self { + Self::new() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_new_account() { + let mut user_data = NSSAUserData::new(); + + let addr = user_data.generate_new_account(); + + assert_eq!(user_data.get_account_balance(&addr), 0); + } + + #[test] + fn test_update_balance() { + let mut user_data = NSSAUserData::new(); + + let address = user_data.generate_new_account(); + + user_data.update_account_balance(address, 500); + + assert_eq!(user_data.get_account_balance(&address), 500); + } + + //ToDo: Part of a private keys update + // #[test] + // fn accounts_accounts_mask_tag_consistency() { + // let account = NSSAUserData::new(); + + // let account_mask = account.make_account_public_mask(); + + // assert_eq!(account.make_tag(), account_mask.make_tag()); + // } +} diff --git a/key_protocol/src/lib.rs b/key_protocol/src/lib.rs new file mode 100644 index 0000000..1a52c20 --- /dev/null +++ b/key_protocol/src/lib.rs @@ -0,0 +1,2 @@ +pub mod key_management; +pub mod key_protocol_core; diff --git a/mempool/src/lib.rs b/mempool/src/lib.rs index 5298bfc..ab1c5d3 100644 --- a/mempool/src/lib.rs +++ b/mempool/src/lib.rs @@ -1,14 +1,10 @@ use std::collections::VecDeque; -use mempoolitem::MemPoolItem; - -pub mod mempoolitem; - -pub struct MemPool { +pub struct MemPool { items: VecDeque, } -impl MemPool { +impl MemPool { pub fn new() -> Self { Self { items: VecDeque::new(), @@ -55,7 +51,7 @@ impl MemPool { } } -impl Default for MemPool { +impl Default for MemPool { fn default() -> Self { Self::new() } @@ -74,14 +70,6 @@ mod tests { id: ItemId, } - impl MemPoolItem for TestItem { - type Identifier = ItemId; - - fn identifier(&self) -> Self::Identifier { - self.id - } - } - fn test_item_with_id(id: u64) -> TestItem { TestItem { id } } diff --git a/mempool/src/mempoolitem.rs b/mempool/src/mempoolitem.rs deleted file mode 100644 index b3e3530..0000000 --- a/mempool/src/mempoolitem.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub trait MemPoolItem { - type Identifier; - fn identifier(&self) -> Self::Identifier; -} diff --git a/nssa/Cargo.toml b/nssa/Cargo.toml new file mode 100644 index 0000000..5a579fd --- /dev/null +++ b/nssa/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "nssa" +version = "0.1.0" +edition = "2024" + +[dependencies] +thiserror = "2.0.12" +risc0-zkvm = "2.3.1" +nssa-core = { path = "core" } +program-methods = { path = "program_methods" } +serde = "1.0.219" +sha2 = "0.10.9" +secp256k1 = "0.31.1" +rand = "0.8" +hex = "0.4.3" +anyhow.workspace = true + +[dev-dependencies] +test-program-methods = { path = "test_program_methods" } diff --git a/nssa/core/Cargo.toml b/nssa/core/Cargo.toml new file mode 100644 index 0000000..feb907d --- /dev/null +++ b/nssa/core/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "nssa-core" +version = "0.1.0" +edition = "2024" + +[dependencies] +risc0-zkvm = "2.3.1" +serde = { version = "1.0", default-features = false } diff --git a/nssa/core/src/account/mod.rs b/nssa/core/src/account/mod.rs new file mode 100644 index 0000000..9d564c4 --- /dev/null +++ b/nssa/core/src/account/mod.rs @@ -0,0 +1,56 @@ +use serde::{Deserialize, Serialize}; + +use crate::program::ProgramId; + +pub type Nonce = u128; +type Data = Vec; + +/// Account to be used both in public and private contexts +#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct Account { + pub program_owner: ProgramId, + pub balance: u128, + pub data: Data, + pub nonce: Nonce, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct AccountWithMetadata { + pub account: Account, + pub is_authorized: bool, +} + +#[cfg(test)] +mod tests { + use crate::program::DEFAULT_PROGRAM_ID; + + use super::*; + + #[test] + fn test_zero_balance_account_data_creation() { + let new_acc = Account::default(); + + assert_eq!(new_acc.balance, 0); + } + + #[test] + fn test_zero_nonce_account_data_creation() { + let new_acc = Account::default(); + + assert_eq!(new_acc.nonce, 0); + } + + #[test] + fn test_empty_data_account_data_creation() { + let new_acc = Account::default(); + + assert!(new_acc.data.is_empty()); + } + + #[test] + fn test_default_program_owner_account_data_creation() { + let new_acc = Account::default(); + + assert_eq!(new_acc.program_owner, DEFAULT_PROGRAM_ID); + } +} diff --git a/nssa/core/src/lib.rs b/nssa/core/src/lib.rs new file mode 100644 index 0000000..d20620e --- /dev/null +++ b/nssa/core/src/lib.rs @@ -0,0 +1,2 @@ +pub mod account; +pub mod program; diff --git a/nssa/core/src/program.rs b/nssa/core/src/program.rs new file mode 100644 index 0000000..9b99a61 --- /dev/null +++ b/nssa/core/src/program.rs @@ -0,0 +1,64 @@ +use crate::account::{Account, AccountWithMetadata}; +use risc0_zkvm::serde::Deserializer; +use risc0_zkvm::{DeserializeOwned, guest::env}; + +pub type ProgramId = [u32; 8]; +pub type InstructionData = Vec; +pub const DEFAULT_PROGRAM_ID: ProgramId = [0; 8]; + +pub fn read_nssa_inputs() -> (Vec, T) { + let pre_states: Vec = env::read(); + let words: InstructionData = env::read(); + let instruction_data = T::deserialize(&mut Deserializer::new(words.as_ref())).unwrap(); + (pre_states, instruction_data) +} +/// Validates well-behaved program execution +/// +/// # Parameters +/// - `pre_states`: The list of input accounts, each annotated with authorization metadata. +/// - `post_states`: The list of resulting accounts after executing the program logic. +/// - `executing_program_id`: The identifier of the program that was executed. +pub fn validate_execution( + pre_states: &[AccountWithMetadata], + post_states: &[Account], + executing_program_id: ProgramId, +) -> bool { + // 1. Lengths must match + if pre_states.len() != post_states.len() { + return false; + } + + for (pre, post) in pre_states.iter().zip(post_states) { + // 2. Nonce must remain unchanged + if pre.account.nonce != post.nonce { + return false; + } + + // 3. Ownership change only allowed from default accounts + if pre.account.program_owner != post.program_owner && pre.account != Account::default() { + return false; + } + + // 4. Decreasing balance only allowed if owned by executing program + if post.balance < pre.account.balance && pre.account.program_owner != executing_program_id { + return false; + } + + // 5. Data changes only allowed if owned by executing program + if pre.account.data != post.data + && (executing_program_id != pre.account.program_owner + || executing_program_id != post.program_owner) + { + return false; + } + } + + // 6. Total balance is preserved + let total_balance_pre_states: u128 = pre_states.iter().map(|pre| pre.account.balance).sum(); + let total_balance_post_states: u128 = post_states.iter().map(|post| post.balance).sum(); + if total_balance_pre_states != total_balance_post_states { + return false; + } + + true +} diff --git a/zkvm/test_methods/Cargo.toml b/nssa/program_methods/Cargo.toml similarity index 51% rename from zkvm/test_methods/Cargo.toml rename to nssa/program_methods/Cargo.toml index 48f27b8..ea7e36b 100644 --- a/zkvm/test_methods/Cargo.toml +++ b/nssa/program_methods/Cargo.toml @@ -1,10 +1,10 @@ [package] -name = "test-methods" +name = "program-methods" version = "0.1.0" edition = "2021" [build-dependencies] -risc0-build = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } +risc0-build = { version = "2.3.1" } [package.metadata.risc0] methods = ["guest"] diff --git a/zkvm/test_methods/build.rs b/nssa/program_methods/build.rs similarity index 100% rename from zkvm/test_methods/build.rs rename to nssa/program_methods/build.rs diff --git a/Cargo.lock b/nssa/program_methods/guest/Cargo.lock similarity index 55% rename from Cargo.lock rename to nssa/program_methods/guest/Cargo.lock index 9417564..1d3063f 100644 --- a/Cargo.lock +++ b/nssa/program_methods/guest/Cargo.lock @@ -2,288 +2,13 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "accounts" -version = "0.1.0" -dependencies = [ - "aes-gcm", - "anyhow", - "common", - "elliptic-curve", - "env_logger", - "hex", - "k256", - "lazy_static", - "log", - "rand 0.8.5", - "serde", - "serde_json", - "sha2", - "tiny-keccak", - "utxo", -] - -[[package]] -name = "actix" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de7fa236829ba0841304542f7614c42b80fca007455315c45c785ccfa873a85b" -dependencies = [ - "actix-macros", - "actix-rt", - "actix_derive", - "bitflags 2.9.1", - "bytes", - "crossbeam-channel", - "futures-core", - "futures-sink", - "futures-task", - "futures-util", - "log", - "once_cell", - "parking_lot", - "pin-project-lite", - "smallvec", - "tokio", - "tokio-util", -] - -[[package]] -name = "actix-codec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" -dependencies = [ - "bitflags 2.9.1", - "bytes", - "futures-core", - "futures-sink", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-cors" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0346d8c1f762b41b458ed3145eea914966bb9ad20b9be0d6d463b20d45586370" -dependencies = [ - "actix-utils", - "actix-web", - "derive_more 0.99.20", - "futures-util", - "log", - "once_cell", - "smallvec", -] - -[[package]] -name = "actix-http" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44dfe5c9e0004c623edc65391dfd51daa201e7e30ebd9c9bedf873048ec32bc2" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "base64 0.22.1", - "bitflags 2.9.1", - "bytes", - "bytestring", - "derive_more 2.0.1", - "encoding_rs", - "foldhash", - "futures-core", - "h2", - "http 0.2.12", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "mime", - "percent-encoding", - "pin-project-lite", - "rand 0.9.2", - "sha1", - "smallvec", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" -dependencies = [ - "quote", - "syn 2.0.104", -] - -[[package]] -name = "actix-router" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" -dependencies = [ - "bytestring", - "cfg-if", - "http 0.2.12", - "regex", - "regex-lite", - "serde", - "tracing", -] - -[[package]] -name = "actix-rt" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" -dependencies = [ - "actix-macros", - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65064ea4a457eaf07f2fba30b4c695bf43b721790e9530d26cb6f9019ff7502" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "mio", - "socket2 0.5.10", - "tokio", - "tracing", -] - -[[package]] -name = "actix-service" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e46f36bf0e5af44bdc4bdb36fbbd421aa98c79a9bce724e1edeb3894e10dc7f" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "actix-utils" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" -dependencies = [ - "local-waker", - "pin-project-lite", -] - -[[package]] -name = "actix-web" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27e8fe9ba4ae613c21f677c2cfaf0696c3744030c6f485b34634e502d6bb379" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "ahash 0.7.8", - "bytes", - "bytestring", - "cfg-if", - "derive_more 0.99.20", - "encoding_rs", - "futures-core", - "futures-util", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "pin-project-lite", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2 0.4.10", - "time", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "actix_derive" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6ac1e58cded18cb28ddc17143c4dea5345b3ad575e14f32f66e4054a56eb271" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "addchain" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" -dependencies = [ - "num-bigint 0.3.3", - "num-integer", - "num-traits", -] - -[[package]] -name = "addr2line" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" -dependencies = [ - "cpp_demangle", - "fallible-iterator", - "gimli 0.29.0", - "memmap2", - "object 0.35.0", - "rustc-demangle", - "smallvec", -] - [[package]] name = "addr2line" version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ - "gimli 0.31.1", + "gimli", ] [[package]] @@ -292,52 +17,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom 0.2.16", - "once_cell", - "version_check", -] - [[package]] name = "ahash" version = "0.8.12" @@ -365,82 +44,11 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "anstream" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" -dependencies = [ - "windows-sys 0.60.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.60.2", -] - [[package]] name = "anyhow" version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" -dependencies = [ - "backtrace", -] - -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - -[[package]] -name = "arbitrary" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" -dependencies = [ - "derive_arbitrary", -] [[package]] name = "ark-bn254" @@ -460,7 +68,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0c292754729c8a190e50414fd1a37093c786c709899f29c9f7daccecfa855e" dependencies = [ - "ahash 0.8.12", + "ahash", "ark-crypto-primitives-macros", "ark-ec", "ark-ff", @@ -493,7 +101,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" dependencies = [ - "ahash 0.8.12", + "ahash", "ark-ff", "ark-poly", "ark-serialize", @@ -501,8 +109,8 @@ dependencies = [ "educe", "fnv", "hashbrown 0.15.4", - "itertools 0.13.0", - "num-bigint 0.4.6", + "itertools", + "num-bigint", "num-integer", "num-traits", "zeroize", @@ -521,8 +129,8 @@ dependencies = [ "arrayvec", "digest", "educe", - "itertools 0.13.0", - "num-bigint 0.4.6", + "itertools", + "num-bigint", "num-traits", "paste", "zeroize", @@ -544,7 +152,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" dependencies = [ - "num-bigint 0.4.6", + "num-bigint", "num-traits", "proc-macro2", "quote", @@ -572,7 +180,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" dependencies = [ - "ahash 0.8.12", + "ahash", "ark-ff", "ark-serialize", "ark-std", @@ -592,7 +200,7 @@ dependencies = [ "ark-relations", "ark-std", "educe", - "num-bigint 0.4.6", + "num-bigint", "num-integer", "num-traits", "tracing", @@ -620,7 +228,7 @@ dependencies = [ "ark-std", "arrayvec", "digest", - "num-bigint 0.4.6", + "num-bigint", ] [[package]] @@ -668,21 +276,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "atomic-polyfill" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" -dependencies = [ - "critical-section", -] - -[[package]] -name = "auto_ops" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7460f7dd8e100147b82a63afca1a20eb6c231ee36b90ba7272e14951cb58af59" - [[package]] name = "autocfg" version = "1.5.0" @@ -695,39 +288,21 @@ version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ - "addr2line 0.24.2", + "addr2line", "cfg-if", "libc", "miniz_oxide", - "object 0.36.7", + "object", "rustc-demangle", "windows-targets 0.52.6", ] -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64ct" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" - [[package]] name = "bincode" version = "1.3.3" @@ -737,39 +312,12 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.65.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.104", -] - [[package]] name = "bit-vec" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" -[[package]] -name = "bitcoin-private" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" - [[package]] name = "bitflags" version = "1.3.2" @@ -782,18 +330,6 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "blake2" version = "0.10.6" @@ -821,11 +357,12 @@ dependencies = [ [[package]] name = "bonsai-sdk" version = "1.4.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bce8d6acc5286a16e94c29e9c885d1869358885e08a6feeb6bc54e36fe20055" dependencies = [ "duplicate", "maybe-async", - "reqwest 0.12.22", + "reqwest", "serde", "thiserror 1.0.69", ] @@ -894,25 +431,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bytestring" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e465647ae23b2823b0753f50decb2d5a86d2bb2cac04788fafd1f80e45378e5f" -dependencies = [ - "bytes", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" -dependencies = [ - "cc", - "pkg-config", -] - [[package]] name = "camino" version = "1.1.10" @@ -951,20 +469,9 @@ version = "1.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" dependencies = [ - "jobserver", - "libc", "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.1" @@ -977,67 +484,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "4.5.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "clap_lex" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" - [[package]] name = "cobs" version = "0.3.0" @@ -1047,44 +493,12 @@ dependencies = [ "thiserror 2.0.12", ] -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[package]] -name = "common" -version = "0.1.0" -dependencies = [ - "anyhow", - "elliptic-curve", - "hex", - "k256", - "log", - "rand 0.8.5", - "reqwest 0.11.27", - "risc0-zkvm", - "rs_merkle", - "secp256k1-zkp", - "serde", - "serde_json", - "sha2", - "thiserror 1.0.69", -] - [[package]] name = "const-oid" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "core-foundation" version = "0.9.4" @@ -1112,15 +526,6 @@ dependencies = [ "libc", ] -[[package]] -name = "cpp_demangle" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" -dependencies = [ - "cfg-if", -] - [[package]] name = "cpufeatures" version = "0.2.17" @@ -1130,73 +535,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "critical-section" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -1204,65 +542,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "cust" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6cc71911e179f12483b9734120b45bd00bf64fab085cc4818428523eedd469" -dependencies = [ - "bitflags 1.3.2", - "bytemuck", - "cust_core", - "cust_derive", - "cust_raw", - "find_cuda_helper", -] - -[[package]] -name = "cust_core" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039f79662cb8f890cbf335e818cd522d6e3a53fe63f61d1aaaf859cd3d975f06" -dependencies = [ - "cust_derive", - "glam", - "mint", - "vek", -] - -[[package]] -name = "cust_derive" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3bc95fe629aed92b2423de6ccff9e40174b21d19cb6ee6281a4d04ac72f66" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cust_raw" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf40d6ade12cb9828bbc844b9875c7b93d25e67a3c9bf61c7aa3ae09e402bf8" -dependencies = [ - "find_cuda_helper", -] - [[package]] name = "darling" version = "0.20.11" @@ -1298,26 +580,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" -dependencies = [ - "powerfmt", -] - [[package]] name = "derivative" version = "2.2.0" @@ -1329,17 +591,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_arbitrary" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "derive_builder" version = "0.20.2" @@ -1371,19 +622,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "derive_more" -version = "0.99.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.104", -] - [[package]] name = "derive_more" version = "2.0.1" @@ -1417,15 +655,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "directories" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" -dependencies = [ - "dirs-sys", -] - [[package]] name = "dirs" version = "5.0.1" @@ -1470,20 +699,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" -[[package]] -name = "downloader" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac1e888d6830712d565b2f3a974be3200be9296bc1b03db8251a4cbf18a4a34" -dependencies = [ - "digest", - "futures", - "rand 0.8.5", - "reqwest 0.12.22", - "thiserror 1.0.69", - "tokio", -] - [[package]] name = "duplicate" version = "1.0.0" @@ -1494,21 +709,6 @@ dependencies = [ "proc-macro-error", ] -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest", - "elliptic-curve", - "rfc6979", - "serdect", - "signature", - "spki", -] - [[package]] name = "educe" version = "0.6.0" @@ -1533,27 +733,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest", - "ff", - "generic-array", - "group", - "pem-rfc7468", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "serdect", - "subtle", - "zeroize", -] - [[package]] name = "embedded-io" version = "0.4.0" @@ -1575,26 +754,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "enum-map" -version = "2.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" -dependencies = [ - "enum-map-derive", -] - -[[package]] -name = "enum-map-derive" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "enum-ordinalize" version = "4.3.0" @@ -1615,35 +774,12 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "env_logger" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" -[[package]] -name = "erased-serde" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" -dependencies = [ - "serde", - "typeid", -] - [[package]] name = "errno" version = "0.3.13" @@ -1654,86 +790,18 @@ dependencies = [ "windows-sys 0.60.2", ] -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - [[package]] name = "fastrand" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "ff" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" -dependencies = [ - "bitvec", - "byteorder", - "ff_derive", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff_derive" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f10d12652036b0e99197587c6ba87a8fc3031986499973c030d8b44fcc151b60" -dependencies = [ - "addchain", - "num-bigint 0.3.3", - "num-integer", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "find_cuda_helper" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f9e65c593dd01ac77daad909ea4ad17f0d6d1776193fc8ea766356177abdad" -dependencies = [ - "glob", -] - -[[package]] -name = "flate2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared 0.1.1", -] - [[package]] name = "foreign-types" version = "0.5.0" @@ -1741,7 +809,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared 0.3.1", + "foreign-types-shared", ] [[package]] @@ -1755,12 +823,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -1776,27 +838,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" version = "0.3.31" @@ -1813,17 +854,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - [[package]] name = "futures-io" version = "0.3.31" @@ -1859,7 +889,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1879,7 +908,6 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] @@ -1909,102 +937,19 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "gimli" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" -dependencies = [ - "fallible-iterator", - "stable_deref_trait", -] - [[package]] name = "gimli" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" -[[package]] -name = "glam" -version = "0.20.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43e957e744be03f5801a55472f593d43fabdebf25a4585db250f04d86b1675f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.8", -] - [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.12", + "ahash", ] [[package]] @@ -2025,20 +970,6 @@ dependencies = [ "hashbrown 0.14.5", ] -[[package]] -name = "heapless" -version = "0.7.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" -dependencies = [ - "atomic-polyfill", - "hash32", - "rustc_version", - "serde", - "spin", - "stable_deref_trait", -] - [[package]] name = "heck" version = "0.4.1" @@ -2051,12 +982,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - [[package]] name = "hex" version = "0.4.3" @@ -2069,35 +994,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.3.1" @@ -2109,17 +1005,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.1" @@ -2127,7 +1012,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.3.1", + "http", ] [[package]] @@ -2138,8 +1023,8 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.3.1", - "http-body 1.0.1", + "http", + "http-body", "pin-project-lite", ] @@ -2149,42 +1034,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humantime" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" - -[[package]] -name = "hyper" -version = "0.14.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.10", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.6.0" @@ -2194,8 +1043,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.3.1", - "http-body 1.0.1", + "http", + "http-body", "httparse", "itoa", "pin-project-lite", @@ -2210,8 +1059,8 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.3.1", - "hyper 1.6.0", + "http", + "hyper", "hyper-util", "rustls", "rustls-pki-types", @@ -2221,33 +1070,20 @@ dependencies = [ "webpki-roots", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper 0.14.32", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "hyper-util" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-channel", "futures-core", "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "hyper 1.6.0", + "http", + "http-body", + "hyper", "ipnet", "libc", "percent-encoding", @@ -2387,48 +1223,6 @@ dependencies = [ "hashbrown 0.15.4", ] -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - -[[package]] -name = "integration_tests" -version = "0.1.0" -dependencies = [ - "accounts", - "actix", - "actix-web", - "anyhow", - "clap", - "common", - "env_logger", - "hex", - "log", - "sequencer_core", - "sequencer_rpc", - "sequencer_runner", - "serde", - "serde_json", - "tempfile", - "tokio", - "toml 0.7.8", - "wallet", -] - -[[package]] -name = "inventory" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83" -dependencies = [ - "rustversion", -] - [[package]] name = "io-uring" version = "0.7.9" @@ -2456,41 +1250,6 @@ dependencies = [ "serde", ] -[[package]] -name = "is-terminal" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -2500,31 +1259,12 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "jobserver" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" -dependencies = [ - "getrandom 0.3.3", - "libc", -] - [[package]] name = "js-sys" version = "0.3.77" @@ -2535,21 +1275,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "k256" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "serdect", - "sha2", - "signature", -] - [[package]] name = "keccak" version = "0.1.5" @@ -2559,12 +1284,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - [[package]] name = "lazy-regex" version = "3.4.1" @@ -2597,28 +1316,12 @@ dependencies = [ "spin", ] -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" -[[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.53.3", -] - [[package]] name = "libm" version = "0.2.15" @@ -2635,49 +1338,6 @@ dependencies = [ "libc", ] -[[package]] -name = "librocksdb-sys" -version = "0.11.0+8.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" -dependencies = [ - "bindgen", - "bzip2-sys", - "cc", - "glob", - "libc", - "libz-sys", -] - -[[package]] -name = "libz-sys" -version = "1.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "light-poseidon" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3d87542063daaccbfecd78b60f988079b6ec4e089249658b9455075c78d42" -dependencies = [ - "ark-bn254", - "ark-ff", - "num-bigint 0.4.6", - "thiserror 1.0.69", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - [[package]] name = "linux-raw-sys" version = "0.9.4" @@ -2690,123 +1350,18 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" -[[package]] -name = "local-channel" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" -dependencies = [ - "futures-core", - "futures-sink", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" - -[[package]] -name = "lock_api" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" -[[package]] -name = "lru" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" -dependencies = [ - "hashbrown 0.12.3", -] - [[package]] name = "lru-slab" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" -[[package]] -name = "lzma-sys" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "malachite" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fbdf9cb251732db30a7200ebb6ae5d22fe8e11397364416617d2c2cf0c51cb5" -dependencies = [ - "malachite-base", - "malachite-float", - "malachite-nz", - "malachite-q", -] - -[[package]] -name = "malachite-base" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea0ed76adf7defc1a92240b5c36d5368cfe9251640dcce5bd2d0b7c1fd87aeb" -dependencies = [ - "hashbrown 0.14.5", - "itertools 0.11.0", - "libm", - "ryu", -] - -[[package]] -name = "malachite-float" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af9d20db1c73759c1377db7b27575df6f2eab7368809dd62c0a715dc1bcc39f7" -dependencies = [ - "itertools 0.11.0", - "malachite-base", - "malachite-nz", - "malachite-q", -] - -[[package]] -name = "malachite-nz" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34a79feebb2bc9aa7762047c8e5495269a367da6b5a90a99882a0aeeac1841f7" -dependencies = [ - "itertools 0.11.0", - "libm", - "malachite-base", -] - -[[package]] -name = "malachite-q" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f235d5747b1256b47620f5640c2a17a88c7569eebdf27cd9cb130e1a619191" -dependencies = [ - "itertools 0.11.0", - "malachite-base", - "malachite-nz", -] - [[package]] name = "malloc_buf" version = "0.0.6" @@ -2816,16 +1371,6 @@ dependencies = [ "libc", ] -[[package]] -name = "matrixmultiply" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" -dependencies = [ - "autocfg", - "rawpointer", -] - [[package]] name = "maybe-async" version = "0.2.10" @@ -2843,26 +1388,6 @@ version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" -[[package]] -name = "memmap2" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28" -dependencies = [ - "libc", -] - -[[package]] -name = "mempool" -version = "0.1.0" -dependencies = [ - "anyhow", - "env_logger", - "log", - "serde", - "serde_json", -] - [[package]] name = "merlin" version = "3.0.0" @@ -2884,24 +1409,12 @@ dependencies = [ "bitflags 2.9.1", "block", "core-graphics-types", - "foreign-types 0.5.0", + "foreign-types", "log", "objc", "paste", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2911,12 +1424,6 @@ dependencies = [ "adler2", ] -[[package]] -name = "mint" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff" - [[package]] name = "mio" version = "1.0.4" @@ -2924,44 +1431,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "log", "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.59.0", ] -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "ndarray" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" -dependencies = [ - "matrixmultiply", - "num-complex", - "num-integer", - "num-traits", - "portable-atomic", - "portable-atomic-util", - "rawpointer", - "rayon", -] - [[package]] name = "no_std_strings" version = "0.1.3" @@ -2969,24 +1442,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5b0c77c1b780822bc749a33e39aeb2c07584ab93332303babeabb645298a76e" [[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +name = "nssa-core" +version = "0.1.0" dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "num-bigint" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", + "risc0-zkvm", + "serde", ] [[package]] @@ -2999,32 +1459,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "num-integer" version = "0.1.46" @@ -3041,16 +1475,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", -] - -[[package]] -name = "nvtx" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad2e855e8019f99e4b94ac33670eb4e4f570a2e044f3749a0b2c7f83b841e52c" -dependencies = [ - "cc", ] [[package]] @@ -3062,17 +1486,6 @@ dependencies = [ "malloc_buf", ] -[[package]] -name = "object" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" -dependencies = [ - "flate2", - "memchr", - "ruzstd", -] - [[package]] name = "object" version = "0.36.7" @@ -3088,112 +1501,18 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "once_cell_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "openssl" -version = "0.10.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "foreign-types 0.3.2", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "parking_lot" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.6", -] - [[package]] name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -3212,49 +1531,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "portable-atomic" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" - -[[package]] -name = "portable-atomic-util" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" -dependencies = [ - "portable-atomic", -] - [[package]] name = "postcard" version = "1.1.3" @@ -3264,7 +1540,6 @@ dependencies = [ "cobs", "embedded-io 0.4.0", "embedded-io 0.6.1", - "heapless", "serde", ] @@ -3277,12 +1552,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" version = "0.2.21" @@ -3292,23 +1561,13 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" -dependencies = [ - "proc-macro2", - "syn 2.0.104", -] - [[package]] name = "proc-macro-crate" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ - "toml_edit 0.22.27", + "toml_edit", ] [[package]] @@ -3344,6 +1603,14 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "programs" +version = "0.1.0" +dependencies = [ + "nssa-core", + "risc0-zkvm", +] + [[package]] name = "prost" version = "0.13.5" @@ -3361,26 +1628,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.14.0", + "itertools", "proc-macro2", "quote", "syn 2.0.104", ] -[[package]] -name = "puffin" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa9dae7b05c02ec1a6bc9bcf20d8bc64a7dcbf57934107902a872014899b741f" -dependencies = [ - "anyhow", - "byteorder", - "cfg-if", - "itertools 0.10.5", - "once_cell", - "parking_lot", -] - [[package]] name = "quinn" version = "0.11.8" @@ -3392,7 +1645,7 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.1", + "rustc-hash", "rustls", "socket2 0.5.10", "thiserror 2.0.12", @@ -3412,7 +1665,7 @@ dependencies = [ "lru-slab", "rand 0.9.2", "ring", - "rustc-hash 2.1.1", + "rustc-hash", "rustls", "rustls-pki-types", "slab", @@ -3451,19 +1704,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc", "rand_chacha 0.3.1", "rand_core 0.6.4", ] @@ -3503,9 +1749,6 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] [[package]] name = "rand_core" @@ -3516,41 +1759,6 @@ dependencies = [ "getrandom 0.3.3", ] -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.5.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" -dependencies = [ - "bitflags 2.9.1", -] - [[package]] name = "redox_users" version = "0.4.6" @@ -3585,73 +1793,27 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "regex-lite" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" - [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - [[package]] name = "reqwest" version = "0.12.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-channel", "futures-core", "futures-util", - "http 1.3.1", - "http-body 1.0.1", + "http", + "http-body", "http-body-util", - "hyper 1.6.0", + "hyper", "hyper-rustls", "hyper-util", "js-sys", @@ -3664,7 +1826,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tokio-rustls", "tokio-util", @@ -3679,16 +1841,6 @@ dependencies = [ "webpki-roots", ] -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - [[package]] name = "ring" version = "0.17.14" @@ -3703,20 +1855,15 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "ringbuffer" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6368f71f205ff9c33c076d170dd56ebf68e8161c733c0caa07a7a5509ed53" - [[package]] name = "risc0-binfmt" version = "2.0.2" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62eb7025356a233c1bc267c458a2ce56fcfc89b136d813c8a77be14ef1eaf2b1" dependencies = [ "anyhow", "borsh", - "derive_more 2.0.1", + "derive_more", "elf", "lazy_static", "postcard", @@ -3730,7 +1877,8 @@ dependencies = [ [[package]] name = "risc0-build" version = "2.3.1" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ffc0f135e6c1e9851e7e19438d03ff41a9d49199ee4f6c17b8bb30b4f83910" dependencies = [ "anyhow", "cargo_metadata", @@ -3750,155 +1898,71 @@ dependencies = [ "tempfile", ] -[[package]] -name = "risc0-build-kernel" -version = "2.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" -dependencies = [ - "cc", - "directories", - "glob", - "hex", - "rayon", - "sha2", - "tempfile", -] - [[package]] name = "risc0-circuit-keccak" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0094af5a57b020388a03bdd3834959c7d62723f1687be81414ade25104d93263" dependencies = [ "anyhow", "bytemuck", - "cfg-if", - "keccak", "paste", - "rayon", "risc0-binfmt", - "risc0-circuit-keccak-sys", "risc0-circuit-recursion", "risc0-core", - "risc0-sys", "risc0-zkp", "tracing", - "xz2", -] - -[[package]] -name = "risc0-circuit-keccak-sys" -version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" -dependencies = [ - "cc", - "cust", - "derive_more 2.0.1", - "glob", - "risc0-build-kernel", - "risc0-core", - "risc0-sys", - "sppark", ] [[package]] name = "risc0-circuit-recursion" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ebded45c902c2b6939924a1cddd1d06b5d1d4ad1531e8798ebfee78f9c038d" dependencies = [ "anyhow", "bytemuck", - "cfg-if", - "cust", - "downloader", "hex", - "lazy-regex", "metal", - "rand 0.8.5", - "rayon", - "risc0-circuit-recursion-sys", "risc0-core", - "risc0-sys", "risc0-zkp", - "serde", - "sha2", "tracing", - "zip", -] - -[[package]] -name = "risc0-circuit-recursion-sys" -version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" -dependencies = [ - "glob", - "risc0-build-kernel", - "risc0-core", - "risc0-sys", - "sppark", ] [[package]] name = "risc0-circuit-rv32im" version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15030849f8356f01f23c74b37dbfa4283100b594eb634109993e9e005ef45f64" dependencies = [ "anyhow", - "auto_ops", "bit-vec", "bytemuck", - "byteorder", - "cfg-if", - "derive_more 2.0.1", - "enum-map", - "malachite", - "num-derive", - "num-traits", + "derive_more", "paste", - "postcard", - "rand 0.8.5", - "rayon", - "ringbuffer", "risc0-binfmt", - "risc0-circuit-rv32im-sys", "risc0-core", - "risc0-sys", "risc0-zkp", "serde", - "smallvec", "tracing", ] -[[package]] -name = "risc0-circuit-rv32im-sys" -version = "3.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" -dependencies = [ - "cc", - "cust", - "derive_more 2.0.1", - "glob", - "risc0-build-kernel", - "risc0-core", - "risc0-sys", - "sppark", -] - [[package]] name = "risc0-core" version = "2.0.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317bbf70a8750b64d4fd7a2bdc9d7d5f30d8bb305cae486962c797ef35c8d08e" dependencies = [ "bytemuck", "bytemuck_derive", - "nvtx", - "puffin", "rand_core 0.6.4", ] [[package]] name = "risc0-groth16" version = "2.0.2" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cf5d0b673d5fc67a89147c2e9c53134707dcc8137a43d1ef06b4ff68e99b74f" dependencies = [ "anyhow", "ark-bn254", @@ -3907,33 +1971,19 @@ dependencies = [ "ark-serialize", "bytemuck", "hex", - "num-bigint 0.4.6", + "num-bigint", "num-traits", "risc0-binfmt", - "risc0-core", "risc0-zkp", "serde", - "serde_json", "stability", - "tempfile", - "tracing", -] - -[[package]] -name = "risc0-sys" -version = "1.4.0" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" -dependencies = [ - "anyhow", - "cust", - "risc0-build-kernel", - "sppark", ] [[package]] name = "risc0-zkos-v1compat" version = "2.0.1" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f76c479b69d1987cb54ac72dcc017197296fdcd6daf78fafc10cbbd3a167a7de" dependencies = [ "include_bytes_aligned", "no_std_strings", @@ -3942,27 +1992,21 @@ dependencies = [ [[package]] name = "risc0-zkp" version = "2.0.2" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a287e9cd6d7b3b38eeb49c62090c46a1935922309fbd997a9143ed8c43c8f3cb" dependencies = [ "anyhow", "blake2", "borsh", "bytemuck", "cfg-if", - "cust", "digest", - "ff", "hex", "hex-literal", "metal", - "ndarray", - "parking_lot", "paste", - "rand 0.8.5", "rand_core 0.6.4", - "rayon", "risc0-core", - "risc0-sys", "risc0-zkvm-platform", "serde", "sha2", @@ -3973,27 +2017,20 @@ dependencies = [ [[package]] name = "risc0-zkvm" version = "2.3.1" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9684b333c1c5d83f29ce2a92314ccfafd9d8cdfa6c4e19c07b97015d2f1eb9d0" dependencies = [ - "addr2line 0.22.0", "anyhow", "bincode", "bonsai-sdk", "borsh", "bytemuck", "bytes", - "derive_more 2.0.1", - "elf", - "enum-map", + "derive_more", "getrandom 0.2.16", "hex", - "keccak", "lazy-regex", - "num-bigint 0.4.6", - "num-traits", "prost", - "rand 0.8.5", - "rayon", "risc0-binfmt", "risc0-build", "risc0-circuit-keccak", @@ -4005,7 +2042,6 @@ dependencies = [ "risc0-zkp", "risc0-zkvm-platform", "rrs-lib", - "rustc-demangle", "rzup", "semver", "serde", @@ -4013,13 +2049,13 @@ dependencies = [ "stability", "tempfile", "tracing", - "typetag", ] [[package]] name = "risc0-zkvm-platform" version = "2.0.3" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae9cb2c2f6cab2dfa395ea6e2576713929040c7fb0c5f4150d13e1119d18686" dependencies = [ "bytemuck", "cfg-if", @@ -4029,16 +2065,6 @@ dependencies = [ "stability", ] -[[package]] -name = "rocksdb" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" -dependencies = [ - "libc", - "librocksdb-sys", -] - [[package]] name = "rrs-lib" version = "0.1.0" @@ -4049,55 +2075,18 @@ dependencies = [ "paste", ] -[[package]] -name = "rs_merkle" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb09b49230ba22e8c676e7b75dfe2887dea8121f18b530ae0ba519ce442d2b21" -dependencies = [ - "sha2", -] - [[package]] name = "rustc-demangle" version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.9.1", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - [[package]] name = "rustix" version = "1.0.8" @@ -4107,7 +2096,7 @@ dependencies = [ "bitflags 2.9.1", "errno", "libc", - "linux-raw-sys 0.9.4", + "linux-raw-sys", "windows-sys 0.60.2", ] @@ -4125,15 +2114,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - [[package]] name = "rustls-pki-types" version = "1.12.0" @@ -4161,17 +2141,6 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" -[[package]] -name = "ruzstd" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5174a470eeb535a721ae9fdd6e291c2411a906b96592182d05217591d5c5cf7b" -dependencies = [ - "byteorder", - "derive_more 0.99.20", - "twox-hash", -] - [[package]] name = "ryu" version = "1.0.20" @@ -4181,139 +2150,18 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "rzup" version = "0.4.1" -source = "git+https://github.com/risc0/risc0.git?branch=release-2.3#03853380e36e1a093bf06d306601f7358151e2ed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "400558bf12d4292a7804093b60a437ba8b0219ea7d53716b2c010a0d31e5f4a8" dependencies = [ "semver", "serde", "strum", "tempfile", "thiserror 2.0.12", - "toml 0.8.23", + "toml", "yaml-rust2", ] -[[package]] -name = "sc_core" -version = "0.1.0" -dependencies = [ - "accounts", - "anyhow", - "ark-bn254", - "ark-ff", - "bincode", - "common", - "elliptic-curve", - "env_logger", - "hex", - "k256", - "light-poseidon", - "log", - "rand 0.8.5", - "risc0-zkvm", - "secp256k1-zkp", - "serde", - "serde_json", - "sha2", - "storage", - "utxo", -] - -[[package]] -name = "schannel" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "serdect", - "subtle", - "zeroize", -] - -[[package]] -name = "secp256k1" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" -dependencies = [ - "rand 0.8.5", - "secp256k1-sys", - "serde", -] - -[[package]] -name = "secp256k1-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" -dependencies = [ - "cc", -] - -[[package]] -name = "secp256k1-zkp" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a44aed3002b5ae975f8624c5df3a949cfbf00479e18778b6058fcd213b76e3" -dependencies = [ - "bitcoin-private", - "rand 0.8.5", - "secp256k1", - "secp256k1-zkp-sys", - "serde", -] - -[[package]] -name = "secp256k1-zkp-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57f08b2d0b143a22e07f798ae4f0ab20d5590d7c68e0d090f2088a48a21d1654" -dependencies = [ - "cc", - "secp256k1-sys", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.9.1", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "semver" version = "1.0.26" @@ -4323,71 +2171,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sequencer_core" -version = "0.1.0" -dependencies = [ - "accounts", - "anyhow", - "common", - "elliptic-curve", - "env_logger", - "hex", - "k256", - "log", - "mempool", - "rand 0.8.5", - "secp256k1-zkp", - "serde", - "serde_json", - "storage", - "tempfile", - "tiny-keccak", -] - -[[package]] -name = "sequencer_rpc" -version = "0.1.0" -dependencies = [ - "accounts", - "actix", - "actix-cors", - "actix-web", - "anyhow", - "common", - "env_logger", - "futures", - "hex", - "log", - "mempool", - "sequencer_core", - "serde", - "serde_json", - "storage", - "tempfile", - "tokio", -] - -[[package]] -name = "sequencer_runner" -version = "0.1.0" -dependencies = [ - "actix", - "actix-web", - "anyhow", - "clap", - "common", - "env_logger", - "log", - "mempool", - "sequencer_core", - "sequencer_rpc", - "serde", - "serde_json", - "tokio", - "toml 0.7.8", -] - [[package]] name = "serde" version = "1.0.219" @@ -4441,27 +2224,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serdect" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" -dependencies = [ - "base16ct", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "sha2" version = "0.10.9" @@ -4479,31 +2241,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook-registry" -version = "1.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest", - "rand_core 0.6.4", -] - -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - [[package]] name = "slab" version = "0.4.10" @@ -4516,16 +2253,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.10" @@ -4551,29 +2278,6 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "sppark" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdc4f02f557e3037bbe2a379cac8be6e014a67beb7bf0996b536979392f6361" -dependencies = [ - "cc", - "which", -] [[package]] name = "stability" @@ -4591,28 +2295,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "storage" -version = "0.1.0" -dependencies = [ - "anyhow", - "common", - "env_logger", - "hex", - "log", - "lru", - "rocksdb", - "serde", - "serde_json", - "thiserror 1.0.69", -] - [[package]] name = "strsim" version = "0.11.1" @@ -4669,12 +2351,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.2" @@ -4695,33 +2371,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "tempfile" version = "3.20.0" @@ -4731,26 +2380,10 @@ dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", - "rustix 1.0.8", + "rustix", "windows-sys 0.59.0", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "test-methods" -version = "0.1.0" -dependencies = [ - "risc0-build", -] - [[package]] name = "thiserror" version = "1.0.69" @@ -4791,46 +2424,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "time" -version = "0.3.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" - -[[package]] -name = "time-macros" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - [[package]] name = "tinystr" version = "0.8.1" @@ -4867,24 +2460,12 @@ dependencies = [ "io-uring", "libc", "mio", - "parking_lot", "pin-project-lite", - "signal-hook-registry", "slab", "socket2 0.6.0", "windows-sys 0.59.0", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.26.2" @@ -4908,18 +2489,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.19.15", -] - [[package]] name = "toml" version = "0.8.23" @@ -4929,7 +2498,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.27", + "toml_edit", ] [[package]] @@ -4941,19 +2510,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.27" @@ -4965,7 +2521,7 @@ dependencies = [ "serde_spanned", "toml_datetime", "toml_write", - "winnow 0.7.12", + "winnow", ] [[package]] @@ -4983,7 +2539,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tower-layer", "tower-service", @@ -4998,8 +2554,8 @@ dependencies = [ "bitflags 2.9.1", "bytes", "futures-util", - "http 1.3.1", - "http-body 1.0.1", + "http", + "http-body", "iri-string", "pin-project-lite", "tower", @@ -5067,52 +2623,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "twox-hash" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if", - "static_assertions", -] - -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - [[package]] name = "typenum" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" -[[package]] -name = "typetag" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f22b40dd7bfe8c14230cf9702081366421890435b2d625fa92b4acc4c3de6f" -dependencies = [ - "erased-serde", - "inventory", - "once_cell", - "serde", - "typetag-impl", -] - -[[package]] -name = "typetag-impl" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "unicode-ident" version = "1.0.18" @@ -5125,16 +2641,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - [[package]] name = "untrusted" version = "0.9.0" @@ -5158,87 +2664,18 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "utxo" -version = "0.1.0" -dependencies = [ - "anyhow", - "common", - "env_logger", - "hex", - "log", - "rand 0.8.5", - "serde", - "serde_json", - "sha2", -] - [[package]] name = "valuable" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vek" -version = "0.15.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8085882662f9bc47fc8b0cdafa5e19df8f592f650c02b9083da8d45ac9eebd17" -dependencies = [ - "approx", - "num-integer", - "num-traits", - "rustc_version", -] - [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "wallet" -version = "0.1.0" -dependencies = [ - "accounts", - "actix-rt", - "anyhow", - "bincode", - "clap", - "common", - "elliptic-curve", - "env_logger", - "hex", - "k256", - "log", - "rand 0.8.5", - "reqwest 0.11.27", - "risc0-zkvm", - "sc_core", - "secp256k1-zkp", - "serde", - "serde_json", - "sha2", - "tempfile", - "thiserror 1.0.69", - "tokio", - "utxo", - "zkvm", -] - [[package]] name = "want" version = "0.3.1" @@ -5376,49 +2813,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-link" version = "0.1.3" @@ -5647,15 +3041,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.7.12" @@ -5665,16 +3050,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "wit-bindgen-rt" version = "0.39.0" @@ -5690,24 +3065,6 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xz2" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" -dependencies = [ - "lzma-sys", -] - [[package]] name = "yaml-rust2" version = "0.9.0" @@ -5817,9 +3174,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.2" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", @@ -5836,50 +3193,3 @@ dependencies = [ "quote", "syn 2.0.104", ] - -[[package]] -name = "zip" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" -dependencies = [ - "arbitrary", - "crc32fast", - "crossbeam-utils", - "displaydoc", - "flate2", - "indexmap", - "memchr", - "thiserror 2.0.12", - "zopfli", -] - -[[package]] -name = "zkvm" -version = "0.1.0" -dependencies = [ - "accounts", - "anyhow", - "common", - "env_logger", - "log", - "rand 0.8.5", - "risc0-zkvm", - "serde", - "serde_json", - "test-methods", - "thiserror 1.0.69", - "utxo", -] - -[[package]] -name = "zopfli" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" -dependencies = [ - "bumpalo", - "crc32fast", - "log", - "simd-adler32", -] diff --git a/nssa/program_methods/guest/Cargo.toml b/nssa/program_methods/guest/Cargo.toml new file mode 100644 index 0000000..4b377c8 --- /dev/null +++ b/nssa/program_methods/guest/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "programs" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +risc0-zkvm = { version = "2.3.1", default-features = false, features = ['std'] } +nssa-core = { path = "../../core" } diff --git a/nssa/program_methods/guest/src/bin/authenticated_transfer.rs b/nssa/program_methods/guest/src/bin/authenticated_transfer.rs new file mode 100644 index 0000000..a89b090 --- /dev/null +++ b/nssa/program_methods/guest/src/bin/authenticated_transfer.rs @@ -0,0 +1,36 @@ +use nssa_core::program::read_nssa_inputs; +use risc0_zkvm::guest::env; + +type Instruction = u128; + +/// A transfer of balance program. +/// To be used both in public and private contexts. +fn main() { + // Read input accounts. + // It is expected to receive only two accounts: [sender_account, receiver_account] + let (input_accounts, balance_to_move) = read_nssa_inputs::(); + + // Continue only if input_accounts is an array of two elements + let [sender, receiver] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + // Continue only if the sender has authorized this operation + if !sender.is_authorized { + return; + } + + // Continue only if the sender has enough balance + if sender.account.balance < balance_to_move { + return; + } + + // Create accounts post states, with updated balances + let mut sender_post = sender.account.clone(); + let mut receiver_post = receiver.account.clone(); + sender_post.balance -= balance_to_move; + receiver_post.balance += balance_to_move; + + env::commit(&vec![sender_post, receiver_post]); +} diff --git a/zkvm/test_methods/src/lib.rs b/nssa/program_methods/src/lib.rs similarity index 100% rename from zkvm/test_methods/src/lib.rs rename to nssa/program_methods/src/lib.rs diff --git a/nssa/rust-toolchain.toml b/nssa/rust-toolchain.toml new file mode 100644 index 0000000..36614c3 --- /dev/null +++ b/nssa/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "stable" +components = ["rustfmt", "rust-src"] +profile = "minimal" diff --git a/nssa/src/address.rs b/nssa/src/address.rs new file mode 100644 index 0000000..d54af10 --- /dev/null +++ b/nssa/src/address.rs @@ -0,0 +1,130 @@ +use std::{fmt::Display, str::FromStr}; + +use anyhow::anyhow; +use serde::{Deserialize, Serialize}; + +use crate::signature::PublicKey; + +pub const LENGTH_MISMATCH_ERROR_MESSAGE: &str = "Slice length != 32 "; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct Address { + value: [u8; 32], +} + +impl Address { + pub fn new(value: [u8; 32]) -> Self { + Self { value } + } + + pub fn value(&self) -> &[u8; 32] { + &self.value + } +} + +impl AsRef<[u8]> for Address { + fn as_ref(&self) -> &[u8] { + &self.value + } +} + +impl TryFrom> for Address { + type Error = anyhow::Error; + + fn try_from(value: Vec) -> Result { + let addr_val: [u8; 32] = value + .try_into() + .map_err(|_| anyhow!(LENGTH_MISMATCH_ERROR_MESSAGE))?; + + Ok(Address::new(addr_val)) + } +} + +impl From<&PublicKey> for Address { + fn from(value: &PublicKey) -> Self { + // TODO: Check specs + Self::new(*value.value()) + } +} + +#[derive(Debug, thiserror::Error)] +pub enum AddressError { + #[error("invalid hex")] + InvalidHex(#[from] hex::FromHexError), + #[error("invalid length: expected 32 bytes, got {0}")] + InvalidLength(usize), +} + +impl FromStr for Address { + type Err = AddressError; + fn from_str(s: &str) -> Result { + let bytes = hex::decode(s)?; + if bytes.len() != 32 { + return Err(AddressError::InvalidLength(bytes.len())); + } + let mut value = [0u8; 32]; + value.copy_from_slice(&bytes); + Ok(Address { value }) + } +} + +impl Display for Address { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", hex::encode(self.value)) + } +} + +impl Serialize for Address { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let hex_string = self.to_string(); + + hex_string.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for Address { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let hex_string = String::deserialize(deserializer)?; + + Address::from_str(&hex_string).map_err(serde::de::Error::custom) + } +} + +#[cfg(test)] +mod tests { + use crate::{Address, address::AddressError}; + + #[test] + fn parse_valid_address() { + let hex_str = "00".repeat(32); // 64 hex chars = 32 bytes + let addr: Address = hex_str.parse().unwrap(); + assert_eq!(addr.value, [0u8; 32]); + } + + #[test] + fn parse_invalid_hex() { + let hex_str = "zz".repeat(32); // invalid hex chars + let result = hex_str.parse::
().unwrap_err(); + assert!(matches!(result, AddressError::InvalidHex(_))); + } + + #[test] + fn parse_wrong_length_short() { + let hex_str = "00".repeat(31); // 62 chars = 31 bytes + let result = hex_str.parse::
().unwrap_err(); + assert!(matches!(result, AddressError::InvalidLength(_))); + } + + #[test] + fn parse_wrong_length_long() { + let hex_str = "00".repeat(33); // 66 chars = 33 bytes + let result = hex_str.parse::
().unwrap_err(); + assert!(matches!(result, AddressError::InvalidLength(_))); + } +} diff --git a/nssa/src/error.rs b/nssa/src/error.rs new file mode 100644 index 0000000..11a2f41 --- /dev/null +++ b/nssa/src/error.rs @@ -0,0 +1,27 @@ +use std::io; + +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum NssaError { + #[error("Invalid input: {0}")] + InvalidInput(String), + + #[error("Risc0 error: {0}")] + ProgramExecutionFailed(String), + + #[error("Program violated execution rules")] + InvalidProgramBehavior, + + #[error("Serialization error: {0}")] + InstructionSerializationError(String), + + #[error("Invalid private key")] + InvalidPrivateKey, + + #[error("IO error: {0}")] + Io(#[from] io::Error), + + #[error("Invalid Public Key")] + InvalidPublicKey, +} diff --git a/nssa/src/lib.rs b/nssa/src/lib.rs new file mode 100644 index 0000000..9555b14 --- /dev/null +++ b/nssa/src/lib.rs @@ -0,0 +1,13 @@ +pub mod address; +pub mod error; +pub mod program; +pub mod public_transaction; +mod signature; +mod state; + +pub use address::Address; +pub use public_transaction::PublicTransaction; +pub use signature::PrivateKey; +pub use signature::PublicKey; +pub use signature::Signature; +pub use state::V01State; diff --git a/nssa/src/program.rs b/nssa/src/program.rs new file mode 100644 index 0000000..e2762ba --- /dev/null +++ b/nssa/src/program.rs @@ -0,0 +1,206 @@ +use nssa_core::{ + account::{Account, AccountWithMetadata}, + program::{DEFAULT_PROGRAM_ID, InstructionData, ProgramId}, +}; +use program_methods::{AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID}; +use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, default_executor, serde::to_vec}; +use serde::Serialize; + +use crate::error::NssaError; + +#[derive(Debug, PartialEq, Eq)] +pub struct Program { + id: ProgramId, + elf: &'static [u8], +} + +impl Program { + pub fn id(&self) -> ProgramId { + self.id + } + + pub fn serialize_instruction( + instruction: T, + ) -> Result { + to_vec(&instruction).map_err(|e| NssaError::InstructionSerializationError(e.to_string())) + } + + pub(crate) fn execute( + &self, + pre_states: &[AccountWithMetadata], + instruction_data: &InstructionData, + ) -> Result, NssaError> { + // Write inputs to the program + let mut env_builder = ExecutorEnv::builder(); + Self::write_inputs(pre_states, instruction_data, &mut env_builder)?; + let env = env_builder.build().unwrap(); + + // Execute the program (without proving) + let executor = default_executor(); + let session_info = executor + .execute(env, self.elf) + .map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?; + + // Get outputs + let mut post_states: Vec = session_info + .journal + .decode() + .map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?; + + // Claim any output account with default program owner field + for account in post_states.iter_mut() { + if account.program_owner == DEFAULT_PROGRAM_ID { + account.program_owner = self.id; + } + } + + Ok(post_states) + } + + /// Writes inputs to `env_builder` in the order expected by the programs + fn write_inputs( + pre_states: &[AccountWithMetadata], + instruction_data: &[u32], + env_builder: &mut ExecutorEnvBuilder, + ) -> Result<(), NssaError> { + let pre_states = pre_states.to_vec(); + env_builder + .write(&(pre_states, instruction_data)) + .map_err(|e| NssaError::ProgramExecutionFailed(e.to_string()))?; + Ok(()) + } + + pub fn authenticated_transfer_program() -> Self { + Self { + id: AUTHENTICATED_TRANSFER_ID, + elf: AUTHENTICATED_TRANSFER_ELF, + } + } +} + +#[cfg(test)] +mod tests { + use nssa_core::account::{Account, AccountWithMetadata}; + + use crate::program::Program; + + impl Program { + /// A program that changes the nonce of an account + pub fn nonce_changer_program() -> Self { + use test_program_methods::{NONCE_CHANGER_ELF, NONCE_CHANGER_ID}; + + Program { + id: NONCE_CHANGER_ID, + elf: NONCE_CHANGER_ELF, + } + } + + /// A program that produces more output accounts than the inputs it received + pub fn extra_output_program() -> Self { + use test_program_methods::{EXTRA_OUTPUT_ELF, EXTRA_OUTPUT_ID}; + + Program { + id: EXTRA_OUTPUT_ID, + elf: EXTRA_OUTPUT_ELF, + } + } + + /// A program that produces less output accounts than the inputs it received + pub fn missing_output_program() -> Self { + use test_program_methods::{MISSING_OUTPUT_ELF, MISSING_OUTPUT_ID}; + + Program { + id: MISSING_OUTPUT_ID, + elf: MISSING_OUTPUT_ELF, + } + } + + /// A program that changes the program owner of an account to [0, 1, 2, 3, 4, 5, 6, 7] + pub fn program_owner_changer() -> Self { + use test_program_methods::{PROGRAM_OWNER_CHANGER_ELF, PROGRAM_OWNER_CHANGER_ID}; + + Program { + id: PROGRAM_OWNER_CHANGER_ID, + elf: PROGRAM_OWNER_CHANGER_ELF, + } + } + + /// A program that transfers balance without caring about authorizations + pub fn simple_balance_transfer() -> Self { + use test_program_methods::{SIMPLE_BALANCE_TRANSFER_ELF, SIMPLE_BALANCE_TRANSFER_ID}; + + Program { + id: SIMPLE_BALANCE_TRANSFER_ID, + elf: SIMPLE_BALANCE_TRANSFER_ELF, + } + } + + /// A program that modifies the data of an account + pub fn data_changer() -> Self { + use test_program_methods::{DATA_CHANGER_ELF, DATA_CHANGER_ID}; + + Program { + id: DATA_CHANGER_ID, + elf: DATA_CHANGER_ELF, + } + } + + /// A program that mints balance + pub fn minter() -> Self { + use test_program_methods::{MINTER_ELF, MINTER_ID}; + + Program { + id: MINTER_ID, + elf: MINTER_ELF, + } + } + + /// A program that burns balance + pub fn burner() -> Self { + use test_program_methods::{BURNER_ELF, BURNER_ID}; + + Program { + id: BURNER_ID, + elf: BURNER_ELF, + } + } + } + + #[test] + fn test_program_execution() { + let program = Program::simple_balance_transfer(); + let balance_to_move: u128 = 11223344556677; + let instruction_data = Program::serialize_instruction(balance_to_move).unwrap(); + let sender = AccountWithMetadata { + account: Account { + balance: 77665544332211, + ..Account::default() + }, + is_authorized: false, + }; + let recipient = AccountWithMetadata { + account: Account::default(), + is_authorized: false, + }; + + let expected_sender_post = Account { + balance: 77665544332211 - balance_to_move, + program_owner: program.id(), + ..Account::default() + }; + let expected_recipient_post = Account { + balance: balance_to_move, + // Program claims the account since the pre_state has default prorgam owner + program_owner: program.id(), + ..Account::default() + }; + let [sender_post, recipient_post] = program + .execute(&[sender, recipient], &instruction_data) + .unwrap() + .try_into() + .unwrap(); + + assert_eq!(sender_post, expected_sender_post); + assert_eq!(recipient_post, expected_recipient_post); + } +} diff --git a/nssa/src/public_transaction/encoding.rs b/nssa/src/public_transaction/encoding.rs new file mode 100644 index 0000000..3c004a0 --- /dev/null +++ b/nssa/src/public_transaction/encoding.rs @@ -0,0 +1,145 @@ +use std::io::{Cursor, Read}; + +use nssa_core::program::ProgramId; + +use crate::{ + Address, PublicKey, PublicTransaction, Signature, + error::NssaError, + public_transaction::{Message, WitnessSet}, +}; + +const MESSAGE_ENCODING_PREFIX_LEN: usize = 19; +const MESSAGE_ENCODING_PREFIX: &[u8; MESSAGE_ENCODING_PREFIX_LEN] = b"NSSA/v0.1/TxMessage"; + +impl Message { + /// Serializes a `Message` into bytes in the following layout: + /// PREFIX || (4 bytes LE) * 8 || addresses_len (4 bytes LE) || addresses (32 bytes * N) || nonces_len (4 bytes LE) || nonces (16 bytes LE * M) || instruction_data_len || instruction_data (4 bytes LE * K) + /// Integers and words are encoded in little-endian byte order, and fields appear in the above order. + pub(crate) fn to_bytes(&self) -> Vec { + let mut bytes = MESSAGE_ENCODING_PREFIX.to_vec(); + // program_id: [u32; 8] + for word in &self.program_id { + bytes.extend_from_slice(&word.to_le_bytes()); + } + // addresses: Vec<[u8;32]> + // serialize length as u32 little endian, then all addresses concatenated + let addresses_len = self.addresses.len() as u32; + bytes.extend(&addresses_len.to_le_bytes()); + for addr in &self.addresses { + bytes.extend_from_slice(addr.value()); + } + // nonces: Vec + // serialize length as u32 little endian, then all nonces concatenated in LE + let nonces_len = self.nonces.len() as u32; + bytes.extend(&nonces_len.to_le_bytes()); + for nonce in &self.nonces { + bytes.extend(&nonce.to_le_bytes()); + } + // instruction_data: Vec + // serialize length as u32 little endian, then all addresses concatenated + let instr_len = self.instruction_data.len() as u32; + bytes.extend(&instr_len.to_le_bytes()); + for word in &self.instruction_data { + bytes.extend(&word.to_le_bytes()); + } + + bytes + } + + pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result { + let prefix = { + let mut this = [0u8; MESSAGE_ENCODING_PREFIX_LEN]; + cursor.read_exact(&mut this)?; + this + }; + assert_eq!(&prefix, MESSAGE_ENCODING_PREFIX); + let program_id: ProgramId = { + let mut this = [0u32; 8]; + for item in &mut this { + *item = u32_from_cursor(cursor)?; + } + this + }; + let addresses_len = u32_from_cursor(cursor)?; + let mut addresses = Vec::with_capacity(addresses_len as usize); + for _ in 0..addresses_len { + let mut value = [0u8; 32]; + cursor.read_exact(&mut value)?; + addresses.push(Address::new(value)) + } + let nonces_len = u32_from_cursor(cursor)?; + let mut nonces = Vec::with_capacity(nonces_len as usize); + for _ in 0..nonces_len { + let mut buf = [0u8; 16]; + cursor.read_exact(&mut buf)?; + nonces.push(u128::from_le_bytes(buf)) + } + let instruction_data_len = u32_from_cursor(cursor)?; + let mut instruction_data = Vec::with_capacity(instruction_data_len as usize); + for _ in 0..instruction_data_len { + let word = u32_from_cursor(cursor)?; + instruction_data.push(word) + } + Ok(Self { + program_id, + addresses, + nonces, + instruction_data, + }) + } +} + +impl WitnessSet { + pub(crate) fn to_bytes(&self) -> Vec { + let mut bytes = Vec::new(); + let size = self.signatures_and_public_keys().len() as u32; + bytes.extend_from_slice(&size.to_le_bytes()); + for (signature, public_key) in self.signatures_and_public_keys() { + bytes.extend_from_slice(signature.to_bytes()); + bytes.extend_from_slice(public_key.to_bytes()); + } + bytes + } + + pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result { + let num_signatures: u32 = { + let mut buf = [0u8; 4]; + cursor.read_exact(&mut buf)?; + u32::from_le_bytes(buf) + }; + let mut signatures_and_public_keys = Vec::with_capacity(num_signatures as usize); + for _i in 0..num_signatures { + let signature = Signature::from_cursor(cursor)?; + let public_key = PublicKey::from_cursor(cursor)?; + signatures_and_public_keys.push((signature, public_key)) + } + Ok(Self { + signatures_and_public_keys, + }) + } +} + +impl PublicTransaction { + pub fn to_bytes(&self) -> Vec { + let mut bytes = self.message().to_bytes(); + bytes.extend_from_slice(&self.witness_set().to_bytes()); + bytes + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + let mut cursor = Cursor::new(bytes); + Self::from_cursor(&mut cursor) + } + + pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result { + let message = Message::from_cursor(cursor)?; + let witness_set = WitnessSet::from_cursor(cursor)?; + Ok(PublicTransaction::new(message, witness_set)) + } +} + +fn u32_from_cursor(cursor: &mut Cursor<&[u8]>) -> Result { + let mut word_buf = [0u8; 4]; + cursor.read_exact(&mut word_buf)?; + Ok(u32::from_le_bytes(word_buf)) +} diff --git a/nssa/src/public_transaction/message.rs b/nssa/src/public_transaction/message.rs new file mode 100644 index 0000000..68cb5fb --- /dev/null +++ b/nssa/src/public_transaction/message.rs @@ -0,0 +1,32 @@ +use nssa_core::{ + account::Nonce, + program::{InstructionData, ProgramId}, +}; +use serde::Serialize; + +use crate::{Address, error::NssaError, program::Program}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Message { + pub(crate) program_id: ProgramId, + pub(crate) addresses: Vec
, + pub(crate) nonces: Vec, + pub(crate) instruction_data: InstructionData, +} + +impl Message { + pub fn try_new( + program_id: ProgramId, + addresses: Vec
, + nonces: Vec, + instruction: T, + ) -> Result { + let instruction_data = Program::serialize_instruction(instruction)?; + Ok(Self { + program_id, + addresses, + nonces, + instruction_data, + }) + } +} diff --git a/nssa/src/public_transaction/mod.rs b/nssa/src/public_transaction/mod.rs new file mode 100644 index 0000000..9ae24cf --- /dev/null +++ b/nssa/src/public_transaction/mod.rs @@ -0,0 +1,8 @@ +mod encoding; +mod message; +mod transaction; +mod witness_set; + +pub use message::Message; +pub use transaction::PublicTransaction; +pub use witness_set::WitnessSet; diff --git a/nssa/src/public_transaction/transaction.rs b/nssa/src/public_transaction/transaction.rs new file mode 100644 index 0000000..d160004 --- /dev/null +++ b/nssa/src/public_transaction/transaction.rs @@ -0,0 +1,315 @@ +use std::collections::{HashMap, HashSet}; + +use nssa_core::{ + account::{Account, AccountWithMetadata}, + program::validate_execution, +}; +use sha2::{Digest, digest::FixedOutput}; + +use crate::{ + V01State, + address::Address, + error::NssaError, + public_transaction::{Message, WitnessSet}, +}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PublicTransaction { + message: Message, + witness_set: WitnessSet, +} + +impl PublicTransaction { + pub fn new(message: Message, witness_set: WitnessSet) -> Self { + Self { + message, + witness_set, + } + } + + pub fn message(&self) -> &Message { + &self.message + } + + pub fn witness_set(&self) -> &WitnessSet { + &self.witness_set + } + + pub(crate) fn signer_addresses(&self) -> Vec
{ + self.witness_set + .signatures_and_public_keys() + .iter() + .map(|(_, public_key)| Address::from(public_key)) + .collect() + } + + pub fn hash(&self) -> [u8; 32] { + let bytes = self.to_bytes(); + let mut hasher = sha2::Sha256::new(); + hasher.update(&bytes); + hasher.finalize_fixed().into() + } + + pub(crate) fn validate_and_compute_post_states( + &self, + state: &V01State, + ) -> Result, NssaError> { + let message = self.message(); + let witness_set = self.witness_set(); + + // All addresses must be different + if message.addresses.iter().collect::>().len() != message.addresses.len() { + return Err(NssaError::InvalidInput( + "Duplicate addresses found in message".into(), + )); + } + + if message.nonces.len() != witness_set.signatures_and_public_keys.len() { + return Err(NssaError::InvalidInput( + "Mismatch between number of nonces and signatures/public keys".into(), + )); + } + + // Check the signatures are valid + if !witness_set.is_valid_for(message) { + return Err(NssaError::InvalidInput( + "Invalid signature for given message and public key".into(), + )); + } + + let signer_addresses = self.signer_addresses(); + // Check nonces corresponds to the current nonces on the public state. + for (address, nonce) in signer_addresses.iter().zip(&message.nonces) { + let current_nonce = state.get_account_by_address(address).nonce; + if current_nonce != *nonce { + return Err(NssaError::InvalidInput("Nonce mismatch".into())); + } + } + + // Build pre_states for execution + let pre_states: Vec<_> = message + .addresses + .iter() + .map(|address| AccountWithMetadata { + account: state.get_account_by_address(address), + is_authorized: signer_addresses.contains(address), + }) + .collect(); + + // Check the `program_id` corresponds to a built-in program + // Only allowed program so far is the authenticated transfer program + let Some(program) = state.builtin_programs().get(&message.program_id) else { + return Err(NssaError::InvalidInput("Unknown program".into())); + }; + + // // Execute program + let post_states = program.execute(&pre_states, &message.instruction_data)?; + + // Verify execution corresponds to a well-behaved program. + // See the # Programs section for the definition of the `validate_execution` method. + if !validate_execution(&pre_states, &post_states, message.program_id) { + return Err(NssaError::InvalidProgramBehavior); + } + + Ok(message.addresses.iter().cloned().zip(post_states).collect()) + } +} + +#[cfg(test)] +pub mod tests { + use sha2::{Digest, digest::FixedOutput}; + + use crate::{ + Address, PrivateKey, PublicKey, PublicTransaction, Signature, V01State, + error::NssaError, + program::Program, + public_transaction::{Message, WitnessSet}, + }; + + fn keys_for_tests() -> (PrivateKey, PrivateKey, Address, Address) { + let key1 = PrivateKey::try_new([1; 32]).unwrap(); + let key2 = PrivateKey::try_new([2; 32]).unwrap(); + let addr1 = Address::from(&PublicKey::new_from_private_key(&key1)); + let addr2 = Address::from(&PublicKey::new_from_private_key(&key2)); + (key1, key2, addr1, addr2) + } + + fn state_for_tests() -> V01State { + let (_, _, addr1, addr2) = keys_for_tests(); + let initial_data = [(addr1, 10000), (addr2, 20000)]; + V01State::new_with_genesis_accounts(&initial_data) + } + + fn transaction_for_tests() -> PublicTransaction { + let (key1, key2, addr1, addr2) = keys_for_tests(); + let nonces = vec![0, 0]; + let instruction = 1337; + let message = Message::try_new( + Program::authenticated_transfer_program().id(), + vec![addr1, addr2], + nonces, + instruction, + ) + .unwrap(); + + let witness_set = WitnessSet::for_message(&message, &[&key1, &key2]); + PublicTransaction::new(message, witness_set) + } + + #[test] + fn test_new_constructor() { + let tx = transaction_for_tests(); + let message = tx.message().clone(); + let witness_set = tx.witness_set().clone(); + let tx_from_constructor = PublicTransaction::new(message.clone(), witness_set.clone()); + assert_eq!(tx_from_constructor.message, message); + assert_eq!(tx_from_constructor.witness_set, witness_set); + } + + #[test] + fn test_message_getter() { + let tx = transaction_for_tests(); + assert_eq!(&tx.message, tx.message()); + } + + #[test] + fn test_witness_set_getter() { + let tx = transaction_for_tests(); + assert_eq!(&tx.witness_set, tx.witness_set()); + } + + #[test] + fn test_signer_addresses() { + let tx = transaction_for_tests(); + let expected_signer_addresses = vec![ + Address::new([ + 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, + 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143, + ]), + Address::new([ + 77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217, + 234, 216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102, + ]), + ]; + let signer_addresses = tx.signer_addresses(); + assert_eq!(signer_addresses, expected_signer_addresses); + } + + #[test] + fn test_public_transaction_encoding_bytes_roundtrip() { + let tx = transaction_for_tests(); + let bytes = tx.to_bytes(); + let tx_from_bytes = PublicTransaction::from_bytes(&bytes).unwrap(); + assert_eq!(tx, tx_from_bytes); + } + + #[test] + fn test_hash_is_sha256_of_transaction_bytes() { + let tx = transaction_for_tests(); + let hash = tx.hash(); + let expected_hash: [u8; 32] = { + let bytes = tx.to_bytes(); + let mut hasher = sha2::Sha256::new(); + hasher.update(&bytes); + hasher.finalize_fixed().into() + }; + assert_eq!(hash, expected_hash); + } + + #[test] + fn test_address_list_cant_have_duplicates() { + let (key1, _, addr1, _) = keys_for_tests(); + let state = state_for_tests(); + let nonces = vec![0, 0]; + let instruction = 1337; + let message = Message::try_new( + Program::authenticated_transfer_program().id(), + vec![addr1, addr1], + nonces, + instruction, + ) + .unwrap(); + + let witness_set = WitnessSet::for_message(&message, &[&key1, &key1]); + let tx = PublicTransaction::new(message, witness_set); + let result = tx.validate_and_compute_post_states(&state); + assert!(matches!(result, Err(NssaError::InvalidInput(_)))) + } + + #[test] + fn test_number_of_nonces_must_match_number_of_signatures() { + let (key1, key2, addr1, addr2) = keys_for_tests(); + let state = state_for_tests(); + let nonces = vec![0]; + let instruction = 1337; + let message = Message::try_new( + Program::authenticated_transfer_program().id(), + vec![addr1, addr2], + nonces, + instruction, + ) + .unwrap(); + + let witness_set = WitnessSet::for_message(&message, &[&key1, &key2]); + let tx = PublicTransaction::new(message, witness_set); + let result = tx.validate_and_compute_post_states(&state); + assert!(matches!(result, Err(NssaError::InvalidInput(_)))) + } + + #[test] + fn test_all_signatures_must_be_valid() { + let (key1, key2, addr1, addr2) = keys_for_tests(); + let state = state_for_tests(); + let nonces = vec![0, 0]; + let instruction = 1337; + let message = Message::try_new( + Program::authenticated_transfer_program().id(), + vec![addr1, addr2], + nonces, + instruction, + ) + .unwrap(); + + let mut witness_set = WitnessSet::for_message(&message, &[&key1, &key2]); + witness_set.signatures_and_public_keys[0].0 = Signature::new_for_tests([1; 64]); + let tx = PublicTransaction::new(message, witness_set); + let result = tx.validate_and_compute_post_states(&state); + assert!(matches!(result, Err(NssaError::InvalidInput(_)))) + } + + #[test] + fn test_nonces_must_match_the_state_current_nonces() { + let (key1, key2, addr1, addr2) = keys_for_tests(); + let state = state_for_tests(); + let nonces = vec![0, 1]; + let instruction = 1337; + let message = Message::try_new( + Program::authenticated_transfer_program().id(), + vec![addr1, addr2], + nonces, + instruction, + ) + .unwrap(); + + let witness_set = WitnessSet::for_message(&message, &[&key1, &key2]); + let tx = PublicTransaction::new(message, witness_set); + let result = tx.validate_and_compute_post_states(&state); + assert!(matches!(result, Err(NssaError::InvalidInput(_)))) + } + + #[test] + fn test_program_id_must_belong_to_bulitin_program_ids() { + let (key1, key2, addr1, addr2) = keys_for_tests(); + let state = state_for_tests(); + let nonces = vec![0, 0]; + let instruction = 1337; + let unknown_program_id = [0xdeadbeef; 8]; + let message = + Message::try_new(unknown_program_id, vec![addr1, addr2], nonces, instruction).unwrap(); + + let witness_set = WitnessSet::for_message(&message, &[&key1, &key2]); + let tx = PublicTransaction::new(message, witness_set); + let result = tx.validate_and_compute_post_states(&state); + assert!(matches!(result, Err(NssaError::InvalidInput(_)))) + } +} diff --git a/nssa/src/public_transaction/witness_set.rs b/nssa/src/public_transaction/witness_set.rs new file mode 100644 index 0000000..f0e5c6b --- /dev/null +++ b/nssa/src/public_transaction/witness_set.rs @@ -0,0 +1,72 @@ +use crate::{PrivateKey, PublicKey, Signature, public_transaction::Message}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct WitnessSet { + pub(super) signatures_and_public_keys: Vec<(Signature, PublicKey)>, +} + +impl WitnessSet { + pub fn for_message(message: &Message, private_keys: &[&PrivateKey]) -> Self { + let message_bytes = message.to_bytes(); + let signatures_and_public_keys = private_keys + .iter() + .map(|&key| { + ( + Signature::new(key, &message_bytes), + PublicKey::new_from_private_key(key), + ) + }) + .collect(); + Self { + signatures_and_public_keys, + } + } + + pub fn is_valid_for(&self, message: &Message) -> bool { + let message_bytes = message.to_bytes(); + for (signature, public_key) in self.signatures_and_public_keys() { + if !signature.is_valid_for(&message_bytes, public_key) { + return false; + } + } + true + } + + pub fn signatures_and_public_keys(&self) -> &[(Signature, PublicKey)] { + &self.signatures_and_public_keys + } +} + +#[cfg(test)] +mod tests { + use crate::Address; + + use super::*; + + #[test] + fn test_for_message_constructor() { + let key1 = PrivateKey::try_new([1; 32]).unwrap(); + let key2 = PrivateKey::try_new([2; 32]).unwrap(); + let pubkey1 = PublicKey::new_from_private_key(&key1); + let pubkey2 = PublicKey::new_from_private_key(&key2); + let addr1 = Address::from(&pubkey1); + let addr2 = Address::from(&pubkey2); + let nonces = vec![1, 2]; + let instruction = vec![1, 2, 3, 4]; + let message = Message::try_new([0; 8], vec![addr1, addr2], nonces, instruction).unwrap(); + + let witness_set = WitnessSet::for_message(&message, &[&key1, &key2]); + + assert_eq!(witness_set.signatures_and_public_keys.len(), 2); + + let message_bytes = message.to_bytes(); + for ((signature, public_key), expected_public_key) in witness_set + .signatures_and_public_keys + .into_iter() + .zip([pubkey1, pubkey2]) + { + assert_eq!(public_key, expected_public_key); + assert!(signature.is_valid_for(&message_bytes, &expected_public_key)); + } + } +} diff --git a/nssa/src/signature/bip340_test_vectors.rs b/nssa/src/signature/bip340_test_vectors.rs new file mode 100644 index 0000000..0e91bcb --- /dev/null +++ b/nssa/src/signature/bip340_test_vectors.rs @@ -0,0 +1,367 @@ +use crate::{PrivateKey, PublicKey, Signature}; + +fn hex_to_bytes(hex: &str) -> [u8; N] { + hex::decode(hex).unwrap().try_into().unwrap() +} + +pub struct TestVector { + pub seckey: Option, + pub pubkey: PublicKey, + pub aux_rand: Option<[u8; 32]>, + pub message: Option>, + pub signature: Signature, + pub verification_result: bool, +} + +/// Test vectors from +/// https://github.com/bitcoin/bips/blob/master/bip-0340/test-vectors.csv +// +pub fn test_vectors() -> Vec { + vec![ + TestVector { + seckey: Some(PrivateKey::try_new(hex_to_bytes( + "0000000000000000000000000000000000000000000000000000000000000003", + )).unwrap()), + pubkey: PublicKey::try_new(hex_to_bytes( + "F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + )).unwrap(), + aux_rand: Some(hex_to_bytes::<32>( + "0000000000000000000000000000000000000000000000000000000000000000", + )), + message: Some( + hex::decode("0000000000000000000000000000000000000000000000000000000000000000") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "E907831F80848D1069A5371B402410364BDF1C5F8307B0084C55F1CE2DCA821525F66A4A85EA8B71E482A74F382D2CE5EBEEE8FDB2172F477DF4900D310536C0", + ), + }, + verification_result: true, + }, + TestVector { + seckey: Some(PrivateKey::try_new(hex_to_bytes( + "B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF", + )).unwrap()), + pubkey: PublicKey::try_new(hex_to_bytes( + "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + )).unwrap(), + aux_rand: Some(hex_to_bytes::<32>( + "0000000000000000000000000000000000000000000000000000000000000001", + )), + message: Some( + hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "6896BD60EEAE296DB48A229FF71DFE071BDE413E6D43F917DC8DCF8C78DE33418906D11AC976ABCCB20B091292BFF4EA897EFCB639EA871CFA95F6DE339E4B0A", + ), + }, + verification_result: true, + }, + TestVector { + seckey: Some(PrivateKey::try_new(hex_to_bytes( + "C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C9", + )).unwrap()), + pubkey: PublicKey::try_new(hex_to_bytes( + "DD308AFEC5777E13121FA72B9CC1B7CC0139715309B086C960E18FD969774EB8", + )).unwrap(), + aux_rand: Some(hex_to_bytes::<32>( + "C87AA53824B4D7AE2EB035A2B5BBBCCC080E76CDC6D1692C4B0B62D798E6D906", + )), + message: Some( + hex::decode("7E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "5831AAEED7B44BB74E5EAB94BA9D4294C49BCF2A60728D8B4C200F50DD313C1BAB745879A5AD954A72C45A91C3A51D3C7ADEA98D82F8481E0E1E03674A6F3FB7", + ), + }, + verification_result: true, + }, + TestVector { + seckey: Some(PrivateKey::try_new(hex_to_bytes( + "0B432B2677937381AEF05BB02A66ECD012773062CF3FA2549E44F58ED2401710", + )).unwrap()), + pubkey: PublicKey::try_new(hex_to_bytes( + "25D1DFF95105F5253C4022F628A996AD3A0D95FBF21D468A1B33F8C160D8F517", + )).unwrap(), + aux_rand: Some(hex_to_bytes::<32>( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + )), + message: Some( + hex::decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "7EB0509757E246F19449885651611CB965ECC1A187DD51B64FDA1EDC9637D5EC97582B9CB13DB3933705B32BA982AF5AF25FD78881EBB32771FC5922EFC66EA3", + ), + }, + verification_result: true, + }, + TestVector { + seckey: None, + pubkey: PublicKey::try_new(hex_to_bytes( + "D69C3509BB99E412E68B0FE8544E72837DFA30746D8BE2AA65975F29D22DC7B9", + )).unwrap(), + aux_rand: None, + message: Some( + hex::decode("4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C6376AFB1548AF603B3EB45C9F8207DEE1060CB71C04E80F593060B07D28308D7F4", + ), + }, + verification_result: true, + }, + // Test with invalid public key + // TestVector { + // seckey: None, + // pubkey: PublicKey::new(hex_to_bytes( + // "EEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34", + // )).unwrap(), + // aux_rand: None, + // message: Some( + // hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89").unwrap(), + // ), + // signature: Signature { + // value: hex_to_bytes( + // "6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E17776969E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B", + // ), + // }, + // verification_result: false, + // }, + TestVector { + seckey: None, + pubkey: PublicKey::try_new(hex_to_bytes( + "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + )).unwrap(), + aux_rand: None, + message: Some( + hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "FFF97BD5755EEEA420453A14355235D382F6472F8568A18B2F057A14602975563CC27944640AC607CD107AE10923D9EF7A73C643E166BE5EBEAFA34B1AC553E2", + ), + }, + verification_result: false, + }, + TestVector { + seckey: None, + pubkey: PublicKey::try_new(hex_to_bytes( + "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + )).unwrap(), + aux_rand: None, + message: Some( + hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "1FA62E331EDBC21C394792D2AB1100A7B432B013DF3F6FF4F99FCB33E0E1515F28890B3EDB6E7189B630448B515CE4F8622A954CFE545735AAEA5134FCCDB2BD", + ), + }, + verification_result: false, + }, + TestVector { + seckey: None, + pubkey: PublicKey::try_new(hex_to_bytes( + "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + )).unwrap(), + aux_rand: None, + message: Some( + hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769961764B3AA9B2FFCB6EF947B6887A226E8D7C93E00C5ED0C1834FF0D0C2E6DA6", + ), + }, + verification_result: false, + }, + TestVector { + seckey: None, + pubkey: PublicKey::try_new(hex_to_bytes( + "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + )).unwrap(), + aux_rand: None, + message: Some( + hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "0000000000000000000000000000000000000000000000000000000000000000123DDA8328AF9C23A94C1FEECFD123BA4FB73476F0D594DCB65C6425BD186051", + ), + }, + verification_result: false, + }, + TestVector { + seckey: None, + pubkey: PublicKey::try_new(hex_to_bytes( + "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + )).unwrap(), + aux_rand: None, + message: Some( + hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "00000000000000000000000000000000000000000000000000000000000000017615FBAF5AE28864013C099742DEADB4DBA87F11AC6754F93780D5A1837CF197", + ), + }, + verification_result: false, + }, + TestVector { + seckey: None, + pubkey: PublicKey::try_new(hex_to_bytes( + "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + )).unwrap(), + aux_rand: None, + message: Some( + hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "4A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B", + ), + }, + verification_result: false, + }, + TestVector { + seckey: None, + pubkey: PublicKey::try_new(hex_to_bytes( + "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + )).unwrap(), + aux_rand: None, + message: Some( + hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B", + ), + }, + verification_result: false, + }, + TestVector { + seckey: None, + pubkey: PublicKey::try_new(hex_to_bytes( + "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + )).unwrap(), + aux_rand: None, + message: Some( + hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89") + .unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + ), + }, + verification_result: false, + }, + // Test with invalid public key + // TestVector { + // seckey: None, + // pubkey: PublicKey::new(hex_to_bytes( + // "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30", + // )).unwrap(), + // aux_rand: None, + // message: Some( + // hex::decode("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89").unwrap(), + // ), + // signature: Signature { + // value: hex_to_bytes( + // "6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E17776969E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B", + // ), + // }, + // verification_result: false, + // }, + TestVector { + seckey: Some(PrivateKey::try_new(hex_to_bytes( + "0340034003400340034003400340034003400340034003400340034003400340", + )).unwrap()), + pubkey: PublicKey::try_new(hex_to_bytes( + "778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117", + )).unwrap(), + aux_rand: Some(hex_to_bytes::<32>( + "0000000000000000000000000000000000000000000000000000000000000000", + )), + message: None, + signature: Signature { + value: hex_to_bytes( + "71535DB165ECD9FBBC046E5FFAEA61186BB6AD436732FCCC25291A55895464CF6069CE26BF03466228F19A3A62DB8A649F2D560FAC652827D1AF0574E427AB63", + ), + }, + verification_result: true, + }, + TestVector { + seckey: Some(PrivateKey::try_new(hex_to_bytes( + "0340034003400340034003400340034003400340034003400340034003400340", + )).unwrap()), + pubkey: PublicKey::try_new(hex_to_bytes( + "778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117", + )).unwrap(), + aux_rand: Some(hex_to_bytes::<32>( + "0000000000000000000000000000000000000000000000000000000000000000", + )), + message: Some(hex::decode("11").unwrap()), + signature: Signature { + value: hex_to_bytes( + "08A20A0AFEF64124649232E0693C583AB1B9934AE63B4C3511F3AE1134C6A303EA3173BFEA6683BD101FA5AA5DBC1996FE7CACFC5A577D33EC14564CEC2BACBF", + ), + }, + verification_result: true, + }, + TestVector { + seckey: Some(PrivateKey::try_new(hex_to_bytes( + "0340034003400340034003400340034003400340034003400340034003400340", + )).unwrap()), + pubkey: PublicKey::try_new(hex_to_bytes( + "778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117", + )).unwrap(), + aux_rand: Some(hex_to_bytes::<32>( + "0000000000000000000000000000000000000000000000000000000000000000", + )), + message: Some(hex::decode("0102030405060708090A0B0C0D0E0F1011").unwrap()), + signature: Signature { + value: hex_to_bytes( + "5130F39A4059B43BC7CAC09A19ECE52B5D8699D1A71E3C52DA9AFDB6B50AC370C4A482B77BF960F8681540E25B6771ECE1E5A37FD80E5A51897C5566A97EA5A5", + ), + }, + verification_result: true, + }, + TestVector { + seckey: Some(PrivateKey::try_new(hex_to_bytes( + "0340034003400340034003400340034003400340034003400340034003400340", + )).unwrap()), + pubkey: PublicKey::try_new(hex_to_bytes( + "778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117", + )).unwrap(), + aux_rand: Some(hex_to_bytes::<32>( + "0000000000000000000000000000000000000000000000000000000000000000", + )), + message: Some( + hex::decode("99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999").unwrap(), + ), + signature: Signature { + value: hex_to_bytes( + "403B12B0D8555A344175EA7EC746566303321E5DBFA8BE6F091635163ECA79A8585ED3E3170807E7C03B720FC54C7B23897FCBA0E9D0B4A06894CFD249F22367", + ), + }, + verification_result: true, + }, + ] +} diff --git a/nssa/src/signature/encoding.rs b/nssa/src/signature/encoding.rs new file mode 100644 index 0000000..999e4a1 --- /dev/null +++ b/nssa/src/signature/encoding.rs @@ -0,0 +1,27 @@ +use std::io::{Cursor, Read}; + +use crate::{PublicKey, Signature, error::NssaError}; + +impl PublicKey { + pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result { + let mut value = [0u8; 32]; + cursor.read_exact(&mut value)?; + Self::try_new(value) + } + + pub(crate) fn to_bytes(&self) -> &[u8] { + self.value() + } +} + +impl Signature { + pub(crate) fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result { + let mut value = [0u8; 64]; + cursor.read_exact(&mut value)?; + Ok(Self { value }) + } + + pub(crate) fn to_bytes(&self) -> &[u8] { + &self.value + } +} diff --git a/nssa/src/signature/mod.rs b/nssa/src/signature/mod.rs new file mode 100644 index 0000000..2f18360 --- /dev/null +++ b/nssa/src/signature/mod.rs @@ -0,0 +1,95 @@ +mod encoding; +mod private_key; +mod public_key; + +pub use private_key::PrivateKey; +pub use public_key::PublicKey; + +use rand::{RngCore, rngs::OsRng}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Signature { + value: [u8; 64], +} + +impl Signature { + pub fn new(key: &PrivateKey, message: &[u8]) -> Self { + let mut aux_random = [0u8; 32]; + OsRng.fill_bytes(&mut aux_random); + Self::new_with_aux_random(key, message, aux_random) + } + + pub(crate) fn new_with_aux_random( + key: &PrivateKey, + message: &[u8], + aux_random: [u8; 32], + ) -> Self { + let value = { + let secp = secp256k1::Secp256k1::new(); + let secret_key = secp256k1::SecretKey::from_byte_array(*key.value()).unwrap(); + let keypair = secp256k1::Keypair::from_secret_key(&secp, &secret_key); + let signature = secp.sign_schnorr_with_aux_rand(message, &keypair, &aux_random); + signature.to_byte_array() + }; + Self { value } + } + + pub fn is_valid_for(&self, bytes: &[u8], public_key: &PublicKey) -> bool { + let pk = secp256k1::XOnlyPublicKey::from_byte_array(*public_key.value()).unwrap(); + let secp = secp256k1::Secp256k1::new(); + let sig = secp256k1::schnorr::Signature::from_byte_array(self.value); + secp.verify_schnorr(&sig, bytes, &pk).is_ok() + } +} + +#[cfg(test)] +mod bip340_test_vectors; + +#[cfg(test)] +mod tests { + + use crate::{Signature, signature::bip340_test_vectors}; + + impl Signature { + pub(crate) fn new_for_tests(value: [u8; 64]) -> Self { + Self { value } + } + } + + #[test] + fn test_signature_generation_from_bip340_test_vectors() { + for (i, test_vector) in bip340_test_vectors::test_vectors().into_iter().enumerate() { + let Some(private_key) = test_vector.seckey else { + continue; + }; + let Some(aux_random) = test_vector.aux_rand else { + continue; + }; + let Some(message) = test_vector.message else { + continue; + }; + if !test_vector.verification_result { + continue; + } + let expected_signature = &test_vector.signature; + + let signature = Signature::new_with_aux_random(&private_key, &message, aux_random); + + assert_eq!(&signature, expected_signature, "Failed test vector {i}"); + } + } + + #[test] + fn test_signature_verification_from_bip340_test_vectors() { + for (i, test_vector) in bip340_test_vectors::test_vectors().into_iter().enumerate() { + let message = test_vector.message.unwrap_or(vec![]); + let expected_result = test_vector.verification_result; + + let result = test_vector + .signature + .is_valid_for(&message, &test_vector.pubkey); + + assert_eq!(result, expected_result, "Failed test vector {i}"); + } + } +} diff --git a/nssa/src/signature/private_key.rs b/nssa/src/signature/private_key.rs new file mode 100644 index 0000000..abe5af6 --- /dev/null +++ b/nssa/src/signature/private_key.rs @@ -0,0 +1,54 @@ +use rand::{Rng, rngs::OsRng}; +use serde::{Deserialize, Serialize}; + +use crate::error::NssaError; + +// TODO: Remove Debug, Clone, Serialize, Deserialize, PartialEq and Eq for security reasons +// TODO: Implement Zeroize +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct PrivateKey([u8; 32]); + +impl PrivateKey { + pub fn new_os_random() -> Self { + let mut rng = OsRng; + + loop { + match Self::try_new(rng.r#gen()) { + Ok(key) => break key, + Err(_) => continue, + }; + } + } + + fn is_valid_key(value: [u8; 32]) -> bool { + secp256k1::SecretKey::from_byte_array(value).is_ok() + } + + pub fn try_new(value: [u8; 32]) -> Result { + if Self::is_valid_key(value) { + Ok(Self(value)) + } else { + Err(NssaError::InvalidPrivateKey) + } + } + + pub fn value(&self) -> &[u8; 32] { + &self.0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_value_getter() { + let key = PrivateKey::try_new([1; 32]).unwrap(); + assert_eq!(key.value(), &key.0); + } + + #[test] + fn test_produce_key() { + let key = PrivateKey::new_os_random(); + println!("{:?}", key.0); + } +} diff --git a/nssa/src/signature/public_key.rs b/nssa/src/signature/public_key.rs new file mode 100644 index 0000000..ac163d8 --- /dev/null +++ b/nssa/src/signature/public_key.rs @@ -0,0 +1,81 @@ +use crate::{PrivateKey, error::NssaError}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PublicKey([u8; 32]); + +impl PublicKey { + pub fn new_from_private_key(key: &PrivateKey) -> Self { + let value = { + let secret_key = secp256k1::SecretKey::from_byte_array(*key.value()).unwrap(); + let public_key = + secp256k1::PublicKey::from_secret_key(&secp256k1::Secp256k1::new(), &secret_key); + let (x_only, _) = public_key.x_only_public_key(); + x_only.serialize() + }; + Self(value) + } + + pub(super) fn try_new(value: [u8; 32]) -> Result { + // Check point is valid + let _ = secp256k1::XOnlyPublicKey::from_byte_array(value) + .map_err(|_| NssaError::InvalidPublicKey)?; + Ok(Self(value)) + } + + pub fn value(&self) -> &[u8; 32] { + &self.0 + } +} + +#[cfg(test)] +mod test { + use crate::{PublicKey, error::NssaError, signature::bip340_test_vectors}; + + #[test] + fn test_try_new_invalid_public_key_from_bip340_test_vectors_5() { + let value_invalid_key = [ + 238, 253, 234, 76, 219, 103, 119, 80, 164, 32, 254, 232, 7, 234, 207, 33, 235, 152, + 152, 174, 121, 185, 118, 135, 102, 228, 250, 160, 74, 45, 74, 52, + ]; + + let result = PublicKey::try_new(value_invalid_key); + + assert!(matches!(result, Err(NssaError::InvalidPublicKey))); + } + + #[test] + fn test_try_new_invalid_public_key_from_bip340_test_vector_14() { + let value_invalid_key = [ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 252, 48, + ]; + + let result = PublicKey::try_new(value_invalid_key); + + assert!(matches!(result, Err(NssaError::InvalidPublicKey))); + } + + #[test] + fn test_try_new_valid_public_keys() { + for (i, test_vector) in bip340_test_vectors::test_vectors().into_iter().enumerate() { + let expected_public_key = test_vector.pubkey; + let public_key = PublicKey::try_new(*expected_public_key.value()).unwrap(); + assert_eq!(public_key, expected_public_key, "Failed on test vector {i}"); + } + } + + #[test] + fn test_public_key_generation_from_bip340_test_vectors() { + for (i, test_vector) in bip340_test_vectors::test_vectors().into_iter().enumerate() { + let Some(private_key) = &test_vector.seckey else { + continue; + }; + let public_key = PublicKey::new_from_private_key(private_key); + let expected_public_key = &test_vector.pubkey; + assert_eq!( + &public_key, expected_public_key, + "Failed test vector at index {i}" + ); + } + } +} diff --git a/nssa/src/state.rs b/nssa/src/state.rs new file mode 100644 index 0000000..fc24355 --- /dev/null +++ b/nssa/src/state.rs @@ -0,0 +1,573 @@ +use crate::{ + address::Address, error::NssaError, program::Program, public_transaction::PublicTransaction, +}; +use nssa_core::{account::Account, program::ProgramId}; +use std::collections::HashMap; + +pub struct V01State { + public_state: HashMap, + builtin_programs: HashMap, +} + +impl V01State { + pub fn new_with_genesis_accounts(initial_data: &[(Address, u128)]) -> Self { + let authenticated_transfer_program = Program::authenticated_transfer_program(); + let public_state = initial_data + .iter() + .copied() + .map(|(address, balance)| { + let account = Account { + balance, + program_owner: authenticated_transfer_program.id(), + ..Account::default() + }; + (address, account) + }) + .collect(); + + let mut this = Self { + public_state, + builtin_programs: HashMap::new(), + }; + + this.insert_program(Program::authenticated_transfer_program()); + + this + } + + pub(crate) fn insert_program(&mut self, program: Program) { + self.builtin_programs.insert(program.id(), program); + } + + pub fn transition_from_public_transaction( + &mut self, + tx: &PublicTransaction, + ) -> Result<(), NssaError> { + let state_diff = tx.validate_and_compute_post_states(self)?; + + for (address, post) in state_diff.into_iter() { + let current_account = self.get_account_by_address_mut(address); + *current_account = post; + } + + for address in tx.signer_addresses() { + let current_account = self.get_account_by_address_mut(address); + current_account.nonce += 1; + } + + Ok(()) + } + + fn get_account_by_address_mut(&mut self, address: Address) -> &mut Account { + self.public_state.entry(address).or_default() + } + + pub fn get_account_by_address(&self, address: &Address) -> Account { + self.public_state + .get(address) + .cloned() + .unwrap_or(Account::default()) + } + + pub(crate) fn builtin_programs(&self) -> &HashMap { + &self.builtin_programs + } +} + +#[cfg(test)] +mod tests { + + use std::collections::HashMap; + + use crate::{ + Address, PublicKey, PublicTransaction, V01State, error::NssaError, program::Program, + public_transaction, signature::PrivateKey, + }; + use nssa_core::account::Account; + + fn transfer_transaction( + from: Address, + from_key: PrivateKey, + nonce: u128, + to: Address, + balance: u128, + ) -> PublicTransaction { + let addresses = vec![from, to]; + let nonces = vec![nonce]; + let program_id = Program::authenticated_transfer_program().id(); + let message = + public_transaction::Message::try_new(program_id, addresses, nonces, balance).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[&from_key]); + PublicTransaction::new(message, witness_set) + } + + #[test] + fn test_new_with_genesis() { + let key1 = PrivateKey::try_new([1; 32]).unwrap(); + let key2 = PrivateKey::try_new([2; 32]).unwrap(); + let addr1 = Address::from(&PublicKey::new_from_private_key(&key1)); + let addr2 = Address::from(&PublicKey::new_from_private_key(&key2)); + let initial_data = [(addr1, 100u128), (addr2, 151u128)]; + let program = Program::authenticated_transfer_program(); + let expected_public_state = { + let mut this = HashMap::new(); + this.insert( + addr1, + Account { + balance: 100, + program_owner: program.id(), + ..Account::default() + }, + ); + this.insert( + addr2, + Account { + balance: 151, + program_owner: program.id(), + ..Account::default() + }, + ); + this + }; + let expected_builtin_programs = { + let mut this = HashMap::new(); + this.insert(program.id(), program); + this + }; + + let state = V01State::new_with_genesis_accounts(&initial_data); + + assert_eq!(state.public_state, expected_public_state); + assert_eq!(state.builtin_programs, expected_builtin_programs); + } + + #[test] + fn test_insert_program() { + let mut state = V01State::new_with_genesis_accounts(&[]); + let program_to_insert = Program::simple_balance_transfer(); + let program_id = program_to_insert.id(); + assert!(!state.builtin_programs.contains_key(&program_id)); + + state.insert_program(program_to_insert); + + assert!(state.builtin_programs.contains_key(&program_id)); + } + + #[test] + fn test_get_account_by_address_non_default_account() { + let key = PrivateKey::try_new([1; 32]).unwrap(); + let addr = Address::from(&PublicKey::new_from_private_key(&key)); + let initial_data = [(addr, 100u128)]; + let state = V01State::new_with_genesis_accounts(&initial_data); + let expected_account = state.public_state.get(&addr).unwrap(); + + let account = state.get_account_by_address(&addr); + + assert_eq!(&account, expected_account); + } + + #[test] + fn test_get_account_by_address_default_account() { + let addr2 = Address::new([0; 32]); + let state = V01State::new_with_genesis_accounts(&[]); + let expected_account = Account::default(); + + let account = state.get_account_by_address(&addr2); + + assert_eq!(account, expected_account); + } + + #[test] + fn test_builtin_programs_getter() { + let state = V01State::new_with_genesis_accounts(&[]); + + let builtin_programs = state.builtin_programs(); + + assert_eq!(builtin_programs, &state.builtin_programs); + } + + #[test] + fn transition_from_authenticated_transfer_program_invocation_default_account_destination() { + let key = PrivateKey::try_new([1; 32]).unwrap(); + let address = Address::from(&PublicKey::new_from_private_key(&key)); + let initial_data = [(address, 100)]; + let mut state = V01State::new_with_genesis_accounts(&initial_data); + let from = address; + let to = Address::new([2; 32]); + assert_eq!(state.get_account_by_address(&to), Account::default()); + let balance_to_move = 5; + + let tx = transfer_transaction(from, key, 0, to, balance_to_move); + state.transition_from_public_transaction(&tx).unwrap(); + + assert_eq!(state.get_account_by_address(&from).balance, 95); + assert_eq!(state.get_account_by_address(&to).balance, 5); + assert_eq!(state.get_account_by_address(&from).nonce, 1); + assert_eq!(state.get_account_by_address(&to).nonce, 0); + } + + #[test] + fn transition_from_authenticated_transfer_program_invocation_insuficient_balance() { + let key = PrivateKey::try_new([1; 32]).unwrap(); + let address = Address::from(&PublicKey::new_from_private_key(&key)); + let initial_data = [(address, 100)]; + let mut state = V01State::new_with_genesis_accounts(&initial_data); + let from = address; + let from_key = key; + let to = Address::new([2; 32]); + let balance_to_move = 101; + assert!(state.get_account_by_address(&from).balance < balance_to_move); + + let tx = transfer_transaction(from, from_key, 0, to, balance_to_move); + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_)))); + assert_eq!(state.get_account_by_address(&from).balance, 100); + assert_eq!(state.get_account_by_address(&to).balance, 0); + assert_eq!(state.get_account_by_address(&from).nonce, 0); + assert_eq!(state.get_account_by_address(&to).nonce, 0); + } + + #[test] + fn transition_from_authenticated_transfer_program_invocation_non_default_account_destination() { + let key1 = PrivateKey::try_new([1; 32]).unwrap(); + let key2 = PrivateKey::try_new([2; 32]).unwrap(); + let address1 = Address::from(&PublicKey::new_from_private_key(&key1)); + let address2 = Address::from(&PublicKey::new_from_private_key(&key2)); + let initial_data = [(address1, 100), (address2, 200)]; + let mut state = V01State::new_with_genesis_accounts(&initial_data); + let from = address2; + let from_key = key2; + let to = address1; + assert_ne!(state.get_account_by_address(&to), Account::default()); + let balance_to_move = 8; + + let tx = transfer_transaction(from, from_key, 0, to, balance_to_move); + state.transition_from_public_transaction(&tx).unwrap(); + + assert_eq!(state.get_account_by_address(&from).balance, 192); + assert_eq!(state.get_account_by_address(&to).balance, 108); + assert_eq!(state.get_account_by_address(&from).nonce, 1); + assert_eq!(state.get_account_by_address(&to).nonce, 0); + } + + #[test] + fn transition_from_chained_authenticated_transfer_program_invocations() { + let key1 = PrivateKey::try_new([8; 32]).unwrap(); + let address1 = Address::from(&PublicKey::new_from_private_key(&key1)); + let key2 = PrivateKey::try_new([2; 32]).unwrap(); + let address2 = Address::from(&PublicKey::new_from_private_key(&key2)); + let initial_data = [(address1, 100)]; + let mut state = V01State::new_with_genesis_accounts(&initial_data); + let address3 = Address::new([3; 32]); + let balance_to_move = 5; + + let tx = transfer_transaction(address1, key1, 0, address2, balance_to_move); + state.transition_from_public_transaction(&tx).unwrap(); + let balance_to_move = 3; + let tx = transfer_transaction(address2, key2, 0, address3, balance_to_move); + state.transition_from_public_transaction(&tx).unwrap(); + + assert_eq!(state.get_account_by_address(&address1).balance, 95); + assert_eq!(state.get_account_by_address(&address2).balance, 2); + assert_eq!(state.get_account_by_address(&address3).balance, 3); + assert_eq!(state.get_account_by_address(&address1).nonce, 1); + assert_eq!(state.get_account_by_address(&address2).nonce, 1); + assert_eq!(state.get_account_by_address(&address3).nonce, 0); + } + + impl V01State { + pub fn force_insert_account(&mut self, address: Address, account: Account) { + self.public_state.insert(address, account); + } + + /// Include test programs in the builtin programs map + pub fn with_test_programs(mut self) -> Self { + self.insert_program(Program::nonce_changer_program()); + self.insert_program(Program::extra_output_program()); + self.insert_program(Program::missing_output_program()); + self.insert_program(Program::program_owner_changer()); + self.insert_program(Program::simple_balance_transfer()); + self.insert_program(Program::data_changer()); + self.insert_program(Program::minter()); + self.insert_program(Program::burner()); + self + } + + pub fn with_non_default_accounts_but_default_program_owners(mut self) -> Self { + let account_with_default_values_except_balance = Account { + balance: 100, + ..Account::default() + }; + let account_with_default_values_except_nonce = Account { + nonce: 37, + ..Account::default() + }; + let account_with_default_values_except_data = Account { + data: vec![0xca, 0xfe], + ..Account::default() + }; + self.force_insert_account( + Address::new([255; 32]), + account_with_default_values_except_balance, + ); + self.force_insert_account( + Address::new([254; 32]), + account_with_default_values_except_nonce, + ); + self.force_insert_account( + Address::new([253; 32]), + account_with_default_values_except_data, + ); + self + } + + pub fn with_account_owned_by_burner_program(mut self) -> Self { + let account = Account { + program_owner: Program::burner().id(), + balance: 100, + ..Default::default() + }; + self.force_insert_account(Address::new([252; 32]), account); + self + } + } + + #[test] + fn test_program_should_fail_if_modifies_nonces() { + let initial_data = [(Address::new([1; 32]), 100)]; + let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); + let addresses = vec![Address::new([1; 32])]; + let program_id = Program::nonce_changer_program().id(); + let message = + public_transaction::Message::try_new(program_id, addresses, vec![], ()).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_if_output_accounts_exceed_inputs() { + let initial_data = [(Address::new([1; 32]), 100)]; + let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); + let addresses = vec![Address::new([1; 32])]; + let program_id = Program::extra_output_program().id(); + let message = + public_transaction::Message::try_new(program_id, addresses, vec![], ()).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_with_missing_output_accounts() { + let initial_data = [(Address::new([1; 32]), 100)]; + let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); + let addresses = vec![Address::new([1; 32]), Address::new([2; 32])]; + let program_id = Program::missing_output_program().id(); + let message = + public_transaction::Message::try_new(program_id, addresses, vec![], ()).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_if_modifies_program_owner_with_only_non_default_program_owner() { + let initial_data = [(Address::new([1; 32]), 0)]; + let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); + let address = Address::new([1; 32]); + let account = state.get_account_by_address(&address); + // Assert the target account only differs from the default account in the program owner field + assert_ne!(account.program_owner, Account::default().program_owner); + assert_eq!(account.balance, Account::default().balance); + assert_eq!(account.nonce, Account::default().nonce); + assert_eq!(account.data, Account::default().data); + let program_id = Program::program_owner_changer().id(); + let message = + public_transaction::Message::try_new(program_id, vec![address], vec![], ()).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_if_modifies_program_owner_with_only_non_default_balance() { + let initial_data = []; + let mut state = V01State::new_with_genesis_accounts(&initial_data) + .with_test_programs() + .with_non_default_accounts_but_default_program_owners(); + let address = Address::new([255; 32]); + let account = state.get_account_by_address(&address); + // Assert the target account only differs from the default account in balance field + assert_eq!(account.program_owner, Account::default().program_owner); + assert_ne!(account.balance, Account::default().balance); + assert_eq!(account.nonce, Account::default().nonce); + assert_eq!(account.data, Account::default().data); + let program_id = Program::program_owner_changer().id(); + let message = + public_transaction::Message::try_new(program_id, vec![address], vec![], ()).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_if_modifies_program_owner_with_only_non_default_nonce() { + let initial_data = []; + let mut state = V01State::new_with_genesis_accounts(&initial_data) + .with_test_programs() + .with_non_default_accounts_but_default_program_owners(); + let address = Address::new([254; 32]); + let account = state.get_account_by_address(&address); + // Assert the target account only differs from the default account in nonce field + assert_eq!(account.program_owner, Account::default().program_owner); + assert_eq!(account.balance, Account::default().balance); + assert_ne!(account.nonce, Account::default().nonce); + assert_eq!(account.data, Account::default().data); + let program_id = Program::program_owner_changer().id(); + let message = + public_transaction::Message::try_new(program_id, vec![address], vec![], ()).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_if_modifies_program_owner_with_only_non_default_data() { + let initial_data = []; + let mut state = V01State::new_with_genesis_accounts(&initial_data) + .with_test_programs() + .with_non_default_accounts_but_default_program_owners(); + let address = Address::new([253; 32]); + let account = state.get_account_by_address(&address); + // Assert the target account only differs from the default account in data field + assert_eq!(account.program_owner, Account::default().program_owner); + assert_eq!(account.balance, Account::default().balance); + assert_eq!(account.nonce, Account::default().nonce); + assert_ne!(account.data, Account::default().data); + let program_id = Program::program_owner_changer().id(); + let message = + public_transaction::Message::try_new(program_id, vec![address], vec![], ()).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_if_transfers_balance_from_non_owned_account() { + let initial_data = [(Address::new([1; 32]), 100)]; + let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); + let sender_address = Address::new([1; 32]); + let receiver_address = Address::new([2; 32]); + let balance_to_move: u128 = 1; + let program_id = Program::simple_balance_transfer().id(); + assert_ne!( + state.get_account_by_address(&sender_address).program_owner, + program_id + ); + let message = public_transaction::Message::try_new( + program_id, + vec![sender_address, receiver_address], + vec![], + balance_to_move, + ) + .unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_if_modifies_data_of_non_owned_account() { + let initial_data = []; + let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); + let address = Address::new([1; 32]); + let program_id = Program::data_changer().id(); + + // Consider the extreme case where the target account is the default account + assert_eq!(state.get_account_by_address(&address), Account::default()); + assert_ne!( + state.get_account_by_address(&address).program_owner, + program_id + ); + let message = + public_transaction::Message::try_new(program_id, vec![address], vec![], ()).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_if_does_not_preserve_total_balance_by_minting() { + let initial_data = []; + let mut state = V01State::new_with_genesis_accounts(&initial_data).with_test_programs(); + let address = Address::new([1; 32]); + let program_id = Program::minter().id(); + + let message = + public_transaction::Message::try_new(program_id, vec![address], vec![], ()).unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } + + #[test] + fn test_program_should_fail_if_does_not_preserve_total_balance_by_burning() { + let initial_data = []; + let mut state = V01State::new_with_genesis_accounts(&initial_data) + .with_test_programs() + .with_account_owned_by_burner_program(); + let program_id = Program::burner().id(); + let address = Address::new([252; 32]); + assert_eq!( + state.get_account_by_address(&address).program_owner, + program_id + ); + let balance_to_burn: u128 = 1; + assert!(state.get_account_by_address(&address).balance > balance_to_burn); + + let message = public_transaction::Message::try_new( + program_id, + vec![address], + vec![], + balance_to_burn, + ) + .unwrap(); + let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); + let tx = PublicTransaction::new(message, witness_set); + let result = state.transition_from_public_transaction(&tx); + + assert!(matches!(result, Err(NssaError::InvalidProgramBehavior))); + } +} diff --git a/nssa/test_program_methods/Cargo.toml b/nssa/test_program_methods/Cargo.toml new file mode 100644 index 0000000..dded508 --- /dev/null +++ b/nssa/test_program_methods/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "test-program-methods" +version = "0.1.0" +edition = "2021" + +[build-dependencies] +risc0-build = { version = "2.3.1" } + +[package.metadata.risc0] +methods = ["guest"] diff --git a/nssa/test_program_methods/build.rs b/nssa/test_program_methods/build.rs new file mode 100644 index 0000000..08a8a4e --- /dev/null +++ b/nssa/test_program_methods/build.rs @@ -0,0 +1,3 @@ +fn main() { + risc0_build::embed_methods(); +} diff --git a/nssa/test_program_methods/guest/Cargo.toml b/nssa/test_program_methods/guest/Cargo.toml new file mode 100644 index 0000000..4b377c8 --- /dev/null +++ b/nssa/test_program_methods/guest/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "programs" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +risc0-zkvm = { version = "2.3.1", default-features = false, features = ['std'] } +nssa-core = { path = "../../core" } diff --git a/nssa/test_program_methods/guest/src/bin/burner.rs b/nssa/test_program_methods/guest/src/bin/burner.rs new file mode 100644 index 0000000..018c203 --- /dev/null +++ b/nssa/test_program_methods/guest/src/bin/burner.rs @@ -0,0 +1,19 @@ +use nssa_core::program::read_nssa_inputs; +use risc0_zkvm::guest::env; + +type Instruction = u128; + +fn main() { + let (input_accounts, balance_to_burn) = read_nssa_inputs::(); + + let [pre] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + let account_pre = pre.account; + let mut account_post = account_pre.clone(); + account_post.balance -= balance_to_burn; + + env::commit(&vec![account_post]); +} diff --git a/nssa/test_program_methods/guest/src/bin/data_changer.rs b/nssa/test_program_methods/guest/src/bin/data_changer.rs new file mode 100644 index 0000000..fa1efd3 --- /dev/null +++ b/nssa/test_program_methods/guest/src/bin/data_changer.rs @@ -0,0 +1,20 @@ +use nssa_core::program::read_nssa_inputs; +use risc0_zkvm::guest::env; + +type Instruction = (); + +fn main() { + let (input_accounts, _) = read_nssa_inputs::(); + + let [pre] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + let account_pre = pre.account; + let mut account_post = account_pre.clone(); + account_post.data.push(0); + + env::commit(&vec![account_post]); +} + diff --git a/nssa/test_program_methods/guest/src/bin/extra_output.rs b/nssa/test_program_methods/guest/src/bin/extra_output.rs new file mode 100644 index 0000000..c02c5e2 --- /dev/null +++ b/nssa/test_program_methods/guest/src/bin/extra_output.rs @@ -0,0 +1,17 @@ +use nssa_core::{account::Account, program::read_nssa_inputs}; +use risc0_zkvm::guest::env; + +type Instruction = (); + +fn main() { + let (input_accounts, _) = read_nssa_inputs::(); + + let [pre] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + let account_pre = pre.account; + + env::commit(&vec![account_pre, Account::default()]); +} diff --git a/nssa/test_program_methods/guest/src/bin/minter.rs b/nssa/test_program_methods/guest/src/bin/minter.rs new file mode 100644 index 0000000..b82d9e9 --- /dev/null +++ b/nssa/test_program_methods/guest/src/bin/minter.rs @@ -0,0 +1,19 @@ +use nssa_core::program::read_nssa_inputs; +use risc0_zkvm::guest::env; + +type Instruction = (); + +fn main() { + let (input_accounts, _) = read_nssa_inputs::(); + + let [pre] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + let account_pre = pre.account; + let mut account_post = account_pre.clone(); + account_post.balance += 1; + + env::commit(&vec![account_post]); +} diff --git a/nssa/test_program_methods/guest/src/bin/missing_output.rs b/nssa/test_program_methods/guest/src/bin/missing_output.rs new file mode 100644 index 0000000..61aa8c5 --- /dev/null +++ b/nssa/test_program_methods/guest/src/bin/missing_output.rs @@ -0,0 +1,17 @@ +use nssa_core::program::read_nssa_inputs; +use risc0_zkvm::guest::env; + +type Instruction = (); + +fn main() { + let (input_accounts, _) = read_nssa_inputs::(); + + let [pre1, _] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + let account_pre1 = pre1.account; + + env::commit(&vec![account_pre1]); +} diff --git a/nssa/test_program_methods/guest/src/bin/nonce_changer.rs b/nssa/test_program_methods/guest/src/bin/nonce_changer.rs new file mode 100644 index 0000000..eb1365e --- /dev/null +++ b/nssa/test_program_methods/guest/src/bin/nonce_changer.rs @@ -0,0 +1,19 @@ +use nssa_core::program::read_nssa_inputs; +use risc0_zkvm::guest::env; + +type Instruction = (); + +fn main() { + let (input_accounts, _) = read_nssa_inputs::(); + + let [pre] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + let account_pre = pre.account; + let mut account_post = account_pre.clone(); + account_post.nonce += 1; + + env::commit(&vec![account_post]); +} diff --git a/nssa/test_program_methods/guest/src/bin/program_owner_changer.rs b/nssa/test_program_methods/guest/src/bin/program_owner_changer.rs new file mode 100644 index 0000000..4d11438 --- /dev/null +++ b/nssa/test_program_methods/guest/src/bin/program_owner_changer.rs @@ -0,0 +1,19 @@ +use nssa_core::program::read_nssa_inputs; +use risc0_zkvm::guest::env; + +type Instruction = (); + +fn main() { + let (input_accounts, _) = read_nssa_inputs::(); + + let [pre] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + let account_pre = pre.account; + let mut account_post = account_pre.clone(); + account_post.program_owner = [0, 1, 2, 3, 4, 5, 6, 7]; + + env::commit(&vec![account_post]); +} diff --git a/nssa/test_program_methods/guest/src/bin/simple_balance_transfer.rs b/nssa/test_program_methods/guest/src/bin/simple_balance_transfer.rs new file mode 100644 index 0000000..047e252 --- /dev/null +++ b/nssa/test_program_methods/guest/src/bin/simple_balance_transfer.rs @@ -0,0 +1,20 @@ +use nssa_core::program::read_nssa_inputs; +use risc0_zkvm::guest::env; + +type Instruction = u128; + +fn main() { + let (input_accounts, balance) = read_nssa_inputs::(); + + let [sender_pre, receiver_pre] = match input_accounts.try_into() { + Ok(array) => array, + Err(_) => return, + }; + + let mut sender_post = sender_pre.account.clone(); + let mut receiver_post = receiver_pre.account.clone(); + sender_post.balance -= balance; + receiver_post.balance += balance; + + env::commit(&vec![sender_post, receiver_post]); +} diff --git a/nssa/test_program_methods/src/lib.rs b/nssa/test_program_methods/src/lib.rs new file mode 100644 index 0000000..1bdb308 --- /dev/null +++ b/nssa/test_program_methods/src/lib.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/methods.rs")); diff --git a/sc_core/Cargo.toml b/sc_core/Cargo.toml deleted file mode 100644 index bc6bade..0000000 --- a/sc_core/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "sc_core" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true -rand.workspace = true -k256.workspace = true -sha2.workspace = true -bincode.workspace = true -elliptic-curve.workspace = true -hex.workspace = true -light-poseidon.workspace = true -ark-bn254.workspace = true -ark-ff.workspace = true - -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } - -[dependencies.accounts] -path = "../accounts" - -[dependencies.storage] -path = "../storage" - -[dependencies.utxo] -path = "../utxo" - -[dependencies.common] -path = "../common" - -[dependencies.secp256k1-zkp] -workspace = true -features = ["std", "rand-std", "rand", "serde", "global-context"] diff --git a/sc_core/src/blob_utils.rs b/sc_core/src/blob_utils.rs deleted file mode 100644 index d1210ba..0000000 --- a/sc_core/src/blob_utils.rs +++ /dev/null @@ -1,125 +0,0 @@ -use serde::Serialize; -use storage::{ - sc_db_utils::{produce_blob_from_fit_vec, DataBlob, DataBlobChangeVariant}, - SC_DATA_BLOB_SIZE, -}; - -///Creates blob list from generic serializable state -/// -///`ToDo`: Find a way to align data in a way, to minimize read and write operations in db -pub fn produce_blob_list_from_sc_public_state( - state: &S, -) -> Result, serde_json::Error> { - let mut blob_list = vec![]; - - let ser_data = serde_json::to_vec(state)?; - - //`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust - for i in 0..=(ser_data.len() / SC_DATA_BLOB_SIZE) { - let next_chunk: Vec = if (i + 1) * SC_DATA_BLOB_SIZE < ser_data.len() { - ser_data[(i * SC_DATA_BLOB_SIZE)..((i + 1) * SC_DATA_BLOB_SIZE)].to_vec() - } else { - ser_data[(i * SC_DATA_BLOB_SIZE)..(ser_data.len())].to_vec() - }; - - blob_list.push(produce_blob_from_fit_vec(next_chunk)); - } - - Ok(blob_list) -} - -///Compare two consecutive in time blob lists to produce list of modified ids -pub fn compare_blob_lists( - blob_list_old: &[DataBlob], - blob_list_new: &[DataBlob], -) -> Vec { - let mut changed_ids = vec![]; - let mut id_end = 0; - - let old_len = blob_list_old.len(); - let new_len = blob_list_new.len(); - - if old_len > new_len { - for id in new_len..old_len { - changed_ids.push(DataBlobChangeVariant::Deleted { id }); - } - } else if new_len > old_len { - for (id, blob) in blob_list_new.iter().enumerate().take(new_len).skip(old_len) { - changed_ids.push(DataBlobChangeVariant::Created { id, blob: *blob }); - } - } - - loop { - let old_blob = blob_list_old.get(id_end); - let new_blob = blob_list_new.get(id_end); - - match (old_blob, new_blob) { - (Some(old), Some(new)) => { - if old != new { - changed_ids.push(DataBlobChangeVariant::Modified { - id: id_end, - blob_old: *old, - blob_new: *new, - }); - } - } - _ => break, - } - - id_end += 1; - } - - changed_ids -} - -#[cfg(test)] -mod tests { - use super::*; - use serde::Serialize; - - const TEST_BLOB_SIZE: usize = 256; // Define a test blob size for simplicity - static SC_DATA_BLOB_SIZE: usize = TEST_BLOB_SIZE; - - #[derive(Serialize)] - struct TestState { - a: u32, - b: u32, - } - - #[test] - fn test_produce_blob_list_from_sc_public_state() { - let state = TestState { a: 42, b: 99 }; - let result = produce_blob_list_from_sc_public_state(&state).unwrap(); - assert!(!result.is_empty()); - } - - #[test] - fn test_compare_blob_lists_created() { - let old_list: Vec = vec![]; - let new_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; - - let changes = compare_blob_lists(&old_list, &new_list); - assert_eq!(changes.len(), 1); - assert!(matches!(changes[0], DataBlobChangeVariant::Created { .. })); - } - - #[test] - fn test_compare_blob_lists_deleted() { - let old_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; - let new_list: Vec = vec![]; - - let changes = compare_blob_lists(&old_list, &new_list); - assert_eq!(changes.len(), 1); - assert!(matches!(changes[0], DataBlobChangeVariant::Deleted { .. })); - } - - #[test] - fn test_compare_blob_lists_modified() { - let old_list: Vec = vec![[1; SC_DATA_BLOB_SIZE].into()]; - let new_list: Vec = vec![[2; SC_DATA_BLOB_SIZE].into()]; - - let changes = compare_blob_lists(&old_list, &new_list); - assert_eq!(changes.len(), 1); - assert!(matches!(changes[0], DataBlobChangeVariant::Modified { .. })); - } -} diff --git a/sc_core/src/cryptography.rs b/sc_core/src/cryptography.rs deleted file mode 100644 index d93ce0e..0000000 --- a/sc_core/src/cryptography.rs +++ /dev/null @@ -1,10 +0,0 @@ -use ark_bn254::Fr; -use light_poseidon::{Poseidon, PoseidonBytesHasher}; - -pub fn poseidon_hash(inputs: &[&[u8]]) -> anyhow::Result<[u8; 32]> { - let mut poseidon = Poseidon::::new_circom(2).unwrap(); - - let hash = poseidon.hash_bytes_be(inputs)?; - - Ok(hash) -} diff --git a/sc_core/src/lib.rs b/sc_core/src/lib.rs deleted file mode 100644 index ed70205..0000000 --- a/sc_core/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod blob_utils; -pub mod cryptography; -pub mod proofs_circuits; -pub mod public_context; -pub mod transaction_payloads_tools; diff --git a/sc_core/src/proofs_circuits.rs b/sc_core/src/proofs_circuits.rs deleted file mode 100644 index 08ce431..0000000 --- a/sc_core/src/proofs_circuits.rs +++ /dev/null @@ -1,285 +0,0 @@ -use bincode; -use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; -use rand::{thread_rng, RngCore}; -use secp256k1_zkp::{CommitmentSecrets, Generator, PedersenCommitment, Tag, Tweak, SECP256K1}; -use sha2::{Digest, Sha256}; -use utxo::utxo_core::UTXO; - -// - -use crate::{cryptography::poseidon_hash, public_context::PublicSCContext}; - -fn hash(input: &[u8]) -> Vec { - Sha256::digest(input).to_vec() -} - -/// Generate nullifiers -/// -/// takes the input_utxo and npk -/// -/// returns the nullifiers[i], where the nullifiers[i] = poseidon_hash(in_commitments[i] || npk) -pub fn generate_nullifiers(input_utxo: &UTXO, npk: &[u8]) -> Vec { - let commitment = generate_commitment(input_utxo); - poseidon_hash(&[commitment.as_ref(), npk]).unwrap().to_vec() -} - -/// Generate commitment for UTXO -/// -/// uses the input_utxo -/// -/// returns commitment here commitment is a hash(bincode(input_utxo)) -pub fn generate_commitment(input_utxo: &UTXO) -> Vec { - let serialized = bincode::serialize(input_utxo).unwrap(); // Serialize UTXO. - hash(&serialized) -} - -/// Generate commitments for UTXO -/// -/// uses the input_utxos -/// -/// returns commitments -pub fn generate_commitments(input_utxos: &[UTXO]) -> Vec> { - input_utxos - .iter() - .map(|utxo| { - let serialized = bincode::serialize(utxo).unwrap(); // Serialize UTXO. - hash(&serialized) - }) - .collect() -} - -/// Validate inclusion proof for in_commitments -/// -/// ToDo: Solve it in more scalable way -pub fn validate_in_commitments_tree( - in_commitment: &[u8], - commitment_tree: &UTXOCommitmentsMerkleTree, -) -> bool { - let alighned_hash: [u8; 32] = in_commitment.try_into().unwrap(); - - commitment_tree.get_proof(alighned_hash).is_some() -} - -/// Check, that input utxos balances is equal to out utxo balances -pub fn check_balances_private(in_utxos: &[UTXO], out_utxos: &[UTXO]) -> bool { - let in_sum = in_utxos.iter().fold(0, |prev, utxo| prev + utxo.amount); - let out_sum = out_utxos.iter().fold(0, |prev, utxo| prev + utxo.amount); - - in_sum == out_sum -} - -pub fn private_circuit( - input_utxos: &[UTXO], - output_utxos: &[UTXO], - public_context: &PublicSCContext, -) -> (Vec>, Vec>) { - assert!(check_balances_private(input_utxos, output_utxos)); - - let in_commitments = generate_commitments(input_utxos); - - let mut in_nullifiers = vec![]; - - for in_utxo in input_utxos { - let nullifier_public_key = public_context - .account_masks - .get(&in_utxo.owner) - .unwrap() - .nullifier_public_key; - - let key_ser = serde_json::to_vec(&nullifier_public_key).unwrap(); - - in_nullifiers.push(generate_nullifiers(in_utxo, &key_ser)); - } - - for in_commitment in in_commitments { - assert!(validate_in_commitments_tree( - &in_commitment, - &public_context.commitments_tree, - )); - } - - (in_nullifiers, generate_commitments(output_utxos)) -} - -/// Check balances DE -/// -/// takes the input_utxos[] and output_balance, -/// -/// returns the True if the token amount in output_balance matches the sum of all input_utxos[], otherwise return False. -pub fn check_balances_de(input_utxos: &[UTXO], output_balance: u128) -> bool { - let total_input: u128 = input_utxos.iter().map(|utxo| utxo.amount).sum(); - total_input == output_balance -} - -pub fn deshielded_circuit( - input_utxos: &[UTXO], - output_balance: u128, - public_context: &PublicSCContext, -) -> Vec> { - assert!(check_balances_de(input_utxos, output_balance)); - - let in_commitments = generate_commitments(input_utxos); - - let mut in_nullifiers = vec![]; - - for in_utxo in input_utxos { - let nullifier_public_key = public_context - .account_masks - .get(&in_utxo.owner) - .unwrap() - .nullifier_public_key; - - let key_ser = serde_json::to_vec(&nullifier_public_key).unwrap(); - - in_nullifiers.push(generate_nullifiers(in_utxo, &key_ser)); - } - - for in_commitment in in_commitments { - assert!(validate_in_commitments_tree( - &in_commitment, - &public_context.commitments_tree, - )); - } - - in_nullifiers -} - -#[allow(unused)] -fn commitment_secrets_random(value: u64) -> CommitmentSecrets { - CommitmentSecrets { - value, - value_blinding_factor: Tweak::new(&mut thread_rng()), - generator_blinding_factor: Tweak::new(&mut thread_rng()), - } -} - -pub fn tag_random() -> Tag { - use rand::thread_rng; - use rand::RngCore; - - let mut bytes = [0u8; 32]; - thread_rng().fill_bytes(&mut bytes); - - Tag::from(bytes) -} - -pub fn commit(comm: &CommitmentSecrets, tag: Tag) -> PedersenCommitment { - let generator = Generator::new_blinded(SECP256K1, tag, comm.generator_blinding_factor); - - PedersenCommitment::new(SECP256K1, comm.value, comm.value_blinding_factor, generator) -} - -/// new_commitment for a Vec of values -pub fn pedersen_commitment_vec( - public_info_vec: Vec, -) -> (Tweak, [u8; 32], Vec) { - let mut random_val: [u8; 32] = [0; 32]; - thread_rng().fill_bytes(&mut random_val); - - let generator_blinding_factor = Tweak::new(&mut thread_rng()); - let tag = tag_random(); - - let vec_commitments = public_info_vec - .into_iter() - .map(|public_info| { - let commitment_secrets = CommitmentSecrets { - value: public_info, - value_blinding_factor: Tweak::from_slice(&random_val).unwrap(), - generator_blinding_factor, - }; - - commit(&commitment_secrets, tag) - }) - .collect(); - - (generator_blinding_factor, random_val, vec_commitments) -} - -/// Verify Pedersen commitment -/// -/// takes the public_info, secret_r and pedersen_commitment and -/// -/// checks that commitment(public_info,secret_r) is equal pedersen_commitment where the commitment is pedersen commitment. -pub fn verify_commitment( - public_info: u64, - secret_r: &[u8], - pedersen_commitment: &PedersenCommitment, -) -> bool { - let commitment_secrets = CommitmentSecrets { - value: public_info, - value_blinding_factor: Tweak::from_slice(secret_r).unwrap(), - generator_blinding_factor: Tweak::new(&mut thread_rng()), - }; - - let tag = tag_random(); - let commitment = commit(&commitment_secrets, tag); - - commitment == *pedersen_commitment -} - -/// Validate inclusion proof for pedersen_commitment -/// -/// ToDo: Solve it in more scalable way -pub fn validate_in_commitments_tree_se( - pedersen_commitment: &PedersenCommitment, - commitment_tree: &UTXOCommitmentsMerkleTree, -) -> bool { - let alighned_hash: [u8; 32] = pedersen_commitment.serialize()[0..32].try_into().unwrap(); - - commitment_tree.get_proof(alighned_hash).is_some() -} - -/// Generate nullifier SE -/// -/// takes the pedersen_commitment and npk then -/// returns a nullifier, where the nullifier = poseidon_hash(pedersen_commitment || npk) -pub fn generate_nullifiers_se(pedersen_commitment: &PedersenCommitment, npk: &[u8]) -> Vec { - let commitment_ser = pedersen_commitment.serialize().to_vec(); - - poseidon_hash(&[&commitment_ser, npk]).unwrap().to_vec() -} - -/// Check balances SE -/// -/// takes the input_balance and output_utxos[], -/// -/// returns the True if the token amount in input_balance matches the sum of all output_utxos[], otherwise return False. -pub fn check_balances_se(input_balance: u128, output_utxos: &[UTXO]) -> bool { - let total_output: u128 = output_utxos.iter().map(|utxo| utxo.amount).sum(); - total_output == input_balance -} - -pub fn shielded_circuit( - public_info: u64, - output_utxos: &[UTXO], - pedersen_commitment: PedersenCommitment, - secret_r: &[u8], - public_context: &PublicSCContext, -) -> (Vec>, Vec) { - assert!(check_balances_se(public_info as u128, output_utxos)); - - let out_commitments = generate_commitments(output_utxos); - - let nullifier_public_key = public_context - .account_masks - .get(&public_context.caller_address) - .unwrap() - .nullifier_public_key; - - let key_ser = serde_json::to_vec(&nullifier_public_key).unwrap(); - - let nullifier = generate_nullifiers_se(&pedersen_commitment, &key_ser); - - assert!(validate_in_commitments_tree_se( - &pedersen_commitment, - &public_context.commitments_tree, - )); - - assert!(verify_commitment( - public_info, - secret_r, - &pedersen_commitment - )); - - (out_commitments, nullifier) -} diff --git a/sc_core/src/public_context.rs b/sc_core/src/public_context.rs deleted file mode 100644 index e225513..0000000 --- a/sc_core/src/public_context.rs +++ /dev/null @@ -1,180 +0,0 @@ -use std::collections::BTreeMap; - -use accounts::account_core::{address::AccountAddress, AccountPublicMask}; -use common::merkle_tree_public::{merkle_tree::UTXOCommitmentsMerkleTree, TreeHashType}; -use serde::{ser::SerializeStruct, Serialize}; - -pub const PUBLIC_SC_CONTEXT: &str = "PublicSCContext"; -pub const CALLER_ADDRESS: &str = "caller_address"; -pub const CALLER_BALANCE: &str = "caller_balance"; -pub const ACCOUNT_MASKS_KEYS_SORTED: &str = "account_masks_keys_sorted"; -pub const ACCOUNT_MASKS_VALUES_SORTED: &str = "account_masks_values_sorted"; -pub const COMMITMENT_STORE_ROOT: &str = "commitment_store_root"; -pub const PUT_TX_STORE_ROOT: &str = "put_tx_store_root"; -pub const COMMITMENT_TREE: &str = "commitments_tree"; -pub const NULLIFIERS_SET: &str = "nullifiers_set"; - -///Strucutre, representing context, given to a smart contract on a call -pub struct PublicSCContext { - pub caller_address: AccountAddress, - pub caller_balance: u64, - pub account_masks: BTreeMap, - pub comitment_store_root: TreeHashType, - pub commitments_tree: UTXOCommitmentsMerkleTree, -} - -impl Serialize for PublicSCContext { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut account_masks_keys: Vec<[u8; 32]> = self.account_masks.keys().cloned().collect(); - account_masks_keys.sort(); - - let mut account_mask_values: Vec = - self.account_masks.values().cloned().collect(); - account_mask_values.sort_by(|left, right| left.address.cmp(&right.address)); - - let mut s = serializer.serialize_struct(PUBLIC_SC_CONTEXT, 7)?; - - s.serialize_field(CALLER_ADDRESS, &self.caller_address)?; - s.serialize_field(CALLER_BALANCE, &self.caller_balance)?; - s.serialize_field(ACCOUNT_MASKS_KEYS_SORTED, &account_masks_keys)?; - s.serialize_field(ACCOUNT_MASKS_VALUES_SORTED, &account_mask_values)?; - s.serialize_field(COMMITMENT_STORE_ROOT, &self.comitment_store_root)?; - s.serialize_field(COMMITMENT_TREE, &self.commitments_tree)?; - - s.end() - } -} - -impl PublicSCContext { - ///Produces `u64` from bytes in a vector - /// - /// Assumes, that vector of le_bytes - pub fn produce_u64_from_fit_vec(data: Vec) -> u64 { - let data_len = data.len(); - - assert!(data_len <= 8); - let mut le_bytes: [u8; 8] = [0; 8]; - - for (idx, item) in data.into_iter().enumerate() { - le_bytes[idx] = item - } - - u64::from_le_bytes(le_bytes) - } - - ///Produces vector of `u64` from context - pub fn produce_u64_list_from_context(&self) -> Result, serde_json::Error> { - let mut u64_list = vec![]; - - let ser_data = serde_json::to_vec(self)?; - - //`ToDo` Replace with `next_chunk` usage, when feature stabilizes in Rust - for i in 0..=(ser_data.len() / 8) { - let next_chunk: Vec = if (i + 1) * 8 < ser_data.len() { - ser_data[(i * 8)..((i + 1) * 8)].to_vec() - } else { - ser_data[(i * 8)..(ser_data.len())].to_vec() - }; - - u64_list.push(PublicSCContext::produce_u64_from_fit_vec(next_chunk)); - } - - Ok(u64_list) - } -} - -#[cfg(test)] -mod tests { - use accounts::account_core::Account; - use common::utxo_commitment::UTXOCommitment; - - use super::*; - - fn create_test_context() -> PublicSCContext { - let caller_address = [1; 32]; - let comitment_store_root = [3; 32]; - - let commitments_tree = - UTXOCommitmentsMerkleTree::new(vec![UTXOCommitment { hash: [5; 32] }]); - - let mut account_masks = BTreeMap::new(); - - let acc_1 = Account::new(); - let acc_2 = Account::new(); - let acc_3 = Account::new(); - - account_masks.insert(acc_1.address, acc_1.make_account_public_mask()); - account_masks.insert(acc_2.address, acc_2.make_account_public_mask()); - account_masks.insert(acc_3.address, acc_3.make_account_public_mask()); - - PublicSCContext { - caller_address, - caller_balance: 100, - account_masks, - comitment_store_root, - commitments_tree, - } - } - - #[test] - fn bin_ser_stability_test() { - let test_context = create_test_context(); - - let serialization_1 = serde_json::to_vec(&test_context).unwrap(); - let serialization_2 = serde_json::to_vec(&test_context).unwrap(); - - assert_eq!(serialization_1, serialization_2); - } - - #[test] - fn correct_u64_production_from_fit_vec() { - let le_vec = vec![1, 1, 1, 1, 2, 1, 1, 1]; - - let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); - - assert_eq!(num, 72340177133043969); - } - - #[test] - fn correct_u64_production_from_small_vec() { - //7 items instead of 8 - let le_vec = vec![1, 1, 1, 1, 2, 1, 1]; - - let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); - - assert_eq!(num, 282583095116033); - } - - #[test] - fn correct_u64_production_from_small_vec_le_bytes() { - //7 items instead of 8 - let le_vec = vec![1, 1, 1, 1, 2, 1, 1]; - let le_vec_res = [1, 1, 1, 1, 2, 1, 1, 0]; - - let num = PublicSCContext::produce_u64_from_fit_vec(le_vec); - - assert_eq!(num.to_le_bytes(), le_vec_res); - } - - #[test] - #[should_panic] - fn correct_u64_production_from_unfit_vec_should_panic() { - //9 items instead of 8 - let le_vec = vec![1, 1, 1, 1, 2, 1, 1, 1, 1]; - - PublicSCContext::produce_u64_from_fit_vec(le_vec); - } - - #[test] - fn consistent_len_of_context_commitments() { - let test_context = create_test_context(); - - let context_num_vec1 = test_context.produce_u64_list_from_context().unwrap(); - let context_num_vec2 = test_context.produce_u64_list_from_context().unwrap(); - - assert_eq!(context_num_vec1.len(), context_num_vec2.len()); - } -} diff --git a/sc_core/src/transaction_payloads_tools.rs b/sc_core/src/transaction_payloads_tools.rs deleted file mode 100644 index 543cfa8..0000000 --- a/sc_core/src/transaction_payloads_tools.rs +++ /dev/null @@ -1,100 +0,0 @@ -use accounts::{account_core::Account, key_management::ephemeral_key_holder::EphemeralKeyHolder}; -use anyhow::Result; -use common::transaction::{TransactionBody, TxKind}; -use rand::thread_rng; -use risc0_zkvm::Receipt; -use secp256k1_zkp::{CommitmentSecrets, PedersenCommitment, Tweak}; -use utxo::utxo_core::UTXO; - -use crate::proofs_circuits::{commit, generate_nullifiers, tag_random}; - -pub fn create_public_transaction_payload( - execution_input: Vec, - commitment: Vec, - tweak: Tweak, - secret_r: [u8; 32], - sc_addr: String, -) -> TransactionBody { - TransactionBody { - tx_kind: TxKind::Public, - execution_input, - execution_output: vec![], - utxo_commitments_spent_hashes: vec![], - utxo_commitments_created_hashes: vec![], - nullifier_created_hashes: vec![], - execution_proof_private: "".to_string(), - encoded_data: vec![], - ephemeral_pub_key: vec![], - commitment, - tweak, - secret_r, - sc_addr, - } -} - -pub fn encode_utxos_to_receivers( - utxos_receivers: Vec<(UTXO, &Account)>, -) -> Vec<(Vec, Vec)> { - let mut all_encoded_data = vec![]; - - for (utxo, receiver) in utxos_receivers { - let ephm_key_holder = EphemeralKeyHolder::new_os_random(); - - let encoded_data = Account::encrypt_data( - &ephm_key_holder, - receiver.key_holder.viewing_public_key, - &serde_json::to_vec(&utxo).unwrap(), - ); - - let encoded_data_vec = (encoded_data.0, encoded_data.1.to_vec()); - - all_encoded_data.push(encoded_data_vec); - } - - all_encoded_data -} - -pub fn generate_nullifiers_spent_utxos(utxos_spent: Vec<(UTXO, &Account)>) -> Vec> { - let mut all_nullifiers = vec![]; - - for (utxo, spender) in utxos_spent { - let nullifier = generate_nullifiers( - &utxo, - &spender - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key - .to_bytes(), - ); - - all_nullifiers.push(nullifier); - } - - all_nullifiers -} - -pub fn encode_receipt(receipt: Receipt) -> Result { - Ok(hex::encode(serde_json::to_vec(&receipt)?)) -} - -pub fn generate_secret_random_commitment( - value: u64, - account: &Account, -) -> Result { - let commitment_secrets = CommitmentSecrets { - value, - value_blinding_factor: Tweak::from_slice( - &account - .key_holder - .utxo_secret_key_holder - .viewing_secret_key - .to_bytes(), - )?, - generator_blinding_factor: Tweak::new(&mut thread_rng()), - }; - - let tag = tag_random(); - let commitment = commit(&commitment_secrets, tag); - - Ok(commitment) -} diff --git a/sequencer_core/Cargo.toml b/sequencer_core/Cargo.toml index f148655..2e3570b 100644 --- a/sequencer_core/Cargo.toml +++ b/sequencer_core/Cargo.toml @@ -22,12 +22,15 @@ path = "../storage" [dependencies.mempool] path = "../mempool" -[dependencies.accounts] -path = "../accounts" +[dependencies.key_protocol] +path = "../key_protocol" [dependencies.common] path = "../common" +[dependencies.nssa] +path = "../nssa" + [dependencies.secp256k1-zkp] workspace = true features = ["std", "rand-std", "rand", "serde", "global-context"] diff --git a/sequencer_core/src/config.rs b/sequencer_core/src/config.rs index 2dda687..4a99f0b 100644 --- a/sequencer_core/src/config.rs +++ b/sequencer_core/src/config.rs @@ -6,7 +6,7 @@ use std::path::PathBuf; pub struct AccountInitialData { ///Hex encoded `AccountAddress` pub addr: String, - pub balance: u64, + pub balance: u128, } #[derive(Clone, Serialize, Deserialize)] diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 810166d..b56b34cc 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -1,28 +1,18 @@ use std::fmt::Display; -use accounts::account_core::address::{self, AccountAddress}; use anyhow::Result; -use common::{ - block::HashableBlockData, - execution_input::PublicNativeTokenSend, - merkle_tree_public::TreeHashType, - nullifier::UTXONullifier, - transaction::{AuthenticatedTransaction, Transaction, TransactionBody, TxKind}, - utxo_commitment::UTXOCommitment, -}; +use common::{block::HashableBlockData, merkle_tree_public::TreeHashType}; use config::SequencerConfig; use mempool::MemPool; -use mempool_transaction::MempoolTransaction; use sequencer_store::SequecerChainStore; use serde::{Deserialize, Serialize}; pub mod config; -pub mod mempool_transaction; pub mod sequencer_store; pub struct SequencerCore { pub store: SequecerChainStore, - pub mempool: MemPool, + pub mempool: MemPool, pub sequencer_config: SequencerConfig, pub chain_height: u64, } @@ -34,7 +24,7 @@ pub enum TransactionMalformationErrorKind { TxHashAlreadyPresentInTree { tx: TreeHashType }, NullifierAlreadyPresentInTree { tx: TreeHashType }, UTXOCommitmentAlreadyPresentInTree { tx: TreeHashType }, - MempoolFullForRound { tx: TreeHashType }, + MempoolFullForRound, ChainStateFurtherThanTransactionState { tx: TreeHashType }, FailedToInsert { tx: TreeHashType, details: String }, InvalidSignature, @@ -61,219 +51,47 @@ impl SequencerCore { config.is_genesis_random, &config.initial_accounts, ), - mempool: MemPool::::default(), + mempool: MemPool::default(), chain_height: config.genesis_id, sequencer_config: config, } } - pub fn get_tree_roots(&self) -> [[u8; 32]; 2] { - [ - self.store - .utxo_commitments_store - .get_root() - .unwrap_or([0; 32]), - self.store.pub_tx_store.get_root().unwrap_or([0; 32]), - ] - } - pub fn transaction_pre_check( &mut self, - tx: Transaction, - ) -> Result { - let tx = tx - .into_authenticated() - .map_err(|_| TransactionMalformationErrorKind::InvalidSignature)?; - - let TransactionBody { - tx_kind, - ref execution_input, - ref execution_output, - ref utxo_commitments_created_hashes, - ref nullifier_created_hashes, - .. - } = tx.transaction().body(); - - let tx_hash = *tx.hash(); - - let mempool_size = self.mempool.len(); - - if mempool_size >= self.sequencer_config.max_num_tx_in_block { - return Err(TransactionMalformationErrorKind::MempoolFullForRound { tx: tx_hash }); + tx: nssa::PublicTransaction, + ) -> Result { + // Stateless checks here + if tx.witness_set().is_valid_for(tx.message()) { + Ok(tx) + } else { + Err(TransactionMalformationErrorKind::InvalidSignature) } - - //Sanity check - match tx_kind { - TxKind::Public => { - if !utxo_commitments_created_hashes.is_empty() - || !nullifier_created_hashes.is_empty() - { - //Public transactions can not make private operations. - return Err( - TransactionMalformationErrorKind::PublicTransactionChangedPrivateData { - tx: tx_hash, - }, - ); - } - } - TxKind::Private => { - if !execution_input.is_empty() || !execution_output.is_empty() { - //Not entirely necessary, but useful simplification for a future. - //This way only shielded and deshielded transactions can be used for interaction - //between public and private state. - return Err( - TransactionMalformationErrorKind::PrivateTransactionChangedPublicData { - tx: tx_hash, - }, - ); - } - } - _ => {} - }; - - //Native transfers checks - if let Ok(native_transfer_action) = - serde_json::from_slice::(execution_input) - { - let signer_address = address::from_public_key(&tx.transaction().public_key); - - //Correct sender check - if native_transfer_action.from != signer_address { - return Err(TransactionMalformationErrorKind::IncorrectSender); - } - } - - //Tree checks - let tx_tree_check = self.store.pub_tx_store.get_tx(tx_hash).is_some(); - let nullifier_tree_check = nullifier_created_hashes.iter().any(|nullifier_hash| { - self.store.nullifier_store.contains(&UTXONullifier { - utxo_hash: *nullifier_hash, - }) - }); - let utxo_commitments_check = - utxo_commitments_created_hashes - .iter() - .any(|utxo_commitment_hash| { - self.store - .utxo_commitments_store - .get_tx(*utxo_commitment_hash) - .is_some() - }); - - if tx_tree_check { - return Err( - TransactionMalformationErrorKind::TxHashAlreadyPresentInTree { tx: *tx.hash() }, - ); - } - - if nullifier_tree_check { - return Err( - TransactionMalformationErrorKind::NullifierAlreadyPresentInTree { tx: *tx.hash() }, - ); - } - - if utxo_commitments_check { - return Err( - TransactionMalformationErrorKind::UTXOCommitmentAlreadyPresentInTree { - tx: *tx.hash(), - }, - ); - } - - Ok(tx) } pub fn push_tx_into_mempool_pre_check( &mut self, - transaction: Transaction, + transaction: nssa::PublicTransaction, ) -> Result<(), TransactionMalformationErrorKind> { let mempool_size = self.mempool.len(); if mempool_size >= self.sequencer_config.max_num_tx_in_block { - return Err(TransactionMalformationErrorKind::MempoolFullForRound { - tx: transaction.body().hash(), - }); + return Err(TransactionMalformationErrorKind::MempoolFullForRound); } let authenticated_tx = self.transaction_pre_check(transaction)?; - self.mempool.push_item(authenticated_tx.into()); + self.mempool.push_item(authenticated_tx); Ok(()) } fn execute_check_transaction_on_state( &mut self, - mempool_tx: &MempoolTransaction, - ) -> Result<(), TransactionMalformationErrorKind> { - let TransactionBody { - ref utxo_commitments_created_hashes, - ref nullifier_created_hashes, - execution_input, - .. - } = mempool_tx.auth_tx.transaction().body(); + tx: nssa::PublicTransaction, + ) -> Result { + self.store.state.transition_from_public_transaction(&tx)?; - let tx_hash = *mempool_tx.auth_tx.hash(); - - //Balance move - if let Ok(native_transfer_action) = - serde_json::from_slice::(execution_input) - { - // Nonce check - let signer_addres = - address::from_public_key(&mempool_tx.auth_tx.transaction().public_key); - if self.store.acc_store.get_account_nonce(&signer_addres) - != native_transfer_action.nonce - { - return Err(TransactionMalformationErrorKind::NonceMismatch { tx: tx_hash }); - } - - let from_balance = self - .store - .acc_store - .get_account_balance(&native_transfer_action.from); - let to_balance = self - .store - .acc_store - .get_account_balance(&native_transfer_action.to); - - //Balance check - if from_balance < native_transfer_action.balance_to_move { - return Err(TransactionMalformationErrorKind::BalanceMismatch { tx: tx_hash }); - } - - self.store.acc_store.set_account_balance( - &native_transfer_action.from, - from_balance - native_transfer_action.balance_to_move, - ); - self.store.acc_store.set_account_balance( - &native_transfer_action.to, - to_balance + native_transfer_action.balance_to_move, - ); - - self.store.acc_store.increase_nonce(&signer_addres); - } - - for utxo_comm in utxo_commitments_created_hashes { - self.store - .utxo_commitments_store - .add_tx(&UTXOCommitment { hash: *utxo_comm }); - } - - for nullifier in nullifier_created_hashes.iter() { - self.store.nullifier_store.insert(UTXONullifier { - utxo_hash: *nullifier, - }); - } - - self.store - .pub_tx_store - .add_tx(mempool_tx.auth_tx.transaction()); - - Ok(()) - } - - pub fn register_account(&mut self, account_addr: AccountAddress) { - self.store.acc_store.register_account(account_addr); + Ok(tx) } ///Produces new block from transactions in mempool @@ -284,15 +102,9 @@ impl SequencerCore { .mempool .pop_size(self.sequencer_config.max_num_tx_in_block); - let valid_transactions = transactions + let valid_transactions: Vec<_> = transactions .into_iter() - .filter_map(|mempool_tx| { - if self.execute_check_transaction_on_state(&mempool_tx).is_ok() { - Some(mempool_tx.auth_tx.into_transaction()) - } else { - None - } - }) + .filter_map(|tx| self.execute_check_transaction_on_state(tx).ok()) .collect(); let prev_block_hash = self @@ -305,7 +117,6 @@ impl SequencerCore { block_id: new_block_height, prev_block_id: self.chain_height, transactions: valid_transactions, - data: vec![], prev_block_hash, }; @@ -324,8 +135,6 @@ mod tests { use crate::config::AccountInitialData; use super::*; - use k256::{ecdsa::SigningKey, FieldBytes}; - use mempool_transaction::MempoolTransaction; fn setup_sequencer_config_variable_initial_accounts( initial_accounts: Vec, @@ -347,13 +156,13 @@ mod tests { fn setup_sequencer_config() -> SequencerConfig { let acc1_addr = vec![ - 13, 150, 223, 204, 65, 64, 25, 56, 12, 157, 222, 12, 211, 220, 229, 170, 201, 15, 181, - 68, 59, 248, 113, 16, 135, 65, 174, 175, 222, 85, 42, 215, + 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, + 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143, ]; let acc2_addr = vec![ - 151, 72, 112, 233, 190, 141, 10, 192, 138, 168, 59, 63, 199, 167, 166, 134, 41, 29, - 135, 50, 80, 138, 186, 152, 179, 96, 128, 243, 156, 44, 243, 100, + 77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217, 234, + 216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102, ]; let initial_acc1 = AccountInitialData { @@ -371,36 +180,17 @@ mod tests { setup_sequencer_config_variable_initial_accounts(initial_accounts) } - fn create_signing_key_for_account1() -> SigningKey { - let pub_sign_key_acc1 = [ - 133, 143, 177, 187, 252, 66, 237, 236, 234, 252, 244, 138, 5, 151, 3, 99, 217, 231, - 112, 217, 77, 211, 58, 218, 176, 68, 99, 53, 152, 228, 198, 190, - ]; - - let field_bytes = FieldBytes::from_slice(&pub_sign_key_acc1); - SigningKey::from_bytes(field_bytes).unwrap() + fn create_signing_key_for_account1() -> nssa::PrivateKey { + nssa::PrivateKey::try_new([1; 32]).unwrap() } - fn create_signing_key_for_account2() -> SigningKey { - let pub_sign_key_acc2 = [ - 54, 90, 62, 225, 71, 225, 228, 148, 143, 53, 210, 23, 137, 158, 171, 156, 48, 7, 139, - 52, 117, 242, 214, 7, 99, 29, 122, 184, 59, 116, 144, 107, - ]; - - let field_bytes = FieldBytes::from_slice(&pub_sign_key_acc2); - SigningKey::from_bytes(field_bytes).unwrap() + fn create_signing_key_for_account2() -> nssa::PrivateKey { + nssa::PrivateKey::try_new([2; 32]).unwrap() } fn common_setup(sequencer: &mut SequencerCore) { - let tx = common::test_utils::create_dummy_private_transaction_random_signer( - vec![[9; 32]], - vec![[7; 32]], - vec![[8; 32]], - ); - let mempool_tx = MempoolTransaction { - auth_tx: tx.into_authenticated().unwrap(), - }; - sequencer.mempool.push_item(mempool_tx); + let tx = common::test_utils::produce_dummy_empty_transaction(); + sequencer.mempool.push_item(tx); sequencer .produce_new_block_with_mempool_transactions() @@ -425,29 +215,31 @@ mod tests { .try_into() .unwrap(); - assert!(sequencer.store.acc_store.contains_account(&acc1_addr)); - assert!(sequencer.store.acc_store.contains_account(&acc2_addr)); + let balance_acc_1 = sequencer + .store + .state + .get_account_by_address(&nssa::Address::new(acc1_addr)) + .balance; + let balance_acc_2 = sequencer + .store + .state + .get_account_by_address(&nssa::Address::new(acc2_addr)) + .balance; - assert_eq!( - 10000, - sequencer.store.acc_store.get_account_balance(&acc1_addr) - ); - assert_eq!( - 20000, - sequencer.store.acc_store.get_account_balance(&acc2_addr) - ); + assert_eq!(10000, balance_acc_1); + assert_eq!(20000, balance_acc_2); } #[test] fn test_start_different_intial_accounts_balances() { let acc1_addr = vec![ - 13, 150, 223, 204, 65, 64, 25, 56, 12, 157, 222, 12, 211, 220, 229, 170, 201, 15, 181, - 68, 59, 248, 113, 16, 135, 65, 174, 175, 222, 42, 42, 42, + 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, + 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143, ]; let acc2_addr = vec![ - 151, 72, 112, 233, 190, 141, 10, 192, 138, 168, 59, 63, 199, 167, 166, 134, 41, 29, - 135, 50, 80, 138, 186, 152, 179, 96, 128, 243, 156, 42, 42, 42, + 77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217, 234, + 216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102, ]; let initial_acc1 = AccountInitialData { @@ -462,8 +254,6 @@ mod tests { let initial_accounts = vec![initial_acc1, initial_acc2]; - let intial_accounts_len = initial_accounts.len(); - let config = setup_sequencer_config_variable_initial_accounts(initial_accounts); let sequencer = SequencerCore::start_from_config(config.clone()); @@ -476,32 +266,24 @@ mod tests { .try_into() .unwrap(); - assert!(sequencer.store.acc_store.contains_account(&acc1_addr)); - assert!(sequencer.store.acc_store.contains_account(&acc2_addr)); - - assert_eq!(sequencer.store.acc_store.len(), intial_accounts_len); - assert_eq!( 10000, - sequencer.store.acc_store.get_account_balance(&acc1_addr) + sequencer + .store + .state + .get_account_by_address(&nssa::Address::new(acc1_addr)) + .balance ); assert_eq!( 20000, - sequencer.store.acc_store.get_account_balance(&acc2_addr) + sequencer + .store + .state + .get_account_by_address(&nssa::Address::new(acc2_addr)) + .balance ); } - #[test] - fn test_get_tree_roots() { - let config = setup_sequencer_config(); - let mut sequencer = SequencerCore::start_from_config(config); - - common_setup(&mut sequencer); - - let roots = sequencer.get_tree_roots(); - assert_eq!(roots.len(), 2); // Should return two roots - } - #[test] fn test_transaction_pre_check_pass() { let config = setup_sequencer_config(); @@ -509,12 +291,7 @@ mod tests { common_setup(&mut sequencer); - let tx = common::test_utils::create_dummy_private_transaction_random_signer( - vec![[91; 32]], - vec![[71; 32]], - vec![[81; 32]], - ); - + let tx = common::test_utils::produce_dummy_empty_transaction(); let result = sequencer.transaction_pre_check(tx); assert!(result.is_ok()); @@ -538,10 +315,9 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + let tx = common::test_utils::create_transaction_native_token_transfer( acc1, 0, acc2, 10, sign_key1, ); - let result = sequencer.transaction_pre_check(tx); assert!(result.is_ok()); @@ -565,16 +341,20 @@ mod tests { let sign_key2 = create_signing_key_for_account2(); - let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + let tx = common::test_utils::create_transaction_native_token_transfer( acc1, 0, acc2, 10, sign_key2, ); - let result = sequencer.transaction_pre_check(tx); + // Signature is valid, stateless check pass + let tx = sequencer.transaction_pre_check(tx).unwrap(); - assert_eq!( - result.err().unwrap(), - TransactionMalformationErrorKind::IncorrectSender - ); + // Signature is not from sender. Execution fails + let result = sequencer.execute_check_transaction_on_state(tx); + + assert!(matches!( + result, + Err(nssa::error::NssaError::ProgramExecutionFailed(_)) + )); } #[test] @@ -595,7 +375,7 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + let tx = common::test_utils::create_transaction_native_token_transfer( acc1, 0, acc2, 10000000, sign_key1, ); @@ -604,10 +384,10 @@ mod tests { //Passed pre-check assert!(result.is_ok()); - let result = sequencer.execute_check_transaction_on_state(&result.unwrap().into()); + let result = sequencer.execute_check_transaction_on_state(result.unwrap()); let is_failed_at_balance_mismatch = matches!( result.err().unwrap(), - TransactionMalformationErrorKind::BalanceMismatch { tx: _ } + nssa::error::NssaError::ProgramExecutionFailed(_) ); assert!(is_failed_at_balance_mismatch); @@ -631,16 +411,22 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + let tx = common::test_utils::create_transaction_native_token_transfer( acc1, 0, acc2, 100, sign_key1, ); - sequencer - .execute_check_transaction_on_state(&tx.into_authenticated().unwrap().into()) - .unwrap(); + sequencer.execute_check_transaction_on_state(tx).unwrap(); - let bal_from = sequencer.store.acc_store.get_account_balance(&acc1); - let bal_to = sequencer.store.acc_store.get_account_balance(&acc2); + let bal_from = sequencer + .store + .state + .get_account_by_address(&nssa::Address::new(acc1)) + .balance; + let bal_to = sequencer + .store + .state + .get_account_by_address(&nssa::Address::new(acc2)) + .balance; assert_eq!(bal_from, 9900); assert_eq!(bal_to, 20100); @@ -656,23 +442,16 @@ mod tests { common_setup(&mut sequencer); - let tx = common::test_utils::create_dummy_private_transaction_random_signer( - vec![[92; 32]], - vec![[72; 32]], - vec![[82; 32]], - ); + let tx = common::test_utils::produce_dummy_empty_transaction(); // Fill the mempool - let dummy_tx = MempoolTransaction { - auth_tx: tx.clone().into_authenticated().unwrap(), - }; - sequencer.mempool.push_item(dummy_tx); + sequencer.mempool.push_item(tx.clone()); let result = sequencer.push_tx_into_mempool_pre_check(tx); assert!(matches!( result, - Err(TransactionMalformationErrorKind::MempoolFullForRound { .. }) + Err(TransactionMalformationErrorKind::MempoolFullForRound) )); } @@ -683,11 +462,7 @@ mod tests { common_setup(&mut sequencer); - let tx = common::test_utils::create_dummy_private_transaction_random_signer( - vec![[93; 32]], - vec![[73; 32]], - vec![[83; 32]], - ); + let tx = common::test_utils::produce_dummy_empty_transaction(); let result = sequencer.push_tx_into_mempool_pre_check(tx); assert!(result.is_ok()); @@ -700,15 +475,8 @@ mod tests { let mut sequencer = SequencerCore::start_from_config(config); let genesis_height = sequencer.chain_height; - let tx = common::test_utils::create_dummy_private_transaction_random_signer( - vec![[94; 32]], - vec![[7; 32]], - vec![[8; 32]], - ); - let tx_mempool = MempoolTransaction { - auth_tx: tx.into_authenticated().unwrap(), - }; - sequencer.mempool.push_item(tx_mempool); + let tx = common::test_utils::produce_dummy_empty_transaction(); + sequencer.mempool.push_item(tx); let block_id = sequencer.produce_new_block_with_mempool_transactions(); assert!(block_id.is_ok()); @@ -733,20 +501,15 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + let tx = common::test_utils::create_transaction_native_token_transfer( acc1, 0, acc2, 100, sign_key1, ); - let tx_mempool_original = MempoolTransaction { - auth_tx: tx.clone().into_authenticated().unwrap(), - }; - let tx_mempool_replay = MempoolTransaction { - auth_tx: tx.clone().into_authenticated().unwrap(), - }; - + let tx_original = tx.clone(); + let tx_replay = tx.clone(); // Pushing two copies of the same tx to the mempool - sequencer.mempool.push_item(tx_mempool_original); - sequencer.mempool.push_item(tx_mempool_replay); + sequencer.mempool.push_item(tx_original); + sequencer.mempool.push_item(tx_replay); // Create block let current_height = sequencer @@ -780,15 +543,12 @@ mod tests { let sign_key1 = create_signing_key_for_account1(); - let tx = common::test_utils::create_dummy_transaction_native_token_transfer( + let tx = common::test_utils::create_transaction_native_token_transfer( acc1, 0, acc2, 100, sign_key1, ); // The transaction should be included the first time - let tx_mempool_original = MempoolTransaction { - auth_tx: tx.clone().into_authenticated().unwrap(), - }; - sequencer.mempool.push_item(tx_mempool_original); + sequencer.mempool.push_item(tx.clone()); let current_height = sequencer .produce_new_block_with_mempool_transactions() .unwrap(); @@ -800,10 +560,7 @@ mod tests { assert_eq!(block.transactions, vec![tx.clone()]); // Add same transaction should fail - let tx_mempool_replay = MempoolTransaction { - auth_tx: tx.into_authenticated().unwrap(), - }; - sequencer.mempool.push_item(tx_mempool_replay); + sequencer.mempool.push_item(tx); let current_height = sequencer .produce_new_block_with_mempool_transactions() .unwrap(); diff --git a/sequencer_core/src/mempool_transaction.rs b/sequencer_core/src/mempool_transaction.rs deleted file mode 100644 index 551aaf3..0000000 --- a/sequencer_core/src/mempool_transaction.rs +++ /dev/null @@ -1,20 +0,0 @@ -use common::{merkle_tree_public::TreeHashType, transaction::AuthenticatedTransaction}; -use mempool::mempoolitem::MemPoolItem; - -pub struct MempoolTransaction { - pub auth_tx: AuthenticatedTransaction, -} - -impl From for MempoolTransaction { - fn from(auth_tx: AuthenticatedTransaction) -> Self { - Self { auth_tx } - } -} - -impl MemPoolItem for MempoolTransaction { - type Identifier = TreeHashType; - - fn identifier(&self) -> Self::Identifier { - *self.auth_tx.hash() - } -} diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs deleted file mode 100644 index 4f02220..0000000 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ /dev/null @@ -1,314 +0,0 @@ -use accounts::account_core::address::AccountAddress; -use anyhow::Result; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub(crate) struct AccountPublicData { - pub balance: u64, - pub address: AccountAddress, - nonce: u64, -} - -impl AccountPublicData { - pub fn new(address: AccountAddress) -> Self { - Self { - balance: 0, - nonce: 0, - address, - } - } - - fn new_with_balance(address: AccountAddress, balance: u64) -> Self { - Self { - balance, - address, - nonce: 0, - } - } -} - -#[derive(Debug, Clone)] -pub struct SequencerAccountsStore { - accounts: HashMap, -} - -impl SequencerAccountsStore { - pub fn new(initial_accounts: &[(AccountAddress, u64)]) -> Self { - let mut accounts = HashMap::new(); - - for (account_addr, balance) in initial_accounts { - accounts.insert( - *account_addr, - AccountPublicData::new_with_balance(*account_addr, *balance), - ); - } - - Self { accounts } - } - - ///Register new account in accounts store - /// - ///Starts with zero public balance - pub fn register_account(&mut self, account_addr: AccountAddress) { - self.accounts - .insert(account_addr, AccountPublicData::new(account_addr)); - } - - ///Check, if `account_addr` present in account store - pub fn contains_account(&self, account_addr: &AccountAddress) -> bool { - self.accounts.contains_key(account_addr) - } - - ///Check `account_addr` balance, - /// - ///returns 0, if account address not found - pub fn get_account_balance(&self, account_addr: &AccountAddress) -> u64 { - self.accounts - .get(account_addr) - .map(|acc| acc.balance) - .unwrap_or(0) - } - - pub fn get_account_nonce(&self, account_addr: &AccountAddress) -> u64 { - self.accounts - .get(account_addr) - .map(|acc| acc.nonce) - .unwrap_or(0) - } - - ///Update `account_addr` balance, - /// - /// returns 0, if account address not found, otherwise returns previous balance - /// - /// Also, if account was not previously found, sets it with zero balance - pub fn set_account_balance(&mut self, account_addr: &AccountAddress, new_balance: u64) -> u64 { - let acc_data = self.accounts.get_mut(account_addr); - - if let Some(acc_data) = acc_data { - let old_balance = acc_data.balance; - - acc_data.balance = new_balance; - - old_balance - } else { - self.register_account(*account_addr); - - let acc = self.accounts.get_mut(account_addr).unwrap(); - - acc.balance = new_balance; - - 0 - } - } - - ///Update `account_addr` nonce, - /// - /// Returns previous nonce - pub fn increase_nonce(&mut self, account_addr: &AccountAddress) -> u64 { - if let Some(acc_data) = self.accounts.get_mut(account_addr) { - let old_nonce = acc_data.nonce; - acc_data.nonce += 1; - old_nonce - } else { - self.register_account(*account_addr); - self.increase_nonce(account_addr) - } - } - - ///Remove account from storage - /// - /// Fails, if `balance` is != 0 - /// - /// Returns `Option` which is `None` if `account_addr` vere not present in store - pub fn unregister_account( - &mut self, - account_addr: AccountAddress, - ) -> Result> { - if self.get_account_balance(&account_addr) == 0 { - Ok(self.accounts.remove(&account_addr).map(|data| data.address)) - } else { - anyhow::bail!("Chain consistency violation: It is forbidden to remove account with nonzero balance"); - } - } - - ///Number of accounts present in store - pub fn len(&self) -> usize { - self.accounts.len() - } - - ///Is accounts store empty - pub fn is_empty(&self) -> bool { - self.accounts.is_empty() - } -} - -impl Default for SequencerAccountsStore { - fn default() -> Self { - Self::new(&[]) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_zero_balance_account_data_creation() { - let new_acc = AccountPublicData::new([1; 32]); - - assert_eq!(new_acc.balance, 0); - assert_eq!(new_acc.address, [1; 32]); - } - - #[test] - fn test_zero_nonce_account_data_creation() { - let new_acc = AccountPublicData::new([1; 32]); - - assert_eq!(new_acc.nonce, 0); - } - - #[test] - fn test_non_zero_balance_account_data_creation() { - let new_acc = AccountPublicData::new_with_balance([1; 32], 10); - - assert_eq!(new_acc.balance, 10); - assert_eq!(new_acc.address, [1; 32]); - } - - #[test] - fn test_zero_nonce_account_data_creation_with_balance() { - let new_acc = AccountPublicData::new_with_balance([1; 32], 10); - - assert_eq!(new_acc.nonce, 0); - } - - #[test] - fn default_account_sequencer_store() { - let seq_acc_store = SequencerAccountsStore::default(); - - assert!(seq_acc_store.accounts.is_empty()); - } - - #[test] - fn account_sequencer_store_register_acc() { - let mut seq_acc_store = SequencerAccountsStore::default(); - - seq_acc_store.register_account([1; 32]); - - assert!(seq_acc_store.contains_account(&[1; 32])); - - let acc_balance = seq_acc_store.get_account_balance(&[1; 32]); - - assert_eq!(acc_balance, 0); - } - - #[test] - fn account_sequencer_store_unregister_acc_not_present() { - let mut seq_acc_store = SequencerAccountsStore::default(); - - seq_acc_store.register_account([1; 32]); - - let rem_res = seq_acc_store.unregister_account([2; 32]).unwrap(); - - assert!(rem_res.is_none()); - } - - #[test] - fn account_sequencer_store_unregister_acc_not_zero_balance() { - let mut seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); - - let rem_res = seq_acc_store.unregister_account([1; 32]); - - assert!(rem_res.is_err()); - } - - #[test] - fn account_sequencer_store_unregister_acc() { - let mut seq_acc_store = SequencerAccountsStore::default(); - - seq_acc_store.register_account([1; 32]); - - assert!(seq_acc_store.contains_account(&[1; 32])); - - seq_acc_store.unregister_account([1; 32]).unwrap().unwrap(); - - assert!(!seq_acc_store.contains_account(&[1; 32])); - } - - #[test] - fn account_sequencer_store_with_preset_accounts_1() { - let seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); - - assert!(seq_acc_store.contains_account(&[1; 32])); - assert!(seq_acc_store.contains_account(&[2; 32])); - - let acc_balance = seq_acc_store.get_account_balance(&[1; 32]); - - assert_eq!(acc_balance, 12); - - let acc_balance = seq_acc_store.get_account_balance(&[2; 32]); - - assert_eq!(acc_balance, 100); - } - - #[test] - fn account_sequencer_store_with_preset_accounts_2() { - let seq_acc_store = - SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); - - assert!(seq_acc_store.contains_account(&[6; 32])); - assert!(seq_acc_store.contains_account(&[7; 32])); - assert!(seq_acc_store.contains_account(&[8; 32])); - - let acc_balance = seq_acc_store.get_account_balance(&[6; 32]); - - assert_eq!(acc_balance, 120); - - let acc_balance = seq_acc_store.get_account_balance(&[7; 32]); - - assert_eq!(acc_balance, 15); - - let acc_balance = seq_acc_store.get_account_balance(&[8; 32]); - - assert_eq!(acc_balance, 10); - } - - #[test] - fn account_sequencer_store_fetch_unknown_account() { - let seq_acc_store = - SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); - - let acc_balance = seq_acc_store.get_account_balance(&[9; 32]); - - assert_eq!(acc_balance, 0); - } - - #[test] - fn account_sequencer_store_is_empty_test() { - let seq_acc_store = SequencerAccountsStore::default(); - - assert!(seq_acc_store.is_empty()); - } - - #[test] - fn account_sequencer_store_set_balance_to_unknown_account() { - let mut seq_acc_store = SequencerAccountsStore::default(); - - let ret = seq_acc_store.set_account_balance(&[1; 32], 100); - - assert_eq!(ret, 0); - assert!(seq_acc_store.contains_account(&[1; 32])); - assert_eq!(seq_acc_store.get_account_balance(&[1; 32]), 100); - } - - #[test] - fn test_increase_nonce() { - let mut account_store = SequencerAccountsStore::default(); - let address = [1; 32]; - let first_nonce = account_store.increase_nonce(&address); - assert_eq!(first_nonce, 0); - let second_nonce = account_store.increase_nonce(&address); - assert_eq!(second_nonce, 1); - } -} diff --git a/sequencer_core/src/sequencer_store/block_store.rs b/sequencer_core/src/sequencer_store/block_store.rs index 6467539..3bd68cb 100644 --- a/sequencer_core/src/sequencer_store/block_store.rs +++ b/sequencer_core/src/sequencer_store/block_store.rs @@ -1,7 +1,7 @@ use std::{collections::HashMap, path::Path}; use anyhow::Result; -use common::{block::Block, merkle_tree_public::TreeHashType, transaction::Transaction}; +use common::{block::Block, merkle_tree_public::TreeHashType}; use storage::RocksDBIO; pub struct SequecerBlockStore { @@ -51,12 +51,12 @@ impl SequecerBlockStore { } /// Returns the transaction corresponding to the given hash, if it exists in the blockchain. - pub fn get_transaction_by_hash(&self, hash: TreeHashType) -> Option { + pub fn get_transaction_by_hash(&self, hash: TreeHashType) -> Option { let block_id = self.tx_hash_to_block_map.get(&hash); let block = block_id.map(|&id| self.get_block_at_id(id)); if let Some(Ok(block)) = block { for transaction in block.transactions.into_iter() { - if transaction.body().hash() == hash { + if transaction.hash() == hash { return Some(transaction); } } @@ -69,13 +69,14 @@ fn block_to_transactions_map(block: &Block) -> HashMap { block .transactions .iter() - .map(|transaction| (transaction.body().hash(), block.block_id)) + .map(|transaction| (transaction.hash(), block.block_id)) .collect() } #[cfg(test)] mod tests { use super::*; + use tempfile::tempdir; #[test] @@ -88,22 +89,21 @@ mod tests { prev_block_hash: [0; 32], hash: [1; 32], transactions: vec![], - data: vec![], }; // Start an empty node store let mut node_store = SequecerBlockStore::open_db_with_genesis(path, Some(genesis_block)).unwrap(); let tx = common::test_utils::produce_dummy_empty_transaction(); - let block = common::test_utils::produce_dummy_block(1, None, vec![tx.clone()], vec![]); + let block = common::test_utils::produce_dummy_block(1, None, vec![tx.clone()]); // Try retrieve a tx that's not in the chain yet. - let retrieved_tx = node_store.get_transaction_by_hash(tx.body().hash()); + let retrieved_tx = node_store.get_transaction_by_hash(tx.hash()); assert_eq!(None, retrieved_tx); // Add the block with the transaction node_store.put_block_at_id(block).unwrap(); // Try again - let retrieved_tx = node_store.get_transaction_by_hash(tx.body().hash()); + let retrieved_tx = node_store.get_transaction_by_hash(tx.hash()); assert_eq!(Some(tx), retrieved_tx); } } diff --git a/sequencer_core/src/sequencer_store/mod.rs b/sequencer_core/src/sequencer_store/mod.rs index 3a1ff36..3d9708d 100644 --- a/sequencer_core/src/sequencer_store/mod.rs +++ b/sequencer_core/src/sequencer_store/mod.rs @@ -1,25 +1,17 @@ -use std::{collections::HashSet, path::Path}; +use std::path::Path; -use accounts_store::SequencerAccountsStore; use block_store::SequecerBlockStore; -use common::{ - block::HashableBlockData, - merkle_tree_public::merkle_tree::{PublicTransactionMerkleTree, UTXOCommitmentsMerkleTree}, - nullifier::UTXONullifier, -}; +use common::block::HashableBlockData; +use nssa::{self, Address}; use rand::{rngs::OsRng, RngCore}; use crate::config::AccountInitialData; -pub mod accounts_store; pub mod block_store; pub struct SequecerChainStore { - pub acc_store: SequencerAccountsStore, + pub state: nssa::V01State, pub block_store: SequecerBlockStore, - pub nullifier_store: HashSet, - pub utxo_commitments_store: UTXOCommitmentsMerkleTree, - pub pub_tx_store: PublicTransactionMerkleTree, } impl SequecerChainStore { @@ -29,7 +21,7 @@ impl SequecerChainStore { is_genesis_random: bool, initial_accounts: &[AccountInitialData], ) -> Self { - let init_accs: Vec<_> = initial_accounts + let init_accs: Vec<(Address, u128)> = initial_accounts .iter() .map(|acc_data| { ( @@ -42,10 +34,7 @@ impl SequecerChainStore { }) .collect(); - let acc_store = SequencerAccountsStore::new(&init_accs); - let nullifier_store = HashSet::new(); - let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); - let pub_tx_store = PublicTransactionMerkleTree::new(vec![]); + let state = nssa::V01State::new_with_genesis_accounts(&init_accs); let mut data = [0; 32]; let mut prev_block_hash = [0; 32]; @@ -59,7 +48,6 @@ impl SequecerChainStore { block_id: genesis_id, prev_block_id: genesis_id.saturating_sub(1), transactions: vec![], - data: data.to_vec(), prev_block_hash, }; @@ -73,12 +61,6 @@ impl SequecerChainStore { ) .unwrap(); - Self { - acc_store, - block_store, - nullifier_store, - utxo_commitments_store, - pub_tx_store, - } + Self { state, block_store } } } diff --git a/sequencer_rpc/Cargo.toml b/sequencer_rpc/Cargo.toml index 3e9662a..c6ce004 100644 --- a/sequencer_rpc/Cargo.toml +++ b/sequencer_rpc/Cargo.toml @@ -14,6 +14,7 @@ actix-cors.workspace = true futures.workspace = true hex.workspace = true tempfile.workspace = true +base64.workspace = true actix-web.workspace = true tokio.workspace = true @@ -21,8 +22,8 @@ tokio.workspace = true [dependencies.mempool] path = "../mempool" -[dependencies.accounts] -path = "../accounts" +[dependencies.key_protocol] +path = "../key_protocol" [dependencies.sequencer_core] path = "../sequencer_core" @@ -32,3 +33,6 @@ path = "../storage" [dependencies.common] path = "../common" + +[dependencies.nssa] +path = "../nssa" diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index eadfe55..2d5a29a 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -1,8 +1,11 @@ use actix_web::Error as HttpError; +use base64::{engine::general_purpose, Engine}; +use nssa; use sequencer_core::config::AccountInitialData; use serde_json::Value; use common::{ + block::HashableBlockData, merkle_tree_public::TreeHashType, rpc_primitives::{ errors::RpcError, @@ -17,14 +20,13 @@ use common::{ use common::rpc_primitives::requests::{ GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse, - GetLastBlockRequest, GetLastBlockResponse, HelloRequest, HelloResponse, RegisterAccountRequest, - RegisterAccountResponse, SendTxRequest, SendTxResponse, + GetLastBlockRequest, GetLastBlockResponse, HelloRequest, HelloResponse, SendTxRequest, + SendTxResponse, }; use super::{respond, types::err_rpc::RpcErr, JsonHandler}; pub const HELLO: &str = "hello"; -pub const REGISTER_ACCOUNT: &str = "register_account"; pub const SEND_TX: &str = "send_tx"; pub const GET_BLOCK: &str = "get_block"; pub const GET_GENESIS: &str = "get_genesis"; @@ -66,29 +68,15 @@ impl JsonHandler { respond(helperstruct) } - async fn process_register_account_request(&self, request: Request) -> Result { - let acc_req = RegisterAccountRequest::parse(Some(request.params))?; - - { - let mut acc_store = self.sequencer_state.lock().await; - - acc_store.register_account(acc_req.address); - } - - let helperstruct = RegisterAccountResponse { - status: SUCCESS.to_string(), - }; - - respond(helperstruct) - } - async fn process_send_tx(&self, request: Request) -> Result { let send_tx_req = SendTxRequest::parse(Some(request.params))?; + let tx = nssa::PublicTransaction::from_bytes(&send_tx_req.transaction) + .map_err(|e| RpcError::serialization_error(&e.to_string()))?; { let mut state = self.sequencer_state.lock().await; - state.push_tx_into_mempool_pre_check(send_tx_req.transaction)?; + state.push_tx_into_mempool_pre_check(tx)?; } let helperstruct = SendTxResponse { @@ -110,7 +98,9 @@ impl JsonHandler { .get_block_at_id(get_block_req.block_id)? }; - let helperstruct = GetBlockDataResponse { block }; + let helperstruct = GetBlockDataResponse { + block: HashableBlockData::from(block).to_bytes(), + }; respond(helperstruct) } @@ -164,13 +154,16 @@ impl JsonHandler { let get_account_req = GetAccountBalanceRequest::parse(Some(request.params))?; let address_bytes = hex::decode(get_account_req.address) .map_err(|_| RpcError::invalid_params("invalid hex".to_string()))?; - let address = address_bytes - .try_into() - .map_err(|_| RpcError::invalid_params("invalid length".to_string()))?; + let address = nssa::Address::new( + address_bytes + .try_into() + .map_err(|_| RpcError::invalid_params("invalid length".to_string()))?, + ); let balance = { let state = self.sequencer_state.lock().await; - state.store.acc_store.get_account_balance(&address) + let account = state.store.state.get_account_by_address(&address); + account.balance }; let helperstruct = GetAccountBalanceResponse { balance }; @@ -190,16 +183,22 @@ impl JsonHandler { let transaction = { let state = self.sequencer_state.lock().await; - state.store.block_store.get_transaction_by_hash(hash) + state + .store + .block_store + .get_transaction_by_hash(hash) + .map(|tx| tx.to_bytes()) + }; + let base64_encoded = transaction.map(|tx| general_purpose::STANDARD.encode(tx)); + let helperstruct = GetTransactionByHashResponse { + transaction: base64_encoded, }; - let helperstruct = GetTransactionByHashResponse { transaction }; respond(helperstruct) } pub async fn process_request_internal(&self, request: Request) -> Result { match request.method.as_ref() { HELLO => self.process_temp_hello(request).await, - REGISTER_ACCOUNT => self.process_register_account_request(request).await, SEND_TX => self.process_send_tx(request).await, GET_BLOCK => self.process_get_block_data(request).await, GET_GENESIS => self.process_get_genesis(request).await, @@ -217,10 +216,9 @@ mod tests { use std::sync::Arc; use crate::{rpc_handler, JsonHandler}; - use common::{ - rpc_primitives::RpcPollingConfig, - transaction::{SignaturePrivateKey, Transaction, TransactionBody}, - }; + use base64::{engine::general_purpose, Engine}; + use common::rpc_primitives::RpcPollingConfig; + use sequencer_core::{ config::{AccountInitialData, SequencerConfig}, SequencerCore, @@ -233,13 +231,13 @@ mod tests { let tempdir = tempdir().unwrap(); let home = tempdir.path().to_path_buf(); let acc1_addr = vec![ - 13, 150, 223, 204, 65, 64, 25, 56, 12, 157, 222, 12, 211, 220, 229, 170, 201, 15, 181, - 68, 59, 248, 113, 16, 135, 65, 174, 175, 222, 85, 42, 215, + 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, + 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143, ]; let acc2_addr = vec![ - 151, 72, 112, 233, 190, 141, 10, 192, 138, 168, 59, 63, 199, 167, 166, 134, 41, 29, - 135, 50, 80, 138, 186, 152, 179, 96, 128, 243, 156, 44, 243, 100, + 77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217, 234, + 216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102, ]; let initial_acc1 = AccountInitialData { @@ -266,31 +264,32 @@ mod tests { } } - fn json_handler_for_tests() -> (JsonHandler, Vec) { + fn components_for_tests() -> ( + JsonHandler, + Vec, + nssa::PublicTransaction, + ) { let config = sequencer_config_for_tests(); - let mut sequencer_core = SequencerCore::start_from_config(config); - let initial_accounts = sequencer_core.sequencer_config.initial_accounts.clone(); - let tx_body = TransactionBody { - tx_kind: common::transaction::TxKind::Shielded, - execution_input: Default::default(), - execution_output: Default::default(), - utxo_commitments_spent_hashes: Default::default(), - utxo_commitments_created_hashes: Default::default(), - nullifier_created_hashes: Default::default(), - execution_proof_private: Default::default(), - encoded_data: Default::default(), - ephemeral_pub_key: Default::default(), - commitment: Default::default(), - tweak: Default::default(), - secret_r: Default::default(), - sc_addr: Default::default(), - }; - let tx = Transaction::new(tx_body, SignaturePrivateKey::from_slice(&[1; 32]).unwrap()); + let signing_key = nssa::PrivateKey::try_new([1; 32]).unwrap(); + let balance_to_move = 10; + let tx = common::test_utils::create_transaction_native_token_transfer( + [ + 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, + 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143, + ], + 0, + [2; 32], + balance_to_move, + signing_key, + ); + + sequencer_core + .push_tx_into_mempool_pre_check(tx.clone()) + .unwrap(); - sequencer_core.push_tx_into_mempool_pre_check(tx).unwrap(); sequencer_core .produce_new_block_with_mempool_transactions() .unwrap(); @@ -303,6 +302,7 @@ mod tests { sequencer_state: sequencer_core, }, initial_accounts, + tx, ) } @@ -329,7 +329,7 @@ mod tests { #[actix_web::test] async fn test_get_account_balance_for_non_existent_account() { - let (json_handler, _) = json_handler_for_tests(); + let (json_handler, _, _) = components_for_tests(); let request = serde_json::json!({ "jsonrpc": "2.0", "method": "get_account_balance", @@ -351,7 +351,7 @@ mod tests { #[actix_web::test] async fn test_get_account_balance_for_invalid_hex() { - let (json_handler, _) = json_handler_for_tests(); + let (json_handler, _, _) = components_for_tests(); let request = serde_json::json!({ "jsonrpc": "2.0", "method": "get_account_balance", @@ -374,7 +374,7 @@ mod tests { #[actix_web::test] async fn test_get_account_balance_for_invalid_length() { - let (json_handler, _) = json_handler_for_tests(); + let (json_handler, _, _) = components_for_tests(); let request = serde_json::json!({ "jsonrpc": "2.0", "method": "get_account_balance", @@ -397,7 +397,7 @@ mod tests { #[actix_web::test] async fn test_get_account_balance_for_existing_account() { - let (json_handler, initial_accounts) = json_handler_for_tests(); + let (json_handler, initial_accounts, _) = components_for_tests(); let acc1_addr = initial_accounts[0].addr.clone(); @@ -411,7 +411,7 @@ mod tests { "id": 1, "jsonrpc": "2.0", "result": { - "balance": 10000 + "balance": 10000 - 10 } }); @@ -422,7 +422,7 @@ mod tests { #[actix_web::test] async fn test_get_transaction_by_hash_for_non_existent_hash() { - let (json_handler, _) = json_handler_for_tests(); + let (json_handler, _, _) = components_for_tests(); let request = serde_json::json!({ "jsonrpc": "2.0", "method": "get_transaction_by_hash", @@ -444,7 +444,7 @@ mod tests { #[actix_web::test] async fn test_get_transaction_by_hash_for_invalid_hex() { - let (json_handler, _) = json_handler_for_tests(); + let (json_handler, _, _) = components_for_tests(); let request = serde_json::json!({ "jsonrpc": "2.0", "method": "get_transaction_by_hash", @@ -468,7 +468,7 @@ mod tests { #[actix_web::test] async fn test_get_transaction_by_hash_for_invalid_length() { - let (json_handler, _) = json_handler_for_tests(); + let (json_handler, _, _) = components_for_tests(); let request = serde_json::json!({ "jsonrpc": "2.0", "method": "get_transaction_by_hash", @@ -492,11 +492,14 @@ mod tests { #[actix_web::test] async fn test_get_transaction_by_hash_for_existing_transaction() { - let (json_handler, _) = json_handler_for_tests(); + let (json_handler, _, tx) = components_for_tests(); + let tx_hash_hex = hex::encode(tx.hash()); + let expected_base64_encoded = general_purpose::STANDARD.encode(tx.to_bytes()); + let request = serde_json::json!({ "jsonrpc": "2.0", "method": "get_transaction_by_hash", - "params": { "hash": "2c69b9639bcf8d58509204e18f1d5962029bf26840915f2bf2bb434501ad3c38"}, + "params": { "hash": tx_hash_hex}, "id": 1 }); @@ -504,28 +507,9 @@ mod tests { "id": 1, "jsonrpc": "2.0", "result": { - "transaction": { - "body": { - "commitment": [], - "encoded_data": [], - "ephemeral_pub_key": [], - "execution_input": [], - "execution_output": [], - "execution_proof_private": "", - "nullifier_created_hashes": [], - "sc_addr": "", - "secret_r": vec![0; 32], - "tweak": "0".repeat(64), - "tx_kind": "Shielded", - "utxo_commitments_created_hashes": [], - "utxo_commitments_spent_hashes": [], - }, - "public_key": "3056301006072A8648CE3D020106052B8104000A034200041B84C5567B126440995D3ED5AABA0565D71E1834604819FF9C17F5E9D5DD078F70BEAF8F588B541507FED6A642C5AB42DFDF8120A7F639DE5122D47A69A8E8D1", - "signature": "D75783642EA6E7D5E13AE8CCD3C2D3F82728C0A778A80C9F2976C739CD9F7F3F240B0532954D87761DE299A6CB9E6606295786BA5D0F5CACAB3F3626724528B1" - } + "transaction": expected_base64_encoded, } }); - let response = call_rpc_handler_with_json(json_handler, request).await; assert_eq!(response, expected_response); diff --git a/storage/src/lib.rs b/storage/src/lib.rs index ac54406..0dd12b7 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -1,6 +1,6 @@ use std::{path::Path, sync::Arc}; -use common::block::Block; +use common::block::{Block, HashableBlockData}; use error::DbError; use rocksdb::{ BoundColumnFamily, ColumnFamilyDescriptor, DBWithThreadMode, MultiThreaded, Options, @@ -242,12 +242,7 @@ impl RocksDBIO { .put_cf( &cf_block, block.block_id.to_be_bytes(), - serde_json::to_vec(&block).map_err(|serr| { - DbError::serde_cast_message( - serr, - Some("Block Serialization failed".to_string()), - ) - })?, + HashableBlockData::from(block).to_bytes(), ) .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; Ok(()) @@ -261,9 +256,7 @@ impl RocksDBIO { .map_err(|rerr| DbError::rocksdb_cast_message(rerr, None))?; if let Some(data) = res { - Ok(serde_json::from_slice::(&data).map_err(|serr| { - DbError::serde_cast_message(serr, Some("Block Deserialization failed".to_string())) - })?) + Ok(HashableBlockData::from_bytes(&data).into()) } else { Err(DbError::db_interaction_error( "Block on this id not found".to_string(), diff --git a/utxo/Cargo.toml b/utxo/Cargo.toml deleted file mode 100644 index 02b9ed8..0000000 --- a/utxo/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "utxo" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true -sha2.workspace = true -hex.workspace = true -rand.workspace = true - -[dependencies.common] -path = "../common" diff --git a/utxo/src/lib.rs b/utxo/src/lib.rs deleted file mode 100644 index 7baf984..0000000 --- a/utxo/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod utxo_core; diff --git a/utxo/src/utxo_core.rs b/utxo/src/utxo_core.rs deleted file mode 100644 index 07a8830..0000000 --- a/utxo/src/utxo_core.rs +++ /dev/null @@ -1,162 +0,0 @@ -use anyhow::Result; -use common::{merkle_tree_public::TreeHashType, AccountId}; -use log::info; -use rand::{rngs::OsRng, RngCore}; -use serde::{Deserialize, Serialize}; -use sha2::{digest::FixedOutput, Digest}; - -///Raw asset data -pub type Asset = Vec; -pub type Randomness = [u8; 32]; - -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] -///Container for raw utxo payload -pub struct UTXO { - pub hash: TreeHashType, - pub owner: AccountId, - pub asset: Asset, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: Randomness, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UTXOPayload { - pub owner: AccountId, - pub asset: Asset, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: Randomness, -} - -impl UTXOPayload { - fn to_bytes(&self) -> Vec { - let mut result = Vec::new(); - result.extend_from_slice(&self.owner); - result.extend_from_slice(&self.asset); - result.extend_from_slice(&self.amount.to_be_bytes()); - result.push(self.privacy_flag as u8); - result.extend_from_slice(&self.randomness); - result - } -} - -impl UTXO { - pub fn new(owner: AccountId, asset: Asset, amount: u128, privacy_flag: bool) -> Self { - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - let payload = UTXOPayload { - owner, - asset, - amount, - privacy_flag, - randomness, - }; - Self::create_utxo_from_payload(payload) - } - pub fn create_utxo_from_payload(payload_with_asset: UTXOPayload) -> Self { - let mut hasher = sha2::Sha256::new(); - hasher.update(payload_with_asset.to_bytes()); - let hash = ::from(hasher.finalize_fixed()); - - Self { - hash, - owner: payload_with_asset.owner, - asset: payload_with_asset.asset, - amount: payload_with_asset.amount, - privacy_flag: payload_with_asset.privacy_flag, - randomness: payload_with_asset.randomness, - } - } - - pub fn interpret_asset<'de, ToInterpret: Deserialize<'de>>(&'de self) -> Result { - Ok(serde_json::from_slice(&self.asset)?) - } - - pub fn into_payload(&self) -> UTXOPayload { - UTXOPayload { - owner: self.owner, - asset: self.asset.clone(), - amount: self.amount, - privacy_flag: self.privacy_flag, - randomness: self.randomness, - } - } - - pub fn log(&self) { - info!("UTXO hash is {:?}", hex::encode(self.hash)); - info!("UTXO owner is {:?}", hex::encode(self.owner)); - info!("UTXO asset is {:?}", hex::encode(self.asset.clone())); - info!("UTXO amount is {:?}", self.amount); - info!("UTXO privacy_flag is {:?}", self.privacy_flag); - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct TestAsset { - id: u32, - name: String, - } - - fn sample_account() -> AccountId { - AccountId::default() - } - - fn sample_payload() -> UTXOPayload { - UTXOPayload { - owner: sample_account(), - asset: serde_json::to_vec(&TestAsset { - id: 1, - name: "Test".to_string(), - }) - .unwrap(), - amount: 10, - privacy_flag: false, - randomness: Randomness::default(), - } - } - - #[test] - fn test_create_utxo_from_payload() { - let payload = sample_payload(); - let utxo = UTXO::create_utxo_from_payload(payload.clone()); - - // Ensure hash is created and the UTXO fields are correctly assigned - assert_eq!(utxo.owner, payload.owner); - assert_eq!(utxo.asset, payload.asset); - } - - #[test] - fn test_interpret_asset() { - let payload = sample_payload(); - let utxo = UTXO::create_utxo_from_payload(payload); - - // Interpret asset as TestAsset - let interpreted: TestAsset = utxo.interpret_asset().unwrap(); - - assert_eq!( - interpreted, - TestAsset { - id: 1, - name: "Test".to_string() - } - ); - } - - #[test] - fn test_interpret_invalid_asset() { - let mut payload = sample_payload(); - payload.asset = vec![0, 1, 2, 3]; // Invalid data for deserialization - let utxo = UTXO::create_utxo_from_payload(payload); - - // This should fail because the asset is not valid JSON for TestAsset - let result: Result = utxo.interpret_asset(); - assert!(result.is_err()); - } -} diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index a3166fc..4a67791 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -18,22 +18,17 @@ reqwest.workspace = true thiserror.workspace = true tokio.workspace = true tempfile.workspace = true -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } +risc0-zkvm = "2.3.1" hex.workspace = true actix-rt.workspace = true clap.workspace = true +nssa-core = { path = "../nssa/core" } -[dependencies.sc_core] -path = "../sc_core" +[dependencies.key_protocol] +path = "../key_protocol" -[dependencies.accounts] -path = "../accounts" - -[dependencies.utxo] -path = "../utxo" - -[dependencies.zkvm] -path = "../zkvm" +[dependencies.nssa] +path = "../nssa" [dependencies.common] path = "../common" diff --git a/wallet/src/chain_storage/accounts_store.rs b/wallet/src/chain_storage/accounts_store.rs deleted file mode 100644 index cd46a6f..0000000 --- a/wallet/src/chain_storage/accounts_store.rs +++ /dev/null @@ -1,111 +0,0 @@ -use accounts::account_core::{address::AccountAddress, Account}; -use std::collections::HashMap; - -pub struct WalletAccountsStore { - pub accounts: HashMap, -} - -impl WalletAccountsStore { - pub fn new() -> Self { - Self { - accounts: HashMap::new(), - } - } - - pub fn register_account(&mut self, account: Account) { - self.accounts.insert(account.address, account); - } - - pub fn unregister_account(&mut self, account_addr: AccountAddress) { - self.accounts.remove(&account_addr); - } -} - -impl Default for WalletAccountsStore { - fn default() -> Self { - Self::new() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use accounts::account_core::Account; - /// Helper function to create a sample account - fn create_sample_account(balance: u64) -> Account { - Account::new_with_balance(balance) - } - - fn pad_to_32(slice: &[u8]) -> [u8; 32] { - let mut padded = [0u8; 32]; - let len = slice.len().min(32); - padded[..len].copy_from_slice(&slice[..len]); - padded - } - - #[test] - fn test_create_empty_store() { - let store = WalletAccountsStore::new(); - assert!(store.accounts.is_empty()); - } - - #[test] - fn test_register_account() { - let mut store = WalletAccountsStore::new(); - - let account = create_sample_account(100); - let account_addr = account.address; - - store.register_account(account); - - assert_eq!(store.accounts.len(), 1); - let stored_account = store.accounts.get(&account_addr).unwrap(); - assert_eq!(stored_account.balance, 100); - } - - #[test] - fn test_unregister_account() { - let mut store = WalletAccountsStore::new(); - - let account = create_sample_account(100); - let account_addr = account.address; - store.register_account(account); - - assert_eq!(store.accounts.len(), 1); - - store.unregister_account(account_addr); - assert!(store.accounts.is_empty()); - } - - #[test] - fn test_unregister_nonexistent_account() { - let mut store = WalletAccountsStore::new(); - - let account_addr: [u8; 32] = pad_to_32("nonexistent".to_string().as_bytes()); - store.unregister_account(account_addr); - - assert!(store.accounts.is_empty()); - } - - #[test] - fn test_register_multiple_accounts() { - let mut store = WalletAccountsStore::new(); - - let account1 = create_sample_account(100); - let account2 = create_sample_account(200); - - let address_1 = account1.address; - let address_2 = account2.address; - - store.register_account(account1); - store.register_account(account2); - - assert_eq!(store.accounts.len(), 2); - - let stored_account1 = store.accounts.get(&address_1).unwrap(); - let stored_account2 = store.accounts.get(&address_2).unwrap(); - - assert_eq!(stored_account1.balance, 100); - assert_eq!(stored_account2.balance, 200); - } -} diff --git a/wallet/src/chain_storage/mod.rs b/wallet/src/chain_storage/mod.rs index f0fa6b1..40c9ddc 100644 --- a/wallet/src/chain_storage/mod.rs +++ b/wallet/src/chain_storage/mod.rs @@ -1,252 +1,72 @@ -use std::collections::{BTreeMap, HashMap}; +use std::collections::HashMap; -use accounts::account_core::{address::AccountAddress, Account}; use anyhow::Result; use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree; -use sc_core::public_context::PublicSCContext; -use serde::{Deserialize, Serialize}; +use key_protocol::key_protocol_core::NSSAUserData; use crate::config::WalletConfig; -pub mod accounts_store; - -#[derive(Deserialize, Serialize)] -pub struct AccMap { - pub acc_map: HashMap, -} - -impl From> for AccMap { - fn from(value: HashMap<[u8; 32], Account>) -> Self { - AccMap { - acc_map: value - .into_iter() - .map(|(key, val)| (hex::encode(key), val)) - .collect(), - } - } -} - -impl From for HashMap<[u8; 32], Account> { - fn from(value: AccMap) -> Self { - value - .acc_map - .into_iter() - .map(|(key, val)| (hex::decode(key).unwrap().try_into().unwrap(), val)) - .collect() - } -} - pub struct WalletChainStore { - pub acc_map: HashMap, + pub user_data: NSSAUserData, pub utxo_commitments_store: UTXOCommitmentsMerkleTree, pub wallet_config: WalletConfig, } impl WalletChainStore { pub fn new(config: WalletConfig) -> Result { - let acc_map = HashMap::new(); + let accounts: HashMap = config + .initial_accounts + .clone() + .into_iter() + .map(|init_acc_data| (init_acc_data.address, init_acc_data.account)) + .collect(); + + let accounts_keys: HashMap = config + .initial_accounts + .clone() + .into_iter() + .map(|init_acc_data| (init_acc_data.address, init_acc_data.pub_sign_key)) + .collect(); + let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); Ok(Self { - acc_map, + user_data: NSSAUserData::new_with_accounts(accounts_keys, accounts), utxo_commitments_store, wallet_config: config, }) } - - pub fn produce_context(&self, caller: AccountAddress) -> PublicSCContext { - let mut account_masks = BTreeMap::new(); - - for (acc_addr, acc) in &self.acc_map { - account_masks.insert(*acc_addr, acc.make_account_public_mask()); - } - - PublicSCContext { - caller_address: caller, - caller_balance: self.acc_map.get(&caller).unwrap().balance, - account_masks, - comitment_store_root: self.utxo_commitments_store.get_root().unwrap_or([0; 32]), - commitments_tree: self.utxo_commitments_store.clone(), - } - } } #[cfg(test)] mod tests { + use crate::config::InitialAccountData; + use super::*; - use accounts::account_core::Account; use std::path::PathBuf; use tempfile::tempdir; - fn create_initial_accounts() -> Vec { + fn create_initial_accounts() -> Vec { let initial_acc1 = serde_json::from_str(r#"{ - "address": [ - 244, - 55, - 238, - 205, - 74, - 115, - 179, - 192, - 65, - 186, - 166, - 169, - 221, - 45, - 6, - 57, - 200, - 65, - 195, - 70, - 118, - 252, - 206, - 100, - 215, - 250, - 72, - 230, - 19, - 71, - 217, - 249 - ], - "balance": 100, - "nonce": 0, - "key_holder": { - "nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718", - "pub_account_signing_key": [ - 244, - 88, - 134, - 61, - 35, - 209, - 229, - 101, - 85, - 35, - 140, - 140, - 192, - 226, - 83, - 83, - 190, - 189, - 110, - 8, - 89, - 127, - 147, - 142, - 157, - 204, - 51, - 109, - 189, - 92, - 144, - 68 - ], - "top_secret_key_holder": { - "secret_spending_key": "7BC46784DB1BC67825D8F029436846712BFDF9B5D79EA3AB11D39A52B9B229D4" - }, - "utxo_secret_key_holder": { - "nullifier_secret_key": "BB54A8D3C9C51B82C431082D1845A74677B0EF829A11B517E1D9885DE3139506", - "viewing_secret_key": "AD923E92F6A5683E30140CEAB2702AFB665330C1EE4EFA70FAF29767B6B52BAF" - }, - "viewing_public_key": "0361220C5D277E7A1709340FD31A52600C1432B9C45B9BCF88A43581D58824A8B6" - }, - "utxos": {} + "address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", + "pub_sign_key": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "account": { + "program_owner": [0,0,0,0,0,0,0,0], + "balance": 100, + "nonce": 0, + "data": [] + } }"#).unwrap(); let initial_acc2 = serde_json::from_str(r#"{ - "address": [ - 72, - 169, - 70, - 237, - 1, - 96, - 35, - 157, - 25, - 15, - 83, - 18, - 52, - 206, - 202, - 63, - 48, - 59, - 173, - 76, - 78, - 7, - 254, - 229, - 28, - 45, - 194, - 79, - 6, - 89, - 58, - 85 - ], - "balance": 200, - "nonce": 0, - "key_holder": { - "nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271", - "pub_account_signing_key": [ - 136, - 105, - 9, - 53, - 180, - 145, - 64, - 5, - 235, - 174, - 62, - 211, - 206, - 116, - 185, - 24, - 214, - 62, - 244, - 64, - 224, - 59, - 120, - 150, - 30, - 249, - 160, - 46, - 189, - 254, - 47, - 244 - ], - "top_secret_key_holder": { - "secret_spending_key": "80A186737C8D38B4288A03F0F589957D9C040D79C19F3E0CC4BA80F8494E5179" - }, - "utxo_secret_key_holder": { - "nullifier_secret_key": "746928E63F0984F6F4818933493CE9C067562D9CB932FDC06D82C86CDF6D7122", - "viewing_secret_key": "89176CF4BC9E673807643FD52110EF99D4894335AFB10D881AC0B5041FE1FCB7" - }, - "viewing_public_key": "026072A8F83FEC3472E30CDD4767683F30B91661D25B1040AD9A5FC2E01D659F99" - }, - "utxos": {} + "address": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766", + "pub_sign_key": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + "account": { + "program_owner": [0,0,0,0,0,0,0,0], + "balance": 100, + "nonce": 0, + "data": [] + } }"#).unwrap(); let initial_accounts = vec![initial_acc1, initial_acc2]; @@ -273,7 +93,7 @@ mod tests { let store = WalletChainStore::new(config.clone()).unwrap(); - assert!(store.acc_map.is_empty()); + assert_eq!(store.user_data.accounts.len(), 2); assert_eq!( store.utxo_commitments_store.get_root().unwrap_or([0; 32]), [0; 32] diff --git a/wallet/src/config.rs b/wallet/src/config.rs index d2c3a78..21bd912 100644 --- a/wallet/src/config.rs +++ b/wallet/src/config.rs @@ -1,8 +1,12 @@ +use serde::{Deserialize, Serialize}; use std::path::PathBuf; -use accounts::account_core::Account; -use serde::{Deserialize, Serialize}; -use zkvm::gas_calculator::GasCalculator; +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct InitialAccountData { + pub address: nssa::Address, + pub account: nssa_core::account::Account, + pub pub_sign_key: nssa::PrivateKey, +} #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GasConfig { @@ -22,20 +26,6 @@ pub struct GasConfig { pub gas_limit_runtime: u64, } -impl From for zkvm::gas_calculator::GasCalculator { - fn from(value: GasConfig) -> Self { - GasCalculator::new( - value.gas_fee_per_byte_deploy, - value.gas_fee_per_input_buffer_runtime, - value.gas_fee_per_byte_runtime, - value.gas_cost_runtime, - value.gas_cost_deploy, - value.gas_limit_deploy, - value.gas_limit_runtime, - ) - } -} - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WalletConfig { ///Home dir of sequencer storage @@ -47,5 +37,5 @@ pub struct WalletConfig { ///Sequencer polling duration for new blocks in seconds pub seq_poll_timeout_secs: u64, ///Initial accounts for wallet - pub initial_accounts: Vec, + pub initial_accounts: Vec, } diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index a66b1e0..51b9d9d 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -1,9 +1,12 @@ use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr}; -use accounts::account_core::Account; -use anyhow::{anyhow, Result}; +use anyhow::Result; +use nssa::Address; -use crate::{config::WalletConfig, HOME_DIR_ENV_VAR}; +use crate::{ + config::{InitialAccountData, WalletConfig}, + HOME_DIR_ENV_VAR, +}; ///Get home dir for wallet. Env var `NSSA_WALLET_HOME_DIR` must be set before execution to succeed. pub fn get_home() -> Result { @@ -20,16 +23,14 @@ pub fn fetch_config() -> Result { } //ToDo: Replace with structures conversion in future -pub fn produce_account_addr_from_hex(hex_str: String) -> Result<[u8; 32]> { - hex::decode(hex_str)? - .try_into() - .map_err(|_| anyhow!("Failed conversion to 32 bytes")) +pub fn produce_account_addr_from_hex(hex_str: String) -> Result
{ + Ok(hex_str.parse()?) } ///Fetch list of accounts stored at `NSSA_WALLET_HOME_DIR/curr_accounts.json` /// /// If file not present, it is considered as empty list of persistent accounts -pub fn fetch_persistent_accounts() -> Result> { +pub fn fetch_persistent_accounts() -> Result> { let home = get_home()?; let accs_path = home.join("curr_accounts.json"); diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 875da65..2c4b711 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -1,24 +1,20 @@ -use std::{fs::File, io::Write, path::PathBuf, sync::Arc}; +use std::sync::Arc; use common::{ - execution_input::PublicNativeTokenSend, sequencer_client::{json::SendTxResponse, SequencerClient}, - transaction::Transaction, ExecutionFailureKind, }; -use accounts::account_core::{address::AccountAddress, Account}; use anyhow::Result; use chain_storage::WalletChainStore; -use common::transaction::TransactionBody; use config::WalletConfig; use log::info; -use sc_core::proofs_circuits::pedersen_commitment_vec; +use nssa::Address; use clap::{Parser, Subcommand}; use crate::helperfunctions::{ - fetch_config, fetch_persistent_accounts, get_home, produce_account_addr_from_hex, + fetch_config, fetch_persistent_accounts, produce_account_addr_from_hex, }; pub const HOME_DIR_ENV_VAR: &str = "NSSA_WALLET_HOME_DIR"; @@ -30,7 +26,6 @@ pub mod helperfunctions; pub struct WalletCore { pub storage: WalletChainStore, - pub wallet_config: WalletConfig, pub sequencer_client: Arc, } @@ -38,106 +33,66 @@ impl WalletCore { pub async fn start_from_config_update_chain(config: WalletConfig) -> Result { let client = Arc::new(SequencerClient::new(config.sequencer_addr.clone())?); - let mut storage = WalletChainStore::new(config.clone())?; - for acc in config.clone().initial_accounts { - storage.acc_map.insert(acc.address, acc); - } + let mut storage = WalletChainStore::new(config)?; - //Persistent accounts take precedence for initial accounts let persistent_accounts = fetch_persistent_accounts()?; for acc in persistent_accounts { - storage.acc_map.insert(acc.address, acc); + storage + .user_data + .update_account_balance(acc.address, acc.account.balance); } Ok(Self { storage, - wallet_config: config.clone(), sequencer_client: client.clone(), }) } - pub async fn create_new_account(&mut self) -> AccountAddress { - let account = Account::new(); - account.log(); - - let addr = account.address; - - self.storage.acc_map.insert(account.address, account); - - addr + pub async fn create_new_account(&mut self) -> Address { + self.storage.user_data.generate_new_account() } pub async fn send_public_native_token_transfer( &self, - from: AccountAddress, - nonce: u64, - to: AccountAddress, - balance_to_move: u64, + from: Address, + nonce: u128, + to: Address, + balance_to_move: u128, ) -> Result { - let public_context = self.storage.produce_context(from); - - let (tweak, secret_r, commitment) = pedersen_commitment_vec( - //Will not panic, as public context is serializable - public_context.produce_u64_list_from_context().unwrap(), - ); - - let sc_addr = hex::encode([0; 32]); - - let tx: TransactionBody = - sc_core::transaction_payloads_tools::create_public_transaction_payload( - serde_json::to_vec(&PublicNativeTokenSend { - from, - nonce, - to, - balance_to_move, - }) - .unwrap(), - commitment, - tweak, - secret_r, - sc_addr, - ); - tx.log(); - - let account = self.storage.acc_map.get(&from); + let account = self.storage.user_data.get_account(&from); if let Some(account) = account { - let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key(); + if account.balance >= balance_to_move { + let addresses = vec![from, to]; + let nonces = vec![nonce]; + let program_id = nssa::program::Program::authenticated_transfer_program().id(); + let message = nssa::public_transaction::Message::try_new( + program_id, + addresses, + nonces, + balance_to_move, + ) + .unwrap(); - let signed_transaction = Transaction::new(tx, key_to_sign_transaction); + let signing_key = self.storage.user_data.get_account_signing_key(&from); - Ok(self.sequencer_client.send_tx(signed_transaction).await?) + if let Some(signing_key) = signing_key { + let witness_set = + nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); + + let tx = nssa::PublicTransaction::new(message, witness_set); + + Ok(self.sequencer_client.send_tx(tx).await?) + } else { + Err(ExecutionFailureKind::KeyNotFoundError) + } + } else { + Err(ExecutionFailureKind::InsufficientFundsError) + } } else { Err(ExecutionFailureKind::AmountMismatchError) } } - - ///Dumps all accounts from acc_map at `path` - /// - ///Currently storing everything in one file - /// - ///ToDo: extend storage - pub fn store_present_accounts_at_path(&self, path: PathBuf) -> Result { - let dump_path = path.join("curr_accounts.json"); - - let curr_accs: Vec = self.storage.acc_map.values().cloned().collect(); - let accs_serialized = serde_json::to_vec_pretty(&curr_accs)?; - - let mut acc_file = File::create(&dump_path).unwrap(); - acc_file.write_all(&accs_serialized).unwrap(); - - Ok(dump_path) - } - - ///Dumps all accounts from acc_map at `NSSA_WALLET_HOME_DIR` - /// - ///Currently storing everything in one file - /// - ///ToDo: extend storage - pub fn store_present_accounts_at_home(&self) -> Result { - let home = get_home()?; - self.store_present_accounts_at_path(home) - } } ///Represents CLI command for a wallet @@ -149,21 +104,15 @@ pub enum Command { ///from - valid 32 byte hex string #[arg(long)] from: String, - ///nonce - u64 integer + ///nonce - u128 integer #[arg(long)] - nonce: u64, + nonce: u128, ///to - valid 32 byte hex string #[arg(long)] to: String, ///amount - amount of balance to move #[arg(long)] - amount: u64, - }, - ///Dump accounts at destination - DumpAccountsOnDisc { - ///Dump path for accounts - #[arg(short, long)] - dump_path: PathBuf, + amount: u128, }, } @@ -198,19 +147,6 @@ pub async fn execute_subcommand(command: Command) -> Result<()> { info!("Results of tx send is {res:#?}"); //ToDo: Insert transaction polling logic here - - let acc_storage_path = wallet_core.store_present_accounts_at_home()?; - - info!("Accounts stored at {acc_storage_path:#?}"); - } - Command::DumpAccountsOnDisc { dump_path } => { - let node_config = fetch_config()?; - - let wallet_core = WalletCore::start_from_config_update_chain(node_config).await?; - - wallet_core.store_present_accounts_at_path(dump_path.clone())?; - - info!("Accounts stored at path {dump_path:#?}"); } } diff --git a/zkvm/Cargo.toml b/zkvm/Cargo.toml deleted file mode 100644 index d87d142..0000000 --- a/zkvm/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "zkvm" -version = "0.1.0" -edition = "2021" - -[dependencies] -anyhow.workspace = true -serde_json.workspace = true -env_logger.workspace = true -log.workspace = true -serde.workspace = true -thiserror.workspace = true -rand.workspace = true - -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.3" } -test-methods = { path = "test_methods" } - -[dependencies.accounts] -path = "../accounts" - -[dependencies.utxo] -path = "../utxo" - -[dependencies.common] -path = "../common" - -[features] -cuda = ["risc0-zkvm/cuda"] -default = [] -prove = ["risc0-zkvm/prove"] diff --git a/zkvm/src/gas_calculator.rs b/zkvm/src/gas_calculator.rs deleted file mode 100644 index ac2c737..0000000 --- a/zkvm/src/gas_calculator.rs +++ /dev/null @@ -1,113 +0,0 @@ -#[derive(Debug, Clone)] -pub struct GasCalculator { - /// Gas spent per deploying one byte of data - gas_fee_per_byte_deploy: u64, - /// Gas spent per reading one byte of data in VM - gas_fee_per_input_buffer_runtime: u64, - /// Gas spent per one byte of contract data in runtime - gas_fee_per_byte_runtime: u64, - /// Cost of one gas of runtime in public balance - gas_cost_runtime: u64, - /// Cost of one gas of deployment in public balance - gas_cost_deploy: u64, - /// Gas limit for deployment - gas_limit_deploy: u64, - /// Gas limit for runtime - gas_limit_runtime: u64, -} - -impl GasCalculator { - pub fn new( - gas_fee_per_byte_deploy: u64, - gas_fee_per_input_buffer_runtime: u64, - gas_fee_per_byte_runtime: u64, - gas_cost_runtime: u64, - gas_cost_deploy: u64, - gas_limit_deploy: u64, - gas_limit_runtime: u64, - ) -> Self { - Self { - gas_fee_per_byte_deploy, - gas_fee_per_input_buffer_runtime, - gas_fee_per_byte_runtime, - gas_cost_deploy, - gas_cost_runtime, - gas_limit_deploy, - gas_limit_runtime, - } - } - - pub fn gas_fee_per_byte_deploy(&self) -> u64 { - self.gas_fee_per_byte_deploy - } - - pub fn gas_fee_per_input_buffer_runtime(&self) -> u64 { - self.gas_fee_per_input_buffer_runtime - } - - pub fn gas_fee_per_byte_runtime(&self) -> u64 { - self.gas_fee_per_byte_runtime - } - - pub fn gas_cost_runtime(&self) -> u64 { - self.gas_cost_runtime - } - - pub fn gas_cost_deploy(&self) -> u64 { - self.gas_cost_deploy - } - - pub fn gas_limit_deploy(&self) -> u64 { - self.gas_limit_deploy - } - - pub fn gas_limit_runtime(&self) -> u64 { - self.gas_limit_runtime - } - - ///Returns Option - /// - /// Some(_) - in case if `gas` < `gas_limit_deploy` - /// - /// None - else - pub fn gas_deploy(&self, elf: &[u8]) -> Option { - let gas = self.gas_fee_per_byte_deploy() * (elf.len() as u64); - - if gas < self.gas_limit_deploy() { - Some(gas) - } else { - None - } - } - - pub fn gas_runtime(&self, elf: &[u8]) -> u64 { - self.gas_fee_per_byte_runtime() * (elf.len() as u64) - } - - pub fn gas_input_buffer(&self, input_length: usize) -> u64 { - self.gas_fee_per_input_buffer_runtime() * (input_length as u64) - } - - ///Returns Option - /// - /// Some(_) - in case if `gas` < `gas_limit_runtime` - /// - /// None - else - pub fn gas_runtime_full(&self, elf: &[u8], input_length: usize) -> Option { - let gas = self.gas_runtime(elf) + self.gas_input_buffer(input_length); - - if gas < self.gas_limit_runtime() { - Some(gas) - } else { - None - } - } - - pub fn deploy_cost(&self, deploy_gas: u64) -> u64 { - deploy_gas * self.gas_cost_deploy() - } - - pub fn runtime_cost(&self, runtime_gas: u64) -> u64 { - runtime_gas * self.gas_cost_runtime() - } -} diff --git a/zkvm/src/lib.rs b/zkvm/src/lib.rs deleted file mode 100644 index 0fbae70..0000000 --- a/zkvm/src/lib.rs +++ /dev/null @@ -1,635 +0,0 @@ -use accounts::account_core::address::AccountAddress; -use common::ExecutionFailureKind; -use rand::{rngs::OsRng, RngCore}; -use risc0_zkvm::{default_executor, default_prover, sha::Digest, ExecutorEnv, Receipt}; -use serde::Serialize; -use utxo::utxo_core::{Randomness, UTXOPayload, UTXO}; - -pub mod gas_calculator; - -pub use test_methods; - -#[allow(clippy::result_large_err)] -pub fn gas_limits_check( - input_buffer: INP, - elf: &[u8], - gas_calculator: &gas_calculator::GasCalculator, - attached_funds: u64, -) -> Result<(), ExecutionFailureKind> { - let mut input_buffer_len: usize = 0; - input_buffer_len += serde_json::to_vec(&input_buffer).unwrap().len(); - - let gas_limit = gas_calculator - .gas_runtime_full(elf, input_buffer_len) - .ok_or(ExecutionFailureKind::InsufficientGasError)?; - - let cost = gas_calculator.runtime_cost(gas_limit); - - if cost > attached_funds { - return Err(ExecutionFailureKind::InsufficientFundsError); - } - - Ok(()) -} - -#[allow(clippy::result_large_err)] -pub fn prove_mint_utxo( - amount_to_mint: u128, - owner: AccountAddress, -) -> Result<(UTXO, Receipt), ExecutionFailureKind> { - let mut builder = ExecutorEnv::builder(); - - builder - .write(&amount_to_mint) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&owner) - .map_err(ExecutionFailureKind::write_error)?; - - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - builder - .write(&randomness) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::MINT_UTXO_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: UTXOPayload = receipt.journal.decode()?; - - Ok((UTXO::create_utxo_from_payload(digest), receipt)) -} - -#[allow(clippy::result_large_err)] -pub fn prove_send_utxo( - spent_utxo: UTXO, - owners_parts: Vec<(u128, AccountAddress)>, -) -> Result<(Vec<(UTXO, AccountAddress)>, Receipt), ExecutionFailureKind> { - let cumulative_spent = owners_parts.iter().fold(0, |acc, item| acc + item.0); - - if cumulative_spent != spent_utxo.amount { - return Err(ExecutionFailureKind::AmountMismatchError); - } - - let mut builder = ExecutorEnv::builder(); - let utxo_payload = spent_utxo.into_payload(); - - builder - .write(&utxo_payload) - .map_err(ExecutionFailureKind::write_error)?; - - let owners_parts_with_randomness = owners_parts - .into_iter() - .map(|(amount, addr)| { - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - (amount, addr, randomness) - }) - .collect::>(); - - builder - .write(&owners_parts_with_randomness) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::SEND_UTXO_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: Vec<(UTXOPayload, AccountAddress)> = receipt.journal.decode()?; - - Ok(( - digest - .into_iter() - .map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr)) - .collect(), - receipt, - )) -} - -#[allow(clippy::result_large_err)] -pub fn prove_send_utxo_multiple_assets_one_receiver( - spent_utxos: Vec, - number_to_send: usize, - receiver: AccountAddress, -) -> Result<(Vec, Vec, Receipt), ExecutionFailureKind> { - if number_to_send > spent_utxos.len() { - return Err(ExecutionFailureKind::AmountMismatchError); - } - - let mut builder = ExecutorEnv::builder(); - let utxo_payload: Vec = spent_utxos - .into_iter() - .map(|spent_utxo| spent_utxo.into_payload()) - .collect(); - - builder - .write(&utxo_payload) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&number_to_send) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&receiver) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::SEND_UTXO_MULTIPLE_ASSETS_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: (Vec, Vec) = receipt.journal.decode()?; - - Ok(( - digest - .0 - .into_iter() - .map(UTXO::create_utxo_from_payload) - .collect(), - digest - .1 - .into_iter() - .map(UTXO::create_utxo_from_payload) - .collect(), - receipt, - )) -} - -#[allow(clippy::result_large_err)] -pub fn prove_send_utxo_shielded( - owner: AccountAddress, - amount: u128, - owners_parts: Vec<(u128, AccountAddress)>, -) -> Result<(Vec<(UTXO, AccountAddress)>, Receipt), ExecutionFailureKind> { - let cumulative_spent = owners_parts.iter().fold(0, |acc, item| acc + item.0); - - if cumulative_spent != amount { - return Err(ExecutionFailureKind::AmountMismatchError); - } - - let temp_utxo_to_spend = UTXO::new(owner, vec![], amount, true); - let utxo_payload = temp_utxo_to_spend.into_payload(); - - let mut builder = ExecutorEnv::builder(); - - builder - .write(&utxo_payload) - .map_err(ExecutionFailureKind::write_error)?; - - let owners_parts_with_randomness = owners_parts - .into_iter() - .map(|(amount, addr)| { - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - (amount, addr, randomness) - }) - .collect::>(); - - builder - .write(&owners_parts_with_randomness) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::SEND_UTXO_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: Vec<(UTXOPayload, AccountAddress)> = receipt.journal.decode()?; - - Ok(( - digest - .into_iter() - .map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr)) - .collect(), - receipt, - )) -} - -#[allow(clippy::result_large_err)] -pub fn prove_send_utxo_deshielded( - spent_utxo: UTXO, - owners_parts: Vec<(u128, AccountAddress)>, -) -> Result<(Vec<(u128, AccountAddress)>, Receipt), ExecutionFailureKind> { - let cumulative_spent = owners_parts.iter().fold(0, |acc, item| acc + item.0); - - if cumulative_spent != spent_utxo.amount { - return Err(ExecutionFailureKind::AmountMismatchError); - } - - let mut builder = ExecutorEnv::builder(); - let utxo_payload = spent_utxo.into_payload(); - - builder - .write(&utxo_payload) - .map_err(ExecutionFailureKind::write_error)?; - - let owners_parts_with_randomness = owners_parts - .into_iter() - .map(|(amount, addr)| { - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - (amount, addr, randomness) - }) - .collect::>(); - - builder - .write(&owners_parts_with_randomness) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::SEND_UTXO_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: Vec<(UTXOPayload, AccountAddress)> = receipt.journal.decode()?; - - Ok(( - digest - .into_iter() - .map(|(payload, addr)| (payload.amount, addr)) - .collect(), - receipt, - )) -} - -#[allow(clippy::result_large_err)] -pub fn prove_mint_utxo_multiple_assets( - amount_to_mint: u128, - number_of_assets: usize, - owner: AccountAddress, -) -> Result<(Vec, Receipt), ExecutionFailureKind> { - let mut builder = ExecutorEnv::builder(); - - builder - .write(&amount_to_mint) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&number_of_assets) - .map_err(ExecutionFailureKind::write_error)?; - builder - .write(&owner) - .map_err(ExecutionFailureKind::write_error)?; - - let env = builder - .build() - .map_err(ExecutionFailureKind::builder_error)?; - - let prover = default_prover(); - - let receipt = prover - .prove(env, test_methods::MINT_UTXO_MULTIPLE_ASSETS_ELF) - .map_err(ExecutionFailureKind::prove_error)? - .receipt; - - let digest: Vec = receipt.journal.decode()?; - - Ok(( - digest - .into_iter() - .map(UTXO::create_utxo_from_payload) - .collect(), - receipt, - )) -} - -pub fn execute_mint_utxo( - amount_to_mint: u128, - owner: AccountAddress, - randomness: [u8; 32], -) -> anyhow::Result { - let mut builder = ExecutorEnv::builder(); - - builder.write(&amount_to_mint)?; - builder.write(&owner)?; - builder.write(&randomness)?; - - let env = builder.build()?; - - let executor = default_executor(); - - let receipt = executor.execute(env, test_methods::MINT_UTXO_ELF)?; - - let digest: UTXOPayload = receipt.journal.decode()?; - - Ok(UTXO::create_utxo_from_payload(digest)) -} - -pub fn execute_send_utxo( - spent_utxo: UTXO, - owners_parts: Vec<(u128, AccountAddress)>, -) -> anyhow::Result<(UTXO, Vec<(UTXO, AccountAddress)>)> { - let mut builder = ExecutorEnv::builder(); - - let utxo_payload = spent_utxo.into_payload(); - - builder.write(&utxo_payload)?; - let owners_parts_with_randomness = owners_parts - .into_iter() - .map(|(amount, addr)| { - let mut randomness = Randomness::default(); - OsRng.fill_bytes(&mut randomness); - (amount, addr, randomness) - }) - .collect::>(); - - builder.write(&owners_parts_with_randomness)?; - - let env = builder.build()?; - - let executor = default_executor(); - - let receipt = executor.execute(env, test_methods::SEND_UTXO_ELF)?; - - let digest: (UTXOPayload, Vec<(UTXOPayload, AccountAddress)>) = receipt.journal.decode()?; - - Ok(( - UTXO::create_utxo_from_payload(digest.0), - digest - .1 - .into_iter() - .map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr)) - .collect(), - )) -} - -pub fn prove( - input_vec: Vec, - elf: &[u8], -) -> anyhow::Result<(u64, Receipt)> { - let mut builder = ExecutorEnv::builder(); - - for input in input_vec { - builder.write(&input)?; - } - - let env = builder.build()?; - - let prover = default_prover(); - - let receipt = prover.prove(env, elf)?.receipt; - - let digest = receipt.journal.decode()?; - Ok((digest, receipt)) -} - -// This only executes the program and does not generate a receipt. -pub fn execute serde::Deserialize<'de>>( - input_vec: Vec, - elf: &[u8], -) -> anyhow::Result { - let mut builder = ExecutorEnv::builder(); - - for input in input_vec { - builder.write(&input)?; - } - - let env = builder.build()?; - - let exec = default_executor(); - let session = exec.execute(env, elf)?; - - // We read the result committed to the journal by the guest code. - let result: T = session.journal.decode()?; - - Ok(result) -} - -pub fn verify(receipt: Receipt, image_id: impl Into) -> anyhow::Result<()> { - Ok(receipt.verify(image_id)?) -} - -#[cfg(test)] -mod tests { - use crate::gas_calculator::GasCalculator; - - use super::*; - use test_methods::BIG_CALCULATION_ELF; - use test_methods::{MULTIPLICATION_ELF, MULTIPLICATION_ID}; - use test_methods::{SUMMATION_ELF, SUMMATION_ID}; - - #[test] - fn prove_simple_sum() { - let message = 1; - let message_2 = 2; - - let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap(); - - verify(receipt, SUMMATION_ID).unwrap(); - assert_eq!(digest, message + message_2); - } - - #[test] - fn prove_bigger_sum() { - let message = 123476; - let message_2 = 2342384; - - let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap(); - - verify(receipt, SUMMATION_ID).unwrap(); - assert_eq!(digest, message + message_2); - } - - #[test] - fn prove_simple_multiplication() { - let message = 1; - let message_2 = 2; - - let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap(); - - verify(receipt, MULTIPLICATION_ID).unwrap(); - assert_eq!(digest, message * message_2); - } - - #[test] - fn prove_bigger_multiplication() { - let message = 3498; - let message_2 = 438563; - - let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap(); - - verify(receipt, MULTIPLICATION_ID).unwrap(); - assert_eq!(digest, message * message_2); - } - - #[test] - fn execute_simple_sum() { - let message: u64 = 1; - let message_2: u64 = 2; - - let result = execute(vec![message, message_2], SUMMATION_ELF).unwrap(); - assert_eq!(result, message + message_2); - } - - #[test] - fn execute_bigger_sum() { - let message: u64 = 123476; - let message_2: u64 = 2342384; - - let result = execute(vec![message, message_2], SUMMATION_ELF).unwrap(); - assert_eq!(result, message + message_2); - } - - #[test] - fn execute_big_calculation() { - let message: u128 = 1; - let message_2: u128 = 2; - - let result = execute(vec![message, message_2], BIG_CALCULATION_ELF).unwrap(); - assert_eq!(result, big_calculation(message, message_2)); - } - - #[test] - fn execute_big_calculation_long() { - let message: u128 = 20; - let message_2: u128 = 10; - - let result = execute(vec![message, message_2], BIG_CALCULATION_ELF).unwrap(); - assert_eq!(result, big_calculation(message, message_2)); - } - - fn big_calculation(lhs: u128, rhs: u128) -> u128 { - let mut res = 1_u128; - for _ in 0..lhs { - res *= rhs; - res += lhs; - } - - res - } - - #[test] - fn test_gas_limits_check_sufficient_funds() { - let message = 1; - let message_2 = 2; - let gas_calc = GasCalculator::new(1, 1, 1, 1, 1, 1000000, 1000000); - - let result = gas_limits_check(vec![message, message_2], SUMMATION_ELF, &gas_calc, 1000000); - assert!(result.is_ok()); - } - - #[test] - fn test_gas_limits_check_insufficient_funds() { - let message = 1; - let message_2 = 2; - let gas_calc = GasCalculator::new(1, 1, 1, 1, 1, 1000000, 1000000); - - let result = gas_limits_check(vec![message, message_2], SUMMATION_ELF, &gas_calc, 1); - assert!(matches!( - result, - Err(ExecutionFailureKind::InsufficientFundsError) - )); - } - - #[test] - fn test_execute_mint_utxo() { - let owner = AccountAddress::default(); - let amount = 123456789; - let mut randomness = [0u8; 32]; - OsRng.fill_bytes(&mut randomness); - - let utxo_exec = execute_mint_utxo(amount, owner, randomness).expect("execution failed"); - assert_eq!(utxo_exec.amount, amount); - assert_eq!(utxo_exec.owner, owner); - } - - #[test] - fn test_prove_mint_utxo() { - let owner = AccountAddress::default(); - let amount = 123456789; - - let (utxo, _) = prove_mint_utxo(amount, owner).expect("proof failed"); - assert_eq!(utxo.amount, amount); - assert_eq!(utxo.owner, owner); - } - - #[test] - fn test_prove_send_utxo() { - let owner = AccountAddress::default(); - let amount = 100; - let (input_utxo, _) = prove_mint_utxo(amount, owner).expect("mint failed"); - - let parts = vec![(40, owner), (60, owner)]; - let (outputs, _receipt) = prove_send_utxo(input_utxo, parts.clone()).expect("send failed"); - - let total: u128 = outputs.iter().map(|(utxo, _)| utxo.amount).sum(); - assert_eq!(total, amount); - assert_eq!(outputs.len(), 2); - } - - #[test] - fn test_prove_send_utxo_deshielded() { - let owner = AccountAddress::default(); - let amount = 100; - let (utxo, _) = prove_mint_utxo(amount, owner).unwrap(); - let parts = vec![(60, owner), (40, owner)]; - - let (outputs, _) = prove_send_utxo_deshielded(utxo, parts.clone()).unwrap(); - - let total: u128 = outputs.iter().map(|(amt, _)| amt).sum(); - assert_eq!(total, amount); - assert_eq!(outputs.len(), 2); - } - - #[test] - fn test_prove_send_utxo_shielded() { - let owner = AccountAddress::default(); - let amount = 100; - let parts = vec![(60, owner), (40, owner)]; - - let (outputs, _) = prove_send_utxo_shielded(owner, amount, parts.clone()).unwrap(); - - let total: u128 = outputs.iter().map(|(utxo, _)| utxo.amount).sum(); - assert_eq!(total, amount); - assert_eq!(outputs.len(), 2); - } - - #[test] - fn test_prove_send_utxo_multiple_assets_one_receiver() { - let owner = AccountAddress::default(); - let receiver = AccountAddress::default(); - - let utxos = vec![ - prove_mint_utxo(100, owner).unwrap().0, - prove_mint_utxo(50, owner).unwrap().0, - ]; - - let (to_receiver, to_change, _receipt) = - prove_send_utxo_multiple_assets_one_receiver(utxos, 1, receiver).unwrap(); - let total_to_receiver: u128 = to_receiver.iter().map(|u| u.amount).sum(); - - assert!(total_to_receiver > 0); - assert_eq!(to_receiver.len() + to_change.len(), 2); - } -} diff --git a/zkvm/test_methods/guest/Cargo.lock b/zkvm/test_methods/guest/Cargo.lock deleted file mode 100644 index 0ee4887..0000000 --- a/zkvm/test_methods/guest/Cargo.lock +++ /dev/null @@ -1,1053 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "anyhow" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" - -[[package]] -name = "ark-bn254" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-std", -] - -[[package]] -name = "ark-crypto-primitives" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56" -dependencies = [ - "ark-ec", - "ark-ff", - "ark-relations", - "ark-serialize", - "ark-snark", - "ark-std", - "blake2", - "derivative", - "digest", - "sha2", -] - -[[package]] -name = "ark-ec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" -dependencies = [ - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", - "itertools", - "num-traits", - "zeroize", -] - -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "derivative", - "digest", - "itertools", - "num-bigint", - "num-traits", - "paste", - "rustc_version", - "zeroize", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-groth16" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20ceafa83848c3e390f1cbf124bc3193b3e639b3f02009e0e290809a501b95fc" -dependencies = [ - "ark-crypto-primitives", - "ark-ec", - "ark-ff", - "ark-poly", - "ark-relations", - "ark-serialize", - "ark-std", -] - -[[package]] -name = "ark-poly" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" -dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", - "derivative", - "hashbrown 0.13.2", -] - -[[package]] -name = "ark-relations" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0" -dependencies = [ - "ark-ff", - "ark-std", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-serialize-derive", - "ark-std", - "digest", - "num-bigint", -] - -[[package]] -name = "ark-serialize-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-snark" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63" -dependencies = [ - "ark-ff", - "ark-relations", - "ark-serialize", - "ark-std", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "borsh" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5327f6c99920069d1fe374aa743be1af0031dea9f250852cdf1ae6a0861ee24" -dependencies = [ - "borsh-derive", - "cfg_aliases", -] - -[[package]] -name = "borsh-derive" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10aedd8f1a81a8aafbfde924b0e3061cd6fedd6f6bbcfc6a76e6fd426d7bfe26" -dependencies = [ - "once_cell", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "bytemuck" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "elf" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - -[[package]] -name = "indexmap" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" -dependencies = [ - "equivalent", - "hashbrown 0.15.1", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" - -[[package]] -name = "libc" -version = "0.2.162" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" - -[[package]] -name = "libm" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "metal" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" -dependencies = [ - "bitflags 2.6.0", - "block", - "core-graphics-types", - "foreign-types", - "log", - "objc", - "paste", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pin-project-lite" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" - -[[package]] -name = "risc0-binfmt" -version = "1.2.0-alpha.1" -source = "git+https://github.com/risc0/risc0.git#cc8e628638530815fa8b9ac840543c720ec402e8" -dependencies = [ - "anyhow", - "borsh", - "elf", - "risc0-zkp", - "risc0-zkvm-platform", - "serde", - "tracing", -] - -[[package]] -name = "risc0-circuit-recursion" -version = "1.2.0-alpha.1" -source = "git+https://github.com/risc0/risc0.git#cc8e628638530815fa8b9ac840543c720ec402e8" -dependencies = [ - "anyhow", - "bytemuck", - "hex", - "metal", - "risc0-core", - "risc0-zkp", - "tracing", -] - -[[package]] -name = "risc0-circuit-rv32im" -version = "1.2.0-alpha.1" -source = "git+https://github.com/risc0/risc0.git#cc8e628638530815fa8b9ac840543c720ec402e8" -dependencies = [ - "anyhow", - "metal", - "risc0-binfmt", - "risc0-core", - "risc0-zkp", - "risc0-zkvm-platform", - "serde", - "tracing", -] - -[[package]] -name = "risc0-core" -version = "1.2.0-alpha.1" -source = "git+https://github.com/risc0/risc0.git#cc8e628638530815fa8b9ac840543c720ec402e8" -dependencies = [ - "bytemuck", - "rand_core", -] - -[[package]] -name = "risc0-groth16" -version = "1.2.0-alpha.1" -source = "git+https://github.com/risc0/risc0.git#cc8e628638530815fa8b9ac840543c720ec402e8" -dependencies = [ - "anyhow", - "ark-bn254", - "ark-ec", - "ark-groth16", - "ark-serialize", - "bytemuck", - "hex", - "num-bigint", - "num-traits", - "risc0-binfmt", - "risc0-zkp", - "serde", - "stability", -] - -[[package]] -name = "risc0-zkp" -version = "1.2.0-alpha.1" -source = "git+https://github.com/risc0/risc0.git#cc8e628638530815fa8b9ac840543c720ec402e8" -dependencies = [ - "anyhow", - "blake2", - "borsh", - "bytemuck", - "cfg-if", - "digest", - "hex", - "hex-literal", - "metal", - "paste", - "rand_core", - "risc0-core", - "risc0-zkvm-platform", - "serde", - "sha2", - "tracing", -] - -[[package]] -name = "risc0-zkvm" -version = "1.2.0-alpha.1" -source = "git+https://github.com/risc0/risc0.git#cc8e628638530815fa8b9ac840543c720ec402e8" -dependencies = [ - "anyhow", - "borsh", - "bytemuck", - "getrandom", - "hex", - "risc0-binfmt", - "risc0-circuit-recursion", - "risc0-circuit-rv32im", - "risc0-core", - "risc0-groth16", - "risc0-zkp", - "risc0-zkvm-platform", - "rrs-lib", - "semver", - "serde", - "sha2", - "stability", - "tracing", -] - -[[package]] -name = "risc0-zkvm-platform" -version = "1.2.0-alpha.1" -source = "git+https://github.com/risc0/risc0.git#cc8e628638530815fa8b9ac840543c720ec402e8" -dependencies = [ - "bytemuck", - "getrandom", - "libm", - "stability", -] - -[[package]] -name = "rrs-lib" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4382d3af3a4ebdae7f64ba6edd9114fff92c89808004c4943b393377a25d001" -dependencies = [ - "downcast-rs", - "paste", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "serde" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "serde_json" -version = "1.0.134" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "stability" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" -dependencies = [ - "quote", - "syn 2.0.87", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "test" -version = "0.1.0" -dependencies = [ - "risc0-zkvm", - "serde", - "serde_json", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-subscriber" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" -dependencies = [ - "tracing-core", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "winnow" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" -dependencies = [ - "memchr", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] diff --git a/zkvm/test_methods/guest/Cargo.toml b/zkvm/test_methods/guest/Cargo.toml deleted file mode 100644 index ea2c331..0000000 --- a/zkvm/test_methods/guest/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "test" -version = "0.1.0" -edition = "2021" - -[workspace] - -[dependencies] -serde_json = "1.0.81" -risc0-zkvm = { git = "https://github.com/risc0/risc0.git", default-features = false, features = [ - "std", -] } - -[dependencies.serde] -features = ["derive"] -version = "1.0.60" diff --git a/zkvm/test_methods/guest/src/bin/big_calculation.rs b/zkvm/test_methods/guest/src/bin/big_calculation.rs deleted file mode 100644 index b546857..0000000 --- a/zkvm/test_methods/guest/src/bin/big_calculation.rs +++ /dev/null @@ -1,14 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; - -fn main() { - let lhs: u128 = env::read(); - let rhs: u128 = env::read(); - let mut res = 1; - for i in 0..lhs { - res *= rhs; - res += lhs; - } - env::commit(&(res)); -} diff --git a/zkvm/test_methods/guest/src/bin/mint_utxo.rs b/zkvm/test_methods/guest/src/bin/mint_utxo.rs deleted file mode 100644 index 5123643..0000000 --- a/zkvm/test_methods/guest/src/bin/mint_utxo.rs +++ /dev/null @@ -1,32 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; -use serde::{Deserialize, Serialize}; - -type AccountAddr = [u8; 32]; - -#[derive(Serialize, Deserialize)] -pub struct UTXOPayload { - pub owner: AccountAddr, - pub asset: Vec, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: [u8; 32], -} - -fn main() { - let amount_to_mint: u128 = env::read(); - let owner: AccountAddr = env::read(); - let randomness: [u8; 32] = env::read(); - - let payload = UTXOPayload { - owner, - asset: vec![], - amount: amount_to_mint, - privacy_flag: true, - randomness, - }; - - env::commit(&(payload)); -} diff --git a/zkvm/test_methods/guest/src/bin/mint_utxo_multiple_assets.rs b/zkvm/test_methods/guest/src/bin/mint_utxo_multiple_assets.rs deleted file mode 100644 index 47ad2ac..0000000 --- a/zkvm/test_methods/guest/src/bin/mint_utxo_multiple_assets.rs +++ /dev/null @@ -1,39 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; -use serde::{Deserialize, Serialize}; - -type AccountAddr = [u8; 32]; - -#[derive(Serialize, Deserialize)] -pub struct UTXOPayload { - pub owner: AccountAddr, - pub asset: Vec, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: [u8; 32], -} - -fn main() { - let amount_to_mint: u128 = env::read(); - let number_of_assets: usize = env::read(); - let owner: AccountAddr = env::read(); - let randomness: [u8; 32] = env::read(); - - let mut asseted_utxos = vec![]; - - for i in 0..number_of_assets { - let payload = UTXOPayload { - owner, - asset: vec![i as u8], - amount: amount_to_mint, - privacy_flag: true, - randomness - }; - - asseted_utxos.push(payload); - } - - env::commit(&(asseted_utxos)); -} diff --git a/zkvm/test_methods/guest/src/bin/multiplication.rs b/zkvm/test_methods/guest/src/bin/multiplication.rs deleted file mode 100644 index 047ac07..0000000 --- a/zkvm/test_methods/guest/src/bin/multiplication.rs +++ /dev/null @@ -1,9 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; - -fn main() { - let lhs: u64 = env::read(); - let rhs: u64 = env::read(); - env::commit(&(lhs * rhs)); -} diff --git a/zkvm/test_methods/guest/src/bin/send_utxo.rs b/zkvm/test_methods/guest/src/bin/send_utxo.rs deleted file mode 100644 index 64035a9..0000000 --- a/zkvm/test_methods/guest/src/bin/send_utxo.rs +++ /dev/null @@ -1,34 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; -use serde::{Deserialize, Serialize}; - -type AccountAddr = [u8; 32]; - -#[derive(Serialize, Deserialize)] -pub struct UTXOPayload { - pub owner: AccountAddr, - pub asset: Vec, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: [u8; 32], -} - -fn main() { - let utxo_spent: UTXOPayload = env::read(); - let owners_parts: Vec<(u128, AccountAddr, [u8; 32])> = env::read(); - - let res: Vec<(UTXOPayload, AccountAddr)> = owners_parts.into_iter().map(|(amount, addr, randomness)| ( - UTXOPayload { - owner: addr.clone(), - asset: vec![], - amount, - privacy_flag: true, - randomness, - }, - addr - )).collect(); - - env::commit(&(res)); -} diff --git a/zkvm/test_methods/guest/src/bin/send_utxo_multiple_assets.rs b/zkvm/test_methods/guest/src/bin/send_utxo_multiple_assets.rs deleted file mode 100644 index e73f844..0000000 --- a/zkvm/test_methods/guest/src/bin/send_utxo_multiple_assets.rs +++ /dev/null @@ -1,41 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; -use serde::{Deserialize, Serialize}; - -type AccountAddr = [u8; 32]; - -#[derive(Clone, Serialize, Deserialize)] -pub struct UTXOPayload { - pub owner: AccountAddr, - pub asset: Vec, - // TODO: change to u256 - pub amount: u128, - pub privacy_flag: bool, - pub randomness: [u8; 32], -} - -fn main() { - let utxo_spent: Vec = env::read(); - let number_to_send = env::read(); - let receiver: AccountAddr = env::read(); - - let mut utxo_received = vec![]; - let mut utxo_not_spent = vec![]; - - for i in 0..utxo_spent.len() { - let mut utxo_payload = utxo_spent[i].clone(); - - if i < number_to_send { - utxo_payload.owner = receiver; - - utxo_received.push(utxo_payload); - } else { - utxo_payload.asset.push(0); - - utxo_not_spent.push(utxo_payload); - } - } - - env::commit(&(utxo_received, utxo_not_spent)); -} diff --git a/zkvm/test_methods/guest/src/bin/summation.rs b/zkvm/test_methods/guest/src/bin/summation.rs deleted file mode 100644 index cd642fd..0000000 --- a/zkvm/test_methods/guest/src/bin/summation.rs +++ /dev/null @@ -1,9 +0,0 @@ -use risc0_zkvm::{ - guest::env, -}; - -fn main() { - let data: u64 = env::read(); - let data_2: u64 = env::read(); - env::commit(&(data + data_2)); -}