From 0e83463718001ef14564068f2087fb6dc50b0fa3 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Wed, 1 Feb 2023 10:59:05 +0200 Subject: [PATCH] fix: feature flag separation for validation (#5137) Description --- Removes OpenSSL from the WalletFFI lib as its not required or used by it. Fixes validation feature flags. Motivation and Context --- Recent refactor added `base_node` feature flag to the walletFFI. This should not be done as it adds in all the base node specific crates that not required by the wallet like randomX, lmdb etc. This splits the validation traits and implementations between the features `transactions` and `base_node`. How Has This Been Tested? --- Manual and unit tests Fixes: https://github.com/tari-project/tari/issues/4974 --- Cargo.lock | 3 +- base_layer/core/src/blocks/block.rs | 13 ---- .../unconfirmed_pool/unconfirmed_pool.rs | 3 +- base_layer/core/src/test_helpers/mod.rs | 2 +- .../core/src/transactions/coinbase_builder.rs | 32 +++++----- .../core/src/transactions/test_helpers.rs | 7 +-- .../transaction_components/test.rs | 4 +- .../transaction_builder.rs | 36 +++-------- .../transaction_output.rs | 5 ++ .../transaction_protocol/sender.rs | 51 +++------------ .../aggregate_body_internal_validator.rs | 57 ++++++++++++++--- .../core/src/validation/aggregate_body/mod.rs | 1 - .../block_body_internal_validator.rs | 20 +----- .../core/src/validation/block_body/test.rs | 8 +-- base_layer/core/src/validation/error.rs | 2 + base_layer/core/src/validation/helpers.rs | 2 - base_layer/core/src/validation/mod.rs | 7 +-- base_layer/core/src/validation/test.rs | 6 +- base_layer/core/src/validation/traits.rs | 1 - .../core/src/validation/transaction/mod.rs | 2 - .../transaction/transaction_full_validator.rs | 6 +- .../transaction_internal_validator.rs | 16 ++--- base_layer/core/tests/block_validation.rs | 2 +- base_layer/core/tests/mempool.rs | 39 ++++-------- .../wallet/src/output_manager_service/mod.rs | 7 +-- .../src/output_manager_service/resources.rs | 3 +- .../src/output_manager_service/service.rs | 62 +++---------------- .../wallet/src/transaction_service/error.rs | 11 +--- .../protocols/transaction_receive_protocol.rs | 29 +-------- .../protocols/transaction_send_protocol.rs | 29 +++------ .../wallet/src/transaction_service/service.rs | 32 +--------- .../output_manager_service_tests/service.rs | 6 +- .../transaction_service_tests/service.rs | 37 +---------- base_layer/wallet_ffi/Cargo.toml | 14 +---- infrastructure/libtor/Cargo.toml | 1 + integration_tests/tests/utils/miner.rs | 2 +- integration_tests/tests/utils/transaction.rs | 37 +++++------ 37 files changed, 180 insertions(+), 415 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eaa8890b13..b8c47f2cbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5475,6 +5475,7 @@ dependencies = [ "derivative", "libtor", "log", + "openssl", "rand 0.7.3", "tari_common", "tari_p2p", @@ -5788,9 +5789,7 @@ dependencies = [ "log", "log4rs", "num-traits", - "openssl", "rand 0.7.3", - "security-framework", "serde_json", "tari_common", "tari_common_types", diff --git a/base_layer/core/src/blocks/block.rs b/base_layer/core/src/blocks/block.rs index d017ee70c2..5a43a083d2 100644 --- a/base_layer/core/src/blocks/block.rs +++ b/base_layer/core/src/blocks/block.rs @@ -61,8 +61,6 @@ pub enum BlockValidationError { TransactionError(#[from] TransactionError), #[error("Invalid input in block")] InvalidInput, - #[error("Contains kernels or inputs that are not yet spendable")] - MaturityError, #[error("Mismatched {kind} MMR roots")] MismatchedMmrRoots { kind: &'static str }, #[error("MMR size for {mmr_tree} does not match. Expected: {expected}, received: {actual}")] @@ -71,8 +69,6 @@ pub enum BlockValidationError { expected: u64, actual: u64, }, - #[error("The block weight ({actual_weight}) is above the maximum ({max_weight})")] - BlockTooLarge { actual_weight: u64, max_weight: u64 }, } /// A Tari block. Blocks are linked together into a blockchain. @@ -131,15 +127,6 @@ impl Block { Ok(()) } - /// Checks that all STXO rules (maturity etc) and kernel heights are followed - pub fn check_spend_rules(&self) -> Result<(), BlockValidationError> { - self.body.check_utxo_rules(self.header.height)?; - if self.body.max_kernel_timelock() > self.header.height { - return Err(BlockValidationError::MaturityError); - } - Ok(()) - } - /// Destroys the block and returns the pieces of the block: header, inputs, outputs and kernels pub fn dissolve( self, diff --git a/base_layer/core/src/mempool/unconfirmed_pool/unconfirmed_pool.rs b/base_layer/core/src/mempool/unconfirmed_pool/unconfirmed_pool.rs index 33910354b0..9f5c3290a1 100644 --- a/base_layer/core/src/mempool/unconfirmed_pool/unconfirmed_pool.rs +++ b/base_layer/core/src/mempool/unconfirmed_pool/unconfirmed_pool.rs @@ -711,7 +711,6 @@ mod test { #[test] fn test_double_spend_inputs() { - let rules = create_consensus_rules(); let (tx1, _, _) = tx!(MicroTari(5_000), fee: MicroTari(10), inputs: 1, outputs: 1); const INPUT_AMOUNT: MicroTari = MicroTari(5_000); let (tx2, inputs, _) = tx!(INPUT_AMOUNT, fee: MicroTari(5), inputs: 1, outputs: 1); @@ -749,7 +748,7 @@ mod test { let factories = CryptoFactories::default(); let mut stx_protocol = stx_builder.build(&factories, None, u64::MAX).unwrap(); - stx_protocol.finalize(rules, &factories, None, u64::MAX).unwrap(); + stx_protocol.finalize().unwrap(); let tx3 = stx_protocol.get_transaction().unwrap().clone(); diff --git a/base_layer/core/src/test_helpers/mod.rs b/base_layer/core/src/test_helpers/mod.rs index c119cdd8d8..3f2eef2d06 100644 --- a/base_layer/core/src/test_helpers/mod.rs +++ b/base_layer/core/src/test_helpers/mod.rs @@ -85,7 +85,7 @@ pub fn create_block(rules: &ConsensusManager, prev_block: &Block, spec: BlockSpe .with_fees(0.into()) .with_nonce(0.into()) .with_spend_key(block_height.into()) - .build_with_reward(rules.clone(), rules.consensus_constants(block_height), reward) + .build_with_reward(rules.consensus_constants(block_height), reward) .unwrap(); let mut block = header diff --git a/base_layer/core/src/transactions/coinbase_builder.rs b/base_layer/core/src/transactions/coinbase_builder.rs index 9884d277b7..6de524109d 100644 --- a/base_layer/core/src/transactions/coinbase_builder.rs +++ b/base_layer/core/src/transactions/coinbase_builder.rs @@ -36,7 +36,6 @@ use crate::{ consensus::{ emission::{Emission, EmissionSchedule}, ConsensusConstants, - ConsensusManager, }, covenants::Covenant, transactions::{ @@ -178,13 +177,12 @@ impl CoinbaseBuilder { pub fn build( self, - rules: ConsensusManager, constants: &ConsensusConstants, emission_schedule: &EmissionSchedule, ) -> Result<(Transaction, UnblindedOutput), CoinbaseBuildError> { let height = self.block_height.ok_or(CoinbaseBuildError::MissingBlockHeight)?; let reward = emission_schedule.block_reward(height); - self.build_with_reward(rules, constants, reward) + self.build_with_reward(constants, reward) } /// Try and construct a Coinbase Transaction while specifying the block reward. The other parameters (keys, nonces @@ -197,7 +195,6 @@ impl CoinbaseBuilder { #[allow(clippy::erasing_op)] // This is for 0 * uT pub fn build_with_reward( self, - rules: ConsensusManager, constants: &ConsensusConstants, block_reward: MicroTari, ) -> Result<(Transaction, UnblindedOutput), CoinbaseBuildError> { @@ -295,7 +292,7 @@ impl CoinbaseBuilder { .with_reward(total_reward) .with_kernel(kernel); let tx = builder - .build(rules, &self.factories, None, height) + .build() .map_err(|e| CoinbaseBuildError::BuildError(e.to_string()))?; Ok((tx, unblinded_output)) } @@ -341,7 +338,7 @@ mod test { let (builder, rules, _) = get_builder(); assert_eq!( builder - .build(rules.clone(), rules.consensus_constants(0), rules.emission_schedule(),) + .build(rules.consensus_constants(0), rules.emission_schedule(),) .unwrap_err(), CoinbaseBuildError::MissingBlockHeight ); @@ -353,7 +350,7 @@ mod test { let builder = builder.with_block_height(42); assert_eq!( builder - .build(rules.clone(), rules.consensus_constants(42), rules.emission_schedule(),) + .build(rules.consensus_constants(42), rules.emission_schedule(),) .unwrap_err(), CoinbaseBuildError::MissingFees ); @@ -368,7 +365,7 @@ mod test { let builder = builder.with_block_height(42).with_fees(fees).with_nonce(p.nonce); assert_eq!( builder - .build(rules.clone(), rules.consensus_constants(42), rules.emission_schedule(),) + .build(rules.consensus_constants(42), rules.emission_schedule(),) .unwrap_err(), CoinbaseBuildError::MissingSpendKey ); @@ -384,7 +381,7 @@ mod test { .with_nonce(p.nonce.clone()) .with_spend_key(p.spend_key.clone()); let (tx, _unblinded_output) = builder - .build(rules.clone(), rules.consensus_constants(42), rules.emission_schedule()) + .build(rules.consensus_constants(42), rules.emission_schedule()) .unwrap(); let utxo = &tx.body.outputs()[0]; let block_reward = rules.emission_schedule().block_reward(42) + 145 * uT; @@ -422,7 +419,7 @@ mod test { .with_spend_key(p.spend_key.clone()) .with_rewind_data(rewind_data.clone()); let (tx, _) = builder - .build(rules.clone(), rules.consensus_constants(42), rules.emission_schedule()) + .build(rules.consensus_constants(42), rules.emission_schedule()) .unwrap(); let block_reward = rules.emission_schedule().block_reward(42) + 145 * uT; @@ -448,7 +445,7 @@ mod test { .with_nonce(p.nonce.clone()) .with_spend_key(p.spend_key); let (mut tx, _) = builder - .build(rules.clone(), rules.consensus_constants(42), rules.emission_schedule()) + .build(rules.consensus_constants(42), rules.emission_schedule()) .unwrap(); tx.body.outputs_mut()[0].features.maturity = 1; assert!(matches!( @@ -475,7 +472,7 @@ mod test { .with_nonce(p.nonce.clone()) .with_spend_key(p.spend_key.clone()); let (mut tx, _) = builder - .build(rules.clone(), rules.consensus_constants(0), rules.emission_schedule()) + .build(rules.consensus_constants(0), rules.emission_schedule()) .unwrap(); let block_reward = rules.emission_schedule().block_reward(42) + missing_fee; let builder = CoinbaseBuilder::new(factories.clone()); @@ -485,7 +482,7 @@ mod test { .with_nonce(p.nonce.clone()) .with_spend_key(p.spend_key.clone()); let (tx2, _) = builder - .build(rules.clone(), rules.consensus_constants(0), rules.emission_schedule()) + .build(rules.consensus_constants(0), rules.emission_schedule()) .unwrap(); let mut coinbase2 = tx2.body.outputs()[0].clone(); let mut coinbase_kernel2 = tx2.body.kernels()[0].clone(); @@ -512,7 +509,7 @@ mod test { .with_nonce(p.nonce.clone()) .with_spend_key(p.spend_key); let (tx3, _) = builder - .build(rules.clone(), rules.consensus_constants(0), rules.emission_schedule()) + .build(rules.consensus_constants(0), rules.emission_schedule()) .unwrap(); assert!(tx3 .body @@ -539,7 +536,7 @@ mod test { .with_nonce(p.nonce.clone()) .with_spend_key(p.spend_key.clone()); let (mut tx, _) = builder - .build(rules.clone(), rules.consensus_constants(0), rules.emission_schedule()) + .build(rules.consensus_constants(0), rules.emission_schedule()) .unwrap(); let block_reward = rules.emission_schedule().block_reward(42) + missing_fee; let builder = CoinbaseBuilder::new(factories.clone()); @@ -549,7 +546,7 @@ mod test { .with_nonce(p.nonce.clone()) .with_spend_key(p.spend_key); let (tx2, output) = builder - .build(rules.clone(), rules.consensus_constants(0), rules.emission_schedule()) + .build(rules.consensus_constants(0), rules.emission_schedule()) .unwrap(); let mut tx_kernel_test = tx.clone(); @@ -571,6 +568,7 @@ mod test { tx.body.add_output(coinbase2); tx.body.add_kernel(coinbase_kernel2); + tx.body.sort(); // lets add duplciate coinbase kernel let mut coinbase2 = tx2.body.outputs()[0].clone(); @@ -579,6 +577,8 @@ mod test { tx_kernel_test.body.add_output(coinbase2); tx_kernel_test.body.add_kernel(coinbase_kernel2); + tx_kernel_test.body.sort(); + // test catches that coinbase count on the utxo is wrong assert!(matches!( tx.body.check_coinbase_output( diff --git a/base_layer/core/src/transactions/test_helpers.rs b/base_layer/core/src/transactions/test_helpers.rs index 612a0a2177..dcfa78d345 100644 --- a/base_layer/core/src/transactions/test_helpers.rs +++ b/base_layer/core/src/transactions/test_helpers.rs @@ -624,7 +624,7 @@ pub fn create_sender_transaction_protocol_with( }); let mut stx_protocol = stx_builder.build(&factories, None, u64::MAX).unwrap(); - stx_protocol.finalize(rules, &factories, None, u64::MAX)?; + stx_protocol.finalize()?; Ok(stx_protocol) } @@ -634,11 +634,8 @@ pub fn create_sender_transaction_protocol_with( /// This is obviously less efficient, but is offered as a convenience. /// The output features will be applied to every output pub fn spend_utxos(schema: TransactionSchema) -> (Transaction, Vec) { - let rules = ConsensusManager::builder(Network::LocalNet).build(); let (mut stx_protocol, outputs) = create_stx_protocol(schema); - stx_protocol - .finalize(rules, &CryptoFactories::default(), None, u64::MAX) - .unwrap(); + stx_protocol.finalize().unwrap(); let txn = stx_protocol.get_transaction().unwrap().clone(); (txn, outputs) } diff --git a/base_layer/core/src/transactions/transaction_components/test.rs b/base_layer/core/src/transactions/transaction_components/test.rs index 64acd8cbce..458dfad632 100644 --- a/base_layer/core/src/transactions/transaction_components/test.rs +++ b/base_layer/core/src/transactions/transaction_components/test.rs @@ -356,7 +356,7 @@ fn check_cut_through() { assert_eq!(tx2.body.outputs().len(), 3); assert_eq!(tx2.body.kernels().len(), 1); - let tx3 = tx + tx2; + let mut tx3 = tx + tx2; let mut tx3_cut_through = tx3.clone(); // check that all inputs are as we expect them to be assert_eq!(tx3.body.inputs().len(), 3); @@ -376,6 +376,8 @@ fn check_cut_through() { tx3_cut_through.body.outputs_mut().retain(|x| !input.is_equal_to(x)); tx3_cut_through.body.inputs_mut().retain(|x| *x != input); } + tx3.body.sort(); + tx3_cut_through.body.sort(); // Validate basis transaction where cut-through has not been applied. validator.validate(&tx3, None, None, u64::MAX).unwrap(); diff --git a/base_layer/core/src/transactions/transaction_components/transaction_builder.rs b/base_layer/core/src/transactions/transaction_components/transaction_builder.rs index df2cd3a2a9..7d1985f957 100644 --- a/base_layer/core/src/transactions/transaction_components/transaction_builder.rs +++ b/base_layer/core/src/transactions/transaction_components/transaction_builder.rs @@ -23,23 +23,12 @@ // Portions of this file were originally copyrighted (c) 2018 The Grin Developers, issued under the Apache License, // Version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0. -use tari_common_types::types::{BlindingFactor, HashOutput}; +use tari_common_types::types::BlindingFactor; -use crate::{ - consensus::ConsensusManager, - transactions::{ - aggregated_body::AggregateBody, - tari_amount::MicroTari, - transaction_components::{ - Transaction, - TransactionError, - TransactionInput, - TransactionKernel, - TransactionOutput, - }, - CryptoFactories, - }, - validation::transaction::TransactionInternalConsistencyValidator, +use crate::transactions::{ + aggregated_body::AggregateBody, + tari_amount::MicroTari, + transaction_components::{Transaction, TransactionError, TransactionInput, TransactionKernel, TransactionOutput}, }; //---------------------------------------- Transaction Builder ----------------------------------------------------// @@ -104,20 +93,11 @@ impl TransactionBuilder { } /// Build the transaction. - pub fn build( - self, - rules: ConsensusManager, - factories: &CryptoFactories, - prev_header: Option, - height: u64, - ) -> Result { + pub fn build(self) -> Result { if let (Some(script_offset), Some(offset)) = (self.script_offset, self.offset) { let (i, o, k) = self.body.dissolve(); - let tx = Transaction::new(i, o, k, offset, script_offset); - let validator = TransactionInternalConsistencyValidator::new(true, rules, factories.clone()); - validator - .validate(&tx, self.reward, prev_header, height) - .map_err(|err| TransactionError::ValidationError(err.to_string()))?; + let mut tx = Transaction::new(i, o, k, offset, script_offset); + tx.body.sort(); Ok(tx) } else { Err(TransactionError::ValidationError( diff --git a/base_layer/core/src/transactions/transaction_components/transaction_output.rs b/base_layer/core/src/transactions/transaction_components/transaction_output.rs index b207222ca6..5511913447 100644 --- a/base_layer/core/src/transactions/transaction_components/transaction_output.rs +++ b/base_layer/core/src/transactions/transaction_components/transaction_output.rs @@ -160,6 +160,11 @@ impl TransactionOutput { &self.proof } + /// Accessor method for the TariScript contained in an output + pub fn script(&self) -> &TariScript { + &self.script + } + pub fn hash(&self) -> FixedHash { transaction_components::hash_output( self.version, diff --git a/base_layer/core/src/transactions/transaction_protocol/sender.rs b/base_layer/core/src/transactions/transaction_protocol/sender.rs index a1c36cdf99..f6b875b3ba 100644 --- a/base_layer/core/src/transactions/transaction_protocol/sender.rs +++ b/base_layer/core/src/transactions/transaction_protocol/sender.rs @@ -37,10 +37,9 @@ use tari_script::TariScript; use super::CalculateTxIdTransactionProtocolHasherBlake256; use crate::{ - consensus::{ConsensusConstants, ConsensusManager}, + consensus::ConsensusConstants, covenants::Covenant, transactions::{ - crypto_factories::CryptoFactories, fee::Fee, tari_amount::*, transaction_components::{ @@ -48,7 +47,6 @@ use crate::{ OutputFeatures, Transaction, TransactionBuilder, - TransactionError, TransactionInput, TransactionKernel, TransactionOutput, @@ -63,7 +61,6 @@ use crate::{ TransactionProtocolError as TPE, }, }, - validation::transaction::TransactionInternalConsistencyValidator, }; //---------------------------------------- Local Data types ----------------------------------------------------// @@ -497,11 +494,7 @@ impl SenderTransactionProtocol { } /// Attempts to build the final transaction. - fn build_transaction( - info: &RawTransactionInfo, - rules: ConsensusManager, - factories: &CryptoFactories, - ) -> Result { + fn build_transaction(info: &RawTransactionInfo) -> Result { let mut tx_builder = TransactionBuilder::new(); for i in &info.inputs { tx_builder.add_input(i.clone()); @@ -525,9 +518,7 @@ impl SenderTransactionProtocol { .with_signature(&s_agg) .build()?; tx_builder.with_kernel(kernel); - tx_builder - .build(rules, factories, info.prev_header, info.height) - .map_err(TPE::from) + tx_builder.build().map_err(TPE::from) } /// Performs sanity checks on the collected transaction pieces prior to building the final Transaction instance @@ -589,13 +580,7 @@ impl SenderTransactionProtocol { /// formally validate the transaction terms (no inflation, signature matches etc). If any step fails, /// the transaction protocol moves to Failed state and we are done; you can't rescue the situation. The function /// returns `Ok(false)` in this instance. - pub fn finalize( - &mut self, - rules: ConsensusManager, - factories: &CryptoFactories, - prev_header: Option, - height: u64, - ) -> Result<(), TPE> { + pub fn finalize(&mut self) -> Result<(), TPE> { // Create the final aggregated signature, moving to the Failed state if anything goes wrong match &mut self.state { SenderState::Finalizing(_) => { @@ -609,22 +594,9 @@ impl SenderTransactionProtocol { // Validate the inputs we have, and then construct the final transaction match &self.state { SenderState::Finalizing(info) => { - let result = self - .validate() - .and_then(|_| Self::build_transaction(info, rules.clone(), factories)); + let result = self.validate().and_then(|_| Self::build_transaction(info)); match result { - Ok(mut transaction) => { - transaction.body.sort(); - let validator = TransactionInternalConsistencyValidator::new(true, rules, factories.clone()); - let result = validator - .validate(&transaction, None, prev_header, height) - .map_err(|err| { - TPE::TransactionBuildError(TransactionError::ValidationError(err.to_string())) - }); - if let Err(e) = result { - self.state = SenderState::Failed(e.clone()); - return Err(e); - } + Ok(transaction) => { self.state = SenderState::FinalizedTransaction(transaction); Ok(()) }, @@ -951,7 +923,6 @@ mod test { #[test] fn zero_recipients() { - let rules = create_consensus_rules(); let factories = CryptoFactories::default(); let p1 = TestParams::new(); let p2 = TestParams::new(); @@ -980,7 +951,7 @@ mod test { let mut sender = builder.build(&factories, None, u64::MAX).unwrap(); assert!(!sender.is_failed()); assert!(sender.is_finalizing()); - match sender.finalize(rules, &factories, None, u64::MAX) { + match sender.finalize() { Ok(_) => (), Err(e) => panic!("{:?}", e), } @@ -990,7 +961,6 @@ mod test { #[test] fn single_recipient_no_change() { - let rules = create_consensus_rules(); let factories = CryptoFactories::default(); // Alice's parameters let a = TestParams::new(); @@ -1027,7 +997,7 @@ mod test { alice.add_single_recipient_info(bob_info.clone()).unwrap(); // Transaction should be complete assert!(alice.is_finalizing()); - match alice.finalize(rules, &factories, None, u64::MAX) { + match alice.finalize() { Ok(_) => (), Err(e) => panic!("{:?}", e), }; @@ -1110,7 +1080,7 @@ mod test { alice.add_single_recipient_info(bob_info).unwrap(); // Transaction should be complete assert!(alice.is_finalizing()); - match alice.finalize(rules.clone(), &factories, None, u64::MAX) { + match alice.finalize() { Ok(_) => (), Err(e) => panic!("{:?}", e), }; @@ -1245,7 +1215,6 @@ mod test { #[test] fn single_recipient_with_rewindable_change_and_receiver_outputs_bulletproofs() { - let rules = create_consensus_rules(); let factories = CryptoFactories::default(); // Alice's parameters let alice_test_params = TestParams::new(); @@ -1308,7 +1277,7 @@ mod test { alice.add_single_recipient_info(bob_info).unwrap(); // Transaction should be complete assert!(alice.is_finalizing()); - match alice.finalize(rules, &factories, None, u64::MAX) { + match alice.finalize() { Ok(_) => (), Err(e) => panic!("{:?}", e), }; diff --git a/base_layer/core/src/validation/aggregate_body/aggregate_body_internal_validator.rs b/base_layer/core/src/validation/aggregate_body/aggregate_body_internal_validator.rs index 4814fc4fc2..1adf0e9644 100644 --- a/base_layer/core/src/validation/aggregate_body/aggregate_body_internal_validator.rs +++ b/base_layer/core/src/validation/aggregate_body/aggregate_body_internal_validator.rs @@ -41,7 +41,6 @@ use tari_script::ScriptContext; use tari_utilities::hex::Hex; use crate::{ - blocks::BlockValidationError, consensus::{ConsensusConstants, ConsensusManager}, transactions::{ aggregated_body::AggregateBody, @@ -59,6 +58,8 @@ use crate::{ validation::{ helpers::{ check_permitted_output_types, + check_tari_script_byte_size, + is_all_unique_and_sorted, validate_input_version, validate_kernel_version, validate_output_version, @@ -108,9 +109,18 @@ impl AggregateBodyInternalConsistencyValidator { ) -> Result<(), ValidationError> { let total_reward = total_reward.unwrap_or(MicroTari::zero()); - // old internal validatior + // old internal validator verify_kernel_signatures(body)?; + check_script_size( + body, + self.consensus_manager + .consensus_constants(height) + .get_max_script_byte_size(), + )?; + + check_sorting_and_duplicates(body)?; + let total_offset = self.factories.commitment.commit_value(tx_offset, total_reward.0); validate_kernel_sum(body, total_offset, &self.factories.commitment)?; @@ -157,6 +167,38 @@ fn verify_kernel_signatures(body: &AggregateBody) -> Result<(), ValidationError> Ok(()) } +/// Verify that the TariScript is not larger than the max size +fn check_script_size(body: &AggregateBody, max_script_size: usize) -> Result<(), ValidationError> { + for output in body.outputs() { + check_tari_script_byte_size(output.script(), max_script_size).map_err(|e| { + warn!( + target: LOG_TARGET, + "output ({}) script size exceeded max size {:?}.", output, e + ); + e + })?; + } + Ok(()) +} + +// This function checks for duplicate inputs and outputs. There should be no duplicate inputs or outputs in a aggregated +// body +fn check_sorting_and_duplicates(body: &AggregateBody) -> Result<(), ValidationError> { + if !is_all_unique_and_sorted(body.inputs()) { + return Err(ValidationError::UnsortedOrDuplicateInput); + } + + if !is_all_unique_and_sorted(body.outputs()) { + return Err(ValidationError::UnsortedOrDuplicateOutput); + } + + if !is_all_unique_and_sorted(body.kernels()) { + return Err(ValidationError::UnsortedOrDuplicateKernel); + } + + Ok(()) +} + /// Confirm that the (sum of the outputs) - (sum of inputs) = Kernel excess /// /// The offset_and_reward commitment includes the offset & the total coinbase reward (block reward + fees for @@ -289,18 +331,17 @@ fn check_weight( Ok(()) } else { - Err(BlockValidationError::BlockTooLarge { + Err(ValidationError::BlockTooLarge { actual_weight: block_weight, max_weight, - } - .into()) + }) } } /// Checks that all transactions (given by their kernels) are spendable at the given height -fn check_kernel_lock_height(height: u64, kernels: &[TransactionKernel]) -> Result<(), BlockValidationError> { +fn check_kernel_lock_height(height: u64, kernels: &[TransactionKernel]) -> Result<(), ValidationError> { if kernels.iter().any(|k| k.lock_height > height) { - return Err(BlockValidationError::MaturityError); + return Err(ValidationError::MaturityError); } Ok(()) } @@ -424,7 +465,7 @@ mod test { kernel.lock_height = 2; assert!(matches!( check_kernel_lock_height(1, &[kernel.clone()]), - Err(BlockValidationError::MaturityError) + Err(ValidationError::MaturityError) )); check_kernel_lock_height(2, &[kernel.clone()]).unwrap(); diff --git a/base_layer/core/src/validation/aggregate_body/mod.rs b/base_layer/core/src/validation/aggregate_body/mod.rs index 1804718a0e..eb4ef67350 100644 --- a/base_layer/core/src/validation/aggregate_body/mod.rs +++ b/base_layer/core/src/validation/aggregate_body/mod.rs @@ -22,6 +22,5 @@ mod aggregate_body_internal_validator; pub use aggregate_body_internal_validator::AggregateBodyInternalConsistencyValidator; - mod aggregate_body_chain_validator; pub use aggregate_body_chain_validator::AggregateBodyChainLinkedValidator; diff --git a/base_layer/core/src/validation/block_body/block_body_internal_validator.rs b/base_layer/core/src/validation/block_body/block_body_internal_validator.rs index d8a357deaa..06c2b0ddb2 100644 --- a/base_layer/core/src/validation/block_body/block_body_internal_validator.rs +++ b/base_layer/core/src/validation/block_body/block_body_internal_validator.rs @@ -29,7 +29,6 @@ use crate::{ transactions::{aggregated_body::AggregateBody, CryptoFactories}, validation::{ aggregate_body::AggregateBodyInternalConsistencyValidator, - helpers::is_all_unique_and_sorted, InternalConsistencyValidator, ValidationError, }, @@ -89,7 +88,7 @@ fn validate_block_specific_checks( warn!(target: LOG_TARGET, "Attempt to validate genesis block"); return Err(ValidationError::ValidatingGenesis); } - check_sorting_and_duplicates(&block.body)?; + check_coinbase_output(block, consensus_manager, factories)?; check_output_features(&block.body, constants)?; @@ -149,20 +148,3 @@ fn check_coinbase_output( ) .map_err(ValidationError::from) } - -// This function checks for duplicate inputs and outputs. There should be no duplicate inputs or outputs in a block -fn check_sorting_and_duplicates(body: &AggregateBody) -> Result<(), ValidationError> { - if !is_all_unique_and_sorted(body.inputs()) { - return Err(ValidationError::UnsortedOrDuplicateInput); - } - - if !is_all_unique_and_sorted(body.outputs()) { - return Err(ValidationError::UnsortedOrDuplicateOutput); - } - - if !is_all_unique_and_sorted(body.kernels()) { - return Err(ValidationError::UnsortedOrDuplicateKernel); - } - - Ok(()) -} diff --git a/base_layer/core/src/validation/block_body/test.rs b/base_layer/core/src/validation/block_body/test.rs index b74bf772a5..c8b2bd3caa 100644 --- a/base_layer/core/src/validation/block_body/test.rs +++ b/base_layer/core/src/validation/block_body/test.rs @@ -110,11 +110,7 @@ async fn it_checks_exactly_one_coinbase() { .with_fees(0.into()) .with_nonce(0.into()) .with_spend_key(42.into()) - .build_with_reward( - blockchain.rules().clone(), - blockchain.rules().consensus_constants(1), - coinbase.value, - ) + .build_with_reward(blockchain.rules().consensus_constants(1), coinbase.value) .unwrap(); block.body.add_output( @@ -214,7 +210,7 @@ async fn it_limits_the_script_byte_size() { .add_consensus_constants( ConsensusConstantsBuilder::new(Network::LocalNet) .with_coinbase_lockheight(0) - .with_max_script_byte_size(0) + .with_max_script_byte_size(2) .build(), ) .build(); diff --git a/base_layer/core/src/validation/error.rs b/base_layer/core/src/validation/error.rs index bb123c94f5..32ddef3d34 100644 --- a/base_layer/core/src/validation/error.rs +++ b/base_layer/core/src/validation/error.rs @@ -44,6 +44,8 @@ pub enum ValidationError { BlockError(#[from] BlockValidationError), #[error("Contains kernels or inputs that are not yet spendable")] MaturityError, + #[error("The block weight ({actual_weight}) is above the maximum ({max_weight})")] + BlockTooLarge { actual_weight: u64, max_weight: u64 }, #[error("Contains {} unknown inputs", .0.len())] UnknownInputs(Vec), #[error("Contains an unknown input")] diff --git a/base_layer/core/src/validation/helpers.rs b/base_layer/core/src/validation/helpers.rs index 1d533ac49a..7ddc54f4ed 100644 --- a/base_layer/core/src/validation/helpers.rs +++ b/base_layer/core/src/validation/helpers.rs @@ -75,7 +75,6 @@ pub fn calc_median_timestamp(timestamps: &[EpochTime]) -> EpochTime { trace!(target: LOG_TARGET, "Median timestamp:{}", median_timestamp); median_timestamp } - pub fn check_header_timestamp_greater_than_median( block_header: &BlockHeader, timestamps: &[EpochTime], @@ -105,7 +104,6 @@ pub fn check_header_timestamp_greater_than_median( Ok(()) } - pub fn check_target_difficulty( block_header: &BlockHeader, target: Difficulty, diff --git a/base_layer/core/src/validation/mod.rs b/base_layer/core/src/validation/mod.rs index 478418a523..af0ea9d261 100644 --- a/base_layer/core/src/validation/mod.rs +++ b/base_layer/core/src/validation/mod.rs @@ -33,6 +33,7 @@ pub use error::ValidationError; pub(crate) mod helpers; mod traits; + pub use traits::{ BlockBodyValidator, CandidateBlockValidator, @@ -41,17 +42,13 @@ pub use traits::{ InternalConsistencyValidator, TransactionValidator, }; - pub mod block_body; mod difficulty_calculator; pub use difficulty_calculator::*; +mod chain_balance; pub mod mocks; pub mod transaction; -// pub mod header_validator; - -mod chain_balance; pub use chain_balance::ChainBalanceValidator; - pub mod aggregate_body; pub mod header; diff --git a/base_layer/core/src/validation/test.rs b/base_layer/core/src/validation/test.rs index 8f016b55dc..c5364ede84 100644 --- a/base_layer/core/src/validation/test.rs +++ b/base_layer/core/src/validation/test.rs @@ -425,7 +425,8 @@ mod transaction_validator { let validator = TransactionInternalConsistencyValidator::new(true, consensus_manager, factories); let features = OutputFeatures::create_coinbase(0, None); let (tx, _, _) = tx!(MicroTari(100_000), fee: MicroTari(5), inputs: 1, outputs: 1, features: features); - let err = validator.validate_with_current_tip(&tx, db).unwrap_err(); + let tip = db.get_chain_metadata().unwrap(); + let err = validator.validate_with_current_tip(&tx, tip).unwrap_err(); unpack_enum!(ValidationError::ErroneousCoinbaseOutput = err); } @@ -438,7 +439,8 @@ mod transaction_validator { let mut features = OutputFeatures { ..Default::default() }; features.coinbase_extra = b"deadbeef".to_vec(); let (tx, _, _) = tx!(MicroTari(100_000), fee: MicroTari(5), inputs: 1, outputs: 1, features: features); - let err = validator.validate_with_current_tip(&tx, db).unwrap_err(); + let tip = db.get_chain_metadata().unwrap(); + let err = validator.validate_with_current_tip(&tx, tip).unwrap_err(); assert!(matches!( err, ValidationError::TransactionError(TransactionError::NonCoinbaseHasOutputFeaturesCoinbaseExtra) diff --git a/base_layer/core/src/validation/traits.rs b/base_layer/core/src/validation/traits.rs index 6bf3853966..d4cdd97244 100644 --- a/base_layer/core/src/validation/traits.rs +++ b/base_layer/core/src/validation/traits.rs @@ -19,7 +19,6 @@ // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - use tari_common_types::{chain_metadata::ChainMetadata, types::Commitment}; use tari_utilities::epoch_time::EpochTime; diff --git a/base_layer/core/src/validation/transaction/mod.rs b/base_layer/core/src/validation/transaction/mod.rs index 93a5ab26e0..ac6da98857 100644 --- a/base_layer/core/src/validation/transaction/mod.rs +++ b/base_layer/core/src/validation/transaction/mod.rs @@ -22,9 +22,7 @@ mod transaction_internal_validator; pub use transaction_internal_validator::TransactionInternalConsistencyValidator; - mod transaction_chain_validator; pub use transaction_chain_validator::TransactionChainLinkedValidator; - mod transaction_full_validator; pub use transaction_full_validator::TransactionFullValidator; diff --git a/base_layer/core/src/validation/transaction/transaction_full_validator.rs b/base_layer/core/src/validation/transaction/transaction_full_validator.rs index c9848733f4..4be593e393 100644 --- a/base_layer/core/src/validation/transaction/transaction_full_validator.rs +++ b/base_layer/core/src/validation/transaction/transaction_full_validator.rs @@ -57,7 +57,11 @@ impl TransactionFullValidator { impl TransactionValidator for TransactionFullValidator { fn validate(&self, tx: &Transaction) -> Result<(), ValidationError> { - self.internal_validator.validate_with_current_tip(tx, self.db.clone())?; + let tip = { + let db = self.db.db_read_access()?; + db.fetch_chain_metadata() + }?; + self.internal_validator.validate_with_current_tip(tx, tip)?; self.chain_validator.validate(tx)?; Ok(()) diff --git a/base_layer/core/src/validation/transaction/transaction_internal_validator.rs b/base_layer/core/src/validation/transaction/transaction_internal_validator.rs index f9cfec9a85..98e3235572 100644 --- a/base_layer/core/src/validation/transaction/transaction_internal_validator.rs +++ b/base_layer/core/src/validation/transaction/transaction_internal_validator.rs @@ -20,10 +20,9 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use tari_common_types::types::HashOutput; +use tari_common_types::{chain_metadata::ChainMetadata, types::HashOutput}; use crate::{ - chain_storage::{BlockchainBackend, BlockchainDatabase}, consensus::ConsensusManager, transactions::{tari_amount::MicroTari, transaction_components::Transaction, CryptoFactories}, validation::{aggregate_body::AggregateBodyInternalConsistencyValidator, ValidationError}, @@ -65,10 +64,10 @@ impl TransactionInternalConsistencyValidator { .validate(&tx.body, &tx.offset, &tx.script_offset, reward, prev_header, height) } - pub fn validate_with_current_tip( + pub fn validate_with_current_tip( &self, tx: &Transaction, - db: BlockchainDatabase, + tip_metadata: ChainMetadata, ) -> Result<(), ValidationError> { if tx.body.outputs().iter().any(|o| o.features.is_coinbase()) { return Err(ValidationError::ErroneousCoinbaseOutput); @@ -78,18 +77,13 @@ impl TransactionInternalConsistencyValidator { // only coinbases may have the extra field set (the only field that the fn argument affects). tx.body.check_output_features(1)?; - let tip = { - let db = db.db_read_access()?; - db.fetch_chain_metadata() - }?; - self.aggregate_body_validator.validate( &tx.body, &tx.offset, &tx.script_offset, None, - Some(*tip.best_block()), - tip.height_of_longest_chain(), + Some(*tip_metadata.best_block()), + tip_metadata.height_of_longest_chain(), ) } } diff --git a/base_layer/core/tests/block_validation.rs b/base_layer/core/tests/block_validation.rs index b6797aa31d..a225e3dea5 100644 --- a/base_layer/core/tests/block_validation.rs +++ b/base_layer/core/tests/block_validation.rs @@ -746,7 +746,7 @@ async fn test_block_sync_body_validator() { assert!( matches!( err, - ValidationError::BlockError(BlockValidationError::BlockTooLarge { actual_weight, max_weight }) if + ValidationError::BlockTooLarge { actual_weight, max_weight } if actual_weight == 449 && max_weight == 400 ), "{}", diff --git a/base_layer/core/tests/mempool.rs b/base_layer/core/tests/mempool.rs index 70266646f7..acb6db10ae 100644 --- a/base_layer/core/tests/mempool.rs +++ b/base_layer/core/tests/mempool.rs @@ -40,7 +40,6 @@ use tari_common_types::types::{Commitment, PrivateKey, PublicKey, Signature}; use tari_comms_dht::domain_message::OutboundDomainMessage; use tari_core::{ base_node::state_machine_service::states::{ListeningInfo, StateInfo, StatusInfo}, - blocks::BlockValidationError, consensus::{ConsensusConstantsBuilder, ConsensusManager, NetworkConsensus}, mempool::{Mempool, MempoolConfig, MempoolServiceConfig, TxStorageResponse}, proof_of_work::Difficulty, @@ -1013,7 +1012,8 @@ async fn consensus_validation_large_tx() { .build() .unwrap(); let kernels = vec![kernel]; - let tx = Transaction::new(inputs, outputs, kernels, offset, script_offset_pvt); + let mut tx = Transaction::new(inputs, outputs, kernels, offset, script_offset_pvt); + tx.body.sort(); let height = blocks.len() as u64; let constants = consensus_manager.consensus_constants(height); @@ -1022,10 +1022,7 @@ async fn consensus_validation_large_tx() { let factories = CryptoFactories::default(); let validator = TransactionInternalConsistencyValidator::new(true, consensus_manager.clone(), factories); let err = validator.validate(&tx, None, None, u64::MAX).unwrap_err(); - assert!(matches!( - err, - ValidationError::BlockError(BlockValidationError::BlockTooLarge { .. }) - )); + assert!(matches!(err, ValidationError::BlockTooLarge { .. })); let weighting = constants.transaction_weight(); let weight = tx.calculate_weight(weighting); @@ -1126,10 +1123,10 @@ async fn consensus_validation_versions() { ); let txs = vec![schema]; generate_new_block(&mut store, &mut blocks, &mut outputs, txs, &consensus_manager).unwrap(); - + let validator = TransactionInternalConsistencyValidator::new(true, consensus_manager, CryptoFactories::default()); // Cases: // invalid input version - let tx = TransactionSchema { + let tx_schema = TransactionSchema { from: vec![outputs[1][0].clone()], to: vec![1 * T], to_outputs: vec![], @@ -1142,15 +1139,11 @@ async fn consensus_validation_versions() { input_version: Some(TransactionInputVersion::V1), output_version: None, }; - - // TODO: find a way to construct and invalid transaction in tests to pass it to the mempool - panic::catch_unwind(|| { - spend_utxos(tx); - }) - .unwrap_err(); + let (tx, _) = spend_utxos(tx_schema); + validator.validate(&tx, Some(25.into()), None, u64::MAX).unwrap_err(); // invalid output version - let tx = TransactionSchema { + let tx_schema = TransactionSchema { from: vec![outputs[1][1].clone()], to: vec![], to_outputs: vec![output_v1_features_v0], @@ -1164,14 +1157,11 @@ async fn consensus_validation_versions() { output_version: Some(TransactionOutputVersion::V1), }; - // TODO: find a way to construct and invalid transaction in tests to pass it to the mempool - panic::catch_unwind(|| { - spend_utxos(tx); - }) - .unwrap_err(); + let (tx, _) = spend_utxos(tx_schema); + validator.validate(&tx, Some(25.into()), None, u64::MAX).unwrap_err(); // invalid output features version - let tx = TransactionSchema { + let tx_schema = TransactionSchema { from: vec![outputs[1][2].clone()], to: vec![], to_outputs: vec![output_v0_features_v1], @@ -1185,11 +1175,8 @@ async fn consensus_validation_versions() { output_version: None, }; - // TODO: find a way to construct and invalid transaction in tests to pass it to the mempool - panic::catch_unwind(|| { - spend_utxos(tx); - }) - .unwrap_err(); + let (tx, _) = spend_utxos(tx_schema); + validator.validate(&tx, Some(25.into()), None, u64::MAX).unwrap_err(); } #[tokio::test] diff --git a/base_layer/wallet/src/output_manager_service/mod.rs b/base_layer/wallet/src/output_manager_service/mod.rs index c6d851b782..49a49371b4 100644 --- a/base_layer/wallet/src/output_manager_service/mod.rs +++ b/base_layer/wallet/src/output_manager_service/mod.rs @@ -38,10 +38,7 @@ use std::{marker::PhantomData, sync::Arc}; use futures::future; use log::*; use tari_comms::NodeIdentity; -use tari_core::{ - consensus::{ConsensusManager, NetworkConsensus}, - transactions::CryptoFactories, -}; +use tari_core::{consensus::NetworkConsensus, transactions::CryptoFactories}; use tari_service_framework::{ async_trait, reply_channel, @@ -118,7 +115,6 @@ where let factories = self.factories.clone(); let config = self.config.clone(); let constants = self.network.create_consensus_constants().pop().unwrap(); - let consensus_manager = ConsensusManager::builder(self.network.as_network()).build(); let node_identity = self.node_identity.clone(); context.spawn_when_ready(move |handles| async move { let base_node_service_handle = handles.expect_handle::(); @@ -131,7 +127,6 @@ where OutputManagerDatabase::new(backend), publisher, factories, - consensus_manager, constants, handles.get_shutdown_signal(), base_node_service_handle, diff --git a/base_layer/wallet/src/output_manager_service/resources.rs b/base_layer/wallet/src/output_manager_service/resources.rs index 3737157167..e6dc5b511c 100644 --- a/base_layer/wallet/src/output_manager_service/resources.rs +++ b/base_layer/wallet/src/output_manager_service/resources.rs @@ -22,7 +22,7 @@ use strum::EnumIter; use tari_core::{ - consensus::{ConsensusConstants, ConsensusManager}, + consensus::ConsensusConstants, transactions::{transaction_protocol::RewindData, CryptoFactories}, }; use tari_shutdown::ShutdownSignal; @@ -41,7 +41,6 @@ pub(crate) struct OutputManagerResources, event_publisher: OutputManagerEventSender, factories: CryptoFactories, - consensus_manager: ConsensusManager, consensus_constants: ConsensusConstants, shutdown_signal: ShutdownSignal, base_node_service: BaseNodeServiceHandle, @@ -161,7 +160,6 @@ where connectivity, event_publisher, master_key_manager: key_manager, - consensus_manager, consensus_constants, shutdown_signal, rewind_data, @@ -1113,11 +1111,7 @@ where .with_nonce(nonce) .with_rewind_data(self.resources.rewind_data.clone()) .with_extra(extra) - .build_with_reward( - self.resources.consensus_manager.clone(), - &self.resources.consensus_constants, - reward, - )?; + .build_with_reward(&self.resources.consensus_constants, reward)?; let output = DbUnblindedOutput::rewindable_from_unblinded_output( unblinded_output, @@ -1246,12 +1240,7 @@ where self.resources .db .encumber_outputs(tx_id, input_selection.into_selected(), db_outputs)?; - stp.finalize( - self.resources.consensus_manager.clone(), - &self.resources.factories, - None, - u64::MAX, - )?; + stp.finalize()?; Ok((tx_id, stp.take_transaction()?)) } @@ -1371,7 +1360,6 @@ where ); } - let factories = CryptoFactories::default(); let mut stp = builder .build( &self.resources.factories, @@ -1410,12 +1398,7 @@ where self.confirm_encumberance(tx_id)?; let fee = stp.get_fee_amount()?; trace!(target: LOG_TARGET, "Finalize send-to-self transaction ({}).", tx_id); - stp.finalize( - self.resources.consensus_manager.clone(), - &factories, - None, - self.last_seen_tip_height.unwrap_or(u64::MAX), - )?; + stp.finalize()?; let tx = stp.take_transaction()?; Ok((fee, tx)) @@ -1897,12 +1880,7 @@ where ); // finalizing transaction - stp.finalize( - self.resources.consensus_manager.clone(), - &self.resources.factories, - None, - self.last_seen_tip_height.unwrap_or(u64::MAX), - )?; + stp.finalize()?; Ok((tx_id, stp.take_transaction()?, aftertax_amount + fee)) } @@ -2155,12 +2133,7 @@ where ); // finalizing transaction - stp.finalize( - self.resources.consensus_manager.clone(), - &self.resources.factories, - None, - self.last_seen_tip_height.unwrap_or(u64::MAX), - )?; + stp.finalize()?; let value = if has_leftover_change { total_split_amount @@ -2328,12 +2301,7 @@ where ); // finalizing transaction - stp.finalize( - self.resources.consensus_manager.clone(), - &self.resources.factories, - None, - self.last_seen_tip_height.unwrap_or(u64::MAX), - )?; + stp.finalize()?; Ok((tx_id, stp.take_transaction()?, aftertax_amount + fee)) } @@ -2431,7 +2399,6 @@ where script_private_key, ); - let factories = CryptoFactories::default(); let mut stp = builder .build( &self.resources.factories, @@ -2464,12 +2431,7 @@ where self.confirm_encumberance(tx_id)?; let fee = stp.get_fee_amount()?; trace!(target: LOG_TARGET, "Finalize send-to-self transaction ({}).", tx_id); - stp.finalize( - self.resources.consensus_manager.clone(), - &factories, - None, - self.last_seen_tip_height.unwrap_or(u64::MAX), - )?; + stp.finalize()?; let tx = stp.take_transaction()?; Ok((tx_id, fee, amount - fee, tx)) @@ -2526,7 +2488,6 @@ where script_private_key, ); - let factories = CryptoFactories::default(); let mut stp = builder .build( &self.resources.factories, @@ -2557,12 +2518,7 @@ where let fee = stp.get_fee_amount()?; - stp.finalize( - self.resources.consensus_manager.clone(), - &factories, - None, - self.last_seen_tip_height.unwrap_or(u64::MAX), - )?; + stp.finalize()?; let tx = stp.take_transaction()?; diff --git a/base_layer/wallet/src/transaction_service/error.rs b/base_layer/wallet/src/transaction_service/error.rs index dbafd7ce13..11c3ab67d8 100644 --- a/base_layer/wallet/src/transaction_service/error.rs +++ b/base_layer/wallet/src/transaction_service/error.rs @@ -30,12 +30,9 @@ use tari_common_types::{ }; use tari_comms::{connectivity::ConnectivityError, peer_manager::node_id::NodeIdError, protocol::rpc::RpcError}; use tari_comms_dht::outbound::DhtOutboundError; -use tari_core::{ - transactions::{ - transaction_components::{EncryptionError, TransactionError}, - transaction_protocol::TransactionProtocolError, - }, - validation::ValidationError, +use tari_core::transactions::{ + transaction_components::{EncryptionError, TransactionError}, + transaction_protocol::TransactionProtocolError, }; use tari_p2p::services::liveness::error::LivenessError; use tari_service_framework::reply_channel::TransportChannelError; @@ -128,8 +125,6 @@ pub enum TransactionServiceError { InvalidMessageError(String), #[error("Transaction error: `{0}`")] TransactionError(#[from] TransactionError), - #[error("Transaction validation error: `{0}`")] - TransactionValidationError(#[from] ValidationError), #[error("Conversion error: `{0}`")] ConversionError(#[from] TransactionConversionError), #[error("duration::NegativeDurationError: {0}")] diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs index acf9d84fc4..23b0d44706 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs @@ -28,14 +28,10 @@ use log::*; use tari_common_types::{ tari_address::TariAddress, transaction::{TransactionDirection, TransactionStatus, TxId}, - types::HashOutput, }; -use tari_core::{ - transactions::{ - transaction_components::Transaction, - transaction_protocol::{recipient::RecipientState, sender::TransactionSenderMessage}, - }, - validation::transaction::TransactionInternalConsistencyValidator, +use tari_core::transactions::{ + transaction_components::Transaction, + transaction_protocol::{recipient::RecipientState, sender::TransactionSenderMessage}, }; use tokio::{ sync::{mpsc, oneshot}, @@ -73,9 +69,6 @@ pub struct TransactionReceiveProtocol { resources: TransactionServiceResources, transaction_finalize_receiver: Option>, cancellation_receiver: Option>, - prev_header: Option, - height: Option, - validator: TransactionInternalConsistencyValidator, } impl TransactionReceiveProtocol @@ -91,11 +84,7 @@ where resources: TransactionServiceResources, transaction_finalize_receiver: mpsc::Receiver<(TariAddress, TxId, Transaction)>, cancellation_receiver: oneshot::Receiver<()>, - prev_header: Option, - height: Option, ) -> Self { - let factories = resources.factories.clone(); - let consensus_manager = resources.consensus_manager.clone(); Self { id, source_address, @@ -104,9 +93,6 @@ where resources, transaction_finalize_receiver: Some(transaction_finalize_receiver), cancellation_receiver: Some(cancellation_receiver), - prev_header, - height, - validator: TransactionInternalConsistencyValidator::new(true, consensus_manager, factories), } } @@ -370,15 +356,6 @@ where self.source_address.clone() ); - self.validator - .validate( - &finalized_transaction, - None, - self.prev_header, - self.height.unwrap_or(u64::MAX), - ) - .map_err(|e| TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)))?; - // Find your own output in the transaction let rtp_output = match inbound_tx.receiver_protocol.state.clone() { RecipientState::Finalized(s) => s.output, diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs index da4b5d5f94..3c475f2df2 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs @@ -28,7 +28,6 @@ use log::*; use tari_common_types::{ tari_address::TariAddress, transaction::{TransactionDirection, TransactionStatus, TxId}, - types::HashOutput, }; use tari_comms::types::CommsPublicKey; use tari_comms_dht::{ @@ -97,8 +96,6 @@ pub struct TransactionSendProtocol { resources: TransactionServiceResources, transaction_reply_receiver: Option>, cancellation_receiver: Option>, - prev_header: Option, - height: Option, tx_meta: TransactionMetadata, sender_protocol: Option, } @@ -122,8 +119,6 @@ where oneshot::Sender>, >, stage: TransactionSendProtocolStage, - prev_header: Option, - height: Option, sender_protocol: Option, ) -> Self { Self { @@ -137,8 +132,6 @@ where message, service_request_reply_channel, stage, - prev_header, - height, tx_meta, sender_protocol, } @@ -549,21 +542,13 @@ where .add_single_recipient_info(recipient_reply) .map_err(|e| TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)))?; - outbound_tx - .sender_protocol - .finalize( - self.resources.consensus_manager.clone(), - &self.resources.factories, - self.prev_header, - self.height.unwrap_or(u64::MAX), - ) - .map_err(|e| { - error!( - target: LOG_TARGET, - "Transaction (TxId: {}) could not be finalized. Failure error: {:?}", self.id, e, - ); - TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)) - })?; + outbound_tx.sender_protocol.finalize().map_err(|e| { + error!( + target: LOG_TARGET, + "Transaction (TxId: {}) could not be finalized. Failure error: {:?}", self.id, e, + ); + TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)) + })?; let tx = outbound_tx .sender_protocol diff --git a/base_layer/wallet/src/transaction_service/service.rs b/base_layer/wallet/src/transaction_service/service.rs index 59630c1221..1bbf85cb26 100644 --- a/base_layer/wallet/src/transaction_service/service.rs +++ b/base_layer/wallet/src/transaction_service/service.rs @@ -1001,8 +1001,6 @@ where Some(reply_channel), TransactionSendProtocolStage::Initial, None, - self.last_seen_tip_height, - None, ); let join_handle = tokio::spawn(protocol.execute()); join_handles.push(join_handle); @@ -1141,13 +1139,7 @@ where // Finalize - stp.finalize( - self.resources.consensus_manager.clone(), - &self.resources.factories, - None, - self.last_seen_tip_height.unwrap_or(u64::MAX), - ) - .map_err(|e| { + stp.finalize().map_err(|e| { error!( target: LOG_TARGET, "Transaction (TxId: {}) could not be finalized. Failure error: {:?}", tx_id, e, @@ -1279,13 +1271,7 @@ where // Finalize - stp.finalize( - self.resources.consensus_manager.clone(), - &self.resources.factories, - None, - self.last_seen_tip_height.unwrap_or(u64::MAX), - ) - .map_err(|e| { + stp.finalize().map_err(|e| { error!( target: LOG_TARGET, "Transaction (TxId: {}) could not be finalized. Failure error: {:?}", tx_id, e, @@ -1432,13 +1418,7 @@ where // Finalize - stp.finalize( - self.resources.consensus_manager.clone(), - &self.resources.factories, - None, - self.last_seen_tip_height.unwrap_or(u64::MAX), - ) - .map_err(|e| { + stp.finalize().map_err(|e| { error!( target: LOG_TARGET, "Transaction (TxId: {}) could not be finalized. Failure error: {:?}", tx_id, e, @@ -1878,8 +1858,6 @@ where TransactionMetadata::default(), None, stage, - None, - self.last_seen_tip_height, sender_protocol, ); @@ -2011,8 +1989,6 @@ where self.resources.clone(), tx_finalized_receiver, cancellation_receiver, - None, - self.last_seen_tip_height, ); let join_handle = tokio::spawn(protocol.execute()); @@ -2197,8 +2173,6 @@ where self.resources.clone(), tx_finalized_receiver, cancellation_receiver, - None, - self.last_seen_tip_height, ); let join_handle = tokio::spawn(protocol.execute()); diff --git a/base_layer/wallet/tests/output_manager_service_tests/service.rs b/base_layer/wallet/tests/output_manager_service_tests/service.rs index 7f4ed98dd4..07afceae51 100644 --- a/base_layer/wallet/tests/output_manager_service_tests/service.rs +++ b/base_layer/wallet/tests/output_manager_service_tests/service.rs @@ -42,7 +42,7 @@ use tari_core::{ transactions::{ fee::Fee, tari_amount::{uT, MicroTari}, - test_helpers::{create_consensus_manager, create_unblinded_output, TestParams as TestParamsHelpers}, + test_helpers::{create_unblinded_output, TestParams as TestParamsHelpers}, transaction_components::{EncryptedValue, OutputFeatures, OutputType, TransactionOutput, UnblindedOutput}, transaction_protocol::{sender::TransactionSenderMessage, RewindData, TransactionMetadata}, weight::TransactionWeight, @@ -131,7 +131,6 @@ async fn setup_output_manager_service TestOmsService { let shutdown = Shutdown::new(); - let consensus_manager = create_consensus_manager(); let factories = CryptoFactories::default(); let (oms_request_sender, oms_request_receiver) = reply_channel::unbounded(); @@ -191,7 +190,6 @@ async fn setup_output_manager_service( broadcast::Sender>, ) { let shutdown = Shutdown::new(); - let consensus_manager = create_consensus_manager(); let factories = CryptoFactories::default(); let (oms_request_sender, oms_request_receiver) = reply_channel::unbounded(); @@ -272,7 +269,6 @@ pub async fn setup_oms_with_bn_state( OutputManagerDatabase::new(backend), oms_event_publisher.clone(), factories, - consensus_manager, constants, shutdown.to_signal(), base_node_service_handle.clone(), diff --git a/base_layer/wallet/tests/transaction_service_tests/service.rs b/base_layer/wallet/tests/transaction_service_tests/service.rs index 54808ef0c1..3d6c95225a 100644 --- a/base_layer/wallet/tests/transaction_service_tests/service.rs +++ b/base_layer/wallet/tests/transaction_service_tests/service.rs @@ -348,7 +348,6 @@ async fn setup_transaction_service_no_comms( oms_db, output_manager_service_event_publisher.clone(), factories.clone(), - consensus_manager.clone(), constants, shutdown.to_signal(), base_node_service_handle.clone(), @@ -1394,8 +1393,6 @@ async fn test_accepting_unknown_tx_id_and_malformed_reply() { let mut alice_ts_interface = setup_transaction_service_no_comms(factories.clone(), connection_alice, None).await; - let mut alice_event_stream = alice_ts_interface.transaction_service_handle.get_event_stream(); - let (_utxo, uo) = make_input(&mut OsRng, MicroTari(250000), &factories.commitment).await; alice_ts_interface @@ -1461,35 +1458,10 @@ async fn test_accepting_unknown_tx_id_and_malformed_reply() { )) .await .unwrap(); - - let delay = sleep(Duration::from_secs(30)); - tokio::pin!(delay); - - let mut errors = 0; - loop { - tokio::select! { - event = alice_event_stream.recv() => { - if let TransactionEvent::Error(s) = &*event.unwrap() { - if s == &"TransactionProtocolError(TransactionBuildError(ValidationError(\"The transaction is invalid: Signature is invalid: Verifying kernel signature\")))".to_string() { - errors+=1; - } - if errors >= 1 { - break; - } - } - }, - () = &mut delay => { - break; - }, - } - } - assert!(errors >= 1); } #[tokio::test] async fn finalize_tx_with_incorrect_pubkey() { - let network = Network::LocalNet; - let consensus_manager = ConsensusManager::builder(network).build(); let factories = CryptoFactories::default(); let temp_dir = tempdir().unwrap(); @@ -1559,7 +1531,7 @@ async fn finalize_tx_with_incorrect_pubkey() { .unwrap(); stp.add_single_recipient_info(recipient_reply.clone()).unwrap(); - stp.finalize(consensus_manager, &factories, None, u64::MAX).unwrap(); + stp.finalize().unwrap(); let tx = stp.get_transaction().unwrap(); let finalized_transaction_message = proto::TransactionFinalizedMessage { @@ -1602,8 +1574,6 @@ async fn finalize_tx_with_incorrect_pubkey() { #[tokio::test] async fn finalize_tx_with_missing_output() { - let network = Network::LocalNet; - let consensus_manager = ConsensusManager::builder(network).build(); let factories = CryptoFactories::default(); let temp_dir = tempdir().unwrap(); @@ -1675,7 +1645,7 @@ async fn finalize_tx_with_missing_output() { .unwrap(); stp.add_single_recipient_info(recipient_reply.clone()).unwrap(); - stp.finalize(consensus_manager, &factories, None, u64::MAX).unwrap(); + stp.finalize().unwrap(); let finalized_transaction_message = proto::TransactionFinalizedMessage { tx_id: recipient_reply.tx_id.as_u64(), @@ -2954,7 +2924,6 @@ async fn test_tx_direct_send_behaviour() { #[tokio::test] async fn test_restarting_transaction_protocols() { let network = Network::LocalNet; - let consensus_manager = ConsensusManager::builder(network).build(); let factories = CryptoFactories::default(); let (alice_connection, _temp_dir) = make_wallet_database_connection(None); @@ -3029,7 +2998,7 @@ async fn test_restarting_transaction_protocols() { bob_stp.add_single_recipient_info(alice_reply.clone()).unwrap(); - match bob_stp.finalize(consensus_manager, &factories, None, u64::MAX) { + match bob_stp.finalize() { Ok(_) => (), Err(e) => panic!("Should be able to finalize tx: {}", e), }; diff --git a/base_layer/wallet_ffi/Cargo.toml b/base_layer/wallet_ffi/Cargo.toml index fcba8c6514..2decc59af1 100644 --- a/base_layer/wallet_ffi/Cargo.toml +++ b/base_layer/wallet_ffi/Cargo.toml @@ -7,7 +7,7 @@ version = "0.44.1" edition = "2018" [dependencies] -tari_core = { version = "^0.44", path = "../../base_layer/core", default-features = false, features = ["tari_mmr", "base_node", "transactions"]} +tari_core = { version = "^0.44", path = "../../base_layer/core", default-features = false, features = ["tari_mmr", "transactions"]} tari_common = {path="../../common"} tari_common_types = {path="../common_types"} tari_comms = { version = "^0.44", path = "../../comms/core", features = ["c_integration"]} @@ -26,8 +26,6 @@ futures = { version = "^0.3.1", features =["compat", "std"]} libc = "0.2.65" log = "0.4.6" log4rs = {version = "1.2.0", features = ["console_appender", "file_appender", "yaml_format"]} -# Needs to be higher than 0.10.41 to address a security issue -openssl = { version = "0.10.41", features = ["vendored"] } rand = "0.7.3" thiserror = "1.0.26" tokio = "1.23" @@ -36,16 +34,6 @@ itertools = "0.10.3" zeroize = "1" serde_json = "1.0" -# -# Temporary workaround until crates utilizing openssl have been updated from security-framework 2.4.0 -# which is currently broken for iOS -[target.x86_64-apple-ios.dependencies] -security-framework = "2.4.2" - -[target.aarch64-apple-ios.dependencies] -security-framework = "2.4.2" -# - [lib] crate-type = ["staticlib","cdylib"] diff --git a/infrastructure/libtor/Cargo.toml b/infrastructure/libtor/Cargo.toml index 2024b16d4c..40127252a0 100644 --- a/infrastructure/libtor/Cargo.toml +++ b/infrastructure/libtor/Cargo.toml @@ -14,6 +14,7 @@ log = "0.4.8" rand = "0.7.3" tempfile = "3.1.0" tor-hash-passwd = "1.0.1" +openssl = { version = "0.10.41", features = ["vendored"] } [target.'cfg(unix)'.dependencies] libtor = { version="46.9.0"} diff --git a/integration_tests/tests/utils/miner.rs b/integration_tests/tests/utils/miner.rs index 1a0c7f4464..1cb09525a5 100644 --- a/integration_tests/tests/utils/miner.rs +++ b/integration_tests/tests/utils/miner.rs @@ -320,7 +320,7 @@ pub fn generate_coinbase(coinbase_req: GetCoinbaseRequest) -> (TransactionOutput .with_script_key(script_private_key) .with_nonce(nonce) .with_extra(extra) - .build_with_reward(consensus_manager.clone(), consensus_constants, reward.into()) + .build_with_reward(consensus_constants, reward.into()) .unwrap(); let tx_out = tx.body().outputs().first().unwrap().clone(); diff --git a/integration_tests/tests/utils/transaction.rs b/integration_tests/tests/utils/transaction.rs index 9f6b8a3312..18f42d35d7 100644 --- a/integration_tests/tests/utils/transaction.rs +++ b/integration_tests/tests/utils/transaction.rs @@ -22,26 +22,22 @@ use std::default::Default; -use tari_common::configuration::Network; use tari_common_types::types::{Commitment, PrivateKey, Signature}; -use tari_core::{ - consensus::ConsensusManager, - transactions::{ - tari_amount::MicroTari, - test_helpers::TestParams, - transaction_components::{ - KernelBuilder, - Transaction, - TransactionBuilder, - TransactionInput, - TransactionKernel, - TransactionOutput, - UnblindedOutput, - UnblindedOutputBuilder, - }, - transaction_protocol::TransactionMetadata, - CryptoFactories, +use tari_core::transactions::{ + tari_amount::MicroTari, + test_helpers::TestParams, + transaction_components::{ + KernelBuilder, + Transaction, + TransactionBuilder, + TransactionInput, + TransactionKernel, + TransactionOutput, + UnblindedOutput, + UnblindedOutputBuilder, }, + transaction_protocol::TransactionMetadata, + CryptoFactories, }; use tari_crypto::{ keys::PublicKey, @@ -124,10 +120,7 @@ impl TestTransactionBuilder { .add_script_offset(script_offset_pvt.clone()) .with_kernel(kernel.clone()); - let rules = ConsensusManager::builder(Network::LocalNet).build(); - let tx = tx_builder - .build(rules, &self.factories, None, self.inputs_max_height) - .unwrap(); + let tx = tx_builder.build().unwrap(); (tx, output.1) }