mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -05:00
contract/test-harness: Add a generate_block() function.
This is supposed to be used whenever we want a Holder to produce a block and receive the mining reward. As part of the integration test, it will test PoWReward functionality.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@
|
||||
*.wasm
|
||||
*.zk.bin
|
||||
|
||||
witness.json
|
||||
*_circuit_layout.png
|
||||
|
||||
/bin/zkas/zkas
|
||||
|
||||
@@ -61,7 +61,7 @@ impl TokenFreezeCallBuilder {
|
||||
let token_id = self.token_attrs.to_token_id();
|
||||
|
||||
let public_inputs = vec![mint_pubkey.x(), mint_pubkey.y(), token_id.inner()];
|
||||
darkfi::zk::export_witness_json("witness.json", &prover_witnesses, &public_inputs);
|
||||
//darkfi::zk::export_witness_json("witness.json", &prover_witnesses, &public_inputs);
|
||||
|
||||
let circuit = ZkCircuit::new(prover_witnesses, &self.freeze_zkbin);
|
||||
let proof = Proof::create(&self.freeze_pk, &[circuit], &public_inputs, &mut OsRng)?;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
use darkfi::Result;
|
||||
use darkfi_contract_test_harness::{init_logger, Holder, TestHarness};
|
||||
use darkfi_sdk::blockchain::expected_reward;
|
||||
use log::info;
|
||||
|
||||
#[test]
|
||||
@@ -32,50 +31,12 @@ fn money_integration() -> Result<()> {
|
||||
// Initialize harness
|
||||
let mut th = TestHarness::new(&HOLDERS, true).await?;
|
||||
|
||||
// Generate a new block mined by Alice
|
||||
th.generate_block(&Holder::Alice, &HOLDERS).await?;
|
||||
|
||||
// Block height to verify against
|
||||
let current_block_height = 1;
|
||||
|
||||
// Drop some money to Alice
|
||||
info!("[Alice] Building block proposal");
|
||||
let (alice_proposal_tx, alice_proposal_params) =
|
||||
th.pow_reward(&Holder::Alice, None, None).await?;
|
||||
|
||||
for holder in HOLDERS {
|
||||
info!("[{holder:?}] Executing Alice's block proposal");
|
||||
th.execute_pow_reward_tx(
|
||||
&holder,
|
||||
&alice_proposal_tx,
|
||||
&alice_proposal_params,
|
||||
current_block_height,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let alice_owncoins = th.holders.get(&Holder::Alice).unwrap().unspent_money_coins.clone();
|
||||
assert!(alice_owncoins[0].note.value == expected_reward(current_block_height));
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
// And some to Bob
|
||||
info!("[Bob] Building block proposal");
|
||||
let (bob_proposal_tx, bob_proposal_params) =
|
||||
th.pow_reward(&Holder::Bob, None, None).await?;
|
||||
|
||||
for holder in HOLDERS {
|
||||
info!("[{holder:?}] Executing Alice's block proposal");
|
||||
th.execute_pow_reward_tx(
|
||||
&holder,
|
||||
&bob_proposal_tx,
|
||||
&bob_proposal_params,
|
||||
current_block_height,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
// Alice sends a payment of some DRK to Bob.
|
||||
|
||||
// Thanks for reading
|
||||
Ok(())
|
||||
})
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
use darkfi::{
|
||||
blockchain::{BlockInfo, Header},
|
||||
tx::{ContractCallLeaf, Transaction, TransactionBuilder},
|
||||
zk::halo2::Field,
|
||||
Result,
|
||||
@@ -32,6 +33,7 @@ use darkfi_sdk::{
|
||||
ContractCall,
|
||||
};
|
||||
use darkfi_serial::AsyncEncodable;
|
||||
use log::info;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use super::{Holder, TestHarness};
|
||||
@@ -41,7 +43,7 @@ impl TestHarness {
|
||||
///
|
||||
/// Optionally takes a specific reward recipient and a nonstandard reward value.
|
||||
/// Returns the created [`Transaction`] and [`MoneyPoWRewardParamsV1`].
|
||||
pub async fn pow_reward(
|
||||
async fn pow_reward(
|
||||
&mut self,
|
||||
holder: &Holder,
|
||||
recipient: Option<&Holder>,
|
||||
@@ -94,34 +96,67 @@ impl TestHarness {
|
||||
Ok((tx, debris.params))
|
||||
}
|
||||
|
||||
/// Execute the transaction created by `pow_reward()` for a given [`Holder`].
|
||||
/// Generate and add an empty block to the given [`Holder`]s blockchains.
|
||||
/// The `miner` holder will produce the block and receive the reward.
|
||||
///
|
||||
/// Returns any gathered [`OwnCoin`]s from the transaction.
|
||||
pub async fn execute_pow_reward_tx(
|
||||
/// Returns any found [`OwnCoin`]s.
|
||||
pub async fn generate_block(
|
||||
&mut self,
|
||||
holder: &Holder,
|
||||
tx: &Transaction,
|
||||
params: &MoneyPoWRewardParamsV1,
|
||||
block_height: u64,
|
||||
miner: &Holder,
|
||||
holders: &[Holder],
|
||||
) -> Result<Vec<OwnCoin>> {
|
||||
let wallet = self.holders.get_mut(holder).unwrap();
|
||||
// Build the POW reward transaction
|
||||
info!("Building PoWReward transaction for {:?}", miner);
|
||||
let (tx, params) = self.pow_reward(miner, None, None).await?;
|
||||
|
||||
wallet.validator.add_test_producer_transaction(tx, block_height, true).await?;
|
||||
wallet.money_merkle_tree.append(MerkleNode::from(params.output.coin.inner()));
|
||||
// Fetch the last block in the blockchain
|
||||
let wallet = self.holders.get(miner).unwrap();
|
||||
let previous = wallet.validator.blockchain.last_block()?;
|
||||
|
||||
// Attempt to decrypt the output note to see if this is a coin for the holder.
|
||||
let Ok(note) = params.output.note.decrypt::<MoneyNote>(&wallet.keypair.secret) else {
|
||||
return Ok(vec![])
|
||||
};
|
||||
// We increment timestamp so we don't have to use sleep
|
||||
let mut timestamp = previous.header.timestamp;
|
||||
timestamp.add(1);
|
||||
|
||||
let owncoin = OwnCoin {
|
||||
coin: params.output.coin,
|
||||
note: note.clone(),
|
||||
secret: wallet.keypair.secret,
|
||||
leaf_position: wallet.money_merkle_tree.mark().unwrap(),
|
||||
};
|
||||
// Generate block header
|
||||
let header = Header::new(
|
||||
previous.hash()?,
|
||||
previous.header.height + 1,
|
||||
timestamp,
|
||||
previous.header.nonce,
|
||||
);
|
||||
|
||||
wallet.unspent_money_coins.push(owncoin.clone());
|
||||
Ok(vec![owncoin])
|
||||
// Generate the block
|
||||
let mut block = BlockInfo::new_empty(header);
|
||||
|
||||
// Add producer transaction to the block
|
||||
block.append_txs(vec![tx])?;
|
||||
|
||||
// Attach signature
|
||||
block.sign(&wallet.keypair.secret)?;
|
||||
|
||||
// For all holders, append the block
|
||||
let mut found_owncoins = vec![];
|
||||
for holder in holders {
|
||||
let wallet = self.holders.get_mut(holder).unwrap();
|
||||
wallet.validator.add_blocks(&[block.clone()]).await?;
|
||||
wallet.money_merkle_tree.append(MerkleNode::from(params.output.coin.inner()));
|
||||
|
||||
// Attempt to decrypt the note to see if this is a coin for the holder
|
||||
let Ok(note) = params.output.note.decrypt::<MoneyNote>(&wallet.keypair.secret) else {
|
||||
continue
|
||||
};
|
||||
|
||||
let owncoin = OwnCoin {
|
||||
coin: params.output.coin,
|
||||
note: note.clone(),
|
||||
secret: wallet.keypair.secret,
|
||||
leaf_position: wallet.money_merkle_tree.mark().unwrap(),
|
||||
};
|
||||
|
||||
wallet.unspent_money_coins.push(owncoin.clone());
|
||||
found_owncoins.push(owncoin);
|
||||
}
|
||||
|
||||
Ok(found_owncoins)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user