diff --git a/api/src/foreign.rs b/api/src/foreign.rs index ead6d18..f17dcec 100644 --- a/api/src/foreign.rs +++ b/api/src/foreign.rs @@ -35,13 +35,12 @@ pub type ForeignCheckMiddleware = fn(ForeignCheckMiddlewareFn, Option, Option<&Slate>) -> Result<(), Error>; /// Middleware Identifiers for each function +#[non_exhaustive] pub enum ForeignCheckMiddlewareFn { /// check_version CheckVersion, /// build_coinbase BuildCoinbase, - /// verify_slate_messages - VerifySlateMessages, /// receive_tx ReceiveTx, /// contract_new @@ -50,6 +49,8 @@ pub enum ForeignCheckMiddlewareFn { ContractSign, /// finalize_tx FinalizeTx, + /// verify_payment_proof_invoice + VerifyPaymentProofInvoice, } /// Main interface into all wallet API functions. @@ -457,6 +458,13 @@ where pub fn finalize_tx(&self, slate: &Slate, post_automatically: bool) -> Result { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; + if let Some(m) = self.middleware.as_ref() { + m( + ForeignCheckMiddlewareFn::FinalizeTx, + w.w2n_client().get_version_info(), + Some(slate), + )?; + } let post_automatically = match self.doctest_mode { true => false, false => post_automatically, @@ -506,6 +514,13 @@ where ) -> Result<(), Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; + if let Some(m) = self.middleware.as_ref() { + m( + ForeignCheckMiddlewareFn::VerifyPaymentProofInvoice, + w.w2n_client().get_version_info(), + None, + )?; + } foreign::verify_payment_proof_invoice(w, recipient_address, proof) } } diff --git a/controller/tests/contract_early_proofs_srs.rs b/controller/tests/contract_early_proofs_srs.rs index 5d61839..efac025 100644 --- a/controller/tests/contract_early_proofs_srs.rs +++ b/controller/tests/contract_early_proofs_srs.rs @@ -27,7 +27,7 @@ use grin_wallet_libwallet as libwallet; use impls::test_framework::{self}; use libwallet::contract::my_fee_contribution; use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI}; -use libwallet::{Slate, SlateState, Slatepacker, SlatepackerArgs, TxLogEntryType}; +use libwallet::{NodeVersionInfo, Slate, SlateState, Slatepacker, SlatepackerArgs, TxLogEntryType}; use std::sync::atomic::Ordering; use std::thread; use std::time::Duration; @@ -37,6 +37,21 @@ mod common; use common::{clean_output_dir, create_wallets, setup}; use std::path::PathBuf; +fn reject_proof_verification( + method: grin_wallet_api::ForeignCheckMiddlewareFn, + _node_version: Option, + slate: Option<&Slate>, +) -> Result<(), libwallet::Error> { + assert!(matches!( + method, + grin_wallet_api::ForeignCheckMiddlewareFn::VerifyPaymentProofInvoice + )); + assert!(slate.is_none()); + Err(libwallet::Error::GenericError( + "Proof rejected by middleware".to_string(), + )) +} + fn roundtrip_slate(slate: &Slate, version: u16) -> Result { let packer = Slatepacker::new(SlatepackerArgs { sender: None, @@ -213,6 +228,23 @@ fn contract_early_proofs_srs_test_impl(test_dir: &'static str) -> Result<(), lib // Should have all proof fields filled out println!("INVOICE PROOF: {}", invoice_proof_json); + { + let api = grin_wallet_api::Foreign::new( + recv_wallet.clone(), + PathBuf::from(test_dir), + recv_mask.cloned(), + Some(reject_proof_verification), + false, + ); + let err = api + .verify_payment_proof_invoice(recipient_address.as_ref().unwrap(), &invoice_proof) + .unwrap_err(); + assert!(matches!( + err, + libwallet::Error::GenericError(ref msg) + if msg == "Proof rejected by middleware" + )); + } wallet::controller::foreign_single_use( recv_wallet.clone(), diff --git a/controller/tests/no_change.rs b/controller/tests/no_change.rs index aa1a56e..41c46e9 100644 --- a/controller/tests/no_change.rs +++ b/controller/tests/no_change.rs @@ -22,7 +22,7 @@ use std::path::PathBuf; use grin_wallet_libwallet as libwallet; use impls::test_framework::{self, LocalWalletClient}; -use libwallet::{InitTxArgs, IssueInvoiceTxArgs, Slate}; +use libwallet::{InitTxArgs, IssueInvoiceTxArgs, NodeVersionInfo, Slate}; use std::sync::atomic::Ordering; use std::thread; use std::time::Duration; @@ -31,6 +31,21 @@ use std::time::Duration; mod common; use common::{clean_output_dir, create_wallet_proxy, setup}; +fn reject_finalize( + method: grin_wallet_api::ForeignCheckMiddlewareFn, + _node_version: Option, + slate: Option<&Slate>, +) -> Result<(), libwallet::Error> { + assert!(matches!( + method, + grin_wallet_api::ForeignCheckMiddlewareFn::FinalizeTx + )); + assert!(slate.is_some()); + Err(libwallet::Error::GenericError( + "Finalize rejected by middleware".to_string(), + )) +} + fn no_change_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { let mut wallet_proxy = create_wallet_proxy(test_dir); let chain = wallet_proxy.chain.clone(); @@ -182,6 +197,21 @@ fn no_change_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { )?; // wallet 2 finalizes and posts + { + let api = grin_wallet_api::Foreign::new( + wallet2.clone(), + PathBuf::from(test_dir), + mask2_i.clone(), + Some(reject_finalize), + false, + ); + let err = api.finalize_tx(&slate, false).unwrap_err(); + assert!(matches!( + err, + libwallet::Error::GenericError(ref msg) + if msg == "Finalize rejected by middleware" + )); + } wallet::controller::foreign_single_use( wallet2.clone(), PathBuf::from(test_dir),