mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
darkfid|drk|minerd: use the new Address format everywhere + minor cleanups and docs updates
This commit is contained in:
@@ -42,11 +42,32 @@ pub enum RpcError {
|
||||
MinerInvalidHeader = -32301,
|
||||
MinerMissingRecipient = -32302,
|
||||
MinerInvalidRecipient = -32303,
|
||||
MinerInvalidSpendHook = -32304,
|
||||
MinerInvalidUserData = -32305,
|
||||
MinerMissingNonce = -32306,
|
||||
MinerInvalidNonce = -32307,
|
||||
MinerUnknownJob = -32308,
|
||||
MinerInvalidRecipientPrefix = -32304,
|
||||
MinerInvalidSpendHook = -32305,
|
||||
MinerInvalidUserData = -32306,
|
||||
MinerMissingNonce = -32307,
|
||||
MinerInvalidNonce = -32308,
|
||||
MinerMissingAddress = -32309,
|
||||
MinerInvalidAddress = -32310,
|
||||
MinerMissingAuxHash = -32311,
|
||||
MinerInvalidAuxHash = -32312,
|
||||
MinerMissingHeight = -32313,
|
||||
MinerInvalidHeight = -32314,
|
||||
MinerMissingPrevId = -32315,
|
||||
MinerInvalidPrevId = -32316,
|
||||
MinerMissingAuxBlob = -32317,
|
||||
MinerInvalidAuxBlob = -32318,
|
||||
MinerMissingBlob = -32319,
|
||||
MinerInvalidBlob = -32320,
|
||||
MinerMissingMerkleProof = -32321,
|
||||
MinerInvalidMerkleProof = -32322,
|
||||
MinerMissingPath = -32323,
|
||||
MinerInvalidPath = -32324,
|
||||
MinerMissingSeedHash = -32325,
|
||||
MinerInvalidSeedHash = -32326,
|
||||
MinerMerkleProofConstructionFailed = -32327,
|
||||
MinerMoneroPowDataConstructionFailed = -32328,
|
||||
MinerUnknownJob = -32329,
|
||||
}
|
||||
|
||||
fn to_tuple(e: RpcError) -> (i32, String) {
|
||||
@@ -68,10 +89,39 @@ fn to_tuple(e: RpcError) -> (i32, String) {
|
||||
RpcError::MinerInvalidHeader => "Request Header hash is invalid",
|
||||
RpcError::MinerMissingRecipient => "Request is missing the recipient wallet address",
|
||||
RpcError::MinerInvalidRecipient => "Request recipient wallet address is invalid",
|
||||
RpcError::MinerInvalidRecipientPrefix => {
|
||||
"Request recipient wallet address prefix is invalid"
|
||||
}
|
||||
RpcError::MinerInvalidSpendHook => "Request spend hook is invalid",
|
||||
RpcError::MinerInvalidUserData => "Request user data is invalid",
|
||||
RpcError::MinerMissingNonce => "Request is missing the Header nonce",
|
||||
RpcError::MinerInvalidNonce => "Request Header nonce is invalid",
|
||||
RpcError::MinerMissingAddress => {
|
||||
"Request is missing the recipient wallet address configuration"
|
||||
}
|
||||
RpcError::MinerInvalidAddress => {
|
||||
"Request recipient wallet address configuration is invalid"
|
||||
}
|
||||
RpcError::MinerMissingAuxHash => "Request is missing the merge mining job (aux_hash)",
|
||||
RpcError::MinerInvalidAuxHash => "Request merge mining job (aux_hash) is invalid",
|
||||
RpcError::MinerMissingHeight => "Request is missing the Monero height",
|
||||
RpcError::MinerInvalidHeight => "Request Monero height is invalid",
|
||||
RpcError::MinerMissingPrevId => "Request is missing the hash of the previous Monero block",
|
||||
RpcError::MinerInvalidPrevId => "Request hash of the previous Monero block is invalid",
|
||||
RpcError::MinerMissingAuxBlob => "Request is missing the merge mining blob",
|
||||
RpcError::MinerInvalidAuxBlob => "Request merge mining bob is invalid",
|
||||
RpcError::MinerMissingBlob => "Request is missing the Monero block template",
|
||||
RpcError::MinerInvalidBlob => "Request Monero block template is invalid",
|
||||
RpcError::MinerMissingMerkleProof => "Request is missing the Merkle proof",
|
||||
RpcError::MinerInvalidMerkleProof => "Request Merkle proof is invalid",
|
||||
RpcError::MinerMissingPath => "Request is missing the Merkle proof path",
|
||||
RpcError::MinerInvalidPath => "Request Merkle proof path is invalid",
|
||||
RpcError::MinerMissingSeedHash => "Request is missing the RandomX seed key",
|
||||
RpcError::MinerInvalidSeedHash => "Request RandomX seed key is invalid",
|
||||
RpcError::MinerMerkleProofConstructionFailed => {
|
||||
"failed constructing aux chain Merkle proof"
|
||||
}
|
||||
RpcError::MinerMoneroPowDataConstructionFailed => "Failed constructing Monero PoW data",
|
||||
RpcError::MinerUnknownJob => "Request job is unknown",
|
||||
};
|
||||
|
||||
|
||||
@@ -39,7 +39,10 @@ use darkfi::{
|
||||
Error, Result,
|
||||
};
|
||||
use darkfi_money_contract::MONEY_CONTRACT_ZKAS_MINT_NS_V1;
|
||||
use darkfi_sdk::crypto::{keypair::SecretKey, MONEY_CONTRACT_ID};
|
||||
use darkfi_sdk::crypto::{
|
||||
keypair::{Network, SecretKey},
|
||||
MONEY_CONTRACT_ID,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@@ -69,6 +72,8 @@ pub type DarkfiNodePtr = Arc<DarkfiNode>;
|
||||
|
||||
/// Structure representing a DarkFi node
|
||||
pub struct DarkfiNode {
|
||||
/// Blockchain network
|
||||
network: Network,
|
||||
/// P2P network protocols handler.
|
||||
p2p_handler: DarkfidP2pHandlerPtr,
|
||||
/// Validator(node) pointer
|
||||
@@ -91,6 +96,7 @@ pub struct DarkfiNode {
|
||||
|
||||
impl DarkfiNode {
|
||||
pub async fn new(
|
||||
network: Network,
|
||||
p2p_handler: DarkfidP2pHandlerPtr,
|
||||
validator: ValidatorPtr,
|
||||
txs_batch_size: usize,
|
||||
@@ -99,6 +105,7 @@ impl DarkfiNode {
|
||||
let powrewardv1_zk = PowRewardV1Zk::new(validator.clone())?;
|
||||
|
||||
Ok(Arc::new(Self {
|
||||
network,
|
||||
p2p_handler,
|
||||
validator,
|
||||
txs_batch_size,
|
||||
@@ -161,6 +168,7 @@ impl Darkfid {
|
||||
/// Generates a new `DarkfiNode` for provided configuration,
|
||||
/// along with all the corresponding background tasks.
|
||||
pub async fn init(
|
||||
network: Network,
|
||||
sled_db: &sled_overlay::sled::Db,
|
||||
config: &ValidatorConfig,
|
||||
net_settings: &Settings,
|
||||
@@ -194,7 +202,8 @@ impl Darkfid {
|
||||
subscribers.insert("dnet", JsonSubscriber::new("dnet.subscribe_events"));
|
||||
|
||||
// Initialize node
|
||||
let node = DarkfiNode::new(p2p_handler, validator, txs_batch_size, subscribers).await?;
|
||||
let node =
|
||||
DarkfiNode::new(network, p2p_handler, validator, txs_batch_size, subscribers).await?;
|
||||
|
||||
// Generate the background tasks
|
||||
let dnet_task = StoppableTask::new();
|
||||
|
||||
@@ -35,6 +35,7 @@ use darkfi::{
|
||||
validator::{Validator, ValidatorConfig},
|
||||
Error, Result,
|
||||
};
|
||||
use darkfi_sdk::crypto::keypair::Network;
|
||||
use darkfi_serial::deserialize_async;
|
||||
|
||||
use darkfid::{task::consensus::ConsensusInitTaskConfig, Darkfid};
|
||||
@@ -148,7 +149,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
|
||||
info!(target: "darkfid", "Initializing DarkFi node...");
|
||||
|
||||
// Grab blockchain network configuration
|
||||
let (blockchain_config, genesis_block) = match args.network.as_str() {
|
||||
let ((network, blockchain_config), genesis_block) = match args.network.as_str() {
|
||||
"localnet" => {
|
||||
(parse_blockchain_config(args.config, "localnet").await?, GENESIS_BLOCK_LOCALNET)
|
||||
}
|
||||
@@ -234,6 +235,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
|
||||
|
||||
// Generate the daemon
|
||||
let daemon = Darkfid::init(
|
||||
network,
|
||||
&sled_db,
|
||||
&config,
|
||||
&blockchain_config.net.into(),
|
||||
@@ -275,7 +277,14 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
|
||||
pub async fn parse_blockchain_config(
|
||||
config: Option<String>,
|
||||
network: &str,
|
||||
) -> Result<BlockchainNetwork> {
|
||||
) -> Result<(Network, BlockchainNetwork)> {
|
||||
// Grab network prefix
|
||||
let used_net = match network {
|
||||
"mainnet" | "localnet" => Network::Mainnet,
|
||||
"testnet" => Network::Testnet,
|
||||
_ => return Err(Error::ParseFailed("Invalid blockchain network")),
|
||||
};
|
||||
|
||||
// Grab config path
|
||||
let config_path = get_config_path(config, CONFIG_FILE)?;
|
||||
debug!(target: "darkfid", "Parsing configuration file: {config_path:?}");
|
||||
@@ -312,5 +321,5 @@ pub async fn parse_blockchain_config(
|
||||
};
|
||||
debug!(target: "darkfid", "Parsed network configuration: {network_config:?}");
|
||||
|
||||
Ok(network_config)
|
||||
Ok((used_net, network_config))
|
||||
}
|
||||
|
||||
@@ -35,8 +35,9 @@ use darkfi::{
|
||||
use darkfi_money_contract::{client::pow_reward_v1::PoWRewardCallBuilder, MoneyFunction};
|
||||
use darkfi_sdk::{
|
||||
crypto::{
|
||||
pasta_prelude::PrimeField, FuncId, Keypair, MerkleTree, PublicKey, SecretKey,
|
||||
MONEY_CONTRACT_ID,
|
||||
keypair::{Address, Keypair, SecretKey},
|
||||
pasta_prelude::PrimeField,
|
||||
FuncId, MerkleTree, MONEY_CONTRACT_ID,
|
||||
},
|
||||
pasta::pallas,
|
||||
ContractCall,
|
||||
@@ -52,7 +53,7 @@ use crate::{proto::ProposalMessage, server_error, DarkfiNode, RpcError};
|
||||
/// Auxiliary structure representing node miner rewards recipient configuration.
|
||||
pub struct MinerRewardsRecipientConfig {
|
||||
/// Wallet mining address to receive mining rewards
|
||||
pub recipient: PublicKey,
|
||||
pub recipient: Address,
|
||||
/// Optional contract spend hook to use in the mining reward
|
||||
pub spend_hook: Option<FuncId>,
|
||||
/// Optional contract user data to use in the mining reward.
|
||||
@@ -168,12 +169,15 @@ impl DarkfiNode {
|
||||
let Some(recipient) = params.get("recipient") else {
|
||||
return server_error(RpcError::MinerMissingRecipient, id, None)
|
||||
};
|
||||
let Some(recipient) = recipient.get::<String>() else {
|
||||
let Some(recipient_str) = recipient.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidRecipient, id, None)
|
||||
};
|
||||
let Ok(recipient) = PublicKey::from_str(recipient) else {
|
||||
let Ok(recipient) = Address::from_str(recipient_str) else {
|
||||
return server_error(RpcError::MinerInvalidRecipient, id, None)
|
||||
};
|
||||
if recipient.network() != self.network {
|
||||
return server_error(RpcError::MinerInvalidRecipientPrefix, id, None)
|
||||
};
|
||||
|
||||
// Parse spend hook
|
||||
let spend_hook = match params.get("spend_hook") {
|
||||
@@ -221,7 +225,8 @@ impl DarkfiNode {
|
||||
// We'll also obtain a lock here to avoid getting polled
|
||||
// multiple times and potentially missing a job. The lock is
|
||||
// released when this function exits.
|
||||
let address_bytes = serialize_async(&(recipient, spend_hook, user_data)).await;
|
||||
let address_bytes =
|
||||
serialize_async(&(recipient_str.clone().into_bytes(), spend_hook, user_data)).await;
|
||||
let mut blocktemplates = self.blocktemplates.lock().await;
|
||||
let mut extended_fork = match self.validator.best_current_fork().await {
|
||||
Ok(f) => f,
|
||||
@@ -267,7 +272,6 @@ impl DarkfiNode {
|
||||
// At this point, we should query the Validator for a new blocktemplate.
|
||||
// We first need to construct `MinerRewardsRecipientConfig` from the
|
||||
// address configuration provided to us through the RPC.
|
||||
let recipient_str = format!("{recipient}");
|
||||
let spend_hook_str = match spend_hook {
|
||||
Some(spend_hook) => format!("{spend_hook}"),
|
||||
None => String::from("-"),
|
||||
@@ -373,12 +377,15 @@ impl DarkfiNode {
|
||||
let Some(recipient) = params.get("recipient") else {
|
||||
return server_error(RpcError::MinerMissingRecipient, id, None)
|
||||
};
|
||||
let Some(recipient) = recipient.get::<String>() else {
|
||||
let Some(recipient_str) = recipient.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidRecipient, id, None)
|
||||
};
|
||||
let Ok(recipient) = PublicKey::from_str(recipient) else {
|
||||
let Ok(recipient) = Address::from_str(recipient_str) else {
|
||||
return server_error(RpcError::MinerInvalidRecipient, id, None)
|
||||
};
|
||||
if recipient.network() != self.network {
|
||||
return server_error(RpcError::MinerInvalidRecipientPrefix, id, None)
|
||||
};
|
||||
|
||||
// Parse spend hook
|
||||
let spend_hook = match params.get("spend_hook") {
|
||||
@@ -424,7 +431,8 @@ impl DarkfiNode {
|
||||
};
|
||||
|
||||
// If we don't know about this job, we can just abort here.
|
||||
let address_bytes = serialize_async(&(recipient, spend_hook, user_data)).await;
|
||||
let address_bytes =
|
||||
serialize_async(&(recipient_str.clone().into_bytes(), spend_hook, user_data)).await;
|
||||
let mut blocktemplates = self.blocktemplates.lock().await;
|
||||
let Some(blocktemplate) = blocktemplates.get(&address_bytes) else {
|
||||
return server_error(RpcError::MinerUnknownJob, id, None)
|
||||
@@ -565,7 +573,7 @@ fn generate_transaction(
|
||||
signature_keypair: *block_signing_keypair,
|
||||
block_height,
|
||||
fees,
|
||||
recipient: Some(recipient_config.recipient),
|
||||
recipient: Some(*recipient_config.recipient.public_key()),
|
||||
spend_hook: recipient_config.spend_hook,
|
||||
user_data: recipient_config.user_data,
|
||||
mint_zkbin: zkbin.clone(),
|
||||
|
||||
@@ -32,7 +32,7 @@ use darkfi::{
|
||||
validator::consensus::Proposal,
|
||||
};
|
||||
use darkfi_sdk::{
|
||||
crypto::{pasta_prelude::PrimeField, FuncId, PublicKey},
|
||||
crypto::{keypair::Address, pasta_prelude::PrimeField, FuncId},
|
||||
pasta::pallas,
|
||||
};
|
||||
use darkfi_serial::{deserialize_async, serialize_async};
|
||||
@@ -61,8 +61,11 @@ impl DarkfiNode {
|
||||
// --> {"jsonrpc":"2.0", "method": "merge_mining_get_chain_id", "id": 1}
|
||||
// <-- {"jsonrpc":"2.0", "result": {"chain_id": "0f28c...7863"}, "id": 1}
|
||||
pub async fn xmr_merge_mining_get_chain_id(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
// Check request doesn't contain params
|
||||
if !params.get::<Vec<JsonValue>>().unwrap().is_empty() {
|
||||
// Verify request params
|
||||
let Some(params) = params.get::<Vec<JsonValue>>() else {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
};
|
||||
if !params.is_empty() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
@@ -113,70 +116,50 @@ impl DarkfiNode {
|
||||
let Some(params) = params.get::<HashMap<String, JsonValue>>() else {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
};
|
||||
if params.len() != 4 {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
// Parse address mining configuration
|
||||
let Some(address) = params.get("address") else {
|
||||
return JsonError::new(InvalidParams, Some("missing address".to_string()), id).into()
|
||||
return server_error(RpcError::MinerMissingAddress, id, None)
|
||||
};
|
||||
let Some(address) = address.get::<String>() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid address format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAddress, id, None)
|
||||
};
|
||||
let Some(address_bytes) = base64::decode(address) else {
|
||||
return JsonError::new(InvalidParams, Some("invalid address format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAddress, id, None)
|
||||
};
|
||||
let Ok((recipient, spend_hook, user_data)) =
|
||||
deserialize_async::<(PublicKey, Option<String>, Option<String>)>(&address_bytes).await
|
||||
deserialize_async::<(String, Option<String>, Option<String>)>(&address_bytes).await
|
||||
else {
|
||||
return JsonError::new(InvalidParams, Some("invalid address format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAddress, id, None)
|
||||
};
|
||||
let Ok(recipient) = Address::from_str(&recipient) else {
|
||||
return server_error(RpcError::MinerInvalidRecipient, id, None)
|
||||
};
|
||||
if recipient.network() != self.network {
|
||||
return server_error(RpcError::MinerInvalidRecipientPrefix, id, None)
|
||||
}
|
||||
let spend_hook = match spend_hook {
|
||||
Some(s) => match FuncId::from_str(&s) {
|
||||
Ok(s) => Some(s),
|
||||
Err(_) => {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid address format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
Err(_) => return server_error(RpcError::MinerInvalidSpendHook, id, None),
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
let user_data: Option<pallas::Base> = match user_data {
|
||||
Some(u) => {
|
||||
let Ok(bytes) = bs58::decode(&u).into_vec() else {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid address format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidUserData, id, None)
|
||||
};
|
||||
let bytes: [u8; 32] = match bytes.try_into() {
|
||||
Ok(b) => b,
|
||||
Err(_) => {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid address format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
Err(_) => return server_error(RpcError::MinerInvalidUserData, id, None),
|
||||
};
|
||||
match pallas::Base::from_repr(bytes).into() {
|
||||
Some(v) => Some(v),
|
||||
None => {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid address format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
None => return server_error(RpcError::MinerInvalidUserData, id, None),
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
@@ -184,38 +167,33 @@ impl DarkfiNode {
|
||||
|
||||
// Parse aux_hash
|
||||
let Some(aux_hash) = params.get("aux_hash") else {
|
||||
return JsonError::new(InvalidParams, Some("missing aux_hash".to_string()), id).into()
|
||||
return server_error(RpcError::MinerMissingAuxHash, id, None)
|
||||
};
|
||||
let Some(aux_hash) = aux_hash.get::<String>() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid aux_hash format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAuxHash, id, None)
|
||||
};
|
||||
let Ok(aux_hash) = HeaderHash::from_str(aux_hash) else {
|
||||
return JsonError::new(InvalidParams, Some("invalid aux_hash format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAuxHash, id, None)
|
||||
};
|
||||
|
||||
// Parse height
|
||||
let Some(height) = params.get("height") else {
|
||||
return JsonError::new(InvalidParams, Some("missing height".to_string()), id).into()
|
||||
return server_error(RpcError::MinerMissingHeight, id, None)
|
||||
};
|
||||
let Some(height) = height.get::<f64>() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid height format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidHeight, id, None)
|
||||
};
|
||||
let height = *height as u64;
|
||||
|
||||
// Parse prev_id
|
||||
let Some(prev_id) = params.get("prev_id") else {
|
||||
return JsonError::new(InvalidParams, Some("missing prev_id".to_string()), id).into()
|
||||
return server_error(RpcError::MinerMissingPrevId, id, None)
|
||||
};
|
||||
let Some(prev_id) = prev_id.get::<String>() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid prev_id format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidPrevId, id, None)
|
||||
};
|
||||
let Ok(prev_id) = hex::decode(prev_id) else {
|
||||
return JsonError::new(InvalidParams, Some("invalid prev_id format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidPrevId, id, None)
|
||||
};
|
||||
let prev_id = monero::Hash::from_slice(&prev_id);
|
||||
|
||||
@@ -372,157 +350,120 @@ impl DarkfiNode {
|
||||
let Some(params) = params.get::<HashMap<String, JsonValue>>() else {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
};
|
||||
if params.len() != 6 {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
// Parse address mining configuration from aux_blob
|
||||
let Some(aux_blob) = params.get("aux_blob") else {
|
||||
return JsonError::new(InvalidParams, Some("missing aux_blob".to_string()), id).into()
|
||||
return server_error(RpcError::MinerMissingAuxBlob, id, None)
|
||||
};
|
||||
let Some(aux_blob) = aux_blob.get::<String>() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid aux_blob format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAuxBlob, id, None)
|
||||
};
|
||||
let Ok(address_bytes) = hex::decode(aux_blob) else {
|
||||
return JsonError::new(InvalidParams, Some("invalid aux_blob format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAuxBlob, id, None)
|
||||
};
|
||||
let Ok((_, spend_hook, user_data)) =
|
||||
deserialize_async::<(PublicKey, Option<String>, Option<String>)>(&address_bytes).await
|
||||
let Ok((recipient, spend_hook, user_data)) =
|
||||
deserialize_async::<(String, Option<String>, Option<String>)>(&address_bytes).await
|
||||
else {
|
||||
return JsonError::new(InvalidParams, Some("invalid aux_blob format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAuxBlob, id, None)
|
||||
};
|
||||
let Ok(recipient) = Address::from_str(&recipient) else {
|
||||
return server_error(RpcError::MinerInvalidRecipient, id, None)
|
||||
};
|
||||
if recipient.network() != self.network {
|
||||
return server_error(RpcError::MinerInvalidRecipientPrefix, id, None)
|
||||
}
|
||||
if let Some(spend_hook) = spend_hook {
|
||||
if FuncId::from_str(&spend_hook).is_err() {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid aux_blob format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidSpendHook, id, None)
|
||||
}
|
||||
};
|
||||
if let Some(user_data) = user_data {
|
||||
let Ok(bytes) = bs58::decode(&user_data).into_vec() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid address format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidUserData, id, None)
|
||||
};
|
||||
let bytes: [u8; 32] = match bytes.try_into() {
|
||||
Ok(b) => b,
|
||||
Err(_) => {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid aux_blob format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
Err(_) => return server_error(RpcError::MinerInvalidUserData, id, None),
|
||||
};
|
||||
let _: pallas::Base = match pallas::Base::from_repr(bytes).into() {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid aux_blob format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
None => return server_error(RpcError::MinerInvalidUserData, id, None),
|
||||
};
|
||||
};
|
||||
|
||||
// Parse aux_hash
|
||||
let Some(aux_hash) = params.get("aux_hash") else {
|
||||
return JsonError::new(InvalidParams, Some("missing aux_hash".to_string()), id).into()
|
||||
return server_error(RpcError::MinerMissingAuxHash, id, None)
|
||||
};
|
||||
let Some(aux_hash) = aux_hash.get::<String>() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid aux_hash format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAuxHash, id, None)
|
||||
};
|
||||
let Ok(aux_hash) = HeaderHash::from_str(aux_hash) else {
|
||||
return JsonError::new(InvalidParams, Some("invalid aux_hash format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidAuxHash, id, None)
|
||||
};
|
||||
|
||||
// If we don't know about this job, we can just abort here.
|
||||
let mut mm_blocktemplates = self.mm_blocktemplates.lock().await;
|
||||
if !mm_blocktemplates.contains_key(&address_bytes) {
|
||||
return JsonError::new(InvalidParams, Some("unknown address".to_string()), id).into()
|
||||
return server_error(RpcError::MinerUnknownJob, id, None)
|
||||
}
|
||||
|
||||
// Parse blob
|
||||
let Some(blob) = params.get("blob") else {
|
||||
return JsonError::new(InvalidParams, Some("missing blob".to_string()), id).into()
|
||||
return server_error(RpcError::MinerMissingBlob, id, None)
|
||||
};
|
||||
let Some(blob) = blob.get::<String>() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid blob format".to_string()), id).into()
|
||||
return server_error(RpcError::MinerInvalidBlob, id, None)
|
||||
};
|
||||
let Ok(block) = monero_block_deserialize(blob) else {
|
||||
return JsonError::new(InvalidParams, Some("invalid blob format".to_string()), id).into()
|
||||
return server_error(RpcError::MinerInvalidBlob, id, None)
|
||||
};
|
||||
|
||||
// Parse merkle_proof
|
||||
let Some(merkle_proof_j) = params.get("merkle_proof") else {
|
||||
return JsonError::new(InvalidParams, Some("missing merkle_proof".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerMissingMerkleProof, id, None)
|
||||
};
|
||||
let Some(merkle_proof_j) = merkle_proof_j.get::<Vec<JsonValue>>() else {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid merkle_proof format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidMerkleProof, id, None)
|
||||
};
|
||||
let mut merkle_proof: Vec<monero::Hash> = Vec::with_capacity(merkle_proof_j.len());
|
||||
for hash in merkle_proof_j.iter() {
|
||||
match hash.get::<String>() {
|
||||
Some(v) => {
|
||||
let Ok(val) = monero::Hash::from_hex(v) else {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid merkle_proof format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidMerkleProof, id, None)
|
||||
};
|
||||
|
||||
merkle_proof.push(val);
|
||||
}
|
||||
None => {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("invalid merkle_proof format".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
None => return server_error(RpcError::MinerInvalidMerkleProof, id, None),
|
||||
}
|
||||
}
|
||||
|
||||
// Parse path
|
||||
let Some(path) = params.get("path") else {
|
||||
return JsonError::new(InvalidParams, Some("missing path".to_string()), id).into()
|
||||
return server_error(RpcError::MinerMissingPath, id, None)
|
||||
};
|
||||
let Some(path) = path.get::<f64>() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid path format".to_string()), id).into()
|
||||
return server_error(RpcError::MinerInvalidPath, id, None)
|
||||
};
|
||||
let path = *path as u32;
|
||||
|
||||
// Parse seed_hash
|
||||
let Some(seed_hash) = params.get("seed_hash") else {
|
||||
return JsonError::new(InvalidParams, Some("missing seed_hash".to_string()), id).into()
|
||||
return server_error(RpcError::MinerMissingSeedHash, id, None)
|
||||
};
|
||||
let Some(seed_hash) = seed_hash.get::<String>() else {
|
||||
return JsonError::new(InvalidParams, Some("invalid seed_hash format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidSeedHash, id, None)
|
||||
};
|
||||
let Ok(seed_hash) = monero::Hash::from_hex(seed_hash) else {
|
||||
return JsonError::new(InvalidParams, Some("invalid seed_hash format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidSeedHash, id, None)
|
||||
};
|
||||
let Ok(seed_hash) = FixedByteArray::from_bytes(seed_hash.as_bytes()) else {
|
||||
return JsonError::new(InvalidParams, Some("invalid seed_hash format".to_string()), id)
|
||||
.into()
|
||||
return server_error(RpcError::MinerInvalidSeedHash, id, None)
|
||||
};
|
||||
|
||||
info!(
|
||||
@@ -532,12 +473,7 @@ impl DarkfiNode {
|
||||
|
||||
// Construct the MoneroPowData
|
||||
let Some(merkle_proof) = MerkleProof::try_construct(merkle_proof, path) else {
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("could not construct aux chain merkle proof".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
return server_error(RpcError::MinerMerkleProofConstructionFailed, id, None)
|
||||
};
|
||||
let monero_pow_data = match MoneroPowData::new(block, seed_hash, merkle_proof) {
|
||||
Ok(v) => v,
|
||||
@@ -546,12 +482,7 @@ impl DarkfiNode {
|
||||
target: "darkfid::rpc_xmr::xmr_merge_mining_submit_solution",
|
||||
"[RPC-XMR] Failed constructing MoneroPowData: {e}",
|
||||
);
|
||||
return JsonError::new(
|
||||
InvalidParams,
|
||||
Some("failed constructing moneropowdata".to_string()),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
return server_error(RpcError::MinerMoneroPowDataConstructionFailed, id, None)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,10 @@ use darkfi_money_contract::{
|
||||
client::pow_reward_v1::PoWRewardCallBuilder, MoneyFunction, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
|
||||
};
|
||||
use darkfi_sdk::{
|
||||
crypto::{Keypair, MerkleTree, MONEY_CONTRACT_ID},
|
||||
crypto::{
|
||||
keypair::{Keypair, Network},
|
||||
MerkleTree, MONEY_CONTRACT_ID,
|
||||
},
|
||||
ContractCall,
|
||||
};
|
||||
use darkfi_serial::Encodable;
|
||||
@@ -288,8 +291,14 @@ pub async fn generate_node(
|
||||
subscribers.insert("dnet", JsonSubscriber::new("dnet.subscribe_events"));
|
||||
|
||||
let p2p_handler = DarkfidP2pHandler::init(settings, ex).await?;
|
||||
let node =
|
||||
DarkfiNode::new(p2p_handler.clone(), validator.clone(), 50, subscribers.clone()).await?;
|
||||
let node = DarkfiNode::new(
|
||||
Network::Mainnet,
|
||||
p2p_handler.clone(),
|
||||
validator.clone(),
|
||||
50,
|
||||
subscribers.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
p2p_handler.clone().start(ex, &validator, &subscribers).await?;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ use darkfi::{
|
||||
Result,
|
||||
};
|
||||
use darkfi_contract_test_harness::init_logger;
|
||||
use darkfi_sdk::num_traits::One;
|
||||
use darkfi_sdk::{crypto::keypair::Network, num_traits::One};
|
||||
use num_bigint::BigUint;
|
||||
use smol::Executor;
|
||||
use tracing::warn;
|
||||
@@ -288,6 +288,7 @@ fn darkfid_programmatic_control() -> Result<()> {
|
||||
|
||||
// Initialize a daemon
|
||||
let daemon = crate::Darkfid::init(
|
||||
Network::Mainnet,
|
||||
&sled_db,
|
||||
&config,
|
||||
&darkfi::net::Settings::default(),
|
||||
|
||||
@@ -38,7 +38,7 @@ pub fn prettytable_addrs(
|
||||
) -> Table {
|
||||
let mut table = Table::new();
|
||||
table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
|
||||
table.set_titles(row!["Key ID", "Address", "Secret Key", "Is Default"]);
|
||||
table.set_titles(row!["Key ID", "Address", "Public Key", "Secret Key", "Is Default"]);
|
||||
for (key_id, public_key, secret_key, is_default) in addresses {
|
||||
let is_default = match is_default {
|
||||
1 => "*",
|
||||
@@ -46,7 +46,7 @@ pub fn prettytable_addrs(
|
||||
};
|
||||
|
||||
let address: Address = StandardAddress::from_public(network, *public_key).into();
|
||||
table.add_row(row![key_id, address, secret_key, is_default]);
|
||||
table.add_row(row![key_id, address, public_key, secret_key, is_default]);
|
||||
}
|
||||
|
||||
table
|
||||
|
||||
@@ -58,13 +58,13 @@ use darkfi_money_contract::{
|
||||
use darkfi_sdk::{
|
||||
bridgetree,
|
||||
crypto::{
|
||||
keypair::{Address, StandardAddress},
|
||||
keypair::{Address, PublicKey, SecretKey, StandardAddress},
|
||||
pasta_prelude::PrimeField,
|
||||
poseidon_hash,
|
||||
smt::{MemoryStorageFp, PoseidonFp, SmtMemoryFp, EMPTY_NODES_FP},
|
||||
util::{fp_mod_fv, fp_to_u64},
|
||||
BaseBlind, Blind, FuncId, FuncRef, MerkleNode, MerkleTree, PublicKey, ScalarBlind,
|
||||
SecretKey, DAO_CONTRACT_ID, MONEY_CONTRACT_ID,
|
||||
BaseBlind, Blind, FuncId, FuncRef, MerkleNode, MerkleTree, ScalarBlind, DAO_CONTRACT_ID,
|
||||
MONEY_CONTRACT_ID,
|
||||
},
|
||||
dark_tree::DarkTree,
|
||||
pasta::pallas,
|
||||
@@ -1914,7 +1914,9 @@ impl Drk {
|
||||
/// Fetch known unspent balances from the wallet for the given DAO name.
|
||||
pub async fn dao_mining_config(&self, name: &str, output: &mut Vec<String>) -> Result<()> {
|
||||
let dao = self.get_dao_by_name(name).await?;
|
||||
let recipient = dao.params.dao.notes_public_key;
|
||||
let address: Address =
|
||||
StandardAddress::from_public(self.network, dao.params.dao.notes_public_key).into();
|
||||
let recipient = address.to_string();
|
||||
let spend_hook = format!(
|
||||
"{}",
|
||||
FuncRef { contract_id: *DAO_CONTRACT_ID, func_code: DaoFunction::Exec as u8 }
|
||||
|
||||
@@ -1968,6 +1968,8 @@ async fn handle_dao_proposal(drk: &DrkPtr, parts: &[&str], output: &mut Vec<Stri
|
||||
return
|
||||
}
|
||||
};
|
||||
let recipient: Address =
|
||||
StandardAddress::from_public(lock.network, coin.public_key).into();
|
||||
let spend_hook = if coin.spend_hook == FuncId::none() {
|
||||
"-".to_string()
|
||||
} else {
|
||||
@@ -1983,7 +1985,7 @@ async fn handle_dao_proposal(drk: &DrkPtr, parts: &[&str], output: &mut Vec<Stri
|
||||
contract_calls.push_str(&format!(
|
||||
"\n\t\t{}: {}\n\t\t{}: {} ({})\n\t\t{}: {}\n\t\t{}: {}\n\t\t{}: {}\n\t\t{}: {}\n\n",
|
||||
"Recipient",
|
||||
coin.public_key,
|
||||
recipient,
|
||||
"Amount",
|
||||
coin.value,
|
||||
encode_base10(coin.value, BALANCE_BASE10_DECIMALS),
|
||||
|
||||
@@ -46,9 +46,9 @@ use darkfi_dao_contract::{blockwindow, model::DaoProposalBulla, DaoFunction};
|
||||
use darkfi_money_contract::model::{Coin, CoinAttributes, TokenId};
|
||||
use darkfi_sdk::{
|
||||
crypto::{
|
||||
keypair::{Address, Network},
|
||||
keypair::{Address, Keypair, Network, SecretKey, StandardAddress},
|
||||
note::AeadEncryptedNote,
|
||||
BaseBlind, ContractId, FuncId, FuncRef, Keypair, SecretKey, DAO_CONTRACT_ID,
|
||||
BaseBlind, ContractId, FuncId, FuncRef, DAO_CONTRACT_ID,
|
||||
},
|
||||
pasta::{group::ff::PrimeField, pallas},
|
||||
tx::TransactionHash,
|
||||
@@ -600,7 +600,8 @@ struct BlockchainNetwork {
|
||||
async fn parse_blockchain_config(
|
||||
config: Option<String>,
|
||||
network: &str,
|
||||
) -> Result<(BlockchainNetwork, Network)> {
|
||||
) -> Result<(Network, BlockchainNetwork)> {
|
||||
// Grab network
|
||||
let used_net = match network {
|
||||
"mainnet" | "localnet" => Network::Mainnet,
|
||||
"testnet" => Network::Testnet,
|
||||
@@ -641,7 +642,7 @@ async fn parse_blockchain_config(
|
||||
}
|
||||
};
|
||||
|
||||
Ok((network_config, used_net))
|
||||
Ok((used_net, network_config))
|
||||
}
|
||||
|
||||
/// Auxiliary function to create a `Drk` wallet for provided configuration.
|
||||
@@ -672,7 +673,7 @@ async fn new_wallet(
|
||||
async_daemonize!(realmain);
|
||||
async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
|
||||
// Grab blockchain network configuration
|
||||
let (blockchain_config, network) = match args.network.as_str() {
|
||||
let (network, blockchain_config) = match args.network.as_str() {
|
||||
"localnet" => parse_blockchain_config(args.config, "localnet").await?,
|
||||
"testnet" => parse_blockchain_config(args.config, "testnet").await?,
|
||||
"mainnet" => parse_blockchain_config(args.config, "mainnet").await?,
|
||||
@@ -829,7 +830,11 @@ async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
|
||||
}
|
||||
|
||||
WalletSubcmd::Address => match drk.default_address().await {
|
||||
Ok(address) => println!("{address}"),
|
||||
Ok(public_key) => {
|
||||
let address: Address =
|
||||
StandardAddress::from_public(drk.network, public_key).into();
|
||||
println!("{address}");
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to fetch default address: {e}");
|
||||
exit(2);
|
||||
@@ -1681,6 +1686,8 @@ async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
|
||||
}
|
||||
let coin: CoinAttributes =
|
||||
deserialize_async(proposal.data.as_ref().unwrap()).await?;
|
||||
let recipient: Address =
|
||||
StandardAddress::from_public(drk.network, coin.public_key).into();
|
||||
let spend_hook = if coin.spend_hook == FuncId::none() {
|
||||
"-".to_string()
|
||||
} else {
|
||||
@@ -1695,7 +1702,7 @@ async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
|
||||
|
||||
contract_calls.push_str(&format!("\n\t\t{}: {}\n\t\t{}: {} ({})\n\t\t{}: {}\n\t\t{}: {}\n\t\t{}: {}\n\t\t{}: {}\n\n",
|
||||
"Recipient",
|
||||
coin.public_key,
|
||||
recipient,
|
||||
"Amount",
|
||||
coin.value,
|
||||
encode_base10(coin.value, BALANCE_BASE10_DECIMALS),
|
||||
|
||||
@@ -49,8 +49,10 @@ use darkfi_money_contract::{
|
||||
use darkfi_sdk::{
|
||||
bridgetree::Position,
|
||||
crypto::{
|
||||
note::AeadEncryptedNote, pasta_prelude::PrimeField, BaseBlind, FuncId, Keypair, MerkleNode,
|
||||
MerkleTree, PublicKey, ScalarBlind, SecretKey, MONEY_CONTRACT_ID,
|
||||
keypair::{Address, Keypair, PublicKey, SecretKey, StandardAddress},
|
||||
note::AeadEncryptedNote,
|
||||
pasta_prelude::PrimeField,
|
||||
BaseBlind, FuncId, MerkleNode, MerkleTree, ScalarBlind, MONEY_CONTRACT_ID,
|
||||
},
|
||||
dark_tree::DarkLeaf,
|
||||
pasta::pallas,
|
||||
@@ -157,7 +159,8 @@ impl Drk {
|
||||
)?;
|
||||
|
||||
output.push(String::from("New address:"));
|
||||
output.push(format!("{}", keypair.public));
|
||||
let address: Address = StandardAddress::from_public(self.network, keypair.public).into();
|
||||
output.push(format!("{address}"));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -293,6 +296,8 @@ impl Drk {
|
||||
return Err(Error::ParseFailed("[mining_address] Key bytes parsing failed"))
|
||||
};
|
||||
let public_key: PublicKey = deserialize_async(key_bytes).await?;
|
||||
let address: Address = StandardAddress::from_public(self.network, public_key).into();
|
||||
let recipient = address.to_string();
|
||||
|
||||
let spend_hook = spend_hook.as_ref().map(|spend_hook| spend_hook.to_string());
|
||||
|
||||
@@ -300,7 +305,7 @@ impl Drk {
|
||||
user_data.as_ref().map(|user_data| bs58::encode(user_data.to_repr()).into_string());
|
||||
|
||||
output.push(String::from("DarkFi TOML configuration:"));
|
||||
output.push(format!("recipient = \"{public_key}\""));
|
||||
output.push(format!("recipient = \"{recipient}\""));
|
||||
match spend_hook {
|
||||
Some(ref spend_hook) => output.push(format!("spend_hook = \"{spend_hook}\"")),
|
||||
None => output.push(String::from("#spend_hook = \"\"")),
|
||||
@@ -310,7 +315,7 @@ impl Drk {
|
||||
None => output.push(String::from("#user_data = \"\"")),
|
||||
}
|
||||
output.push(String::from("\nP2Pool wallet address to use:"));
|
||||
output.push(base64::encode(&serialize(&(public_key, spend_hook, user_data))).to_string());
|
||||
output.push(base64::encode(&serialize(&(recipient, spend_hook, user_data))).to_string());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ use darkfi::{
|
||||
system::{sleep, ExecutorPtr, StoppableTask, StoppableTaskPtr},
|
||||
Error,
|
||||
};
|
||||
use darkfi_sdk::crypto::Keypair;
|
||||
use darkfi_sdk::crypto::keypair::{Address, Keypair, Network, StandardAddress};
|
||||
|
||||
/// Miner benchmarking related methods
|
||||
pub mod benchmark;
|
||||
@@ -59,6 +59,8 @@ pub struct MinerNodeConfig {
|
||||
|
||||
impl Default for MinerNodeConfig {
|
||||
fn default() -> Self {
|
||||
let address: Address =
|
||||
StandardAddress::from_public(Network::Mainnet, Keypair::default().public).into();
|
||||
Self::new(
|
||||
true,
|
||||
false,
|
||||
@@ -66,10 +68,7 @@ impl Default for MinerNodeConfig {
|
||||
1,
|
||||
5,
|
||||
0,
|
||||
HashMap::from([(
|
||||
String::from("recipient"),
|
||||
JsonValue::String(Keypair::default().public.to_string()),
|
||||
)]),
|
||||
HashMap::from([(String::from("recipient"), JsonValue::String(address.to_string()))]),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ use darkfi::{
|
||||
util::path::get_config_path, Error, Result,
|
||||
};
|
||||
use darkfi_sdk::{
|
||||
crypto::{pasta_prelude::PrimeField, FuncId, PublicKey},
|
||||
crypto::{keypair::Address, pasta_prelude::PrimeField, FuncId},
|
||||
pasta::pallas,
|
||||
};
|
||||
|
||||
@@ -176,7 +176,7 @@ async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
|
||||
debug!(target: "minerd", "Blockchain config: {blockchain_config:?}");
|
||||
|
||||
// Parse the network wallet configuration
|
||||
if PublicKey::from_str(&blockchain_config.recipient).is_err() {
|
||||
if Address::from_str(&blockchain_config.recipient).is_err() {
|
||||
return Err(Error::InvalidAddress)
|
||||
}
|
||||
let mut wallet_config = HashMap::from([(
|
||||
|
||||
@@ -35,7 +35,7 @@ network = "localnet"
|
||||
# Wallet mining address to receive mining rewards.
|
||||
# This is a dummy one so the miner can start,
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
recipient = "DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
@@ -35,7 +35,7 @@ network = "localnet"
|
||||
# Wallet mining address to receive mining rewards.
|
||||
# This is a dummy one so the miner can start,
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
recipient = "DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
@@ -35,7 +35,7 @@ network = "localnet"
|
||||
# Wallet mining address to receive mining rewards.
|
||||
# This is a dummy one so the miner can start,
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
recipient = "DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
@@ -35,7 +35,7 @@ network = "localnet"
|
||||
# Wallet mining address to receive mining rewards.
|
||||
# This is a dummy one so the miner can start,
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
recipient = "DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
@@ -35,7 +35,7 @@ network = "localnet"
|
||||
# Wallet mining address to receive mining rewards.
|
||||
# This is a dummy one so the miner can start,
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
recipient = "DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
rm -rf darkfid drk
|
||||
sed -i -e "s|recipient =.*|recipient = \"9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U\"|g" minerd.toml
|
||||
sed -i -e "s|recipient =.*|recipient = \"DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf\"|g" minerd.toml
|
||||
|
||||
@@ -7,4 +7,4 @@ $DRK wallet initialize
|
||||
$DRK wallet keygen
|
||||
$DRK wallet default-address 1
|
||||
wallet=$($DRK wallet address)
|
||||
sed -i -e "s|9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U|$wallet|g" minerd.toml
|
||||
sed -i -e "s|DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf|$wallet|g" minerd.toml
|
||||
|
||||
@@ -35,7 +35,7 @@ network = "localnet"
|
||||
# Wallet mining address to receive mining rewards.
|
||||
# This is a dummy one so the miner can start,
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
recipient = "DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward.
|
||||
# This is the DAO spend hook set for convinience,
|
||||
|
||||
@@ -68,7 +68,7 @@ wait_dao_mint() {
|
||||
}
|
||||
|
||||
fill_treasury() {
|
||||
PUBKEY="$($DRK dao list AnonDAO | grep '^Notes Public key: ' | cut -d ' ' -f4)"
|
||||
PUBKEY="$($DRK dao list AnonDAO | grep '^Wallet Address: ' | cut -d ' ' -f3)"
|
||||
SPEND_HOOK="$($DRK dao spend-hook)"
|
||||
BULLA="$($DRK dao list AnonDAO | grep '^Bulla: ' | cut -d' ' -f2)"
|
||||
$DRK transfer 20 DAWN "$PUBKEY" "$SPEND_HOOK" "$BULLA" | tee $OUTPUT_FOLDER/xfer.tx | $DRK broadcast
|
||||
|
||||
@@ -35,7 +35,7 @@ network = "localnet"
|
||||
# Wallet mining address to receive mining rewards.
|
||||
# This is a dummy one so the miner can start,
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
recipient = "DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
@@ -35,7 +35,7 @@ network = "localnet"
|
||||
# Wallet mining address to receive mining rewards.
|
||||
# This is a dummy one so the miner can start,
|
||||
# replace with your own one.
|
||||
recipient = "9vw6WznKk7xEFQwwXhJWMMdjUPi3cXL8NrFKQpKifG1U"
|
||||
recipient = "DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf"
|
||||
|
||||
# Optional contract spend hook to use in the mining reward
|
||||
#spend_hook = "YOUR_SPEND_HOOK_HERE"
|
||||
|
||||
@@ -185,11 +185,11 @@ Set it as the default one in the wallet and grab its secret key:
|
||||
```shell
|
||||
drk> wallet addresses
|
||||
|
||||
Key ID | Public Key | Secret Key | Is Default
|
||||
-----------------------+------------------+-----------------------------+------------
|
||||
1 | {NORMAL_ADDRESS} | {NORMAL_ADDRESS_SECRET_KEY} | *
|
||||
Key ID | Address | Public Key | Secret Key | Is Default
|
||||
-----------------------+------------------+-----------------------------+-----------------------------+------------
|
||||
1 | {NORMAL_ADDRESS} | {NORMAL_ADDRESS_PUBLIC_KEY} | {NORMAL_ADDRESS_SECRET_KEY} | *
|
||||
...
|
||||
{DUMMY_ADDRESS_INDEX} | {DUMMY_ADDRESS} | {DUMMY_ADDRESS_SECRET_KEY} |
|
||||
{DUMMY_ADDRESS_INDEX} | {DUMMY_ADDRESS} | {DUMMY_ADDRESS_PUBLIC_KEY} | {DUMMY_ADDRESS_SECRET_KEY} |
|
||||
|
||||
drk> wallet default-address {DUMMY_ADDRESS_INDEX}
|
||||
```
|
||||
|
||||
@@ -725,7 +725,7 @@ configuration, execute:
|
||||
drk> dao mining-config {YOUR_DAO}
|
||||
|
||||
DarkFi TOML configuration:
|
||||
recipient = "{YOUR_DAO_NOTES_PUBLIC_KEY}"
|
||||
recipient = "{YOUR_DAO_WALLET_ADDRESS}"
|
||||
spend_hook = "{DAO_CONTRACT_SPEND_HOOK}"
|
||||
user_data = "{YOUR_DAO_BULLA}"
|
||||
|
||||
@@ -738,8 +738,8 @@ corresponding fields(uncomment if needed) as per retrieved
|
||||
configuration:
|
||||
|
||||
```toml
|
||||
# Put your DAO notes public key here
|
||||
recipient = "{YOUR_DAO_NOTES_PUBLIC_KEY}"
|
||||
# Put your DAO wallet address here
|
||||
recipient = "{YOUR_DAO_WALLET_ADDRESS}"
|
||||
|
||||
# Put the DAO contract spend hook here
|
||||
spend_hook = "{DAO_CONTRACT_SPEND_HOOK}"
|
||||
|
||||
@@ -191,6 +191,12 @@ or press `p` to pause mining.
|
||||
|
||||
## p2pool setup with merge-mining
|
||||
|
||||
> NOTE: `p2pool` uses plain `http` connections for RPC calls, as its
|
||||
> assumed to be running on a localnet. Don't run a `p2pool` instance
|
||||
> with a `darkfid` instance outside of your network, since someone
|
||||
> snooping your traffic can see your wallet address used for the block
|
||||
> rewards.
|
||||
|
||||
Now that everything is in order, we can use `p2pool` with merge-mining
|
||||
enabled in order to merge mine DarkFi. For receiving mining rewards
|
||||
on DarkFi, we'll need a DarkFi wallet address so make sure you have
|
||||
@@ -244,7 +250,7 @@ To retrieve a DAO merge mining configuration, execute:
|
||||
drk> dao mining-config {YOUR_DAO}
|
||||
|
||||
DarkFi TOML configuration:
|
||||
recipient = "{YOUR_DAO_NOTES_PUBLIC_KEY}"
|
||||
recipient = "{YOUR_DAO_WALLET_ADDRESS}"
|
||||
spend_hook = "{DAO_CONTRACT_SPEND_HOOK}"
|
||||
user_data = "{YOUR_DAO_BULLA}"
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ $ ./drk wallet keygen
|
||||
|
||||
Generating a new keypair
|
||||
New address:
|
||||
CbaqFqGTgn86Zh9AjUeMw3DJyVCshaPSPFtmj6Cyd5yU
|
||||
DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf
|
||||
```
|
||||
|
||||
```shell
|
||||
@@ -181,7 +181,7 @@ retrieve your default address using:
|
||||
```shell
|
||||
$ ./drk wallet address
|
||||
|
||||
CbaqFqGTgn86Zh9AjUeMw3DJyVCshaPSPFtmj6Cyd5yU
|
||||
DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf
|
||||
```
|
||||
|
||||
### Miner
|
||||
@@ -244,12 +244,19 @@ You can retrieve your `drk` wallet address as follows:
|
||||
```shell
|
||||
$ ./drk wallet address
|
||||
|
||||
CbaqFqGTgn86Zh9AjUeMw3DJyVCshaPSPFtmj6Cyd5yU
|
||||
DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf
|
||||
```
|
||||
|
||||
Note: when modifying the `minerd` config file to use with the
|
||||
testnet, be sure to change the values under the section marked
|
||||
`[network_config."testnet"]` (not localnet or mainnet!).
|
||||
> Notes:
|
||||
>
|
||||
> When modifying the `minerd` config file to use with the
|
||||
> testnet, be sure to change the values under the section marked
|
||||
> `[network_config."testnet"]` (not localnet or mainnet!).
|
||||
>
|
||||
> If you are not on the same network as the `darkfid` instance you
|
||||
> are using, you must configure and use `tcp+tls` for the RPC
|
||||
> endpoints, so your traffic is not plaintext, as it contains your
|
||||
> wallet address used for the block rewards.
|
||||
|
||||
Once that's in place, you can run it again and `minerd` will start,
|
||||
polling `darkfid` for new block headers to mine.
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
Using the tokens we minted, we can make payments to other addresses.
|
||||
We will use a dummy recepient, but you can also test this with friends.
|
||||
Let's try to send some `ANON` tokens to
|
||||
`8sRwB7AwBTKEkyTW6oMyRoJWZhJwtqGTf7nyHwuJ74pj`:
|
||||
`DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf`:
|
||||
|
||||
```shell
|
||||
drk> transfer 2.69 ANON 8sRwB7AwBTKEkyTW6oMyRoJWZhJwtqGTf7nyHwuJ74pj | broadcast
|
||||
drk> transfer 2.69 ANON DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf | broadcast
|
||||
|
||||
[mark_tx_spend] Processing transaction: 47b4818caec22470427922f506d72788233001a79113907fd1a93b7756b07395
|
||||
[mark_tx_spend] Found Money contract in call 0
|
||||
@@ -16,8 +16,9 @@ Transaction ID: 47b4818caec22470427922f506d72788233001a79113907fd1a93b7756b07395
|
||||
```
|
||||
|
||||
On success we'll see a transaction ID. Now again the same confirmation
|
||||
process has to occur and `8sRwB7AwBTKEkyTW6oMyRoJWZhJwtqGTf7nyHwuJ74pj`
|
||||
will receive the tokens you've sent.
|
||||
process has to occur and
|
||||
`DZnsGMCvZU5CEzvpuExnxbvz6SEhE2rn89sMcuHsppFE6TjL4SBTrKkf` will receive
|
||||
the tokens you've sent.
|
||||
|
||||

|
||||
|
||||
|
||||
Reference in New Issue
Block a user