Skip to content

Commit

Permalink
implement infrastructure for softfork extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
arvidn committed Apr 24, 2023
1 parent efb41cf commit 3a245a6
Show file tree
Hide file tree
Showing 8 changed files with 384 additions and 93 deletions.
7 changes: 7 additions & 0 deletions src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ impl Allocator {
}

pub fn restore_checkpoint(&mut self, cp: &Checkpoint) {
// if any of these asserts fire, it means we're trying to restore to
// a state that has already been "long-jumped" passed (via another
// restore to an earler state). You can only restore backwards in time,
// not forwards.
assert!(self.u8_vec.len() >= cp.u8s);
assert!(self.pair_vec.len() >= cp.pairs);
assert!(self.atom_vec.len() >= cp.atoms);
self.u8_vec.truncate(cp.u8s);
self.pair_vec.truncate(cp.pairs);
self.atom_vec.truncate(cp.atoms);
Expand Down
31 changes: 22 additions & 9 deletions src/chia_dialect.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::allocator::{Allocator, NodePtr};
use crate::core_ops::{op_cons, op_eq, op_first, op_if, op_listp, op_raise, op_rest};
use crate::cost::Cost;
use crate::dialect::Dialect;
use crate::dialect::{Dialect, Extension};
use crate::err_utils::err;
use crate::more_ops::{
op_add, op_all, op_any, op_ash, op_concat, op_div, op_divmod, op_gr, op_gr_bytes, op_logand,
op_logior, op_lognot, op_logxor, op_lsh, op_multiply, op_not, op_point_add, op_pubkey_for_exp,
op_sha256, op_softfork, op_strlen, op_substr, op_subtract, op_unknown,
op_sha256, op_strlen, op_substr, op_subtract, op_unknown,
};
use crate::reduction::Response;

Expand Down Expand Up @@ -56,12 +56,15 @@ impl Dialect for ChiaDialect {
o: NodePtr,
argument_list: NodePtr,
max_cost: Cost,
_extensions: Extension,
) -> Response {
let b = &allocator.atom(o);
if b.len() != 1 {
return unknown_operator(allocator, o, argument_list, self.flags, max_cost);
}
let f = match b[0] {
// 1 = quote
// 2 = apply
3 => op_if,
4 => op_cons,
5 => op_first,
Expand Down Expand Up @@ -95,14 +98,9 @@ impl Dialect for ChiaDialect {
33 => op_any,
34 => op_all,
// 35 ---
36 => {
if (self.flags & NO_UNKNOWN_OPS) != 0 {
return err(o, "no softfork implemented");
} else {
op_softfork
}
}
// 36 = softfork
_ => {
// new extension opcodes go here
return unknown_operator(allocator, o, argument_list, self.flags, max_cost);
}
};
Expand All @@ -117,11 +115,26 @@ impl Dialect for ChiaDialect {
&[2]
}

fn softfork_kw(&self) -> &[u8] {
&[36]
}

fn softfork_extension(&self, ext: u32) -> Extension {
match ext {
// new extensions go here
_ => Extension::None,
}
}

fn stack_limit(&self) -> usize {
if (self.flags & LIMIT_STACK) != 0 {
20000000
} else {
usize::MAX
}
}

fn allow_unknown_ops(&self) -> bool {
(self.flags & NO_UNKNOWN_OPS) == 0
}
}
19 changes: 17 additions & 2 deletions src/dialect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,25 @@ use crate::allocator::{Allocator, NodePtr};
use crate::cost::Cost;
use crate::reduction::Response;

#[repr(u32)]
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum Extension {
None = 0,
}

pub trait Dialect {
fn quote_kw(&self) -> &[u8];
fn apply_kw(&self) -> &[u8];
fn op(&self, allocator: &mut Allocator, op: NodePtr, args: NodePtr, max_cost: Cost)
-> Response;
fn softfork_kw(&self) -> &[u8];
fn softfork_extension(&self, ext: u32) -> Extension;
fn op(
&self,
allocator: &mut Allocator,
op: NodePtr,
args: NodePtr,
max_cost: Cost,
extensions: Extension,
) -> Response;
fn stack_limit(&self) -> usize;
fn allow_unknown_ops(&self) -> bool;
}
5 changes: 2 additions & 3 deletions src/f_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::cost::Cost;
use crate::more_ops::{
op_add, op_all, op_any, op_ash, op_concat, op_div, op_divmod, op_gr, op_gr_bytes, op_logand,
op_logior, op_lognot, op_logxor, op_lsh, op_multiply, op_not, op_point_add, op_pubkey_for_exp,
op_sha256, op_softfork, op_strlen, op_substr, op_subtract,
op_sha256, op_strlen, op_substr, op_subtract,
};
use crate::reduction::Response;

Expand All @@ -15,7 +15,7 @@ type OpFn = fn(&mut Allocator, NodePtr, Cost) -> Response;
pub type FLookup = [Option<OpFn>; 256];

pub fn opcode_by_name(name: &str) -> Option<OpFn> {
let opcode_lookup: [(OpFn, &str); 30] = [
let opcode_lookup: [(OpFn, &str); 29] = [
(op_if, "op_if"),
(op_cons, "op_cons"),
(op_first, "op_first"),
Expand Down Expand Up @@ -44,7 +44,6 @@ pub fn opcode_by_name(name: &str) -> Option<OpFn> {
(op_not, "op_not"),
(op_any, "op_any"),
(op_all, "op_all"),
(op_softfork, "op_softfork"),
(op_div, "op_div"),
];
let name: &[u8] = name.as_ref();
Expand Down
19 changes: 1 addition & 18 deletions src/more_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::err_utils::err;
use crate::node::Node;
use crate::number::{number_from_u8, ptr_from_number, Number};
use crate::op_utils::{
arg_count, atom, check_arg_count, i32_atom, int_atom, two_ints, u32_from_u8, uint_atom,
arg_count, atom, check_arg_count, i32_atom, int_atom, two_ints, u32_from_u8,
};
use crate::reduction::{Reduction, Response};
use crate::sha2::{Digest, Sha256};
Expand Down Expand Up @@ -786,23 +786,6 @@ pub fn op_all(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
Ok(Reduction(cost, total.node))
}

pub fn op_softfork(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
let args = Node::new(a, input);
match args.pair() {
Some((p1, _)) => {
let cost = uint_atom::<8>(&p1, "softfork")?;
if cost > max_cost {
return args.err("cost exceeded");
}
if cost == 0 {
return args.err("cost must be > 0");
}
Ok(Reduction(cost, args.null().node))
}
_ => args.err("softfork takes at least 1 argument"),
}
}

lazy_static! {
static ref GROUP_ORDER: Number = {
let order_as_bytes = &[
Expand Down
Loading

0 comments on commit 3a245a6

Please sign in to comment.