From 184e7cf34d1c4241e844607e69f396e4d395a381 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Sat, 22 Apr 2023 17:19:14 -0300 Subject: [PATCH 01/18] add ZIP-317 rules to mempool --- zebra-chain/src/transaction.rs | 4 +- zebra-chain/src/transaction/unmined.rs | 19 +- zebra-chain/src/transaction/unmined/zip317.rs | 36 +++ .../src/transaction/unmined/zip317/tests.rs | 28 ++ zebra-consensus/src/error.rs | 4 + zebra-consensus/src/transaction.rs | 7 +- zebra-consensus/src/transaction/tests.rs | 266 ++++++++++++++++-- zebra-consensus/src/transaction/tests/prop.rs | 9 +- .../methods/get_block_template_rpcs/zip317.rs | 6 +- .../components/inbound/tests/fake_peer_set.rs | 8 +- .../src/components/mempool/storage/tests.rs | 5 +- .../components/mempool/storage/tests/prop.rs | 12 +- .../mempool/storage/tests/vectors.rs | 4 +- zebrad/src/components/mempool/tests/vector.rs | 18 +- 14 files changed, 372 insertions(+), 54 deletions(-) create mode 100644 zebra-chain/src/transaction/unmined/zip317/tests.rs diff --git a/zebra-chain/src/transaction.rs b/zebra-chain/src/transaction.rs index d6de1f895fb..0b2c25583d2 100644 --- a/zebra-chain/src/transaction.rs +++ b/zebra-chain/src/transaction.rs @@ -34,7 +34,9 @@ pub use serialize::{ MIN_TRANSPARENT_TX_V5_SIZE, }; pub use sighash::{HashType, SigHash}; -pub use unmined::{UnminedTx, UnminedTxId, VerifiedUnminedTx, MEMPOOL_TRANSACTION_COST_THRESHOLD}; +pub use unmined::{ + zip317, UnminedTx, UnminedTxId, VerifiedUnminedTx, MEMPOOL_TRANSACTION_COST_THRESHOLD, +}; use crate::{ amount::{Amount, Error as AmountError, NegativeAllowed, NonNegative}, diff --git a/zebra-chain/src/transaction/unmined.rs b/zebra-chain/src/transaction/unmined.rs index 9d479ac131b..2daeea9118b 100644 --- a/zebra-chain/src/transaction/unmined.rs +++ b/zebra-chain/src/transaction/unmined.rs @@ -36,7 +36,7 @@ use proptest_derive::Arbitrary; #[allow(unused_imports)] use crate::block::MAX_BLOCK_BYTES; -mod zip317; +pub mod zip317; /// The minimum cost value for a transaction in the mempool. /// @@ -335,6 +335,9 @@ impl fmt::Display for VerifiedUnminedTx { .finish() } } +/// The ZIP-317 recommended limit on the number of unpaid actions per block. +/// `block_unpaid_action_limit` in ZIP-317. +pub const BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT: u32 = 50; impl VerifiedUnminedTx { /// Create a new verified unmined transaction from an unmined transaction, @@ -343,17 +346,25 @@ impl VerifiedUnminedTx { transaction: UnminedTx, miner_fee: Amount, legacy_sigop_count: u64, - ) -> Self { + ) -> Result { let fee_weight_ratio = zip317::conventional_fee_weight_ratio(&transaction, miner_fee); let unpaid_actions = zip317::unpaid_actions(&transaction, miner_fee); - Self { + // Make the mempool checks. + zip317::mempool_checks( + unpaid_actions, + BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT, + miner_fee, + transaction.conventional_fee, + )?; + + Ok(Self { transaction, miner_fee, legacy_sigop_count, fee_weight_ratio, unpaid_actions, - } + }) } /// Returns `true` if the transaction pays at least the [ZIP-317] conventional fee. diff --git a/zebra-chain/src/transaction/unmined/zip317.rs b/zebra-chain/src/transaction/unmined/zip317.rs index 96c76a8481a..a6595e69b1c 100644 --- a/zebra-chain/src/transaction/unmined/zip317.rs +++ b/zebra-chain/src/transaction/unmined/zip317.rs @@ -4,6 +4,8 @@ use std::cmp::max; +use thiserror::Error; + use crate::{ amount::{Amount, NonNegative}, block::MAX_BLOCK_BYTES, @@ -11,6 +13,9 @@ use crate::{ transaction::{Transaction, UnminedTx}, }; +#[cfg(test)] +mod tests; + /// The marginal fee for the ZIP-317 fee calculation, in zatoshis per logical action. // // TODO: allow Amount in constants @@ -153,3 +158,34 @@ fn div_ceil(quotient: usize, divisor: usize) -> usize { // as long as the addition doesn't overflow or underflow. (quotient + divisor - 1) / divisor } + +/// Make ZIP-317 checks before inserting a transaction into the mempool. +pub fn mempool_checks( + unpaid_actions: u32, + unpaid_action_limit: u32, + miner_fee: Amount, + conventional_fee: Amount, +) -> Result<(), Error> { + // Check unpaid actions is below the thershold. + if unpaid_actions > unpaid_action_limit { + return Err(Error::UnpaidActions); + } + + // Check the fee is not below the calculated conventional fee for the transaction. + if miner_fee < conventional_fee { + return Err(Error::MinerFee); + } + + Ok(()) +} + +/// Errors related to ZIP-317. +#[derive(Error, Copy, Clone, Debug, PartialEq, Eq)] +#[allow(missing_docs)] +pub enum Error { + #[error("Unpaid actions is higher than the limit")] + UnpaidActions, + + #[error("Transaction fee is too low")] + MinerFee, +} diff --git a/zebra-chain/src/transaction/unmined/zip317/tests.rs b/zebra-chain/src/transaction/unmined/zip317/tests.rs new file mode 100644 index 00000000000..3ceb33b19f2 --- /dev/null +++ b/zebra-chain/src/transaction/unmined/zip317/tests.rs @@ -0,0 +1,28 @@ +//! ZIP-317 tests. + +use super::{mempool_checks, Amount, Error}; +#[test] +fn zip317_unpaid_actions_err() { + let check = mempool_checks( + 51, + 50, + Amount::try_from(1).unwrap(), + Amount::try_from(10000).unwrap(), + ); + + assert!(check.is_err()); + assert_eq!(check.err(), Some(Error::UnpaidActions)); +} + +#[test] +fn zip317_miner_fee_err() { + let check = mempool_checks( + 50, + 50, + Amount::try_from(1).unwrap(), + Amount::try_from(10000).unwrap(), + ); + + assert!(check.is_err()); + assert_eq!(check.err(), Some(Error::MinerFee)); +} diff --git a/zebra-consensus/src/error.rs b/zebra-consensus/src/error.rs index 578f706cb0f..833600c2caa 100644 --- a/zebra-consensus/src/error.rs +++ b/zebra-consensus/src/error.rs @@ -193,6 +193,10 @@ pub enum TransactionError { #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] // TODO: turn this into a typed error ValidateMempoolLockTimeError(String), + + #[error("failed to verify ZIP-317 transaction rules, transaction was not inserted to mempool")] + #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] + Zip317(#[from] zebra_chain::transaction::zip317::Error), } impl From for TransactionError { diff --git a/zebra-consensus/src/transaction.rs b/zebra-consensus/src/transaction.rs index 30516887de1..c2a361a73a6 100644 --- a/zebra-consensus/src/transaction.rs +++ b/zebra-consensus/src/transaction.rs @@ -460,14 +460,15 @@ where miner_fee, legacy_sigop_count, }, - Request::Mempool { transaction, .. } => Response::Mempool { - transaction: VerifiedUnminedTx::new( + Request::Mempool { transaction, .. } => { + let transaction = VerifiedUnminedTx::new( transaction, miner_fee.expect( "unexpected mempool coinbase transaction: should have already rejected", ), legacy_sigop_count, - ), + )?; + Response::Mempool { transaction } }, }; diff --git a/zebra-consensus/src/transaction/tests.rs b/zebra-consensus/src/transaction/tests.rs index 039adc132db..13e6137cbbd 100644 --- a/zebra-consensus/src/transaction/tests.rs +++ b/zebra-consensus/src/transaction/tests.rs @@ -23,7 +23,7 @@ use zebra_chain::{ fake_v5_transactions_for_network, insert_fake_orchard_shielded_data, test_transactions, transactions_from_blocks, }, - Hash, HashType, JoinSplitData, LockTime, Transaction, + zip317, Hash, HashType, JoinSplitData, LockTime, Transaction, }, transparent::{self, CoinbaseData}, }; @@ -240,7 +240,12 @@ async fn mempool_request_with_present_input_is_accepted() { .activation_height(Network::Mainnet) .expect("Canopy activation height is specified"); let fund_height = (height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(10001).expect("invalid value"), + ); // Create a non-coinbase V4 tx with the last valid expiry height. let tx = Transaction::V4 { @@ -302,7 +307,12 @@ async fn mempool_request_with_invalid_lock_time_is_rejected() { .activation_height(Network::Mainnet) .expect("Canopy activation height is specified"); let fund_height = (height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // Create a non-coinbase V4 tx with the last valid expiry height. let tx = Transaction::V4 { @@ -376,7 +386,12 @@ async fn mempool_request_with_unlocked_lock_time_is_accepted() { .activation_height(Network::Mainnet) .expect("Canopy activation height is specified"); let fund_height = (height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(10001).expect("invalid value"), + ); // Create a non-coinbase V4 tx with the last valid expiry height. let tx = Transaction::V4 { @@ -438,7 +453,12 @@ async fn mempool_request_with_lock_time_max_sequence_number_is_accepted() { .activation_height(Network::Mainnet) .expect("Canopy activation height is specified"); let fund_height = (height - 1).expect("fake source fund block height is too small"); - let (mut input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (mut input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(10001).expect("invalid value"), + ); // Ignore the lock time. input.set_sequence(u32::MAX); @@ -503,7 +523,12 @@ async fn mempool_request_with_past_lock_time_is_accepted() { .activation_height(Network::Mainnet) .expect("Canopy activation height is specified"); let fund_height = (height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(10001).expect("invalid value"), + ); // Create a non-coinbase V4 tx with the last valid expiry height. let tx = Transaction::V4 { @@ -738,7 +763,12 @@ async fn v4_transaction_with_transparent_transfer_is_accepted() { (transaction_block_height - 1).expect("fake source fund block height is too small"); // Create a fake transparent transfer that should succeed - let (input, output, known_utxos) = mock_transparent_transfer(fake_source_fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fake_source_fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // Create a V4 transaction let transaction = Transaction::V4 { @@ -783,7 +813,12 @@ async fn v4_transaction_with_last_valid_expiry_height() { .activation_height(Network::Mainnet) .expect("Canopy activation height is specified"); let fund_height = (block_height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // Create a non-coinbase V4 tx with the last valid expiry height. let transaction = Transaction::V4 { @@ -867,7 +902,12 @@ async fn v4_transaction_with_too_low_expiry_height() { .expect("Canopy activation height is specified"); let fund_height = (block_height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // This expiry height is too low so that the tx should seem expired to the verifier. let expiry_height = (block_height - 1).expect("original block height is too small"); @@ -912,7 +952,12 @@ async fn v4_transaction_with_exceeding_expiry_height() { let block_height = block::Height::MAX; let fund_height = (block_height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // This expiry height exceeds the maximum defined by the specification. let expiry_height = block::Height(500_000_000); @@ -1065,7 +1110,12 @@ async fn v4_transaction_with_transparent_transfer_is_rejected_by_the_script() { (transaction_block_height - 1).expect("fake source fund block height is too small"); // Create a fake transparent transfer that should not succeed - let (input, output, known_utxos) = mock_transparent_transfer(fake_source_fund_height, false, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fake_source_fund_height, + false, + 0, + Amount::try_from(1).expect("invalid value"), + ); // Create a V4 transaction let transaction = Transaction::V4 { @@ -1115,7 +1165,12 @@ async fn v4_transaction_with_conflicting_transparent_spend_is_rejected() { (transaction_block_height - 1).expect("fake source fund block height is too small"); // Create a fake transparent transfer that should succeed - let (input, output, known_utxos) = mock_transparent_transfer(fake_source_fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fake_source_fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // Create a V4 transaction let transaction = Transaction::V4 { @@ -1303,7 +1358,12 @@ async fn v5_transaction_with_transparent_transfer_is_accepted() { (transaction_block_height - 1).expect("fake source fund block height is too small"); // Create a fake transparent transfer that should succeed - let (input, output, known_utxos) = mock_transparent_transfer(fake_source_fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fake_source_fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // Create a V5 transaction let transaction = Transaction::V5 { @@ -1349,7 +1409,12 @@ async fn v5_transaction_with_last_valid_expiry_height() { .activation_height(Network::Testnet) .expect("Nu5 activation height for testnet is specified"); let fund_height = (block_height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // Create a non-coinbase V5 tx with the last valid expiry height. let transaction = Transaction::V5 { @@ -1504,7 +1569,12 @@ async fn v5_transaction_with_too_low_expiry_height() { .activation_height(Network::Testnet) .expect("Nu5 activation height for testnet is specified"); let fund_height = (block_height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // This expiry height is too low so that the tx should seem expired to the verifier. let expiry_height = (block_height - 1).expect("original block height is too small"); @@ -1550,7 +1620,12 @@ async fn v5_transaction_with_exceeding_expiry_height() { let block_height = block::Height::MAX; let fund_height = (block_height - 1).expect("fake source fund block height is too small"); - let (input, output, known_utxos) = mock_transparent_transfer(fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // This expiry height exceeds the maximum defined by the specification. let expiry_height = block::Height(500_000_000); @@ -1655,7 +1730,12 @@ async fn v5_transaction_with_transparent_transfer_is_rejected_by_the_script() { (transaction_block_height - 1).expect("fake source fund block height is too small"); // Create a fake transparent transfer that should not succeed - let (input, output, known_utxos) = mock_transparent_transfer(fake_source_fund_height, false, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fake_source_fund_height, + false, + 0, + Amount::try_from(1).expect("invalid value"), + ); // Create a V5 transaction let transaction = Transaction::V5 { @@ -1707,7 +1787,12 @@ async fn v5_transaction_with_conflicting_transparent_spend_is_rejected() { (transaction_block_height - 1).expect("fake source fund block height is too small"); // Create a fake transparent transfer that should succeed - let (input, output, known_utxos) = mock_transparent_transfer(fake_source_fund_height, true, 0); + let (input, output, known_utxos) = mock_transparent_transfer( + fake_source_fund_height, + true, + 0, + Amount::try_from(1).expect("invalid value"), + ); // Create a V4 transaction let transaction = Transaction::V5 { @@ -2165,6 +2250,7 @@ fn mock_transparent_transfer( previous_utxo_height: block::Height, script_should_succeed: bool, outpoint_index: u32, + previous_output_value: Amount, ) -> ( transparent::Input, transparent::Output, @@ -2188,7 +2274,7 @@ fn mock_transparent_transfer( }; let previous_output = transparent::Output { - value: Amount::try_from(1).expect("1 is an invalid amount"), + value: previous_output_value, lock_script, }; @@ -2628,3 +2714,145 @@ fn shielded_outputs_are_not_decryptable_for_fake_v5_blocks() { ); } } + +#[tokio::test] +async fn mempool_zip317_error() { + let mut state: MockService<_, _, _, _> = MockService::build().for_prop_tests(); + let verifier = Verifier::new(Network::Mainnet, state.clone()); + + let height = NetworkUpgrade::Nu5 + .activation_height(Network::Mainnet) + .expect("Canopy activation height is specified"); + let fund_height = (height - 1).expect("fake source fund block height is too small"); + + // Will produce a small enough miner fee to fail the check. + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(10).expect("invalid value"), + ); + + // Create a non-coinbase V4 tx with the last valid expiry height. + let tx = Transaction::V5 { + inputs: vec![input], + outputs: vec![output], + lock_time: LockTime::unlocked(), + network_upgrade: NetworkUpgrade::Nu5, + expiry_height: height, + sapling_shielded_data: None, + orchard_shielded_data: None, + }; + + let input_outpoint = match tx.inputs()[0] { + transparent::Input::PrevOut { outpoint, .. } => outpoint, + transparent::Input::Coinbase { .. } => panic!("requires a non-coinbase transaction"), + }; + + tokio::spawn(async move { + state + .expect_request(zebra_state::Request::UnspentBestChainUtxo(input_outpoint)) + .await + .expect("verifier should call mock state service with correct request") + .respond(zebra_state::Response::UnspentBestChainUtxo( + known_utxos + .get(&input_outpoint) + .map(|utxo| utxo.utxo.clone()), + )); + + state + .expect_request_that(|req| { + matches!( + req, + zebra_state::Request::CheckBestChainTipNullifiersAndAnchors(_) + ) + }) + .await + .expect("verifier should call mock state service with correct request") + .respond(zebra_state::Response::ValidBestChainTipNullifiersAndAnchors); + }); + + let verifier_response = verifier + .oneshot(Request::Mempool { + transaction: tx.into(), + height, + }) + .await; + + // Mempool refuse to add this transaction into storage. + assert!(verifier_response.is_err()); + assert_eq!( + verifier_response.err(), + Some(TransactionError::Zip317(zip317::Error::MinerFee)) + ); +} + +#[tokio::test] +async fn mempool_zip317_ok() { + let mut state: MockService<_, _, _, _> = MockService::build().for_prop_tests(); + let verifier = Verifier::new(Network::Mainnet, state.clone()); + + let height = NetworkUpgrade::Nu5 + .activation_height(Network::Mainnet) + .expect("Canopy activation height is specified"); + let fund_height = (height - 1).expect("fake source fund block height is too small"); + + // Will produce a small enough miner fee to fail the check. + let (input, output, known_utxos) = mock_transparent_transfer( + fund_height, + true, + 0, + Amount::try_from(10001).expect("invalid value"), + ); + + // Create a non-coinbase V4 tx with the last valid expiry height. + let tx = Transaction::V5 { + inputs: vec![input], + outputs: vec![output], + lock_time: LockTime::unlocked(), + network_upgrade: NetworkUpgrade::Nu5, + expiry_height: height, + sapling_shielded_data: None, + orchard_shielded_data: None, + }; + + let input_outpoint = match tx.inputs()[0] { + transparent::Input::PrevOut { outpoint, .. } => outpoint, + transparent::Input::Coinbase { .. } => panic!("requires a non-coinbase transaction"), + }; + + tokio::spawn(async move { + state + .expect_request(zebra_state::Request::UnspentBestChainUtxo(input_outpoint)) + .await + .expect("verifier should call mock state service with correct request") + .respond(zebra_state::Response::UnspentBestChainUtxo( + known_utxos + .get(&input_outpoint) + .map(|utxo| utxo.utxo.clone()), + )); + + state + .expect_request_that(|req| { + matches!( + req, + zebra_state::Request::CheckBestChainTipNullifiersAndAnchors(_) + ) + }) + .await + .expect("verifier should call mock state service with correct request") + .respond(zebra_state::Response::ValidBestChainTipNullifiersAndAnchors); + }); + + let verifier_response = verifier + .oneshot(Request::Mempool { + transaction: tx.into(), + height, + }) + .await; + + assert!( + verifier_response.is_ok(), + "expected successful verification, got: {verifier_response:?}" + ); +} diff --git a/zebra-consensus/src/transaction/tests/prop.rs b/zebra-consensus/src/transaction/tests/prop.rs index aaddb3649d6..a2c22377464 100644 --- a/zebra-consensus/src/transaction/tests/prop.rs +++ b/zebra-consensus/src/transaction/tests/prop.rs @@ -7,6 +7,7 @@ use proptest::{collection::vec, prelude::*}; use tower::ServiceExt; use zebra_chain::{ + amount::Amount, block, parameters::{Network, NetworkUpgrade}, serialization::arbitrary::{datetime_full, datetime_u32}, @@ -387,8 +388,12 @@ fn mock_transparent_transfers( .try_into() .expect("too many mock transparent transfers requested"); - let (input, output, new_utxos) = - mock_transparent_transfer(fake_source_fund_height, true, outpoint_index); + let (input, output, new_utxos) = mock_transparent_transfer( + fake_source_fund_height, + true, + outpoint_index, + Amount::try_from(1).expect("invalid value"), + ); inputs.push(input); outputs.push(output); diff --git a/zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs b/zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs index 2b086522667..07e63c7eb7c 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs @@ -15,7 +15,7 @@ use zebra_chain::{ amount::NegativeOrZero, block::{Height, MAX_BLOCK_BYTES}, parameters::Network, - transaction::VerifiedUnminedTx, + transaction::{VerifiedUnminedTx, BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT}, transparent, }; use zebra_consensus::MAX_BLOCK_SIGOPS; @@ -24,10 +24,6 @@ use crate::methods::get_block_template_rpcs::{ get_block_template::generate_coinbase_transaction, types::transaction::TransactionTemplate, }; -/// The ZIP-317 recommended limit on the number of unpaid actions per block. -/// `block_unpaid_action_limit` in ZIP-317. -pub const BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT: u32 = 50; - /// Selects mempool transactions for block production according to [ZIP-317], /// using a fake coinbase transaction and the mempool. /// diff --git a/zebrad/src/components/inbound/tests/fake_peer_set.rs b/zebrad/src/components/inbound/tests/fake_peer_set.rs index 9a9b797c027..da17caa6597 100644 --- a/zebrad/src/components/inbound/tests/fake_peer_set.rs +++ b/zebrad/src/components/inbound/tests/fake_peer_set.rs @@ -168,7 +168,7 @@ async fn mempool_push_transaction() -> Result<(), crate::BoxError> { transaction, Amount::zero(), 0, - ))); + ).expect("verification should pass"))); }); let (push_response, _) = futures::join!(request, verification); @@ -270,7 +270,7 @@ async fn mempool_advertise_transaction_ids() -> Result<(), crate::BoxError> { transaction, Amount::zero(), 0, - ))); + ).expect("verification should pass"))); }); let (advertise_response, _, _) = futures::join!(request, peer_set_responder, verification); @@ -369,7 +369,7 @@ async fn mempool_transaction_expiration() -> Result<(), crate::BoxError> { transaction, Amount::zero(), 0, - ))); + ).expect("verification should pass"))); }); let (push_response, _) = futures::join!(request, verification); @@ -503,7 +503,7 @@ async fn mempool_transaction_expiration() -> Result<(), crate::BoxError> { transaction, Amount::zero(), 0, - ))); + ).expect("verification should pass"))); }); let (push_response, _) = futures::join!(request, verification); diff --git a/zebrad/src/components/mempool/storage/tests.rs b/zebrad/src/components/mempool/storage/tests.rs index 8fdf5431a39..3d77d72cbcb 100644 --- a/zebrad/src/components/mempool/storage/tests.rs +++ b/zebrad/src/components/mempool/storage/tests.rs @@ -37,5 +37,8 @@ pub fn unmined_transactions_in_blocks( selected_blocks .flat_map(|block| block.transactions) .map(UnminedTx::from) - .map(|transaction| VerifiedUnminedTx::new(transaction, Amount::zero(), 0)) + .map(|transaction| { + VerifiedUnminedTx::new(transaction, Amount::zero(), 0) + .expect("verification should pass") + }) } diff --git a/zebrad/src/components/mempool/storage/tests/prop.rs b/zebrad/src/components/mempool/storage/tests/prop.rs index 9b3a447c9e0..d2b1b02f332 100644 --- a/zebrad/src/components/mempool/storage/tests/prop.rs +++ b/zebrad/src/components/mempool/storage/tests/prop.rs @@ -475,8 +475,10 @@ impl SpendConflictTestInput { }; ( - VerifiedUnminedTx::new(first.0.into(), Amount::zero(), 0), - VerifiedUnminedTx::new(second.0.into(), Amount::zero(), 0), + VerifiedUnminedTx::new(first.0.into(), Amount::zero(), 0) + .expect("verification should pass"), + VerifiedUnminedTx::new(second.0.into(), Amount::zero(), 0) + .expect("verification should pass"), ) } @@ -493,8 +495,10 @@ impl SpendConflictTestInput { Self::remove_orchard_conflicts(&mut first, &mut second); ( - VerifiedUnminedTx::new(first.0.into(), Amount::zero(), 0), - VerifiedUnminedTx::new(second.0.into(), Amount::zero(), 0), + VerifiedUnminedTx::new(first.0.into(), Amount::zero(), 0) + .expect("verification should pass"), + VerifiedUnminedTx::new(second.0.into(), Amount::zero(), 0) + .expect("verification should pass"), ) } diff --git a/zebrad/src/components/mempool/storage/tests/vectors.rs b/zebrad/src/components/mempool/storage/tests/vectors.rs index 5977662f19b..51c3b71366c 100644 --- a/zebrad/src/components/mempool/storage/tests/vectors.rs +++ b/zebrad/src/components/mempool/storage/tests/vectors.rs @@ -271,7 +271,9 @@ fn mempool_expired_basic_for_network(network: Network) -> Result<()> { let tx_id = tx.unmined_id(); // Insert the transaction into the mempool, with a fake zero miner fee and sigops - storage.insert(VerifiedUnminedTx::new(tx.into(), Amount::zero(), 0))?; + storage.insert( + VerifiedUnminedTx::new(tx.into(), Amount::zero(), 0).expect("verification should pass"), + )?; assert_eq!(storage.transaction_count(), 1); diff --git a/zebrad/src/components/mempool/tests/vector.rs b/zebrad/src/components/mempool/tests/vector.rs index 3dad0f1a466..e05e082c963 100644 --- a/zebrad/src/components/mempool/tests/vector.rs +++ b/zebrad/src/components/mempool/tests/vector.rs @@ -805,11 +805,10 @@ async fn mempool_reverifies_after_tip_change() -> Result<(), Report> { .expect("unexpected non-mempool request"); // Set a dummy fee and sigops. - responder.respond(transaction::Response::from(VerifiedUnminedTx::new( - transaction, - Amount::zero(), - 0, - ))); + responder.respond(transaction::Response::from( + VerifiedUnminedTx::new(transaction, Amount::zero(), 0) + .expect("verification should pass"), + )); }) .await; @@ -862,11 +861,10 @@ async fn mempool_reverifies_after_tip_change() -> Result<(), Report> { .expect("unexpected non-mempool request"); // Set a dummy fee and sigops. - responder.respond(transaction::Response::from(VerifiedUnminedTx::new( - transaction, - Amount::zero(), - 0, - ))); + responder.respond(transaction::Response::from( + VerifiedUnminedTx::new(transaction, Amount::zero(), 0) + .expect("verification should pass"), + )); }) .await; From 021c98637d34a9f354b7ecde462b7f56b465b61d Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 25 Apr 2023 15:32:14 -0300 Subject: [PATCH 02/18] fix some docs --- zebra-chain/src/transaction/unmined.rs | 1 - zebra-consensus/src/transaction/tests.rs | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/zebra-chain/src/transaction/unmined.rs b/zebra-chain/src/transaction/unmined.rs index 0a1ea123307..9cb0f0287ed 100644 --- a/zebra-chain/src/transaction/unmined.rs +++ b/zebra-chain/src/transaction/unmined.rs @@ -360,7 +360,6 @@ impl VerifiedUnminedTx { let fee_weight_ratio = zip317::conventional_fee_weight_ratio(&transaction, miner_fee); let unpaid_actions = zip317::unpaid_actions(&transaction, miner_fee); - // Make the mempool checks. zip317::mempool_checks( unpaid_actions, BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT, diff --git a/zebra-consensus/src/transaction/tests.rs b/zebra-consensus/src/transaction/tests.rs index f4f4bc84014..fc9cb908626 100644 --- a/zebra-consensus/src/transaction/tests.rs +++ b/zebra-consensus/src/transaction/tests.rs @@ -2825,7 +2825,7 @@ async fn mempool_zip317_error() { let height = NetworkUpgrade::Nu5 .activation_height(Network::Mainnet) - .expect("Canopy activation height is specified"); + .expect("Nu5 activation height is specified"); let fund_height = (height - 1).expect("fake source fund block height is too small"); // Will produce a small enough miner fee to fail the check. @@ -2836,7 +2836,7 @@ async fn mempool_zip317_error() { Amount::try_from(10).expect("invalid value"), ); - // Create a non-coinbase V4 tx with the last valid expiry height. + // Create a non-coinbase V5 tx. let tx = Transaction::V5 { inputs: vec![input], outputs: vec![output], @@ -2882,7 +2882,7 @@ async fn mempool_zip317_error() { }) .await; - // Mempool refuse to add this transaction into storage. + // Mempool refuses to add this transaction into storage. assert!(verifier_response.is_err()); assert_eq!( verifier_response.err(), @@ -2897,10 +2897,10 @@ async fn mempool_zip317_ok() { let height = NetworkUpgrade::Nu5 .activation_height(Network::Mainnet) - .expect("Canopy activation height is specified"); + .expect("Nu5 activation height is specified"); let fund_height = (height - 1).expect("fake source fund block height is too small"); - // Will produce a small enough miner fee to fail the check. + // Will produce a big enough miner fee to pass the check. let (input, output, known_utxos) = mock_transparent_transfer( fund_height, true, @@ -2908,7 +2908,7 @@ async fn mempool_zip317_ok() { Amount::try_from(10001).expect("invalid value"), ); - // Create a non-coinbase V4 tx with the last valid expiry height. + // Create a non-coinbase V5 tx. let tx = Transaction::V5 { inputs: vec![input], outputs: vec![output], From 350cac8fa738789545e127a0da98cfa2e91aced2 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 25 Apr 2023 15:45:24 -0300 Subject: [PATCH 03/18] rustfmt --- .../components/inbound/tests/fake_peer_set.rs | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/zebrad/src/components/inbound/tests/fake_peer_set.rs b/zebrad/src/components/inbound/tests/fake_peer_set.rs index da17caa6597..44c0787e60c 100644 --- a/zebrad/src/components/inbound/tests/fake_peer_set.rs +++ b/zebrad/src/components/inbound/tests/fake_peer_set.rs @@ -164,11 +164,10 @@ async fn mempool_push_transaction() -> Result<(), crate::BoxError> { .expect("unexpected non-mempool request"); // Set a dummy fee and sigops. - responder.respond(transaction::Response::from(VerifiedUnminedTx::new( - transaction, - Amount::zero(), - 0, - ).expect("verification should pass"))); + responder.respond(transaction::Response::from( + VerifiedUnminedTx::new(transaction, Amount::zero(), 0) + .expect("verification should pass"), + )); }); let (push_response, _) = futures::join!(request, verification); @@ -266,11 +265,10 @@ async fn mempool_advertise_transaction_ids() -> Result<(), crate::BoxError> { .expect("unexpected non-mempool request"); // Set a dummy fee and sigops. - responder.respond(transaction::Response::from(VerifiedUnminedTx::new( - transaction, - Amount::zero(), - 0, - ).expect("verification should pass"))); + responder.respond(transaction::Response::from( + VerifiedUnminedTx::new(transaction, Amount::zero(), 0) + .expect("verification should pass"), + )); }); let (advertise_response, _, _) = futures::join!(request, peer_set_responder, verification); @@ -365,11 +363,10 @@ async fn mempool_transaction_expiration() -> Result<(), crate::BoxError> { .expect("unexpected non-mempool request"); // Set a dummy fee and sigops. - responder.respond(transaction::Response::from(VerifiedUnminedTx::new( - transaction, - Amount::zero(), - 0, - ).expect("verification should pass"))); + responder.respond(transaction::Response::from( + VerifiedUnminedTx::new(transaction, Amount::zero(), 0) + .expect("verification should pass"), + )); }); let (push_response, _) = futures::join!(request, verification); @@ -499,11 +496,10 @@ async fn mempool_transaction_expiration() -> Result<(), crate::BoxError> { .expect("unexpected non-mempool request"); // Set a dummy fee and sigops. - responder.respond(transaction::Response::from(VerifiedUnminedTx::new( - transaction, - Amount::zero(), - 0, - ).expect("verification should pass"))); + responder.respond(transaction::Response::from( + VerifiedUnminedTx::new(transaction, Amount::zero(), 0) + .expect("verification should pass"), + )); }); let (push_response, _) = futures::join!(request, verification); From 8267e1358f5d948a8dbf655c0e0a4f364c778609 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 25 Apr 2023 16:02:54 -0300 Subject: [PATCH 04/18] fix import --- zebra-chain/src/transaction.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zebra-chain/src/transaction.rs b/zebra-chain/src/transaction.rs index 0b2c25583d2..e1be66a8dc3 100644 --- a/zebra-chain/src/transaction.rs +++ b/zebra-chain/src/transaction.rs @@ -35,7 +35,8 @@ pub use serialize::{ }; pub use sighash::{HashType, SigHash}; pub use unmined::{ - zip317, UnminedTx, UnminedTxId, VerifiedUnminedTx, MEMPOOL_TRANSACTION_COST_THRESHOLD, + zip317, UnminedTx, UnminedTxId, VerifiedUnminedTx, BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT, + MEMPOOL_TRANSACTION_COST_THRESHOLD, }; use crate::{ From 789b3f3f5087b35fa6d21b6e4142e460a9ba6445 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 25 Apr 2023 16:30:07 -0300 Subject: [PATCH 05/18] typo --- zebra-chain/src/transaction/unmined/zip317.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra-chain/src/transaction/unmined/zip317.rs b/zebra-chain/src/transaction/unmined/zip317.rs index a6595e69b1c..536b5c04087 100644 --- a/zebra-chain/src/transaction/unmined/zip317.rs +++ b/zebra-chain/src/transaction/unmined/zip317.rs @@ -166,7 +166,7 @@ pub fn mempool_checks( miner_fee: Amount, conventional_fee: Amount, ) -> Result<(), Error> { - // Check unpaid actions is below the thershold. + // Check unpaid actions is below the threshold. if unpaid_actions > unpaid_action_limit { return Err(Error::UnpaidActions); } From ea7183b96d632ea8c3a7027a5e8ac5607a086069 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 25 Apr 2023 17:33:40 -0300 Subject: [PATCH 06/18] fix tests --- .../src/components/mempool/storage/tests/prop.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/zebrad/src/components/mempool/storage/tests/prop.rs b/zebrad/src/components/mempool/storage/tests/prop.rs index d2b1b02f332..1c662ad2292 100644 --- a/zebrad/src/components/mempool/storage/tests/prop.rs +++ b/zebrad/src/components/mempool/storage/tests/prop.rs @@ -475,10 +475,18 @@ impl SpendConflictTestInput { }; ( - VerifiedUnminedTx::new(first.0.into(), Amount::zero(), 0) - .expect("verification should pass"), - VerifiedUnminedTx::new(second.0.into(), Amount::zero(), 0) - .expect("verification should pass"), + VerifiedUnminedTx::new( + first.0.into(), + Amount::try_from(10001).expect("invalid value"), + 0, + ) + .expect("verification should pass"), + VerifiedUnminedTx::new( + second.0.into(), + Amount::try_from(10001).expect("invalid value"), + 0, + ) + .expect("verification should pass"), ) } From 073a5d109a067b59827676da3b5060de5814ca98 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 25 Apr 2023 19:36:44 -0300 Subject: [PATCH 07/18] fix tests 2 --- zebrad/src/components/mempool/storage/tests/prop.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/zebrad/src/components/mempool/storage/tests/prop.rs b/zebrad/src/components/mempool/storage/tests/prop.rs index 1c662ad2292..c48df7d0528 100644 --- a/zebrad/src/components/mempool/storage/tests/prop.rs +++ b/zebrad/src/components/mempool/storage/tests/prop.rs @@ -477,13 +477,15 @@ impl SpendConflictTestInput { ( VerifiedUnminedTx::new( first.0.into(), - Amount::try_from(10001).expect("invalid value"), + // make sure miner fee is big enough for all cases + Amount::try_from(1000000).expect("invalid value"), 0, ) .expect("verification should pass"), VerifiedUnminedTx::new( second.0.into(), - Amount::try_from(10001).expect("invalid value"), + // make sure miner fee is big enough for all cases + Amount::try_from(1000000).expect("invalid value"), 0, ) .expect("verification should pass"), From 584858702b166b78e2b2aac52dc4248fc49fe6b1 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 26 Apr 2023 09:18:12 -0300 Subject: [PATCH 08/18] fix tests 3 --- zebrad/src/components/inbound/tests/fake_peer_set.rs | 8 ++++++-- zebrad/src/components/mempool/storage/tests.rs | 8 ++++++-- zebrad/src/components/mempool/storage/tests/prop.rs | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/zebrad/src/components/inbound/tests/fake_peer_set.rs b/zebrad/src/components/inbound/tests/fake_peer_set.rs index 44c0787e60c..ee1d3db3c22 100644 --- a/zebrad/src/components/inbound/tests/fake_peer_set.rs +++ b/zebrad/src/components/inbound/tests/fake_peer_set.rs @@ -165,8 +165,12 @@ async fn mempool_push_transaction() -> Result<(), crate::BoxError> { // Set a dummy fee and sigops. responder.respond(transaction::Response::from( - VerifiedUnminedTx::new(transaction, Amount::zero(), 0) - .expect("verification should pass"), + VerifiedUnminedTx::new( + transaction, + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass"), )); }); diff --git a/zebrad/src/components/mempool/storage/tests.rs b/zebrad/src/components/mempool/storage/tests.rs index 3d77d72cbcb..cad844108c4 100644 --- a/zebrad/src/components/mempool/storage/tests.rs +++ b/zebrad/src/components/mempool/storage/tests.rs @@ -38,7 +38,11 @@ pub fn unmined_transactions_in_blocks( .flat_map(|block| block.transactions) .map(UnminedTx::from) .map(|transaction| { - VerifiedUnminedTx::new(transaction, Amount::zero(), 0) - .expect("verification should pass") + VerifiedUnminedTx::new( + transaction, + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass") }) } diff --git a/zebrad/src/components/mempool/storage/tests/prop.rs b/zebrad/src/components/mempool/storage/tests/prop.rs index c48df7d0528..055bea34a3b 100644 --- a/zebrad/src/components/mempool/storage/tests/prop.rs +++ b/zebrad/src/components/mempool/storage/tests/prop.rs @@ -478,14 +478,14 @@ impl SpendConflictTestInput { VerifiedUnminedTx::new( first.0.into(), // make sure miner fee is big enough for all cases - Amount::try_from(1000000).expect("invalid value"), + Amount::try_from(1_000_000).expect("invalid value"), 0, ) .expect("verification should pass"), VerifiedUnminedTx::new( second.0.into(), // make sure miner fee is big enough for all cases - Amount::try_from(1000000).expect("invalid value"), + Amount::try_from(1_000_000).expect("invalid value"), 0, ) .expect("verification should pass"), From 70af48ef38dd01fe0341ecf34c2f12838fdfe294 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 26 Apr 2023 10:09:47 -0300 Subject: [PATCH 09/18] fix tests 4 --- .../components/mempool/storage/tests/prop.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/zebrad/src/components/mempool/storage/tests/prop.rs b/zebrad/src/components/mempool/storage/tests/prop.rs index 055bea34a3b..eca65935acb 100644 --- a/zebrad/src/components/mempool/storage/tests/prop.rs +++ b/zebrad/src/components/mempool/storage/tests/prop.rs @@ -505,10 +505,20 @@ impl SpendConflictTestInput { Self::remove_orchard_conflicts(&mut first, &mut second); ( - VerifiedUnminedTx::new(first.0.into(), Amount::zero(), 0) - .expect("verification should pass"), - VerifiedUnminedTx::new(second.0.into(), Amount::zero(), 0) - .expect("verification should pass"), + VerifiedUnminedTx::new( + first.0.into(), + // make sure miner fee is big enough for all cases + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass"), + VerifiedUnminedTx::new( + second.0.into(), + // make sure miner fee is big enough for all cases + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass"), ) } From 8e6e66e60b3968c23db1ffc56d8ffd32578022a7 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 26 Apr 2023 12:57:17 -0300 Subject: [PATCH 10/18] fix tests 5 --- .../components/inbound/tests/fake_peer_set.rs | 24 ++++++++++++++----- .../mempool/storage/tests/vectors.rs | 7 +++++- zebrad/src/components/mempool/tests/vector.rs | 16 +++++++++---- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/zebrad/src/components/inbound/tests/fake_peer_set.rs b/zebrad/src/components/inbound/tests/fake_peer_set.rs index ee1d3db3c22..1a226390c82 100644 --- a/zebrad/src/components/inbound/tests/fake_peer_set.rs +++ b/zebrad/src/components/inbound/tests/fake_peer_set.rs @@ -270,8 +270,12 @@ async fn mempool_advertise_transaction_ids() -> Result<(), crate::BoxError> { // Set a dummy fee and sigops. responder.respond(transaction::Response::from( - VerifiedUnminedTx::new(transaction, Amount::zero(), 0) - .expect("verification should pass"), + VerifiedUnminedTx::new( + transaction, + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass"), )); }); @@ -368,8 +372,12 @@ async fn mempool_transaction_expiration() -> Result<(), crate::BoxError> { // Set a dummy fee and sigops. responder.respond(transaction::Response::from( - VerifiedUnminedTx::new(transaction, Amount::zero(), 0) - .expect("verification should pass"), + VerifiedUnminedTx::new( + transaction, + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass"), )); }); @@ -501,8 +509,12 @@ async fn mempool_transaction_expiration() -> Result<(), crate::BoxError> { // Set a dummy fee and sigops. responder.respond(transaction::Response::from( - VerifiedUnminedTx::new(transaction, Amount::zero(), 0) - .expect("verification should pass"), + VerifiedUnminedTx::new( + transaction, + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass"), )); }); diff --git a/zebrad/src/components/mempool/storage/tests/vectors.rs b/zebrad/src/components/mempool/storage/tests/vectors.rs index 51c3b71366c..35827574946 100644 --- a/zebrad/src/components/mempool/storage/tests/vectors.rs +++ b/zebrad/src/components/mempool/storage/tests/vectors.rs @@ -272,7 +272,12 @@ fn mempool_expired_basic_for_network(network: Network) -> Result<()> { // Insert the transaction into the mempool, with a fake zero miner fee and sigops storage.insert( - VerifiedUnminedTx::new(tx.into(), Amount::zero(), 0).expect("verification should pass"), + VerifiedUnminedTx::new( + tx.into(), + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass"), )?; assert_eq!(storage.transaction_count(), 1); diff --git a/zebrad/src/components/mempool/tests/vector.rs b/zebrad/src/components/mempool/tests/vector.rs index e05e082c963..4dbed9426bb 100644 --- a/zebrad/src/components/mempool/tests/vector.rs +++ b/zebrad/src/components/mempool/tests/vector.rs @@ -806,8 +806,12 @@ async fn mempool_reverifies_after_tip_change() -> Result<(), Report> { // Set a dummy fee and sigops. responder.respond(transaction::Response::from( - VerifiedUnminedTx::new(transaction, Amount::zero(), 0) - .expect("verification should pass"), + VerifiedUnminedTx::new( + transaction, + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass"), )); }) .await; @@ -862,8 +866,12 @@ async fn mempool_reverifies_after_tip_change() -> Result<(), Report> { // Set a dummy fee and sigops. responder.respond(transaction::Response::from( - VerifiedUnminedTx::new(transaction, Amount::zero(), 0) - .expect("verification should pass"), + VerifiedUnminedTx::new( + transaction, + Amount::try_from(1_000_000).expect("invalid value"), + 0, + ) + .expect("verification should pass"), )); }) .await; From 6056b5c0cee3ec50e8f9cd0115702ba964a7d619 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 27 Apr 2023 16:42:20 -0300 Subject: [PATCH 11/18] move constant --- zebra-chain/src/transaction.rs | 3 +-- zebra-chain/src/transaction/unmined.rs | 10 +--------- zebra-chain/src/transaction/unmined/zip317.rs | 7 +++++-- zebra-chain/src/transaction/unmined/zip317/tests.rs | 2 -- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/zebra-chain/src/transaction.rs b/zebra-chain/src/transaction.rs index e1be66a8dc3..0b2c25583d2 100644 --- a/zebra-chain/src/transaction.rs +++ b/zebra-chain/src/transaction.rs @@ -35,8 +35,7 @@ pub use serialize::{ }; pub use sighash::{HashType, SigHash}; pub use unmined::{ - zip317, UnminedTx, UnminedTxId, VerifiedUnminedTx, BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT, - MEMPOOL_TRANSACTION_COST_THRESHOLD, + zip317, UnminedTx, UnminedTxId, VerifiedUnminedTx, MEMPOOL_TRANSACTION_COST_THRESHOLD, }; use crate::{ diff --git a/zebra-chain/src/transaction/unmined.rs b/zebra-chain/src/transaction/unmined.rs index 9cb0f0287ed..f09e3566680 100644 --- a/zebra-chain/src/transaction/unmined.rs +++ b/zebra-chain/src/transaction/unmined.rs @@ -345,9 +345,6 @@ impl fmt::Display for VerifiedUnminedTx { .finish() } } -/// The ZIP-317 recommended limit on the number of unpaid actions per block. -/// `block_unpaid_action_limit` in ZIP-317. -pub const BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT: u32 = 50; impl VerifiedUnminedTx { /// Create a new verified unmined transaction from an unmined transaction, @@ -360,12 +357,7 @@ impl VerifiedUnminedTx { let fee_weight_ratio = zip317::conventional_fee_weight_ratio(&transaction, miner_fee); let unpaid_actions = zip317::unpaid_actions(&transaction, miner_fee); - zip317::mempool_checks( - unpaid_actions, - BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT, - miner_fee, - transaction.conventional_fee, - )?; + zip317::mempool_checks(unpaid_actions, miner_fee, transaction.conventional_fee)?; Ok(Self { transaction, diff --git a/zebra-chain/src/transaction/unmined/zip317.rs b/zebra-chain/src/transaction/unmined/zip317.rs index 536b5c04087..ee0ef14f9da 100644 --- a/zebra-chain/src/transaction/unmined/zip317.rs +++ b/zebra-chain/src/transaction/unmined/zip317.rs @@ -40,6 +40,10 @@ const BLOCK_PRODUCTION_WEIGHT_RATIO_CAP: f32 = 4.0; /// This avoids special handling for transactions with zero weight. const MIN_BLOCK_PRODUCTION_SUBSTITUTE_FEE: i64 = 1; +/// The ZIP-317 recommended limit on the number of unpaid actions per block. +/// `block_unpaid_action_limit` in ZIP-317. +pub const BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT: u32 = 50; + /// Returns the conventional fee for `transaction`, as defined by [ZIP-317]. /// /// [ZIP-317]: https://zips.z.cash/zip-0317#fee-calculation @@ -162,12 +166,11 @@ fn div_ceil(quotient: usize, divisor: usize) -> usize { /// Make ZIP-317 checks before inserting a transaction into the mempool. pub fn mempool_checks( unpaid_actions: u32, - unpaid_action_limit: u32, miner_fee: Amount, conventional_fee: Amount, ) -> Result<(), Error> { // Check unpaid actions is below the threshold. - if unpaid_actions > unpaid_action_limit { + if unpaid_actions > BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT { return Err(Error::UnpaidActions); } diff --git a/zebra-chain/src/transaction/unmined/zip317/tests.rs b/zebra-chain/src/transaction/unmined/zip317/tests.rs index 3ceb33b19f2..a7494011f30 100644 --- a/zebra-chain/src/transaction/unmined/zip317/tests.rs +++ b/zebra-chain/src/transaction/unmined/zip317/tests.rs @@ -5,7 +5,6 @@ use super::{mempool_checks, Amount, Error}; fn zip317_unpaid_actions_err() { let check = mempool_checks( 51, - 50, Amount::try_from(1).unwrap(), Amount::try_from(10000).unwrap(), ); @@ -17,7 +16,6 @@ fn zip317_unpaid_actions_err() { #[test] fn zip317_miner_fee_err() { let check = mempool_checks( - 50, 50, Amount::try_from(1).unwrap(), Amount::try_from(10000).unwrap(), From ddabc3ab066e2c786877fa478fb9a307e447282b Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 27 Apr 2023 17:16:44 -0300 Subject: [PATCH 12/18] fix constant for feature --- zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs b/zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs index 07e63c7eb7c..3737f339ef0 100644 --- a/zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs +++ b/zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs @@ -15,7 +15,7 @@ use zebra_chain::{ amount::NegativeOrZero, block::{Height, MAX_BLOCK_BYTES}, parameters::Network, - transaction::{VerifiedUnminedTx, BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT}, + transaction::{zip317::BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT, VerifiedUnminedTx}, transparent, }; use zebra_consensus::MAX_BLOCK_SIGOPS; From 2140ce270cd0c29c7d707b1bb36ba4c197e6a240 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 27 Apr 2023 17:27:00 -0300 Subject: [PATCH 13/18] document/quote zip rules --- zebra-chain/src/transaction/unmined/zip317.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/zebra-chain/src/transaction/unmined/zip317.rs b/zebra-chain/src/transaction/unmined/zip317.rs index 8d7c4281a48..ee744129343 100644 --- a/zebra-chain/src/transaction/unmined/zip317.rs +++ b/zebra-chain/src/transaction/unmined/zip317.rs @@ -154,12 +154,23 @@ pub fn mempool_checks( miner_fee: Amount, conventional_fee: Amount, ) -> Result<(), Error> { - // Check unpaid actions is below the threshold. + // # Standard Rule + // + // > If a transaction has more than `block_unpaid_action_limit` "unpaid actions" as defined by the + // > Recommended algorithm for block template construction, it will never be mined by that algorithm. + // > Nodes MAY drop these transactions. + // + // if unpaid_actions > BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT { return Err(Error::UnpaidActions); } - // Check the fee is not below the calculated conventional fee for the transaction. + // # Standard Rule + // + // > Nodes that normally relay transactions are expected to do so for transactions that pay at least the + // > conventional fee as specified in this ZIP. + // + // if miner_fee < conventional_fee { return Err(Error::MinerFee); } From a74f12d0efd6c0c323104233254413636ff68b06 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Thu, 27 Apr 2023 18:29:39 -0300 Subject: [PATCH 14/18] add Minimum Fee Rate rule --- zebra-chain/src/transaction/unmined.rs | 7 ++++- zebra-chain/src/transaction/unmined/zip317.rs | 26 ++++++++++++++++--- .../src/transaction/unmined/zip317/tests.rs | 19 ++++++++++++-- zebra-consensus/src/transaction/tests.rs | 4 ++- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/zebra-chain/src/transaction/unmined.rs b/zebra-chain/src/transaction/unmined.rs index f09e3566680..cfdb6962423 100644 --- a/zebra-chain/src/transaction/unmined.rs +++ b/zebra-chain/src/transaction/unmined.rs @@ -357,7 +357,12 @@ impl VerifiedUnminedTx { let fee_weight_ratio = zip317::conventional_fee_weight_ratio(&transaction, miner_fee); let unpaid_actions = zip317::unpaid_actions(&transaction, miner_fee); - zip317::mempool_checks(unpaid_actions, miner_fee, transaction.conventional_fee)?; + zip317::mempool_checks( + unpaid_actions, + miner_fee, + transaction.conventional_fee, + transaction.size, + )?; Ok(Self { transaction, diff --git a/zebra-chain/src/transaction/unmined/zip317.rs b/zebra-chain/src/transaction/unmined/zip317.rs index ee744129343..d2b748a39d8 100644 --- a/zebra-chain/src/transaction/unmined/zip317.rs +++ b/zebra-chain/src/transaction/unmined/zip317.rs @@ -153,6 +153,7 @@ pub fn mempool_checks( unpaid_actions: u32, miner_fee: Amount, conventional_fee: Amount, + transaction_size: usize, ) -> Result<(), Error> { // # Standard Rule // @@ -172,7 +173,23 @@ pub fn mempool_checks( // // if miner_fee < conventional_fee { - return Err(Error::MinerFee); + return Err(Error::FeeBelowConventional); + } + + // # Standard rule + // + // > Minimum Fee Rate + // > + // > Transactions must pay a fee of at least 100 zatoshis per 1000 bytes of serialized size, + // > with a maximum fee of 1000 zatoshis. In zcashd this is `DEFAULT_MIN_RELAY_TX_FEE`. + // + // + let limit = std::cmp::min( + 1000, + (f32::floor(100.0 * transaction_size as f32 / 1000.0)) as u64, + ); + if miner_fee < Amount::::try_from(limit).expect("limit value is invalid") { + return Err(Error::FeeBelowMinimumRate); } Ok(()) @@ -185,6 +202,9 @@ pub enum Error { #[error("Unpaid actions is higher than the limit")] UnpaidActions, - #[error("Transaction fee is too low")] - MinerFee, + #[error("Transaction fee is below the conventional fee for the transaction")] + FeeBelowConventional, + + #[error("Transaction fee is below the minimum fee rate")] + FeeBelowMinimumRate, } diff --git a/zebra-chain/src/transaction/unmined/zip317/tests.rs b/zebra-chain/src/transaction/unmined/zip317/tests.rs index a7494011f30..a3ed8b62067 100644 --- a/zebra-chain/src/transaction/unmined/zip317/tests.rs +++ b/zebra-chain/src/transaction/unmined/zip317/tests.rs @@ -7,6 +7,7 @@ fn zip317_unpaid_actions_err() { 51, Amount::try_from(1).unwrap(), Amount::try_from(10000).unwrap(), + 1, ); assert!(check.is_err()); @@ -14,13 +15,27 @@ fn zip317_unpaid_actions_err() { } #[test] -fn zip317_miner_fee_err() { +fn zip317_convetional_fee_err() { let check = mempool_checks( 50, Amount::try_from(1).unwrap(), Amount::try_from(10000).unwrap(), + 1, ); assert!(check.is_err()); - assert_eq!(check.err(), Some(Error::MinerFee)); + assert_eq!(check.err(), Some(Error::FeeBelowConventional)); +} + +#[test] +fn zip317_minimum_rate_fee_err() { + let check = mempool_checks( + 50, + Amount::try_from(1).unwrap(), + Amount::try_from(1).unwrap(), + 1000, + ); + + assert!(check.is_err()); + assert_eq!(check.err(), Some(Error::FeeBelowMinimumRate)); } diff --git a/zebra-consensus/src/transaction/tests.rs b/zebra-consensus/src/transaction/tests.rs index fc9cb908626..74db70504c6 100644 --- a/zebra-consensus/src/transaction/tests.rs +++ b/zebra-consensus/src/transaction/tests.rs @@ -2886,7 +2886,9 @@ async fn mempool_zip317_error() { assert!(verifier_response.is_err()); assert_eq!( verifier_response.err(), - Some(TransactionError::Zip317(zip317::Error::MinerFee)) + Some(TransactionError::Zip317( + zip317::Error::FeeBelowConventional + )) ); } From 98f57ed551e4a77318af99e14d844077f569c8dd Mon Sep 17 00:00:00 2001 From: teor Date: Sat, 29 Apr 2023 00:07:04 +1000 Subject: [PATCH 15/18] change(mempool): Refactor the ZIP-317 minimum fee rate calculation to use usize (#6585) * Refactor the minimum fee rate calculation to use usize * Check for overflow if constants change --- zebra-chain/src/transaction/unmined/zip317.rs | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/zebra-chain/src/transaction/unmined/zip317.rs b/zebra-chain/src/transaction/unmined/zip317.rs index d2b748a39d8..9923991764b 100644 --- a/zebra-chain/src/transaction/unmined/zip317.rs +++ b/zebra-chain/src/transaction/unmined/zip317.rs @@ -45,6 +45,23 @@ const MIN_BLOCK_PRODUCTION_SUBSTITUTE_FEE: i64 = 1; /// `block_unpaid_action_limit` in ZIP-317. pub const BLOCK_PRODUCTION_UNPAID_ACTION_LIMIT: u32 = 50; +/// The minimum fee per kilobyte for Zebra mempool transactions. +/// Also used as the minimum fee for a mempool transaction. +/// +/// Based on `DEFAULT_MIN_RELAY_TX_FEE` in `zcashd`: +/// +/// +/// This is a `usize` to simplify transaction size-based calculation code. +pub const MIN_MEMPOOL_TX_FEE_RATE: usize = 100; + +/// The fee cap for [`MIN_MEMPOOL_TX_FEE_RATE`] minimum required mempool fees. +/// +/// Based on `LEGACY_DEFAULT_FEE` in `zcashd`: +/// +/// +/// This is a `usize` to simplify transaction size-based calculation code. +pub const MEMPOOL_TX_FEE_REQUIREMENT_CAP: usize = 1000; + /// Returns the conventional fee for `transaction`, as defined by [ZIP-317]. /// /// [ZIP-317]: https://zips.z.cash/zip-0317#fee-calculation @@ -184,11 +201,24 @@ pub fn mempool_checks( // > with a maximum fee of 1000 zatoshis. In zcashd this is `DEFAULT_MIN_RELAY_TX_FEE`. // // - let limit = std::cmp::min( - 1000, - (f32::floor(100.0 * transaction_size as f32 / 1000.0)) as u64, + const KILOBYTE: usize = 1000; + + // This calculation can't overflow, because transactions are limited to 2 MB, + // and usize is at least 4 GB. + assert!( + MIN_MEMPOOL_TX_FEE_RATE + < usize::MAX / usize::try_from(MAX_BLOCK_BYTES).expect("constant fits in usize"), + "the fee rate multiplication must never overflow", ); - if miner_fee < Amount::::try_from(limit).expect("limit value is invalid") { + + let min_fee = (MIN_MEMPOOL_TX_FEE_RATE * transaction_size / KILOBYTE) + .clamp(MIN_MEMPOOL_TX_FEE_RATE, MEMPOOL_TX_FEE_REQUIREMENT_CAP); + let min_fee: u64 = min_fee + .try_into() + .expect("clamped value always fits in u64"); + let min_fee: Amount = min_fee.try_into().expect("clamped value is positive"); + + if miner_fee < min_fee { return Err(Error::FeeBelowMinimumRate); } From 00b03ad92176766ae5dcbb7795cbc2197ff7b262 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Fri, 28 Apr 2023 11:25:24 -0300 Subject: [PATCH 16/18] remove 1 rule check, fix docs --- zebra-chain/src/transaction/unmined.rs | 7 +---- zebra-chain/src/transaction/unmined/zip317.rs | 23 +++++++--------- .../src/transaction/unmined/zip317/tests.rs | 27 ++----------------- zebra-consensus/src/transaction/tests.rs | 4 +-- 4 files changed, 13 insertions(+), 48 deletions(-) diff --git a/zebra-chain/src/transaction/unmined.rs b/zebra-chain/src/transaction/unmined.rs index cfdb6962423..9c081018c97 100644 --- a/zebra-chain/src/transaction/unmined.rs +++ b/zebra-chain/src/transaction/unmined.rs @@ -357,12 +357,7 @@ impl VerifiedUnminedTx { let fee_weight_ratio = zip317::conventional_fee_weight_ratio(&transaction, miner_fee); let unpaid_actions = zip317::unpaid_actions(&transaction, miner_fee); - zip317::mempool_checks( - unpaid_actions, - miner_fee, - transaction.conventional_fee, - transaction.size, - )?; + zip317::mempool_checks(unpaid_actions, miner_fee, transaction.size)?; Ok(Self { transaction, diff --git a/zebra-chain/src/transaction/unmined/zip317.rs b/zebra-chain/src/transaction/unmined/zip317.rs index 9923991764b..44ef709aacd 100644 --- a/zebra-chain/src/transaction/unmined/zip317.rs +++ b/zebra-chain/src/transaction/unmined/zip317.rs @@ -169,7 +169,6 @@ fn conventional_actions(transaction: &Transaction) -> u32 { pub fn mempool_checks( unpaid_actions: u32, miner_fee: Amount, - conventional_fee: Amount, transaction_size: usize, ) -> Result<(), Error> { // # Standard Rule @@ -189,18 +188,17 @@ pub fn mempool_checks( // > conventional fee as specified in this ZIP. // // - if miner_fee < conventional_fee { - return Err(Error::FeeBelowConventional); - } - - // # Standard rule // - // > Minimum Fee Rate - // > - // > Transactions must pay a fee of at least 100 zatoshis per 1000 bytes of serialized size, - // > with a maximum fee of 1000 zatoshis. In zcashd this is `DEFAULT_MIN_RELAY_TX_FEE`. + // In Zebra, we use a similar minimum fee rate to `zcashd` v5.5.0 and later. + // Transactions must pay a fee of at least 100 zatoshis per 1000 bytes of serialized size, + // with a maximum fee of 1000 zatoshis. + // + // // - // + // In zcashd this is `DEFAULT_MIN_RELAY_TX_FEE` and `LEGACY_DEFAULT_FEE`: + // + // + const KILOBYTE: usize = 1000; // This calculation can't overflow, because transactions are limited to 2 MB, @@ -232,9 +230,6 @@ pub enum Error { #[error("Unpaid actions is higher than the limit")] UnpaidActions, - #[error("Transaction fee is below the conventional fee for the transaction")] - FeeBelowConventional, - #[error("Transaction fee is below the minimum fee rate")] FeeBelowMinimumRate, } diff --git a/zebra-chain/src/transaction/unmined/zip317/tests.rs b/zebra-chain/src/transaction/unmined/zip317/tests.rs index a3ed8b62067..fb708a73c0b 100644 --- a/zebra-chain/src/transaction/unmined/zip317/tests.rs +++ b/zebra-chain/src/transaction/unmined/zip317/tests.rs @@ -3,38 +3,15 @@ use super::{mempool_checks, Amount, Error}; #[test] fn zip317_unpaid_actions_err() { - let check = mempool_checks( - 51, - Amount::try_from(1).unwrap(), - Amount::try_from(10000).unwrap(), - 1, - ); + let check = mempool_checks(51, Amount::try_from(1).unwrap(), 1); assert!(check.is_err()); assert_eq!(check.err(), Some(Error::UnpaidActions)); } -#[test] -fn zip317_convetional_fee_err() { - let check = mempool_checks( - 50, - Amount::try_from(1).unwrap(), - Amount::try_from(10000).unwrap(), - 1, - ); - - assert!(check.is_err()); - assert_eq!(check.err(), Some(Error::FeeBelowConventional)); -} - #[test] fn zip317_minimum_rate_fee_err() { - let check = mempool_checks( - 50, - Amount::try_from(1).unwrap(), - Amount::try_from(1).unwrap(), - 1000, - ); + let check = mempool_checks(50, Amount::try_from(1).unwrap(), 1000); assert!(check.is_err()); assert_eq!(check.err(), Some(Error::FeeBelowMinimumRate)); diff --git a/zebra-consensus/src/transaction/tests.rs b/zebra-consensus/src/transaction/tests.rs index 74db70504c6..9f9fd6fbfd5 100644 --- a/zebra-consensus/src/transaction/tests.rs +++ b/zebra-consensus/src/transaction/tests.rs @@ -2886,9 +2886,7 @@ async fn mempool_zip317_error() { assert!(verifier_response.is_err()); assert_eq!( verifier_response.err(), - Some(TransactionError::Zip317( - zip317::Error::FeeBelowConventional - )) + Some(TransactionError::Zip317(zip317::Error::FeeBelowMinimumRate)) ); } From 5de06e696b58134d5f0d5580e189fa9e14f7d93b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 15:57:20 +0000 Subject: [PATCH 17/18] build(deps): bump serde_with from 2.3.2 to 2.3.3 Bumps [serde_with](https://github.com/jonasbb/serde_with) from 2.3.2 to 2.3.3. - [Release notes](https://github.com/jonasbb/serde_with/releases) - [Commits](https://github.com/jonasbb/serde_with/compare/v2.3.2...v2.3.3) --- updated-dependencies: - dependency-name: serde_with dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 148 ++++++++++++++++++++--------------------- zebra-chain/Cargo.toml | 2 +- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4c7729d56f..2819a8e86cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,7 +38,7 @@ checksum = "74f5722bc48763cb9d81d8427ca05b6aa2842f6632cf8e4c0a29eef9baececcc" dependencies = [ "darling 0.10.2", "ident_case", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", "synstructure", @@ -214,7 +214,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -225,9 +225,9 @@ version = "0.1.67" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86ea188f25f0255d8f92797797c97ebf5631fa88178beb1a46fdf5622c9a00e4" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", - "syn 2.0.8", + "syn 2.0.15", ] [[package]] @@ -380,7 +380,7 @@ dependencies = [ "lazycell", "log", "peeking_take_while", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "regex", "rustc-hash", @@ -1071,10 +1071,10 @@ dependencies = [ "cc", "codespan-reporting", "once_cell", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "scratch", - "syn 2.0.8", + "syn 2.0.15", ] [[package]] @@ -1084,9 +1084,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5a1d8bcc452ce138e068129073b0b6b9669dda4eec735bc599c88d83249e373" dependencies = [ "codespan-reporting", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", - "syn 2.0.8", + "syn 2.0.15", ] [[package]] @@ -1101,7 +1101,7 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -1128,12 +1128,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "e7c99d16b88c92aef47e58dadd53e87b4bd234c29934947a6cec8b466300f99b" dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", + "darling_core 0.20.0", + "darling_macro 0.20.0", ] [[package]] @@ -1144,7 +1144,7 @@ checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "strsim 0.9.3", "syn 1.0.109", @@ -1158,7 +1158,7 @@ checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "strsim 0.10.0", "syn 1.0.109", @@ -1166,16 +1166,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "2ea05d2fcb27b53f7a98faddaf5f2914760330ab7703adfc9df13332b42189f9" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "strsim 0.10.0", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] @@ -1202,13 +1202,13 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "7bfb82b62b1b8a2a9808fb4caf844ede819a76cfc23b2827d7f94eefb49551eb" dependencies = [ - "darling_core 0.14.4", + "darling_core 0.20.0", "quote 1.0.26", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] @@ -1276,7 +1276,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -1358,7 +1358,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "355f93763ef7b0ae1c43c4d8eccc9d5848d84ad1a1d8ce61c421d1ac85a19d05" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -1624,9 +1624,9 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", - "syn 2.0.8", + "syn 2.0.15", ] [[package]] @@ -1709,7 +1709,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -1791,7 +1791,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90454ce4de40b7ca6a8968b5ef367bdab48413962588d0d2b1638d60090c35d7" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -2193,7 +2193,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -2372,7 +2372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2" dependencies = [ "proc-macro-crate 0.1.5", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -2683,9 +2683,9 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", - "syn 2.0.8", + "syn 2.0.15", ] [[package]] @@ -2930,7 +2930,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -3097,7 +3097,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" dependencies = [ "proc-macro-crate 1.3.1", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -3251,7 +3251,7 @@ checksum = "75a1ef20bf3193c15ac345acb32e26b3dc3223aff4d77ae4fc5359567683796b" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -3292,7 +3292,7 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -3378,7 +3378,7 @@ version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "syn 1.0.109", ] @@ -3419,7 +3419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", "version_check", @@ -3431,7 +3431,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "version_check", ] @@ -3447,9 +3447,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -3526,7 +3526,7 @@ checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -3595,7 +3595,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "608c156fd8e97febc07dc9c2e2c80bf74cfc6ef26893eae3daf8bc2bc94a4b7f" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -3615,7 +3615,7 @@ version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", ] [[package]] @@ -4283,9 +4283,9 @@ version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", - "syn 2.0.8", + "syn 2.0.15", ] [[package]] @@ -4333,9 +4333,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331bb8c3bf9b92457ab7abecf07078c13f7d270ba490103e84e8b014490cd0b0" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" dependencies = [ "base64 0.13.1", "chrono", @@ -4343,7 +4343,7 @@ dependencies = [ "indexmap", "serde", "serde_json", - "serde_with_macros 2.3.2", + "serde_with_macros 2.3.3", "time 0.3.20", ] @@ -4354,21 +4354,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ "darling 0.13.4", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] [[package]] name = "serde_with_macros" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859011bddcc11f289f07f467cc1fe01c7a941daa4d8f6c40d4d1c92eb6d9319c" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling 0.14.4", - "proc-macro2 1.0.53", + "darling 0.20.0", + "proc-macro2 1.0.56", "quote 1.0.26", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] @@ -4492,7 +4492,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bdfb59103e43a0f99a346b57860d50f2138a7008d08acd964e9ac0fef3ae9a5" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -4567,7 +4567,7 @@ checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck 0.3.3", "proc-macro-error", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -4595,18 +4595,18 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.8" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc02725fd69ab9f26eab07fad303e2497fad6fb9eba4f96c4d1687bdf704ad9" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "unicode-ident", ] @@ -4623,7 +4623,7 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", "unicode-xid 0.2.4", @@ -4687,9 +4687,9 @@ version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", - "syn 2.0.8", + "syn 2.0.15", ] [[package]] @@ -4800,9 +4800,9 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", - "syn 2.0.8", + "syn 2.0.15", ] [[package]] @@ -4989,7 +4989,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07" dependencies = [ "prettyplease", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "prost-build", "quote 1.0.26", "syn 1.0.109", @@ -5108,7 +5108,7 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", ] @@ -5492,7 +5492,7 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", "wasm-bindgen-shared", @@ -5526,7 +5526,7 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", "wasm-bindgen-backend", @@ -5963,7 +5963,7 @@ dependencies = [ "serde", "serde-big-array", "serde_json", - "serde_with 2.3.2", + "serde_with 2.3.3", "sha2 0.9.9", "spandoc", "static_assertions", @@ -6296,7 +6296,7 @@ version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" dependencies = [ - "proc-macro2 1.0.53", + "proc-macro2 1.0.56", "quote 1.0.26", "syn 1.0.109", "synstructure", diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index 379f677490b..52eef36a0a1 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -81,7 +81,7 @@ tracing = "0.1.37" # Serialization hex = { version = "0.4.3", features = ["serde"] } serde = { version = "1.0.160", features = ["serde_derive", "rc"] } -serde_with = "2.3.2" +serde_with = "2.3.3" serde-big-array = "0.5.1" # Processing From 41ac287e5589727ea6bb2cbaf8a6aa2fe50089dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 15:56:54 +0000 Subject: [PATCH 18/18] build(deps): bump tj-actions/changed-files from 35.9.0 to 35.9.2 Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 35.9.0 to 35.9.2. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v35.9.0...v35.9.2) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/lint.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ab536b5ce27..3ec3dc6c250 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -37,7 +37,7 @@ jobs: - name: Rust files id: changed-files-rust - uses: tj-actions/changed-files@v35.9.0 + uses: tj-actions/changed-files@v35.9.2 with: files: | **/*.rs @@ -49,7 +49,7 @@ jobs: - name: Workflow files id: changed-files-workflows - uses: tj-actions/changed-files@v35.9.0 + uses: tj-actions/changed-files@v35.9.2 with: files: | .github/workflows/*.yml