Skip to content

Commit

Permalink
Merge pull request #282 from Chia-Network/move-lazy-node
Browse files Browse the repository at this point in the history
move LazyNode python binding into chia-protocol
  • Loading branch information
arvidn committed Oct 19, 2023
2 parents c6d1dfc + 42bd24c commit 5079e29
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 51 deletions.
52 changes: 52 additions & 0 deletions chia-protocol/src/lazy_node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use clvmr::{allocator::NodePtr, allocator::SExp, Allocator};
use pyo3::prelude::*;
use pyo3::types::{PyBytes, PyTuple};
use std::rc::Rc;

#[pyclass(subclass, unsendable, frozen)]
#[derive(Clone)]
pub struct LazyNode {
allocator: Rc<Allocator>,
node: NodePtr,
}

impl ToPyObject for LazyNode {
fn to_object(&self, py: Python<'_>) -> PyObject {
let node: &PyCell<LazyNode> = PyCell::new(py, self.clone()).unwrap();
let pa: &PyAny = node;
pa.to_object(py)
}
}

#[pymethods]
impl LazyNode {
#[getter(pair)]
pub fn pair(&self, py: Python) -> PyResult<Option<PyObject>> {
match &self.allocator.sexp(self.node) {
SExp::Pair(p1, p2) => {
let r1 = Self::new(self.allocator.clone(), *p1);
let r2 = Self::new(self.allocator.clone(), *p2);
let v: &PyTuple = PyTuple::new(py, &[r1, r2]);
Ok(Some(v.into()))
}
_ => Ok(None),
}
}

#[getter(atom)]
pub fn atom(&self, py: Python) -> Option<PyObject> {
match &self.allocator.sexp(self.node) {
SExp::Atom => Some(PyBytes::new(py, self.allocator.atom(self.node)).into()),
_ => None,
}
}
}

impl LazyNode {
pub const fn new(a: Rc<Allocator>, n: NodePtr) -> Self {
Self {
allocator: a,
node: n,
}
}
}
6 changes: 6 additions & 0 deletions chia-protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ pub mod vdf;
pub mod wallet_protocol;
pub mod weight_proof;

#[cfg(feature = "py-bindings")]
pub mod lazy_node;

// export shorter names
pub use crate::bytes::*;
pub use crate::chia_protocol::*;
Expand All @@ -41,3 +44,6 @@ pub use crate::spend_bundle::*;
pub use crate::vdf::*;
pub use crate::wallet_protocol::*;
pub use crate::weight_proof::*;

#[cfg(feature = "py-bindings")]
pub use crate::lazy_node::*;
2 changes: 1 addition & 1 deletion wheel/generate_type_stubs.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def parse_rust_source(filename: str) -> List[Tuple[str, List[str]]]:

classes = []
for f in sorted(glob(str(input_dir / "*.rs"))):
if f.endswith("bytes.rs"):
if f.endswith("bytes.rs") or f.endswith("lazy_node.rs"):
continue
classes.extend(parse_rust_source(f))

Expand Down
51 changes: 1 addition & 50 deletions wheel/src/run_program.rs
Original file line number Diff line number Diff line change
@@ -1,65 +1,16 @@
use super::adapt_response::eval_err_to_pyresult;
use chia::allocator::make_allocator;
use chia::gen::flags::ALLOW_BACKREFS;
use clvmr::allocator::{Allocator, NodePtr, SExp};
use chia_protocol::LazyNode;
use clvmr::chia_dialect::ChiaDialect;
use clvmr::cost::Cost;
use clvmr::reduction::Response;
use clvmr::run_program::run_program;
use clvmr::serde::{node_from_bytes, node_from_bytes_backrefs, serialized_length_from_bytes};
use pyo3::buffer::PyBuffer;
use pyo3::prelude::*;
use pyo3::types::{PyBytes, PyTuple};
use std::rc::Rc;

#[pyclass(subclass, unsendable, frozen)]
#[derive(Clone)]
pub struct LazyNode {
allocator: Rc<Allocator>,
node: NodePtr,
}

impl ToPyObject for LazyNode {
fn to_object(&self, py: Python<'_>) -> PyObject {
let node: &PyCell<LazyNode> = PyCell::new(py, self.clone()).unwrap();
let pa: &PyAny = node;
pa.to_object(py)
}
}

#[pymethods]
impl LazyNode {
#[getter(pair)]
pub fn pair(&self, py: Python) -> PyResult<Option<PyObject>> {
match &self.allocator.sexp(self.node) {
SExp::Pair(p1, p2) => {
let r1 = Self::new(self.allocator.clone(), *p1);
let r2 = Self::new(self.allocator.clone(), *p2);
let v: &PyTuple = PyTuple::new(py, &[r1, r2]);
Ok(Some(v.into()))
}
_ => Ok(None),
}
}

#[getter(atom)]
pub fn atom(&self, py: Python) -> Option<PyObject> {
match &self.allocator.sexp(self.node) {
SExp::Atom => Some(PyBytes::new(py, self.allocator.atom(self.node)).into()),
_ => None,
}
}
}

impl LazyNode {
pub const fn new(a: Rc<Allocator>, n: NodePtr) -> Self {
Self {
allocator: a,
node: n,
}
}
}

#[allow(clippy::borrow_deref_ref)]
#[pyfunction]
pub fn serialized_length(program: PyBuffer<u8>) -> PyResult<u64> {
Expand Down

0 comments on commit 5079e29

Please sign in to comment.