|
@@ -21,7 +21,9 @@ use std::slice;
|
|
|
use darkfi::{
|
|
use darkfi::{
|
|
|
blockchain::{BlockInfo, BlockchainOverlay, Header},
|
|
blockchain::{BlockInfo, BlockchainOverlay, Header},
|
|
|
tx::{ContractCallLeaf, Transaction, TransactionBuilder},
|
|
tx::{ContractCallLeaf, Transaction, TransactionBuilder},
|
|
|
- validator::verification::apply_producer_transaction,
|
|
|
|
|
|
|
+ validator::verification::{
|
|
|
|
|
+ apply_producer_transaction, verify_producer_transaction, verify_transactions,
|
|
|
|
|
+ },
|
|
|
Result,
|
|
Result,
|
|
|
};
|
|
};
|
|
|
use darkfi_money_contract::{
|
|
use darkfi_money_contract::{
|
|
@@ -157,4 +159,70 @@ impl TestHarness {
|
|
|
|
|
|
|
|
Ok(found_owncoins)
|
|
Ok(found_owncoins)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /// Generate and add a block containing non-producer transactions.
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// The caller must provide the block's accumulated miner-claimable fees.
|
|
|
|
|
+ /// Returns any found miner reward [`OwnCoin`]s.
|
|
|
|
|
+ pub async fn generate_block_with_txs(
|
|
|
|
|
+ &mut self,
|
|
|
|
|
+ miner: &Holder,
|
|
|
|
|
+ holders: &[Holder],
|
|
|
|
|
+ txs: Vec<Transaction>,
|
|
|
|
|
+ fees: u64,
|
|
|
|
|
+ ) -> Result<Vec<OwnCoin>> {
|
|
|
|
|
+ info!("Building PoWReward transaction for {miner:?}");
|
|
|
|
|
+ let (producer_tx, params) = self.pow_reward(miner, None, None, Some(fees)).await?;
|
|
|
|
|
+
|
|
|
|
|
+ let wallet = self.wallet(miner);
|
|
|
|
|
+ let validator = wallet.validator.read().await;
|
|
|
|
|
+ let previous = validator.blockchain.last_block()?;
|
|
|
|
|
+ let timestamp = previous.header.timestamp.checked_add(1.into())?;
|
|
|
|
|
+
|
|
|
|
|
+ let header = Header::new(
|
|
|
|
|
+ previous.hash(),
|
|
|
|
|
+ previous.header.height + 1,
|
|
|
|
|
+ previous.header.nonce,
|
|
|
|
|
+ timestamp,
|
|
|
|
|
+ );
|
|
|
|
|
+ let mut block = BlockInfo::new_empty(header);
|
|
|
|
|
+
|
|
|
|
|
+ block.append_txs(txs);
|
|
|
|
|
+ block.append_txs(vec![producer_tx]);
|
|
|
|
|
+
|
|
|
|
|
+ let overlay = BlockchainOverlay::new(&validator.blockchain)?;
|
|
|
|
|
+ let mut tree = MerkleTree::new(1);
|
|
|
|
|
+ let non_producer_txs = &block.txs[..block.txs.len() - 1];
|
|
|
|
|
+ verify_transactions(
|
|
|
|
|
+ &overlay,
|
|
|
|
|
+ block.header.height,
|
|
|
|
|
+ validator.consensus.module.target,
|
|
|
|
|
+ non_producer_txs,
|
|
|
|
|
+ &mut tree,
|
|
|
|
|
+ validator.verify_fees,
|
|
|
|
|
+ )
|
|
|
|
|
+ .await?;
|
|
|
|
|
+ verify_producer_transaction(
|
|
|
|
|
+ &overlay,
|
|
|
|
|
+ block.header.height,
|
|
|
|
|
+ validator.consensus.module.target,
|
|
|
|
|
+ block.txs.last().unwrap(),
|
|
|
|
|
+ &mut tree,
|
|
|
|
|
+ )
|
|
|
|
|
+ .await?;
|
|
|
|
|
+ drop(validator);
|
|
|
|
|
+
|
|
|
|
|
+ let diff = overlay.lock().unwrap().overlay.lock().unwrap().diff(&[])?;
|
|
|
|
|
+ block.header.state_root = overlay.lock().unwrap().contracts.update_state_monotree(&diff)?;
|
|
|
|
|
+ block.sign(&wallet.keypair.secret);
|
|
|
|
|
+
|
|
|
|
|
+ let mut found_owncoins = vec![];
|
|
|
|
|
+ for holder in holders {
|
|
|
|
|
+ let wallet = self.wallet_mut(holder);
|
|
|
|
|
+ wallet.validator.write().await.add_test_blocks(&[block.clone()]).await?;
|
|
|
|
|
+ found_owncoins.extend(wallet.process_outputs(slice::from_ref(¶ms.output), holder));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Ok(found_owncoins)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|