Эх сурвалжийг харах

[src/sdk/python] upgrade pyo3 to 0.22.6

zerin 1 жил өмнө
parent
commit
adc9078c70

+ 13 - 13
Cargo.lock

@@ -1,6 +1,6 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
+version = 4
 
 [[package]]
 name = "addr2line"
@@ -5424,15 +5424,15 @@ dependencies = [
 
 [[package]]
 name = "pyo3"
-version = "0.21.2"
+version = "0.22.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8"
+checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
 dependencies = [
  "cfg-if 1.0.0",
  "indoc",
  "libc",
  "memoffset",
- "parking_lot 0.12.3",
+ "once_cell",
  "portable-atomic",
  "pyo3-build-config",
  "pyo3-ffi",
@@ -5442,9 +5442,9 @@ dependencies = [
 
 [[package]]
 name = "pyo3-build-config"
-version = "0.21.2"
+version = "0.22.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50"
+checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
 dependencies = [
  "once_cell",
  "target-lexicon",
@@ -5452,9 +5452,9 @@ dependencies = [
 
 [[package]]
 name = "pyo3-ffi"
-version = "0.21.2"
+version = "0.22.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403"
+checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
 dependencies = [
  "libc",
  "pyo3-build-config",
@@ -5462,9 +5462,9 @@ dependencies = [
 
 [[package]]
 name = "pyo3-macros"
-version = "0.21.2"
+version = "0.22.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c"
+checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453"
 dependencies = [
  "proc-macro2",
  "pyo3-macros-backend",
@@ -5474,11 +5474,11 @@ dependencies = [
 
 [[package]]
 name = "pyo3-macros-backend"
-version = "0.21.2"
+version = "0.22.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c"
+checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe"
 dependencies = [
- "heck 0.4.1",
+ "heck 0.5.0",
  "proc-macro2",
  "pyo3-build-config",
  "quote",

+ 1 - 1
src/sdk/python/Cargo.toml

@@ -19,7 +19,7 @@ darkfi-sdk = {path = "../"}
 halo2_proofs = {version = "0.3.0", features = ["dev-graph", "sanity-checks"]}
 halo2_gadgets = "0.3.0"
 plotters = "0.3.7"
-pyo3 = {version = "0.21.2", features = ["gil-refs"]}
+pyo3 = {version = "0.22.6", features = ["gil-refs"]}
 rand = "0.8.5"
 
 [lints]

+ 12 - 9
src/sdk/python/src/crypto.rs

@@ -19,13 +19,16 @@
 use std::ops::Deref;
 
 use darkfi_sdk::{crypto, pasta::pallas};
-use pyo3::{pyfunction, types::PyModule, wrap_pyfunction, PyCell, PyResult, Python};
+use pyo3::{
+    prelude::{PyModule, PyModuleMethods},
+    pyfunction, wrap_pyfunction, Bound, PyResult, Python,
+};
 
 use super::pasta::{Ep, Fp, Fq};
 
 /// Calculate the Poseidon hash of given `Fp` elements.
 #[pyfunction]
-pub fn poseidon_hash(messages: Vec<&PyCell<Fp>>) -> Fp {
+pub fn poseidon_hash(messages: Vec<Bound<Fp>>) -> Fp {
     let messages: Vec<pallas::Base> = messages.iter().map(|x| x.borrow().deref().0).collect();
     match messages.len() {
         1 => Fp(crypto::util::poseidon_hash::<1>(messages.try_into().unwrap())),
@@ -50,13 +53,13 @@ pub fn poseidon_hash(messages: Vec<&PyCell<Fp>>) -> Fp {
 
 /// Calculate a Pedersen commitment with an u64 value.
 #[pyfunction]
-pub fn pedersen_commitment_u64(value: u64, blind: &PyCell<Fq>) -> Ep {
+pub fn pedersen_commitment_u64(value: u64, blind: &Bound<Fq>) -> Ep {
     Ep(crypto::pedersen::pedersen_commitment_u64(value, crypto::Blind(blind.borrow().deref().0)))
 }
 
 /// Calculate a Pedersen commitment with an Fp value.
 #[pyfunction]
-pub fn pedersen_commitment_base(value: &PyCell<Fp>, blind: &PyCell<Fq>) -> Ep {
+pub fn pedersen_commitment_base(value: &Bound<Fp>, blind: &Bound<Fq>) -> Ep {
     Ep(crypto::pedersen::pedersen_commitment_base(
         value.borrow().deref().0,
         crypto::Blind(blind.borrow().deref().0),
@@ -64,10 +67,10 @@ pub fn pedersen_commitment_base(value: &PyCell<Fp>, blind: &PyCell<Fq>) -> Ep {
 }
 
 /// Wrapper function for creating this Python module.
-pub(crate) fn create_module(py: Python<'_>) -> PyResult<&PyModule> {
-    let submod = PyModule::new(py, "crypto")?;
-    submod.add_function(wrap_pyfunction!(poseidon_hash, submod)?)?;
-    submod.add_function(wrap_pyfunction!(pedersen_commitment_u64, submod)?)?;
-    submod.add_function(wrap_pyfunction!(pedersen_commitment_base, submod)?)?;
+pub(crate) fn create_module(py: Python<'_>) -> PyResult<Bound<PyModule>> {
+    let submod = PyModule::new_bound(py, "crypto")?;
+    submod.add_function(wrap_pyfunction!(poseidon_hash, &submod)?)?;
+    submod.add_function(wrap_pyfunction!(pedersen_commitment_u64, &submod)?)?;
+    submod.add_function(wrap_pyfunction!(pedersen_commitment_base, &submod)?)?;
     Ok(submod)
 }

+ 8 - 5
src/sdk/python/src/lib.rs

@@ -29,22 +29,25 @@ mod crypto;
 mod zkas;
 
 #[pyo3::prelude::pymodule]
-fn darkfi_sdk(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> {
+fn darkfi_sdk(
+    py: pyo3::Python<'_>,
+    m: &pyo3::Bound<'_, pyo3::prelude::PyModule>,
+) -> pyo3::PyResult<()> {
     let submodule = pasta::create_module(py)?;
     pyo3::py_run!(py, submodule, "import sys; sys.modules['darkfi_sdk.pasta'] = submodule");
-    m.add_submodule(submodule)?;
+    pyo3::types::PyModuleMethods::add_submodule(m, &submodule)?;
 
     let submodule = merkle::create_module(py)?;
     pyo3::py_run!(py, submodule, "import sys; sys.modules['darkfi_sdk.merkle'] = submodule");
-    m.add_submodule(submodule)?;
+    pyo3::types::PyModuleMethods::add_submodule(m, &submodule)?;
 
     let submodule = crypto::create_module(py)?;
     pyo3::py_run!(py, submodule, "import sys; sys.modules['darkfi_sdk.crypto'] = submodule");
-    m.add_submodule(submodule)?;
+    pyo3::types::PyModuleMethods::add_submodule(m, &submodule)?;
 
     let submodule = zkas::create_module(py)?;
     pyo3::py_run!(py, submodule, "import sys; sys.modules['darkfi_sdk.zkas'] = submodule");
-    m.add_submodule(submodule)?;
+    pyo3::types::PyModuleMethods::add_submodule(m, &submodule)?;
 
     Ok(())
 }

+ 8 - 4
src/sdk/python/src/merkle.rs

@@ -15,10 +15,14 @@
  * You should have received a copy of the GNU Affero General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 use std::ops::Deref;
 
 use darkfi_sdk::crypto::{merkle_node, MerkleNode};
-use pyo3::{pyclass, pymethods, types::PyModule, PyCell, PyResult};
+use pyo3::{
+    prelude::{PyModule, PyModuleMethods},
+    pyclass, pymethods, Bound, PyResult,
+};
 
 use super::pasta::Fp;
 
@@ -33,7 +37,7 @@ impl MerkleTree {
         Self(merkle_node::MerkleTree::new(1))
     }
 
-    fn append(&mut self, node: &PyCell<Fp>) -> PyResult<bool> {
+    fn append(&mut self, node: &Bound<Fp>) -> PyResult<bool> {
         Ok(self.0.append(MerkleNode::from(node.borrow().deref().0)))
     }
 
@@ -53,8 +57,8 @@ impl MerkleTree {
 }
 
 /// Wrapper function for creating this Python module.
-pub(crate) fn create_module(py: pyo3::Python<'_>) -> PyResult<&PyModule> {
-    let submod = PyModule::new(py, "merkle")?;
+pub(crate) fn create_module(py: pyo3::Python<'_>) -> PyResult<Bound<PyModule>> {
+    let submod = PyModule::new_bound(py, "merkle")?;
     submod.add_class::<MerkleTree>()?;
     Ok(submod)
 }

+ 19 - 20
src/sdk/python/src/pasta.rs

@@ -24,8 +24,10 @@ use darkfi_sdk::{
 };
 use halo2_gadgets::ecc::chip::FixedPoint;
 use pyo3::{
-    basic::CompareOp, pyclass, pyfunction, pymethods, types::PyModule, wrap_pyfunction, PyCell,
-    PyResult,
+    basic::CompareOp,
+    pyclass, pyfunction, pymethods,
+    types::{PyAnyMethods, PyModule, PyModuleMethods, PyStringMethods, PyTypeMethods},
+    wrap_pyfunction, Bound, PyResult,
 };
 use rand::rngs::OsRng;
 
@@ -101,9 +103,8 @@ macro_rules! impl_elem {
                 Ok(format!("{:?}", self.0))
             }
 
-            fn __repr__(slf: &PyCell<Self>) -> PyResult<String> {
-                let class_name: &str = &slf.get_type().name()?;
-                Ok(format!("{}({:?})", class_name, slf.borrow().0))
+            fn __repr__(slf: &Bound<Self>) -> PyResult<String> {
+                Ok(format!("{}({:?})", slf.get_type().name()?.to_str()?, slf.borrow().0))
             }
 
             fn __add__(&self, other: &Self) -> Self {
@@ -153,14 +154,14 @@ macro_rules! impl_affine {
             }
 
             #[staticmethod]
-            fn from_xy(x: &PyCell<$base>, y: &PyCell<$base>) -> PyResult<Self> {
+            fn from_xy(x: &Bound<$base>, y: &Bound<$base>) -> PyResult<Self> {
                 let affine_point =
                     <$inner>::from_xy(x.borrow().deref().0, y.borrow().deref().0).unwrap();
                 Ok(Self(affine_point))
             }
 
             #[staticmethod]
-            fn from_projective(x: &PyCell<$projective>) -> Self {
+            fn from_projective(x: &Bound<$projective>) -> Self {
                 Self(<$inner>::from(x.borrow().deref().0))
             }
 
@@ -168,9 +169,8 @@ macro_rules! impl_affine {
                 format!("{:?}", self.0)
             }
 
-            fn __repr__(slf: &PyCell<Self>) -> PyResult<String> {
-                let class_name: &str = &slf.get_type().name()?;
-                Ok(format!("{}({:?})", class_name, slf.borrow().0))
+            fn __repr__(slf: &Bound<Self>) -> PyResult<String> {
+                Ok(format!("{}({:?})", slf.get_type().name()?.to_str()?, slf.borrow().0))
             }
         }
     };
@@ -181,7 +181,7 @@ macro_rules! impl_point {
         #[pymethods]
         impl $x {
             #[new]
-            fn new(x: &PyCell<$base>, y: &PyCell<$base>) -> PyResult<Self> {
+            fn new(x: &Bound<$base>, y: &Bound<$base>) -> PyResult<Self> {
                 let affine_point = <$affine>::from_xy(x, y).unwrap();
                 Ok(Self::from_affine(affine_point))
             }
@@ -206,15 +206,14 @@ macro_rules! impl_point {
                 Self(<$inner>::from(p.0))
             }
 
-            fn __str__(slf: &PyCell<Self>) -> PyResult<String> {
+            fn __str__(slf: &Bound<Self>) -> PyResult<String> {
                 let affine = <$affine>::from_projective(slf);
                 let (x, y) = affine.coordinates();
                 Ok(format!("[{}, {}]", x.__str__()?, y.__str__()?))
             }
 
-            fn __repr__(slf: &PyCell<Self>) -> PyResult<String> {
-                let class_name: &str = &slf.get_type().name()?;
-                Ok(format!("{}({:?})", class_name, slf.borrow().0))
+            fn __repr__(slf: &Bound<Self>) -> PyResult<String> {
+                Ok(format!("{}({:?})", slf.get_type().name()?.to_str()?, slf.borrow().0))
             }
 
             fn __add__(&self, rhs: &Self) -> Self {
@@ -291,12 +290,12 @@ pub fn nullifier_k() -> EpAffine {
 
 #[pyfunction]
 /// Convert Fp to Fq safely.
-pub fn fp_mod_fv(x: &PyCell<Fp>) -> PyResult<Fq> {
+pub fn fp_mod_fv(x: &Bound<Fp>) -> PyResult<Fq> {
     Ok(Fq(util::fp_mod_fv(x.borrow().deref().0)))
 }
 
-pub fn create_module(py: pyo3::Python<'_>) -> PyResult<&PyModule> {
-    let submod = PyModule::new(py, "pasta")?;
+pub fn create_module(py: pyo3::Python<'_>) -> PyResult<Bound<PyModule>> {
+    let submod = PyModule::new_bound(py, "pasta")?;
 
     submod.add_class::<Fp>()?;
     submod.add_class::<Fq>()?;
@@ -305,8 +304,8 @@ pub fn create_module(py: pyo3::Python<'_>) -> PyResult<&PyModule> {
     submod.add_class::<Eq>()?;
     submod.add_class::<EqAffine>()?;
 
-    submod.add_function(wrap_pyfunction!(nullifier_k, submod)?)?;
-    submod.add_function(wrap_pyfunction!(fp_mod_fv, submod)?)?;
+    submod.add_function(wrap_pyfunction!(nullifier_k, &submod)?)?;
+    submod.add_function(wrap_pyfunction!(fp_mod_fv, &submod)?)?;
 
     Ok(submod)
 }

+ 32 - 23
src/sdk/python/src/zkas.rs

@@ -23,7 +23,10 @@ use darkfi::{
     zkas::{self, decoder},
 };
 use darkfi_sdk::{crypto::MerkleNode, pasta::pallas};
-use pyo3::{pyclass, pymethods, types::PyModule, PyCell, PyResult, Python};
+use pyo3::{
+    prelude::{PyModule, PyModuleMethods},
+    pyclass, pymethods, Bound, PyResult, Python,
+};
 use rand::rngs::OsRng;
 
 use super::pasta::{Ep, Fp, Fq};
@@ -87,7 +90,8 @@ impl ZkBinary {
     }
 }
 
-#[pyclass]
+#[pyclass(eq, eq_int)]
+#[derive(PartialEq)]
 enum DebugOpValue {
     EcPoint,
     Base,
@@ -114,7 +118,7 @@ pub struct ZkCircuit(zk::vm::ZkCircuit, Vec<zk::vm::Witness>, decoder::ZkBinary)
 #[pymethods]
 impl ZkCircuit {
     #[new]
-    fn new(zkbin: &PyCell<ZkBinary>) -> Self {
+    fn new(zkbin: &Bound<ZkBinary>) -> Self {
         let zkbin = zkbin.borrow().deref().0.clone();
         let circuit = zk::vm::ZkCircuit::new(vec![], &zkbin);
         Self(circuit, vec![], zkbin)
@@ -131,38 +135,38 @@ impl ZkCircuit {
         Self(circuit, witnesses, self.2.clone())
     }
 
-    fn witness_ecpoint(&mut self, w: &PyCell<Ep>) {
+    fn witness_ecpoint(&mut self, w: &Bound<Ep>) {
         let w = w.borrow();
         let w = w.deref();
         self.1.push(zk::vm::Witness::EcPoint(Value::known(w.0)));
     }
 
-    fn witness_ecnipoint(&mut self, w: &PyCell<Ep>) {
+    fn witness_ecnipoint(&mut self, w: &Bound<Ep>) {
         let w = w.borrow();
         let w = w.deref();
         self.1.push(zk::vm::Witness::EcNiPoint(Value::known(w.0)));
     }
 
-    fn witness_base(&mut self, w: &PyCell<Fp>) {
+    fn witness_base(&mut self, w: &Bound<Fp>) {
         let w = w.borrow();
         let w = w.deref();
         self.1.push(zk::vm::Witness::Base(Value::known(w.0)));
     }
 
-    fn witness_scalar(&mut self, w: &PyCell<Fq>) {
+    fn witness_scalar(&mut self, w: &Bound<Fq>) {
         let w = w.borrow();
         let w = w.deref();
         self.1.push(zk::vm::Witness::Scalar(Value::known(w.0)));
     }
 
-    fn witness_merklepath(&mut self, w: Vec<&PyCell<Fp>>) {
+    fn witness_merklepath(&mut self, w: Vec<Bound<Fp>>) {
         assert!(w.len() == 32);
         let path: Vec<MerkleNode> =
             w.iter().map(|x| MerkleNode::from(x.borrow().deref().0)).collect();
         self.1.push(zk::vm::Witness::MerklePath(Value::known(path.try_into().unwrap())));
     }
 
-    fn witness_sparsemerklepath(&mut self, w: Vec<&PyCell<Fp>>) {
+    fn witness_sparsemerklepath(&mut self, w: Vec<Bound<Fp>>) {
         assert!(w.len() == 255);
         let path: Vec<pallas::Base> = w.iter().map(|x| x.borrow().deref().0).collect();
         self.1.push(zk::vm::Witness::SparseMerklePath(Value::known(path.try_into().unwrap())));
@@ -213,6 +217,12 @@ impl ZkCircuit {
             Err(_) => false,
         }
     }
+
+    fn replace(&mut self, other: &Self) -> Self {
+        let current = Self(self.0.clone(), self.1.clone(), self.2.clone());
+        *self = Self(other.0.clone(), other.1.clone(), other.2.clone());
+        current
+    }
 }
 
 #[pyclass]
@@ -222,7 +232,7 @@ pub struct VerifyingKey(zk::proof::VerifyingKey);
 #[pymethods]
 impl VerifyingKey {
     #[staticmethod]
-    fn build(k: u32, circuit: &PyCell<ZkCircuit>) -> Self {
+    fn build(k: u32, circuit: &Bound<ZkCircuit>) -> Self {
         let circuit_ref = circuit.borrow();
         let circuit = &circuit_ref.deref().0;
         let vk = zk::proof::VerifyingKey::build(k, circuit);
@@ -237,7 +247,7 @@ pub struct ProvingKey(zk::proof::ProvingKey);
 #[pymethods]
 impl ProvingKey {
     #[staticmethod]
-    fn build(k: u32, circuit: &PyCell<ZkCircuit>) -> Self {
+    fn build(k: u32, circuit: &Bound<ZkCircuit>) -> Self {
         let circuit_ref = circuit.borrow();
         let circuit = &circuit_ref.deref().0;
         let pk = zk::proof::ProvingKey::build(k, circuit);
@@ -253,9 +263,9 @@ pub struct Proof(zk::proof::Proof);
 impl Proof {
     #[staticmethod]
     fn create(
-        pk: &PyCell<ProvingKey>,
-        circuits: Vec<&PyCell<ZkCircuit>>,
-        instances: Vec<&PyCell<Fp>>,
+        pk: &Bound<ProvingKey>,
+        circuits: Vec<Bound<ZkCircuit>>,
+        instances: Vec<Bound<Fp>>,
     ) -> Option<Self> {
         let pk = pk.borrow().deref().0.clone();
 
@@ -277,10 +287,9 @@ impl Proof {
             opcodes: Vec::new(),
         };
         let empty_circuit = zk::vm::ZkCircuit::new(Vec::new(), &zkbin);
-        let curr_circuits: Vec<ZkCircuit> = circuits
-            .iter()
-            .map(|c| c.replace(ZkCircuit(empty_circuit.clone(), Vec::new(), zkbin.clone())))
-            .collect();
+        let empty_py_circuit = ZkCircuit(empty_circuit, Vec::new(), zkbin);
+        let curr_circuits: Vec<ZkCircuit> =
+            circuits.iter().map(|c| c.borrow_mut().replace(&empty_py_circuit)).collect();
 
         let mut ucircuits = Vec::new();
         let mut other_stuff = Vec::new();
@@ -305,12 +314,12 @@ impl Proof {
         // Now replace the "stuff" back again
         for (old_circ, (circ, stuff)) in circuits.iter().zip(ucircuits.into_iter().zip(other_stuff))
         {
-            old_circ.replace(ZkCircuit(circ, stuff.0, stuff.1));
+            old_circ.borrow_mut().replace(&ZkCircuit(circ, stuff.0, stuff.1));
         }
         Some(Self(proof))
     }
 
-    fn verify(&self, vk: &PyCell<VerifyingKey>, instances: Vec<&PyCell<Fp>>) -> bool {
+    fn verify(&self, vk: &Bound<VerifyingKey>, instances: Vec<Bound<Fp>>) -> bool {
         let vk = vk.borrow().deref().0.clone();
         let instances: Vec<pallas::Base> = instances.iter().map(|i| i.borrow().deref().0).collect();
         self.0.verify(&vk, instances.as_slice()).is_ok()
@@ -325,7 +334,7 @@ pub struct MockProver(zk::halo2::dev::MockProver<pallas::Base>);
 #[pymethods]
 impl MockProver {
     #[staticmethod]
-    fn run(k: u32, circuit: &PyCell<ZkCircuit>, instances: Vec<&PyCell<Fp>>) -> Self {
+    fn run(k: u32, circuit: &Bound<ZkCircuit>, instances: Vec<Bound<Fp>>) -> Self {
         let circuit = circuit.borrow().deref().0.clone();
         let instances: Vec<pallas::Base> = instances.iter().map(|i| i.borrow().deref().0).collect();
         let prover = zk::halo2::dev::MockProver::run(k, &circuit, vec![instances]).unwrap();
@@ -337,8 +346,8 @@ impl MockProver {
     }
 }
 
-pub fn create_module(py: Python<'_>) -> PyResult<&PyModule> {
-    let submod = PyModule::new(py, "zkas")?;
+pub fn create_module(py: Python<'_>) -> PyResult<Bound<PyModule>> {
+    let submod = PyModule::new_bound(py, "zkas")?;
 
     submod.add_class::<ZkBinary>()?;
     submod.add_class::<ZkCircuit>()?;