mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-08-25 11:21:12 +00:00
Privacy-preserving circuit: - Add ProgramImageClaim, letting a Deploy-created program's real image_id be anchored to its account for privacy-circuit env::verify, with the sequencer independently re-deriving the real image_id via get_program to authenticate the claim (journal reconstruction, same pattern as public_actions pre-states). - Fix compute_public_authorized_pdas and the private circuit's resolve_authorization_and_record_bindings to use the caller's real recovered image_id instead of bijection-guessing it from the caller's account_id, which was wrong for Deploy-created callers. Program storage: - V03State::insert_program (used by both genesis's with_programs and live ProgramDeploymentTransaction execution) now always writes the Deploy two-account shape (ProgramData header + segment), not the legacy PROGRAM_STORAGE_OWNER raw-elf shape. The header stays at the existing bijection address so no dispatch-address reference needed to change; only the segment (never a caller-facing address) moves to its PDA. - Drop the now-redundant ProgramAlreadyExists pre-check in ProgramDeploymentTransaction validation; PDA claiming already prevents redeploying an account. - Migrate remaining tests off ProgramDeploymentTransaction onto native Deploy (sequencer_core, integration_tests' auth_transfer and block_size_limit), adding a shared deploy_targets/deploy_transaction/encoded_tx_size helper. Rebuild artifacts and the prebuilt test fixture for the circuit and program storage changes.
116 lines
3.6 KiB
Rust
116 lines
3.6 KiB
Rust
use std::borrow::Cow;
|
|
|
|
use borsh::{BorshDeserialize, BorshSerialize};
|
|
use lee_core::{
|
|
account::{AccountId, AccountWithMetadata},
|
|
program::{InstructionData, ProgramId, ProgramOutput},
|
|
};
|
|
use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, default_executor, serde::to_vec};
|
|
use serde::Serialize;
|
|
|
|
use crate::error::LeeError;
|
|
|
|
/// Maximum number of cycles for a public execution.
|
|
/// TODO: Make this variable when fees are implemented.
|
|
const MAX_NUM_CYCLES_PUBLIC_EXECUTION: u64 = 1024 * 1024 * 32; // 32M cycles
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
|
|
pub struct Program {
|
|
id: ProgramId,
|
|
elf: Cow<'static, [u8]>,
|
|
}
|
|
|
|
impl Program {
|
|
pub fn new(elf: Cow<'static, [u8]>) -> Result<Self, LeeError> {
|
|
let binary = risc0_binfmt::ProgramBinary::decode(elf.as_ref())
|
|
.map_err(LeeError::InvalidProgramBytecode)?;
|
|
let id = binary
|
|
.compute_image_id()
|
|
.map_err(LeeError::InvalidProgramBytecode)?
|
|
.into();
|
|
Ok(Self { id, elf })
|
|
}
|
|
|
|
#[must_use]
|
|
pub const fn new_unchecked(id: ProgramId, elf: Cow<'static, [u8]>) -> Self {
|
|
Self { id, elf }
|
|
}
|
|
|
|
#[must_use]
|
|
pub const fn id(&self) -> ProgramId {
|
|
self.id
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn elf(&self) -> &[u8] {
|
|
&self.elf
|
|
}
|
|
|
|
pub fn serialize_instruction<T: Serialize>(
|
|
instruction: T,
|
|
) -> Result<InstructionData, LeeError> {
|
|
to_vec(&instruction).map_err(|e| LeeError::InstructionSerializationError(e.to_string()))
|
|
}
|
|
|
|
pub(crate) fn execute(
|
|
&self,
|
|
self_account_id: AccountId,
|
|
caller_account_id: Option<AccountId>,
|
|
pre_states: &[AccountWithMetadata],
|
|
instruction_data: &InstructionData,
|
|
) -> Result<ProgramOutput, LeeError> {
|
|
// Write inputs to the program
|
|
let mut env_builder = ExecutorEnv::builder();
|
|
env_builder.session_limit(Some(MAX_NUM_CYCLES_PUBLIC_EXECUTION));
|
|
Self::write_inputs(
|
|
self_account_id,
|
|
caller_account_id,
|
|
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| LeeError::ProgramExecutionFailed(e.to_string()))?;
|
|
|
|
// Get outputs
|
|
let program_output = session_info
|
|
.journal
|
|
.decode()
|
|
.map_err(|e| LeeError::ProgramExecutionFailed(e.to_string()))?;
|
|
|
|
Ok(program_output)
|
|
}
|
|
|
|
/// Writes inputs to `env_builder` in the order expected by the programs.
|
|
pub(crate) fn write_inputs(
|
|
self_account_id: AccountId,
|
|
caller_account_id: Option<AccountId>,
|
|
pre_states: &[AccountWithMetadata],
|
|
instruction_data: &[u32],
|
|
env_builder: &mut ExecutorEnvBuilder,
|
|
) -> Result<(), LeeError> {
|
|
env_builder
|
|
.write(&self_account_id)
|
|
.map_err(|e| LeeError::ProgramWriteInputFailed(e.to_string()))?;
|
|
env_builder
|
|
.write(&caller_account_id)
|
|
.map_err(|e| LeeError::ProgramWriteInputFailed(e.to_string()))?;
|
|
let pre_states = pre_states.to_vec();
|
|
env_builder
|
|
.write(&pre_states)
|
|
.map_err(|e| LeeError::ProgramWriteInputFailed(e.to_string()))?;
|
|
env_builder
|
|
.write(&instruction_data)
|
|
.map_err(|e| LeeError::ProgramWriteInputFailed(e.to_string()))?;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|