From 4ac904948fb651d2422b3d983ffcee3c19696b1c Mon Sep 17 00:00:00 2001 From: drcpu Date: Sun, 24 Nov 2024 19:49:53 +0000 Subject: [PATCH 1/6] fix(validations): handle TooManyWitnesses edge case when synchronizing a node --- validations/src/tests/mod.rs | 380 ++++++++++++++++++--------------- validations/src/validations.rs | 26 ++- 2 files changed, 227 insertions(+), 179 deletions(-) diff --git a/validations/src/tests/mod.rs b/validations/src/tests/mod.rs index 61c87732e..fcf99369b 100644 --- a/validations/src/tests/mod.rs +++ b/validations/src/tests/mod.rs @@ -74,6 +74,34 @@ static DEFAULT_INPUT_VALUE: u64 = 2 * ONE_WIT; // Block epoch used in tally tests const E: Epoch = LAST_EPOCH_WITH_WIP_ACTIVATED; +const CONSENSUS_CONSTANTS_FOR_TALLY: ConsensusConstants = ConsensusConstants { + checkpoint_zero_timestamp: 0, + collateral_minimum: 1_000_000_000, + bootstrapping_committee: vec![], + collateral_age: 1, + superblock_period: 0, + mining_backup_factor: 8, + bootstrap_hash: Hash::SHA256([1; 32]), + genesis_hash: Hash::SHA256([1; 32]), + max_dr_weight: MAX_DR_WEIGHT, + activity_period: 0, + reputation_expire_alpha_diff: 0, + reputation_issuance: 0, + reputation_issuance_stop: 0, + max_vt_weight: MAX_VT_WEIGHT, + checkpoints_period: 0, + reputation_penalization_factor: 0.0, + mining_replication_factor: 0, + extra_rounds: 0, + minimum_difficulty: 2, + epochs_with_minimum_difficulty: 0, + superblock_signing_committee_size: 100, + superblock_committee_decreasing_period: 100, + superblock_committee_decreasing_step: 5, + initial_block_reward: INITIAL_BLOCK_REWARD, + halving_period: HALVING_PERIOD, +}; + // This should only be used in tests fn active_wips_from_mainnet(block_epoch: Epoch) -> ActiveWips { let mut tapi_engine = TapiEngine::default(); @@ -5144,8 +5172,8 @@ fn tally_dr_not_tally_stage() { let mut dr_pool = DataRequestPool::default(); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, Some(epoch), @@ -5160,8 +5188,8 @@ fn tally_dr_not_tally_stage() { dr_pool.update_data_request_stages(None, Some(epoch)); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, Some(epoch), @@ -5177,8 +5205,8 @@ fn tally_dr_not_tally_stage() { dr_pool.update_data_request_stages(None, Some(epoch)); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, Some(epoch), @@ -5194,8 +5222,8 @@ fn tally_dr_not_tally_stage() { dr_pool.update_data_request_stages(None, Some(epoch)); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, Some(epoch), @@ -5210,7 +5238,7 @@ fn tally_invalid_consensus() { // Reveal value: integer(0) let reveal_value = vec![0x00]; let dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 5, @@ -5272,8 +5300,8 @@ fn tally_invalid_consensus() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -5290,7 +5318,7 @@ fn tally_invalid_consensus() { #[test] fn tally_valid_1_reveal_5_commits() { let collateral = DEFAULT_COLLATERAL; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test(5, vec![vec![0]]); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test(5, vec![vec![0]]); let change = 5 * DEFAULT_WITNESS_REWARD + 4 * 20; let tally_value = RadonReport::from_result( @@ -5345,8 +5373,8 @@ fn tally_valid_1_reveal_5_commits() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -5483,7 +5511,7 @@ fn generic_tally_test_inner( #[test] fn tally_valid_1_reveal_5_commits_invalid_value() { let collateral = DEFAULT_COLLATERAL; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test(5, vec![vec![0]]); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test(5, vec![vec![0]]); let change = 5 * DEFAULT_WITNESS_REWARD + 4 * 20; let tally_value = RadonReport::from_result( @@ -5538,8 +5566,8 @@ fn tally_valid_1_reveal_5_commits_invalid_value() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -5557,7 +5585,7 @@ fn tally_valid_1_reveal_5_commits_invalid_value() { #[test] fn tally_valid_1_reveal_5_commits_with_absurd_timelock() { let collateral = DEFAULT_COLLATERAL; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test(5, vec![vec![0]]); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test(5, vec![vec![0]]); let change = 5 * DEFAULT_WITNESS_REWARD + 4 * 20; let tally_value = RadonReport::from_result( @@ -5612,8 +5640,8 @@ fn tally_valid_1_reveal_5_commits_with_absurd_timelock() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -5634,7 +5662,7 @@ fn tally_valid() { // Reveal value: integer(0) let reveal_value = vec![0x00]; let dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 5, @@ -5693,8 +5721,8 @@ fn tally_valid() { let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -5709,7 +5737,7 @@ fn tally_too_many_outputs() { let reveal_value = vec![0x00]; let active_wips = current_active_wips(); let dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 5, @@ -5756,8 +5784,8 @@ fn tally_too_many_outputs() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -5778,7 +5806,7 @@ fn tally_too_less_outputs() { // Reveal value: integer(0) let reveal_value = vec![0x00]; let dr_output = example_data_request_output(2, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 2, @@ -5803,8 +5831,8 @@ fn tally_too_less_outputs() { TallyTransaction::new(dr_pointer, tally_value, vec![vt0], slashed, error_witnesses); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -5825,7 +5853,7 @@ fn tally_invalid_change() { // Reveal value: integer(0) let reveal_value = vec![0x00]; let dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 5, @@ -5883,8 +5911,8 @@ fn tally_invalid_change() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -5905,7 +5933,7 @@ fn tally_double_reward() { // Reveal value: integer(0) let reveal_value = vec![0x00]; let dr_output = example_data_request_output(2, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 2, @@ -5939,8 +5967,8 @@ fn tally_double_reward() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -5958,7 +5986,7 @@ fn tally_reveal_not_found() { // Reveal value: integer(0) let reveal_value = vec![0x00]; let dr_output = example_data_request_output(2, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 2, @@ -5992,8 +6020,8 @@ fn tally_reveal_not_found() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -6011,7 +6039,7 @@ fn tally_invalid_reward() { // Reveal value: integer(0) let reveal_value = vec![0x00]; let dr_output = example_data_request_output(2, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 2, @@ -6046,8 +6074,8 @@ fn tally_invalid_reward() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -6068,7 +6096,7 @@ fn tally_valid_2_reveals() { // Reveal value: integer(0) let reveal_value = vec![0x00]; let dr_output = example_data_request_output(2, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 2, @@ -6103,8 +6131,8 @@ fn tally_valid_2_reveals() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -6122,7 +6150,7 @@ fn tally_valid_3_reveals_dr_liar() { // Create a DataRequestPool with 3 reveals (one of them is a lie from the data requester) let dr_output = example_data_request_output_with_mode_filter(3, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage_with_dr_liar( dr_output, 3, @@ -6171,8 +6199,8 @@ fn tally_valid_3_reveals_dr_liar() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -6190,7 +6218,7 @@ fn tally_valid_3_reveals_dr_liar_invalid() { // Create a DataRequestPool with 3 reveals (one of them is a lie from the data requester) let dr_output = example_data_request_output_with_mode_filter(3, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage_with_dr_liar( dr_output, 3, @@ -6239,8 +6267,8 @@ fn tally_valid_3_reveals_dr_liar_invalid() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -6265,7 +6293,7 @@ fn tally_valid_5_reveals_1_liar_1_error() { // Create a DataRequestPool with 5 reveals (one of them is a lie and another is an error) let dr_output = example_data_request_output_with_mode_filter(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage_with_errors( dr_output, 5, @@ -6327,8 +6355,8 @@ fn tally_valid_5_reveals_1_liar_1_error() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -6345,7 +6373,7 @@ fn tally_valid_3_reveals_1_error() { // Create a DataRequestPool with 3 reveals (one of them is a lie from the data requester) let dr_output = example_data_request_output_with_mode_filter(3, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage_with_errors( dr_output, 3, @@ -6391,8 +6419,8 @@ fn tally_valid_3_reveals_1_error() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -6409,7 +6437,7 @@ fn tally_valid_3_reveals_1_error_invalid_reward() { // Create a DataRequestPool with 3 reveals (one of them is a lie from the data requester) let dr_output = example_data_request_output_with_mode_filter(3, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage_with_errors( dr_output, 3, @@ -6455,8 +6483,8 @@ fn tally_valid_3_reveals_1_error_invalid_reward() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -6479,7 +6507,7 @@ fn tally_valid_3_reveals_mark_all_as_error() { // Create a DataRequestPool with 3 reveals (one of them is a lie from the data requester) let dr_output = example_data_request_output_with_mode_filter(3, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage_with_errors( dr_output, 3, @@ -6525,8 +6553,8 @@ fn tally_valid_3_reveals_mark_all_as_error() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -6550,7 +6578,7 @@ fn tally_dishonest_reward() { // Create a DataRequestPool with 3 reveals (one of them is a lie from the data requester) let dr_output = example_data_request_output_with_mode_filter(3, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage_with_dr_liar( dr_output, 3, @@ -6598,8 +6626,8 @@ fn tally_dishonest_reward() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -6626,7 +6654,7 @@ fn create_tally_validation_dr_liar() { // Create a DataRequestPool with 3 reveals (one of them is a lie from the data requester) let dr_output = example_data_request_output_with_mode_filter(3, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, _slashed, _error_witnesses, dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, _slashed, _error_witnesses, dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage_with_dr_liar( dr_output.clone(), 3, @@ -6687,8 +6715,8 @@ fn create_tally_validation_dr_liar() { let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -6717,7 +6745,7 @@ fn create_tally_validation_5_reveals_1_liar_1_error() { // Create a DataRequestPool with 5 reveals (one lie and one error) let dr_output = example_data_request_output_with_mode_filter(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage_with_errors( dr_output.clone(), 5, @@ -6797,8 +6825,8 @@ fn create_tally_validation_5_reveals_1_liar_1_error() { let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -6817,7 +6845,7 @@ fn create_tally_validation_4_commits_2_reveals() { // Create a DataRequestPool with 4 commits and 2 reveals let dr_output = example_data_request_output_with_mode_filter(4, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, _error_witnesses, dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, _error_witnesses, dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage( dr_output.clone(), 4, @@ -6874,8 +6902,8 @@ fn create_tally_validation_4_commits_2_reveals() { let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -6888,7 +6916,7 @@ fn create_tally_validation_4_commits_2_reveals() { fn tally_valid_zero_commits() { let active_wips = current_active_wips(); let dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage(dr_output, 0, 0, 0, vec![], vec![], active_wips.clone()); assert_eq!(reward, 0); @@ -6909,8 +6937,8 @@ fn tally_valid_zero_commits() { TallyTransaction::new(dr_pointer, tally_value, vec![vt0], slashed, error_witnesses); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -6923,7 +6951,7 @@ fn tally_valid_zero_commits() { fn create_tally_validation_zero_commits() { let active_wips = current_active_wips(); let dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, _rewarded, _slashed, _error_witnesses, dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, _rewarded, _slashed, _error_witnesses, dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage( dr_output.clone(), 0, @@ -6956,8 +6984,8 @@ fn create_tally_validation_zero_commits() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -6970,7 +6998,7 @@ fn create_tally_validation_zero_commits() { fn tally_invalid_zero_commits() { let active_wips = current_active_wips(); let dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage(dr_output, 0, 0, 0, vec![], vec![], active_wips.clone()); assert_eq!(reward, 0); @@ -7001,8 +7029,8 @@ fn tally_invalid_zero_commits() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -7021,7 +7049,7 @@ fn tally_invalid_zero_commits() { fn tally_valid_zero_reveals() { let active_wips = current_active_wips(); let dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage( dr_output.clone(), 5, @@ -7083,8 +7111,8 @@ fn tally_valid_zero_reveals() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -7097,7 +7125,7 @@ fn tally_valid_zero_reveals() { fn create_tally_validation_zero_reveals() { let active_wips = current_active_wips(); let dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage( dr_output.clone(), 5, @@ -7138,8 +7166,8 @@ fn create_tally_validation_zero_reveals() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -7153,7 +7181,7 @@ fn create_tally_validation_zero_reveals_zero_collateral() { let active_wips = current_active_wips(); let mut dr_output = example_data_request_output(5, DEFAULT_WITNESS_REWARD, 20); dr_output.collateral = 0; - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, dr_pkh, _change, reward) = dr_pool_with_dr_in_tally_stage( dr_output.clone(), 5, @@ -7194,8 +7222,8 @@ fn create_tally_validation_zero_reveals_zero_collateral() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -7388,7 +7416,8 @@ fn tally_valid_4_reveals_all_liars() { let collateral = DEFAULT_COLLATERAL; let reveals = vec![vec![24, 60], vec![24, 60], vec![24, 61], vec![24, 47]]; let stddev_cbor = vec![249, 0, 0]; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr(4, reveals, stddev_cbor); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = + generic_tally_test_stddev_dr(4, reveals, stddev_cbor); let change = DEFAULT_WITNESS_REWARD * 4; // Tally value: insufficient consensus @@ -7429,8 +7458,8 @@ fn tally_valid_4_reveals_all_liars() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7442,7 +7471,7 @@ fn tally_valid_4_reveals_all_liars() { #[test] fn tally_valid_4_reveals_all_liars_attacker_pkh() { let collateral = DEFAULT_COLLATERAL; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr( + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_stddev_dr( 4, vec![vec![24, 60], vec![24, 60], vec![24, 61], vec![24, 47]], vec![249, 0, 0], @@ -7488,8 +7517,8 @@ fn tally_valid_4_reveals_all_liars_attacker_pkh() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7506,7 +7535,7 @@ fn tally_valid_4_reveals_all_liars_attacker_pkh() { fn tally_valid_4_reveals_2_liars_2_true() { let collateral = DEFAULT_COLLATERAL; let stddev_cbor = vec![249, 0x39, 0]; // 0.625 - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr( + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_stddev_dr( 4, vec![vec![24, 60], vec![24, 60], vec![24, 61], vec![24, 47]], stddev_cbor, @@ -7551,8 +7580,8 @@ fn tally_valid_4_reveals_2_liars_2_true() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7571,7 +7600,8 @@ fn tally_valid_4_reveals_2_errors_2_true() { vec![216, 39, 129, 0], vec![216, 39, 129, 0], ]; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr(4, reveals, stddev_cbor); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = + generic_tally_test_stddev_dr(4, reveals, stddev_cbor); let change = DEFAULT_WITNESS_REWARD * 4; // Tally value: insufficient consensus @@ -7612,8 +7642,8 @@ fn tally_valid_4_reveals_2_errors_2_true() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7626,7 +7656,7 @@ fn tally_valid_4_reveals_2_errors_2_true() { fn tally_valid_4_reveals_1_liar_2_true() { let collateral = DEFAULT_COLLATERAL; let stddev_cbor = vec![249, 0x39, 0]; // 0.625 - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr( + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_stddev_dr( 4, vec![vec![24, 60], vec![24, 60], vec![24, 61]], stddev_cbor, @@ -7671,8 +7701,8 @@ fn tally_valid_4_reveals_1_liar_2_true() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7690,7 +7720,8 @@ fn tally_valid_4_reveals_invalid_script_arg() { // Invalid argument for DeviationStandard filter (invalid CBOR): let stddev_cbor = vec![0x3F]; let reveals = vec![vec![24, 60], vec![24, 60], vec![24, 61], vec![24, 47]]; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr(4, reveals, stddev_cbor); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = + generic_tally_test_stddev_dr(4, reveals, stddev_cbor); let change = DEFAULT_WITNESS_REWARD * 4; // TODO: serialize tally value from RadError to make this test more clear @@ -7734,8 +7765,8 @@ fn tally_valid_4_reveals_invalid_script_arg() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7753,7 +7784,8 @@ fn tally_valid_3_reveals_1_no_reveal_invalid_script_arg() { // Invalid argument for DeviationStandard filter (invalid CBOR): let stddev_cbor = vec![0x3F]; let reveals = vec![vec![24, 60], vec![24, 60], vec![24, 61]]; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr(4, reveals, stddev_cbor); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = + generic_tally_test_stddev_dr(4, reveals, stddev_cbor); let change = DEFAULT_WITNESS_REWARD * 4 + 10; // TODO: serialize tally value from RadError to make this test more clear @@ -7797,8 +7829,8 @@ fn tally_valid_3_reveals_1_no_reveal_invalid_script_arg() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7817,7 +7849,7 @@ fn tally_valid_4_reveals_majority_of_errors() { vec![216, 39, 129, 24, 49], vec![216, 39, 129, 24, 49], ]; - let (pkhs, _dr_pkh, dr_pointer, dr_pool) = + let (pkhs, _dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_stddev_dr(4, reveals, stddev_cbor); let reward = DEFAULT_WITNESS_REWARD + DEFAULT_COLLATERAL; @@ -7852,8 +7884,8 @@ fn tally_valid_4_reveals_majority_of_errors() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7871,7 +7903,8 @@ fn tally_valid_3_reveals_1_no_reveal_majority_of_errors() { vec![216, 39, 129, 24, 49], vec![216, 39, 129, 24, 49], ]; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr(4, reveals, stddev_cbor); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = + generic_tally_test_stddev_dr(4, reveals, stddev_cbor); let active_wips = current_active_wips(); let (reward, change) = if active_wips.wip0023() { ( @@ -7916,8 +7949,8 @@ fn tally_valid_3_reveals_1_no_reveal_majority_of_errors() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7932,7 +7965,8 @@ fn tally_valid_2_reveals_2_no_reveals_majority_of_errors_insufficient_consensus( let stddev_cbor = vec![249, 0, 0]; // 0.0 // RetrieveTimeout let reveals = vec![vec![216, 39, 129, 24, 49], vec![216, 39, 129, 24, 49]]; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr(4, reveals, stddev_cbor); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = + generic_tally_test_stddev_dr(4, reveals, stddev_cbor); let change = DEFAULT_WITNESS_REWARD * 4 + 10 * 2; // TODO: serialize tally value from RadError to make this test more clear @@ -7973,8 +8007,8 @@ fn tally_valid_2_reveals_2_no_reveals_majority_of_errors_insufficient_consensus( ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -7995,7 +8029,8 @@ fn tally_valid_4_reveals_majority_of_errors_insufficient_consensus() { vec![216, 39, 129, 24, 64], // Overflow vec![216, 39, 129, 24, 65], // Underflow ]; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr(4, reveals, stddev_cbor); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = + generic_tally_test_stddev_dr(4, reveals, stddev_cbor); let change = DEFAULT_WITNESS_REWARD * 4; // TODO: serialize tally value from RadError to make this test more clear @@ -8036,8 +8071,8 @@ fn tally_valid_4_reveals_majority_of_errors_insufficient_consensus() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -8057,7 +8092,8 @@ fn tally_valid_3_reveals_1_no_reveal_majority_of_errors_insufficient_consensus() vec![216, 39, 129, 24, 49], vec![216, 39, 129, 24, 64], // Overflow ]; - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_stddev_dr(4, reveals, stddev_cbor); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = + generic_tally_test_stddev_dr(4, reveals, stddev_cbor); let change = DEFAULT_WITNESS_REWARD * 4 + 10; // TODO: serialize tally value from RadError to make this test more clear @@ -8098,8 +8134,8 @@ fn tally_valid_3_reveals_1_no_reveal_majority_of_errors_insufficient_consensus() ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -8129,7 +8165,7 @@ fn tally_valid_rng() { )), ]; let reveals = reveals.into_iter().map(|x| x.encode().unwrap()).collect(); - let (pkhs, _dr_pkh, dr_pointer, dr_pool) = generic_tally_test_rng(4, reveals); + let (pkhs, _dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_rng(4, reveals); let reward = DEFAULT_WITNESS_REWARD + DEFAULT_COLLATERAL; let tally_value = RadonTypes::from(RadonBytes::from( @@ -8166,8 +8202,8 @@ fn tally_valid_rng() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -8185,7 +8221,7 @@ fn tally_valid_rng_wrong_bytes_len() { RadonTypes::from(RadonBytes::from(hex::decode("4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8affffffffffffffffffffffff").unwrap())), ]; let reveals = reveals.into_iter().map(|x| x.encode().unwrap()).collect(); - let (pkhs, _dr_pkh, dr_pointer, dr_pool) = generic_tally_test_rng(4, reveals); + let (pkhs, _dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_rng(4, reveals); let reward = DEFAULT_WITNESS_REWARD + DEFAULT_COLLATERAL; let tally_value = RadonTypes::from(RadonBytes::from( @@ -8222,8 +8258,8 @@ fn tally_valid_rng_wrong_bytes_len() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -8256,7 +8292,7 @@ fn tally_valid_rng_one_error() { ), ]; let reveals = reveals.into_iter().map(|x| x.encode().unwrap()).collect(); - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_rng(4, reveals); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_rng(4, reveals); let collateral = DEFAULT_COLLATERAL; let reward = collateral + DEFAULT_WITNESS_REWARD; let change = DEFAULT_WITNESS_REWARD; @@ -8300,8 +8336,8 @@ fn tally_valid_rng_one_error() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -8343,7 +8379,7 @@ fn tally_valid_rng_all_errors() { ), ]; let reveals = reveals.into_iter().map(|x| x.encode().unwrap()).collect(); - let (pkhs, _dr_pkh, dr_pointer, dr_pool) = generic_tally_test_rng(4, reveals); + let (pkhs, _dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_rng(4, reveals); let collateral = DEFAULT_COLLATERAL; let reward = collateral + DEFAULT_WITNESS_REWARD; @@ -8385,8 +8421,8 @@ fn tally_valid_rng_all_errors() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -8413,7 +8449,7 @@ fn tally_valid_rng_one_invalid_type() { RadonTypes::from(RadonInteger::from(4)), ]; let reveals = reveals.into_iter().map(|x| x.encode().unwrap()).collect(); - let (pkhs, dr_pkh, dr_pointer, dr_pool) = generic_tally_test_rng(4, reveals); + let (pkhs, dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_rng(4, reveals); let collateral = DEFAULT_COLLATERAL; let active_wips = current_active_wips(); let reward = if active_wips.wip0023() { @@ -8457,8 +8493,8 @@ fn tally_valid_rng_one_invalid_type() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -8476,7 +8512,7 @@ fn tally_valid_rng_all_invalid_type() { RadonTypes::from(RadonInteger::from(4)), ]; let reveals = reveals.into_iter().map(|x| x.encode().unwrap()).collect(); - let (pkhs, _dr_pkh, dr_pointer, dr_pool) = generic_tally_test_rng(4, reveals); + let (pkhs, _dr_pkh, dr_pointer, mut dr_pool) = generic_tally_test_rng(4, reveals); let collateral = DEFAULT_COLLATERAL; let reward = collateral + DEFAULT_WITNESS_REWARD; @@ -8514,8 +8550,8 @@ fn tally_valid_rng_all_invalid_type() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, ¤t_active_wips(), None, None, @@ -8541,7 +8577,7 @@ fn tally_unserializable_value() { // Reveal value: negative(18446744073709551361) let reveal_value = vec![59, 255, 255, 255, 255, 255, 255, 255, 0]; let dr_output = example_data_request_output_average_mean_reducer(2, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage( dr_output, 2, @@ -8576,8 +8612,8 @@ fn tally_unserializable_value() { ); let x = validate_tally_transaction( &tally_transaction, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8596,7 +8632,7 @@ fn tally_unhandled_intercept_with_message() { 216, 39, 130, 24, 255, 0x66, b'H', b'e', b'l', b'l', b'o', b'!', ]; let dr_output = example_data_request_output(2, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = dr_pool_with_dr_in_tally_all_errors(dr_output, 2, 2, reveal_value.clone()); // You earn your reward, and get your collateral back assert_eq!(reward, DEFAULT_WITNESS_REWARD + DEFAULT_COLLATERAL); @@ -8639,8 +8675,8 @@ fn tally_unhandled_intercept_with_message() { // tally_transaction_with_message is valid, tally_transaction_no_message is invalid let x = validate_tally_transaction( &tally_transaction_with_message, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8649,8 +8685,8 @@ fn tally_unhandled_intercept_with_message() { x.unwrap(); let x = validate_tally_transaction( &tally_transaction_no_message, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8673,8 +8709,8 @@ fn tally_unhandled_intercept_with_message() { // tally_transaction_with_message is invalid, tally_transaction_no_message is valid let x = validate_tally_transaction( &tally_transaction_with_message, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8689,8 +8725,8 @@ fn tally_unhandled_intercept_with_message() { ); let x = validate_tally_transaction( &tally_transaction_no_message, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8711,7 +8747,7 @@ fn tally_unhandled_intercept_mode_tie_has_no_message() { let reveal_value_2 = vec![0x02]; let reveal_values = vec![reveal_value_1, reveal_value_2]; let dr_output = example_data_request_output(2, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = dr_pool_with_dr_in_tally_stage_different_reveals( dr_output, 2, @@ -8770,8 +8806,8 @@ fn tally_unhandled_intercept_mode_tie_has_no_message() { // tally_transaction_with_message is valid, tally_transaction_no_message is invalid let x = validate_tally_transaction( &tally_transaction_with_message, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8780,8 +8816,8 @@ fn tally_unhandled_intercept_mode_tie_has_no_message() { x.unwrap(); let x = validate_tally_transaction( &tally_transaction_no_message, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8804,8 +8840,8 @@ fn tally_unhandled_intercept_mode_tie_has_no_message() { // tally_transaction_with_message is invalid, tally_transaction_no_message is valid let x = validate_tally_transaction( &tally_transaction_with_message, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8820,8 +8856,8 @@ fn tally_unhandled_intercept_mode_tie_has_no_message() { ); let x = validate_tally_transaction( &tally_transaction_no_message, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8835,7 +8871,7 @@ fn tally_error_encode_reveal_wip() { // Reveal value (EncodeReveal error): 39([97]) let reveal_value = vec![216, 39, 129, 24, 97]; let dr_output = example_data_request_output(2, DEFAULT_WITNESS_REWARD, 20); - let (dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = + let (mut dr_pool, dr_pointer, _rewarded, slashed, error_witnesses, _dr_pkh, change, reward) = dr_pool_with_dr_in_tally_all_errors(dr_output, 2, 2, reveal_value); // You earn your reward, and get your collateral back assert_eq!(reward, DEFAULT_WITNESS_REWARD + DEFAULT_COLLATERAL); @@ -8870,8 +8906,8 @@ fn tally_error_encode_reveal_wip() { // Before WIP-0026: let x = validate_tally_transaction( &tally_transaction_error_encode_reveal, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, @@ -8891,8 +8927,8 @@ fn tally_error_encode_reveal_wip() { // After WIP-0026: let x = validate_tally_transaction( &tally_transaction_error_encode_reveal, - &dr_pool, - ONE_WIT, + &mut dr_pool, + &CONSENSUS_CONSTANTS_FOR_TALLY, &active_wips, None, None, diff --git a/validations/src/validations.rs b/validations/src/validations.rs index d2bddda61..d61027bfc 100644 --- a/validations/src/validations.rs +++ b/validations/src/validations.rs @@ -27,7 +27,7 @@ use witnet_data_structures::{ data_request_has_too_many_witnesses, DataRequestPool, }, error::{BlockError, DataRequestError, TransactionError}, - get_protocol_version, + get_protocol_version, get_protocol_version_activation_epoch, proto::versioning::{ProtocolVersion, VersionedHashable}, radon_report::{RadonReport, ReportContext}, staking::prelude::{Power, QueryStakesKey, StakeKey, StakesTracker}, @@ -1040,8 +1040,8 @@ pub fn calculate_liars_and_errors_count_from_tally(tally_tx: &TallyTransaction) /// Function to validate a tally transaction pub fn validate_tally_transaction<'a>( ta_tx: &'a TallyTransaction, - dr_pool: &DataRequestPool, - collateral_minimum: u64, + dr_pool: &mut DataRequestPool, + consensus_constants: &ConsensusConstants, active_wips: &ActiveWips, validator_count: Option, epoch: Option, @@ -1049,9 +1049,21 @@ pub fn validate_tally_transaction<'a>( let validator_count = validator_count.unwrap_or(witnet_data_structures::DEFAULT_VALIDATOR_COUNT_FOR_TESTS); let too_many_witnesses; - if let Some(dr_state) = dr_pool.data_request_state(&ta_tx.dr_pointer) { + if let Some(dr_state) = dr_pool.data_request_state_mutable(&ta_tx.dr_pointer) { too_many_witnesses = data_request_has_too_many_witnesses(&dr_state.data_request, validator_count, epoch); + + // Update the data request once at the epoch where V2.0 activates + // This handles the edge case where a data request which was already included still needs to be + // updated in consolidate_block, but is was short-circuited to the tally stage when V2.0 activates + // because it requested too many witnesses + if too_many_witnesses { + if let Some(epoch) = epoch { + if get_protocol_version_activation_epoch(ProtocolVersion::V2_0) == epoch { + dr_state.update_stage(consensus_constants.extra_rounds, too_many_witnesses); + } + } + } } else { return Err(TransactionError::DataRequestNotFound { hash: ta_tx.dr_pointer, @@ -1061,7 +1073,7 @@ pub fn validate_tally_transaction<'a>( let (expected_ta_tx, dr_state) = create_expected_tally_transaction( ta_tx, dr_pool, - collateral_minimum, + consensus_constants.collateral_minimum, active_wips, too_many_witnesses, epoch, @@ -1138,7 +1150,7 @@ pub fn validate_tally_transaction<'a>( ); let collateral = if dr_state.data_request.collateral == 0 { - collateral_minimum + consensus_constants.collateral_minimum } else { dr_state.data_request.collateral }; @@ -2092,7 +2104,7 @@ pub fn validate_block_transactions( let (outputs, fee) = validate_tally_transaction( transaction, dr_pool, - consensus_constants.collateral_minimum, + consensus_constants, active_wips, Some(stakes.validator_count()), Some(epoch), From 0a244b1e9963a03c33a8851598677970b9bea06b Mon Sep 17 00:00:00 2001 From: drcpu Date: Sun, 24 Nov 2024 19:52:40 +0000 Subject: [PATCH 2/6] fix(node): use correct epochs while synchronizing node --- node/src/actors/chain_manager/actor.rs | 17 ++++------ node/src/actors/chain_manager/mod.rs | 47 ++++++++++---------------- 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/node/src/actors/chain_manager/actor.rs b/node/src/actors/chain_manager/actor.rs index 633e94c01..5c7f0a343 100644 --- a/node/src/actors/chain_manager/actor.rs +++ b/node/src/actors/chain_manager/actor.rs @@ -192,16 +192,6 @@ impl ChainManager { if consensus_constants == &chain_info_from_storage.consensus_constants { log::debug!("ChainInfo successfully obtained from storage"); - // Load protocol info into global state (overwrites whatever was set - // through configuration). If possible, derives the current protocol - // version from that info and the current epoch. This essentially - // allows a node to catch up with a new protocol version if the - // transition happened while it was down. - load_protocol_info(chain_info_from_storage.protocol.clone()); - if let Some(ChainInfo { highest_block_checkpoint, .. }) = chain_state_from_storage.chain_info { - refresh_protocol_version(highest_block_checkpoint.checkpoint); - } - chain_state_from_storage } else { // Mismatching consensus constants between config and storage @@ -370,6 +360,13 @@ impl ChainManager { chain_info.highest_block_checkpoint.hash_prev_block ); + // Load protocol info into global state (overwrites whatever was set through + // configuration). If possible, derives the current protocol version from that + // info and the current epoch. This essentially allows a node to catch up with + // a new protocol version if the transition happened while it was down. + load_protocol_info(chain_info.protocol.clone()); + refresh_protocol_version(chain_info.highest_block_checkpoint.checkpoint); + // If hash_prev_block is the bootstrap hash, create and consolidate genesis block. // Consolidating the genesis block is not needed if the chain state has been reset // because of a rewind: the genesis block will be processed with the other blocks. diff --git a/node/src/actors/chain_manager/mod.rs b/node/src/actors/chain_manager/mod.rs index 2f02fe34d..712371b12 100644 --- a/node/src/actors/chain_manager/mod.rs +++ b/node/src/actors/chain_manager/mod.rs @@ -950,23 +950,6 @@ impl ChainManager { } }; - let current_epoch = if let Some(epoch) = self.current_epoch { - epoch - } else { - // If there is no epoch set, it's because the chain is yet to be bootstrapped, or because of a data race - match self.chain_state.chain_info.as_ref() { - // If the chain is yet to be bootstrapped (the block we are processing is the genesis block), set the epoch to zero - Some(chain_info) if chain_info.consensus_constants.genesis_hash == block.hash() => { - 0 - } - // In case of data race, shortcut the function - _ => { - log::error!("Current epoch not loaded in ChainManager"); - return; - } - } - }; - match self.chain_state { ChainState { chain_info: Some(ref mut chain_info), @@ -1203,7 +1186,7 @@ impl ChainManager { transaction_fees += vt_transaction_fee( vt_tx, &utxo_diff_wit2, - current_epoch, + block_epoch, epoch_constants, ) .unwrap_or_default(); @@ -1212,7 +1195,7 @@ impl ChainManager { transaction_fees += dr_transaction_fee( dr_tx, &utxo_diff_wit2, - current_epoch, + block_epoch, epoch_constants, ) .unwrap_or_default(); @@ -1221,7 +1204,7 @@ impl ChainManager { transaction_fees += st_transaction_fee( st_tx, &utxo_diff_wit2, - current_epoch, + block_epoch, epoch_constants, ) .unwrap_or_default(); @@ -1252,9 +1235,9 @@ impl ChainManager { log::debug!( "Resetting mining age for {} to {}", miner_pkh, - current_epoch, + block_epoch + 1, ); - let _ = stakes.reset_age(miner_pkh, Capability::Mining, current_epoch, 1); + let _ = stakes.reset_age(miner_pkh, Capability::Mining, block_epoch + 1, 1); // Reset witnessing power for co_tx in &block.txns.commit_txns { @@ -1262,10 +1245,14 @@ impl ChainManager { log::debug!( "Resetting witnessing age for {} to {}", commit_pkh, - current_epoch, + block_epoch + 1, + ); + let _ = stakes.reset_age( + commit_pkh, + Capability::Witnessing, + block_epoch + 1, + 1, ); - let _ = - stakes.reset_age(commit_pkh, Capability::Witnessing, current_epoch, 1); } // Slash lieing validators @@ -1325,7 +1312,7 @@ impl ChainManager { let minimum_stakeable = self .consensus_constants_wit2 - .get_validator_min_stake_nanowits(current_epoch); + .get_validator_min_stake_nanowits(block_epoch); let _ = process_stake_transactions( stakes, @@ -1341,7 +1328,7 @@ impl ChainManager { let minimum_stakeable = self .consensus_constants_wit2 - .get_validator_min_stake_nanowits(current_epoch); + .get_validator_min_stake_nanowits(block_epoch); let _ = process_unstake_transactions( stakes, @@ -1381,7 +1368,7 @@ impl ChainManager { let reveals = self .chain_state .data_request_pool - .update_data_request_stages(Some(validator_count), Some(current_epoch)); + .update_data_request_stages(Some(validator_count), Some(block_epoch)); for reveal in reveals { // Send AddTransaction message to self @@ -1407,7 +1394,7 @@ impl ChainManager { let reveals = self .chain_state .data_request_pool - .update_data_request_stages(Some(validator_count), Some(current_epoch)); + .update_data_request_stages(Some(validator_count), Some(block_epoch)); for reveal in reveals { // Send AddTransaction message to self @@ -1433,7 +1420,7 @@ impl ChainManager { let reveals = self .chain_state .data_request_pool - .update_data_request_stages(Some(validator_count), Some(current_epoch)); + .update_data_request_stages(Some(validator_count), Some(block_epoch)); show_info_dr(&self.chain_state.data_request_pool, &block); From 65134e20c18ee2fb3b342775e49a055df72e97a5 Mon Sep 17 00:00:00 2001 From: drcpu Date: Sun, 24 Nov 2024 19:55:25 +0000 Subject: [PATCH 3/6] chore(node): disable reputation updating in wit/2 --- node/src/actors/chain_manager/mod.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/node/src/actors/chain_manager/mod.rs b/node/src/actors/chain_manager/mod.rs index 712371b12..6566522f8 100644 --- a/node/src/actors/chain_manager/mod.rs +++ b/node/src/actors/chain_manager/mod.rs @@ -1295,16 +1295,18 @@ impl ChainManager { // Do not update reputation or stakes when consolidating genesis block if block_hash != chain_info.consensus_constants.genesis_hash { - update_reputation( - reputation_engine, - &mut self.chain_state.alt_keys, - &chain_info.consensus_constants, - miner_pkh, - rep_info, - log_level, - block_epoch, - self.own_pkh.unwrap_or_default(), - ); + if ProtocolVersion::from_epoch(block_epoch) < ProtocolVersion::V2_0 { + update_reputation( + reputation_engine, + &mut self.chain_state.alt_keys, + &chain_info.consensus_constants, + miner_pkh, + rep_info, + log_level, + block_epoch, + self.own_pkh.unwrap_or_default(), + ); + } let stake_txns_count = block.txns.stake_txns.len(); if stake_txns_count > 0 { From 1a364850d2e839ed60df47e22681e391dd5a1990 Mon Sep 17 00:00:00 2001 From: drcpu Date: Wed, 27 Nov 2024 09:11:04 +0000 Subject: [PATCH 4/6] fix(stakes): use by_validator in rank function to prevent duplicated entries --- data_structures/src/staking/stakes.rs | 58 ++++++++++++----------- node/src/actors/chain_manager/handlers.rs | 6 +-- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/data_structures/src/staking/stakes.rs b/data_structures/src/staking/stakes.rs index 1f850b1eb..a7ffacb9f 100644 --- a/data_structures/src/staking/stakes.rs +++ b/data_structures/src/staking/stakes.rs @@ -206,7 +206,7 @@ where capability: Capability, epoch: Epoch, strategy: CensusStrategy, - ) -> Box> + '_> { + ) -> Box + '_> { let iterator = self.rank(capability, epoch).map(|(address, _)| address); match strategy { @@ -256,13 +256,17 @@ where &self, capability: Capability, current_epoch: Epoch, - ) -> impl Iterator, Power)> + '_ { - self.by_coins + ) -> impl Iterator + '_ { + self.by_validator .iter() - .map(move |(CoinsAndAddresses { addresses, .. }, stake)| { - let power = stake.read_value().power(capability, current_epoch); - - (addresses.clone(), power) + .map(move |(address, stakes)| { + let power = stakes + .first() + .unwrap() + .read_value() + .power(capability, current_epoch); + + (address.clone(), power) }) .sorted_by_key(|(_, power)| *power) .rev() @@ -1025,17 +1029,17 @@ mod tests { assert_eq!( stakes.rank(Capability::Mining, 100).collect::>(), [ - (charlie_erin.into(), 2100), - (bob_david.into(), 1600), - (alice_charlie.into(), 1000) + (charlie.into(), 2100), + (bob.into(), 1600), + (alice.into(), 1000) ] ); assert_eq!( stakes.rank(Capability::Witnessing, 100).collect::>(), [ - (charlie_erin.into(), 2100), - (bob_david.into(), 1600), - (alice_charlie.into(), 1000) + (charlie.into(), 2100), + (bob.into(), 1600), + (alice.into(), 1000) ] ); @@ -1064,17 +1068,17 @@ mod tests { assert_eq!( stakes.rank(Capability::Mining, 101).collect::>(), [ - (bob_david.into(), 1_620), - (alice_charlie.into(), 1_010), - (charlie_erin.into(), 0) + (bob.into(), 1_620), + (alice.into(), 1_010), + (charlie.into(), 0) ] ); assert_eq!( stakes.rank(Capability::Witnessing, 101).collect::>(), [ - (charlie_erin.into(), 2_130), - (bob_david.into(), 1_620), - (alice_charlie.into(), 1_010) + (charlie.into(), 2_130), + (bob.into(), 1_620), + (alice.into(), 1_010) ] ); @@ -1105,17 +1109,17 @@ mod tests { assert_eq!( stakes.rank(Capability::Mining, 300).collect::>(), [ - (charlie_erin.into(), 5_970), - (bob_david.into(), 5_600), - (alice_charlie.into(), 3_000) + (charlie.into(), 5_970), + (bob.into(), 5_600), + (alice.into(), 3_000) ] ); assert_eq!( stakes.rank(Capability::Witnessing, 300).collect::>(), [ - (charlie_erin.into(), 8_100), - (bob_david.into(), 5_600), - (alice_charlie.into(), 3_000) + (charlie.into(), 8_100), + (bob.into(), 5_600), + (alice.into(), 3_000) ] ); } @@ -1159,9 +1163,9 @@ mod tests { // david_erin: 40 * (90 - 30) = 2400 // erin_alice: 50 * (90 - 40) = 2500 let rank_subset: Vec<_> = stakes.rank(Capability::Mining, 90).take(4).collect(); - for (i, (stake_key, _)) in rank_subset.into_iter().enumerate() { + for (i, (validator, _)) in rank_subset.into_iter().enumerate() { let _ = stakes.reset_age( - stake_key.validator, + validator, Capability::Mining, 90, (i + 1).try_into().unwrap(), diff --git a/node/src/actors/chain_manager/handlers.rs b/node/src/actors/chain_manager/handlers.rs index 45efd60b3..b1425a3bb 100644 --- a/node/src/actors/chain_manager/handlers.rs +++ b/node/src/actors/chain_manager/handlers.rs @@ -201,13 +201,13 @@ impl Handler> for ChainManager { .rank(Capability::Mining, previous_epoch) .take(replication_factor.into()) .collect(); - for (i, (stake_key, _)) in rank_subset.into_iter().enumerate() { + for (i, (validator, _)) in rank_subset.into_iter().enumerate() { log::warn!( "Slashed the power of {} as it did not propose a block", - stake_key.validator + validator ); let _ = stakes.reset_age( - stake_key.validator, + validator, Capability::Mining, msg.checkpoint, // This should never fail From 40d08713b8cc5753c4cdd373de59c329d0c49b0c Mon Sep 17 00:00:00 2001 From: drcpu Date: Fri, 22 Nov 2024 22:40:45 +0100 Subject: [PATCH 5/6] feat(stakes): enforce total ordering on the rank function --- data_structures/src/staking/stakes.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/data_structures/src/staking/stakes.rs b/data_structures/src/staking/stakes.rs index a7ffacb9f..8f8bf0ba2 100644 --- a/data_structures/src/staking/stakes.rs +++ b/data_structures/src/staking/stakes.rs @@ -268,7 +268,14 @@ where (address.clone(), power) }) - .sorted_by_key(|(_, power)| *power) + .sorted_by(|(address_1, power_1), (address_2, power_2)| { + // Equal power, compare the addresses to achieve deterministic ordering + if power_1 == power_2 { + address_1.cmp(address_2) + } else { + power_1.cmp(power_2) + } + }) .rev() } From eafc461d986c767dcc7ee2d35d4c6eefd339a390 Mon Sep 17 00:00:00 2001 From: drcpu Date: Wed, 27 Nov 2024 11:36:30 +0100 Subject: [PATCH 6/6] feat(stakes): remove empty stake entries from by_validator and by_withdrawer --- data_structures/src/staking/stakes.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/data_structures/src/staking/stakes.rs b/data_structures/src/staking/stakes.rs index 8f8bf0ba2..bcb447fa5 100644 --- a/data_structures/src/staking/stakes.rs +++ b/data_structures/src/staking/stakes.rs @@ -323,6 +323,28 @@ where // No need to keep the entry if the stake has gone to zero if final_coins.is_zero() { by_address_entry.remove(); + if let Some(ref mut stakes) = self.by_validator.get_mut(&key.validator) { + stakes.remove( + stakes + .iter() + .position(|stake| stake.read_value().coins == 0.into()) + .unwrap(), + ); + if stakes.is_empty() { + self.by_validator.remove(&key.validator); + } + } + if let Some(ref mut stakes) = self.by_withdrawer.get_mut(&key.withdrawer) { + stakes.remove( + stakes + .iter() + .position(|stake| stake.read_value().coins == 0.into()) + .unwrap(), + ); + if stakes.is_empty() { + self.by_withdrawer.remove(&key.withdrawer); + } + } self.by_coins.remove(&CoinsAndAddresses { coins: initial_coins, addresses: key,