mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
validator: properly test producer txs
This commit is contained in:
@@ -61,7 +61,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
|
||||
// Now Alice can stake her owncoin
|
||||
let alice_staked_oc =
|
||||
th.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_oc, 489).await?;
|
||||
th.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_oc, 21).await?;
|
||||
|
||||
// We progress after grace period
|
||||
current_slot += (calculate_grace_period() * EPOCH_LENGTH) + EPOCH_LENGTH;
|
||||
@@ -98,7 +98,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
|
||||
// Now Alice can stake her unstaked owncoin again to try some mallicious cases
|
||||
let alice_staked_oc = th
|
||||
.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_unstaked_oc, 15)
|
||||
.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_unstaked_oc, 121)
|
||||
.await?;
|
||||
|
||||
// Alice tries to stake her coin again
|
||||
@@ -106,7 +106,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
info!(target: "consensus", "[Malicious] Checking staking coin again");
|
||||
info!(target: "consensus", "[Malicious] ===========================");
|
||||
let (stake_tx, _, _) = th
|
||||
.stake(&Holder::Alice, current_slot, &alice_unstaked_oc, pallas::Base::from(15))
|
||||
.stake(&Holder::Alice, current_slot, &alice_unstaked_oc, pallas::Base::from(121))
|
||||
.await?;
|
||||
th.execute_erroneous_txs(
|
||||
TxAction::ConsensusStake,
|
||||
@@ -126,14 +126,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
info!(target: "consensus", "[Malicious] Checking proposal before grace period");
|
||||
info!(target: "consensus", "[Malicious] =====================================");
|
||||
let (proposal_tx, _, _, _) = th.proposal(&Holder::Alice, slot, &alice_staked_oc).await?;
|
||||
th.execute_erroneous_txs(
|
||||
TxAction::ConsensusProposal,
|
||||
&Holder::Alice,
|
||||
&[proposal_tx],
|
||||
current_slot,
|
||||
1,
|
||||
)
|
||||
.await?;
|
||||
th.execute_erroneous_proposal_tx(&Holder::Alice, &proposal_tx, current_slot).await?;
|
||||
|
||||
// or be able to unstake the coin
|
||||
info!(target: "consensus", "[Malicious] ======================================");
|
||||
@@ -195,7 +188,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
|
||||
// Now Alice can stake her unstaked owncoin again
|
||||
let alice_staked_oc = th
|
||||
.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_unstaked_oc, 65)
|
||||
.execute_stake(&HOLDERS, &Holder::Alice, current_slot, &alice_unstaked_oc, 181)
|
||||
.await?;
|
||||
|
||||
// We progress after grace period
|
||||
@@ -214,14 +207,7 @@ fn consensus_contract_stake_unstake() -> Result<()> {
|
||||
info!(target: "consensus", "[Malicious] Checking using unstaked coin in proposal");
|
||||
info!(target: "consensus", "[Malicious] ========================================");
|
||||
let (proposal_tx, _, _, _) = th.proposal(&Holder::Alice, slot, &alice_staked_oc).await?;
|
||||
th.execute_erroneous_txs(
|
||||
TxAction::ConsensusProposal,
|
||||
&Holder::Alice,
|
||||
&[proposal_tx],
|
||||
current_slot,
|
||||
1,
|
||||
)
|
||||
.await?;
|
||||
th.execute_erroneous_proposal_tx(&Holder::Alice, &proposal_tx, current_slot).await?;
|
||||
|
||||
// We progress after grace period
|
||||
current_slot += (calculate_grace_period() * EPOCH_LENGTH) + EPOCH_LENGTH;
|
||||
|
||||
@@ -62,7 +62,7 @@ impl TestHarness {
|
||||
pallas::Scalar::random(&mut OsRng),
|
||||
pallas::Base::random(&mut OsRng),
|
||||
pallas::Scalar::random(&mut OsRng),
|
||||
pallas::Base::from(138),
|
||||
pallas::Base::from(4),
|
||||
)?;
|
||||
|
||||
let (genesis_stake_params, genesis_stake_proofs) =
|
||||
|
||||
@@ -111,7 +111,7 @@ impl TestHarness {
|
||||
|
||||
let timer = Instant::now();
|
||||
|
||||
wallet.validator.read().await.add_transactions(&[tx.clone()], slot, true).await?;
|
||||
wallet.validator.read().await.add_test_producer_transaction(tx, slot, true).await?;
|
||||
wallet.consensus_staked_merkle_tree.append(MerkleNode::from(params.output.coin.inner()));
|
||||
tx_action_benchmark.verify_times.push(timer.elapsed());
|
||||
|
||||
@@ -138,9 +138,9 @@ impl TestHarness {
|
||||
) = self.proposal(holder, slot, staked_oc).await?;
|
||||
|
||||
for h in holders {
|
||||
info!(target: "consensus", "[{h:?}] ===========================");
|
||||
info!(target: "consensus", "[{h:?}] ================================");
|
||||
info!(target: "consensus", "[{h:?}] Executing {holder:?} proposal tx");
|
||||
info!(target: "consensus", "[{h:?}] ===========================");
|
||||
info!(target: "consensus", "[{h:?}] ================================");
|
||||
self.execute_proposal_tx(h, &proposal_tx, &proposal_params, current_slot).await?;
|
||||
}
|
||||
|
||||
@@ -158,4 +158,27 @@ impl TestHarness {
|
||||
|
||||
Ok(rewarded_staked_oc)
|
||||
}
|
||||
|
||||
pub async fn execute_erroneous_proposal_tx(
|
||||
&mut self,
|
||||
holder: &Holder,
|
||||
tx: &Transaction,
|
||||
slot: u64,
|
||||
) -> Result<()> {
|
||||
let wallet = self.holders.get_mut(holder).unwrap();
|
||||
let tx_action_benchmark =
|
||||
self.tx_action_benchmarks.get_mut(&TxAction::ConsensusProposal).unwrap();
|
||||
let timer = Instant::now();
|
||||
|
||||
assert!(wallet
|
||||
.validator
|
||||
.read()
|
||||
.await
|
||||
.add_test_producer_transaction(tx, slot, true)
|
||||
.await
|
||||
.is_err());
|
||||
tx_action_benchmark.verify_times.push(timer.elapsed());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,9 @@ pub mod pid;
|
||||
|
||||
/// Verification functions
|
||||
pub mod verification;
|
||||
use verification::{verify_block, verify_genesis_block, verify_transactions};
|
||||
use verification::{
|
||||
verify_block, verify_genesis_block, verify_producer_transaction, verify_transactions,
|
||||
};
|
||||
|
||||
/// Validation functions
|
||||
pub mod validation;
|
||||
@@ -393,6 +395,54 @@ impl Validator {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validate a producer `Transaction` and apply it if valid.
|
||||
/// In case the transactions fail, ir will be returned to the caller.
|
||||
/// The function takes a boolean called `write` which tells it to actually write
|
||||
/// the state transitions to the database.
|
||||
/// This should be only used for test purposes.
|
||||
pub async fn add_test_producer_transaction(
|
||||
&self,
|
||||
tx: &Transaction,
|
||||
verifying_slot: u64,
|
||||
write: bool,
|
||||
) -> Result<()> {
|
||||
debug!(target: "validator::add_test_producer_transaction", "Instantiating BlockchainOverlay");
|
||||
let overlay = BlockchainOverlay::new(&self.blockchain)?;
|
||||
|
||||
// Generate a time keeper using transaction verifying slot
|
||||
let time_keeper = TimeKeeper::new(
|
||||
self.consensus.time_keeper.genesis_ts,
|
||||
self.consensus.time_keeper.epoch_length,
|
||||
self.consensus.time_keeper.slot_time,
|
||||
verifying_slot,
|
||||
);
|
||||
|
||||
// Verify transaction
|
||||
let mut erroneous_txs = vec![];
|
||||
if let Err(e) = verify_producer_transaction(&overlay, &time_keeper, tx).await {
|
||||
warn!(target: "validator::add_test_producer_transaction", "Transaction verification failed: {}", e);
|
||||
erroneous_txs.push(tx.clone());
|
||||
}
|
||||
|
||||
let lock = overlay.lock().unwrap();
|
||||
let mut overlay = lock.overlay.lock().unwrap();
|
||||
if !erroneous_txs.is_empty() {
|
||||
warn!(target: "validator::add_test_producer_transaction", "Erroneous transactions found in set");
|
||||
overlay.purge_new_trees()?;
|
||||
return Err(TxVerifyFailed::ErroneousTxs(erroneous_txs).into())
|
||||
}
|
||||
|
||||
if !write {
|
||||
debug!(target: "validator::add_test_producer_transaction", "Skipping apply of state updates because write=false");
|
||||
overlay.purge_new_trees()?;
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
debug!(target: "validator::add_test_producer_transaction", "Applying overlay changes");
|
||||
overlay.apply()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Retrieve all existing blocks and try to apply them
|
||||
/// to an in memory overlay to verify their correctness.
|
||||
/// Be careful as this will try to load everything in memory.
|
||||
|
||||
Reference in New Issue
Block a user