mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
darkfid2: Update to new RPC dependencies.
This commit is contained in:
@@ -90,10 +90,10 @@ impl Darkfid {
|
||||
//
|
||||
// **Returns:**
|
||||
// * Serialized [`Transaction`](https://darkrenaissance.github.io/darkfi/development/darkfi/tx/struct.Transaction.html)
|
||||
// object
|
||||
// object encoded with base64
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "blockchain.get_tx", "params": ["TxHash"], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": "ABCD...", "id": 1}
|
||||
pub async fn blockchain_get_tx(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if params.len() != 1 || !params[0].is_string() {
|
||||
|
||||
@@ -25,7 +25,7 @@ sled = "0.34.7"
|
||||
|
||||
# JSON-RPC
|
||||
async-trait = "0.1.73"
|
||||
serde_json = "1.0.105"
|
||||
tinyjson = "2.5.1"
|
||||
url = "2.4.0"
|
||||
|
||||
# Daemon
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
use darkfi::rpc::jsonrpc::{ErrorCode::ServerError, JsonError, JsonResult};
|
||||
|
||||
/// Custom RPC errors available for darkfid.
|
||||
@@ -38,7 +36,7 @@ pub enum RpcError {
|
||||
ContractZkasDbNotFound = -32200,
|
||||
}
|
||||
|
||||
fn to_tuple(e: RpcError) -> (i64, String) {
|
||||
fn to_tuple(e: RpcError) -> (i32, String) {
|
||||
let msg = match e {
|
||||
// Transaction-related errors
|
||||
RpcError::TxSimulationFail => "Failed simulating transaction state change",
|
||||
@@ -52,10 +50,10 @@ fn to_tuple(e: RpcError) -> (i64, String) {
|
||||
RpcError::ContractZkasDbNotFound => "zkas database not found for given contract",
|
||||
};
|
||||
|
||||
(e as i64, msg.to_string())
|
||||
(e as i32, msg.to_string())
|
||||
}
|
||||
|
||||
pub fn server_error(e: RpcError, id: Value, msg: Option<&str>) -> JsonResult {
|
||||
pub fn server_error(e: RpcError, id: u16, msg: Option<&str>) -> JsonResult {
|
||||
let (code, default_msg) = to_tuple(e);
|
||||
|
||||
if let Some(message) = msg {
|
||||
|
||||
@@ -28,7 +28,7 @@ use darkfi::{
|
||||
blockchain::BlockInfo,
|
||||
cli_desc,
|
||||
net::{settings::SettingsOpt, P2pPtr},
|
||||
rpc::{jsonrpc::MethodSubscriber, server::listen_and_serve},
|
||||
rpc::{jsonrpc::JsonSubscriber, server::listen_and_serve},
|
||||
util::time::TimeKeeper,
|
||||
validator::{Validator, ValidatorConfig, ValidatorPtr},
|
||||
Result,
|
||||
@@ -110,7 +110,7 @@ pub struct Darkfid {
|
||||
/// Validator(node) pointer
|
||||
validator: ValidatorPtr,
|
||||
/// A map of various subscribers exporting live info from the blockchain
|
||||
subscribers: HashMap<&'static str, MethodSubscriber>,
|
||||
subscribers: HashMap<&'static str, JsonSubscriber>,
|
||||
}
|
||||
|
||||
impl Darkfid {
|
||||
@@ -118,7 +118,7 @@ impl Darkfid {
|
||||
sync_p2p: P2pPtr,
|
||||
consensus_p2p: Option<P2pPtr>,
|
||||
validator: ValidatorPtr,
|
||||
subscribers: HashMap<&'static str, MethodSubscriber>,
|
||||
subscribers: HashMap<&'static str, JsonSubscriber>,
|
||||
) -> Self {
|
||||
Self { sync_p2p, consensus_p2p, validator, subscribers }
|
||||
}
|
||||
@@ -157,11 +157,10 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
|
||||
|
||||
// Here we initialize various subscribers that can export live blockchain/consensus data.
|
||||
let mut subscribers = HashMap::new();
|
||||
subscribers.insert("blocks", MethodSubscriber::new("blockchain.subscribe_blocks".into()));
|
||||
subscribers.insert("txs", MethodSubscriber::new("blockchain.subscribe_txs".into()));
|
||||
subscribers.insert("blocks", JsonSubscriber::new("blockchain.subscribe_blocks"));
|
||||
subscribers.insert("txs", JsonSubscriber::new("blockchain.subscribe_txs"));
|
||||
if args.consensus {
|
||||
subscribers
|
||||
.insert("proposals", MethodSubscriber::new("blockchain.subscribe_proposals".into()));
|
||||
subscribers.insert("proposals", JsonSubscriber::new("blockchain.subscribe_proposals"));
|
||||
}
|
||||
|
||||
// Initialize syncing P2P network
|
||||
|
||||
@@ -29,7 +29,7 @@ use darkfi::{
|
||||
ChannelPtr, Message, MessageSubscription, P2pPtr, ProtocolBase, ProtocolBasePtr,
|
||||
ProtocolJobsManager, ProtocolJobsManagerPtr,
|
||||
},
|
||||
rpc::jsonrpc::MethodSubscriber,
|
||||
rpc::jsonrpc::JsonSubscriber,
|
||||
validator::ValidatorPtr,
|
||||
Result,
|
||||
};
|
||||
@@ -53,7 +53,7 @@ pub struct ProtocolBlock {
|
||||
validator: ValidatorPtr,
|
||||
p2p: P2pPtr,
|
||||
channel_address: Url,
|
||||
subscriber: MethodSubscriber,
|
||||
subscriber: JsonSubscriber,
|
||||
}
|
||||
|
||||
impl ProtocolBlock {
|
||||
@@ -61,7 +61,7 @@ impl ProtocolBlock {
|
||||
channel: ChannelPtr,
|
||||
validator: ValidatorPtr,
|
||||
p2p: P2pPtr,
|
||||
subscriber: MethodSubscriber,
|
||||
subscriber: JsonSubscriber,
|
||||
) -> Result<ProtocolBasePtr> {
|
||||
debug!(
|
||||
target: "validator::protocol_block::init",
|
||||
@@ -124,7 +124,7 @@ impl ProtocolBlock {
|
||||
match self.validator.write().await.append_block(&block_copy.0).await {
|
||||
Ok(()) => {
|
||||
self.p2p.broadcast_with_exclude(&block_copy, &exclude_list).await;
|
||||
self.subscriber.notify(&block_copy).await;
|
||||
self.subscriber.notify(&[block_copy]).await;
|
||||
}
|
||||
Err(e) => {
|
||||
debug!(
|
||||
|
||||
@@ -28,7 +28,7 @@ use darkfi::{
|
||||
ChannelPtr, Message, MessageSubscription, P2pPtr, ProtocolBase, ProtocolBasePtr,
|
||||
ProtocolJobsManager, ProtocolJobsManagerPtr,
|
||||
},
|
||||
rpc::jsonrpc::MethodSubscriber,
|
||||
rpc::jsonrpc::JsonSubscriber,
|
||||
validator::{consensus::Proposal, ValidatorPtr},
|
||||
Result,
|
||||
};
|
||||
@@ -46,7 +46,7 @@ pub struct ProtocolProposal {
|
||||
validator: ValidatorPtr,
|
||||
p2p: P2pPtr,
|
||||
channel_address: Url,
|
||||
subscriber: MethodSubscriber,
|
||||
subscriber: JsonSubscriber,
|
||||
}
|
||||
|
||||
impl ProtocolProposal {
|
||||
@@ -54,7 +54,7 @@ impl ProtocolProposal {
|
||||
channel: ChannelPtr,
|
||||
validator: ValidatorPtr,
|
||||
p2p: P2pPtr,
|
||||
subscriber: MethodSubscriber,
|
||||
subscriber: JsonSubscriber,
|
||||
) -> Result<ProtocolBasePtr> {
|
||||
debug!(
|
||||
target: "validator::protocol_proposal::init",
|
||||
@@ -114,7 +114,7 @@ impl ProtocolProposal {
|
||||
match self.validator.write().await.consensus.append_proposal(&proposal_copy.0).await {
|
||||
Ok(()) => {
|
||||
self.p2p.broadcast_with_exclude(&proposal_copy, &exclude_list).await;
|
||||
self.subscriber.notify(&proposal_copy).await;
|
||||
self.subscriber.notify(&[proposal_copy]).await;
|
||||
}
|
||||
Err(e) => {
|
||||
debug!(
|
||||
|
||||
@@ -28,7 +28,7 @@ use darkfi::{
|
||||
ChannelPtr, Message, MessageSubscription, P2pPtr, ProtocolBase, ProtocolBasePtr,
|
||||
ProtocolJobsManager, ProtocolJobsManagerPtr,
|
||||
},
|
||||
rpc::jsonrpc::MethodSubscriber,
|
||||
rpc::jsonrpc::JsonSubscriber,
|
||||
tx::Transaction,
|
||||
validator::ValidatorPtr,
|
||||
Result,
|
||||
@@ -47,7 +47,7 @@ pub struct ProtocolTx {
|
||||
validator: ValidatorPtr,
|
||||
p2p: P2pPtr,
|
||||
channel_address: Url,
|
||||
subscriber: MethodSubscriber,
|
||||
subscriber: JsonSubscriber,
|
||||
}
|
||||
|
||||
impl ProtocolTx {
|
||||
@@ -55,7 +55,7 @@ impl ProtocolTx {
|
||||
channel: ChannelPtr,
|
||||
validator: ValidatorPtr,
|
||||
p2p: P2pPtr,
|
||||
subscriber: MethodSubscriber,
|
||||
subscriber: JsonSubscriber,
|
||||
) -> Result<ProtocolBasePtr> {
|
||||
debug!(
|
||||
target: "validator::protocol_tx::init",
|
||||
@@ -110,7 +110,7 @@ impl ProtocolTx {
|
||||
match self.validator.write().await.append_tx(&tx_copy.0).await {
|
||||
Ok(()) => {
|
||||
self.p2p.broadcast_with_exclude(&tx_copy, &exclude_list).await;
|
||||
self.subscriber.notify(&tx_copy).await;
|
||||
self.subscriber.notify(&[tx_copy]).await;
|
||||
}
|
||||
Err(e) => {
|
||||
debug!(
|
||||
|
||||
@@ -18,10 +18,9 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use log::debug;
|
||||
use serde_json::{json, Value};
|
||||
use tinyjson::JsonValue;
|
||||
|
||||
use darkfi::{
|
||||
net,
|
||||
rpc::{
|
||||
jsonrpc::{ErrorCode, JsonError, JsonRequest, JsonResponse, JsonResult},
|
||||
server::RequestHandler,
|
||||
@@ -34,80 +33,62 @@ use crate::Darkfid;
|
||||
#[async_trait]
|
||||
impl RequestHandler for Darkfid {
|
||||
async fn handle_request(&self, req: JsonRequest) -> JsonResult {
|
||||
if req.params.as_array().is_none() {
|
||||
return JsonError::new(ErrorCode::InvalidRequest, None, req.id).into()
|
||||
}
|
||||
|
||||
let params = req.params.as_array().unwrap();
|
||||
|
||||
debug!(target: "darkfid::rpc", "--> {}", serde_json::to_string(&req).unwrap());
|
||||
debug!(target: "darkfid::rpc", "--> {}", req.stringify().unwrap());
|
||||
|
||||
match req.method.as_str() {
|
||||
// =====================
|
||||
// Miscellaneous methods
|
||||
// =====================
|
||||
Some("ping") => return self.pong(req.id, params).await,
|
||||
Some("clock") => return self.clock(req.id, params).await,
|
||||
Some("sync_dnet_switch") => return self.sync_dnet_switch(req.id, params).await,
|
||||
Some("sync_dnet_info") => return self.sync_dnet_info(req.id, params).await,
|
||||
Some("consensus_dnet_switch") => {
|
||||
return self.consensus_dnet_switch(req.id, params).await
|
||||
}
|
||||
Some("consensus_dnet_info") => return self.consensus_dnet_info(req.id, params).await,
|
||||
"ping" => return self.pong(req.id, req.params).await,
|
||||
"clock" => return self.clock(req.id, req.params).await,
|
||||
"sync_dnet_switch" => return self.sync_dnet_switch(req.id, req.params).await,
|
||||
"consensus_dnet_switch" => return self.consensus_dnet_switch(req.id, req.params).await,
|
||||
|
||||
// ==================
|
||||
// Blockchain methods
|
||||
// ==================
|
||||
Some("blockchain.get_slot") => return self.blockchain_get_slot(req.id, params).await,
|
||||
Some("blockchain.get_tx") => return self.blockchain_get_tx(req.id, params).await,
|
||||
Some("blockchain.last_known_slot") => {
|
||||
return self.blockchain_last_known_slot(req.id, params).await
|
||||
"blockchain.get_slot" => return self.blockchain_get_slot(req.id, req.params).await,
|
||||
"blockchain.get_tx" => return self.blockchain_get_tx(req.id, req.params).await,
|
||||
"blockchain.last_known_slot" => {
|
||||
return self.blockchain_last_known_slot(req.id, req.params).await
|
||||
}
|
||||
Some("blockchain.lookup_zkas") => {
|
||||
return self.blockchain_lookup_zkas(req.id, params).await
|
||||
"blockchain.lookup_zkas" => {
|
||||
return self.blockchain_lookup_zkas(req.id, req.params).await
|
||||
}
|
||||
Some("blockchain.subscribe_blocks") => {
|
||||
return self.blockchain_subscribe_blocks(req.id, params).await
|
||||
"blockchain.subscribe_blocks" => {
|
||||
return self.blockchain_subscribe_blocks(req.id, req.params).await
|
||||
}
|
||||
Some("blockchain.subscribe_txs") => {
|
||||
return self.blockchain_subscribe_txs(req.id, params).await
|
||||
"blockchain.subscribe_txs" => {
|
||||
return self.blockchain_subscribe_txs(req.id, req.params).await
|
||||
}
|
||||
Some("blockchain.subscribe_proposals") => {
|
||||
return self.blockchain_subscribe_proposals(req.id, params).await
|
||||
"blockchain.subscribe_proposals" => {
|
||||
return self.blockchain_subscribe_proposals(req.id, req.params).await
|
||||
}
|
||||
|
||||
// ===================
|
||||
// Transaction methods
|
||||
// ===================
|
||||
Some("tx.simulate") => return self.tx_simulate(req.id, params).await,
|
||||
Some("tx.broadcast") => return self.tx_broadcast(req.id, params).await,
|
||||
Some("tx.pending") => return self.tx_pending(req.id, params).await,
|
||||
Some("tx.clean_pending") => return self.tx_pending(req.id, params).await,
|
||||
"tx.simulate" => return self.tx_simulate(req.id, req.params).await,
|
||||
"tx.broadcast" => return self.tx_broadcast(req.id, req.params).await,
|
||||
"tx.pending" => return self.tx_pending(req.id, req.params).await,
|
||||
"tx.clean_pending" => return self.tx_pending(req.id, req.params).await,
|
||||
|
||||
// ==============
|
||||
// Invalid method
|
||||
// ==============
|
||||
Some(_) | None => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
|
||||
_ => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Darkfid {
|
||||
// RPCAPI:
|
||||
// Replies to a ping method.
|
||||
// --> {"jsonrpc": "2.0", "method": "ping", "params": [], "id": 42}
|
||||
// <-- {"jsonrpc": "2.0", "result": "pong", "id": 42}
|
||||
async fn pong(&self, id: Value, _params: &[Value]) -> JsonResult {
|
||||
JsonResponse::new(json!("pong"), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
// Returns current system clock in `Timestamp` format.
|
||||
// Returns current system clock as `u64` (String) timestamp.
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "clock", "params": [], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
|
||||
async fn clock(&self, id: Value, _params: &[Value]) -> JsonResult {
|
||||
JsonResponse::new(json!(Timestamp::current_time()), id).into()
|
||||
// <-- {"jsonrpc": "2.0", "result": "1234", "id": 1}
|
||||
async fn clock(&self, id: u16, _params: JsonValue) -> JsonResult {
|
||||
JsonResponse::new(JsonValue::String(Timestamp::current_time().0.to_string()), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
@@ -117,28 +98,21 @@ impl Darkfid {
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "sync_dnet_switch", "params": [true], "id": 42}
|
||||
// <-- {"jsonrpc": "2.0", "result": true, "id": 42}
|
||||
async fn sync_dnet_switch(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
if params.len() != 1 && params[0].as_bool().is_none() {
|
||||
async fn sync_dnet_switch(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if params.len() != 1 || !params[0].is_bool() {
|
||||
return JsonError::new(ErrorCode::InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
if params[0].as_bool().unwrap() {
|
||||
let switch = params[0].get::<bool>().unwrap();
|
||||
|
||||
if *switch {
|
||||
self.sync_p2p.dnet_enable().await;
|
||||
} else {
|
||||
self.sync_p2p.dnet_disable().await;
|
||||
}
|
||||
|
||||
JsonResponse::new(json!(true), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
// Retrieves sync P2P network information.
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "sync_dnet_info", "params": [], "id": 42}
|
||||
// <-- {"jsonrpc": "2.0", result": {"nodeID": [], "nodeinfo": [], "id": 42}
|
||||
async fn sync_dnet_info(&self, id: Value, _params: &[Value]) -> JsonResult {
|
||||
let dnet_info = self.sync_p2p.dnet_info().await;
|
||||
JsonResponse::new(net::P2p::map_dnet_info(dnet_info), id).into()
|
||||
JsonResponse::new(JsonValue::Boolean(true), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
@@ -148,33 +122,21 @@ impl Darkfid {
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "consensus_dnet_switch", "params": [true], "id": 42}
|
||||
// <-- {"jsonrpc": "2.0", "result": true, "id": 42}
|
||||
async fn consensus_dnet_switch(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
if params.len() != 1 && params[0].as_bool().is_none() {
|
||||
async fn consensus_dnet_switch(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if params.len() != 1 || !params[0].is_bool() {
|
||||
return JsonError::new(ErrorCode::InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
if self.consensus_p2p.is_some() {
|
||||
if params[0].as_bool().unwrap() {
|
||||
let switch = params[0].get::<bool>().unwrap();
|
||||
if *switch {
|
||||
self.consensus_p2p.clone().unwrap().dnet_enable().await;
|
||||
} else {
|
||||
self.consensus_p2p.clone().unwrap().dnet_disable().await;
|
||||
}
|
||||
}
|
||||
|
||||
JsonResponse::new(json!(true), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
// Retrieves consensus P2P network information.
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "consensus_dnet_info", "params": [], "id": 42}
|
||||
// <-- {"jsonrpc": "2.0", result": {"nodeID": [], "nodeinfo": [], "id": 42}
|
||||
async fn consensus_dnet_info(&self, id: Value, _params: &[Value]) -> JsonResult {
|
||||
let dnet_info = if self.consensus_p2p.is_some() {
|
||||
self.consensus_p2p.clone().unwrap().dnet_info().await
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
JsonResponse::new(net::P2p::map_dnet_info(dnet_info), id).into()
|
||||
JsonResponse::new(JsonValue::Boolean(true), id).into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,15 @@ use std::str::FromStr;
|
||||
use darkfi_sdk::crypto::ContractId;
|
||||
use darkfi_serial::{deserialize, serialize};
|
||||
use log::{debug, error};
|
||||
use serde_json::{json, Value};
|
||||
use tinyjson::JsonValue;
|
||||
|
||||
use darkfi::{
|
||||
rpc::jsonrpc::{
|
||||
ErrorCode::{InternalError, InvalidParams, ParseError},
|
||||
JsonError, JsonResponse, JsonResult, JsonSubscriber,
|
||||
JsonError, JsonResponse, JsonResult,
|
||||
},
|
||||
runtime::vm_runtime::SMART_CONTRACT_ZKAS_DB_NAME,
|
||||
util::encoding::base64,
|
||||
};
|
||||
|
||||
use crate::{server_error, Darkfid, RpcError};
|
||||
@@ -39,20 +40,24 @@ impl Darkfid {
|
||||
// Returns a readable block upon success.
|
||||
//
|
||||
// **Params:**
|
||||
// * `array[0]`: `u64` slot ID
|
||||
// * `array[0]`: `u64` slot ID (as string)
|
||||
//
|
||||
// **Returns:**
|
||||
// * [`BlockInfo`](https://darkrenaissance.github.io/darkfi/development/darkfi/consensus/block/struct.BlockInfo.html)
|
||||
// struct as a JSON object
|
||||
// struct serialized into base64.
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "blockchain.get_slot", "params": [0], "id": 1}
|
||||
// --> {"jsonrpc": "2.0", "method": "blockchain.get_slot", "params": ["0"], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
|
||||
pub async fn blockchain_get_slot(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
if params.len() != 1 || !params[0].is_u64() {
|
||||
pub async fn blockchain_get_slot(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if params.len() != 1 || !params[0].is_string() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
let slot = params[0].as_u64().unwrap();
|
||||
let slot = match u64::from_str_radix(params[0].get::<String>().unwrap(), 10) {
|
||||
Ok(v) => v,
|
||||
Err(_) => return JsonError::new(ParseError, None, id).into(),
|
||||
};
|
||||
|
||||
let blocks = match self.validator.read().await.blockchain.get_blocks_by_slot(&[slot]) {
|
||||
Ok(v) => v,
|
||||
@@ -66,7 +71,8 @@ impl Darkfid {
|
||||
return server_error(RpcError::UnknownSlot, id, None)
|
||||
}
|
||||
|
||||
JsonResponse::new(json!(serialize(&blocks[0])), id).into()
|
||||
let block = base64::encode(&serialize(&blocks[0]));
|
||||
JsonResponse::new(JsonValue::String(block), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
@@ -78,25 +84,20 @@ impl Darkfid {
|
||||
//
|
||||
// **Returns:**
|
||||
// * Serialized [`Transaction`](https://darkrenaissance.github.io/darkfi/development/darkfi/tx/struct.Transaction.html)
|
||||
// object
|
||||
// object encoded with base64
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "blockchain.get_tx", "params": ["TxHash"], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
|
||||
pub async fn blockchain_get_tx(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
// <-- {"jsonrpc": "2.0", "result": "ABCD...", "id": 1}
|
||||
pub async fn blockchain_get_tx(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if params.len() != 1 {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
let tx_hash_str = if let Some(tx_hash_str) = params[0].as_str() {
|
||||
tx_hash_str
|
||||
} else {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
};
|
||||
|
||||
let tx_hash = if let Ok(tx_hash) = blake3::Hash::from_hex(tx_hash_str) {
|
||||
tx_hash
|
||||
} else {
|
||||
return JsonError::new(ParseError, None, id).into()
|
||||
let tx_hash = params[0].get::<String>().unwrap();
|
||||
let tx_hash = match blake3::Hash::from_hex(tx_hash) {
|
||||
Ok(v) => v,
|
||||
Err(_) => return JsonError::new(ParseError, None, id).into(),
|
||||
};
|
||||
|
||||
let txs = match self.validator.read().await.blockchain.transactions.get(&[tx_hash], true) {
|
||||
@@ -111,7 +112,8 @@ impl Darkfid {
|
||||
// and strict was used during .get()
|
||||
let tx = txs[0].as_ref().unwrap();
|
||||
|
||||
JsonResponse::new(json!(serialize(tx)), id).into()
|
||||
let tx_enc = base64::encode(&serialize(tx));
|
||||
JsonResponse::new(JsonValue::String(tx_enc), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
@@ -121,11 +123,12 @@ impl Darkfid {
|
||||
// * `None`
|
||||
//
|
||||
// **Returns:**
|
||||
// * `u64` ID of the last known slot
|
||||
// * `u64` ID of the last known slot, as string
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "blockchain.last_known_slot", "params": [], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": 1234, "id": 1}
|
||||
pub async fn blockchain_last_known_slot(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
// <-- {"jsonrpc": "2.0", "result": "1234", "id": 1}
|
||||
pub async fn blockchain_last_known_slot(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if !params.is_empty() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
@@ -135,7 +138,7 @@ impl Darkfid {
|
||||
return JsonError::new(InternalError, None, id).into()
|
||||
};
|
||||
|
||||
JsonResponse::new(json!(last_slot.0), id).into()
|
||||
JsonResponse::new(JsonValue::String(last_slot.0.to_string()), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
@@ -145,14 +148,13 @@ impl Darkfid {
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "blockchain.subscribe_blocks", "params": [], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "method": "blockchain.subscribe_blocks", "params": [`blockinfo`]}
|
||||
pub async fn blockchain_subscribe_blocks(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
pub async fn blockchain_subscribe_blocks(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if !params.is_empty() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
let blocks_subscriber = self.subscribers.get("blocks").unwrap().clone();
|
||||
|
||||
JsonSubscriber::new(blocks_subscriber).into()
|
||||
self.subscribers.get("blocks").unwrap().clone().into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
@@ -162,14 +164,13 @@ impl Darkfid {
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "blockchain.subscribe_txs", "params": [], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "method": "blockchain.subscribe_txs", "params": [`tx_hash`]}
|
||||
pub async fn blockchain_subscribe_txs(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
pub async fn blockchain_subscribe_txs(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if !params.is_empty() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
let txs_subscriber = self.subscribers.get("txs").unwrap().clone();
|
||||
|
||||
JsonSubscriber::new(txs_subscriber).into()
|
||||
self.subscribers.get("txs").unwrap().clone().into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
@@ -179,7 +180,8 @@ impl Darkfid {
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "blockchain.subscribe_proposals", "params": [], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "method": "blockchain.subscribe_proposals", "params": [`blockinfo`]}
|
||||
pub async fn blockchain_subscribe_proposals(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
pub async fn blockchain_subscribe_proposals(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if !params.is_empty() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
@@ -192,7 +194,7 @@ impl Darkfid {
|
||||
return JsonError::new(InternalError, None, id).into()
|
||||
}
|
||||
|
||||
JsonSubscriber::new(proposals_subscriber.unwrap().clone()).into()
|
||||
proposals_subscriber.unwrap().clone().into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
@@ -208,13 +210,15 @@ impl Darkfid {
|
||||
// object
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "blockchain.lookup_zkas", "params": ["6Ef42L1KLZXBoxBuCDto7coi9DA2D2SRtegNqNU4sd74"], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": [["Foo", [...]], ["Bar", [...]]], "id": 1}
|
||||
pub async fn blockchain_lookup_zkas(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
// <-- {"jsonrpc": "2.0", "result": [["Foo", "ABCD..."], ["Bar", "EFGH..."]], "id": 1}
|
||||
pub async fn blockchain_lookup_zkas(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if params.len() != 1 || !params[0].is_string() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
|
||||
let contract_id = match ContractId::from_str(params[0].as_str().unwrap()) {
|
||||
let contract_id = params[0].get::<String>().unwrap();
|
||||
let contract_id = match ContractId::from_str(contract_id) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!(target: "darkfid::rpc::blockchain_lookup_zkas", "Error decoding string to ContractId: {}", e);
|
||||
@@ -236,7 +240,7 @@ impl Darkfid {
|
||||
return server_error(RpcError::ContractZkasDbNotFound, id, None)
|
||||
};
|
||||
|
||||
let mut ret: Vec<(String, Vec<u8>)> = vec![];
|
||||
let mut ret = vec![];
|
||||
|
||||
for i in zkas_db.iter() {
|
||||
debug!(target: "darkfid::rpc::blockchain_lookup_zkas", "Iterating over zkas db");
|
||||
@@ -249,15 +253,13 @@ impl Darkfid {
|
||||
return JsonError::new(InternalError, None, id).into()
|
||||
};
|
||||
|
||||
let Ok((zkas_bincode, _)): Result<(Vec<u8>, Vec<u8>), std::io::Error> =
|
||||
deserialize(&zkas_bytes)
|
||||
else {
|
||||
return JsonError::new(InternalError, None, id).into()
|
||||
};
|
||||
|
||||
ret.push((zkas_ns, zkas_bincode.to_vec()));
|
||||
let zkas_bincode = base64::encode(&zkas_bytes);
|
||||
ret.push(JsonValue::Array(vec![
|
||||
JsonValue::String(zkas_ns),
|
||||
JsonValue::String(zkas_bincode),
|
||||
]));
|
||||
}
|
||||
|
||||
JsonResponse::new(json!(ret), id).into()
|
||||
JsonResponse::new(JsonValue::Array(ret), id).into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
use darkfi_serial::deserialize;
|
||||
use log::error;
|
||||
use serde_json::{json, Value};
|
||||
use tinyjson::JsonValue;
|
||||
|
||||
use darkfi::{
|
||||
rpc::jsonrpc::{
|
||||
@@ -26,6 +26,7 @@ use darkfi::{
|
||||
JsonError, JsonResponse, JsonResult,
|
||||
},
|
||||
tx::Transaction,
|
||||
util::encoding::base64,
|
||||
};
|
||||
|
||||
use super::Darkfid;
|
||||
@@ -37,9 +38,10 @@ impl Darkfid {
|
||||
// Returns `true` if the transaction is valid, otherwise, a corresponding
|
||||
// error.
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "tx.simulate", "params": ["base58encodedTX"], "id": 1}
|
||||
// --> {"jsonrpc": "2.0", "method": "tx.simulate", "params": ["base64encodedTX"], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": true, "id": 1}
|
||||
pub async fn tx_simulate(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
pub async fn tx_simulate(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if params.len() != 1 || !params[0].is_string() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
@@ -50,10 +52,11 @@ impl Darkfid {
|
||||
}
|
||||
|
||||
// Try to deserialize the transaction
|
||||
let tx_bytes = match bs58::decode(params[0].as_str().unwrap().trim()).into_vec() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!(target: "darkfid::rpc::tx_simulate", "Failed decoding base58 transaction: {}", e);
|
||||
let tx_enc = params[0].get::<String>().unwrap().trim();
|
||||
let tx_bytes = match base64::decode(tx_enc) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
error!(target: "darkfid::rpc::tx_simulate", "Failed decoding base64 transaction");
|
||||
return server_error(RpcError::ParseError, id, None)
|
||||
}
|
||||
};
|
||||
@@ -78,7 +81,7 @@ impl Darkfid {
|
||||
return server_error(RpcError::TxSimulationFail, id, None)
|
||||
};
|
||||
|
||||
JsonResponse::new(json!(true), id).into()
|
||||
JsonResponse::new(JsonValue::Boolean(true), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
@@ -87,9 +90,10 @@ impl Darkfid {
|
||||
// if the transaction is actually valid, and in turn it will return an
|
||||
// error if this is the case. Otherwise, a transaction ID will be returned.
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "tx.broadcast", "params": ["base58encodedTX"], "id": 1}
|
||||
// --> {"jsonrpc": "2.0", "method": "tx.broadcast", "params": ["base64encodedTX"], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": "txID...", "id": 1}
|
||||
pub async fn tx_broadcast(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
pub async fn tx_broadcast(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if params.len() != 1 || !params[0].is_string() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
@@ -100,10 +104,11 @@ impl Darkfid {
|
||||
}
|
||||
|
||||
// Try to deserialize the transaction
|
||||
let tx_bytes = match bs58::decode(params[0].as_str().unwrap().trim()).into_vec() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!(target: "darkfid::rpc::tx_broadcast", "Failed decoding base58 transaction: {}", e);
|
||||
let tx_enc = params[0].get::<String>().unwrap().trim();
|
||||
let tx_bytes = match base64::decode(tx_enc) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
error!(target: "darkfid::rpc::tx_broadcast", "Failed decoding base64 transaction");
|
||||
return server_error(RpcError::ParseError, id, None)
|
||||
}
|
||||
};
|
||||
@@ -145,16 +150,17 @@ impl Darkfid {
|
||||
}
|
||||
|
||||
let tx_hash = tx.hash().to_string();
|
||||
JsonResponse::new(json!(tx_hash), id).into()
|
||||
JsonResponse::new(JsonValue::String(tx_hash), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
// Queries the node pending transactions store to retrieve all transactions.
|
||||
// Returns a vector of serialized `Transaction` objects.
|
||||
// Returns a vector of hex-encoded transaction hashes.
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "tx.pending", "params": [], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": "[TxHash,...]", "id": 1}
|
||||
pub async fn tx_pending(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
pub async fn tx_pending(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if !params.is_empty() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
@@ -171,17 +177,21 @@ impl Darkfid {
|
||||
return JsonError::new(InternalError, None, id).into()
|
||||
}
|
||||
};
|
||||
let pending_txs: Vec<String> = pending_txs.iter().map(|x| x.hash().to_string()).collect();
|
||||
JsonResponse::new(json!(pending_txs), id).into()
|
||||
|
||||
let pending_txs: Vec<JsonValue> =
|
||||
pending_txs.iter().map(|x| JsonValue::String(x.hash().to_string())).collect();
|
||||
|
||||
JsonResponse::new(JsonValue::Array(pending_txs), id).into()
|
||||
}
|
||||
|
||||
// RPCAPI:
|
||||
// Queries the node pending transactions store to remove all transactions.
|
||||
// Returns a vector of serialized `Transaction` objects.
|
||||
// Returns a vector of hex-encoded transaction hashes.
|
||||
//
|
||||
// --> {"jsonrpc": "2.0", "method": "tx.clean_pending", "params": [], "id": 1}
|
||||
// <-- {"jsonrpc": "2.0", "result": "[TxHash,...]", "id": 1}
|
||||
pub async fn tx_clean_pending(&self, id: Value, params: &[Value]) -> JsonResult {
|
||||
pub async fn tx_clean_pending(&self, id: u16, params: JsonValue) -> JsonResult {
|
||||
let params = params.get::<Vec<JsonValue>>().unwrap();
|
||||
if !params.is_empty() {
|
||||
return JsonError::new(InvalidParams, None, id).into()
|
||||
}
|
||||
@@ -204,7 +214,9 @@ impl Darkfid {
|
||||
return JsonError::new(InternalError, None, id).into()
|
||||
};
|
||||
|
||||
let pending_txs: Vec<String> = pending_txs.iter().map(|x| x.hash().to_string()).collect();
|
||||
JsonResponse::new(json!(pending_txs), id).into()
|
||||
let pending_txs: Vec<JsonValue> =
|
||||
pending_txs.iter().map(|x| JsonValue::String(x.hash().to_string())).collect();
|
||||
|
||||
JsonResponse::new(JsonValue::Array(pending_txs), id).into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ pub async fn sync_task(node: &Darkfid) -> Result<()> {
|
||||
|
||||
// Notify subscriber
|
||||
for block in &response.blocks {
|
||||
notif_sub.notify(block).await;
|
||||
notif_sub.notify(&[block.clone()]).await;
|
||||
}
|
||||
|
||||
let last_received = node.validator.read().await.blockchain.last()?;
|
||||
|
||||
@@ -23,7 +23,7 @@ use log::info;
|
||||
use darkfi::{
|
||||
error::TxVerifyFailed,
|
||||
net::{P2p, P2pPtr, Settings, SESSION_ALL},
|
||||
rpc::jsonrpc::MethodSubscriber,
|
||||
rpc::jsonrpc::JsonSubscriber,
|
||||
tx::Transaction,
|
||||
validator::ValidatorPtr,
|
||||
Result,
|
||||
@@ -75,7 +75,7 @@ pub fn genesis_txs_total(txs: &[Transaction]) -> Result<u64> {
|
||||
pub async fn spawn_sync_p2p(
|
||||
settings: &Settings,
|
||||
validator: &ValidatorPtr,
|
||||
subscribers: &HashMap<&'static str, MethodSubscriber>,
|
||||
subscribers: &HashMap<&'static str, JsonSubscriber>,
|
||||
) -> P2pPtr {
|
||||
info!(target: "darkfid", "Registering sync network P2P protocols...");
|
||||
let p2p = P2p::new(settings.clone()).await;
|
||||
@@ -116,7 +116,7 @@ pub async fn spawn_sync_p2p(
|
||||
pub async fn spawn_consensus_p2p(
|
||||
settings: &Settings,
|
||||
validator: &ValidatorPtr,
|
||||
subscribers: &HashMap<&'static str, MethodSubscriber>,
|
||||
subscribers: &HashMap<&'static str, JsonSubscriber>,
|
||||
) -> P2pPtr {
|
||||
info!(target: "darkfid", "Registering consensus network P2P protocols...");
|
||||
let p2p = P2p::new(settings.clone()).await;
|
||||
|
||||
Reference in New Issue
Block a user