mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-25 21:16:41 +03:00
rest of Aleo commands
This commit is contained in:
parent
b2f7fd718b
commit
334881cef5
@ -256,7 +256,7 @@ pub struct Cursor<'a> {
|
|||||||
|
|
||||||
pub signer: SvmAddress,
|
pub signer: SvmAddress,
|
||||||
|
|
||||||
rng: ChaCha20Rng,
|
pub rng: ChaCha20Rng,
|
||||||
|
|
||||||
pub block_height: u32,
|
pub block_height: u32,
|
||||||
|
|
||||||
@ -322,14 +322,14 @@ impl<'a> Cursor<'a> {
|
|||||||
self.globals.get(&GlobalId { program: context.program, name }).cloned()
|
self.globals.get(&GlobalId { program: context.program, name }).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_mapping(&self, program: Option<Symbol>, name: Symbol) -> Option<&HashMap<Value, Value>> {
|
pub fn lookup_mapping(&self, program: Option<Symbol>, name: Symbol) -> Option<&HashMap<Value, Value>> {
|
||||||
let Some(program) = program.or(self.contexts.last().map(|c| c.program)) else {
|
let Some(program) = program.or(self.contexts.last().map(|c| c.program)) else {
|
||||||
panic!("no program for mapping lookup");
|
panic!("no program for mapping lookup");
|
||||||
};
|
};
|
||||||
self.mappings.get(&GlobalId { program, name })
|
self.mappings.get(&GlobalId { program, name })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_mapping_mut(&mut self, program: Option<Symbol>, name: Symbol) -> Option<&mut HashMap<Value, Value>> {
|
pub fn lookup_mapping_mut(&mut self, program: Option<Symbol>, name: Symbol) -> Option<&mut HashMap<Value, Value>> {
|
||||||
let Some(program) = program.or(self.contexts.last().map(|c| c.program)) else {
|
let Some(program) = program.or(self.contexts.last().map(|c| c.program)) else {
|
||||||
panic!("no program for mapping lookup");
|
panic!("no program for mapping lookup");
|
||||||
};
|
};
|
||||||
|
@ -19,14 +19,39 @@ use super::*;
|
|||||||
use leo_ast::{BinaryOperation, CoreFunction, IntegerType, Type, UnaryOperation};
|
use leo_ast::{BinaryOperation, CoreFunction, IntegerType, Type, UnaryOperation};
|
||||||
|
|
||||||
use snarkvm::{
|
use snarkvm::{
|
||||||
prelude::{Boolean, Identifier, Literal, LiteralType, PlaintextType, Register, TestnetV0, integers::Integer},
|
prelude::{
|
||||||
|
Boolean,
|
||||||
|
Field,
|
||||||
|
Identifier,
|
||||||
|
Literal,
|
||||||
|
LiteralType,
|
||||||
|
Network as _,
|
||||||
|
PlaintextType,
|
||||||
|
Register,
|
||||||
|
TestnetV0,
|
||||||
|
ToBits as _,
|
||||||
|
ToBytes as _,
|
||||||
|
integers::Integer,
|
||||||
|
},
|
||||||
synthesizer::{Command, Instruction},
|
synthesizer::{Command, Instruction},
|
||||||
};
|
};
|
||||||
use snarkvm_synthesizer_program::{CallOperator, CastType, Operand};
|
use snarkvm_synthesizer_program::{CallOperator, CastType, Operand};
|
||||||
|
|
||||||
|
use rand::Rng as _;
|
||||||
|
use rand_chacha::{ChaCha20Rng, rand_core::SeedableRng};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
impl Cursor<'_> {
|
impl Cursor<'_> {
|
||||||
|
fn mapping_by_call_operator(&self, operator: &CallOperator<TestnetV0>) -> Option<&HashMap<Value, Value>> {
|
||||||
|
let (program, name) = match operator {
|
||||||
|
CallOperator::Locator(locator) => {
|
||||||
|
(Some(snarkvm_identifier_to_symbol(locator.name())), snarkvm_identifier_to_symbol(locator.resource()))
|
||||||
|
}
|
||||||
|
CallOperator::Resource(id) => (None, snarkvm_identifier_to_symbol(id)),
|
||||||
|
};
|
||||||
|
self.lookup_mapping(program, name)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_register(&self, reg: Register<TestnetV0>) -> &Value {
|
fn get_register(&self, reg: Register<TestnetV0>) -> &Value {
|
||||||
let Some(Frame { element: Element::AleoExecution { registers, .. }, .. }) = self.frames.last() else {
|
let Some(Frame { element: Element::AleoExecution { registers, .. }, .. }) = self.frames.last() else {
|
||||||
panic!();
|
panic!();
|
||||||
@ -742,21 +767,108 @@ impl Cursor<'_> {
|
|||||||
|
|
||||||
fn step_aleo_command(&mut self, command: Command<TestnetV0>) -> Result<()> {
|
fn step_aleo_command(&mut self, command: Command<TestnetV0>) -> Result<()> {
|
||||||
use Command::*;
|
use Command::*;
|
||||||
match command {
|
|
||||||
Instruction(instruction) => self.step_aleo_instruction(instruction)?,
|
let (value, destination) = match command {
|
||||||
|
Instruction(instruction) => {
|
||||||
|
self.step_aleo_instruction(instruction)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
Await(await_) => {
|
Await(await_) => {
|
||||||
let Value::Future(future) = self.get_register(await_.register().clone()) else {
|
let Value::Future(future) = self.get_register(await_.register().clone()) else {
|
||||||
halt_no_span!("attempted to await a non-future");
|
halt_no_span!("attempted to await a non-future");
|
||||||
};
|
};
|
||||||
self.contexts.add_future(future.clone());
|
self.contexts.add_future(future.clone());
|
||||||
self.increment_instruction_index();
|
self.increment_instruction_index();
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Contains(contains) => {
|
||||||
|
let mapping = self.mapping_by_call_operator(contains.mapping()).expect("mapping should be present");
|
||||||
|
let key = self.operand_value(contains.key());
|
||||||
|
let result = Value::Bool(mapping.contains_key(&key));
|
||||||
|
self.increment_instruction_index();
|
||||||
|
(result, contains.destination().clone())
|
||||||
|
}
|
||||||
|
Get(get) => {
|
||||||
|
let key = self.operand_value(get.key());
|
||||||
|
let value = self.mapping_by_call_operator(get.mapping()).and_then(|mapping| mapping.get(&key)).cloned();
|
||||||
|
self.increment_instruction_index();
|
||||||
|
|
||||||
|
match value {
|
||||||
|
Some(v) => (v, get.destination().clone()),
|
||||||
|
None => halt_no_span!("map access failure: {key}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GetOrUse(get_or_use) => {
|
||||||
|
let key = self.operand_value(get_or_use.key());
|
||||||
|
let value =
|
||||||
|
self.mapping_by_call_operator(get_or_use.mapping()).and_then(|mapping| mapping.get(&key)).cloned();
|
||||||
|
|
||||||
|
let use_value = value.unwrap_or_else(|| self.operand_value(get_or_use.default()));
|
||||||
|
self.increment_instruction_index();
|
||||||
|
|
||||||
|
(use_value, get_or_use.destination().clone())
|
||||||
|
}
|
||||||
|
Remove(remove) => {
|
||||||
|
let key = self.operand_value(remove.key());
|
||||||
|
let mapping_name = snarkvm_identifier_to_symbol(remove.mapping_name());
|
||||||
|
let maybe_mapping = self.lookup_mapping_mut(None, mapping_name);
|
||||||
|
match maybe_mapping {
|
||||||
|
None => halt_no_span!("no such mapping {mapping_name}"),
|
||||||
|
Some(mapping) => {
|
||||||
|
mapping.remove(&key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.increment_instruction_index();
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Set(set) => {
|
||||||
|
let key = self.operand_value(set.key());
|
||||||
|
let value = self.operand_value(set.value());
|
||||||
|
let mapping_name = snarkvm_identifier_to_symbol(set.mapping_name());
|
||||||
|
let maybe_mapping = self.lookup_mapping_mut(None, mapping_name);
|
||||||
|
match maybe_mapping {
|
||||||
|
None => halt_no_span!("no such mapping {mapping_name}"),
|
||||||
|
Some(mapping) => {
|
||||||
|
mapping.insert(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.increment_instruction_index();
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
RandChaCha(rand) => {
|
||||||
|
// If there are operands, they are additional seeds.
|
||||||
|
let mut bits = Vec::new();
|
||||||
|
for value in rand.operands().iter().map(|op| self.operand_value(op)) {
|
||||||
|
value.write_bits_le(&mut bits);
|
||||||
|
}
|
||||||
|
let field: Field<TestnetV0> = self.rng.gen();
|
||||||
|
field.write_bits_le(&mut bits);
|
||||||
|
let seed_vec = TestnetV0::hash_bhp1024(&bits)?.to_bytes_le()?;
|
||||||
|
let mut seed = [0u8; 32];
|
||||||
|
seed.copy_from_slice(&seed_vec[..32]);
|
||||||
|
let mut rng = ChaCha20Rng::from_seed(seed);
|
||||||
|
let value = match rand.destination_type() {
|
||||||
|
LiteralType::Address => Value::Address(rng.gen()),
|
||||||
|
LiteralType::Boolean => Value::Bool(rng.gen()),
|
||||||
|
LiteralType::Field => Value::Field(rng.gen()),
|
||||||
|
LiteralType::Group => Value::Group(rng.gen()),
|
||||||
|
LiteralType::I8 => Value::I8(rng.gen()),
|
||||||
|
LiteralType::I16 => Value::I16(rng.gen()),
|
||||||
|
LiteralType::I32 => Value::I32(rng.gen()),
|
||||||
|
LiteralType::I64 => Value::I64(rng.gen()),
|
||||||
|
LiteralType::I128 => Value::I128(rng.gen()),
|
||||||
|
LiteralType::U8 => Value::U8(rng.gen()),
|
||||||
|
LiteralType::U16 => Value::U16(rng.gen()),
|
||||||
|
LiteralType::U32 => Value::U32(rng.gen()),
|
||||||
|
LiteralType::U64 => Value::U64(rng.gen()),
|
||||||
|
LiteralType::U128 => Value::U128(rng.gen()),
|
||||||
|
LiteralType::Scalar => Value::Scalar(rng.gen()),
|
||||||
|
LiteralType::Signature => halt_no_span!("Cannot create a random signature"),
|
||||||
|
LiteralType::String => halt_no_span!("Cannot create a random string"),
|
||||||
|
};
|
||||||
|
self.increment_instruction_index();
|
||||||
|
(value, rand.destination().clone())
|
||||||
}
|
}
|
||||||
Contains(_) => todo!(),
|
|
||||||
Get(_) => todo!(),
|
|
||||||
GetOrUse(_) => todo!(),
|
|
||||||
RandChaCha(_) => todo!(),
|
|
||||||
Remove(_) => todo!(),
|
|
||||||
Set(_) => todo!(),
|
|
||||||
BranchEq(branch_eq) => {
|
BranchEq(branch_eq) => {
|
||||||
let first = self.operand_value(branch_eq.first());
|
let first = self.operand_value(branch_eq.first());
|
||||||
let second = self.operand_value(branch_eq.second());
|
let second = self.operand_value(branch_eq.second());
|
||||||
@ -765,6 +877,7 @@ impl Cursor<'_> {
|
|||||||
} else {
|
} else {
|
||||||
self.increment_instruction_index();
|
self.increment_instruction_index();
|
||||||
}
|
}
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
BranchNeq(branch_neq) => {
|
BranchNeq(branch_neq) => {
|
||||||
let first = self.operand_value(branch_neq.first());
|
let first = self.operand_value(branch_neq.first());
|
||||||
@ -774,9 +887,13 @@ impl Cursor<'_> {
|
|||||||
} else {
|
} else {
|
||||||
self.increment_instruction_index();
|
self.increment_instruction_index();
|
||||||
}
|
}
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
Position(_) => {}
|
Position(_) => return Ok(()),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
self.set_register(destination, value);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user