mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
contract/money/client/pow_reward: decoupled signer and recipient keys
This commit is contained in:
@@ -24,7 +24,7 @@ use darkfi::{
|
||||
use darkfi_sdk::{
|
||||
blockchain::expected_reward,
|
||||
crypto::{
|
||||
ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::*, Keypair, PublicKey,
|
||||
ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::*, PublicKey, SecretKey,
|
||||
DARK_TOKEN_ID,
|
||||
},
|
||||
pasta::pallas,
|
||||
@@ -66,8 +66,10 @@ impl PoWRewardRevealed {
|
||||
|
||||
/// Struct holding necessary information to build a `Money::PoWRewardV1` contract call.
|
||||
pub struct PoWRewardCallBuilder {
|
||||
/// Caller's keypair
|
||||
pub keypair: Keypair,
|
||||
/// Caller's secret key, used for signing and VRF proof generation
|
||||
pub secret: SecretKey,
|
||||
/// Reward recipient's public key
|
||||
pub recipient: PublicKey,
|
||||
/// Rewarded block height(slot)
|
||||
pub block_height: u64,
|
||||
/// Extending fork last proposal/block nonce
|
||||
@@ -95,14 +97,10 @@ impl PoWRewardCallBuilder {
|
||||
// Only DARK_TOKEN_ID can be minted as PoW reward.
|
||||
let token_id = *DARK_TOKEN_ID;
|
||||
|
||||
let input = TransactionBuilderClearInputInfo {
|
||||
value,
|
||||
token_id,
|
||||
signature_secret: self.keypair.secret,
|
||||
};
|
||||
let input =
|
||||
TransactionBuilderClearInputInfo { value, token_id, signature_secret: self.secret };
|
||||
|
||||
let output =
|
||||
TransactionBuilderOutputInfo { value, token_id, public_key: self.keypair.public };
|
||||
let output = TransactionBuilderOutputInfo { value, token_id, public_key: self.recipient };
|
||||
|
||||
// We just create the commitment blinds here. We simply encofce
|
||||
// that the clear input and the anon output have the same commitments.
|
||||
@@ -157,7 +155,7 @@ impl PoWRewardCallBuilder {
|
||||
vrf_input.extend_from_slice(&self.last_nonce.to_repr());
|
||||
vrf_input.extend_from_slice(self.fork_previous_hash.as_bytes());
|
||||
vrf_input.extend_from_slice(&pallas::Base::from(self.block_height).to_repr());
|
||||
let vrf_proof = VrfProof::prove(self.keypair.secret, &vrf_input, &mut OsRng);
|
||||
let vrf_proof = VrfProof::prove(self.secret, &vrf_input, &mut OsRng);
|
||||
|
||||
let params = MoneyPoWRewardParamsV1 {
|
||||
input: c_input,
|
||||
|
||||
@@ -51,7 +51,7 @@ fn pow_reward() -> Result<()> {
|
||||
info!(target: "money", "[Malicious] =======================================");
|
||||
info!(target: "money", "[Malicious] Building PoW reward tx for genesis slot");
|
||||
info!(target: "money", "[Malicious] =======================================");
|
||||
let (pow_reward_tx, _) = th.pow_reward(&Holder::Alice, current_height, Some(0))?;
|
||||
let (pow_reward_tx, _) = th.pow_reward(&Holder::Alice, None, current_height, Some(0))?;
|
||||
|
||||
info!(target: "money", "[Malicious] =======================================");
|
||||
info!(target: "money", "[Malicious] Checking PoW reward tx for genesis slot");
|
||||
@@ -67,7 +67,7 @@ fn pow_reward() -> Result<()> {
|
||||
info!(target: "money", "[Malicious] Building erroneous PoW reward tx");
|
||||
info!(target: "money", "[Malicious] ================================");
|
||||
let (pow_reward_tx, _) =
|
||||
th.pow_reward(&Holder::Alice, current_height, Some(alice_reward + 1))?;
|
||||
th.pow_reward(&Holder::Alice, None, current_height, Some(alice_reward + 1))?;
|
||||
|
||||
info!(target: "money", "[Malicious] =======================================");
|
||||
info!(target: "money", "[Malicious] Checking erroneous amount PoW reward tx");
|
||||
@@ -79,7 +79,7 @@ fn pow_reward() -> Result<()> {
|
||||
info!(target: "money", "[Alice] Building PoW reward tx");
|
||||
info!(target: "money", "[Alice] ======================");
|
||||
let (pow_reward_tx, pow_reward_params) =
|
||||
th.pow_reward(&Holder::Alice, current_height, None)?;
|
||||
th.pow_reward(&Holder::Alice, None, current_height, None)?;
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] =============================");
|
||||
@@ -128,11 +128,36 @@ fn pow_reward() -> Result<()> {
|
||||
let bob_oc = th.gather_owncoin(&Holder::Bob, &transfer_params.outputs[1], None)?;
|
||||
bob_owncoins.push(bob_oc);
|
||||
|
||||
// Alice can also send her PoW reward directly to bob
|
||||
current_height += 1;
|
||||
th.generate_slot(current_height).await?;
|
||||
|
||||
info!(target: "money", "[Alice] ==============================");
|
||||
info!(target: "money", "[Alice] Building PoW reward tx for Bob");
|
||||
info!(target: "money", "[Alice] ==============================");
|
||||
let (pow_reward_tx, pow_reward_params) =
|
||||
th.pow_reward(&Holder::Alice, Some(&Holder::Bob), current_height, None)?;
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] =====================================");
|
||||
info!(target: "money", "[{holder:?}] Executing Alice PoW reward tx for Bob");
|
||||
info!(target: "money", "[{holder:?}] =====================================");
|
||||
th.execute_pow_reward_tx(holder, &pow_reward_tx, &pow_reward_params, current_height)
|
||||
.await?;
|
||||
}
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
// Bob gathers his new owncoin
|
||||
let bob_oc = th.gather_owncoin(&Holder::Bob, &pow_reward_params.output, None)?;
|
||||
bob_owncoins.push(bob_oc);
|
||||
|
||||
// Validating transaction outcomes
|
||||
assert!(alice_owncoins.len() == 1);
|
||||
assert!(bob_owncoins.len() == 1);
|
||||
assert!(bob_owncoins.len() == 2);
|
||||
assert!(alice_owncoins[0].note.value == alice_reward - alice_send);
|
||||
assert!(bob_owncoins[0].note.value == alice_send);
|
||||
assert!(bob_owncoins[1].note.value == alice_reward);
|
||||
|
||||
// Statistics
|
||||
th.statistics();
|
||||
|
||||
@@ -37,6 +37,7 @@ impl TestHarness {
|
||||
pub fn pow_reward(
|
||||
&mut self,
|
||||
holder: &Holder,
|
||||
recipient: Option<&Holder>,
|
||||
block_height: u64,
|
||||
reward: Option<u64>,
|
||||
) -> Result<(Transaction, MoneyPoWRewardParamsV1)> {
|
||||
@@ -58,8 +59,16 @@ impl TestHarness {
|
||||
let spend_hook = pallas::Base::zero();
|
||||
let user_data = pallas::Base::zero();
|
||||
|
||||
let recipient = if let Some(holder) = recipient {
|
||||
let holder = self.holders.get(holder).unwrap();
|
||||
holder.keypair.public
|
||||
} else {
|
||||
wallet.keypair.public
|
||||
};
|
||||
|
||||
let builder = PoWRewardCallBuilder {
|
||||
keypair: wallet.keypair,
|
||||
secret: wallet.keypair.secret,
|
||||
recipient,
|
||||
block_height,
|
||||
last_nonce,
|
||||
fork_hash,
|
||||
|
||||
Reference in New Issue
Block a user