From e758949d92280ef7a4bbfa0956a20b17f6f405a2 Mon Sep 17 00:00:00 2001 From: parazyd Date: Thu, 4 Aug 2022 17:49:37 +0200 Subject: [PATCH] darkfid: Implement RPC endpoint for building a merkle path from leaf position. --- Cargo.lock | 1 + bin/darkfid/Cargo.toml | 1 + bin/darkfid/src/main.rs | 1 + bin/darkfid/src/rpc_wallet.rs | 25 +++++++++++++++++++++++++ 4 files changed, 28 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index c32930c46..7fc4edc64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1271,6 +1271,7 @@ dependencies = [ "easy-parallel", "futures-lite", "fxhash", + "incrementalmerkletree", "lazy-init", "log", "num-bigint", diff --git a/bin/darkfid/Cargo.toml b/bin/darkfid/Cargo.toml index cca0ffb05..96e2f95f9 100644 --- a/bin/darkfid/Cargo.toml +++ b/bin/darkfid/Cargo.toml @@ -21,6 +21,7 @@ darkfi = {path = "../../", features = ["blockchain", "wallet", "rpc", "net", "no easy-parallel = "3.2.0" futures-lite = "1.12.0" fxhash = "0.2.1" +incrementalmerkletree = "0.3.0" lazy-init = "0.5.1" log = "0.4.17" num-bigint = {version = "0.4.3", features = ["serde"]} diff --git a/bin/darkfid/src/main.rs b/bin/darkfid/src/main.rs index abae773c9..70ad29c18 100644 --- a/bin/darkfid/src/main.rs +++ b/bin/darkfid/src/main.rs @@ -184,6 +184,7 @@ impl RequestHandler for Darkfid { } Some("wallet.get_balances") => return self.get_balances(req.id, params).await, Some("wallet.get_coins_valtok") => return self.get_coins_valtok(req.id, params).await, + Some("wallet.get_merkle_path") => return self.get_merkle_path(req.id, params).await, Some(_) | None => return JsonError::new(MethodNotFound, None, req.id).into(), } } diff --git a/bin/darkfid/src/rpc_wallet.rs b/bin/darkfid/src/rpc_wallet.rs index 1cd37e2d6..d33823165 100644 --- a/bin/darkfid/src/rpc_wallet.rs +++ b/bin/darkfid/src/rpc_wallet.rs @@ -1,4 +1,5 @@ use fxhash::FxHashMap; +use incrementalmerkletree::Tree; use log::error; use pasta_curves::group::ff::PrimeField; use serde_json::{json, Value}; @@ -258,4 +259,28 @@ impl Darkfid { coins.iter().map(|x| bs58::encode(serialize(x)).into_string()).collect(); JsonResponse::new(json!(ret), id).into() } + + // RPCAPI: + // Query the state merkle tree for the merkle path of a given leaf position. + // --> {"jsonrpc": "2.0", "method": "wallet.get_merkle_path", "params": [3], "id": 1} + // <-- {"jsonrpc": "2.0", "result": ["f091uf1...", "081ff0h10w1h0...", ...], "id": 1} + pub async fn get_merkle_path(&self, id: Value, params: &[Value]) -> JsonResult { + if params.len() != 1 || !params[0].is_u64() { + return JsonError::new(InvalidParams, None, id).into() + } + + let leaf_pos: incrementalmerkletree::Position = + ((params[0].as_u64().unwrap() as u64) as usize).into(); + + let validator_state = self.validator_state.read().await; + let state = validator_state.state_machine.lock().await; + let root = state.tree.root(0).unwrap(); + let merkle_path = state.tree.authentication_path(leaf_pos, &root).unwrap(); + drop(state); + drop(validator_state); + + let ret: Vec = + merkle_path.iter().map(|x| bs58::encode(serialize(x)).into_string()).collect(); + JsonResponse::new(json!(ret), id).into() + } }