darkfid2: Update to new RPC dependencies.

This commit is contained in:
parazyd
2023-08-20 13:53:56 +02:00
parent db607de661
commit f85d0d6c46
12 changed files with 154 additions and 181 deletions

View File

@@ -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() {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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!(

View File

@@ -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!(

View File

@@ -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!(

View File

@@ -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()
}
}

View File

@@ -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()
}
}

View File

@@ -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()
}
}

View File

@@ -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()?;

View File

@@ -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;