Skip to content

Commit

Permalink
TicketItem for Stack and instruction skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
matsakiv committed Jul 25, 2023
1 parent 46179e2 commit 09a0644
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ bin
target
tezos_kernel/target
boot_kernel/target
.env
.env
.bin
local.env
5 changes: 5 additions & 0 deletions michelson_vm/src/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ impl Formatter for Instruction {
Instruction::Blake2B(_) => "Blake2B".into(),
Instruction::HashKey(_) => "HashKey".into(),
Instruction::CheckSignature(_) => "CheckSignature".into(),
Instruction::Ticket(_) => "Ticket".into(),
Instruction::ReadTicket(_) => "ReadTicket".into(),
Instruction::SplitTicket(_) => "SplitTicket".into(),
Instruction::JoinTickets(_) => "JoinTicket".into(),
_ => format!("{:?}", self),
}
}
Expand Down Expand Up @@ -166,6 +170,7 @@ impl Formatter for Type {
Type::Operation(_) => "operation".into(),
Type::Parameter(ty) => format!("(parameter {})", ty.r#type.format()),
Type::Storage(ty) => format!("(storage {})", ty.r#type.format()),
Type::Ticket(ty) => format!("(ticket {})", ty.r#type.format()),
ty => format!("{:?}", ty),
}
}
Expand Down
1 change: 1 addition & 0 deletions michelson_vm/src/instructions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ mod lambda;
mod math;
mod scope;
mod stack;
mod tickets;
89 changes: 89 additions & 0 deletions michelson_vm/src/instructions/tickets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// SPDX-FileCopyrightText: 2023 Baking Bad <[email protected]>
//
// SPDX-License-Identifier: MIT

use tezos_michelson::michelson::data::instructions::{
Ticket, ReadTicket, SplitTicket, JoinTickets,
};

use crate::{
err_mismatch,
interpreter::{
ContextInterpreter, InterpreterContext, PureInterpreter,
},
//pop_cast,
stack::Stack,
Result, types::{AddressItem, NatItem, StackItem, TicketItem, PairItem, OptionItem},
};

impl ContextInterpreter for Ticket {
fn execute(&self, stack: &mut Stack, context: &mut impl InterpreterContext) -> Result<()> {
let identifier = stack.pop()?;
let amount = stack.pop()?;

// TODO: compare amount with zero
// TODO: convert StackItem identifier to Micheline
// TODO: get Type for identifier
// TODO: get self address
// TODO: save balance info to context?

//stack.push(StackItem::Ticket(TicketItem::new()));
Ok(())
}
}

impl PureInterpreter for ReadTicket {
fn execute(&self, stack: &mut Stack) -> Result<()> {
let ticket_item = stack.pop()?;
let ticket = match ticket_item {
StackItem::Ticket(ticket) => ticket,
item => return err_mismatch!("Ticket", item)
};

let source = StackItem::Address(AddressItem::new(ticket.source));
let identifier = ticket.identifier; // TODO: identifier to StackItem
let amount = StackItem::Nat(NatItem::new(ticket.amount));

let pair = PairItem::from_items(vec![source, identifier, amount])?;

stack.push(StackItem::Pair(pair));
stack.push(ticket_item); // return ticket back to stack
Ok(())
}
}

impl ContextInterpreter for SplitTicket {
fn execute(&self, stack: &mut Stack, context: &mut impl InterpreterContext) -> Result<()> {
let ticket = stack.pop()?; // ticket
let split_pair = stack.pop()?; // pair nat nat

// TODO: if n + m != ticket.amount or n == 0 or m == 0 return none
stack.push(StackItem::Option(OptionItem::None()));

// TODO: else return pair (ticket_n, ticket_m)
stack.push(StackItem::Option(OptionItem::Some()));

// TODO: update balance in context?

Ok(())
}
}

impl ContextInterpreter for JoinTickets {
fn execute(&self, stack: &mut Stack, context: &mut impl InterpreterContext) -> Result<()> {
let tickets = stack.pop()?; // tickets pair
// TODO: get ticket_a
// TODO: get ticket_b
// TODO: compare sources and identifiers (and identifiers types?)

// TODO: if ticket_a.source != ticket_b.source or ticket_a.identifier != ticket_b.identifier
stack.push(StackItem::Option(OptionItem::None()));

// TODO: OR otherwise return Some(ticket)
stack.push(StackItem::Option(OptionItem::Some()));

// TODO: update balance in context?

Ok(())
}
}
1 change: 1 addition & 0 deletions michelson_vm/src/typechecker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ impl StackItem {
StackItem::Operation(_) => Ok(types::operation()),
StackItem::Lambda(item) => item.get_type(),
StackItem::Contract(item) => Ok(item.get_type()),
StackItem::Ticket(item) => item.get_type(),
}
}

Expand Down
11 changes: 11 additions & 0 deletions michelson_vm/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub mod or;
pub mod pair;
pub mod set;
pub mod timestamp;
pub mod ticket;

use derive_more::{Display, From, TryInto};
use ibig::{IBig, UBig};
Expand Down Expand Up @@ -100,6 +101,7 @@ not_comparable!(LambdaItem);
not_comparable!(ContractItem);
not_comparable!(BigMapItem);
not_comparable!(OperationItem);
not_comparable!(TicketItem);

#[derive(Debug, Clone, PartialEq)]
pub enum InternalContent {
Expand Down Expand Up @@ -157,6 +159,14 @@ pub enum BigMapItem {
Ptr(i64),
}

#[derive(Debug, Clone, PartialEq)]
pub struct TicketItem {
pub source: Address,
pub identifier: Micheline,
pub identifier_type: Type,
pub amount: UBig,
}

#[derive(Debug, Display, Clone, From, TryInto, PartialEq, PartialOrd, Eq, Ord)]
pub enum StackItem {
Unit(UnitItem),
Expand All @@ -182,6 +192,7 @@ pub enum StackItem {
Map(MapItem),
BigMap(BigMapItem),
Lambda(LambdaItem),
Ticket(TicketItem),
}

impl AsMut<StackItem> for StackItem {
Expand Down
4 changes: 4 additions & 0 deletions michelson_vm/src/types/nat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ use crate::{
};

impl NatItem {
pub fn new(nat: UBig) -> Self {
Self(nat)
}

pub fn from_data(data: Data) -> Result<StackItem> {
let val: UBig = match data {
Data::Int(val) => val.try_into()?,
Expand Down
36 changes: 36 additions & 0 deletions michelson_vm/src/types/ticket.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-FileCopyrightText: 2023 Baking Bad <[email protected]>
//
// SPDX-License-Identifier: MIT

use std::fmt::Display;

use ibig::UBig;
use tezos_core::types::encoded::Address;
use tezos_michelson::{michelson::types::{self, Type}, micheline::Micheline};

use crate::{
types::TicketItem,
Result,
};

impl TicketItem {
pub fn new(source: Address, identifier: Micheline, identifier_type: Type, amount: UBig) -> Self{
Self {
source,
identifier,
identifier_type,
amount,
}
}

pub fn get_type(&self) -> Result<Type> {
Ok(types::ticket(self.identifier_type.clone()))
}

}

impl Display for TicketItem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("({:?} {:?} {})", self.source, self.identifier, self.amount))
}
}

0 comments on commit 09a0644

Please sign in to comment.