mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 06:38:12 -05:00
darkfid; Minor cleanups
This commit is contained in:
@@ -42,10 +42,6 @@ mod rpc_blockchain;
|
||||
/// Transactions related methods
|
||||
mod rpc_tx;
|
||||
|
||||
// TODO: drop
|
||||
/// minerd related methods
|
||||
mod rpc_miner;
|
||||
|
||||
/// Stratum JSON-RPC related methods for native mining
|
||||
pub mod rpc_stratum;
|
||||
|
||||
|
||||
@@ -1,434 +0,0 @@
|
||||
/* This file is part of DarkFi (https://dark.fi)
|
||||
*
|
||||
* Copyright (C) 2020-2025 Dyne.org foundation
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::DarkfiNode;
|
||||
|
||||
impl DarkfiNode {
|
||||
/*
|
||||
// RPCAPI:
|
||||
// Queries the validator for the current mining RandomX key,
|
||||
// based on next block height.
|
||||
// If no forks exist, returns the canonical key.
|
||||
// Returns the current mining RandomX key encoded as base64 string.
|
||||
//
|
||||
// **Params:**
|
||||
// * `None`
|
||||
//
|
||||
// **Returns:**
|
||||
// * `String`: Current mining RandomX key (base64 encoded)
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "miner.get_current_mining_randomx_key", "params": [], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": ["randomx_key"], "id": 1}
|
||||
pub async fn miner_get_current_mining_randomx_key(
|
||||
&self,
|
||||
id: u16,
|
||||
params: JsonValue,
|
||||
) -> JsonResult {
|
||||
// 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()
|
||||
}
|
||||
|
||||
// Grab current mining RandomX key
|
||||
let randomx_key = match self.validator.current_mining_randomx_key().await {
|
||||
Ok(key) => key,
|
||||
Err(e) => {
|
||||
error!(
|
||||
target: "darkfid::rpc::current_mining_randomx_key",
|
||||
"[RPC] Retrieving current mining RandomX key failed: {e}",
|
||||
);
|
||||
return JsonError::new(ErrorCode::InternalError, None, id).into()
|
||||
}
|
||||
};
|
||||
|
||||
// Encode them and build response
|
||||
let response = JsonValue::Array(vec![JsonValue::String(base64::encode(
|
||||
&serialize_async(&randomx_key).await,
|
||||
))]);
|
||||
|
||||
JsonResponse::new(response, id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
// Queries the validator for the current best fork next header to
|
||||
// mine.
|
||||
// Returns the current RandomX key, the mining target and the next
|
||||
// block header, all encoded as base64 strings.
|
||||
//
|
||||
// **Params:**
|
||||
// * `header` : Mining job Header hash that is currently being polled (as string)
|
||||
// * `recipient` : Wallet mining address to receive mining rewards (as string)
|
||||
// * `spend_hook`: Optional contract spend hook to use in the mining reward (as string)
|
||||
// * `user_data` : Optional contract user data (not arbitrary data) to use in the mining reward (as string)
|
||||
//
|
||||
// **Returns:**
|
||||
// * `String`: Current best fork RandomX key (base64 encoded)
|
||||
// * `String`: Current best fork mining target (base64 encoded)
|
||||
// * `String`: Current best fork next block header (base64 encoded)
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "miner.get_header", "params": {"header": "hash", "recipient": "address"}, "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": ["randomx_key", "target", "header"], "id": 1}
|
||||
pub async fn miner_get_header(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
// Check if node is synced before responding to miner
|
||||
if !*self.validator.synced.read().await {
|
||||
return server_error(RpcError::NotSynced, id, None)
|
||||
}
|
||||
|
||||
// Parse request params
|
||||
let Some(params) = params.get::<HashMap<String, JsonValue>>() else {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
};
|
||||
if params.len() < 2 || params.len() > 4 {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
// Parse header hash
|
||||
let Some(header_hash) = params.get("header") else {
|
||||
return server_error(RpcError::MinerMissingHeader, id, None)
|
||||
};
|
||||
let Some(header_hash) = header_hash.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidHeader, id, None)
|
||||
};
|
||||
let Ok(header_hash) = HeaderHash::from_str(header_hash) else {
|
||||
return server_error(RpcError::MinerInvalidHeader, id, None)
|
||||
};
|
||||
|
||||
// Parse recipient wallet address
|
||||
let Some(recipient) = params.get("recipient") else {
|
||||
return server_error(RpcError::MinerMissingRecipient, id, None)
|
||||
};
|
||||
let Some(recipient_str) = recipient.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidRecipient, id, None)
|
||||
};
|
||||
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") {
|
||||
Some(spend_hook) => {
|
||||
let Some(spend_hook) = spend_hook.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidSpendHook, id, None)
|
||||
};
|
||||
let Ok(spend_hook) = FuncId::from_str(spend_hook) else {
|
||||
return server_error(RpcError::MinerInvalidSpendHook, id, None)
|
||||
};
|
||||
Some(spend_hook)
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Parse user data
|
||||
let user_data: Option<pallas::Base> = match params.get("user_data") {
|
||||
Some(user_data) => {
|
||||
let Some(user_data) = user_data.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidUserData, id, None)
|
||||
};
|
||||
let Ok(bytes) = bs58::decode(&user_data).into_vec() else {
|
||||
return server_error(RpcError::MinerInvalidUserData, id, None)
|
||||
};
|
||||
let bytes: [u8; 32] = match bytes.try_into() {
|
||||
Ok(b) => b,
|
||||
Err(_) => return server_error(RpcError::MinerInvalidUserData, id, None),
|
||||
};
|
||||
let Some(user_data) = pallas::Base::from_repr(bytes).into() else {
|
||||
return server_error(RpcError::MinerInvalidUserData, id, None)
|
||||
};
|
||||
Some(user_data)
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Now that method params format is correct, we can check if we
|
||||
// already have a mining job for this wallet. If we already
|
||||
// have it, we check if the fork it extends is still the best
|
||||
// one. If both checks pass, we can just return an empty
|
||||
// response if the request `aux_hash` matches the job one,
|
||||
// otherwise return the job block template hash. In case the
|
||||
// best fork has changed, we drop this job and generate a
|
||||
// new one. If we don't know this wallet, we create a new job.
|
||||
// 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_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,
|
||||
Err(e) => {
|
||||
error!(
|
||||
target: "darkfid::rpc::miner_get_header",
|
||||
"[RPC] Finding best fork index failed: {e}",
|
||||
);
|
||||
return JsonError::new(ErrorCode::InternalError, None, id).into()
|
||||
}
|
||||
};
|
||||
if let Some(blocktemplate) = blocktemplates.get(&address_bytes) {
|
||||
let last_proposal = match extended_fork.last_proposal() {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
error!(
|
||||
target: "darkfid::rpc::miner_get_header",
|
||||
"[RPC] Retrieving best fork last proposal failed: {e}",
|
||||
);
|
||||
return JsonError::new(ErrorCode::InternalError, None, id).into()
|
||||
}
|
||||
};
|
||||
if last_proposal.hash == blocktemplate.block.header.previous {
|
||||
return if blocktemplate.block.header.hash() != header_hash {
|
||||
JsonResponse::new(
|
||||
JsonValue::Array(vec![
|
||||
JsonValue::String(blocktemplate.randomx_key.clone()),
|
||||
JsonValue::String(blocktemplate.target.clone()),
|
||||
JsonValue::String(base64::encode(
|
||||
&serialize_async(&blocktemplate.block.header).await,
|
||||
)),
|
||||
]),
|
||||
id,
|
||||
)
|
||||
.into()
|
||||
} else {
|
||||
JsonResponse::new(JsonValue::Array(vec![]), id).into()
|
||||
}
|
||||
}
|
||||
blocktemplates.remove(&address_bytes);
|
||||
}
|
||||
|
||||
// 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 spend_hook_str = match spend_hook {
|
||||
Some(spend_hook) => format!("{spend_hook}"),
|
||||
None => String::from("-"),
|
||||
};
|
||||
let user_data_str = match user_data {
|
||||
Some(user_data) => bs58::encode(user_data.to_repr()).into_string(),
|
||||
None => String::from("-"),
|
||||
};
|
||||
let recipient_config = MinerRewardsRecipientConfig { recipient, spend_hook, user_data };
|
||||
|
||||
// Now let's try to construct the blocktemplate.
|
||||
let (target, block, secret) = match generate_next_block(
|
||||
&mut extended_fork,
|
||||
&recipient_config,
|
||||
&self.powrewardv1_zk.zkbin,
|
||||
&self.powrewardv1_zk.provingkey,
|
||||
self.validator.consensus.module.read().await.target,
|
||||
self.validator.verify_fees,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!(
|
||||
target: "darkfid::rpc::miner_get_header",
|
||||
"[RPC] Failed to generate next blocktemplate: {e}",
|
||||
);
|
||||
return JsonError::new(ErrorCode::InternalError, None, id).into()
|
||||
}
|
||||
};
|
||||
|
||||
// Grab the RandomX key to use.
|
||||
// We only use the next key when the next block is the
|
||||
// height changing one.
|
||||
let randomx_key = if block.header.height > RANDOMX_KEY_CHANGING_HEIGHT &&
|
||||
block.header.height % RANDOMX_KEY_CHANGING_HEIGHT == RANDOMX_KEY_CHANGE_DELAY
|
||||
{
|
||||
base64::encode(&serialize_async(&extended_fork.module.darkfi_rx_keys.1).await)
|
||||
} else {
|
||||
base64::encode(&serialize_async(&extended_fork.module.darkfi_rx_keys.0).await)
|
||||
};
|
||||
|
||||
// Convert the target
|
||||
let target = base64::encode(&target.to_bytes_le());
|
||||
|
||||
// Construct the block template
|
||||
let blocktemplate = BlockTemplate {
|
||||
block,
|
||||
randomx_key: randomx_key.clone(),
|
||||
target: target.clone(),
|
||||
secret,
|
||||
};
|
||||
|
||||
// Now we have the blocktemplate. We'll mark it down in memory,
|
||||
// and then ship it to RPC.
|
||||
let header_hash = blocktemplate.block.header.hash().to_string();
|
||||
let header = base64::encode(&serialize_async(&blocktemplate.block.header).await);
|
||||
blocktemplates.insert(address_bytes, blocktemplate);
|
||||
info!(
|
||||
target: "darkfid::rpc::miner_get_header",
|
||||
"[RPC] Created new blocktemplate: address={recipient_str}, spend_hook={spend_hook_str}, user_data={user_data_str}, hash={header_hash}"
|
||||
);
|
||||
|
||||
let response = JsonValue::Array(vec![
|
||||
JsonValue::String(randomx_key),
|
||||
JsonValue::String(target),
|
||||
JsonValue::String(header),
|
||||
]);
|
||||
|
||||
JsonResponse::new(response, id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
// Submits a PoW solution header nonce for a block.
|
||||
// Returns the block submittion status.
|
||||
//
|
||||
// **Params:**
|
||||
// * `recipient` : Wallet mining address used (as string)
|
||||
// * `spend_hook`: Optional contract spend hook used (as string)
|
||||
// * `user_data` : Optional contract user data (not arbitrary data) used (as string)
|
||||
// * `nonce` : The solution header nonce (as f64)
|
||||
//
|
||||
// **Returns:**
|
||||
// * `String`: Block submit status
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "miner.submit_solution", "params": {"recipient": "address", "nonce": 42}, "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": "accepted", "id": 1}
|
||||
pub async fn miner_submit_solution(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
// Check if node is synced before responding to p2pool
|
||||
if !*self.validator.synced.read().await {
|
||||
return server_error(RpcError::NotSynced, id, None)
|
||||
}
|
||||
|
||||
// Parse request params
|
||||
let Some(params) = params.get::<HashMap<String, JsonValue>>() else {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
};
|
||||
if params.len() < 2 || params.len() > 4 {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
// Parse recipient wallet address
|
||||
let Some(recipient) = params.get("recipient") else {
|
||||
return server_error(RpcError::MinerMissingRecipient, id, None)
|
||||
};
|
||||
let Some(recipient_str) = recipient.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidRecipient, id, None)
|
||||
};
|
||||
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") {
|
||||
Some(spend_hook) => {
|
||||
let Some(spend_hook) = spend_hook.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidSpendHook, id, None)
|
||||
};
|
||||
let Ok(spend_hook) = FuncId::from_str(spend_hook) else {
|
||||
return server_error(RpcError::MinerInvalidSpendHook, id, None)
|
||||
};
|
||||
Some(spend_hook)
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Parse user data
|
||||
let user_data: Option<pallas::Base> = match params.get("user_data") {
|
||||
Some(user_data) => {
|
||||
let Some(user_data) = user_data.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidUserData, id, None)
|
||||
};
|
||||
let Ok(bytes) = bs58::decode(&user_data).into_vec() else {
|
||||
return server_error(RpcError::MinerInvalidUserData, id, None)
|
||||
};
|
||||
let bytes: [u8; 32] = match bytes.try_into() {
|
||||
Ok(b) => b,
|
||||
Err(_) => return server_error(RpcError::MinerInvalidUserData, id, None),
|
||||
};
|
||||
let Some(user_data) = pallas::Base::from_repr(bytes).into() else {
|
||||
return server_error(RpcError::MinerInvalidUserData, id, None)
|
||||
};
|
||||
Some(user_data)
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Parse nonce
|
||||
let Some(nonce) = params.get("nonce") else {
|
||||
return server_error(RpcError::MinerMissingNonce, id, None)
|
||||
};
|
||||
let Some(nonce) = nonce.get::<f64>() else {
|
||||
return server_error(RpcError::MinerInvalidNonce, id, None)
|
||||
};
|
||||
|
||||
// If we don't know about this job, we can just abort here.
|
||||
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)
|
||||
};
|
||||
|
||||
info!(
|
||||
target: "darkfid::rpc::miner_submit_solution",
|
||||
"[RPC] Got solution submission for block template: {}", blocktemplate.block.header.hash(),
|
||||
);
|
||||
|
||||
// Sign the DarkFi block
|
||||
let mut block = blocktemplate.block.clone();
|
||||
block.header.nonce = *nonce as u32;
|
||||
block.sign(&blocktemplate.secret);
|
||||
info!(
|
||||
target: "darkfid::rpc::miner_submit_solution",
|
||||
"[RPC] Mined block header hash: {}", blocktemplate.block.header.hash(),
|
||||
);
|
||||
|
||||
// At this point we should be able to remove the submitted job.
|
||||
// We still won't release the lock in hope of proposing the block
|
||||
// first.
|
||||
blocktemplates.remove(&address_bytes);
|
||||
|
||||
// Propose the new block
|
||||
info!(
|
||||
target: "darkfid::rpc::miner_submit_solution",
|
||||
"[RPC] Proposing new block to network",
|
||||
);
|
||||
let proposal = Proposal::new(block);
|
||||
if let Err(e) = self.validator.append_proposal(&proposal).await {
|
||||
error!(
|
||||
target: "darkfid::rpc::miner_submit_solution",
|
||||
"[RPC] Error proposing new block: {e}",
|
||||
);
|
||||
return JsonResponse::new(JsonValue::String(String::from("rejected")), id).into()
|
||||
}
|
||||
|
||||
let proposals_sub = self.subscribers.get("proposals").unwrap();
|
||||
let enc_prop = JsonValue::String(base64::encode(&serialize_async(&proposal).await));
|
||||
proposals_sub.notify(vec![enc_prop].into()).await;
|
||||
|
||||
info!(
|
||||
target: "darkfid::rpc::miner_submit_solution",
|
||||
"[RPC] Broadcasting new block to network",
|
||||
);
|
||||
let message = ProposalMessage(proposal);
|
||||
self.p2p_handler.p2p.broadcast(&message).await;
|
||||
|
||||
JsonResponse::new(JsonValue::String(String::from("accepted")), id).into()
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -86,6 +86,7 @@ impl DarkfiNode {
|
||||
// * `target` : Current mining target
|
||||
// * `algo` : The mining algorithm - RandomX
|
||||
// * `seed_hash` : Current RandomX key
|
||||
// * `next_seed_hash`: (optional) Next RandomX key if it is known
|
||||
//
|
||||
// --> {"jsonrpc":"2.0", "method": "login", "id": 1, "params": {"login": "MINING_CONFIG", "pass": "", "agent": "XMRig", "algo": ["rx/0"]}}
|
||||
// <-- {"jsonrpc":"2.0", "id": 1, "result": {"id": "1be0b7b6-b15a-47be-a17d-46b2911cf7d0", "job": { ... }, "status": "OK"}}
|
||||
@@ -99,9 +100,6 @@ 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 login mining configuration
|
||||
let Some(wallet) = params.get("login") else {
|
||||
@@ -120,12 +118,9 @@ impl DarkfiNode {
|
||||
let Some(pass) = params.get("pass") else {
|
||||
return server_error(RpcError::MinerMissingPassword, id, None)
|
||||
};
|
||||
let Some(pass) = pass.get::<String>() else {
|
||||
let Some(_pass) = pass.get::<String>() else {
|
||||
return server_error(RpcError::MinerInvalidPassword, id, None)
|
||||
};
|
||||
if pass != "x" {
|
||||
return server_error(RpcError::MinerInvalidPassword, id, None)
|
||||
}
|
||||
|
||||
// Parse agent
|
||||
let Some(agent) = params.get("agent") else {
|
||||
@@ -160,7 +155,10 @@ impl DarkfiNode {
|
||||
}
|
||||
|
||||
// Register the new miner
|
||||
info!(target: "darkfid::rpc::rpc_stratum::stratum_login","[RPC-STRATUM] Got login from {wallet} ({agent})");
|
||||
info!(
|
||||
target: "darkfid::rpc::rpc_stratum::stratum_login",
|
||||
"[RPC-STRATUM] Got login from {wallet} ({agent})",
|
||||
);
|
||||
let (client_id, block_template, publisher) =
|
||||
match self.registry.register_miner(&self.validator, wallet, &config).await {
|
||||
Ok(p) => p,
|
||||
@@ -214,9 +212,6 @@ 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 client id
|
||||
let Some(client_id) = params.get("id") else {
|
||||
@@ -309,7 +304,7 @@ impl DarkfiNode {
|
||||
{
|
||||
error!(
|
||||
target: "darkfid::rpc::rpc_xmr::xmr_merge_submit_solution",
|
||||
"[RPC-XMR] Error submitting new block: {e}",
|
||||
"[RPC-STRATUM] Error submitting new block: {e}",
|
||||
);
|
||||
return JsonResponse::new(
|
||||
JsonValue::from(HashMap::from([(
|
||||
@@ -360,9 +355,6 @@ impl DarkfiNode {
|
||||
let Some(params) = params.get::<HashMap<String, JsonValue>>() else {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
};
|
||||
if params.len() != 1 {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
// Parse client id
|
||||
let Some(client_id) = params.get("id") else {
|
||||
|
||||
@@ -65,10 +65,6 @@ impl RequestHandler<MmRpcHandler> for DarkfiNode {
|
||||
"merge_mining_get_chain_id" => self.xmr_merge_mining_get_chain_id(req.id, req.params).await,
|
||||
"merge_mining_get_aux_block" => self.xmr_merge_mining_get_aux_block(req.id, req.params).await,
|
||||
"merge_mining_submit_solution" => self.xmr_merge_mining_submit_solution(req.id, req.params).await,
|
||||
|
||||
// ==============
|
||||
// Invalid method
|
||||
// ==============
|
||||
_ => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
|
||||
}
|
||||
}
|
||||
@@ -146,9 +142,6 @@ 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 aux_hash
|
||||
let Some(aux_hash) = params.get("aux_hash") else {
|
||||
@@ -261,9 +254,6 @@ 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 aux_hash
|
||||
let Some(aux_hash) = params.get("aux_hash") else {
|
||||
|
||||
Reference in New Issue
Block a user