Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to #[classmethod] for SpendBundle::py_aggregate #678

Merged
merged 33 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a4740e8
switch to classmethod for py_aggregate
matt-o-how Aug 26, 2024
d1f02d3
import under cfg feature
matt-o-how Aug 26, 2024
6a7ee09
update stubs
matt-o-how Aug 26, 2024
5985332
add test for derived class returning correctly
matt-o-how Aug 26, 2024
8644b38
change pystreamable macro to use classmethods instead of staticmethods
matt-o-how Aug 27, 2024
7c85ba1
fmt and clippy
matt-o-how Aug 27, 2024
1ab56bf
fix line ending format
matt-o-how Aug 27, 2024
c602f5c
black test
matt-o-how Aug 27, 2024
6c2a324
add tests for the streamable macro functions
matt-o-how Aug 29, 2024
7185a6b
fix tests to actually test what we're expecting
matt-o-how Aug 29, 2024
cfe8665
fix aggregate
matt-o-how Aug 30, 2024
eaa227b
nonworking commit for arvid
matt-o-how Sep 3, 2024
91205ae
fixup
arvidn Sep 3, 2024
5f0bab7
add downcasting step to streamable classmethods that support it
matt-o-how Sep 5, 2024
c256de6
fix tests and remove duplicate imports
matt-o-how Sep 5, 2024
b058c2d
add from_parent for OwnedSpendConditions and OwnedSpendBundleConditions
matt-o-how Sep 6, 2024
2723e1f
fmt
matt-o-how Sep 6, 2024
34ab0f9
fix stubs and use ?
matt-o-how Sep 9, 2024
58bf3ed
pushing broken optional skip to work from laptop
matt-o-how Sep 10, 2024
26bed89
fix
matt-o-how Sep 10, 2024
773be19
update all remaining streamable macros to use check and skip
matt-o-how Sep 10, 2024
6ba0981
update stubs to reflect new Streamable
matt-o-how Sep 10, 2024
dbef1e9
use py as paramter instead of calling with_gil()
matt-o-how Sep 10, 2024
71933f9
Add NotImplemented error for unsupported from_parent() calls
matt-o-how Sep 10, 2024
7f82ad3
re-enable from_parent in SpendBundle
matt-o-how Sep 11, 2024
89888cf
make error messages struct specific
matt-o-how Sep 12, 2024
763c1a7
fmt
matt-o-how Sep 13, 2024
423d41d
fix if statement for from_parent skip
matt-o-how Sep 13, 2024
b62d9d4
clippy fixes
matt-o-how Sep 13, 2024
ef7ecbe
add from_parent skip to aggregate()
matt-o-how Sep 13, 2024
f316c7e
clippy fix
matt-o-how Sep 13, 2024
2448708
Remove final with_gil()
matt-o-how Sep 16, 2024
2ebcd94
fmt
matt-o-how Sep 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion crates/chia-bls/src/gtelement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ use blst::*;
use chia_traits::chia_error::Result;
use chia_traits::{read_bytes, Streamable};
use clvmr::sha2::Sha256;
#[cfg(feature = "py-bindings")]
use pyo3::exceptions::PyNotImplementedError;
#[cfg(feature = "py-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "py-bindings")]
use pyo3::types::PyType;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::io::Cursor;
Expand Down Expand Up @@ -112,6 +118,14 @@ impl GTElement {
hex::encode(self.to_bytes())
}

#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(_cls: &Bound<'_, PyType>, _instance: &Self) -> PyResult<PyObject> {
Err(PyNotImplementedError::new_err(
"GTElement does not support from_parent().",
))
}

#[must_use]
pub fn __mul__(&self, rhs: &Self) -> Self {
let mut ret = self.clone();
Expand All @@ -130,7 +144,6 @@ mod pybindings {

use crate::parse_hex::parse_hex_string;
use chia_traits::{FromJsonDict, ToJsonDict};
use pyo3::prelude::*;

impl ToJsonDict for GTElement {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
Expand Down
25 changes: 22 additions & 3 deletions crates/chia-bls/src/public_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ use crate::{DerivableKey, Error, Result};
use blst::*;
use chia_traits::{read_bytes, Streamable};
use clvmr::sha2::Sha256;
#[cfg(feature = "py-bindings")]
use pyo3::exceptions::PyNotImplementedError;
#[cfg(feature = "py-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "py-bindings")]
use pyo3::types::PyType;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::io::Cursor;
Expand Down Expand Up @@ -321,6 +327,14 @@ impl PublicKey {
other.pair(self)
}

#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(_cls: &Bound<'_, PyType>, _instance: &Self) -> PyResult<PyObject> {
Err(PyNotImplementedError::new_err(
"PublicKey does not support from_parent().",
))
}

#[pyo3(name = "get_fingerprint")]
pub fn py_get_fingerprint(&self) -> u32 {
self.get_fingerprint()
Expand Down Expand Up @@ -353,7 +367,6 @@ mod pybindings {
use crate::parse_hex::parse_hex_string;

use chia_traits::{FromJsonDict, ToJsonDict};
use pyo3::prelude::*;

impl ToJsonDict for PublicKey {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
Expand Down Expand Up @@ -737,7 +750,11 @@ mod pytests {
let pk = sk.public_key();
Python::with_gil(|py| {
let string = pk.to_json_dict(py).expect("to_json_dict");
let pk2 = PublicKey::from_json_dict(string.bind(py)).unwrap();
let py_class = py.get_type_bound::<PublicKey>();
let pk2: PublicKey = PublicKey::from_json_dict(&py_class, py, string.bind(py))
.unwrap()
.extract(py)
.unwrap();
assert_eq!(pk, pk2);
});
}
Expand All @@ -752,8 +769,10 @@ mod pytests {
fn test_json_dict(#[case] input: &str, #[case] msg: &str) {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let py_class = py.get_type_bound::<PublicKey>();
let err =
PublicKey::from_json_dict(input.to_string().into_py(py).bind(py)).unwrap_err();
PublicKey::from_json_dict(&py_class, py, input.to_string().into_py(py).bind(py))
.unwrap_err();
assert_eq!(err.value_bound(py).to_string(), msg.to_string());
});
}
Expand Down
25 changes: 22 additions & 3 deletions crates/chia-bls/src/secret_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ use blst::*;
use chia_traits::{read_bytes, Streamable};
use clvmr::sha2::Sha256;
use hkdf::HkdfExtract;
#[cfg(feature = "py-bindings")]
use pyo3::exceptions::PyNotImplementedError;
#[cfg(feature = "py-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "py-bindings")]
use pyo3::types::PyType;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::io::Cursor;
Expand Down Expand Up @@ -266,6 +272,14 @@ impl SecretKey {
hex::encode(self.to_bytes())
}

#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(_cls: &Bound<'_, PyType>, _instance: &Self) -> PyResult<PyObject> {
Err(PyNotImplementedError::new_err(
"SecretKey does not support from_parent().",
))
}

#[pyo3(name = "derive_hardened")]
#[must_use]
pub fn py_derive_hardened(&self, idx: u32) -> Self {
Expand All @@ -292,7 +306,6 @@ mod pybindings {
use crate::parse_hex::parse_hex_string;

use chia_traits::{FromJsonDict, ToJsonDict};
use pyo3::prelude::*;

impl ToJsonDict for SecretKey {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
Expand Down Expand Up @@ -557,7 +570,11 @@ mod pytests {
let sk = SecretKey::from_seed(&data);
Python::with_gil(|py| {
let string = sk.to_json_dict(py).expect("to_json_dict");
let sk2 = SecretKey::from_json_dict(string.bind(py)).unwrap();
let py_class = py.get_type_bound::<SecretKey>();
let sk2 = SecretKey::from_json_dict(&py_class, py, string.bind(py))
.unwrap()
.extract(py)
.unwrap();
assert_eq!(sk, sk2);
assert_eq!(sk.public_key(), sk2.public_key());
});
Expand Down Expand Up @@ -588,8 +605,10 @@ mod pytests {
fn test_json_dict(#[case] input: &str, #[case] msg: &str) {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let py_class = py.get_type_bound::<SecretKey>();
let err =
SecretKey::from_json_dict(input.to_string().into_py(py).bind(py)).unwrap_err();
SecretKey::from_json_dict(&py_class, py, input.to_string().into_py(py).bind(py))
.unwrap_err();
assert_eq!(err.value_bound(py).to_string(), msg.to_string());
});
}
Expand Down
25 changes: 22 additions & 3 deletions crates/chia-bls/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ use crate::{Error, GTElement, PublicKey, Result, SecretKey};
use blst::*;
use chia_traits::{read_bytes, Streamable};
use clvmr::sha2::Sha256;
#[cfg(feature = "py-bindings")]
use pyo3::exceptions::PyNotImplementedError;
#[cfg(feature = "py-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "py-bindings")]
use pyo3::types::PyType;
use std::borrow::Borrow;
use std::fmt;
use std::hash::{Hash, Hasher};
Expand Down Expand Up @@ -486,6 +492,14 @@ impl Signature {
Self::default()
}

#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(_cls: &Bound<'_, PyType>, _instance: &Self) -> PyResult<PyObject> {
Err(PyNotImplementedError::new_err(
"Signature does not support from_parent().",
))
}

#[pyo3(name = "pair")]
pub fn py_pair(&self, other: &PublicKey) -> GTElement {
self.pair(other)
Expand Down Expand Up @@ -518,7 +532,6 @@ mod pybindings {
use crate::parse_hex::parse_hex_string;

use chia_traits::{FromJsonDict, ToJsonDict};
use pyo3::prelude::*;

impl ToJsonDict for Signature {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
Expand Down Expand Up @@ -1259,7 +1272,11 @@ mod pytests {
let sig = sign(&sk, msg);
Python::with_gil(|py| {
let string = sig.to_json_dict(py).expect("to_json_dict");
let sig2 = Signature::from_json_dict(string.bind(py)).unwrap();
let py_class = py.get_type_bound::<Signature>();
let sig2 = Signature::from_json_dict(&py_class, py, string.bind(py))
.unwrap()
.extract(py)
.unwrap();
assert_eq!(sig, sig2);
});
}
Expand All @@ -1274,8 +1291,10 @@ mod pytests {
fn test_json_dict(#[case] input: &str, #[case] msg: &str) {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let py_class = py.get_type_bound::<Signature>();
let err =
Signature::from_json_dict(input.to_string().into_py(py).bind(py)).unwrap_err();
Signature::from_json_dict(&py_class, py, input.to_string().into_py(py).bind(py))
.unwrap_err();
assert_eq!(err.value_bound(py).to_string(), msg.to_string());
});
}
Expand Down
31 changes: 31 additions & 0 deletions crates/chia-consensus/src/gen/owned_conditions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ use super::conditions::{SpendBundleConditions, SpendConditions};
#[cfg(feature = "py-bindings")]
use chia_py_streamable_macro::{PyJsonDict, PyStreamable};

#[cfg(feature = "py-bindings")]
use pyo3::exceptions::PyNotImplementedError;
#[cfg(feature = "py-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "py-bindings")]
use pyo3::types::PyType;

#[derive(Streamable, Hash, Debug, Clone, Eq, PartialEq)]
#[cfg_attr(
feature = "py-bindings",
Expand Down Expand Up @@ -144,3 +151,27 @@ fn convert_agg_sigs(a: &Allocator, agg_sigs: &[(PublicKey, NodePtr)]) -> Vec<(Pu
}
ret
}

#[cfg(feature = "py-bindings")]
#[pymethods]
impl OwnedSpendConditions {
#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(_cls: &Bound<'_, PyType>, _instance: &Self) -> PyResult<PyObject> {
Err(PyNotImplementedError::new_err(
"OwnedSpendConditions does not support from_parent().",
))
}
}

#[cfg(feature = "py-bindings")]
#[pymethods]
impl OwnedSpendBundleConditions {
#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(_cls: &Bound<'_, PyType>, _instance: &Self) -> PyResult<PyObject> {
Err(PyNotImplementedError::new_err(
"OwnedSpendBundleConditions does not support from_parent().",
))
}
}
16 changes: 16 additions & 0 deletions crates/chia-protocol/src/coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ use clvm_traits::{
};
use clvmr::sha2::Sha256;

#[cfg(feature = "py-bindings")]
use pyo3::exceptions::PyNotImplementedError;
#[cfg(feature = "py-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "py-bindings")]
use pyo3::types::PyType;

#[streamable]
#[derive(Copy)]
Expand Down Expand Up @@ -55,6 +59,18 @@ impl Coin {
}
}

#[cfg(feature = "py-bindings")]
#[pymethods]
impl Coin {
#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(_cls: &Bound<'_, PyType>, _coin: Self) -> PyResult<PyObject> {
Err(PyNotImplementedError::new_err(
"Coin does not support from_parent().",
))
}
}

impl<N, E: ClvmEncoder<Node = N>> ToClvm<E> for Coin {
fn to_clvm(&self, encoder: &mut E) -> Result<N, ToClvmError> {
clvm_list!(self.parent_coin_info, self.puzzle_hash, self.amount).to_clvm(encoder)
Expand Down
17 changes: 17 additions & 0 deletions crates/chia-protocol/src/coin_spend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,27 @@ use chia_streamable_macro::streamable;

use crate::coin::Coin;
use crate::program::Program;
#[cfg(feature = "py-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "py-bindings")]
use pyo3::types::PyType;

#[streamable]
pub struct CoinSpend {
coin: Coin,
puzzle_reveal: Program,
solution: Program,
}

#[cfg(feature = "py-bindings")]
#[pymethods]
impl CoinSpend {
#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(cls: &Bound<'_, PyType>, py: Python<'_>, cs: Self) -> PyResult<PyObject> {
// Convert result into potential child class
let instance = cls.call1((cs.coin, cs.puzzle_reveal, cs.solution))?;

Ok(instance.into_py(py))
}
}
19 changes: 16 additions & 3 deletions crates/chia-protocol/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ use clvmr::serde::{
};
use clvmr::sha2::Sha256;
use clvmr::{Allocator, ChiaDialect};
#[cfg(feature = "py-bindings")]
use pyo3::prelude::*;
#[cfg(feature = "py-bindings")]
use pyo3::types::PyType;
use std::io::Cursor;
use std::ops::Deref;

Expand Down Expand Up @@ -152,9 +156,6 @@ use chia_traits::{FromJsonDict, ToJsonDict};
#[cfg(feature = "py-bindings")]
use chia_py_streamable_macro::PyStreamable;

#[cfg(feature = "py-bindings")]
use pyo3::prelude::*;

#[cfg(feature = "py-bindings")]
use pyo3::types::{PyList, PyTuple};

Expand Down Expand Up @@ -486,6 +487,18 @@ impl ToJsonDict for Program {
}
}

#[cfg(feature = "py-bindings")]
#[pymethods]
impl Program {
#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(_cls: &Bound<'_, PyType>, _instance: &Self) -> PyResult<PyObject> {
Err(PyNotImplementedError::new_err(
"This class does not support from_parent().",
))
}
}

#[cfg(feature = "py-bindings")]
impl FromJsonDict for Program {
fn from_json_dict(o: &Bound<'_, PyAny>) -> PyResult<Self> {
Expand Down
Loading
Loading