Contracts - Test fixes + warning cleanups (#694)

* clean up warnings in libwallet crate

* clean up warnings in controller crate

* update all contract tests with awareness of new proof structure
This commit is contained in:
Yeastplume 2023-08-10 13:24:25 +01:00 committed by GitHub
parent 3da7695742
commit fa78d72d35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 94 additions and 76 deletions

View file

@ -483,13 +483,12 @@ where
/// TODO /// TODO
pub fn verify_payment_proof_invoice( pub fn verify_payment_proof_invoice(
&self, &self,
keychain_mask: Option<&SecretKey>,
recipient_address: &DalekPublicKey, recipient_address: &DalekPublicKey,
proof: &InvoiceProof, proof: &InvoiceProof,
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut w_lock = self.wallet_inst.lock(); let mut w_lock = self.wallet_inst.lock();
let w = w_lock.lc_provider()?.wallet_inst()?; let w = w_lock.lc_provider()?.wallet_inst()?;
foreign::verify_payment_proof_invoice(&mut **w, keychain_mask, recipient_address, proof) foreign::verify_payment_proof_invoice(&mut **w, recipient_address, proof)
} }
} }

View file

@ -513,21 +513,43 @@ pub trait OwnerRpc {
``` ```
*/ */
/**
TODO: Full docs once API has stabilised
*/
fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result<VersionedSlate, Error>; fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result<VersionedSlate, Error>;
fn contract_new(&self, token: Token, args: ContractNewArgsAPI)
-> Result<VersionedSlate, Error>; /**
TODO: Implement
*/
// fn contract_setup( // fn contract_setup(
// &self, // &self,
// token: Token, // token: Token,
// slate: VersionedSlate, // slate: VersionedSlate,
// args: ContractSetupArgsAPI, // args: ContractSetupArgsAPI,
// ) -> Result<VersionedSlate, Error>; // ) -> Result<VersionedSlate, Error>;
/**
TODO: Full docs once API has stabilised
*/
fn contract_new(&self, token: Token, args: ContractNewArgsAPI)
-> Result<VersionedSlate, Error>;
/**
TODO: Full docs once API has stabilised
*/
fn contract_sign( fn contract_sign(
&self, &self,
token: Token, token: Token,
slate: VersionedSlate, slate: VersionedSlate,
args: ContractSetupArgsAPI, args: ContractSetupArgsAPI,
) -> Result<VersionedSlate, Error>; ) -> Result<VersionedSlate, Error>;
/**
TODO: Full docs once API has stabilised
*/
fn contract_revoke( fn contract_revoke(
&self, &self,
token: Token, token: Token,

View file

@ -184,6 +184,7 @@ pub fn open_local_wallet(
} }
// Creates the given number of wallets and spawns a thread that runs the wallet proxy // Creates the given number of wallets and spawns a thread that runs the wallet proxy
#[allow(dead_code)]
pub fn create_wallets( pub fn create_wallets(
wallets_def: Vec<Vec<(&'static str, u64)>>, // a vector of boolean that represent whether we mine into a wallet wallets_def: Vec<Vec<(&'static str, u64)>>, // a vector of boolean that represent whether we mine into a wallet
test_dir: &'static str, test_dir: &'static str,

View file

@ -24,9 +24,8 @@ use self::core::global;
use self::keychain::{ExtKeychain, Keychain}; use self::keychain::{ExtKeychain, Keychain};
use grin_wallet_libwallet as libwallet; use grin_wallet_libwallet as libwallet;
use impls::test_framework::{self}; use impls::test_framework::{self};
use libwallet::contract::my_fee_contribution;
use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI}; use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI};
use libwallet::{Slate, SlateState, TxLogEntryType}; use libwallet::{Slate, SlateState};
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -38,7 +37,7 @@ use common::{clean_output_dir, create_wallets, setup};
/// contract accounts testing (mostly the same as accounts.rs) /// contract accounts testing (mostly the same as accounts.rs)
fn contract_accounts_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { fn contract_accounts_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
// create two wallets with some extra accounts and don't mine anything in them // create two wallets with some extra accounts and don't mine anything in them
let (wallets, chain, stopper, mut bh) = create_wallets( let (wallets, chain, stopper, _bh) = create_wallets(
vec![ vec![
vec![ vec![
("default", 0), ("default", 0),
@ -145,6 +144,7 @@ fn contract_accounts_impl(test_dir: &'static str) -> Result<(), libwallet::Error
let mut slate = Slate::blank(0, true); // this gets overriden below let mut slate = Slate::blank(0, true); // this gets overriden below
let mut sender_address = None;
wallet::controller::owner_single_use(Some(wallet1.clone()), mask1, None, |api, m| { wallet::controller::owner_single_use(Some(wallet1.clone()), mask1, None, |api, m| {
// Send wallet inititates a standard transaction with --send=5 // Send wallet inititates a standard transaction with --send=5
let args = &ContractNewArgsAPI { let args = &ContractNewArgsAPI {
@ -155,17 +155,21 @@ fn contract_accounts_impl(test_dir: &'static str) -> Result<(), libwallet::Error
..Default::default() ..Default::default()
}; };
slate = api.contract_new(m, args)?; slate = api.contract_new(m, args)?;
sender_address = Some(api.get_slatepack_address(mask1, 0)?.pub_key);
Ok(()) Ok(())
})?; })?;
assert_eq!(slate.state, SlateState::Standard1); assert_eq!(slate.state, SlateState::Standard1);
let mut recipient_address = None;
wallet::controller::owner_single_use(Some(wallet2.clone()), mask2, None, |api, m| { wallet::controller::owner_single_use(Some(wallet2.clone()), mask2, None, |api, m| {
// Receive wallet calls --receive=5 // Receive wallet calls --receive=5
let args = &ContractSetupArgsAPI { let args = &mut ContractSetupArgsAPI {
net_change: Some(5_000_000_000), net_change: Some(5_000_000_000),
..Default::default() ..Default::default()
}; };
args.proof_args.sender_address = sender_address;
slate = api.contract_sign(m, &slate, args)?; slate = api.contract_sign(m, &slate, args)?;
recipient_address = Some(api.get_slatepack_address(mask2, 0)?.pub_key);
Ok(()) Ok(())
})?; })?;
assert_eq!(slate.state, SlateState::Standard2); assert_eq!(slate.state, SlateState::Standard2);
@ -184,7 +188,6 @@ fn contract_accounts_impl(test_dir: &'static str) -> Result<(), libwallet::Error
api.post_tx(m, &slate, false)?; api.post_tx(m, &slate, false)?;
Ok(()) Ok(())
})?; })?;
bh += 1;
wallet::controller::owner_single_use(Some(wallet1.clone()), mask1, None, |api, m| { wallet::controller::owner_single_use(Some(wallet1.clone()), mask1, None, |api, m| {
let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;

View file

@ -18,15 +18,10 @@ extern crate grin_wallet_impls as impls;
extern crate log; extern crate log;
use grin_core as core; use grin_core as core;
use grin_keychain as keychain;
use self::core::global;
use self::keychain::{ExtKeychain, Keychain};
use grin_wallet_libwallet as libwallet; use grin_wallet_libwallet as libwallet;
use impls::test_framework::{self};
use libwallet::contract::my_fee_contribution; use libwallet::contract::my_fee_contribution;
use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI}; use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI};
use libwallet::{Slate, SlateState, TxLogEntryType}; use libwallet::{Slate, SlateState};
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -38,7 +33,7 @@ use common::{clean_output_dir, create_wallets, setup};
/// contract accounts testing when switching between accounts during transaction building /// contract accounts testing when switching between accounts during transaction building
fn contract_accounts_switch_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { fn contract_accounts_switch_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
// create two wallets with some extra accounts and don't mine anything in them // create two wallets with some extra accounts and don't mine anything in them
let (wallets, chain, stopper, mut bh) = create_wallets( let (wallets, _chain, stopper, _bh) = create_wallets(
vec![ vec![
vec![("default", 0), ("account1", 1), ("account2", 2)], vec![("default", 0), ("account1", 1), ("account2", 2)],
vec![("default", 0), ("account1", 3), ("account2", 4)], vec![("default", 0), ("account1", 3), ("account2", 4)],
@ -118,10 +113,11 @@ fn contract_accounts_switch_impl(test_dir: &'static str) -> Result<(), libwallet
} }
wallet::controller::owner_single_use(Some(wallet2.clone()), mask2, None, |api, m| { wallet::controller::owner_single_use(Some(wallet2.clone()), mask2, None, |api, m| {
// Receive wallet calls --receive=5 // Receive wallet calls --receive=5
let args = &ContractSetupArgsAPI { let args = &mut ContractSetupArgsAPI {
net_change: Some(5_000_000_000), net_change: Some(5_000_000_000),
..Default::default() ..Default::default()
}; };
args.proof_args.suppress_proof = true;
slate = api.contract_sign(m, &slate, args)?; slate = api.contract_sign(m, &slate, args)?;
Ok(()) Ok(())
})?; })?;

View file

@ -20,10 +20,9 @@ extern crate log;
use grin_wallet_libwallet as libwallet; use grin_wallet_libwallet as libwallet;
use grin_core::consensus; use grin_core::consensus;
use impls::test_framework::{self};
use libwallet::contract::my_fee_contribution; use libwallet::contract::my_fee_contribution;
use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI, OutputSelectionArgs}; use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI};
use libwallet::{OutputCommitMapping, OutputStatus, Slate, SlateState, TxLogEntryType}; use libwallet::{OutputStatus, Slate, SlateState};
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -35,7 +34,7 @@ use common::{clean_output_dir, create_wallets, setup};
/// contract new with --add-outputs /// contract new with --add-outputs
fn contract_early_lock_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { fn contract_early_lock_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
// create a single wallet and mine 5 blocks // create a single wallet and mine 5 blocks
let (wallets, chain, stopper, mut bh) = let (wallets, _chain, stopper, _bh) =
create_wallets(vec![vec![("default", 5)]], test_dir).unwrap(); create_wallets(vec![vec![("default", 5)]], test_dir).unwrap();
let send_wallet = wallets[0].0.clone(); let send_wallet = wallets[0].0.clone();
let send_mask = wallets[0].1.as_ref(); let send_mask = wallets[0].1.as_ref();

View file

@ -22,13 +22,10 @@ extern crate grin_wallet_controller as wallet;
extern crate grin_wallet_impls as impls; extern crate grin_wallet_impls as impls;
extern crate log; extern crate log;
use grin_core::consensus::KERNEL_WEIGHT;
use grin_wallet_libwallet as libwallet; use grin_wallet_libwallet as libwallet;
use grin_util::static_secp_instance;
use impls::test_framework::{self}; use impls::test_framework::{self};
use libwallet::contract::my_fee_contribution; use libwallet::contract::my_fee_contribution;
use libwallet::contract::proofs::{InvoiceProof, ProofWitness};
use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI}; use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI};
use libwallet::{Slate, SlateState, TxLogEntryType}; use libwallet::{Slate, SlateState, TxLogEntryType};
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
@ -70,7 +67,7 @@ fn contract_early_proofs_test_impl(test_dir: &'static str) -> Result<(), libwall
let mut recipient_address = None; let mut recipient_address = None;
wallet::controller::owner_single_use(Some(recv_wallet.clone()), recv_mask, None, |api, m| { wallet::controller::owner_single_use(Some(recv_wallet.clone()), recv_mask, None, |api, m| {
// Receive wallet calls --receive=5 // Receive wallet calls --receive=5
let mut args = &mut ContractSetupArgsAPI { let args = &mut ContractSetupArgsAPI {
net_change: Some(5_000_000_000), net_change: Some(5_000_000_000),
..Default::default() ..Default::default()
}; };
@ -145,7 +142,7 @@ fn contract_early_proofs_test_impl(test_dir: &'static str) -> Result<(), libwall
let mut invoice_proof = None; let mut invoice_proof = None;
// Now some time has passed, sender retrieves and verify the payment proof // Now some time has passed, sender retrieves and verify the payment proof
wallet::controller::owner_single_use(Some(send_wallet.clone()), send_mask, None, |api, m| { wallet::controller::owner_single_use(Some(send_wallet.clone()), send_mask, None, |api, _m| {
// Extract the stored data as an invoice proof // Extract the stored data as an invoice proof
invoice_proof = invoice_proof =
Some(api.retrieve_payment_proof_invoice(send_mask, true, None, Some(slate.id))?); Some(api.retrieve_payment_proof_invoice(send_mask, true, None, Some(slate.id))?);
@ -160,14 +157,10 @@ fn contract_early_proofs_test_impl(test_dir: &'static str) -> Result<(), libwall
wallet::controller::foreign_single_use(recv_wallet.clone(), recv_mask.cloned(), |api| { wallet::controller::foreign_single_use(recv_wallet.clone(), recv_mask.cloned(), |api| {
let mut proof = serde_json::from_str(&invoice_proof_json).unwrap(); let mut proof = serde_json::from_str(&invoice_proof_json).unwrap();
api.verify_payment_proof_invoice(recv_mask, recipient_address.as_ref().unwrap(), &proof)?; api.verify_payment_proof_invoice(recipient_address.as_ref().unwrap(), &proof)?;
// tweak something and it shouldn't verify // tweak something and it shouldn't verify
proof.amount = 400000; proof.amount = 400000;
let retval = api.verify_payment_proof_invoice( let retval = api.verify_payment_proof_invoice(recipient_address.as_ref().unwrap(), &proof);
recv_mask,
recipient_address.as_ref().unwrap(),
&proof,
);
assert!(retval.is_err()); assert!(retval.is_err());
Ok(()) Ok(())
})?; })?;

View file

@ -45,13 +45,14 @@ fn contract_rsr_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
wallet::controller::owner_single_use(Some(recv_wallet.clone()), recv_mask, None, |api, m| { wallet::controller::owner_single_use(Some(recv_wallet.clone()), recv_mask, None, |api, m| {
// Receive wallet inititates an invoice transaction with --receive=5 // Receive wallet inititates an invoice transaction with --receive=5
let args = &ContractNewArgsAPI { let args = &mut ContractNewArgsAPI {
setup_args: ContractSetupArgsAPI { setup_args: ContractSetupArgsAPI {
net_change: Some(5_000_000_000), net_change: Some(5_000_000_000),
..Default::default() ..Default::default()
}, },
..Default::default() ..Default::default()
}; };
args.setup_args.proof_args.suppress_proof = true;
slate = api.contract_new(m, args)?; slate = api.contract_new(m, args)?;
Ok(()) Ok(())
})?; })?;
@ -70,9 +71,11 @@ fn contract_rsr_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
// Receive wallet finalizes and posts // Receive wallet finalizes and posts
wallet::controller::owner_single_use(Some(recv_wallet.clone()), recv_mask, None, |api, m| { wallet::controller::owner_single_use(Some(recv_wallet.clone()), recv_mask, None, |api, m| {
let args = &ContractSetupArgsAPI { let args = &mut ContractSetupArgsAPI {
..Default::default() ..Default::default()
}; };
// TODO: This possibly shouldn't be needed here if no proof?
args.proof_args.suppress_proof = true;
slate = api.contract_sign(m, &slate, args)?; slate = api.contract_sign(m, &slate, args)?;
Ok(()) Ok(())
})?; })?;

View file

@ -45,7 +45,7 @@ fn contract_srs_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
wallet::controller::owner_single_use(Some(send_wallet.clone()), send_mask, None, |api, m| { wallet::controller::owner_single_use(Some(send_wallet.clone()), send_mask, None, |api, m| {
// Send wallet inititates a standard transaction with --send=5 // Send wallet inititates a standard transaction with --send=5
let args = &ContractNewArgsAPI { let args = &mut ContractNewArgsAPI {
setup_args: ContractSetupArgsAPI { setup_args: ContractSetupArgsAPI {
net_change: Some(-5_000_000_000), net_change: Some(-5_000_000_000),
..Default::default() ..Default::default()
@ -59,10 +59,11 @@ fn contract_srs_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
wallet::controller::owner_single_use(Some(recv_wallet.clone()), recv_mask, None, |api, m| { wallet::controller::owner_single_use(Some(recv_wallet.clone()), recv_mask, None, |api, m| {
// Receive wallet calls --receive=5 // Receive wallet calls --receive=5
let args = &ContractSetupArgsAPI { let args = &mut ContractSetupArgsAPI {
net_change: Some(5_000_000_000), net_change: Some(5_000_000_000),
..Default::default() ..Default::default()
}; };
args.proof_args.suppress_proof = true;
slate = api.contract_sign(m, &slate, args)?; slate = api.contract_sign(m, &slate, args)?;
Ok(()) Ok(())
})?; })?;
@ -70,9 +71,10 @@ fn contract_srs_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
// Send wallet finalizes and posts // Send wallet finalizes and posts
wallet::controller::owner_single_use(Some(send_wallet.clone()), send_mask, None, |api, m| { wallet::controller::owner_single_use(Some(send_wallet.clone()), send_mask, None, |api, m| {
let args = &ContractSetupArgsAPI { let args = &mut ContractSetupArgsAPI {
..Default::default() ..Default::default()
}; };
args.proof_args.suppress_proof = true;
slate = api.contract_sign(m, &slate, args)?; slate = api.contract_sign(m, &slate, args)?;
Ok(()) Ok(())
})?; })?;

View file

@ -21,8 +21,6 @@ use std::io::{Read, Write};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use uuid::Uuid;
use crate::blake2::blake2b::{Blake2b, Blake2bResult}; use crate::blake2::blake2b::{Blake2b, Blake2bResult};
use crate::keychain::{ChildNumber, ExtKeychain, Identifier, Keychain, SwitchCommitmentType}; use crate::keychain::{ChildNumber, ExtKeychain, Identifier, Keychain, SwitchCommitmentType};

View file

@ -13,7 +13,6 @@
// limitations under the License. // limitations under the License.
//! Generic implementation of owner API functions //! Generic implementation of owner API functions
use grin_util::secp::pedersen::Commitment;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::api_impl::owner::contract_new as owner_contract_new; use crate::api_impl::owner::contract_new as owner_contract_new;
@ -230,7 +229,6 @@ where
/// Verify an invoice payment proof /// Verify an invoice payment proof
pub fn verify_payment_proof_invoice<'a, T: ?Sized, C, K>( pub fn verify_payment_proof_invoice<'a, T: ?Sized, C, K>(
w: &mut T, w: &mut T,
keychain_mask: Option<&SecretKey>,
recipient_address: &DalekPublicKey, recipient_address: &DalekPublicKey,
proof: &InvoiceProof, proof: &InvoiceProof,
) -> Result<(), Error> ) -> Result<(), Error>
@ -239,13 +237,7 @@ where
C: NodeClient + 'a, C: NodeClient + 'a,
K: Keychain + 'a, K: Keychain + 'a,
{ {
let (mut client, parent_key_id, keychain) = { let mut client = w.w2n_client().clone();
(
w.w2n_client().clone(),
w.parent_key_id(),
w.keychain(keychain_mask)?,
)
};
let wd = match proof.witness_data.clone() { let wd = match proof.witness_data.clone() {
Some(w) => w, Some(w) => w,
@ -256,7 +248,7 @@ where
} }
}; };
let (retrieved_kernel, index) = match client.get_kernel(&wd.kernel_commitment, None, None) { let (retrieved_kernel, _) = match client.get_kernel(&wd.kernel_commitment, None, None) {
Err(e) => { Err(e) => {
return Err(Error::PaymentProof(format!( return Err(Error::PaymentProof(format!(
"Error retrieving kernel from chain: {}", "Error retrieving kernel from chain: {}",

View file

@ -45,7 +45,6 @@ use ed25519_dalek::SecretKey as DalekSecretKey;
use ed25519_dalek::Verifier; use ed25519_dalek::Verifier;
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use std::ops::Index;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::sync::Arc; use std::sync::Arc;
@ -713,7 +712,10 @@ where
sender_address: Some(sender_address.to_ed25519()?), sender_address: Some(sender_address.to_ed25519()?),
receiver_address: a.pub_key, receiver_address: a.pub_key,
promise_signature: None, promise_signature: None,
timestamp: DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc), timestamp: DateTime::<Utc>::from_utc(
NaiveDateTime::from_timestamp_opt(0, 0).unwrap(),
Utc,
),
memo: None, memo: None,
}); });

View file

@ -13,9 +13,6 @@
// limitations under the License. // limitations under the License.
//! Implementation of contract revoke //! Implementation of contract revoke
use std::default;
use crate::contract::types::{ContractRevokeArgsAPI, ContractSetupArgsAPI, OutputSelectionArgs}; use crate::contract::types::{ContractRevokeArgsAPI, ContractSetupArgsAPI, OutputSelectionArgs};
use crate::contract::{new, sign}; use crate::contract::{new, sign};
use crate::error::Error; use crate::error::Error;

View file

@ -23,10 +23,10 @@ use crate::types::{NodeClient, WalletBackend};
/// View contract /// View contract
pub fn view<'a, T: ?Sized, C, K>( pub fn view<'a, T: ?Sized, C, K>(
w: &mut T, _w: &mut T,
keychain_mask: Option<&SecretKey>, _keychain_mask: Option<&SecretKey>,
slate: &mut Slate, slate: &mut Slate,
encrypted_for: &str, _encrypted_for: &str,
) -> Result<ContractView, Error> ) -> Result<ContractView, Error>
where where
T: WalletBackend<'a, C, K>, T: WalletBackend<'a, C, K>,

View file

@ -40,6 +40,7 @@ use ed25519_dalek::{Signer, Verifier};
use grin_util::secp::Message; use grin_util::secp::Message;
use std::convert::TryInto; use std::convert::TryInto;
/// All elements required to validate a proof within a single struct
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ProofWitness { pub struct ProofWitness {
/// Kernel index, supplied so verifiers can look up kernel /// Kernel index, supplied so verifiers can look up kernel
@ -58,8 +59,8 @@ pub struct ProofWitness {
pub sender_partial_sig: Signature, pub sender_partial_sig: Signature,
} }
// Payment proof, to be extracted from slates for /// Payment proof, to be extracted from slates for
// signing (when wrapped as PaymentProofBin) or json export from stored tx data /// signing (when wrapped as PaymentProofBin) or json export from stored tx data
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct InvoiceProof { pub struct InvoiceProof {
/// Proof type, 0x00 legacy (though this will use StoredProofInfo above, 1 invoice, 2 Sender nonce) /// Proof type, 0x00 legacy (though this will use StoredProofInfo above, 1 invoice, 2 Sender nonce)
@ -212,7 +213,9 @@ impl InvoiceProof {
}; };
let timestamp = match slate.payment_proof.as_ref() { let timestamp = match slate.payment_proof.as_ref() {
Some(p) => NaiveDateTime::from_timestamp(p.timestamp.timestamp(), 0).timestamp(), Some(p) => NaiveDateTime::from_timestamp_opt(p.timestamp.timestamp(), 0)
.unwrap()
.timestamp(),
None => 0, None => 0,
}; };
@ -239,6 +242,7 @@ impl InvoiceProof {
}) })
} }
/// Sign the invoice proof, provided all fields are populated
pub fn sign(&self, sec_key: &SecretKey) -> Result<(DalekSignature, DalekPublicKey), Error> { pub fn sign(&self, sec_key: &SecretKey) -> Result<(DalekSignature, DalekPublicKey), Error> {
let d_skey = match DalekSecretKey::from_bytes(&sec_key.0) { let d_skey = match DalekSecretKey::from_bytes(&sec_key.0) {
Ok(k) => k, Ok(k) => k,
@ -258,6 +262,7 @@ impl InvoiceProof {
Ok((keypair.sign(&sig_data_bin), pub_key)) Ok((keypair.sign(&sig_data_bin), pub_key))
} }
/// Verify the signature of the invoice proof
pub fn verify_promise_signature( pub fn verify_promise_signature(
&self, &self,
recipient_address: &DalekPublicKey, recipient_address: &DalekPublicKey,
@ -284,6 +289,8 @@ impl InvoiceProof {
Ok(()) Ok(())
} }
/// Verify signature and proof against a given kernel message (kernel lookup is beyond the scope
/// of this module)
pub fn verify_witness( pub fn verify_witness(
&self, &self,
recipient_address: &DalekPublicKey, recipient_address: &DalekPublicKey,
@ -369,7 +376,7 @@ where
// TODO: Just generating invoice (type 1) for now // TODO: Just generating invoice (type 1) for now
let (invoice_proof, promise_signature, receiver_address) = let (invoice_proof, promise_signature, receiver_address) =
generate_invoice_signature(wallet, keychain_mask, slate, context, proof_args)?; generate_invoice_signature(wallet, keychain_mask, slate, context, proof_args)?;
let timestamp = NaiveDateTime::from_timestamp(Utc::now().timestamp(), 0); let timestamp = NaiveDateTime::from_timestamp_opt(Utc::now().timestamp(), 0).unwrap();
let timestamp = DateTime::<Utc>::from_utc(timestamp, Utc); let timestamp = DateTime::<Utc>::from_utc(timestamp, Utc);
let proof = PaymentInfo { let proof = PaymentInfo {
@ -407,7 +414,9 @@ where
let recp_key = let recp_key =
address::address_from_derivation_path(&keychain, &parent_key_id, derivation_index)?; address::address_from_derivation_path(&keychain, &parent_key_id, derivation_index)?;
invoice_proof.timestamp = NaiveDateTime::from_timestamp(Utc::now().timestamp(), 0).timestamp(); invoice_proof.timestamp = NaiveDateTime::from_timestamp_opt(Utc::now().timestamp(), 0)
.unwrap()
.timestamp();
let (sig, addr) = invoice_proof.sign(&recp_key)?; let (sig, addr) = invoice_proof.sign(&recp_key)?;
Ok((invoice_proof, sig, addr)) Ok((invoice_proof, sig, addr))
} }

View file

@ -26,9 +26,10 @@ use super::types::ProofArgs;
use crate::contract::proofs::InvoiceProof; use crate::contract::proofs::InvoiceProof;
use ed25519_dalek::PublicKey as DalekPublicKey; use ed25519_dalek::PublicKey as DalekPublicKey;
/// TODO: Removed for now, consider secp error in sign function
/// The secret key we replace the actual key with after we have signed with the Context keys. This is /// The secret key we replace the actual key with after we have signed with the Context keys. This is
/// to prevent possibility of signing with the same key twice. /// to prevent possibility of signing with the same key twice.
pub const SEC_KEY_FAKE: [u8; 32] = [0; 32]; /// pub const SEC_KEY_FAKE: [u8; 32] = [0; 32];
/// Add payment proof data to slate, noop for sender /// Add payment proof data to slate, noop for sender
pub fn add_payment_proof<'a, T: ?Sized, C, K>( pub fn add_payment_proof<'a, T: ?Sized, C, K>(
@ -46,7 +47,7 @@ where
{ {
// TODO: Implement. Consider adding this function to the Slate itself so they can easily be versioned // TODO: Implement. Consider adding this function to the Slate itself so they can easily be versioned
// e.g. slate.add_payment_proof_data() // e.g. slate.add_payment_proof_data()
trace!("contract::slate::add_payment_proof => called"); debug!("contract::slate::add_payment_proof => called");
// If we're a recipient, generate proof unless explicity told not to // If we're a recipient, generate proof unless explicity told not to
if let Some(ref c) = net_change { if let Some(ref c) = net_change {
if *c > 0 && !proof_args.suppress_proof && slate.payment_proof.is_none() { if *c > 0 && !proof_args.suppress_proof && slate.payment_proof.is_none() {

View file

@ -219,6 +219,8 @@ impl Default for ContractView {
} }
} }
} }
/// Arguments for contract revoke function
#[derive(Clone, Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct ContractRevokeArgsAPI { pub struct ContractRevokeArgsAPI {
/// Tx id to cancel /// Tx id to cancel

View file

@ -26,8 +26,6 @@ use crate::{address, Error, OutputData, OutputStatus, TxLogEntry};
use grin_core::core::FeeFields; use grin_core::core::FeeFields;
use uuid::Uuid; use uuid::Uuid;
use super::proofs::InvoiceProof;
/// Creates an initial TxLogEntry without input/output or kernel information /// Creates an initial TxLogEntry without input/output or kernel information
pub fn create_tx_log_entry( pub fn create_tx_log_entry(
slate: &Slate, slate: &Slate,

View file

@ -257,7 +257,7 @@ pub enum Error {
#[error("Proof Address decoding: {0}")] #[error("Proof Address decoding: {0}")]
AddressDecoding(String), AddressDecoding(String),
// Payment proof - no sender address provided or found in slate /// Payment proof - no sender address provided or found in slate
#[error("Sender address has not been provided")] #[error("Sender address has not been provided")]
NoSenderAddressProvided, NoSenderAddressProvided,

View file

@ -1600,7 +1600,10 @@ impl From<&PaymentInfoV4> for PaymentInfo {
sender_address: Some(sender_address), sender_address: Some(sender_address),
receiver_address, receiver_address,
promise_signature: receiver_signature, promise_signature: receiver_signature,
timestamp: DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc), timestamp: DateTime::<Utc>::from_utc(
NaiveDateTime::from_timestamp_opt(0, 0).unwrap(),
Utc,
),
memo: None, memo: None,
} }
} }

View file

@ -142,7 +142,7 @@ impl VersionedCoinbase {
} }
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use crate::grin_core::core::transaction::{FeeFields, OutputFeatures}; use crate::grin_core::core::transaction::OutputFeatures;
use crate::grin_util::from_hex; use crate::grin_util::from_hex;
use crate::grin_util::secp::key::PublicKey; use crate::grin_util::secp::key::PublicKey;
use crate::grin_util::secp::pedersen::{Commitment, RangeProof}; use crate::grin_util::secp::pedersen::{Commitment, RangeProof};
@ -155,7 +155,6 @@ pub mod tests {
use ed25519_dalek::Signature as DalekSignature; use ed25519_dalek::Signature as DalekSignature;
use grin_core::global::{set_local_chain_type, ChainTypes}; use grin_core::global::{set_local_chain_type, ChainTypes};
use grin_keychain::{ExtKeychain, Keychain, SwitchCommitmentType}; use grin_keychain::{ExtKeychain, Keychain, SwitchCommitmentType};
use grin_wallet_util::byte_ser::from_bytes;
use std::convert::TryInto; use std::convert::TryInto;
// Populate a test internal slate with all fields to test conversions // Populate a test internal slate with all fields to test conversions
@ -224,7 +223,7 @@ pub mod tests {
let b = from_hex(raw_pubkey_str).unwrap(); let b = from_hex(raw_pubkey_str).unwrap();
let d_pkey = DalekPublicKey::from_bytes(&b).unwrap(); let d_pkey = DalekPublicKey::from_bytes(&b).unwrap();
// Need to remove milliseconds component for comparison. Won't be serialized // Need to remove milliseconds component for comparison. Won't be serialized
let ts = NaiveDateTime::from_timestamp(Utc::now().timestamp(), 0); let ts = NaiveDateTime::from_timestamp_opt(Utc::now().timestamp(), 0).unwrap();
let ts = DateTime::<Utc>::from_utc(ts, Utc); let ts = DateTime::<Utc>::from_utc(ts, Utc);
let pm = PaymentMemo { let pm = PaymentMemo {
memo_type: 1, memo_type: 1,

View file

@ -14,7 +14,7 @@
//! Wraps a V5 Slate into a V5 Binary slate //! Wraps a V5 Slate into a V5 Binary slate
use crate::grin_core::core::transaction::{FeeFields, OutputFeatures}; use crate::grin_core::core::transaction::OutputFeatures;
use crate::grin_core::ser as grin_ser; use crate::grin_core::ser as grin_ser;
use crate::grin_core::ser::{Readable, Reader, Writeable, Writer}; use crate::grin_core::ser::{Readable, Reader, Writeable, Writer};
use crate::grin_keychain::BlindingFactor; use crate::grin_keychain::BlindingFactor;
@ -24,9 +24,7 @@ use crate::grin_util::secp::Signature;
use chrono::{DateTime, NaiveDateTime, Utc}; use chrono::{DateTime, NaiveDateTime, Utc};
use ed25519_dalek::PublicKey as DalekPublicKey; use ed25519_dalek::PublicKey as DalekPublicKey;
use ed25519_dalek::Signature as DalekSignature; use ed25519_dalek::Signature as DalekSignature;
use grin_wallet_util::byte_ser::from_bytes;
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use uuid::Uuid;
use crate::slate_versions::v5::{ use crate::slate_versions::v5::{
CommitsV5, KernelFeaturesArgsV5, ParticipantDataV5, PaymentInfoV5, PaymentMemoV5, SlateStateV5, CommitsV5, KernelFeaturesArgsV5, ParticipantDataV5, PaymentInfoV5, PaymentMemoV5, SlateStateV5,
@ -249,7 +247,8 @@ impl Readable for ProofWrap {
let saddr = DalekPublicKey::from_bytes(&reader.read_fixed_bytes(32)?).unwrap(); let saddr = DalekPublicKey::from_bytes(&reader.read_fixed_bytes(32)?).unwrap();
let raddr = DalekPublicKey::from_bytes(&reader.read_fixed_bytes(32)?).unwrap(); let raddr = DalekPublicKey::from_bytes(&reader.read_fixed_bytes(32)?).unwrap();
let ts_raw: i64 = reader.read_i64().unwrap(); let ts_raw: i64 = reader.read_i64().unwrap();
let ts = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(ts_raw, 0), Utc); let ts =
DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp_opt(ts_raw, 0).unwrap(), Utc);
let psig = match reader.read_u8()? { let psig = match reader.read_u8()? {
0 => None, 0 => None,
1 | _ => Some(DalekSignature::try_from(&reader.read_fixed_bytes(64)?[..]).unwrap()), 1 | _ => Some(DalekSignature::try_from(&reader.read_fixed_bytes(64)?[..]).unwrap()),
@ -488,7 +487,7 @@ fn slate_v5_serialize_deserialize() {
let b = from_hex(raw_pubkey_str).unwrap(); let b = from_hex(raw_pubkey_str).unwrap();
let d_pkey = DalekPublicKey::from_bytes(&b).unwrap(); let d_pkey = DalekPublicKey::from_bytes(&b).unwrap();
// Need to remove milliseconds component for comparison. Won't be serialized // Need to remove milliseconds component for comparison. Won't be serialized
let ts = NaiveDateTime::from_timestamp(Utc::now().timestamp(), 0); let ts = NaiveDateTime::from_timestamp_opt(Utc::now().timestamp(), 0).unwrap();
let ts = DateTime::<Utc>::from_utc(ts, Utc); let ts = DateTime::<Utc>::from_utc(ts, Utc);
let pm = PaymentMemoV5 { let pm = PaymentMemoV5 {
memo_type: 0, memo_type: 0,