mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
darkfid: optional mining reward spend hook and user data added
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2206,6 +2206,7 @@ version = "0.4.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"blake3 1.5.1",
|
||||
"bs58",
|
||||
"darkfi",
|
||||
"darkfi-contract-test-harness",
|
||||
"darkfi-sdk",
|
||||
|
||||
@@ -10,7 +10,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
# Darkfi
|
||||
darkfi = {path = "../../", features = ["async-daemonize"]}
|
||||
darkfi = {path = "../../", features = ["async-daemonize", "bs58"]}
|
||||
darkfi_money_contract = {path = "../../src/contract/money"}
|
||||
darkfi-contract-test-harness = {path = "../../src/contract/test-harness"}
|
||||
darkfi-sdk = {path = "../../src/sdk"}
|
||||
@@ -18,6 +18,7 @@ darkfi-serial = {path = "../../src/serial"}
|
||||
|
||||
# Misc
|
||||
blake3 = "1.5.1"
|
||||
bs58 = "0.5.1"
|
||||
log = "0.4.21"
|
||||
num-bigint = "0.4.5"
|
||||
rand = "0.8.5"
|
||||
|
||||
@@ -40,6 +40,12 @@ miner = true
|
||||
# replace with your own one.
|
||||
recipient = "5ZHfYpt4mpJcwBNxfEyxLzeFJUEeoePs5NQ5jVEgHrMf"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = true
|
||||
|
||||
@@ -132,6 +138,12 @@ miner = false
|
||||
# Wallet address to receive mining rewards.
|
||||
#recipient = "YOUR_WALLET_ADDRESS_HERE"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = false
|
||||
|
||||
@@ -228,6 +240,12 @@ miner = false
|
||||
# Wallet address to receive mining rewards.
|
||||
#recipient = "YOUR_WALLET_ADDRESS_HERE"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = false
|
||||
|
||||
|
||||
@@ -136,6 +136,14 @@ pub struct BlockchainNetwork {
|
||||
/// Wallet address to receive mining rewards
|
||||
pub recipient: Option<String>,
|
||||
|
||||
#[structopt(long)]
|
||||
/// Optional contract spend hook to use in the mining reward
|
||||
pub spend_hook: Option<String>,
|
||||
|
||||
#[structopt(long)]
|
||||
/// Optional user data to use in the mining reward
|
||||
pub user_data: Option<String>,
|
||||
|
||||
#[structopt(long)]
|
||||
/// Skip syncing process and start node right away
|
||||
pub skip_sync: bool,
|
||||
@@ -341,13 +349,16 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
|
||||
consensus_task.clone().start(
|
||||
consensus_init_task(
|
||||
darkfid.clone(),
|
||||
ConsensusInitTaskConfig::new(
|
||||
blockchain_config.skip_sync,
|
||||
blockchain_config.checkpoint_height,
|
||||
blockchain_config.checkpoint, blockchain_config.miner,
|
||||
blockchain_config.recipient,
|
||||
ConsensusInitTaskConfig {
|
||||
skip_sync: blockchain_config.skip_sync,
|
||||
checkpoint_height: blockchain_config.checkpoint_height,
|
||||
checkpoint: blockchain_config.checkpoint,
|
||||
miner: blockchain_config.miner,
|
||||
recipient: blockchain_config.recipient,
|
||||
spend_hook: blockchain_config.spend_hook,
|
||||
user_data: blockchain_config.user_data,
|
||||
bootstrap,
|
||||
),
|
||||
},
|
||||
ex.clone(),
|
||||
),
|
||||
|res| async move {
|
||||
|
||||
@@ -25,36 +25,28 @@ use darkfi::{
|
||||
util::{encoding::base64, time::Timestamp},
|
||||
Error, Result,
|
||||
};
|
||||
use darkfi_sdk::crypto::PublicKey;
|
||||
use darkfi_sdk::{
|
||||
crypto::{FuncId, PublicKey},
|
||||
pasta::{group::ff::PrimeField, pallas},
|
||||
};
|
||||
use darkfi_serial::serialize_async;
|
||||
use log::{error, info};
|
||||
|
||||
use crate::{
|
||||
task::{garbage_collect_task, miner_task, sync_task},
|
||||
task::{garbage_collect_task, miner::MinerRewardsRecipientConfig, miner_task, sync_task},
|
||||
Darkfid,
|
||||
};
|
||||
|
||||
/// Auxiliary structure representing node consesus init task configuration
|
||||
/// Auxiliary structure representing node consensus init task configuration
|
||||
pub struct ConsensusInitTaskConfig {
|
||||
skip_sync: bool,
|
||||
checkpoint_height: Option<u32>,
|
||||
checkpoint: Option<String>,
|
||||
miner: bool,
|
||||
recipient: Option<String>,
|
||||
bootstrap: u64,
|
||||
}
|
||||
|
||||
impl ConsensusInitTaskConfig {
|
||||
pub fn new(
|
||||
skip_sync: bool,
|
||||
checkpoint_height: Option<u32>,
|
||||
checkpoint: Option<String>,
|
||||
miner: bool,
|
||||
recipient: Option<String>,
|
||||
bootstrap: u64,
|
||||
) -> Self {
|
||||
Self { skip_sync, checkpoint_height, checkpoint, miner, recipient, bootstrap }
|
||||
}
|
||||
pub skip_sync: bool,
|
||||
pub checkpoint_height: Option<u32>,
|
||||
pub checkpoint: Option<String>,
|
||||
pub miner: bool,
|
||||
pub recipient: Option<String>,
|
||||
pub spend_hook: Option<String>,
|
||||
pub user_data: Option<String>,
|
||||
pub bootstrap: u64,
|
||||
}
|
||||
|
||||
/// Sync the node consensus state and start the corresponding task, based on node type.
|
||||
@@ -97,15 +89,41 @@ pub async fn consensus_init_task(
|
||||
None
|
||||
};
|
||||
|
||||
// Grab rewards recipient public key(address) if node is a miner
|
||||
let recipient = if config.miner {
|
||||
// Grab rewards recipient public key(address) if node is a miner,
|
||||
// along with configured spend hook and user data.
|
||||
let recipient_config = if config.miner {
|
||||
if config.recipient.is_none() {
|
||||
return Err(Error::ParseFailed("Recipient address missing"))
|
||||
}
|
||||
match PublicKey::from_str(config.recipient.as_ref().unwrap()) {
|
||||
Ok(address) => Some(address),
|
||||
let recipient = match PublicKey::from_str(config.recipient.as_ref().unwrap()) {
|
||||
Ok(address) => address,
|
||||
Err(_) => return Err(Error::InvalidAddress),
|
||||
}
|
||||
};
|
||||
|
||||
let spend_hook = match config.spend_hook {
|
||||
Some(s) => match FuncId::from_str(&s) {
|
||||
Ok(s) => Some(s),
|
||||
Err(_) => return Err(Error::ParseFailed("Invalid spend hook")),
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let user_data = match config.user_data {
|
||||
Some(u) => {
|
||||
let bytes: [u8; 32] = match bs58::decode(&u).into_vec()?.try_into() {
|
||||
Ok(b) => b,
|
||||
Err(_) => return Err(Error::ParseFailed("Invalid user data")),
|
||||
};
|
||||
|
||||
match pallas::Base::from_repr(bytes).into() {
|
||||
Some(v) => Some(v),
|
||||
None => return Err(Error::ParseFailed("Invalid user data")),
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
Some(MinerRewardsRecipientConfig { recipient, spend_hook, user_data })
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -113,7 +131,13 @@ pub async fn consensus_init_task(
|
||||
// Gracefully handle network disconnections
|
||||
loop {
|
||||
let result = if config.miner {
|
||||
miner_task(node.clone(), recipient.unwrap(), config.skip_sync, ex.clone()).await
|
||||
miner_task(
|
||||
node.clone(),
|
||||
recipient_config.as_ref().unwrap(),
|
||||
config.skip_sync,
|
||||
ex.clone(),
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
replicator_task(node.clone(), ex.clone()).await
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ use darkfi_money_contract::{
|
||||
client::pow_reward_v1::PoWRewardCallBuilder, MoneyFunction, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
|
||||
};
|
||||
use darkfi_sdk::{
|
||||
crypto::{poseidon_hash, PublicKey, SecretKey, MONEY_CONTRACT_ID},
|
||||
crypto::{poseidon_hash, FuncId, PublicKey, SecretKey, MONEY_CONTRACT_ID},
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
};
|
||||
@@ -48,6 +48,13 @@ use smol::channel::{Receiver, Sender};
|
||||
|
||||
use crate::{proto::ProposalMessage, task::garbage_collect_task, Darkfid};
|
||||
|
||||
/// Auxiliary structure representing node miner rewards recipient configuration
|
||||
pub struct MinerRewardsRecipientConfig {
|
||||
pub recipient: PublicKey,
|
||||
pub spend_hook: Option<FuncId>,
|
||||
pub user_data: Option<pallas::Base>,
|
||||
}
|
||||
|
||||
/// Async task used for participating in the PoW block production.
|
||||
/// Miner initializes their setup and waits for next finalization,
|
||||
/// by listenning for new proposals from the network, for optimal
|
||||
@@ -60,7 +67,7 @@ use crate::{proto::ProposalMessage, task::garbage_collect_task, Darkfid};
|
||||
/// finishes, node triggers finallization check.
|
||||
pub async fn miner_task(
|
||||
node: Arc<Darkfid>,
|
||||
recipient: PublicKey,
|
||||
recipient_config: &MinerRewardsRecipientConfig,
|
||||
skip_sync: bool,
|
||||
ex: Arc<smol::Executor<'static>>,
|
||||
) -> Result<()> {
|
||||
@@ -158,7 +165,7 @@ pub async fn miner_task(
|
||||
&node,
|
||||
&extended_fork,
|
||||
&mut secret,
|
||||
&recipient,
|
||||
recipient_config,
|
||||
&zkbin,
|
||||
&pk,
|
||||
&stop_signal,
|
||||
@@ -262,7 +269,7 @@ async fn mine(
|
||||
node: &Darkfid,
|
||||
extended_fork: &Fork,
|
||||
secret: &mut SecretKey,
|
||||
recipient: &PublicKey,
|
||||
recipient_config: &MinerRewardsRecipientConfig,
|
||||
zkbin: &ZkBinary,
|
||||
pk: &ProvingKey,
|
||||
stop_signal: &Receiver<()>,
|
||||
@@ -270,7 +277,7 @@ async fn mine(
|
||||
) -> Result<()> {
|
||||
smol::future::or(
|
||||
wait_stop_signal(stop_signal),
|
||||
mine_next_block(node, extended_fork, secret, recipient, zkbin, pk, skip_sync),
|
||||
mine_next_block(node, extended_fork, secret, recipient_config, zkbin, pk, skip_sync),
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -293,7 +300,7 @@ async fn mine_next_block(
|
||||
node: &Darkfid,
|
||||
extended_fork: &Fork,
|
||||
secret: &mut SecretKey,
|
||||
recipient: &PublicKey,
|
||||
recipient_config: &MinerRewardsRecipientConfig,
|
||||
zkbin: &ZkBinary,
|
||||
pk: &ProvingKey,
|
||||
skip_sync: bool,
|
||||
@@ -302,7 +309,7 @@ async fn mine_next_block(
|
||||
let (next_target, mut next_block) = generate_next_block(
|
||||
extended_fork,
|
||||
secret,
|
||||
recipient,
|
||||
recipient_config,
|
||||
zkbin,
|
||||
pk,
|
||||
node.validator.consensus.module.read().await.target,
|
||||
@@ -343,7 +350,7 @@ async fn mine_next_block(
|
||||
async fn generate_next_block(
|
||||
extended_fork: &Fork,
|
||||
secret: &mut SecretKey,
|
||||
recipient: &PublicKey,
|
||||
recipient_config: &MinerRewardsRecipientConfig,
|
||||
zkbin: &ZkBinary,
|
||||
pk: &ProvingKey,
|
||||
block_target: u32,
|
||||
@@ -368,7 +375,7 @@ async fn generate_next_block(
|
||||
*secret = SecretKey::from(next_secret);
|
||||
|
||||
// Generate reward transaction
|
||||
let tx = generate_transaction(next_block_height, fees, secret, recipient, zkbin, pk)?;
|
||||
let tx = generate_transaction(next_block_height, fees, secret, recipient_config, zkbin, pk)?;
|
||||
txs.push(tx);
|
||||
|
||||
// Generate the new header
|
||||
@@ -391,7 +398,7 @@ fn generate_transaction(
|
||||
block_height: u32,
|
||||
fees: u64,
|
||||
secret: &SecretKey,
|
||||
recipient: &PublicKey,
|
||||
recipient_config: &MinerRewardsRecipientConfig,
|
||||
zkbin: &ZkBinary,
|
||||
pk: &ProvingKey,
|
||||
) -> Result<Transaction> {
|
||||
@@ -400,9 +407,9 @@ fn generate_transaction(
|
||||
signature_public: PublicKey::from_secret(*secret),
|
||||
block_height,
|
||||
fees,
|
||||
recipient: Some(*recipient),
|
||||
spend_hook: None,
|
||||
user_data: None,
|
||||
recipient: Some(recipient_config.recipient),
|
||||
spend_hook: recipient_config.spend_hook,
|
||||
user_data: recipient_config.user_data,
|
||||
mint_zkbin: zkbin.clone(),
|
||||
mint_pk: pk.clone(),
|
||||
}
|
||||
|
||||
@@ -34,6 +34,12 @@ miner = true
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = true
|
||||
|
||||
|
||||
@@ -34,6 +34,12 @@ miner = true
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = false
|
||||
|
||||
|
||||
@@ -34,6 +34,12 @@ miner = true
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = false
|
||||
|
||||
|
||||
@@ -34,6 +34,12 @@ miner = true
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = false
|
||||
|
||||
|
||||
@@ -34,6 +34,12 @@ miner = true
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = false
|
||||
|
||||
|
||||
@@ -37,6 +37,12 @@ miner = true
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "6iW9nywZYvyhcM7P1iLwYkh92rvYtREDsC8hgqf2GLuT"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = true
|
||||
|
||||
|
||||
@@ -34,6 +34,12 @@ miner = true
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = true
|
||||
|
||||
|
||||
@@ -42,6 +42,12 @@ miner = true
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
# Optional user data to use in the mining reward
|
||||
#user_data = "YOUR_USER_DATA_HERE"
|
||||
|
||||
# Skip syncing process and start node right away
|
||||
skip_sync = false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user