2024-12-22 16:14:52 +02:00
|
|
|
use accounts::account_core::AccountAddress;
|
2025-02-05 12:24:09 +02:00
|
|
|
use common::ExecutionFailureKind;
|
2024-11-18 02:09:13 +01:00
|
|
|
use risc0_zkvm::{default_executor, default_prover, sha::Digest, ExecutorEnv, Receipt};
|
2025-02-28 12:32:54 +02:00
|
|
|
use serde::Serialize;
|
2024-12-20 11:02:12 +02:00
|
|
|
use utxo::utxo_core::{UTXOPayload, UTXO};
|
|
|
|
|
|
2025-02-28 12:32:54 +02:00
|
|
|
pub mod gas_calculator;
|
|
|
|
|
|
|
|
|
|
pub fn gas_limits_check<INP: Serialize>(
|
|
|
|
|
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(())
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
pub fn prove_mint_utxo(
|
|
|
|
|
amount_to_mint: u128,
|
|
|
|
|
owner: AccountAddress,
|
|
|
|
|
) -> Result<(UTXO, Receipt), ExecutionFailureKind> {
|
2024-12-20 11:02:12 +02:00
|
|
|
let mut builder = ExecutorEnv::builder();
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
builder
|
|
|
|
|
.write(&amount_to_mint)
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?;
|
|
|
|
|
builder
|
|
|
|
|
.write(&owner)
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let env = builder
|
|
|
|
|
.build()
|
|
|
|
|
.map_err(ExecutionFailureKind::builder_error)?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
|
|
|
|
let prover = default_prover();
|
|
|
|
|
|
2024-12-22 16:14:52 +02:00
|
|
|
let receipt = prover
|
|
|
|
|
.prove(env, test_methods::MINT_UTXO_ELF)
|
2025-01-10 03:00:32 +02:00
|
|
|
.map_err(ExecutionFailureKind::prove_error)?
|
2024-12-22 16:14:52 +02:00
|
|
|
.receipt;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let digest: UTXOPayload = receipt.journal.decode()?;
|
2024-12-22 16:14:52 +02:00
|
|
|
|
2025-02-07 15:17:55 -05:00
|
|
|
Ok((
|
|
|
|
|
UTXO::create_utxo_from_payload(digest).map_err(ExecutionFailureKind::write_error)?,
|
|
|
|
|
receipt,
|
|
|
|
|
))
|
2024-12-22 16:14:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn prove_send_utxo(
|
|
|
|
|
spent_utxo: UTXO,
|
|
|
|
|
owners_parts: Vec<(u128, AccountAddress)>,
|
2025-01-10 03:00:32 +02:00
|
|
|
) -> 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);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-22 16:14:52 +02:00
|
|
|
let mut builder = ExecutorEnv::builder();
|
2024-12-30 08:44:26 +02:00
|
|
|
let utxo_payload = spent_utxo.into_payload();
|
2024-12-22 16:14:52 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
builder
|
|
|
|
|
.write(&utxo_payload)
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?;
|
|
|
|
|
builder
|
|
|
|
|
.write(&owners_parts)
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?;
|
2024-12-22 16:14:52 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let env = builder
|
|
|
|
|
.build()
|
|
|
|
|
.map_err(ExecutionFailureKind::builder_error)?;
|
2024-12-22 16:14:52 +02:00
|
|
|
|
|
|
|
|
let prover = default_prover();
|
|
|
|
|
|
|
|
|
|
let receipt = prover
|
|
|
|
|
.prove(env, test_methods::SEND_UTXO_ELF)
|
2025-01-10 03:00:32 +02:00
|
|
|
.map_err(ExecutionFailureKind::prove_error)?
|
2024-12-22 16:14:52 +02:00
|
|
|
.receipt;
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let digest: Vec<(UTXOPayload, AccountAddress)> = receipt.journal.decode()?;
|
2024-12-22 16:14:52 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
Ok((
|
2024-12-22 16:14:52 +02:00
|
|
|
digest
|
|
|
|
|
.into_iter()
|
2025-02-07 15:16:31 -05:00
|
|
|
.map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload).map(|sel| (sel, addr))))
|
2025-02-07 15:17:55 -05:00
|
|
|
.collect::<anyhow::Result<Vec<(UTXO, [u8; 32])>>>()
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?,
|
2024-12-22 16:14:52 +02:00
|
|
|
receipt,
|
2025-01-10 03:00:32 +02:00
|
|
|
))
|
2024-12-20 11:02:12 +02:00
|
|
|
}
|
|
|
|
|
|
2025-01-03 12:43:05 +02:00
|
|
|
pub fn prove_send_utxo_multiple_assets_one_receiver(
|
|
|
|
|
spent_utxos: Vec<UTXO>,
|
|
|
|
|
number_to_send: usize,
|
|
|
|
|
receiver: AccountAddress,
|
2025-01-10 03:00:32 +02:00
|
|
|
) -> Result<(Vec<UTXO>, Vec<UTXO>, Receipt), ExecutionFailureKind> {
|
|
|
|
|
if number_to_send > spent_utxos.len() {
|
|
|
|
|
return Err(ExecutionFailureKind::AmountMismatchError);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-03 12:43:05 +02:00
|
|
|
let mut builder = ExecutorEnv::builder();
|
|
|
|
|
let utxo_payload: Vec<UTXOPayload> = spent_utxos
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|spent_utxo| spent_utxo.into_payload())
|
|
|
|
|
.collect();
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
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)?;
|
2025-01-03 12:43:05 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let env = builder
|
|
|
|
|
.build()
|
|
|
|
|
.map_err(ExecutionFailureKind::builder_error)?;
|
2025-01-03 12:43:05 +02:00
|
|
|
|
|
|
|
|
let prover = default_prover();
|
|
|
|
|
|
|
|
|
|
let receipt = prover
|
|
|
|
|
.prove(env, test_methods::SEND_UTXO_MULTIPLE_ASSETS_ELF)
|
2025-01-10 03:00:32 +02:00
|
|
|
.map_err(ExecutionFailureKind::prove_error)?
|
2025-01-03 12:43:05 +02:00
|
|
|
.receipt;
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let digest: (Vec<UTXOPayload>, Vec<UTXOPayload>) = receipt.journal.decode()?;
|
2025-01-03 12:43:05 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
Ok((
|
2025-01-03 12:43:05 +02:00
|
|
|
digest
|
|
|
|
|
.0
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|payload| UTXO::create_utxo_from_payload(payload))
|
2025-02-07 15:17:55 -05:00
|
|
|
.collect::<anyhow::Result<Vec<UTXO>>>()
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?,
|
2025-01-03 12:43:05 +02:00
|
|
|
digest
|
|
|
|
|
.1
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|payload| UTXO::create_utxo_from_payload(payload))
|
2025-02-07 15:17:55 -05:00
|
|
|
.collect::<anyhow::Result<Vec<UTXO>>>()
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?,
|
2025-01-03 12:43:05 +02:00
|
|
|
receipt,
|
2025-01-10 03:00:32 +02:00
|
|
|
))
|
2025-01-03 12:43:05 +02:00
|
|
|
}
|
|
|
|
|
|
2024-12-22 16:14:52 +02:00
|
|
|
pub fn prove_send_utxo_shielded(
|
|
|
|
|
owner: AccountAddress,
|
|
|
|
|
amount: u128,
|
|
|
|
|
owners_parts: Vec<(u128, AccountAddress)>,
|
2025-01-10 03:00:32 +02:00
|
|
|
) -> 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);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-22 16:14:52 +02:00
|
|
|
let temp_utxo_to_spend = UTXO::create_utxo_from_payload(UTXOPayload {
|
|
|
|
|
owner,
|
|
|
|
|
asset: vec![],
|
|
|
|
|
amount,
|
|
|
|
|
privacy_flag: true,
|
2025-02-07 15:17:55 -05:00
|
|
|
})
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?;
|
2024-12-30 08:44:26 +02:00
|
|
|
let utxo_payload = temp_utxo_to_spend.into_payload();
|
2024-12-22 16:14:52 +02:00
|
|
|
|
|
|
|
|
let mut builder = ExecutorEnv::builder();
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
builder
|
|
|
|
|
.write(&utxo_payload)
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?;
|
|
|
|
|
builder
|
|
|
|
|
.write(&owners_parts)
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?;
|
2024-12-22 16:14:52 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let env = builder
|
|
|
|
|
.build()
|
|
|
|
|
.map_err(ExecutionFailureKind::builder_error)?;
|
2024-12-22 16:14:52 +02:00
|
|
|
|
|
|
|
|
let prover = default_prover();
|
|
|
|
|
|
|
|
|
|
let receipt = prover
|
|
|
|
|
.prove(env, test_methods::SEND_UTXO_ELF)
|
2025-01-10 03:00:32 +02:00
|
|
|
.map_err(ExecutionFailureKind::prove_error)?
|
2024-12-22 16:14:52 +02:00
|
|
|
.receipt;
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let digest: Vec<(UTXOPayload, AccountAddress)> = receipt.journal.decode()?;
|
2024-12-22 16:14:52 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
Ok((
|
2024-12-22 16:14:52 +02:00
|
|
|
digest
|
|
|
|
|
.into_iter()
|
2025-02-07 15:16:31 -05:00
|
|
|
.map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload).map(|sel| (sel, addr))))
|
2025-02-07 15:17:55 -05:00
|
|
|
.collect::<anyhow::Result<Vec<(UTXO, [u8; 32])>>>()
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?,
|
2024-12-22 16:14:52 +02:00
|
|
|
receipt,
|
2025-01-10 03:00:32 +02:00
|
|
|
))
|
2024-12-22 16:14:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn prove_send_utxo_deshielded(
|
|
|
|
|
spent_utxo: UTXO,
|
|
|
|
|
owners_parts: Vec<(u128, AccountAddress)>,
|
2025-01-10 03:00:32 +02:00
|
|
|
) -> 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);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-20 11:02:12 +02:00
|
|
|
let mut builder = ExecutorEnv::builder();
|
2024-12-30 07:43:27 +02:00
|
|
|
let utxo_payload = spent_utxo.into_payload();
|
2024-12-20 11:02:12 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
builder
|
|
|
|
|
.write(&utxo_payload)
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?;
|
|
|
|
|
builder
|
|
|
|
|
.write(&owners_parts)
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let env = builder
|
|
|
|
|
.build()
|
|
|
|
|
.map_err(ExecutionFailureKind::builder_error)?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
|
|
|
|
let prover = default_prover();
|
|
|
|
|
|
2024-12-22 16:14:52 +02:00
|
|
|
let receipt = prover
|
|
|
|
|
.prove(env, test_methods::SEND_UTXO_ELF)
|
2025-01-10 03:00:32 +02:00
|
|
|
.map_err(ExecutionFailureKind::prove_error)?
|
2024-12-22 16:14:52 +02:00
|
|
|
.receipt;
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let digest: Vec<(UTXOPayload, AccountAddress)> = receipt.journal.decode()?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
Ok((
|
2024-12-22 16:14:52 +02:00
|
|
|
digest
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|(payload, addr)| (payload.amount, addr))
|
|
|
|
|
.collect(),
|
|
|
|
|
receipt,
|
2025-01-10 03:00:32 +02:00
|
|
|
))
|
2024-12-20 11:02:12 +02:00
|
|
|
}
|
|
|
|
|
|
2025-01-03 12:43:05 +02:00
|
|
|
pub fn prove_mint_utxo_multiple_assets(
|
|
|
|
|
amount_to_mint: u128,
|
|
|
|
|
number_of_assets: usize,
|
|
|
|
|
owner: AccountAddress,
|
2025-01-10 03:00:32 +02:00
|
|
|
) -> Result<(Vec<UTXO>, Receipt), ExecutionFailureKind> {
|
2025-01-03 12:43:05 +02:00
|
|
|
let mut builder = ExecutorEnv::builder();
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
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)?;
|
2025-01-03 12:43:05 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let env = builder
|
|
|
|
|
.build()
|
|
|
|
|
.map_err(ExecutionFailureKind::builder_error)?;
|
2025-01-03 12:43:05 +02:00
|
|
|
|
|
|
|
|
let prover = default_prover();
|
|
|
|
|
|
|
|
|
|
let receipt = prover
|
|
|
|
|
.prove(env, test_methods::MINT_UTXO_MULTIPLE_ASSETS_ELF)
|
2025-01-10 03:00:32 +02:00
|
|
|
.map_err(ExecutionFailureKind::prove_error)?
|
2025-01-03 12:43:05 +02:00
|
|
|
.receipt;
|
|
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
let digest: Vec<UTXOPayload> = receipt.journal.decode()?;
|
2025-01-03 12:43:05 +02:00
|
|
|
|
2025-01-10 03:00:32 +02:00
|
|
|
Ok((
|
2025-01-03 12:43:05 +02:00
|
|
|
digest
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(UTXO::create_utxo_from_payload)
|
2025-02-07 15:17:55 -05:00
|
|
|
.collect::<anyhow::Result<Vec<UTXO>>>()
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?,
|
2025-01-03 12:43:05 +02:00
|
|
|
receipt,
|
2025-01-10 03:00:32 +02:00
|
|
|
))
|
2025-01-03 12:43:05 +02:00
|
|
|
}
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
pub fn execute_mint_utxo(amount_to_mint: u128, owner: AccountAddress) -> anyhow::Result<UTXO> {
|
2024-12-20 11:02:12 +02:00
|
|
|
let mut builder = ExecutorEnv::builder();
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
builder.write(&amount_to_mint)?;
|
|
|
|
|
builder.write(&owner)?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let env = builder.build()?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
|
|
|
|
let executor = default_executor();
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let receipt = executor.execute(env, test_methods::MINT_UTXO_ELF)?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let digest: UTXOPayload = receipt.journal.decode()?;
|
2024-12-22 16:14:52 +02:00
|
|
|
|
2024-12-20 11:02:12 +02:00
|
|
|
UTXO::create_utxo_from_payload(digest)
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-22 16:14:52 +02:00
|
|
|
pub fn execute_send_utxo(
|
|
|
|
|
spent_utxo: UTXO,
|
|
|
|
|
owners_parts: Vec<(u128, AccountAddress)>,
|
2025-02-07 15:16:31 -05:00
|
|
|
) -> anyhow::Result<(UTXO, Vec<(UTXO, AccountAddress)>)> {
|
2024-12-20 11:02:12 +02:00
|
|
|
let mut builder = ExecutorEnv::builder();
|
|
|
|
|
|
2024-12-30 08:44:26 +02:00
|
|
|
let utxo_payload = spent_utxo.into_payload();
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
builder.write(&utxo_payload)?;
|
|
|
|
|
builder.write(&owners_parts)?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let env = builder.build()?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
|
|
|
|
let executor = default_executor();
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let receipt = executor.execute(env, test_methods::SEND_UTXO_ELF)?;
|
2024-12-20 11:02:12 +02:00
|
|
|
|
2025-02-07 15:17:55 -05:00
|
|
|
let digest: (UTXOPayload, Vec<(UTXOPayload, AccountAddress)>) = receipt.journal.decode()?;
|
2024-12-22 16:14:52 +02:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
Ok((
|
|
|
|
|
UTXO::create_utxo_from_payload(digest.0)?,
|
2024-12-22 16:14:52 +02:00
|
|
|
digest
|
|
|
|
|
.1
|
|
|
|
|
.into_iter()
|
2025-02-07 15:16:31 -05:00
|
|
|
.map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload).map(|sel| (sel, addr))))
|
2025-02-07 15:17:55 -05:00
|
|
|
.collect::<anyhow::Result<Vec<(UTXO, [u8; 32])>>>()
|
|
|
|
|
.map_err(ExecutionFailureKind::write_error)?,
|
2025-02-07 15:16:31 -05:00
|
|
|
))
|
2024-12-20 11:02:12 +02:00
|
|
|
}
|
2024-11-10 02:10:20 +01:00
|
|
|
|
2025-02-07 15:17:55 -05:00
|
|
|
pub fn prove<T: serde::ser::Serialize>(
|
|
|
|
|
input_vec: Vec<T>,
|
|
|
|
|
elf: &[u8],
|
|
|
|
|
) -> anyhow::Result<(u64, Receipt)> {
|
2024-11-10 02:10:20 +01:00
|
|
|
let mut builder = ExecutorEnv::builder();
|
|
|
|
|
|
|
|
|
|
for input in input_vec {
|
2025-02-07 15:16:31 -05:00
|
|
|
builder.write(&input)?;
|
2024-11-10 02:10:20 +01:00
|
|
|
}
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let env = builder.build()?;
|
2024-11-10 02:10:20 +01:00
|
|
|
|
|
|
|
|
let prover = default_prover();
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let receipt = prover.prove(env, elf)?.receipt;
|
2024-11-10 02:10:20 +01:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let digest = receipt.journal.decode()?;
|
|
|
|
|
Ok((digest, receipt))
|
2024-11-10 02:10:20 +01:00
|
|
|
}
|
2024-11-10 02:10:37 +01:00
|
|
|
|
2024-11-18 01:41:30 +01:00
|
|
|
// This only executes the program and does not generate a receipt.
|
2024-11-18 02:09:13 +01:00
|
|
|
pub fn execute<T: serde::ser::Serialize + for<'de> serde::Deserialize<'de>>(
|
|
|
|
|
input_vec: Vec<T>,
|
|
|
|
|
elf: &[u8],
|
2025-02-07 15:16:31 -05:00
|
|
|
) -> anyhow::Result<T> {
|
2024-11-18 01:41:30 +01:00
|
|
|
let mut builder = ExecutorEnv::builder();
|
|
|
|
|
|
|
|
|
|
for input in input_vec {
|
2025-02-07 15:16:31 -05:00
|
|
|
builder.write(&input)?;
|
2024-11-18 01:41:30 +01:00
|
|
|
}
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let env = builder.build()?;
|
2024-11-18 01:41:30 +01:00
|
|
|
|
|
|
|
|
let exec = default_executor();
|
2025-02-07 15:16:31 -05:00
|
|
|
let session = exec.execute(env, elf)?;
|
2024-11-18 01:41:30 +01:00
|
|
|
|
2024-11-18 02:06:37 +01:00
|
|
|
// We read the result committed to the journal by the guest code.
|
2025-02-07 15:16:31 -05:00
|
|
|
let result: T = session.journal.decode()?;
|
2024-11-18 02:06:37 +01:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
Ok(result)
|
2024-11-18 01:41:30 +01:00
|
|
|
}
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
pub fn verify(receipt: Receipt, image_id: impl Into<Digest>) -> anyhow::Result<()> {
|
2025-02-07 15:17:55 -05:00
|
|
|
Ok(receipt.verify(image_id)?)
|
2024-11-10 02:10:37 +01:00
|
|
|
}
|
2024-11-10 02:12:20 +01:00
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
2024-12-22 16:14:52 +02:00
|
|
|
use test_methods::BIG_CALCULATION_ELF;
|
2024-11-10 02:14:01 +01:00
|
|
|
use test_methods::{MULTIPLICATION_ELF, MULTIPLICATION_ID};
|
|
|
|
|
use test_methods::{SUMMATION_ELF, SUMMATION_ID};
|
2024-11-10 02:12:20 +01:00
|
|
|
|
|
|
|
|
#[test]
|
2024-11-18 02:08:58 +01:00
|
|
|
fn prove_simple_sum() {
|
2024-11-10 02:12:20 +01:00
|
|
|
let message = 1;
|
|
|
|
|
let message_2 = 2;
|
2024-11-10 02:14:01 +01:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap();
|
2024-11-10 02:14:01 +01:00
|
|
|
|
2024-11-10 02:12:20 +01:00
|
|
|
verify(receipt, SUMMATION_ID);
|
2024-11-10 02:14:01 +01:00
|
|
|
assert_eq!(digest, message + message_2);
|
2024-11-10 02:12:20 +01:00
|
|
|
}
|
2024-11-10 02:12:37 +01:00
|
|
|
|
|
|
|
|
#[test]
|
2024-11-18 02:08:58 +01:00
|
|
|
fn prove_bigger_sum() {
|
2024-11-10 02:12:37 +01:00
|
|
|
let message = 123476;
|
|
|
|
|
let message_2 = 2342384;
|
2024-11-10 02:14:01 +01:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF).unwrap();
|
2024-11-10 02:14:01 +01:00
|
|
|
|
2024-11-10 02:12:37 +01:00
|
|
|
verify(receipt, SUMMATION_ID);
|
2024-11-10 02:14:01 +01:00
|
|
|
assert_eq!(digest, message + message_2);
|
2024-11-10 02:12:37 +01:00
|
|
|
}
|
2024-11-10 02:12:55 +01:00
|
|
|
|
|
|
|
|
#[test]
|
2024-11-18 02:08:58 +01:00
|
|
|
fn prove_simple_multiplication() {
|
2024-11-10 02:12:55 +01:00
|
|
|
let message = 1;
|
|
|
|
|
let message_2 = 2;
|
2024-11-10 02:14:01 +01:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap();
|
2024-11-10 02:14:01 +01:00
|
|
|
|
2024-11-10 02:12:55 +01:00
|
|
|
verify(receipt, MULTIPLICATION_ID);
|
2024-11-10 02:14:01 +01:00
|
|
|
assert_eq!(digest, message * message_2);
|
2024-11-10 02:12:55 +01:00
|
|
|
}
|
2024-11-10 02:13:24 +01:00
|
|
|
|
|
|
|
|
#[test]
|
2024-11-18 02:08:58 +01:00
|
|
|
fn prove_bigger_multiplication() {
|
2024-11-10 02:13:24 +01:00
|
|
|
let message = 3498;
|
|
|
|
|
let message_2 = 438563;
|
2024-11-10 02:14:01 +01:00
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF).unwrap();
|
2024-11-10 02:14:01 +01:00
|
|
|
|
2024-11-10 02:13:24 +01:00
|
|
|
verify(receipt, MULTIPLICATION_ID);
|
2024-11-10 02:14:01 +01:00
|
|
|
assert_eq!(digest, message * message_2);
|
2024-11-10 02:13:24 +01:00
|
|
|
}
|
2024-11-18 02:07:57 +01:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn execute_simple_sum() {
|
|
|
|
|
let message: u64 = 1;
|
|
|
|
|
let message_2: u64 = 2;
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let result = execute(vec![message, message_2], SUMMATION_ELF).unwrap();
|
2024-11-18 02:07:57 +01:00
|
|
|
assert_eq!(result, message + message_2);
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-18 02:08:08 +01:00
|
|
|
#[test]
|
|
|
|
|
fn execute_bigger_sum() {
|
|
|
|
|
let message: u64 = 123476;
|
|
|
|
|
let message_2: u64 = 2342384;
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let result = execute(vec![message, message_2], SUMMATION_ELF).unwrap();
|
2024-11-18 02:08:08 +01:00
|
|
|
assert_eq!(result, message + message_2);
|
|
|
|
|
}
|
2024-11-18 02:22:07 +01:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn execute_big_calculation() {
|
|
|
|
|
let message: u128 = 1;
|
|
|
|
|
let message_2: u128 = 2;
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let result = execute(vec![message, message_2], BIG_CALCULATION_ELF).unwrap();
|
2024-11-18 02:22:07 +01:00
|
|
|
assert_eq!(result, big_calculation(message, message_2));
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-18 02:22:14 +01:00
|
|
|
#[test]
|
|
|
|
|
fn execute_big_calculation_long() {
|
|
|
|
|
let message: u128 = 20;
|
|
|
|
|
let message_2: u128 = 10;
|
|
|
|
|
|
2025-02-07 15:16:31 -05:00
|
|
|
let result = execute(vec![message, message_2], BIG_CALCULATION_ELF).unwrap();
|
2024-11-18 02:22:14 +01:00
|
|
|
assert_eq!(result, big_calculation(message, message_2));
|
|
|
|
|
}
|
2024-11-18 02:22:07 +01:00
|
|
|
|
|
|
|
|
fn big_calculation(lhs: u128, rhs: u128) -> u128 {
|
|
|
|
|
let mut res = 1_u128;
|
|
|
|
|
for _ in 0..lhs {
|
|
|
|
|
res *= rhs;
|
|
|
|
|
res += lhs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res
|
2024-11-25 10:37:49 +02:00
|
|
|
}
|
2024-11-10 02:12:20 +01:00
|
|
|
}
|