From a90b33c3188aa80f7b9ff47e468afa4049e63a19 Mon Sep 17 00:00:00 2001 From: DhananjayPurohit Date: Fri, 24 Nov 2023 15:42:20 +0530 Subject: [PATCH 1/2] feat: add verify inclusion proof to cli --- src/bitcoind_client.rs | 9 ++++++++- src/client.rs | 12 ++++++++++-- src/inclusionproof.rs | 2 ++ src/proto/adminctrl.proto | 8 ++++++++ src/server.rs | 20 +++++++++++++++++--- src/servicemanager.rs | 5 ++++- 6 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/bitcoind_client.rs b/src/bitcoind_client.rs index d18136f..1a8ce04 100644 --- a/src/bitcoind_client.rs +++ b/src/bitcoind_client.rs @@ -28,11 +28,12 @@ pub enum BitcoindRequest { CheckRpcCall, GenerateTxInclusionProof { txid: String, respond_to: oneshot::Sender> }, CheckMerkleProof { request_id: u64, proof: Proof }, + VerifyInclusionProof { inclusion_proof: InclusionProof, respond_to: oneshot::Sender> }, } #[derive(Debug)] pub enum BitcoindResult { - ProofValid { request_id: u64, valid: bool } + ProofValid { request_id: u64, valid: bool }, } pub struct BitcoindClient { @@ -159,6 +160,12 @@ impl BitcoindHandler { _ => { validation_result.push(BitcoindResult::ProofValid { request_id, valid: false }); } } }, + BitcoindRequest::VerifyInclusionProof { inclusion_proof, respond_to } => { + println!("[CIVKITD] - BITCOIND CLIENT: Received rpc call - Verify inclusion proof"); + + let res = BitcoindClient::verifytxoutproof(inclusion_proof).await; + respond_to.send(Some(res.to_string())); + } _ => {}, } } diff --git a/src/client.rs b/src/client.rs index d7cfac3..2f70419 100644 --- a/src/client.rs +++ b/src/client.rs @@ -9,7 +9,7 @@ use adminctrl::admin_ctrl_client::AdminCtrlClient; //TODO: simplify by using prefix -use adminctrl::{PingRequest, PongRequest, ShutdownRequest, ShutdownReply, SendNote, ReceivedNote, ListClientRequest, ListSubscriptionRequest, PeerConnectionRequest, DisconnectClientRequest, SendNotice, SendOffer, SendInvoice, ListDbEventsRequest, ListDbClientsRequest, ListDbClientsReply, CheckChainStateRequest, CheckChainStateReply, GenerateTxInclusionProofRequest, GenerateTxInclusionProofReply}; +use adminctrl::{PingRequest, PongRequest, ShutdownRequest, ShutdownReply, SendNote, ReceivedNote, ListClientRequest, ListSubscriptionRequest, PeerConnectionRequest, DisconnectClientRequest, SendNotice, SendOffer, SendInvoice, ListDbEventsRequest, ListDbClientsRequest, ListDbClientsReply, CheckChainStateRequest, CheckChainStateReply, GenerateTxInclusionProofRequest, GenerateTxInclusionProofReply, VerifyInclusionProofRequest, VerifyInclusionProofReply}; use std::env; use std::process; @@ -83,7 +83,8 @@ enum Command { /// Generate a merkle block (header + merkle branch) for the target txid GenerateTxInclusionProof { txid: String, - } + }, + VerifyInclusionProof, } #[tokio::main] @@ -222,6 +223,13 @@ async fn main() -> Result<(), Box> { println!("tx inclusion proof: {}", response.into_inner().merkle_block); } } + Command::VerifyInclusionProof => { + let request = tonic::Request::new(VerifyInclusionProofRequest {}); + + if let Ok(response) = client.verify_inclusion_proof(request).await { + println!("verified: {:?}", response.into_inner().verified); + } + } } Ok(()) } diff --git a/src/inclusionproof.rs b/src/inclusionproof.rs index 2dba292..8f0d541 100644 --- a/src/inclusionproof.rs +++ b/src/inclusionproof.rs @@ -17,6 +17,7 @@ use crate::mainstay::{get_proof}; use crate::config::Config; use crate::nostr_db::{write_new_inclusion_proof_db}; +#[derive(Debug, Clone)] pub struct InclusionProof { pub txid: Arc>, pub commitment: Arc>, @@ -25,6 +26,7 @@ pub struct InclusionProof { pub config: Config, } +#[derive(Debug)] pub struct Ops { pub append: bool, pub commitment: String, diff --git a/src/proto/adminctrl.proto b/src/proto/adminctrl.proto index aaa6eb9..3adfb7d 100644 --- a/src/proto/adminctrl.proto +++ b/src/proto/adminctrl.proto @@ -22,6 +22,7 @@ service AdminCtrl { rpc ListDbClients (ListDbClientsRequest) returns (ListDbClientsReply); rpc CheckChainState (CheckChainStateRequest) returns (CheckChainStateReply); rpc GenerateTxInclusionProof (GenerateTxInclusionProofRequest) returns (GenerateTxInclusionProofReply); + rpc VerifyInclusionProof (VerifyInclusionProofRequest) returns (VerifyInclusionProofReply); } message PingRequest { @@ -143,3 +144,10 @@ message GenerateTxInclusionProofRequest { message GenerateTxInclusionProofReply { string merkle_block = 1; } + +message VerifyInclusionProofRequest { +} + +message VerifyInclusionProofReply { + string verified = 1; +} diff --git a/src/server.rs b/src/server.rs index dd2939c..30dbfe4 100644 --- a/src/server.rs +++ b/src/server.rs @@ -288,6 +288,20 @@ impl AdminCtrl for std::sync::Arc { Ok(Response::new(adminctrl::GenerateTxInclusionProofReply { merkle_block: response } )) } else { Ok(Response::new(adminctrl::GenerateTxInclusionProofReply { merkle_block: String::new() })) } } + + async fn verify_inclusion_proof(&self, request: Request) -> Result, Status> { + + println!("[CIVKITD] - CONTROL: verify inclusion proof !"); + + let (send, recv) = oneshot::channel::>(); + { + let mut send_bitcoind_request_lock = self.send_bitcoind_request.lock().unwrap(); + send_bitcoind_request_lock.send(BitcoindRequest::VerifyInclusionProof { inclusion_proof: (*self.inclusion_proof).clone(), respond_to: send }); + } + if let Some(response) = recv.await.expect("BitcoindHandler has been killed") { + Ok(Response::new(adminctrl::VerifyInclusionProofReply { verified: response } )) + } else { Ok(Response::new(adminctrl::VerifyInclusionProofReply { verified: false.to_string() })) } + } } @@ -435,12 +449,12 @@ fn main() -> Result<(), Box> { let mut bitcoind_handler = BitcoindHandler::new(config.clone(), receive_bitcoind_request, receive_bitcoind_request_handler, send_bitcoind_result_gateway); - // Main handler of services provision. - let service_manager_arc = Arc::new(ServiceManager::new(node_signer, anchor_manager, service_mngr_events_send, service_mngr_peer_send, manager_send_dbrequests, manager_send_bitcoind_request, send_events_gateway, config.clone())); - // We initialize the inclusion proof with txid, commitment and merkle proof as empty strings. let mut inclusion_proof = InclusionProof::new("".to_string(), "".to_string(), "".to_string(), Vec::new(), config.clone()); + // Main handler of services provision. + let service_manager_arc = Arc::new(ServiceManager::new(node_signer, anchor_manager, service_mngr_events_send, service_mngr_peer_send, manager_send_dbrequests, manager_send_bitcoind_request, send_events_gateway, Arc::new(inclusion_proof.clone()), config.clone())); + let addr = format!("[::1]:{}", cli.cli_port).parse()?; let service_mngr_svc = Server::builder() diff --git a/src/servicemanager.rs b/src/servicemanager.rs index d22374d..cf5af18 100644 --- a/src/servicemanager.rs +++ b/src/servicemanager.rs @@ -26,6 +26,7 @@ use civkit::nodesigner::NodeSigner; use civkit::peerhandler::PeerInfo; use civkit::bitcoind_client::BitcoindRequest; use civkit::config::Config; +use civkit::inclusionproof::InclusionProof; // use lock from futures::lock use std::sync::Mutex; @@ -52,13 +53,14 @@ pub struct ServiceManager pub send_events_gateway: Mutex>, our_service_pubkey: PublicKey, + pub inclusion_proof: Arc, config: Config, secp_ctx: Secp256k1, } impl ServiceManager { - pub fn new(node_signer: Arc, anchor_manager: Arc, board_events_send: mpsc::UnboundedSender, board_peers_send: mpsc::UnboundedSender, send_db_request: mpsc::UnboundedSender, send_bitcoind_request: mpsc::UnboundedSender, send_gateway_events: mpsc::UnboundedSender, our_config: Config) -> Self { + pub fn new(node_signer: Arc, anchor_manager: Arc, board_events_send: mpsc::UnboundedSender, board_peers_send: mpsc::UnboundedSender, send_db_request: mpsc::UnboundedSender, send_bitcoind_request: mpsc::UnboundedSender, send_gateway_events: mpsc::UnboundedSender, inclusion_proof: Arc, our_config: Config) -> Self { let secp_ctx = Secp256k1::new(); let pubkey = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42;32]).unwrap()); ServiceManager { @@ -71,6 +73,7 @@ impl ServiceManager send_bitcoind_request: Mutex::new(send_bitcoind_request), send_events_gateway: Mutex::new(send_gateway_events), our_service_pubkey: pubkey, + inclusion_proof: inclusion_proof, config: our_config, secp_ctx, } From ec1a6f7a0f3453299ee4bb3462d9592fa1c601c8 Mon Sep 17 00:00:00 2001 From: DhananjayPurohit Date: Wed, 29 Nov 2023 22:44:56 +0530 Subject: [PATCH 2/2] fix: move verify inclusion proof to civkit sample --- src/client.rs | 10 +--------- src/proto/adminctrl.proto | 8 -------- src/proto/civkitservice.proto | 8 ++++++++ src/sample.rs | 25 +++++++++++++++++++++++-- src/server.rs | 31 +++++++++++++++++-------------- 5 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/client.rs b/src/client.rs index 2f70419..da99208 100644 --- a/src/client.rs +++ b/src/client.rs @@ -9,7 +9,7 @@ use adminctrl::admin_ctrl_client::AdminCtrlClient; //TODO: simplify by using prefix -use adminctrl::{PingRequest, PongRequest, ShutdownRequest, ShutdownReply, SendNote, ReceivedNote, ListClientRequest, ListSubscriptionRequest, PeerConnectionRequest, DisconnectClientRequest, SendNotice, SendOffer, SendInvoice, ListDbEventsRequest, ListDbClientsRequest, ListDbClientsReply, CheckChainStateRequest, CheckChainStateReply, GenerateTxInclusionProofRequest, GenerateTxInclusionProofReply, VerifyInclusionProofRequest, VerifyInclusionProofReply}; +use adminctrl::{PingRequest, PongRequest, ShutdownRequest, ShutdownReply, SendNote, ReceivedNote, ListClientRequest, ListSubscriptionRequest, PeerConnectionRequest, DisconnectClientRequest, SendNotice, SendOffer, SendInvoice, ListDbEventsRequest, ListDbClientsRequest, ListDbClientsReply, CheckChainStateRequest, CheckChainStateReply, GenerateTxInclusionProofRequest, GenerateTxInclusionProofReply}; use std::env; use std::process; @@ -84,7 +84,6 @@ enum Command { GenerateTxInclusionProof { txid: String, }, - VerifyInclusionProof, } #[tokio::main] @@ -223,13 +222,6 @@ async fn main() -> Result<(), Box> { println!("tx inclusion proof: {}", response.into_inner().merkle_block); } } - Command::VerifyInclusionProof => { - let request = tonic::Request::new(VerifyInclusionProofRequest {}); - - if let Ok(response) = client.verify_inclusion_proof(request).await { - println!("verified: {:?}", response.into_inner().verified); - } - } } Ok(()) } diff --git a/src/proto/adminctrl.proto b/src/proto/adminctrl.proto index 3adfb7d..aaa6eb9 100644 --- a/src/proto/adminctrl.proto +++ b/src/proto/adminctrl.proto @@ -22,7 +22,6 @@ service AdminCtrl { rpc ListDbClients (ListDbClientsRequest) returns (ListDbClientsReply); rpc CheckChainState (CheckChainStateRequest) returns (CheckChainStateReply); rpc GenerateTxInclusionProof (GenerateTxInclusionProofRequest) returns (GenerateTxInclusionProofReply); - rpc VerifyInclusionProof (VerifyInclusionProofRequest) returns (VerifyInclusionProofReply); } message PingRequest { @@ -144,10 +143,3 @@ message GenerateTxInclusionProofRequest { message GenerateTxInclusionProofReply { string merkle_block = 1; } - -message VerifyInclusionProofRequest { -} - -message VerifyInclusionProofReply { - string verified = 1; -} diff --git a/src/proto/civkitservice.proto b/src/proto/civkitservice.proto index 7a2158c..ea403ee 100644 --- a/src/proto/civkitservice.proto +++ b/src/proto/civkitservice.proto @@ -7,6 +7,7 @@ service CivkitService { rpc RegisterService(RegisterRequest) returns (RegisterReply); rpc FetchServiceEvent(FetchRequest) returns (FetchReply); rpc SubmitServiceEvent(SubmitRequest) returns (SubmitReply); + rpc VerifyInclusionProof (VerifyInclusionProofRequest) returns (VerifyInclusionProofReply); } message RegisterRequest { @@ -30,3 +31,10 @@ message SubmitRequest { message SubmitReply { } + +message VerifyInclusionProofRequest { +} + +message VerifyInclusionProofReply { + string verified = 1; +} diff --git a/src/sample.rs b/src/sample.rs index 0464e41..08e5d23 100644 --- a/src/sample.rs +++ b/src/sample.rs @@ -34,6 +34,11 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio_tungstenite::{connect_async, tungstenite::protocol::Message, tungstenite::error::Error}; use std::str::FromStr; +use crate::civkitservice::civkit_service_client::CivkitServiceClient; + +pub mod civkitservice { + tonic::include_proto!("civkitservice"); +} use std::collections::HashMap; @@ -112,7 +117,7 @@ async fn poll_for_user_input(client_keys: Keys, tx: futures_channel::mpsc::Unbou continue; } - match respond(&line, &tx, &client_keys, &mut credentials_holder) { + match respond(&line, &tx, &client_keys, &mut credentials_holder).await { Ok(quit) => { if quit { process::exit(0x0100); @@ -208,9 +213,14 @@ fn cli() -> Command { .help_template(APPLET_TEMPLATE) .about("Shutdown the REPL"), ) + .subcommand( + Command::new("verifyinclusionproof") + .help_template(APPLET_TEMPLATE) + .about("Verify inclusion proof"), + ) } -fn respond( +async fn respond( line: &str, tx: &futures_channel::mpsc::UnboundedSender, client_keys: &Keys, @@ -392,6 +402,17 @@ fn respond( .unwrap(); } } + Some(("verifyinclusionproof", matches)) => { + println!("verifyinclusionproof"); + + let request = tonic::Request::new(civkitservice::VerifyInclusionProofRequest {}); + + let mut civkitd_client = CivkitServiceClient::connect(format!("http://[::1]:{}", 50031)).await; + + if let Ok(response) = civkitd_client.unwrap().verify_inclusion_proof(request).await { + println!("verified: {:?}", response.into_inner().verified); + } + } _ => { println!("Unknown command"); return Ok(true); diff --git a/src/server.rs b/src/server.rs index 30dbfe4..dfdf1b2 100644 --- a/src/server.rs +++ b/src/server.rs @@ -43,6 +43,8 @@ use adminctrl::admin_ctrl_server::{AdminCtrl, AdminCtrlServer}; use crate::civkitservice::civkit_service_server::{CivkitService, CivkitServiceServer}; +use crate::civkitservice::civkit_service_client::CivkitServiceClient; + use clap::Parser; use nostr::{Keys, EventBuilder}; @@ -52,6 +54,7 @@ use std::net::SocketAddr; use std::process; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; +use std::sync::Mutex; use tokio::io::{AsyncRead, AsyncWrite}; use tokio::net::{TcpListener, TcpStream}; @@ -288,20 +291,6 @@ impl AdminCtrl for std::sync::Arc { Ok(Response::new(adminctrl::GenerateTxInclusionProofReply { merkle_block: response } )) } else { Ok(Response::new(adminctrl::GenerateTxInclusionProofReply { merkle_block: String::new() })) } } - - async fn verify_inclusion_proof(&self, request: Request) -> Result, Status> { - - println!("[CIVKITD] - CONTROL: verify inclusion proof !"); - - let (send, recv) = oneshot::channel::>(); - { - let mut send_bitcoind_request_lock = self.send_bitcoind_request.lock().unwrap(); - send_bitcoind_request_lock.send(BitcoindRequest::VerifyInclusionProof { inclusion_proof: (*self.inclusion_proof).clone(), respond_to: send }); - } - if let Some(response) = recv.await.expect("BitcoindHandler has been killed") { - Ok(Response::new(adminctrl::VerifyInclusionProofReply { verified: response } )) - } else { Ok(Response::new(adminctrl::VerifyInclusionProofReply { verified: false.to_string() })) } - } } @@ -343,6 +332,20 @@ impl CivkitService for std::sync::Arc { Ok(Response::new(civkitservice::SubmitReply {})) } + + async fn verify_inclusion_proof(&self, request: Request) -> Result, Status> { + + println!("[CIVKITD] - CONTROL: verify inclusion proof !"); + + let (send, recv) = oneshot::channel::>(); + { + let mut send_bitcoind_request_lock = self.send_bitcoind_request.lock().unwrap(); + send_bitcoind_request_lock.send(BitcoindRequest::VerifyInclusionProof { inclusion_proof: (*self.inclusion_proof).clone(), respond_to: send }); + } + if let Some(response) = recv.await.expect("BitcoindHandler has been killed") { + Ok(Response::new(civkitservice::VerifyInclusionProofReply { verified: response } )) + } else { Ok(Response::new(civkitservice::VerifyInclusionProofReply { verified: false.to_string() })) } + } } #[derive(Parser, Debug)]