Kaynağa Gözat

tx2: Initial stub for contract transaction type.

parazyd 3 yıl önce
ebeveyn
işleme
cea573071b
6 değiştirilmiş dosya ile 88 ekleme ve 6 silme
  1. 1 2
      src/consensus/state.rs
  2. 4 2
      src/crypto/mod.rs
  3. 1 1
      src/error.rs
  4. 3 0
      src/lib.rs
  5. 3 1
      src/sdk/src/tx.rs
  6. 76 0
      src/tx2/mod.rs

+ 1 - 2
src/consensus/state.rs

@@ -196,7 +196,6 @@ impl ValidatorState {
         let mut runtime = Runtime::new(&money_contract_wasm_bincode[..], blockchain.clone(), cid)?;
         runtime.deploy(&[])?;
         info!("Deployed Money Contract with ID: {}", cid);
-
         // -----END ARTIFACT-----
 
         let address = client.wallet.get_default_address().await?;
@@ -543,7 +542,7 @@ impl ValidatorState {
                 "receive_proposal(): Proposer ({}) signature could not be verified",
                 proposal.block.metadata.address
             );
-            return Err(Error::InvalidSignatureError)
+            return Err(Error::InvalidSignature)
         }
 
         // Check if proposal extends any existing fork chains

+ 4 - 2
src/crypto/mod.rs

@@ -21,15 +21,17 @@ pub mod coin;
 pub mod diffie_hellman;
 pub mod mint_proof;
 pub mod note;
-pub mod proof;
 pub mod types;
 
 /// VDF (Verifiable Delay Function) using MiMC
 pub mod mimc_vdf;
 
+/// Halo2 proof API abstractions
+pub mod proof;
+pub use proof::Proof;
+
 pub use burn_proof::BurnRevealedValues;
 pub use mint_proof::MintRevealedValues;
-pub use proof::Proof;
 
 pub mod lead_proof;
 pub mod leadcoin;

+ 1 - 1
src/error.rs

@@ -221,7 +221,7 @@ pub enum Error {
     LeaderProofVerificationError,
 
     #[error("Signature could not be verified")]
-    InvalidSignatureError,
+    InvalidSignature,
 
     #[error("State transition failed")]
     StateTransitionError,

+ 3 - 0
src/lib.rs

@@ -54,6 +54,9 @@ pub mod system;
 #[cfg(feature = "tx")]
 pub mod tx;
 
+#[cfg(feature = "tx")]
+pub mod tx2;
+
 #[cfg(feature = "util")]
 pub mod util;
 

+ 3 - 1
src/sdk/src/tx.rs

@@ -20,7 +20,9 @@ use darkfi_serial::{SerialDecodable, SerialEncodable};
 
 use super::crypto::ContractId;
 
-#[derive(SerialEncodable, SerialDecodable)]
+/// A ContractCall is the part of a transaction that executes a certain
+/// `contract_id` with `data` as the call's payload.
+#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
 pub struct ContractCall {
     pub contract_id: ContractId,
     pub data: Vec<u8>,

+ 76 - 0
src/tx2/mod.rs

@@ -0,0 +1,76 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2022 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * 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 darkfi_sdk::{
+    crypto::{
+        schnorr::{SchnorrPublic, Signature},
+        PublicKey,
+    },
+    tx::ContractCall,
+};
+use darkfi_serial::{Encodable, SerialDecodable, SerialEncodable};
+use log::{debug, error};
+
+use crate::{crypto::Proof, Error, Result};
+
+/// A Transaction contains an arbitrary number of `ContractCall` objects,
+/// along with corresponding ZK proofs and Schnorr signatures.
+#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
+pub struct Transaction {
+    /// Calls executed in this transaction
+    pub calls: Vec<ContractCall>,
+    /// Attached ZK proofs
+    pub proofs: Vec<Vec<Proof>>,
+    /// Attached Schnorr signatures
+    pub signatures: Vec<Vec<Signature>>,
+}
+
+impl Transaction {
+    /// Verify ZK proofs for the entire transaction.
+    pub fn verify_zkps(&self) -> Result<()> {
+        Ok(())
+    }
+
+    /// Verify Schnorr signatures for the entire transaction.
+    pub fn verify_sigs(&self, pub_table: &[&[PublicKey]]) -> Result<()> {
+        let tx_data = self.encode_without_sigs()?;
+        let data_hash = blake3::hash(&tx_data);
+
+        assert!(pub_table.len() == self.signatures.len());
+
+        for (i, (sigs, pubkeys)) in self.signatures.iter().zip(pub_table.iter()).enumerate() {
+            for (pubkey, signature) in pubkeys.iter().zip(sigs) {
+                if !pubkey.verify(&data_hash.as_bytes()[..], &signature) {
+                    error!("tx::verify_sigs[{}] failed to verify", i);
+                    return Err(Error::InvalidSignature)
+                }
+            }
+            debug!("tx::verify_sigs[{}] passed", i);
+        }
+
+        Ok(())
+    }
+
+    /// Encode the object into a byte vector for signing
+    pub fn encode_without_sigs(&self) -> Result<Vec<u8>> {
+        let mut buf = vec![];
+        self.calls.encode(&mut buf)?;
+        self.proofs.encode(&mut buf)?;
+        Ok(buf)
+    }
+}