Skip to content

Commit

Permalink
test: fix some ignored tests (#3700)
Browse files Browse the repository at this point in the history
Description
---

- remove `#[ignore]` for some tests that are now working
- fix some tests
- remove old network consensus constants
  • Loading branch information
Byron Hambly authored Jan 14, 2022
1 parent f6de59f commit 3c47e04
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 148 deletions.
Empty file.
1 change: 0 additions & 1 deletion base_layer/core/src/base_node/sync/rpc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ mod sync_utxos {
}

#[tokio::test]
#[ignore = "need to put faucet utxos back"]
async fn it_sends_an_offset_response() {
let (service, db, rpc_request_mock, _tmp) = setup();

Expand Down
18 changes: 9 additions & 9 deletions base_layer/core/src/chain_storage/tests/blockchain_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ mod fetch_total_size_stats {
let stats = db.fetch_total_size_stats().unwrap();
assert_eq!(
stats.sizes().iter().find(|s| s.name == "utxos_db").unwrap().num_entries,
3
4003
);
}
}
Expand Down Expand Up @@ -567,14 +567,14 @@ mod fetch_header_containing_utxo_mmr {
fn it_returns_genesis() {
let db = setup();
let genesis = db.fetch_block(0).unwrap();
assert_eq!(genesis.block().body.outputs().len(), 1);
// let mut mmr_position = 0;
// genesis.block().body.outputs().iter().for_each(|_| {
// let header = db.fetch_header_containing_utxo_mmr(mmr_position).unwrap();
// assert_eq!(header.height(), 0);
// mmr_position += 1;
// });
let err = db.fetch_header_containing_utxo_mmr(2).unwrap_err();
assert_eq!(genesis.block().body.outputs().len(), 4001);
let mut mmr_position = 0;
genesis.block().body.outputs().iter().for_each(|_| {
let header = db.fetch_header_containing_utxo_mmr(mmr_position).unwrap();
assert_eq!(header.height(), 0);
mmr_position += 1;
});
let err = db.fetch_header_containing_utxo_mmr(4002).unwrap_err();
matches!(err, ChainStorageError::ValueNotFound { .. });
}

Expand Down
122 changes: 5 additions & 117 deletions base_layer/core/src/consensus/consensus_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,121 +244,6 @@ impl ConsensusConstants {
}]
}

pub fn ridcully() -> Vec<Self> {
let difficulty_block_window = 90;
let mut algos = HashMap::new();
// setting sha3/monero to 40/60 split
algos.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
max_target_time: 1800,
min_difficulty: 60_00.into(),
max_difficulty: u64::MAX.into(),
target_time: 300,
});
algos.insert(PowAlgorithm::Monero, PowAlgorithmConstants {
max_target_time: 1200,
min_difficulty: 60_000.into(),
max_difficulty: u64::MAX.into(),
target_time: 200,
});
vec![ConsensusConstants {
effective_from_height: 0,
coinbase_lock_height: 1,
blockchain_version: 1,
future_time_limit: 540,
difficulty_block_window,
max_block_transaction_weight: 19500,
median_timestamp_count: 11,
emission_initial: 5_538_846_115 * uT,
emission_decay: &EMISSION_DECAY,
emission_tail: 100.into(),
max_randomx_seed_height: u64::MAX,
proof_of_work: algos,
faucet_value: (5000 * 4000) * T,
transaction_weight: TransactionWeight::v1(),
max_script_byte_size: 2048,
}]
}

pub fn stibbons() -> Vec<Self> {
let mut algos = HashMap::new();
// Previously these were incorrectly set to `target_time` of 20 and 30, so
// most blocks before 1400 hit the minimum difficulty of 60M and 60k
// algos.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
// max_target_time: 1800,
// min_difficulty: 60_000_000.into(),
// max_difficulty: u64::MAX.into(),
// target_time: 30,
// });
// algos.insert(PowAlgorithm::Monero, PowAlgorithmConstants {
// max_target_time: 1200,
// min_difficulty: 60_000.into(),
// max_difficulty: u64::MAX.into(),
// target_time: 20,
// });
algos.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
max_target_time: 1800,
min_difficulty: 60_00.into(),
max_difficulty: 60_000_000.into(),
target_time: 300,
});
algos.insert(PowAlgorithm::Monero, PowAlgorithmConstants {
max_target_time: 1200,
min_difficulty: 60_000.into(),
max_difficulty: 60_000.into(),
target_time: 200,
});
let mut algos2 = HashMap::new();
// setting sha3/monero to 40/60 split
algos2.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
max_target_time: 1800,
min_difficulty: 60_000_000.into(),
max_difficulty: u64::MAX.into(),
target_time: 300,
});
algos2.insert(PowAlgorithm::Monero, PowAlgorithmConstants {
max_target_time: 1200,
min_difficulty: 60_000.into(),
max_difficulty: u64::MAX.into(),
target_time: 200,
});
vec![
ConsensusConstants {
effective_from_height: 0,
coinbase_lock_height: 60,
blockchain_version: 1,
future_time_limit: 540,
difficulty_block_window: 90,
max_block_transaction_weight: 19500,
median_timestamp_count: 11,
emission_initial: 5_538_846_115 * uT,
emission_decay: &EMISSION_DECAY,
emission_tail: 100.into(),
max_randomx_seed_height: u64::MAX,
proof_of_work: algos,
faucet_value: (5000 * 4000) * T,
transaction_weight: TransactionWeight::v1(),
max_script_byte_size: 2048,
},
ConsensusConstants {
effective_from_height: 1400,
coinbase_lock_height: 60,
blockchain_version: 1,
future_time_limit: 540,
difficulty_block_window: 90,
max_block_transaction_weight: 19500,
median_timestamp_count: 11,
emission_initial: 5_538_846_115 * uT,
emission_decay: &EMISSION_DECAY,
emission_tail: 100.into(),
max_randomx_seed_height: u64::MAX,
proof_of_work: algos2,
faucet_value: (5000 * 4000) * T,
transaction_weight: TransactionWeight::v1(),
max_script_byte_size: 2048,
},
]
}

pub fn weatherwax() -> Vec<Self> {
let mut algos = HashMap::new();
// setting sha3/monero to 40/60 split
Expand Down Expand Up @@ -395,7 +280,7 @@ impl ConsensusConstants {

pub fn igor() -> Vec<Self> {
let mut algos = HashMap::new();
// seting sha3/monero to 40/60 split
// sha3/monero to 40/60 split
algos.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
max_target_time: 1800,
min_difficulty: 60_000_000.into(),
Expand Down Expand Up @@ -432,7 +317,7 @@ impl ConsensusConstants {

pub fn dibbler() -> Vec<Self> {
let mut algos = HashMap::new();
// setting sha3/monero to 40/60 split
// sha3/monero to 40/60 split
algos.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
max_target_time: 1800,
min_difficulty: 60_000.into(),
Expand All @@ -451,6 +336,9 @@ impl ConsensusConstants {
blockchain_version: 2,
future_time_limit: 540,
difficulty_block_window: 90,
// 65536 = target_block_size / bytes_per_gram = (1024*1024) / 16
// adj. + 95% = 127,795 - this effectively targets ~2Mb blocks closely matching the previous 19500
// weightings
max_block_transaction_weight: 127_795,
median_timestamp_count: 11,
emission_initial: 5_538_846_115 * uT,
Expand Down
8 changes: 4 additions & 4 deletions base_layer/core/src/consensus/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ impl NetworkConsensus {
use Network::*;
match self.as_network() {
MainNet => ConsensusConstants::mainnet(),
Ridcully => ConsensusConstants::ridcully(),
Stibbons => ConsensusConstants::stibbons(),
Weatherwax => ConsensusConstants::weatherwax(),
LocalNet => ConsensusConstants::localnet(),
Igor => ConsensusConstants::igor(),
Dibbler => ConsensusConstants::dibbler(),
Igor => ConsensusConstants::igor(),
Weatherwax => ConsensusConstants::weatherwax(),
Ridcully => unimplemented!("Ridcully network is no longer supported"),
Stibbons => unimplemented!("Stibbons network is no longer supported"),
}
}

Expand Down
4 changes: 2 additions & 2 deletions base_layer/core/src/test_helpers/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use tari_utilities::Hashable;
use super::{create_block, mine_to_difficulty};
use crate::{
blocks::{
genesis_block::get_igor_genesis_block,
genesis_block::get_dibbler_genesis_block,
Block,
BlockAccumulatedData,
BlockHeader,
Expand Down Expand Up @@ -86,7 +86,7 @@ use crate::{
pub fn create_new_blockchain() -> BlockchainDatabase<TempDatabase> {
let network = Network::LocalNet;
let consensus_constants = ConsensusConstantsBuilder::new(network).build();
let genesis = get_igor_genesis_block();
let genesis = get_dibbler_genesis_block();
let consensus_manager = ConsensusManager::builder(network)
.add_consensus_constants(consensus_constants)
.with_block(genesis)
Expand Down
2 changes: 1 addition & 1 deletion base_layer/core/src/transactions/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use tari_crypto::{script::TariScript, tari_utilities::ByteArray};
pub use template_parameter::TemplateParameter;
pub use transaction::Transaction;
pub use transaction_builder::TransactionBuilder;
pub use transaction_input::TransactionInput;
pub use transaction_input::{SpentOutput, TransactionInput};
pub use transaction_kernel::TransactionKernel;
pub use transaction_output::TransactionOutput;
pub use unblinded_output::UnblindedOutput;
Expand Down
69 changes: 65 additions & 4 deletions base_layer/core/src/validation/transaction_validators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use log::*;
use tari_utilities::hex::Hex;

use crate::{
chain_storage::{BlockchainBackend, BlockchainDatabase},
transactions::{transaction::Transaction, CryptoFactories},
chain_storage::{BlockchainBackend, BlockchainDatabase, PrunedOutput},
transactions::{
transaction::{SpentOutput, Transaction},
CryptoFactories,
},
validation::{
helpers::{check_inputs_are_utxos, check_outputs},
MempoolTransactionValidation,
Expand Down Expand Up @@ -78,7 +82,7 @@ impl<B: BlockchainBackend> MempoolTransactionValidation for TxInternalConsistenc
///
/// 1. The transaction weight should not exceed the maximum weight for 1 block
/// 1. All of the outputs should have a unique asset id in the transaction
/// 1. All of the outputs should have a unique asset id not already on chain
/// 1. All of the outputs should have a unique asset id not already on chain (unless spent to a new output)
#[derive(Clone)]
pub struct TxConsensusValidator<B> {
db: BlockchainDatabase<B>,
Expand All @@ -88,6 +92,63 @@ impl<B: BlockchainBackend> TxConsensusValidator<B> {
pub fn new(db: BlockchainDatabase<B>) -> Self {
Self { db }
}

fn validate_unique_asset_rules(&self, tx: &Transaction) -> Result<(), ValidationError> {
let outputs = tx.body.outputs();

// outputs in transaction should have unique asset ids
let mut unique_asset_ids: Vec<_> = outputs.iter().filter_map(|o| o.features.unique_asset_id()).collect();

unique_asset_ids.sort();
let num_ids = unique_asset_ids.len();

unique_asset_ids.dedup();
let num_unique = unique_asset_ids.len();

if num_unique < num_ids {
return Err(ValidationError::ConsensusError(
"Transaction contains outputs with duplicate unique_asset_ids".into(),
));
}

// the output's unique asset id should not already be in the chain
// unless it's being spent as an input as well
for output in outputs {
if let Some(ref unique_id) = output.features.unique_id {
let parent_public_key = output.features.parent_public_key.clone();
let parent_hash = parent_public_key.as_ref().map(|p| p.to_hex());
let unique_id_hex = unique_id.to_hex();
if let Some(info) = self
.db
.fetch_utxo_by_unique_id(parent_public_key, unique_id.clone(), None)?
{
// if it's already on chain then check it's being spent as an input
let output_hex = info.output.hash().to_hex();
if let PrunedOutput::NotPruned { output } = info.output {
let unique_asset_id = output.features.unique_asset_id();
let spent_in_tx = tx.body.inputs().iter().any(|i| {
if let SpentOutput::OutputData { ref features, .. } = i.spent_output {
features.unique_asset_id() == unique_asset_id
} else {
false
}
});

if !spent_in_tx {
let msg = format!(
"Output already exists in blockchain database. Output hash: {}. Parent public key: \
{:?}. Unique ID: {}",
output_hex, parent_hash, unique_id_hex,
);
return Err(ValidationError::ConsensusError(msg));
}
}
}
}
}

Ok(())
}
}

impl<B: BlockchainBackend> MempoolTransactionValidation for TxConsensusValidator<B> {
Expand All @@ -100,7 +161,7 @@ impl<B: BlockchainBackend> MempoolTransactionValidation for TxConsensusValidator
return Err(ValidationError::MaxTransactionWeightExceeded);
}

Ok(())
self.validate_unique_asset_rules(tx)
}
}

Expand Down
16 changes: 14 additions & 2 deletions base_layer/core/tests/mempool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1107,7 +1107,7 @@ async fn consensus_validation_large_tx() {

#[tokio::test]
#[allow(clippy::erasing_op)]
#[ignore = "broken after validator node merge"]
#[allow(clippy::identity_op)]
async fn consensus_validation_unique_id() {
let mut rng = rand::thread_rng();
let network = Network::LocalNet;
Expand Down Expand Up @@ -1138,7 +1138,7 @@ async fn consensus_validation_unique_id() {
};
let txs = vec![txn_schema!(
from: vec![outputs[1][0].clone()],
to: vec![0 * T], fee: 100.into(), lock: 0, features: features
to: vec![1 * T], fee: 100.into(), lock: 0, features: features
)];
generate_new_block(&mut store, &mut blocks, &mut outputs, txs, &consensus_manager).unwrap();

Expand All @@ -1152,6 +1152,18 @@ async fn consensus_validation_unique_id() {
let response = mempool.insert(tx).await.unwrap();
assert!(matches!(response, TxStorageResponse::NotStoredConsensus));

// publishing a transaction that spends a unique id to a new output should succeed
let nft = outputs[2][0].clone();
let features = nft.features.clone();
let tx = txn_schema!(
from: vec![nft],
to: vec![0 * T], fee: 100.into(), lock: 0, features: features
);
let (tx, _) = spend_utxos(tx);
let tx = Arc::new(tx);
let response = mempool.insert(tx).await.unwrap();
assert!(matches!(response, TxStorageResponse::UnconfirmedPool));

// a different unique_id should be fine
let features = OutputFeatures {
flags: OutputFlags::MINT_NON_FUNGIBLE,
Expand Down
2 changes: 0 additions & 2 deletions base_layer/core/tests/node_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,6 @@ async fn local_get_new_block_template_and_get_new_block() {
}

#[tokio::test]
#[ignore = "0-conf regression fixed in #3680"]
async fn local_get_new_block_with_zero_conf() {
let factories = CryptoFactories::default();
let temp_dir = tempdir().unwrap();
Expand Down Expand Up @@ -578,7 +577,6 @@ async fn local_get_new_block_with_zero_conf() {
}

#[tokio::test]
#[ignore = "0-conf regression fixed in #3680"]
async fn local_get_new_block_with_combined_transaction() {
let factories = CryptoFactories::default();
let temp_dir = tempdir().unwrap();
Expand Down
Loading

0 comments on commit 3c47e04

Please sign in to comment.