From 366e8f95d8e1674f492eb2f1af8e701325cf8c66 Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Mon, 7 Jun 2021 09:05:03 +0800 Subject: [PATCH 1/9] add transation time validity Each transaction comes with a start and end block date, which are inclusive bound of validity: start <= current_date <= end and where start < end. if transaction contains the start=0.0, end=0.0 blockdates, we expects the same behavior as before: no expiration of validity Originally the end was relative number of slots from the start, but this creates lots of difficulty to calculate the end precisely, due to possible era changes, so instead this is now a blockdate that doesn't have to match the number of slots per epoch. --- chain-impl-mockchain/doc/format.abnf | 2 + chain-impl-mockchain/src/ledger/check.rs | 27 +++++ chain-impl-mockchain/src/ledger/ledger.rs | 50 ++++---- .../src/ledger/tests/discrimination_tests.rs | 3 +- .../src/ledger/tests/ledger_tests.rs | 5 +- .../src/ledger/tests/transaction_tests.rs | 107 ++++++++++++++++-- .../src/testing/builders/tx_builder.rs | 16 ++- chain-impl-mockchain/src/testing/ledger.rs | 3 +- .../src/testing/scenario/controller.rs | 3 +- .../src/transaction/builder.rs | 29 +++++ .../src/transaction/transaction.rs | 24 ++++ 11 files changed, 234 insertions(+), 35 deletions(-) diff --git a/chain-impl-mockchain/doc/format.abnf b/chain-impl-mockchain/doc/format.abnf index 54bdc8122..e0e25320f 100644 --- a/chain-impl-mockchain/doc/format.abnf +++ b/chain-impl-mockchain/doc/format.abnf @@ -136,6 +136,8 @@ UPDATE-VOTE = TODO IOW = SIZE-ELEMENT-8BIT ; number of inputs SIZE-ELEMENT-8BIT ; number of outputs + BLOCK-DATE ; start validity of this IOW + BLOCK-DATE ; end validity of this IOW *INPUT ; as many as indicated in the number of inputs *OUTPUT ; sa many as indicated in the number of outputs *WITNESS ; as many as indicated in the number of inputs diff --git a/chain-impl-mockchain/src/ledger/check.rs b/chain-impl-mockchain/src/ledger/check.rs index b446631be..07e95589f 100644 --- a/chain-impl-mockchain/src/ledger/check.rs +++ b/chain-impl-mockchain/src/ledger/check.rs @@ -1,5 +1,6 @@ use super::{Block0Error, Error}; use crate::certificate; +use crate::date::BlockDate; use crate::transaction::*; use crate::value::Value; use chain_addr::Address; @@ -142,6 +143,12 @@ pub(super) fn valid_pool_update_certificate(reg: &certificate::PoolUpdate) -> Le pub enum TxVerifyError { #[error("too many outputs, expected maximum of {expected}, but received {actual}")] TooManyOutputs { expected: u8, actual: u8 }, + #[error("Transaction is not yet within validity range")] + TransactionValidityInFuture, + #[error("Transaction validity expired")] + TransactionValidityExpired, + #[error("Transaction validity range is invalid")] + TransactionValidityRangeInvalid, } #[allow(clippy::absurd_extreme_comparisons)] @@ -164,6 +171,26 @@ pub(super) fn valid_transaction_ios_number

( Ok(()) } +pub(super) fn valid_transaction_date

( + tx: &TransactionSlice

, + date: BlockDate, +) -> Result<(), TxVerifyError> { + // if end and start are BlockDate::first, we expect that the transaction has no validity range + let (start, end) = tx.validity(); + if end == start && end == BlockDate::first() { + return Ok(()); + } + if start >= end { + return Err(TxVerifyError::TransactionValidityRangeInvalid); + } else if date < start { + return Err(TxVerifyError::TransactionValidityInFuture); + } else if date > end { + return Err(TxVerifyError::TransactionValidityExpired); + } else { + return Ok(()); + } +} + #[cfg(test)] mod tests { diff --git a/chain-impl-mockchain/src/ledger/ledger.rs b/chain-impl-mockchain/src/ledger/ledger.rs index 8819c9f51..0cbce694b 100644 --- a/chain-impl-mockchain/src/ledger/ledger.rs +++ b/chain-impl-mockchain/src/ledger/ledger.rs @@ -834,7 +834,7 @@ impl Ledger { Fragment::Transaction(tx) => { let tx = tx.as_slice(); let (new_ledger_, _fee) = - new_ledger.apply_transaction(&fragment_id, &tx, ledger_params)?; + new_ledger.apply_transaction(&fragment_id, &tx, block_date, ledger_params)?; new_ledger = new_ledger_; } Fragment::OwnerStakeDelegation(tx) => { @@ -867,13 +867,13 @@ impl Ledger { } let (new_ledger_, _fee) = - new_ledger.apply_transaction(&fragment_id, &tx, ledger_params)?; + new_ledger.apply_transaction(&fragment_id, &tx, block_date, ledger_params)?; new_ledger = new_ledger_.apply_stake_delegation(&payload)?; } Fragment::PoolRegistration(tx) => { let tx = tx.as_slice(); let (new_ledger_, _fee) = - new_ledger.apply_transaction(&fragment_id, &tx, ledger_params)?; + new_ledger.apply_transaction(&fragment_id, &tx, block_date, ledger_params)?; new_ledger = new_ledger_.apply_pool_registration_signcheck( &tx.payload().into_payload(), &tx.transaction_binding_auth_data(), @@ -884,7 +884,7 @@ impl Ledger { let tx = tx.as_slice(); let (new_ledger_, _fee) = - new_ledger.apply_transaction(&fragment_id, &tx, ledger_params)?; + new_ledger.apply_transaction(&fragment_id, &tx, block_date, ledger_params)?; new_ledger = new_ledger_.apply_pool_retirement( &tx.payload().into_payload(), &tx.transaction_binding_auth_data(), @@ -895,7 +895,7 @@ impl Ledger { let tx = tx.as_slice(); let (new_ledger_, _fee) = - new_ledger.apply_transaction(&fragment_id, &tx, ledger_params)?; + new_ledger.apply_transaction(&fragment_id, &tx, block_date, ledger_params)?; new_ledger = new_ledger_.apply_pool_update( &tx.payload().into_payload(), &tx.transaction_binding_auth_data(), @@ -918,7 +918,7 @@ impl Ledger { Fragment::VotePlan(tx) => { let tx = tx.as_slice(); let (new_ledger_, _fee) = - new_ledger.apply_transaction(&fragment_id, &tx, ledger_params)?; + new_ledger.apply_transaction(&fragment_id, &tx, block_date, ledger_params)?; new_ledger = new_ledger_.apply_vote_plan( &tx, block_date, @@ -936,7 +936,7 @@ impl Ledger { let tx = tx.as_slice(); let (new_ledger_, _fee) = - new_ledger.apply_transaction(&fragment_id, &tx, ledger_params)?; + new_ledger.apply_transaction(&fragment_id, &tx, block_date, ledger_params)?; new_ledger = new_ledger_.apply_vote_tally( &tx.payload().into_payload(), @@ -948,7 +948,7 @@ impl Ledger { let tx = tx.as_slice(); let (new_ledger_, _fee) = - new_ledger.apply_transaction(&fragment_id, &tx, ledger_params)?; + new_ledger.apply_transaction(&fragment_id, &tx, block_date, ledger_params)?; new_ledger = new_ledger_.apply_encrypted_vote_tally( &tx.payload().into_payload(), @@ -965,6 +965,7 @@ impl Ledger { mut self, fragment_id: &FragmentId, tx: &TransactionSlice<'a, Extra>, + cur_date: BlockDate, dyn_params: &LedgerParameters, ) -> Result<(Self, Value), Error> where @@ -972,6 +973,7 @@ impl Ledger { LinearFee: FeeAlgorithm, { check::valid_transaction_ios_number(tx)?; + check::valid_transaction_date(tx, cur_date)?; let fee = calculate_fee(tx, dyn_params); tx.verify_strictly_balanced(fee)?; self = self.apply_tx_inputs(tx)?; @@ -2471,7 +2473,9 @@ mod tests { let tx = builder_tx.set_witnesses(&witnesses).set_payload_auth(&()); let fragment = TestTx::new(tx).get_fragment(); - assert!(test_ledger.apply_transaction(fragment).is_err()); + assert!(test_ledger + .apply_transaction(fragment, BlockDate::first()) + .is_err()); } #[test] @@ -2497,7 +2501,7 @@ mod tests { ); println!( "{:?}", - test_ledger.apply_transaction(test_tx.get_fragment()) + test_ledger.apply_transaction(test_tx.get_fragment(), BlockDate::first()) ); TestResult::error(""); } @@ -2524,7 +2528,7 @@ mod tests { &[receiver], ); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_err()); } @@ -2557,7 +2561,7 @@ mod tests { ); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_err()); } @@ -2578,7 +2582,7 @@ mod tests { &reciever, ); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_ok()); LedgerStateVerifier::new(test_ledger.into()) .pots() @@ -2625,7 +2629,7 @@ mod tests { .and_then(|balance| balance - fee); match ( balance_res, - test_ledger.apply_transaction(test_tx.get_fragment()), + test_ledger.apply_transaction(test_tx.get_fragment(), BlockDate::first()), ) { (Ok(balance), Ok(_)) => TestResult::from_bool(balance == Value::zero()), (Err(err), Ok(_)) => TestResult::error(format!( @@ -2663,7 +2667,7 @@ mod tests { let tx = tx_builder.set_witnesses(&witnesses).set_payload_auth(&()); let test_tx = TestTx::new(tx); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_err()); } @@ -2682,7 +2686,7 @@ mod tests { ); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_err()); } @@ -2705,7 +2709,9 @@ mod tests { let fragment = TestTxBuilder::new(test_ledger.block0_hash) .move_all_funds(&mut test_ledger, &faucet, &reciever) .get_fragment(); - assert!(test_ledger.apply_transaction(fragment).is_ok()); + assert!(test_ledger + .apply_transaction(fragment, BlockDate::first()) + .is_ok()); LedgerStateVerifier::new(test_ledger.into()) .address_has_expected_balance(reciever.into(), Value(1)) @@ -2741,7 +2747,7 @@ mod tests { let test_tx = TestTx::new(tx); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_err()); } @@ -2765,7 +2771,7 @@ mod tests { let tx = tx_builder.set_witnesses(&[witness]).set_payload_auth(&()); let test_tx = TestTx::new(tx); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_err()); } @@ -2794,7 +2800,7 @@ mod tests { let test_tx = TestTx::new(tx); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_err()); } @@ -2823,7 +2829,7 @@ mod tests { let test_tx = TestTx::new(tx); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_err()); } @@ -2849,7 +2855,7 @@ mod tests { let tx = tx_builder.set_witnesses(&[witness]).set_payload_auth(&()); let test_tx = TestTx::new(tx); assert!(test_ledger - .apply_transaction(test_tx.get_fragment()) + .apply_transaction(test_tx.get_fragment(), BlockDate::first()) .is_err()); } } diff --git a/chain-impl-mockchain/src/ledger/tests/discrimination_tests.rs b/chain-impl-mockchain/src/ledger/tests/discrimination_tests.rs index a7537342b..a685fd916 100644 --- a/chain-impl-mockchain/src/ledger/tests/discrimination_tests.rs +++ b/chain-impl-mockchain/src/ledger/tests/discrimination_tests.rs @@ -1,6 +1,7 @@ #![cfg(test)] use crate::{ + date::BlockDate, testing::{ arbitrary::KindTypeWithoutMultisig, builders::TestTxBuilder, @@ -73,7 +74,7 @@ pub fn ledger_verifies_transaction_discrimination( .get_fragment(); let are_discriminations_unified = arbitrary_input_disc == arbitrary_output_disc; - let actual_result = ledger.apply_transaction(fragment); + let actual_result = ledger.apply_transaction(fragment, BlockDate::first()); match (are_discriminations_unified, actual_result) { (true, Ok(_)) => TestResult::passed(), diff --git a/chain-impl-mockchain/src/ledger/tests/ledger_tests.rs b/chain-impl-mockchain/src/ledger/tests/ledger_tests.rs index 41c411d46..eee1867ff 100644 --- a/chain-impl-mockchain/src/ledger/tests/ledger_tests.rs +++ b/chain-impl-mockchain/src/ledger/tests/ledger_tests.rs @@ -3,6 +3,7 @@ use crate::{ chaintypes::ConsensusType, config::ConfigParam, + date::BlockDate, fragment::{config::ConfigParams, Fragment}, ledger::{ ledger::{ @@ -38,7 +39,7 @@ pub fn ledger_accepts_correct_transaction( .move_funds(&mut ledger, &faucet, &receiver, faucet.value) .get_fragment(); let total_funds_before = ledger.total_funds(); - let result = ledger.apply_transaction(fragment); + let result = ledger.apply_transaction(fragment, BlockDate::first()); if result.is_err() { return TestResult::error(format!("Error from ledger: {}", result.err().unwrap())); @@ -72,7 +73,7 @@ pub fn total_funds_are_const_in_ledger( &transaction_data.output_addresses, ); let total_funds_before = ledger.total_funds(); - let result = ledger.apply_transaction(signed_tx.get_fragment()); + let result = ledger.apply_transaction(signed_tx.get_fragment(), BlockDate::first()); if result.is_err() { return TestResult::error(format!("Error from ledger: {:?}", result.err())); diff --git a/chain-impl-mockchain/src/ledger/tests/transaction_tests.rs b/chain-impl-mockchain/src/ledger/tests/transaction_tests.rs index d1cd0c2e2..e92ae66ce 100644 --- a/chain-impl-mockchain/src/ledger/tests/transaction_tests.rs +++ b/chain-impl-mockchain/src/ledger/tests/transaction_tests.rs @@ -2,6 +2,7 @@ use crate::{ accounting::account::LedgerError::NonExistent, + date::BlockDate, ledger::{ self, check::TxVerifyError, @@ -40,7 +41,93 @@ pub fn transaction_fail_when_255_outputs() { expected: 254, actual: 255 }), - test_ledger.apply_transaction(fragment) + test_ledger.apply_transaction(fragment, BlockDate::first()) + ); +} + +#[test] +pub fn transaction_fail_when_validity_badrange() { + let mut test_ledger = LedgerBuilder::from_config(ConfigBuilder::new(0)) + .faucet_value(Value(1000)) + .build() + .expect("cannot build test ledger"); + + let receiver = AddressData::utxo(Discrimination::Test); + let output = Output { + address: receiver.address, + value: Value(1), + }; + let outputs = [output]; + + let validity = Some(( + BlockDate { + epoch: 10, + slot_id: 0, + }, + BlockDate { + epoch: 9, + slot_id: 0, + }, + )); + + let fragment = TestTxBuilder::new(test_ledger.block0_hash) + .move_to_outputs_from_faucet_with_validity(&mut test_ledger, validity, &outputs) + .get_fragment(); + + assert_err!( + TransactionMalformed(TxVerifyError::TransactionValidityRangeInvalid), + test_ledger.apply_transaction(fragment, BlockDate::first()) + ); +} + +#[test] +pub fn transaction_fail_when_validity_out_of_range() { + let mut test_ledger = LedgerBuilder::from_config(ConfigBuilder::new(0)) + .faucet_value(Value(1000)) + .build() + .expect("cannot build test ledger"); + + let receiver = AddressData::utxo(Discrimination::Test); + let output = Output { + address: receiver.address, + value: Value(1), + }; + let outputs = [output]; + + let validity = Some(( + BlockDate { + epoch: 10, + slot_id: 10, + }, + BlockDate { + epoch: 10, + slot_id: 50, + }, + )); + + let fragment = TestTxBuilder::new(test_ledger.block0_hash) + .move_to_outputs_from_faucet_with_validity(&mut test_ledger, validity, &outputs) + .get_fragment(); + + assert_err!( + TransactionMalformed(TxVerifyError::TransactionValidityInFuture), + test_ledger.apply_transaction( + fragment.clone(), + BlockDate { + epoch: 10, + slot_id: 9 + } + ) + ); + assert_err!( + TransactionMalformed(TxVerifyError::TransactionValidityExpired), + test_ledger.apply_transaction( + fragment, + BlockDate { + epoch: 10, + slot_id: 51, + } + ) ); } @@ -57,14 +144,14 @@ pub fn duplicated_account_transaction() { .move_from_faucet(&mut test_ledger, &receiver.address, Value(100)) .get_fragment(); let fragment2 = fragment.clone(); - let result = test_ledger.apply_transaction(fragment); + let result = test_ledger.apply_transaction(fragment, BlockDate::first()); match result { Err(err) => panic!("first transaction should be succesful but {}", err), Ok(_) => { assert_err_match!( ledger::Error::AccountInvalidSignature { .. }, - test_ledger.apply_transaction(fragment2) + test_ledger.apply_transaction(fragment2, BlockDate::first()) ); } } @@ -86,7 +173,7 @@ pub fn transaction_nonexisting_account_input() { assert_err!( Account(NonExistent), - test_ledger.apply_transaction(fragment) + test_ledger.apply_transaction(fragment, BlockDate::first()) ); } @@ -105,7 +192,9 @@ pub fn transaction_with_incorrect_account_spending_counter() { .move_from_faucet(&mut test_ledger, &receiver.into(), Value(1000)) .get_fragment(); assert!( - test_ledger.apply_transaction(fragment).is_err(), + test_ledger + .apply_transaction(fragment, BlockDate::first()) + .is_err(), "first transaction should be successful" ); } @@ -123,10 +212,14 @@ pub fn repeated_account_transaction() { let fragment = TestTxBuilder::new(test_ledger.block0_hash) .move_all_funds(&mut test_ledger, &faucet, &receiver) .get_fragment(); - assert!(test_ledger.apply_transaction(fragment).is_ok()); + assert!(test_ledger + .apply_transaction(fragment, BlockDate::first()) + .is_ok()); faucet.confirm_transaction(); let fragment = TestTxBuilder::new(test_ledger.block0_hash) .move_all_funds(&mut test_ledger, &faucet, &receiver) .get_fragment(); - assert!(test_ledger.apply_transaction(fragment).is_err()); + assert!(test_ledger + .apply_transaction(fragment, BlockDate::first()) + .is_err()); } diff --git a/chain-impl-mockchain/src/testing/builders/tx_builder.rs b/chain-impl-mockchain/src/testing/builders/tx_builder.rs index 747a8bff1..4c745a207 100644 --- a/chain-impl-mockchain/src/testing/builders/tx_builder.rs +++ b/chain-impl-mockchain/src/testing/builders/tx_builder.rs @@ -1,5 +1,6 @@ use crate::{ chaintypes::HeaderId, + date::BlockDate, fee::FeeAlgorithm, fragment::{Fragment, FragmentId}, testing::{ @@ -102,9 +103,10 @@ impl TestTxBuilder { TestTx { tx } } - pub fn move_to_outputs_from_faucet( + pub fn move_to_outputs_from_faucet_with_validity( &self, test_ledger: &mut TestLedger, + validity: Option<(BlockDate, BlockDate)>, destination: &[Output

], ) -> TestTx { assert_eq!( @@ -125,6 +127,10 @@ impl TestTxBuilder { )]; let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity( + validity.map(|range| range.0).unwrap_or(BlockDate::first()), + validity.map(|range| range.1).unwrap_or(BlockDate::first()), + ) .set_ios(&inputs, &destination); let witness = @@ -135,6 +141,14 @@ impl TestTxBuilder { TestTx { tx } } + pub fn move_to_outputs_from_faucet( + &self, + test_ledger: &mut TestLedger, + destination: &[Output
], + ) -> TestTx { + self.move_to_outputs_from_faucet_with_validity(test_ledger, None, destination) + } + pub fn move_all_funds( &self, test_ledger: &mut TestLedger, diff --git a/chain-impl-mockchain/src/testing/ledger.rs b/chain-impl-mockchain/src/testing/ledger.rs index 7e4f78dd7..cf460178c 100644 --- a/chain-impl-mockchain/src/testing/ledger.rs +++ b/chain-impl-mockchain/src/testing/ledger.rs @@ -468,13 +468,14 @@ pub struct TestLedger { } impl TestLedger { - pub fn apply_transaction(&mut self, fragment: Fragment) -> Result<(), Error> { + pub fn apply_transaction(&mut self, fragment: Fragment, date: BlockDate) -> Result<(), Error> { let fragment_id = fragment.hash(); match fragment { Fragment::Transaction(tx) => { match self.ledger.clone().apply_transaction( &fragment_id, &tx.as_slice(), + date, &self.parameters, ) { Err(err) => Err(err), diff --git a/chain-impl-mockchain/src/testing/scenario/controller.rs b/chain-impl-mockchain/src/testing/scenario/controller.rs index 09efcb6c6..39075ac82 100644 --- a/chain-impl-mockchain/src/testing/scenario/controller.rs +++ b/chain-impl-mockchain/src/testing/scenario/controller.rs @@ -3,6 +3,7 @@ use crate::{ DecryptedPrivateTally, EncryptedVoteTally, ExternalProposalId, Proposal, VoteCast, VotePlan, VoteTally, }, + date::BlockDate, fee::LinearFee, key::Hash, ledger::Error as LedgerError, @@ -113,7 +114,7 @@ impl Controller { let transaction = self .fragment_factory .transaction(from, to, test_ledger, funds); - test_ledger.apply_transaction(transaction) + test_ledger.apply_transaction(transaction, BlockDate::first()) } pub fn register( diff --git a/chain-impl-mockchain/src/transaction/builder.rs b/chain-impl-mockchain/src/transaction/builder.rs index f20dfd2ea..223e7a2f2 100644 --- a/chain-impl-mockchain/src/transaction/builder.rs +++ b/chain-impl-mockchain/src/transaction/builder.rs @@ -5,6 +5,7 @@ use super::transaction::{ }; use super::transfer::Output; use super::witness::Witness; +use crate::date::BlockDate; use chain_addr::Address; use std::marker::PhantomData; @@ -52,6 +53,8 @@ impl TxBuilder { sz: 0, nb_inputs: 0, nb_outputs: 0, + valid_start_date: BlockDate::first(), + valid_end_date: BlockDate::first(), inputs: 0, outputs: 0, witnesses: 0, @@ -66,6 +69,14 @@ impl TxBuilderState { fn current_pos(&self) -> usize { self.data.len() - FRAGMENT_OVERHEAD } + + // this is not exported to outside this module, as someone + // can set the validity after the witness, with would render + // the witness invalid, instead use set_validity when available + fn _set_validity(&mut self, start: BlockDate, end: BlockDate) { + self.tstruct.valid_start_date = start; + self.tstruct.valid_end_date = end; + } } impl TxBuilderState { @@ -85,9 +96,19 @@ impl TxBuilderState { pub fn set_nopayload(self) -> TxBuilderState> { self.set_payload(&NoExtra) } + + pub fn set_validity(mut self, start: BlockDate, end: BlockDate) -> Self { + self._set_validity(start, end); + self + } } impl

TxBuilderState> { + pub fn set_validity(mut self, start: BlockDate, end: BlockDate) -> Self { + self._set_validity(start, end); + self + } + /// Set the inputs and outputs of this transaction /// /// This cannot accept more than 255 inputs, 255 outputs, since @@ -109,6 +130,14 @@ impl

TxBuilderState> { self.data.push(nb_inputs); self.data.push(nb_outputs); + fn write_date(data: &mut Vec, date: BlockDate) { + data.extend_from_slice(&date.epoch.to_be_bytes()); + data.extend_from_slice(&date.slot_id.to_be_bytes()); + } + + write_date(&mut self.data, self.tstruct.valid_start_date); + write_date(&mut self.data, self.tstruct.valid_end_date); + self.tstruct.nb_inputs = nb_inputs; self.tstruct.nb_outputs = nb_outputs; diff --git a/chain-impl-mockchain/src/transaction/transaction.rs b/chain-impl-mockchain/src/transaction/transaction.rs index 5ec01713f..0f2541a1a 100644 --- a/chain-impl-mockchain/src/transaction/transaction.rs +++ b/chain-impl-mockchain/src/transaction/transaction.rs @@ -4,6 +4,7 @@ use super::input::{Input, INPUT_SIZE}; use super::payload::{Payload, PayloadAuthSlice, PayloadSlice}; use super::transfer::Output; use super::witness::Witness; +use crate::date::BlockDate; use crate::value::{Value, ValueError}; use chain_addr::Address; use chain_core::mempack::{ReadBuf, Readable}; @@ -34,6 +35,7 @@ impl

Debug for Transaction

{ .field("payload", &tx.payload().0) .field("nb_inputs", &tx.nb_inputs()) .field("nb_outputs", &tx.nb_outputs()) + .field("validity", &tx.validity()) .field("nb_witnesses", &tx.nb_witnesses()) .field("total_input_value", &self.total_input()) .field("total_output_value", &self.total_output()) @@ -224,6 +226,7 @@ impl<'a> InputsWitnessesSlice<'a> { pub enum TransactionStructError { CannotReadNbInputs, CannotReadNbOutputs, + CannotReadDate, PayloadInvalid, InputsInvalid, OutputsInvalid, @@ -238,6 +241,8 @@ pub(super) struct TransactionStruct { pub(super) sz: usize, pub(super) nb_inputs: u8, pub(super) nb_outputs: u8, + pub(super) valid_start_date: BlockDate, + pub(super) valid_end_date: BlockDate, pub(super) inputs: usize, pub(super) outputs: usize, pub(super) witnesses: usize, @@ -262,6 +267,19 @@ fn get_spine(slice: &[u8]) -> Result Result { + let epoch = rb + .get_u32() + .map_err(|_| TransactionStructError::CannotReadDate)?; + let slot_id = rb + .get_u32() + .map_err(|_| TransactionStructError::CannotReadDate)?; + Ok(BlockDate { epoch, slot_id }) + } + + let valid_start_date = read_date(&mut rb)?; + let valid_end_date = read_date(&mut rb)?; + let inputs_pos = rb.position(); rb.skip_bytes(nb_inputs as usize * INPUT_SIZE) .map_err(|_| TransactionStructError::InputsInvalid)?; @@ -293,6 +311,8 @@ fn get_spine(slice: &[u8]) -> Result TransactionSlice<'a, P> { self.tstruct.nb_inputs } + pub fn validity(&self) -> (BlockDate, BlockDate) { + (self.tstruct.valid_start_date, self.tstruct.valid_end_date) + } + pub fn nb_outputs(&self) -> u8 { self.tstruct.nb_outputs } From 047ff5ee6621a8eead7192e19215de08df8b2626 Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Tue, 8 Jun 2021 11:25:52 +0800 Subject: [PATCH 2/9] fix lint --- chain-impl-mockchain/src/ledger/check.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chain-impl-mockchain/src/ledger/check.rs b/chain-impl-mockchain/src/ledger/check.rs index 07e95589f..5e3b359ca 100644 --- a/chain-impl-mockchain/src/ledger/check.rs +++ b/chain-impl-mockchain/src/ledger/check.rs @@ -181,13 +181,13 @@ pub(super) fn valid_transaction_date

( return Ok(()); } if start >= end { - return Err(TxVerifyError::TransactionValidityRangeInvalid); + Err(TxVerifyError::TransactionValidityRangeInvalid) } else if date < start { - return Err(TxVerifyError::TransactionValidityInFuture); + Err(TxVerifyError::TransactionValidityInFuture) } else if date > end { - return Err(TxVerifyError::TransactionValidityExpired); + Err(TxVerifyError::TransactionValidityExpired) } else { - return Ok(()); + Ok(()) } } From 8ae3a92d55a54b01e218048920ba093963bdd303 Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Sat, 19 Jun 2021 09:14:31 +0800 Subject: [PATCH 3/9] only use end validity expect the start validity to be defined implicitely by the node's mempool's blockdate --- chain-impl-mockchain/src/ledger/check.rs | 18 ++---- .../src/ledger/tests/transaction_tests.rs | 63 ++----------------- .../src/testing/builders/tx_builder.rs | 7 +-- .../src/transaction/builder.rs | 19 +++--- .../src/transaction/transaction.rs | 15 ++--- 5 files changed, 27 insertions(+), 95 deletions(-) diff --git a/chain-impl-mockchain/src/ledger/check.rs b/chain-impl-mockchain/src/ledger/check.rs index 5e3b359ca..2b10c362f 100644 --- a/chain-impl-mockchain/src/ledger/check.rs +++ b/chain-impl-mockchain/src/ledger/check.rs @@ -143,12 +143,8 @@ pub(super) fn valid_pool_update_certificate(reg: &certificate::PoolUpdate) -> Le pub enum TxVerifyError { #[error("too many outputs, expected maximum of {expected}, but received {actual}")] TooManyOutputs { expected: u8, actual: u8 }, - #[error("Transaction is not yet within validity range")] - TransactionValidityInFuture, #[error("Transaction validity expired")] - TransactionValidityExpired, - #[error("Transaction validity range is invalid")] - TransactionValidityRangeInvalid, + TransactionExpired, } #[allow(clippy::absurd_extreme_comparisons)] @@ -176,16 +172,12 @@ pub(super) fn valid_transaction_date

( date: BlockDate, ) -> Result<(), TxVerifyError> { // if end and start are BlockDate::first, we expect that the transaction has no validity range - let (start, end) = tx.validity(); - if end == start && end == BlockDate::first() { + let valid_until = tx.valid_until(); + if valid_until == BlockDate::first() { return Ok(()); } - if start >= end { - Err(TxVerifyError::TransactionValidityRangeInvalid) - } else if date < start { - Err(TxVerifyError::TransactionValidityInFuture) - } else if date > end { - Err(TxVerifyError::TransactionValidityExpired) + if date > valid_until { + Err(TxVerifyError::TransactionExpired) } else { Ok(()) } diff --git a/chain-impl-mockchain/src/ledger/tests/transaction_tests.rs b/chain-impl-mockchain/src/ledger/tests/transaction_tests.rs index e92ae66ce..cf5844764 100644 --- a/chain-impl-mockchain/src/ledger/tests/transaction_tests.rs +++ b/chain-impl-mockchain/src/ledger/tests/transaction_tests.rs @@ -45,41 +45,6 @@ pub fn transaction_fail_when_255_outputs() { ); } -#[test] -pub fn transaction_fail_when_validity_badrange() { - let mut test_ledger = LedgerBuilder::from_config(ConfigBuilder::new(0)) - .faucet_value(Value(1000)) - .build() - .expect("cannot build test ledger"); - - let receiver = AddressData::utxo(Discrimination::Test); - let output = Output { - address: receiver.address, - value: Value(1), - }; - let outputs = [output]; - - let validity = Some(( - BlockDate { - epoch: 10, - slot_id: 0, - }, - BlockDate { - epoch: 9, - slot_id: 0, - }, - )); - - let fragment = TestTxBuilder::new(test_ledger.block0_hash) - .move_to_outputs_from_faucet_with_validity(&mut test_ledger, validity, &outputs) - .get_fragment(); - - assert_err!( - TransactionMalformed(TxVerifyError::TransactionValidityRangeInvalid), - test_ledger.apply_transaction(fragment, BlockDate::first()) - ); -} - #[test] pub fn transaction_fail_when_validity_out_of_range() { let mut test_ledger = LedgerBuilder::from_config(ConfigBuilder::new(0)) @@ -94,33 +59,17 @@ pub fn transaction_fail_when_validity_out_of_range() { }; let outputs = [output]; - let validity = Some(( - BlockDate { - epoch: 10, - slot_id: 10, - }, - BlockDate { - epoch: 10, - slot_id: 50, - }, - )); + let valid_until = Some(BlockDate { + epoch: 10, + slot_id: 50, + }); let fragment = TestTxBuilder::new(test_ledger.block0_hash) - .move_to_outputs_from_faucet_with_validity(&mut test_ledger, validity, &outputs) + .move_to_outputs_from_faucet_with_validity(&mut test_ledger, valid_until, &outputs) .get_fragment(); assert_err!( - TransactionMalformed(TxVerifyError::TransactionValidityInFuture), - test_ledger.apply_transaction( - fragment.clone(), - BlockDate { - epoch: 10, - slot_id: 9 - } - ) - ); - assert_err!( - TransactionMalformed(TxVerifyError::TransactionValidityExpired), + TransactionMalformed(TxVerifyError::TransactionExpired), test_ledger.apply_transaction( fragment, BlockDate { diff --git a/chain-impl-mockchain/src/testing/builders/tx_builder.rs b/chain-impl-mockchain/src/testing/builders/tx_builder.rs index 4c745a207..1e3767b8c 100644 --- a/chain-impl-mockchain/src/testing/builders/tx_builder.rs +++ b/chain-impl-mockchain/src/testing/builders/tx_builder.rs @@ -106,7 +106,7 @@ impl TestTxBuilder { pub fn move_to_outputs_from_faucet_with_validity( &self, test_ledger: &mut TestLedger, - validity: Option<(BlockDate, BlockDate)>, + validity: Option, destination: &[Output

], ) -> TestTx { assert_eq!( @@ -127,10 +127,7 @@ impl TestTxBuilder { )]; let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity( - validity.map(|range| range.0).unwrap_or(BlockDate::first()), - validity.map(|range| range.1).unwrap_or(BlockDate::first()), - ) + .set_validity(validity.unwrap_or(BlockDate::first())) .set_ios(&inputs, &destination); let witness = diff --git a/chain-impl-mockchain/src/transaction/builder.rs b/chain-impl-mockchain/src/transaction/builder.rs index 223e7a2f2..07c7449c0 100644 --- a/chain-impl-mockchain/src/transaction/builder.rs +++ b/chain-impl-mockchain/src/transaction/builder.rs @@ -53,8 +53,7 @@ impl TxBuilder { sz: 0, nb_inputs: 0, nb_outputs: 0, - valid_start_date: BlockDate::first(), - valid_end_date: BlockDate::first(), + valid_until: BlockDate::first(), inputs: 0, outputs: 0, witnesses: 0, @@ -73,9 +72,8 @@ impl TxBuilderState { // this is not exported to outside this module, as someone // can set the validity after the witness, with would render // the witness invalid, instead use set_validity when available - fn _set_validity(&mut self, start: BlockDate, end: BlockDate) { - self.tstruct.valid_start_date = start; - self.tstruct.valid_end_date = end; + fn _set_validity(&mut self, valid_until: BlockDate) { + self.tstruct.valid_until = valid_until; } } @@ -97,15 +95,15 @@ impl TxBuilderState { self.set_payload(&NoExtra) } - pub fn set_validity(mut self, start: BlockDate, end: BlockDate) -> Self { - self._set_validity(start, end); + pub fn set_validity(mut self, valid_until: BlockDate) -> Self { + self._set_validity(valid_until); self } } impl

TxBuilderState> { - pub fn set_validity(mut self, start: BlockDate, end: BlockDate) -> Self { - self._set_validity(start, end); + pub fn set_validity(mut self, valid_until: BlockDate) -> Self { + self._set_validity(valid_until); self } @@ -135,8 +133,7 @@ impl

TxBuilderState> { data.extend_from_slice(&date.slot_id.to_be_bytes()); } - write_date(&mut self.data, self.tstruct.valid_start_date); - write_date(&mut self.data, self.tstruct.valid_end_date); + write_date(&mut self.data, self.tstruct.valid_until); self.tstruct.nb_inputs = nb_inputs; self.tstruct.nb_outputs = nb_outputs; diff --git a/chain-impl-mockchain/src/transaction/transaction.rs b/chain-impl-mockchain/src/transaction/transaction.rs index 0f2541a1a..2ee61fd45 100644 --- a/chain-impl-mockchain/src/transaction/transaction.rs +++ b/chain-impl-mockchain/src/transaction/transaction.rs @@ -35,7 +35,7 @@ impl

Debug for Transaction

{ .field("payload", &tx.payload().0) .field("nb_inputs", &tx.nb_inputs()) .field("nb_outputs", &tx.nb_outputs()) - .field("validity", &tx.validity()) + .field("valid_until", &tx.valid_until()) .field("nb_witnesses", &tx.nb_witnesses()) .field("total_input_value", &self.total_input()) .field("total_output_value", &self.total_output()) @@ -241,8 +241,7 @@ pub(super) struct TransactionStruct { pub(super) sz: usize, pub(super) nb_inputs: u8, pub(super) nb_outputs: u8, - pub(super) valid_start_date: BlockDate, - pub(super) valid_end_date: BlockDate, + pub(super) valid_until: BlockDate, pub(super) inputs: usize, pub(super) outputs: usize, pub(super) witnesses: usize, @@ -277,8 +276,7 @@ fn get_spine(slice: &[u8]) -> Result(slice: &[u8]) -> Result TransactionSlice<'a, P> { self.tstruct.nb_inputs } - pub fn validity(&self) -> (BlockDate, BlockDate) { - (self.tstruct.valid_start_date, self.tstruct.valid_end_date) + pub fn valid_until(&self) -> BlockDate { + self.tstruct.valid_until } pub fn nb_outputs(&self) -> u8 { From 764e8452e226a45cc2e1dffd46d98a8392b16336 Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Sun, 27 Jun 2021 09:00:00 +0800 Subject: [PATCH 4/9] add settings check to not allow transaction that are valid for too long --- chain-impl-mockchain/src/config.rs | 11 ++++++++++- chain-impl-mockchain/src/ledger/check.rs | 22 +++++++++++++++++----- chain-impl-mockchain/src/ledger/ledger.rs | 2 +- chain-impl-mockchain/src/setting.rs | 8 ++++++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/chain-impl-mockchain/src/config.rs b/chain-impl-mockchain/src/config.rs index 4d4cb024a..7d6019696 100644 --- a/chain-impl-mockchain/src/config.rs +++ b/chain-impl-mockchain/src/config.rs @@ -82,6 +82,7 @@ pub enum ConfigParam { AddCommitteeId(CommitteeId), RemoveCommitteeId(CommitteeId), PerVoteCertificateFees(PerVoteCertificateFee), + TransactionMaximumExpiryEpochs(u8), } #[derive(Clone, Debug, Eq, PartialEq)] @@ -153,6 +154,8 @@ pub enum Tag { RemoveCommitteeId = 27, #[strum(to_string = "per-vote-certificate-fees")] PerVoteCertificateFees = 28, + #[strum(to_string = "transaction-maximum-expiry-epochs")] + TransactionMaximumExpiryEpochs = 29, } impl Tag { @@ -183,6 +186,7 @@ impl Tag { 26 => Some(Tag::AddCommitteeId), 27 => Some(Tag::RemoveCommitteeId), 28 => Some(Tag::PerVoteCertificateFees), + 29 => Some(Tag::TransactionMaximumExpiryEpochs), _ => None, } } @@ -218,6 +222,7 @@ impl<'a> From<&'a ConfigParam> for Tag { ConfigParam::AddCommitteeId(..) => Tag::AddCommitteeId, ConfigParam::RemoveCommitteeId(..) => Tag::RemoveCommitteeId, ConfigParam::PerVoteCertificateFees(..) => Tag::PerVoteCertificateFees, + ConfigParam::TransactionMaximumExpiryEpochs(..) => Tag::TransactionMaximumExpiryEpochs, } } } @@ -298,6 +303,8 @@ impl Readable for ConfigParam { Tag::PerVoteCertificateFees => { ConfigParamVariant::from_payload(bytes).map(ConfigParam::PerVoteCertificateFees) } + Tag::TransactionMaximumExpiryEpochs => ConfigParamVariant::from_payload(bytes) + .map(ConfigParam::TransactionMaximumExpiryEpochs), } .map_err(Into::into) } @@ -334,6 +341,7 @@ impl property::Serialize for ConfigParam { ConfigParam::AddCommitteeId(data) => data.to_payload(), ConfigParam::RemoveCommitteeId(data) => data.to_payload(), ConfigParam::PerVoteCertificateFees(data) => data.to_payload(), + ConfigParam::TransactionMaximumExpiryEpochs(data) => data.to_payload(), }; let taglen = TagLen::new(tag, bytes.len()).ok_or_else(|| { io::Error::new( @@ -858,7 +866,7 @@ mod test { impl Arbitrary for ConfigParam { fn arbitrary(g: &mut G) -> Self { - match u8::arbitrary(g) % 29 { + match u8::arbitrary(g) % 30 { 0 => ConfigParam::Block0Date(Arbitrary::arbitrary(g)), 1 => ConfigParam::Discrimination(Arbitrary::arbitrary(g)), 2 => ConfigParam::ConsensusVersion(Arbitrary::arbitrary(g)), @@ -888,6 +896,7 @@ mod test { 26 => ConfigParam::AddCommitteeId(Arbitrary::arbitrary(g)), 27 => ConfigParam::RemoveCommitteeId(Arbitrary::arbitrary(g)), 28 => ConfigParam::PerCertificateFees(Arbitrary::arbitrary(g)), + 29 => ConfigParam::TransactionMaximumExpiryEpochs(Arbitrary::arbitrary(g)), _ => unreachable!(), } } diff --git a/chain-impl-mockchain/src/ledger/check.rs b/chain-impl-mockchain/src/ledger/check.rs index 2b10c362f..3a38d8705 100644 --- a/chain-impl-mockchain/src/ledger/check.rs +++ b/chain-impl-mockchain/src/ledger/check.rs @@ -1,6 +1,7 @@ use super::{Block0Error, Error}; use crate::certificate; use crate::date::BlockDate; +use crate::setting; use crate::transaction::*; use crate::value::Value; use chain_addr::Address; @@ -145,6 +146,8 @@ pub enum TxVerifyError { TooManyOutputs { expected: u8, actual: u8 }, #[error("Transaction validity expired")] TransactionExpired, + #[error("Transaction validity is too far in the future")] + TransactionValidForTooLong, } #[allow(clippy::absurd_extreme_comparisons)] @@ -168,6 +171,7 @@ pub(super) fn valid_transaction_ios_number

( } pub(super) fn valid_transaction_date

( + settings: &setting::Settings, tx: &TransactionSlice

, date: BlockDate, ) -> Result<(), TxVerifyError> { @@ -176,11 +180,19 @@ pub(super) fn valid_transaction_date

( if valid_until == BlockDate::first() { return Ok(()); } - if date > valid_until { - Err(TxVerifyError::TransactionExpired) - } else { - Ok(()) - } + + // if current date epoch is less than until.epoch - setting, then + // the transaction has a validity range that is too big to be accepted + if_cond_fail_with!( + date.epoch + < valid_until + .epoch + .saturating_sub(settings.transaction_maximum_expiry_epochs.into()), + TxVerifyError::TransactionValidForTooLong + )?; + // if current date is passed the validity until, the transaction is expired + if_cond_fail_with!(date > valid_until, TxVerifyError::TransactionExpired)?; + Ok(()) } #[cfg(test)] diff --git a/chain-impl-mockchain/src/ledger/ledger.rs b/chain-impl-mockchain/src/ledger/ledger.rs index 0cbce694b..33a917d46 100644 --- a/chain-impl-mockchain/src/ledger/ledger.rs +++ b/chain-impl-mockchain/src/ledger/ledger.rs @@ -973,7 +973,7 @@ impl Ledger { LinearFee: FeeAlgorithm, { check::valid_transaction_ios_number(tx)?; - check::valid_transaction_date(tx, cur_date)?; + check::valid_transaction_date(&self.settings, tx, cur_date)?; let fee = calculate_fee(tx, dyn_params); tx.verify_strictly_balanced(fee)?; self = self.apply_tx_inputs(tx)?; diff --git a/chain-impl-mockchain/src/setting.rs b/chain-impl-mockchain/src/setting.rs index af8e54cad..5ddd144a2 100644 --- a/chain-impl-mockchain/src/setting.rs +++ b/chain-impl-mockchain/src/setting.rs @@ -41,6 +41,7 @@ pub struct Settings { pub rewards_limit: rewards::Limit, pub pool_participation_capping: Option<(NonZeroU32, NonZeroU32)>, pub committees: Arc>, + pub transaction_maximum_expiry_epochs: u8, } #[derive(Clone, Debug, Eq, PartialEq)] @@ -127,6 +128,7 @@ impl Settings { rewards_limit: rewards::Limit::None, pool_participation_capping: None, committees: Arc::new(Box::new([])), + transaction_maximum_expiry_epochs: 1, } } @@ -237,6 +239,9 @@ impl Settings { .into(), ); } + ConfigParam::TransactionMaximumExpiryEpochs(max_expiry_epochs) => { + new_state.transaction_maximum_expiry_epochs = *max_expiry_epochs; + } } } @@ -269,6 +274,9 @@ impl Settings { } params.push(ConfigParam::LinearFee(self.linear_fees)); params.push(ConfigParam::ProposalExpiration(self.proposal_expiration)); + params.push(ConfigParam::TransactionMaximumExpiryEpochs( + self.transaction_maximum_expiry_epochs, + )); match &self.reward_params { Some(p) => params.push(ConfigParam::RewardParams(p.clone())), From ca430a6255fa31d9a167d2570be158f82e8cf51c Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Wed, 30 Jun 2021 07:02:00 +0800 Subject: [PATCH 5/9] require validity for all transaction introduce a new SetValidity state in the transaction builder lots of minor adjustment in the test suite to cope with explicit date verification now in the ledger. --- chain-impl-mockchain/src/certificate/pool.rs | 2 + chain-impl-mockchain/src/ledger/check.rs | 4 - chain-impl-mockchain/src/ledger/ledger.rs | 25 +++- .../src/ledger/tests/apply_block_tests.rs | 10 +- .../certificate_tests/pool_registration.rs | 24 ++-- .../tests/certificate_tests/pool_update.rs | 18 +-- .../src/testing/builders/initial_builder.rs | 12 +- .../src/testing/builders/tx_builder.rs | 2 + .../src/testing/builders/tx_cert_builder.rs | 109 +++++++++++++++--- chain-impl-mockchain/src/testing/ledger.rs | 3 + .../src/testing/scenario/controller.rs | 59 ++++++---- .../src/testing/scenario/fragment_factory.rs | 67 +++++++---- .../src/transaction/builder.rs | 53 ++++----- chain-impl-mockchain/src/transaction/mod.rs | 4 +- chain-impl-mockchain/src/transaction/test.rs | 2 + .../src/transaction/transaction.rs | 23 ++-- chain-impl-mockchain/src/vote/manager.rs | 32 ++--- 17 files changed, 296 insertions(+), 153 deletions(-) diff --git a/chain-impl-mockchain/src/certificate/pool.rs b/chain-impl-mockchain/src/certificate/pool.rs index 0b043f584..8ea32f4d1 100644 --- a/chain-impl-mockchain/src/certificate/pool.rs +++ b/chain-impl-mockchain/src/certificate/pool.rs @@ -456,6 +456,7 @@ mod tests { use super::{PoolOwnersSigned, PoolPermissions}; use crate::{ chaintypes::HeaderId, + date::BlockDate, key::EitherEd25519SecretKey, testing::{ builders::{make_witness, StakePoolBuilder}, @@ -739,6 +740,7 @@ mod tests { let builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&pool_owner_with_sign.inputs(), &[]); let auth_data_hash = builder.get_auth_data_for_witness().hash(); let builder = builder diff --git a/chain-impl-mockchain/src/ledger/check.rs b/chain-impl-mockchain/src/ledger/check.rs index 3a38d8705..60ee400d7 100644 --- a/chain-impl-mockchain/src/ledger/check.rs +++ b/chain-impl-mockchain/src/ledger/check.rs @@ -175,11 +175,7 @@ pub(super) fn valid_transaction_date

( tx: &TransactionSlice

, date: BlockDate, ) -> Result<(), TxVerifyError> { - // if end and start are BlockDate::first, we expect that the transaction has no validity range let valid_until = tx.valid_until(); - if valid_until == BlockDate::first() { - return Ok(()); - } // if current date epoch is less than until.epoch - setting, then // the transaction has a validity range that is too big to be accepted diff --git a/chain-impl-mockchain/src/ledger/ledger.rs b/chain-impl-mockchain/src/ledger/ledger.rs index 33a917d46..a148dc5ec 100644 --- a/chain-impl-mockchain/src/ledger/ledger.rs +++ b/chain-impl-mockchain/src/ledger/ledger.rs @@ -1869,6 +1869,7 @@ mod tests { TestTx::new( TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[], &[]) .set_witnesses(&[]) .set_payload_auth(&()), @@ -1879,6 +1880,7 @@ mod tests { TestTx::new( TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(inputs, outputs) .set_witnesses(&[]) .set_payload_auth(&()), @@ -1892,6 +1894,7 @@ mod tests { ) -> TestTx { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[input], &[]); let witness = make_witness( @@ -2456,6 +2459,7 @@ mod tests { let builder_tx = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&inputs, &[reciever.make_output(Value(100))]); let witnesses: Vec = faucets @@ -2547,6 +2551,7 @@ mod tests { let inputs: Vec = faucets.iter().map(|x| x.make_input(None)).collect(); let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&inputs, &[reciever.make_output(Value(2))]); let witness = make_witness( @@ -2606,10 +2611,13 @@ mod tests { .unwrap(); let block0_hash = test_ledger.block0_hash; - let tx_builder = TxBuilder::new().set_payload(&NoExtra).set_ios( - &input_addresses.make_inputs(&test_ledger), - &output_addresses.make_outputs(), - ); + let tx_builder = TxBuilder::new() + .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) + .set_ios( + &input_addresses.make_inputs(&test_ledger), + &output_addresses.make_outputs(), + ); let witnesses: Vec = input_addresses .as_addresses() @@ -2656,6 +2664,7 @@ mod tests { let inputs = [faucets[0].make_input(None), faucets[1].make_input(None)]; let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&inputs, &[reciever.make_output(Value(2))]); let auth_data = tx_builder.get_auth_data_for_witness().hash(); let witnesses = make_witnesses( @@ -2734,6 +2743,7 @@ mod tests { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[faucet.make_input(utxo)], &[reciever.make_output()]); let witness = Witness::new_account( @@ -2760,7 +2770,9 @@ mod tests { .build() .unwrap(); - let tx_builder = TxBuilder::new().set_payload(&NoExtra); + let tx_builder = TxBuilder::new() + .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()); let tx_builder = tx_builder.set_ios(&[faucet.make_input(None)], &[reciever.make_output()]); let random_bytes = TestGen::bytes(); @@ -2788,6 +2800,7 @@ mod tests { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[faucet.make_input(None)], &[reciever.make_output()]); let witness = make_witness( @@ -2817,6 +2830,7 @@ mod tests { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[faucet.make_input(None)], &[reciever.make_output()]); let witness = make_witness( @@ -2845,6 +2859,7 @@ mod tests { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[faucet.make_input(None)], &[reciever.make_output()]); let witness = make_witness( diff --git a/chain-impl-mockchain/src/ledger/tests/apply_block_tests.rs b/chain-impl-mockchain/src/ledger/tests/apply_block_tests.rs index 981b40883..8731b82ff 100644 --- a/chain-impl-mockchain/src/ledger/tests/apply_block_tests.rs +++ b/chain-impl-mockchain/src/ledger/tests/apply_block_tests.rs @@ -20,10 +20,7 @@ pub fn apply_block_increases_leaders_log() { .unwrap(); let stake_pool = controller.stake_pool("stake_pool").unwrap(); - let date = BlockDate { - epoch: 1, - slot_id: 0, - }; + let date = BlockDate::first(); let block = GenesisPraosBlockBuilder::new() .with_date(date) .with_chain_length(ledger.chain_length()) @@ -142,10 +139,7 @@ pub fn apply_block_incorrect_fragment() { let alice = controller.wallet("Alice").unwrap(); let bob = controller.wallet("Bob").unwrap(); - let date = BlockDate { - epoch: 1, - slot_id: 0, - }; + let date = BlockDate::first(); let fragment = TestTxBuilder::new(ledger.block0_hash) .move_funds( diff --git a/chain-impl-mockchain/src/ledger/tests/certificate_tests/pool_registration.rs b/chain-impl-mockchain/src/ledger/tests/certificate_tests/pool_registration.rs index 997358a96..3e0d2228e 100644 --- a/chain-impl-mockchain/src/ledger/tests/certificate_tests/pool_registration.rs +++ b/chain-impl-mockchain/src/ledger/tests/certificate_tests/pool_registration.rs @@ -39,9 +39,9 @@ pub fn pool_registration_is_accepted() { let certificate = build_stake_pool_registration_cert(&stake_pool.info()); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(&[alice, bob, clarice], &certificate); + .make_transaction(test_ledger.date(), &[alice, bob, clarice], &certificate); assert!(test_ledger - .apply_fragment(&fragment, BlockDate::first()) + .apply_fragment(&fragment, test_ledger.date()) .is_ok()); } @@ -67,10 +67,10 @@ pub fn pool_registration_zero_management_threshold() { let certificate = build_stake_pool_registration_cert(&stake_pool.info()); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(&[alice, bob, clarice], &certificate); + .make_transaction(test_ledger.date(), &[alice, bob, clarice], &certificate); assert_err!( Error::PoolRegistrationManagementThresholdZero, - test_ledger.apply_fragment(&fragment, BlockDate::first()) + test_ledger.apply_fragment(&fragment, test_ledger.date()) ); } @@ -96,10 +96,10 @@ pub fn pool_registration_management_threshold_above() { let certificate = build_stake_pool_registration_cert(&stake_pool.info()); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(&[alice, bob, clarice], &certificate); + .make_transaction(test_ledger.date(), &[alice, bob, clarice], &certificate); assert_err!( Error::PoolRegistrationManagementThresholdAbove, - test_ledger.apply_fragment(&fragment, BlockDate::first()) + test_ledger.apply_fragment(&fragment, test_ledger.date()) ); } @@ -123,7 +123,7 @@ pub fn pool_registration_too_many_owners() { let certificate = build_stake_pool_registration_cert(&stake_pool.info()); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(&[alice], &certificate); + .make_transaction(test_ledger.date(), &[alice], &certificate); assert_err!( Error::PoolRegistrationHasTooManyOwners, test_ledger.apply_fragment(&fragment, BlockDate::first()) @@ -151,7 +151,7 @@ pub fn pool_registration_too_many_operators() { let certificate = build_stake_pool_registration_cert(&stake_pool.info()); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(&[alice], &certificate); + .make_transaction(test_ledger.date(), &[alice], &certificate); assert_err!( Error::PoolRegistrationHasTooManyOperators, test_ledger.apply_fragment(&fragment, BlockDate::first()) @@ -175,9 +175,9 @@ pub fn pool_registration_zero_signatures() { let certificate = build_stake_pool_registration_cert(&stake_pool.info()); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction_different_signers(&alice, &[], &certificate); + .make_transaction_different_signers(test_ledger.date(), &alice, &[], &certificate); test_ledger - .apply_fragment(&fragment, BlockDate::first()) + .apply_fragment(&fragment, test_ledger.date()) .unwrap(); } @@ -201,9 +201,9 @@ pub fn pool_registration_too_many_signatures() { let certificate = build_stake_pool_registration_cert(&stake_pool.info()); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction_different_signers(&alice, &signers, &certificate); + .make_transaction_different_signers(test_ledger.date(), &alice, &signers, &certificate); assert_err!( Error::CertificateInvalidSignature, - test_ledger.apply_fragment(&fragment, BlockDate::first()) + test_ledger.apply_fragment(&fragment, test_ledger.date()) ); } diff --git a/chain-impl-mockchain/src/ledger/tests/certificate_tests/pool_update.rs b/chain-impl-mockchain/src/ledger/tests/certificate_tests/pool_update.rs index 977e8bab2..f6c6422c2 100644 --- a/chain-impl-mockchain/src/ledger/tests/certificate_tests/pool_update.rs +++ b/chain-impl-mockchain/src/ledger/tests/certificate_tests/pool_update.rs @@ -81,11 +81,11 @@ pub fn pool_update_wrong_last_hash() { }; let certificate = build_stake_pool_update_cert(&pool_update); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(&[alice], &certificate); + .make_transaction(test_ledger.date(), &[alice], &certificate); assert_eq!( test_ledger - .apply_fragment(&fragment, BlockDate::first()) + .apply_fragment(&fragment, test_ledger.date()) .err() .unwrap(), Error::PoolUpdateLastHashDoesntMatch @@ -119,7 +119,7 @@ pub fn pool_update_not_enough_fee() { }; let certificate = build_stake_pool_update_cert(&pool_update); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, LinearFee::new(0, 0, 0)) - .make_transaction(&[alice], &certificate); + .make_transaction(test_ledger.date(), &[alice], &certificate); assert_eq!( test_ledger @@ -161,7 +161,7 @@ pub fn pool_update_wrong_pool_id() { }; let certificate = build_stake_pool_update_cert(&pool_update); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(&[alice], &certificate); + .make_transaction(test_ledger.date(), &[alice], &certificate); assert_eq!( test_ledger @@ -203,7 +203,7 @@ pub fn pool_update_use_old_hash() { let certificate = build_stake_pool_update_cert(&pool_update); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(Some(&alice), &certificate); + .make_transaction(test_ledger.date(), Some(&alice), &certificate); assert!(test_ledger .apply_fragment(&fragment, BlockDate::first()) @@ -222,7 +222,7 @@ pub fn pool_update_use_old_hash() { let certificate = build_stake_pool_update_cert(&pool_update); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(Some(&alice), &certificate); + .make_transaction(test_ledger.date(), Some(&alice), &certificate); assert!(test_ledger .apply_fragment(&fragment, BlockDate::first()) @@ -242,7 +242,7 @@ pub fn pool_update_use_old_hash() { let certificate = build_stake_pool_update_cert(&pool_update); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(&[alice], &certificate); + .make_transaction(test_ledger.date(), &[alice], &certificate); assert!(test_ledger .apply_fragment(&fragment, BlockDate::first()) @@ -276,7 +276,7 @@ pub fn pool_update_update_fee_is_not_allowed() { let certificate = build_stake_pool_update_cert(&pool_update); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(&[alice], &certificate); + .make_transaction(test_ledger.date(), &[alice], &certificate); assert_eq!( test_ledger @@ -310,7 +310,7 @@ pub fn pool_update_without_any_change() { }; let certificate = build_stake_pool_update_cert(&pool_update); let fragment = TestTxCertBuilder::new(test_ledger.block0_hash, test_ledger.fee()) - .make_transaction(Some(&alice), &certificate); + .make_transaction(test_ledger.date(), Some(&alice), &certificate); assert!(test_ledger .apply_fragment(&fragment, BlockDate::first()) diff --git a/chain-impl-mockchain/src/testing/builders/initial_builder.rs b/chain-impl-mockchain/src/testing/builders/initial_builder.rs index 685fbb9b0..e9b7aaef2 100644 --- a/chain-impl-mockchain/src/testing/builders/initial_builder.rs +++ b/chain-impl-mockchain/src/testing/builders/initial_builder.rs @@ -1,6 +1,7 @@ use crate::{ account::DelegationType, certificate::{Certificate, PoolUpdate, VoteCast, VotePlan, VoteTally}, + date::BlockDate, fragment::Fragment, key::EitherEd25519SecretKey, ledger::ledger::OutputAddress, @@ -74,6 +75,7 @@ pub fn create_initial_vote_tally(vote_tally: &VoteTally, owners: &[Wallet]) -> F pub fn create_initial_transaction(wallet: &Wallet) -> Fragment { let tx = TxBuilder::new() .set_nopayload() + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[], &[wallet.make_output()]) .set_witnesses_unchecked(&[]) .set_payload_auth(&()); @@ -92,11 +94,12 @@ pub fn create_initial_stake_pool_owner_delegation(delegation_type: DelegationTyp } fn set_initial_ios( - builder: TxBuilderState>, + builder: TxBuilderState>, inputs: &[Input], outputs: &[OutputAddress], ) -> TxBuilderState> { builder + .set_validity(BlockDate::first().next_epoch()) .set_ios(inputs, outputs) .set_witnesses_unchecked(&[]) } @@ -199,6 +202,7 @@ impl InitialFaultTolerantTxBuilder { let output = self.reciever.make_output_with_value(Value(1)); let tx = TxBuilder::new() .set_nopayload() + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[input], &[output]) .set_witnesses_unchecked(&[]) .set_payload_auth(&()); @@ -209,6 +213,7 @@ impl InitialFaultTolerantTxBuilder { let input = self.sender.make_input_with_value(Value(1)); let tx = TxBuilder::new() .set_nopayload() + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[input], &[]) .set_witnesses_unchecked(&[]) .set_payload_auth(&()); @@ -216,7 +221,10 @@ impl InitialFaultTolerantTxBuilder { } pub fn transaction_with_witness_only(&self) -> Fragment { - let tx = TxBuilder::new().set_nopayload().set_ios(&[], &[]); + let tx = TxBuilder::new() + .set_nopayload() + .set_validity(BlockDate::first().next_epoch()) + .set_ios(&[], &[]); let witness = self .sender .clone() diff --git a/chain-impl-mockchain/src/testing/builders/tx_builder.rs b/chain-impl-mockchain/src/testing/builders/tx_builder.rs index 1e3767b8c..465410a6b 100644 --- a/chain-impl-mockchain/src/testing/builders/tx_builder.rs +++ b/chain-impl-mockchain/src/testing/builders/tx_builder.rs @@ -93,6 +93,7 @@ impl TestTxBuilder { }]; let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&inputs, &outputs); let witness = @@ -197,6 +198,7 @@ impl TestTxBuilder { .collect(); let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&inputs, &destinations); let witnesses: Vec = sources diff --git a/chain-impl-mockchain/src/testing/builders/tx_cert_builder.rs b/chain-impl-mockchain/src/testing/builders/tx_cert_builder.rs index 11d5c73c6..21a5872af 100644 --- a/chain-impl-mockchain/src/testing/builders/tx_cert_builder.rs +++ b/chain-impl-mockchain/src/testing/builders/tx_cert_builder.rs @@ -5,6 +5,7 @@ use crate::{ TallyProof, VotePlan, VotePlanProof, VoteTally, }, chaintypes::HeaderId, + date::BlockDate, fee::FeeAlgorithm, fee::LinearFee, fragment::Fragment, @@ -12,7 +13,7 @@ use crate::{ ledger::ledger::OutputAddress, testing::{data::Wallet, make_witness}, transaction::{ - AccountBindingSignature, Input, Payload, SetAuthData, SetIOs, + AccountBindingSignature, Input, Payload, SetAuthData, SetValidity, SingleAccountBindingSignature, TxBuilder, TxBuilderState, Witness, }, value::Value, @@ -42,14 +43,19 @@ impl TestTxCertBuilder { fn set_initial_ios( &self, - builder: TxBuilderState>, + current_date: BlockDate, + builder: TxBuilderState>, funder: &Wallet, inputs: &[Input], outputs: &[OutputAddress], should_make_witness: bool, ) -> TxBuilderState> { + let valid_until = BlockDate { + epoch: current_date.epoch + 1, + slot_id: current_date.slot_id, + }; //utxo not supported yet - let builder = builder.set_ios(inputs, outputs); + let builder = builder.set_validity(valid_until).set_ios(inputs, outputs); let witnesses: Vec = { if should_make_witness { @@ -68,6 +74,7 @@ impl TestTxCertBuilder { fn fragment( &self, + current_date: BlockDate, cert: &Certificate, keys: Vec, inputs: &[Input], @@ -78,6 +85,7 @@ impl TestTxCertBuilder { match cert { Certificate::StakeDelegation(s) => { let builder = self.set_initial_ios( + current_date, TxBuilder::new().set_payload(s), &funder, inputs, @@ -93,6 +101,7 @@ impl TestTxCertBuilder { } Certificate::PoolRegistration(s) => { let builder = self.set_initial_ios( + current_date, TxBuilder::new().set_payload(s), &funder, inputs, @@ -105,6 +114,7 @@ impl TestTxCertBuilder { } Certificate::PoolRetirement(s) => { let builder = self.set_initial_ios( + current_date, TxBuilder::new().set_payload(s), &funder, inputs, @@ -117,6 +127,7 @@ impl TestTxCertBuilder { } Certificate::PoolUpdate(s) => { let builder = self.set_initial_ios( + current_date, TxBuilder::new().set_payload(s), &funder, inputs, @@ -129,6 +140,7 @@ impl TestTxCertBuilder { } Certificate::OwnerStakeDelegation(s) => { let builder = self.set_initial_ios( + current_date, TxBuilder::new().set_payload(s), &funder, inputs, @@ -140,6 +152,7 @@ impl TestTxCertBuilder { } Certificate::VotePlan(vp) => { let builder = self.set_initial_ios( + current_date, TxBuilder::new().set_payload(vp), &funder, inputs, @@ -152,6 +165,7 @@ impl TestTxCertBuilder { } Certificate::VoteCast(vp) => { let builder = self.set_initial_ios( + current_date, TxBuilder::new().set_payload(vp), &funder, inputs, @@ -163,6 +177,7 @@ impl TestTxCertBuilder { } Certificate::VoteTally(vt) => { let builder = self.set_initial_ios( + current_date, TxBuilder::new().set_payload(vt), &funder, inputs, @@ -175,6 +190,7 @@ impl TestTxCertBuilder { } Certificate::EncryptedVoteTally(vote_tally) => { let builder = self.set_initial_ios( + current_date, TxBuilder::new().set_payload(vote_tally), &funder, inputs, @@ -188,13 +204,19 @@ impl TestTxCertBuilder { } } - pub fn make_transaction<'a, T>(self, signers: T, certificate: &Certificate) -> Fragment + pub fn make_transaction<'a, T>( + self, + date: BlockDate, + signers: T, + certificate: &Certificate, + ) -> Fragment where T: IntoIterator, { let mut remainder = signers.into_iter(); let funder = remainder.next().expect("needs at least one signer"); self.make_transaction_different_signers( + date, funder, iter::once(funder).chain(remainder), certificate, @@ -203,6 +225,7 @@ impl TestTxCertBuilder { pub fn make_transaction_different_signers<'a, T>( self, + date: BlockDate, funder: &'a Wallet, signers: T, certificate: &Certificate, @@ -212,7 +235,7 @@ impl TestTxCertBuilder { { let keys = signers.into_iter().map(|x| x.private_key()).collect(); let input = funder.make_input_with_value(self.fee(certificate)); - self.fragment(certificate, keys, &[input], &[], true, funder) + self.fragment(date, certificate, keys, &[input], &[], true, funder) } } @@ -285,16 +308,24 @@ pub fn pool_owner_signed( /// in order to test robustness of ledger pub struct FaultTolerantTxCertBuilder { builder: TestTxCertBuilder, + date: BlockDate, cert: Certificate, funder: Wallet, } impl FaultTolerantTxCertBuilder { - pub fn new(block0_hash: HeaderId, fee: LinearFee, cert: Certificate, funder: Wallet) -> Self { + pub fn new( + block0_hash: HeaderId, + fee: LinearFee, + cert: Certificate, + date: BlockDate, + funder: Wallet, + ) -> Self { Self { builder: TestTxCertBuilder::new(block0_hash, fee), cert, funder, + date, } } @@ -303,8 +334,15 @@ impl FaultTolerantTxCertBuilder { let input = self .funder .make_input_with_value(self.builder.fee(&self.cert)); - self.builder - .fragment(&self.cert, keys, &[input], &[], false, &self.funder) + self.builder.fragment( + self.date, + &self.cert, + keys, + &[input], + &[], + false, + &self.funder, + ) } pub fn transaction_input_to_low(&self) -> Fragment { @@ -312,8 +350,15 @@ impl FaultTolerantTxCertBuilder { let input_value = Value(1); let input = self.funder.make_input_with_value(input_value); let output = self.funder.make_output_with_value(Value(2)); - self.builder - .fragment(&self.cert, keys, &[input], &[output], false, &self.funder) + self.builder.fragment( + self.date, + &self.cert, + keys, + &[input], + &[output], + false, + &self.funder, + ) } pub fn transaction_with_input_output(&self) -> Fragment { @@ -321,8 +366,15 @@ impl FaultTolerantTxCertBuilder { let input_value = Value(self.builder.fee(&self.cert).0 + 1); let input = self.funder.make_input_with_value(input_value); let output = self.funder.make_output_with_value(Value(1)); - self.builder - .fragment(&self.cert, keys, &[input], &[output], false, &self.funder) + self.builder.fragment( + self.date, + &self.cert, + keys, + &[input], + &[output], + false, + &self.funder, + ) } pub fn transaction_with_output_only(&self) -> Fragment { @@ -330,8 +382,15 @@ impl FaultTolerantTxCertBuilder { let output = self .funder .make_output_with_value(self.builder.fee(&self.cert)); - self.builder - .fragment(&self.cert, keys, &[], &[output], false, &self.funder) + self.builder.fragment( + self.date, + &self.cert, + keys, + &[], + &[output], + false, + &self.funder, + ) } pub fn transaction_with_input_only(&self) -> Fragment { @@ -339,8 +398,15 @@ impl FaultTolerantTxCertBuilder { let input = self .funder .make_input_with_value(self.builder.fee(&self.cert)); - self.builder - .fragment(&self.cert, keys, &[input], &[], false, &self.funder) + self.builder.fragment( + self.date, + &self.cert, + keys, + &[input], + &[], + false, + &self.funder, + ) } pub fn transaction_with_witness(&self) -> Fragment { @@ -348,7 +414,14 @@ impl FaultTolerantTxCertBuilder { let input = self .funder .make_input_with_value(self.builder.fee(&self.cert)); - self.builder - .fragment(&self.cert, keys, &[input], &[], false, &self.funder) + self.builder.fragment( + self.date, + &self.cert, + keys, + &[input], + &[], + false, + &self.funder, + ) } } diff --git a/chain-impl-mockchain/src/testing/ledger.rs b/chain-impl-mockchain/src/testing/ledger.rs index cf460178c..5654a474a 100644 --- a/chain-impl-mockchain/src/testing/ledger.rs +++ b/chain-impl-mockchain/src/testing/ledger.rs @@ -339,6 +339,7 @@ impl LedgerBuilder { pub fn prefill_output(self, output: Output

) -> Self { let tx = TxBuilder::new() .set_nopayload() + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[], &[output]) .set_witnesses(&[]) .set_payload_auth(&()); @@ -349,6 +350,7 @@ impl LedgerBuilder { for outputs_chunk in outputs.chunks(CHECK_TX_MAXIMUM_INPUTS.into()) { let tx = TxBuilder::new() .set_nopayload() + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[], outputs_chunk) .set_witnesses(&[]) .set_payload_auth(&()); @@ -418,6 +420,7 @@ impl LedgerBuilder { { let tx = TxBuilder::new() .set_nopayload() + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[], &group) .set_witnesses(&[]) .set_payload_auth(&()); diff --git a/chain-impl-mockchain/src/testing/scenario/controller.rs b/chain-impl-mockchain/src/testing/scenario/controller.rs index 39075ac82..1c645f1b9 100644 --- a/chain-impl-mockchain/src/testing/scenario/controller.rs +++ b/chain-impl-mockchain/src/testing/scenario/controller.rs @@ -123,9 +123,9 @@ impl Controller { stake_pool: &StakePool, test_ledger: &mut TestLedger, ) -> Result<(), LedgerError> { - let fragment = self - .fragment_factory - .stake_pool_registration(funder, stake_pool); + let fragment = + self.fragment_factory + .stake_pool_registration(test_ledger.date(), funder, stake_pool); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -135,7 +135,9 @@ impl Controller { stake_pool: &StakePool, test_ledger: &mut TestLedger, ) -> Result<(), LedgerError> { - let fragment = self.fragment_factory.delegation(from, stake_pool); + let fragment = self + .fragment_factory + .delegation(test_ledger.date(), from, stake_pool); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -146,9 +148,12 @@ impl Controller { stake_pool: &StakePool, test_ledger: &mut TestLedger, ) -> Result<(), LedgerError> { - let fragment = self - .fragment_factory - .delegation_different_funder(funder, delegation, stake_pool); + let fragment = self.fragment_factory.delegation_different_funder( + test_ledger.date(), + funder, + delegation, + stake_pool, + ); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -157,7 +162,9 @@ impl Controller { from: &Wallet, test_ledger: &mut TestLedger, ) -> Result<(), LedgerError> { - let fragment = self.fragment_factory.delegation_remove(from); + let fragment = self + .fragment_factory + .delegation_remove(test_ledger.date(), from); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -167,7 +174,9 @@ impl Controller { distribution: &[(&StakePool, u8)], test_ledger: &mut TestLedger, ) -> Result<(), LedgerError> { - let fragment = self.fragment_factory.delegation_to_many(from, distribution); + let fragment = + self.fragment_factory + .delegation_to_many(test_ledger.date(), from, distribution); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -177,7 +186,9 @@ impl Controller { stake_pool: &StakePool, test_ledger: &mut TestLedger, ) -> Result<(), LedgerError> { - let fragment = self.fragment_factory.owner_delegation(from, stake_pool); + let fragment = self + .fragment_factory + .owner_delegation(test_ledger.date(), from, stake_pool); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -187,7 +198,9 @@ impl Controller { stake_pool: &'a StakePool, test_ledger: &'a mut TestLedger, ) -> Result<(), LedgerError> { - let fragment = self.fragment_factory.stake_pool_retire(owners, stake_pool); + let fragment = + self.fragment_factory + .stake_pool_retire(test_ledger.date(), owners, stake_pool); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -198,9 +211,9 @@ impl Controller { owners: impl IntoIterator, test_ledger: &'a mut TestLedger, ) -> Result<(), LedgerError> { - let fragment = self - .fragment_factory - .stake_pool_update(owners, stake_pool, update); + let fragment = + self.fragment_factory + .stake_pool_update(test_ledger.date(), owners, stake_pool, update); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -271,7 +284,9 @@ impl Controller { .expect("cannot find proposal"); let payload = payload_producer(&vote_plan, proposal); let vote_cast = VoteCast::new(vote_plan.to_id(), index, payload); - let fragment = self.fragment_factory.vote_cast(owner, vote_cast); + let fragment = self + .fragment_factory + .vote_cast(test_ledger.date(), owner, vote_cast); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -283,9 +298,9 @@ impl Controller { ) -> Result<(), LedgerError> { let vote_plan: VotePlan = vote_plan_def.clone().into(); let encrypted_tally = EncryptedVoteTally::new(vote_plan.to_id()); - let fragment = self - .fragment_factory - .vote_encrypted_tally(owner, encrypted_tally); + let fragment = + self.fragment_factory + .vote_encrypted_tally(test_ledger.date(), owner, encrypted_tally); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -298,7 +313,9 @@ impl Controller { let vote_plan: VotePlan = vote_plan_def.clone().into(); let vote_tally = VoteTally::new_public(vote_plan.to_id()); - let fragment = self.fragment_factory.vote_tally(owner, vote_tally); + let fragment = self + .fragment_factory + .vote_tally(test_ledger.date(), owner, vote_tally); test_ledger.apply_fragment(&fragment, test_ledger.date()) } @@ -312,7 +329,9 @@ impl Controller { let vote_plan: VotePlan = vote_plan_def.clone().into(); let vote_tally = VoteTally::new_private(vote_plan.to_id(), decrypted_tally); - let fragment = self.fragment_factory.vote_tally(owner, vote_tally); + let fragment = self + .fragment_factory + .vote_tally(test_ledger.date(), owner, vote_tally); test_ledger.apply_fragment(&fragment, test_ledger.date()) } } diff --git a/chain-impl-mockchain/src/testing/scenario/fragment_factory.rs b/chain-impl-mockchain/src/testing/scenario/fragment_factory.rs index fd278176d..830d54109 100644 --- a/chain-impl-mockchain/src/testing/scenario/fragment_factory.rs +++ b/chain-impl-mockchain/src/testing/scenario/fragment_factory.rs @@ -3,6 +3,7 @@ use crate::{ certificate::{ Certificate, EncryptedVoteTally, PoolId, PoolUpdate, VoteCast, VotePlan, VoteTally, }, + date::BlockDate, fee::LinearFee, fragment::Fragment, key::Hash, @@ -51,32 +52,43 @@ impl FragmentFactory { .get_fragment() } - pub fn stake_pool_registration(&self, funder: &Wallet, stake_pool: &StakePool) -> Fragment { + pub fn stake_pool_registration( + &self, + date: BlockDate, + funder: &Wallet, + stake_pool: &StakePool, + ) -> Fragment { let cert = build_stake_pool_registration_cert(&stake_pool.info()); - self.transaction_with_cert(Some(funder), &cert) + self.transaction_with_cert(date, Some(funder), &cert) } - pub fn delegation(&self, from: &Wallet, stake_pool: &StakePool) -> Fragment { + pub fn delegation(&self, date: BlockDate, from: &Wallet, stake_pool: &StakePool) -> Fragment { let cert = build_stake_delegation_cert(&stake_pool.info(), &from.as_account_data()); - self.transaction_with_cert(Some(from), &cert) + self.transaction_with_cert(date, Some(from), &cert) } pub fn delegation_different_funder( &self, + date: BlockDate, funder: &Wallet, delegation: &Wallet, stake_pool: &StakePool, ) -> Fragment { let cert = build_stake_delegation_cert(&stake_pool.info(), &delegation.as_account_data()); - self.transaction_with_cert(Some(funder), &cert) + self.transaction_with_cert(date, Some(funder), &cert) } - pub fn delegation_remove(&self, from: &Wallet) -> Fragment { + pub fn delegation_remove(&self, date: BlockDate, from: &Wallet) -> Fragment { let cert = build_no_stake_delegation(); - self.transaction_with_cert(Some(from), &cert) + self.transaction_with_cert(date, Some(from), &cert) } - pub fn delegation_to_many(&self, from: &Wallet, distribution: &[(&StakePool, u8)]) -> Fragment { + pub fn delegation_to_many( + &self, + date: BlockDate, + from: &Wallet, + distribution: &[(&StakePool, u8)], + ) -> Fragment { let pools_ratio_sum: u8 = distribution.iter().map(|(_st, ratio)| *ratio as u8).sum(); let pools: Vec<(PoolId, u8)> = distribution .iter() @@ -86,25 +98,32 @@ impl FragmentFactory { let delegation_ratio = DelegationRatio::new(pools_ratio_sum, pools); let delegation_type = DelegationType::Ratio(delegation_ratio.unwrap()); let cert = build_owner_stake_delegation(delegation_type); - self.transaction_with_cert(Some(from), &cert) + self.transaction_with_cert(date, Some(from), &cert) } - pub fn owner_delegation(&self, from: &Wallet, stake_pool: &StakePool) -> Fragment { + pub fn owner_delegation( + &self, + date: BlockDate, + from: &Wallet, + stake_pool: &StakePool, + ) -> Fragment { let cert = build_owner_stake_full_delegation(stake_pool.id()); - self.transaction_with_cert(Some(from), &cert) + self.transaction_with_cert(date, Some(from), &cert) } pub fn stake_pool_retire<'a>( &self, + date: BlockDate, owners: impl IntoIterator, stake_pool: &StakePool, ) -> Fragment { let certificate = build_stake_pool_retirement_cert(stake_pool.id(), 0); - self.transaction_with_cert(owners, &certificate) + self.transaction_with_cert(date, owners, &certificate) } pub fn stake_pool_update<'a>( &self, + date: BlockDate, owners: impl IntoIterator, stake_pool: &StakePool, update: StakePool, @@ -115,34 +134,40 @@ impl FragmentFactory { new_pool_reg: update.info(), }; let certificate = build_stake_pool_update_cert(&pool_update); - self.transaction_with_cert(owners, &certificate) + self.transaction_with_cert(date, owners, &certificate) } - pub fn vote_plan(&self, owner: &Wallet, vote_plan: VotePlan) -> Fragment { - self.transaction_with_cert(Some(owner), &vote_plan.into()) + pub fn vote_plan(&self, date: BlockDate, owner: &Wallet, vote_plan: VotePlan) -> Fragment { + self.transaction_with_cert(date, Some(owner), &vote_plan.into()) } - pub fn vote_cast(&self, owner: &Wallet, vote_cast: VoteCast) -> Fragment { - self.transaction_with_cert(Some(owner), &vote_cast.into()) + pub fn vote_cast(&self, date: BlockDate, owner: &Wallet, vote_cast: VoteCast) -> Fragment { + self.transaction_with_cert(date, Some(owner), &vote_cast.into()) } pub fn vote_encrypted_tally( &self, + date: BlockDate, owner: &Wallet, encrypted_tally: EncryptedVoteTally, ) -> Fragment { - self.transaction_with_cert(Some(owner), &encrypted_tally.into()) + self.transaction_with_cert(date, Some(owner), &encrypted_tally.into()) } - pub fn vote_tally(&self, owner: &Wallet, vote_tally: VoteTally) -> Fragment { - self.transaction_with_cert(Some(owner), &vote_tally.into()) + pub fn vote_tally(&self, date: BlockDate, owner: &Wallet, vote_tally: VoteTally) -> Fragment { + self.transaction_with_cert(date, Some(owner), &vote_tally.into()) } fn transaction_with_cert<'a>( &self, + date: BlockDate, wallets: impl IntoIterator, certificate: &Certificate, ) -> Fragment { - TestTxCertBuilder::new(self.block0_hash, self.fee).make_transaction(wallets, certificate) + TestTxCertBuilder::new(self.block0_hash, self.fee).make_transaction( + date, + wallets, + certificate, + ) } } diff --git a/chain-impl-mockchain/src/transaction/builder.rs b/chain-impl-mockchain/src/transaction/builder.rs index 07c7449c0..b8e78f134 100644 --- a/chain-impl-mockchain/src/transaction/builder.rs +++ b/chain-impl-mockchain/src/transaction/builder.rs @@ -27,6 +27,7 @@ impl Clone for TxBuilderState { } pub enum SetPayload {} +pub struct SetValidity

(PhantomData

); pub struct SetIOs

(PhantomData

); pub struct SetWitnesses

(PhantomData

); pub struct SetAuthData(PhantomData

); @@ -68,18 +69,11 @@ impl TxBuilderState { fn current_pos(&self) -> usize { self.data.len() - FRAGMENT_OVERHEAD } - - // this is not exported to outside this module, as someone - // can set the validity after the witness, with would render - // the witness invalid, instead use set_validity when available - fn _set_validity(&mut self, valid_until: BlockDate) { - self.tstruct.valid_until = valid_until; - } } impl TxBuilderState { /// Set the payload of this transaction - pub fn set_payload(mut self, payload: &P) -> TxBuilderState> { + pub fn set_payload(mut self, payload: &P) -> TxBuilderState> { if P::HAS_DATA { self.data.extend_from_slice(payload.payload_data().as_ref()); } @@ -91,22 +85,28 @@ impl TxBuilderState { } } - pub fn set_nopayload(self) -> TxBuilderState> { + pub fn set_nopayload(self) -> TxBuilderState> { self.set_payload(&NoExtra) } +} - pub fn set_validity(mut self, valid_until: BlockDate) -> Self { - self._set_validity(valid_until); - self +impl

TxBuilderState> { + pub fn set_validity(mut self, valid_until: BlockDate) -> TxBuilderState> { + fn write_date(data: &mut Vec, date: BlockDate) { + data.extend_from_slice(&date.epoch.to_be_bytes()); + data.extend_from_slice(&date.slot_id.to_be_bytes()); + } + write_date(&mut self.data, valid_until); + self.tstruct.valid_until = valid_until; + TxBuilderState { + data: self.data, + tstruct: self.tstruct, + phantom: PhantomData, + } } } impl

TxBuilderState> { - pub fn set_validity(mut self, valid_until: BlockDate) -> Self { - self._set_validity(valid_until); - self - } - /// Set the inputs and outputs of this transaction /// /// This cannot accept more than 255 inputs, 255 outputs, since @@ -128,13 +128,6 @@ impl

TxBuilderState> { self.data.push(nb_inputs); self.data.push(nb_outputs); - fn write_date(data: &mut Vec, date: BlockDate) { - data.extend_from_slice(&date.epoch.to_be_bytes()); - data.extend_from_slice(&date.slot_id.to_be_bytes()); - } - - write_date(&mut self.data, self.tstruct.valid_until); - self.tstruct.nb_inputs = nb_inputs; self.tstruct.nb_outputs = nb_outputs; @@ -245,6 +238,7 @@ mod tests { let block0_hash = TestGen::hash(); let tx_builder = TxBuilder::new() .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[faucets[0].make_input(None)], &[reciever.make_output()]); let witness1 = make_witness( @@ -269,10 +263,13 @@ mod tests { ]; let reciever = AddressData::utxo(Discrimination::Test); let block0_hash = TestGen::hash(); - let tx_builder = TxBuilder::new().set_payload(&NoExtra).set_ios( - &[faucets[0].make_input(None), faucets[1].make_input(None)], - &[reciever.make_output(Value(2))], - ); + let tx_builder = TxBuilder::new() + .set_payload(&NoExtra) + .set_validity(BlockDate::first().next_epoch()) + .set_ios( + &[faucets[0].make_input(None), faucets[1].make_input(None)], + &[reciever.make_output(Value(2))], + ); let witness = make_witness( &block0_hash, diff --git a/chain-impl-mockchain/src/transaction/mod.rs b/chain-impl-mockchain/src/transaction/mod.rs index 2796788f9..562f354b2 100644 --- a/chain-impl-mockchain/src/transaction/mod.rs +++ b/chain-impl-mockchain/src/transaction/mod.rs @@ -16,7 +16,9 @@ use chain_core::mempack::{ReadBuf, ReadError, Readable}; use chain_core::property; // to remove.. -pub use builder::{SetAuthData, SetIOs, SetPayload, SetWitnesses, TxBuilder, TxBuilderState}; +pub use builder::{ + SetAuthData, SetIOs, SetPayload, SetValidity, SetWitnesses, TxBuilder, TxBuilderState, +}; pub use element::*; pub use input::*; pub use io::{Error, InputOutput, InputOutputBuilder, OutputPolicy}; diff --git a/chain-impl-mockchain/src/transaction/test.rs b/chain-impl-mockchain/src/transaction/test.rs index 36c759b9c..28aa65284 100644 --- a/chain-impl-mockchain/src/transaction/test.rs +++ b/chain-impl-mockchain/src/transaction/test.rs @@ -4,6 +4,7 @@ use super::{ }; #[cfg(test)] use crate::certificate::OwnerStakeDelegation; +use crate::date::BlockDate; use crate::key::{EitherEd25519SecretKey, SpendingSignature}; #[cfg(test)] use crate::testing::serialization::serialization_bijection_r; @@ -160,6 +161,7 @@ where TxBuilder::new() .set_payload(&payload) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&inputs, &outputs) .set_witnesses(&witnesses) .set_payload_auth(&payload_auth) diff --git a/chain-impl-mockchain/src/transaction/transaction.rs b/chain-impl-mockchain/src/transaction/transaction.rs index 2ee61fd45..008049257 100644 --- a/chain-impl-mockchain/src/transaction/transaction.rs +++ b/chain-impl-mockchain/src/transaction/transaction.rs @@ -258,6 +258,15 @@ fn get_spine(slice: &[u8]) -> Result(slice: &[u8]) -> Result Result { - let epoch = rb - .get_u32() - .map_err(|_| TransactionStructError::CannotReadDate)?; - let slot_id = rb - .get_u32() - .map_err(|_| TransactionStructError::CannotReadDate)?; - Ok(BlockDate { epoch, slot_id }) - } - - let valid_until = read_date(&mut rb)?; - let inputs_pos = rb.position(); rb.skip_bytes(nb_inputs as usize * INPUT_SIZE) .map_err(|_| TransactionStructError::InputsInvalid)?; @@ -361,6 +358,7 @@ impl

Transaction

{ { TxBuilder::new() .set_payload(payload) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[], &[]) .set_witnesses(&[]) .set_payload_auth(payload_auth) @@ -372,6 +370,7 @@ impl

Transaction

{ { TxBuilder::new() .set_payload(payload) + .set_validity(BlockDate::first().next_epoch()) .set_ios(&[], &[]) .set_witnesses(&[]) } diff --git a/chain-impl-mockchain/src/vote/manager.rs b/chain-impl-mockchain/src/vote/manager.rs index e03a641c0..5ec088162 100644 --- a/chain-impl-mockchain/src/vote/manager.rs +++ b/chain-impl-mockchain/src/vote/manager.rs @@ -1007,9 +1007,11 @@ mod tests { 3, ); + let vote_start = BlockDate::from_epoch_slot_id(1, 0); + let vote_end = BlockDate::from_epoch_slot_id(2, 0); let vote_plan = VotePlan::new( - BlockDate::from_epoch_slot_id(1, 0), - BlockDate::from_epoch_slot_id(2, 0), + vote_start, + vote_end, BlockDate::from_epoch_slot_id(3, 0), proposals, PayloadType::Public, @@ -1044,7 +1046,7 @@ mod tests { ) .unwrap(); - let tally_proof = get_tally_proof(&committee, vote_plan.to_id()); + let tally_proof = get_tally_proof(vote_start, &committee, vote_plan.to_id()); let block_date = BlockDate { epoch: 2, @@ -1076,9 +1078,11 @@ mod tests { let committee = Wallet::from_value(Value(100)); let proposals = VoteTestGen::proposals(3); + let vote_start = BlockDate::from_epoch_slot_id(1, 0); + let vote_end = BlockDate::from_epoch_slot_id(2, 0); let vote_plan = VotePlan::new( - BlockDate::from_epoch_slot_id(1, 0), - BlockDate::from_epoch_slot_id(2, 0), + vote_start, + vote_end, BlockDate::from_epoch_slot_id(3, 0), proposals, PayloadType::Public, @@ -1094,7 +1098,7 @@ mod tests { stake_controlled = stake_controlled.add_to(committee.public_key().into(), Stake(51)); stake_controlled = stake_controlled.add_unassigned(Stake(49)); - let tally_proof = get_tally_proof(&committee, vote_plan.to_id()); + let tally_proof = get_tally_proof(vote_start, &committee, vote_plan.to_id()); let block_date = BlockDate { epoch: 2, @@ -1130,9 +1134,11 @@ mod tests { let committee = Wallet::from_value(Value(100)); let proposals = VoteTestGen::proposals(3); + let vote_start = BlockDate::from_epoch_slot_id(1, 0); + let vote_end = BlockDate::from_epoch_slot_id(2, 0); let vote_plan = VotePlan::new( - BlockDate::from_epoch_slot_id(1, 0), - BlockDate::from_epoch_slot_id(2, 0), + vote_start, + vote_end, BlockDate::from_epoch_slot_id(3, 0), proposals, PayloadType::Public, @@ -1148,7 +1154,7 @@ mod tests { stake_controlled = stake_controlled.add_to(committee.public_key().into(), Stake(51)); stake_controlled = stake_controlled.add_unassigned(Stake(49)); - let tally_proof = get_tally_proof(&committee, vote_plan.to_id()); + let tally_proof = get_tally_proof(vote_start, &committee, vote_plan.to_id()); let invalid_block_date = BlockDate { epoch: 0, @@ -1196,7 +1202,7 @@ mod tests { let mut stake_controlled = StakeControl::new(); stake_controlled = stake_controlled.add_to(committee.public_key().into(), Stake(51)); - let tally_proof = get_tally_proof(&committee, vote_plan.to_id()); + let tally_proof = get_tally_proof(vote_plan.vote_start(), &committee, vote_plan.to_id()); let block_date = BlockDate { epoch: 2, @@ -1251,7 +1257,7 @@ mod tests { let mut stake_controlled = StakeControl::new(); stake_controlled = stake_controlled.add_to(committee.public_key().into(), Stake(51)); - let tally_proof = get_tally_proof(&committee, vote_plan.to_id()); + let tally_proof = get_tally_proof(vote_plan.vote_start(), &committee, vote_plan.to_id()); let block_date = BlockDate { epoch: 2, @@ -1274,10 +1280,10 @@ mod tests { ); } - fn get_tally_proof(wallet: &Wallet, id: VotePlanId) -> TallyProof { + fn get_tally_proof(date: BlockDate, wallet: &Wallet, id: VotePlanId) -> TallyProof { let certificate = build_vote_tally_cert(id); let fragment = TestTxCertBuilder::new(TestGen::hash(), LinearFee::new(0, 0, 0)) - .make_transaction(Some(wallet), &certificate); + .make_transaction(date, Some(wallet), &certificate); match fragment { Fragment::VoteTally(tx) => { From 6fd2202c92053a9e6dcf2b22401e16bf24d4e068 Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Thu, 1 Jul 2021 22:33:05 +0800 Subject: [PATCH 6/9] fix bench compilation error --- chain-impl-mockchain/benches/tally.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/chain-impl-mockchain/benches/tally.rs b/chain-impl-mockchain/benches/tally.rs index 2f6f162c2..19b04c36a 100644 --- a/chain-impl-mockchain/benches/tally.rs +++ b/chain-impl-mockchain/benches/tally.rs @@ -5,6 +5,7 @@ use chain_impl_mockchain::{ DecryptedPrivateTally, DecryptedPrivateTallyProposal, EncryptedVoteTally, VoteCast, VotePlan, VoteTally, }, + date::BlockDate, fee::LinearFee, header::BlockDate, testing::{ @@ -133,6 +134,7 @@ fn tally_benchmark( ); res.push(controller.fragment_factory().vote_cast( + BlockDate::first(), private_voter, VoteCast::new(vote_plan.to_id(), proposal_idx as u8, payload), )); @@ -171,9 +173,11 @@ fn tally_benchmark( let mut alice = controller.wallet(ALICE).unwrap(); let encrypted_tally = EncryptedVoteTally::new(vote_plan.to_id()); - let fragment = controller - .fragment_factory() - .vote_encrypted_tally(&alice, encrypted_tally); + let fragment = controller.fragment_factory().vote_encrypted_tally( + BlockDate::first(), + &alice, + encrypted_tally, + ); let parameters = ledger.parameters.clone(); let date = ledger.date(); @@ -264,9 +268,10 @@ fn tally_benchmark( let decrypted_tally = VoteTally::new_private(vote_plan.to_id(), DecryptedPrivateTally::new(shares)); - let fragment = controller - .fragment_factory() - .vote_tally(&alice, decrypted_tally); + let fragment = + controller + .fragment_factory() + .vote_tally(BlockDate::first(), &alice, decrypted_tally); c.bench_function(&format!("vote_tally_{}", benchmark_name), |b| { b.iter(|| { From e4dac782085e4f594a6898db2733f455ca9170b0 Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Thu, 1 Jul 2021 23:07:41 +0800 Subject: [PATCH 7/9] remove spurious import --- chain-impl-mockchain/benches/tally.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/chain-impl-mockchain/benches/tally.rs b/chain-impl-mockchain/benches/tally.rs index 19b04c36a..a042b21b6 100644 --- a/chain-impl-mockchain/benches/tally.rs +++ b/chain-impl-mockchain/benches/tally.rs @@ -5,7 +5,6 @@ use chain_impl_mockchain::{ DecryptedPrivateTally, DecryptedPrivateTallyProposal, EncryptedVoteTally, VoteCast, VotePlan, VoteTally, }, - date::BlockDate, fee::LinearFee, header::BlockDate, testing::{ From 059fb9aa4f5cc5cadefea25a606860a7270317ea Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Tue, 20 Jul 2021 18:24:50 +0800 Subject: [PATCH 8/9] fix order of validity and the removal of start --- chain-impl-mockchain/doc/format.abnf | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/chain-impl-mockchain/doc/format.abnf b/chain-impl-mockchain/doc/format.abnf index e0e25320f..53ed4dc74 100644 --- a/chain-impl-mockchain/doc/format.abnf +++ b/chain-impl-mockchain/doc/format.abnf @@ -134,10 +134,9 @@ UPDATE-VOTE = TODO ; note: IOW stand for Inputs-Outputs-Witnesses ; #################### -IOW = SIZE-ELEMENT-8BIT ; number of inputs +IOW = BLOCK-DATE ; end validity of this IOW + SIZE-ELEMENT-8BIT ; number of inputs SIZE-ELEMENT-8BIT ; number of outputs - BLOCK-DATE ; start validity of this IOW - BLOCK-DATE ; end validity of this IOW *INPUT ; as many as indicated in the number of inputs *OUTPUT ; sa many as indicated in the number of outputs *WITNESS ; as many as indicated in the number of inputs From fc7e2e58cdb286d4f86ad7f03d252795c9b03881 Mon Sep 17 00:00:00 2001 From: Mikhail Zabaluev Date: Tue, 3 Aug 2021 17:29:20 +0300 Subject: [PATCH 9/9] Harmonized API naming on transaction expiry All names now have "expiry", set_validity had too generic meaning. --- chain-impl-mockchain/src/certificate/pool.rs | 2 +- chain-impl-mockchain/src/config.rs | 17 ++++++------- chain-impl-mockchain/src/ledger/check.rs | 2 +- chain-impl-mockchain/src/ledger/ledger.rs | 24 +++++++++---------- chain-impl-mockchain/src/setting.rs | 12 +++++----- .../src/testing/builders/initial_builder.rs | 10 ++++---- .../src/testing/builders/tx_builder.rs | 6 ++--- .../src/testing/builders/tx_cert_builder.rs | 4 +++- chain-impl-mockchain/src/testing/ledger.rs | 6 ++--- .../src/transaction/builder.rs | 6 ++--- chain-impl-mockchain/src/transaction/test.rs | 2 +- .../src/transaction/transaction.rs | 4 ++-- 12 files changed, 49 insertions(+), 46 deletions(-) diff --git a/chain-impl-mockchain/src/certificate/pool.rs b/chain-impl-mockchain/src/certificate/pool.rs index 8ea32f4d1..e1b7cce88 100644 --- a/chain-impl-mockchain/src/certificate/pool.rs +++ b/chain-impl-mockchain/src/certificate/pool.rs @@ -740,7 +740,7 @@ mod tests { let builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&pool_owner_with_sign.inputs(), &[]); let auth_data_hash = builder.get_auth_data_for_witness().hash(); let builder = builder diff --git a/chain-impl-mockchain/src/config.rs b/chain-impl-mockchain/src/config.rs index 7d6019696..c760f173f 100644 --- a/chain-impl-mockchain/src/config.rs +++ b/chain-impl-mockchain/src/config.rs @@ -82,7 +82,7 @@ pub enum ConfigParam { AddCommitteeId(CommitteeId), RemoveCommitteeId(CommitteeId), PerVoteCertificateFees(PerVoteCertificateFee), - TransactionMaximumExpiryEpochs(u8), + TransactionMaxExpiryEpochs(u8), } #[derive(Clone, Debug, Eq, PartialEq)] @@ -155,7 +155,7 @@ pub enum Tag { #[strum(to_string = "per-vote-certificate-fees")] PerVoteCertificateFees = 28, #[strum(to_string = "transaction-maximum-expiry-epochs")] - TransactionMaximumExpiryEpochs = 29, + TransactionMaxExpiryEpochs = 29, } impl Tag { @@ -186,7 +186,7 @@ impl Tag { 26 => Some(Tag::AddCommitteeId), 27 => Some(Tag::RemoveCommitteeId), 28 => Some(Tag::PerVoteCertificateFees), - 29 => Some(Tag::TransactionMaximumExpiryEpochs), + 29 => Some(Tag::TransactionMaxExpiryEpochs), _ => None, } } @@ -222,7 +222,7 @@ impl<'a> From<&'a ConfigParam> for Tag { ConfigParam::AddCommitteeId(..) => Tag::AddCommitteeId, ConfigParam::RemoveCommitteeId(..) => Tag::RemoveCommitteeId, ConfigParam::PerVoteCertificateFees(..) => Tag::PerVoteCertificateFees, - ConfigParam::TransactionMaximumExpiryEpochs(..) => Tag::TransactionMaximumExpiryEpochs, + ConfigParam::TransactionMaxExpiryEpochs(..) => Tag::TransactionMaxExpiryEpochs, } } } @@ -303,8 +303,9 @@ impl Readable for ConfigParam { Tag::PerVoteCertificateFees => { ConfigParamVariant::from_payload(bytes).map(ConfigParam::PerVoteCertificateFees) } - Tag::TransactionMaximumExpiryEpochs => ConfigParamVariant::from_payload(bytes) - .map(ConfigParam::TransactionMaximumExpiryEpochs), + Tag::TransactionMaxExpiryEpochs => { + ConfigParamVariant::from_payload(bytes).map(ConfigParam::TransactionMaxExpiryEpochs) + } } .map_err(Into::into) } @@ -341,7 +342,7 @@ impl property::Serialize for ConfigParam { ConfigParam::AddCommitteeId(data) => data.to_payload(), ConfigParam::RemoveCommitteeId(data) => data.to_payload(), ConfigParam::PerVoteCertificateFees(data) => data.to_payload(), - ConfigParam::TransactionMaximumExpiryEpochs(data) => data.to_payload(), + ConfigParam::TransactionMaxExpiryEpochs(data) => data.to_payload(), }; let taglen = TagLen::new(tag, bytes.len()).ok_or_else(|| { io::Error::new( @@ -896,7 +897,7 @@ mod test { 26 => ConfigParam::AddCommitteeId(Arbitrary::arbitrary(g)), 27 => ConfigParam::RemoveCommitteeId(Arbitrary::arbitrary(g)), 28 => ConfigParam::PerCertificateFees(Arbitrary::arbitrary(g)), - 29 => ConfigParam::TransactionMaximumExpiryEpochs(Arbitrary::arbitrary(g)), + 29 => ConfigParam::TransactionMaxExpiryEpochs(Arbitrary::arbitrary(g)), _ => unreachable!(), } } diff --git a/chain-impl-mockchain/src/ledger/check.rs b/chain-impl-mockchain/src/ledger/check.rs index 60ee400d7..3118a1bd7 100644 --- a/chain-impl-mockchain/src/ledger/check.rs +++ b/chain-impl-mockchain/src/ledger/check.rs @@ -183,7 +183,7 @@ pub(super) fn valid_transaction_date

( date.epoch < valid_until .epoch - .saturating_sub(settings.transaction_maximum_expiry_epochs.into()), + .saturating_sub(settings.transaction_max_expiry_epochs.into()), TxVerifyError::TransactionValidForTooLong )?; // if current date is passed the validity until, the transaction is expired diff --git a/chain-impl-mockchain/src/ledger/ledger.rs b/chain-impl-mockchain/src/ledger/ledger.rs index a148dc5ec..b43574f58 100644 --- a/chain-impl-mockchain/src/ledger/ledger.rs +++ b/chain-impl-mockchain/src/ledger/ledger.rs @@ -1869,7 +1869,7 @@ mod tests { TestTx::new( TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[], &[]) .set_witnesses(&[]) .set_payload_auth(&()), @@ -1880,7 +1880,7 @@ mod tests { TestTx::new( TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(inputs, outputs) .set_witnesses(&[]) .set_payload_auth(&()), @@ -1894,7 +1894,7 @@ mod tests { ) -> TestTx { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[input], &[]); let witness = make_witness( @@ -2459,7 +2459,7 @@ mod tests { let builder_tx = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&inputs, &[reciever.make_output(Value(100))]); let witnesses: Vec = faucets @@ -2551,7 +2551,7 @@ mod tests { let inputs: Vec = faucets.iter().map(|x| x.make_input(None)).collect(); let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&inputs, &[reciever.make_output(Value(2))]); let witness = make_witness( @@ -2613,7 +2613,7 @@ mod tests { let block0_hash = test_ledger.block0_hash; let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios( &input_addresses.make_inputs(&test_ledger), &output_addresses.make_outputs(), @@ -2664,7 +2664,7 @@ mod tests { let inputs = [faucets[0].make_input(None), faucets[1].make_input(None)]; let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&inputs, &[reciever.make_output(Value(2))]); let auth_data = tx_builder.get_auth_data_for_witness().hash(); let witnesses = make_witnesses( @@ -2743,7 +2743,7 @@ mod tests { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[faucet.make_input(utxo)], &[reciever.make_output()]); let witness = Witness::new_account( @@ -2772,7 +2772,7 @@ mod tests { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()); + .set_expiry_date(BlockDate::first().next_epoch()); let tx_builder = tx_builder.set_ios(&[faucet.make_input(None)], &[reciever.make_output()]); let random_bytes = TestGen::bytes(); @@ -2800,7 +2800,7 @@ mod tests { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[faucet.make_input(None)], &[reciever.make_output()]); let witness = make_witness( @@ -2830,7 +2830,7 @@ mod tests { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[faucet.make_input(None)], &[reciever.make_output()]); let witness = make_witness( @@ -2859,7 +2859,7 @@ mod tests { let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[faucet.make_input(None)], &[reciever.make_output()]); let witness = make_witness( diff --git a/chain-impl-mockchain/src/setting.rs b/chain-impl-mockchain/src/setting.rs index 5ddd144a2..8e96eaf69 100644 --- a/chain-impl-mockchain/src/setting.rs +++ b/chain-impl-mockchain/src/setting.rs @@ -41,7 +41,7 @@ pub struct Settings { pub rewards_limit: rewards::Limit, pub pool_participation_capping: Option<(NonZeroU32, NonZeroU32)>, pub committees: Arc>, - pub transaction_maximum_expiry_epochs: u8, + pub transaction_max_expiry_epochs: u8, } #[derive(Clone, Debug, Eq, PartialEq)] @@ -128,7 +128,7 @@ impl Settings { rewards_limit: rewards::Limit::None, pool_participation_capping: None, committees: Arc::new(Box::new([])), - transaction_maximum_expiry_epochs: 1, + transaction_max_expiry_epochs: 1, } } @@ -239,8 +239,8 @@ impl Settings { .into(), ); } - ConfigParam::TransactionMaximumExpiryEpochs(max_expiry_epochs) => { - new_state.transaction_maximum_expiry_epochs = *max_expiry_epochs; + ConfigParam::TransactionMaxExpiryEpochs(max_expiry_epochs) => { + new_state.transaction_max_expiry_epochs = *max_expiry_epochs; } } } @@ -274,8 +274,8 @@ impl Settings { } params.push(ConfigParam::LinearFee(self.linear_fees)); params.push(ConfigParam::ProposalExpiration(self.proposal_expiration)); - params.push(ConfigParam::TransactionMaximumExpiryEpochs( - self.transaction_maximum_expiry_epochs, + params.push(ConfigParam::TransactionMaxExpiryEpochs( + self.transaction_max_expiry_epochs, )); match &self.reward_params { diff --git a/chain-impl-mockchain/src/testing/builders/initial_builder.rs b/chain-impl-mockchain/src/testing/builders/initial_builder.rs index e9b7aaef2..1f6267366 100644 --- a/chain-impl-mockchain/src/testing/builders/initial_builder.rs +++ b/chain-impl-mockchain/src/testing/builders/initial_builder.rs @@ -75,7 +75,7 @@ pub fn create_initial_vote_tally(vote_tally: &VoteTally, owners: &[Wallet]) -> F pub fn create_initial_transaction(wallet: &Wallet) -> Fragment { let tx = TxBuilder::new() .set_nopayload() - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[], &[wallet.make_output()]) .set_witnesses_unchecked(&[]) .set_payload_auth(&()); @@ -99,7 +99,7 @@ fn set_initial_ios( outputs: &[OutputAddress], ) -> TxBuilderState> { builder - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(inputs, outputs) .set_witnesses_unchecked(&[]) } @@ -202,7 +202,7 @@ impl InitialFaultTolerantTxBuilder { let output = self.reciever.make_output_with_value(Value(1)); let tx = TxBuilder::new() .set_nopayload() - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[input], &[output]) .set_witnesses_unchecked(&[]) .set_payload_auth(&()); @@ -213,7 +213,7 @@ impl InitialFaultTolerantTxBuilder { let input = self.sender.make_input_with_value(Value(1)); let tx = TxBuilder::new() .set_nopayload() - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[input], &[]) .set_witnesses_unchecked(&[]) .set_payload_auth(&()); @@ -223,7 +223,7 @@ impl InitialFaultTolerantTxBuilder { pub fn transaction_with_witness_only(&self) -> Fragment { let tx = TxBuilder::new() .set_nopayload() - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[], &[]); let witness = self .sender diff --git a/chain-impl-mockchain/src/testing/builders/tx_builder.rs b/chain-impl-mockchain/src/testing/builders/tx_builder.rs index 465410a6b..5ce8efa74 100644 --- a/chain-impl-mockchain/src/testing/builders/tx_builder.rs +++ b/chain-impl-mockchain/src/testing/builders/tx_builder.rs @@ -93,7 +93,7 @@ impl TestTxBuilder { }]; let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&inputs, &outputs); let witness = @@ -128,7 +128,7 @@ impl TestTxBuilder { )]; let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(validity.unwrap_or(BlockDate::first())) + .set_expiry_date(validity.unwrap_or(BlockDate::first())) .set_ios(&inputs, &destination); let witness = @@ -198,7 +198,7 @@ impl TestTxBuilder { .collect(); let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&inputs, &destinations); let witnesses: Vec = sources diff --git a/chain-impl-mockchain/src/testing/builders/tx_cert_builder.rs b/chain-impl-mockchain/src/testing/builders/tx_cert_builder.rs index 21a5872af..94ae5fc05 100644 --- a/chain-impl-mockchain/src/testing/builders/tx_cert_builder.rs +++ b/chain-impl-mockchain/src/testing/builders/tx_cert_builder.rs @@ -55,7 +55,9 @@ impl TestTxCertBuilder { slot_id: current_date.slot_id, }; //utxo not supported yet - let builder = builder.set_validity(valid_until).set_ios(inputs, outputs); + let builder = builder + .set_expiry_date(valid_until) + .set_ios(inputs, outputs); let witnesses: Vec = { if should_make_witness { diff --git a/chain-impl-mockchain/src/testing/ledger.rs b/chain-impl-mockchain/src/testing/ledger.rs index 5654a474a..c8e573520 100644 --- a/chain-impl-mockchain/src/testing/ledger.rs +++ b/chain-impl-mockchain/src/testing/ledger.rs @@ -339,7 +339,7 @@ impl LedgerBuilder { pub fn prefill_output(self, output: Output

) -> Self { let tx = TxBuilder::new() .set_nopayload() - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[], &[output]) .set_witnesses(&[]) .set_payload_auth(&()); @@ -350,7 +350,7 @@ impl LedgerBuilder { for outputs_chunk in outputs.chunks(CHECK_TX_MAXIMUM_INPUTS.into()) { let tx = TxBuilder::new() .set_nopayload() - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[], outputs_chunk) .set_witnesses(&[]) .set_payload_auth(&()); @@ -420,7 +420,7 @@ impl LedgerBuilder { { let tx = TxBuilder::new() .set_nopayload() - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[], &group) .set_witnesses(&[]) .set_payload_auth(&()); diff --git a/chain-impl-mockchain/src/transaction/builder.rs b/chain-impl-mockchain/src/transaction/builder.rs index b8e78f134..97d976134 100644 --- a/chain-impl-mockchain/src/transaction/builder.rs +++ b/chain-impl-mockchain/src/transaction/builder.rs @@ -91,7 +91,7 @@ impl TxBuilderState { } impl

TxBuilderState> { - pub fn set_validity(mut self, valid_until: BlockDate) -> TxBuilderState> { + pub fn set_expiry_date(mut self, valid_until: BlockDate) -> TxBuilderState> { fn write_date(data: &mut Vec, date: BlockDate) { data.extend_from_slice(&date.epoch.to_be_bytes()); data.extend_from_slice(&date.slot_id.to_be_bytes()); @@ -238,7 +238,7 @@ mod tests { let block0_hash = TestGen::hash(); let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[faucets[0].make_input(None)], &[reciever.make_output()]); let witness1 = make_witness( @@ -265,7 +265,7 @@ mod tests { let block0_hash = TestGen::hash(); let tx_builder = TxBuilder::new() .set_payload(&NoExtra) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios( &[faucets[0].make_input(None), faucets[1].make_input(None)], &[reciever.make_output(Value(2))], diff --git a/chain-impl-mockchain/src/transaction/test.rs b/chain-impl-mockchain/src/transaction/test.rs index 28aa65284..b941636cf 100644 --- a/chain-impl-mockchain/src/transaction/test.rs +++ b/chain-impl-mockchain/src/transaction/test.rs @@ -161,7 +161,7 @@ where TxBuilder::new() .set_payload(&payload) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&inputs, &outputs) .set_witnesses(&witnesses) .set_payload_auth(&payload_auth) diff --git a/chain-impl-mockchain/src/transaction/transaction.rs b/chain-impl-mockchain/src/transaction/transaction.rs index 008049257..447a3d135 100644 --- a/chain-impl-mockchain/src/transaction/transaction.rs +++ b/chain-impl-mockchain/src/transaction/transaction.rs @@ -358,7 +358,7 @@ impl

Transaction

{ { TxBuilder::new() .set_payload(payload) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[], &[]) .set_witnesses(&[]) .set_payload_auth(payload_auth) @@ -370,7 +370,7 @@ impl

Transaction

{ { TxBuilder::new() .set_payload(payload) - .set_validity(BlockDate::first().next_epoch()) + .set_expiry_date(BlockDate::first().next_epoch()) .set_ios(&[], &[]) .set_witnesses(&[]) }