Skip to content

Commit

Permalink
fix: merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
DhananjayPurohit committed Nov 13, 2023
2 parents 9c45daa + 9023dcc commit 622478d
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 66 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,19 @@ jobs:
- name: Install dependencies
run: |
apt-get update
apt-get install -y curl gcc protobuf-compiler libsqlite3-dev
apt-get install -y curl gcc protobuf-compiler libsqlite3-dev pkg-config libssl-dev
- name: Set environment variables for OpenSSL
run: |
echo "OPENSSL_DIR=/usr" >> $GITHUB_ENV
echo "OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu" >> $GITHUB_ENV
- name: Install Rust Toolchain (stable)
shell: bash
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- uses: Swatinem/rust-cache@v2
- name: Build civkit-cli
run: cargo build --bin civkit-cli --verbose
Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ path = "src/services/notaryd.rs"
[dependencies]
futures-channel = "0.3.28"
futures-util = "0.3.28"
lightning = { git = "https://github.com/civkit/rust-lightning.git", branch = "civkit-branch" }
lightning-net-tokio = { git = "https://github.com/civkit/rust-lightning.git", branch = "civkit-branch" }
lightning-invoice = { git = "https://github.com/civkit/rust-lightning.git", branch = "civkit-branch" }
lightning = { git = "https://github.com/DhananjayPurohit/rust-lightning-wizards.git", branch = "civkit-branch" }
lightning-net-tokio = { git = "https://github.com/DhananjayPurohit/rust-lightning-wizards.git", branch = "civkit-branch" }
lightning-invoice = { git = "https://github.com/DhananjayPurohit/rust-lightning-wizards.git", branch = "civkit-branch" }
tokio = { version = "1", features = [ "io-util", "macros", "rt", "rt-multi-thread", "sync", "net", "time" ] }
tokio-tungstenite = "0.19.0"
bitcoin = "0.29.0"
Expand All @@ -45,7 +45,7 @@ serde_json = { version = "1.0" }
toml = "0.5.8"
serde_derive = "1.0"
serde = "1.0.130"
rusqlite = "0.29.0"
rusqlite = { version = "0.29.0", features = ["bundled"] }
simplelog = "0.7.1"
dirs = "3.0.1"
log = "0.4.14"
Expand Down
36 changes: 31 additions & 5 deletions src/bitcoind_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@
use crate::config::Config;
use crate::rpcclient::{Client, Auth};

use tokio::sync::mpsc;
use jsonrpc::Response;

use bitcoin::{MerkleBlock, Txid};
use bitcoin_hashes::hex::FromHex;

use tokio::sync::{mpsc, oneshot};
use tokio::sync::Mutex as TokioMutex;

use tokio::time::{sleep, Duration};

#[derive(Debug)]
pub enum BitcoindRequest {
CheckRpcCall,
GenerateTxInclusionProof { txid: String, respond_to: oneshot::Sender<Option<String>> },
}

pub struct BitcoindClient {
Expand Down Expand Up @@ -71,9 +77,10 @@ impl BitcoindHandler {

let separator = ":";
let url = bitcoind_client.host.clone() + &separator + &bitcoind_client.port.clone();
println!("Client url {}", url);

let rpc_client = Client::new(&url, Auth::None).unwrap();
let user_pass = Auth::UserPass(bitcoind_client.rpc_user.clone(), bitcoind_client.rpc_password.clone());

let rpc_client = Client::new(&url, user_pass).unwrap();

BitcoindHandler {
receive_bitcoind_request: TokioMutex::new(receive_bitcoind_requests),
Expand All @@ -91,10 +98,29 @@ impl BitcoindHandler {
if let Ok(bitcoind_request) = receive_bitcoind_request_lock.await.try_recv() {
match bitcoind_request {
BitcoindRequest::CheckRpcCall => {
println!("[CIVKITD] - BITCOIND CLIENT: Received rpc call");
println!("[CIVKITD] - BITCOIND CLIENT: Received rpc call - Test bitcoind");

self.rpc_client.call("getblockchaininfo", &vec![]);
}
},
BitcoindRequest::GenerateTxInclusionProof { txid, respond_to } => {
println!("[CIVKITD] - BITCOIND CLIENT: Received rpc call - Generate merkle block");

let txid_json_value = serde_json::to_value(txid).unwrap();
let txid_json = serde_json::Value::Array(vec![txid_json_value]);

if let Ok(response) = self.rpc_client.call("gettxoutproof", &[txid_json]) {
if let Some(raw_value) = response.result {
let mut mb_string = raw_value.get().to_string();
let index = mb_string.find('\"').unwrap();
mb_string.remove(index);
let index = mb_string.find('\"').unwrap();
mb_string.remove(index);
//let mb_bytes = Vec::from_hex(&mb_string).unwrap();
//let mb: MerkleBlock = bitcoin::consensus::deserialize(&mb_bytes).unwrap();
respond_to.send(Some(mb_string));
}
} else { respond_to.send(None); }
},
_ => {},
}
}
Expand Down
25 changes: 17 additions & 8 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, CheckTxidInclusionRequest};
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;
Expand Down Expand Up @@ -78,9 +78,11 @@ enum Command {
ListDbEvents,
/// List DB clients entries
ListDbClients,
/// Check txid inclusion
CheckTxidInclusion {
txid: Vec<u8>,
/// Check chain state is available
CheckChainState,
/// Generate a merkle block (header + merkle branch) for the target txid
GenerateTxInclusionProof {
txid: String,
}
}

Expand Down Expand Up @@ -206,12 +208,19 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

let _response = client.list_db_clients(request).await?;
}
Command::CheckTxidInclusion { txid } => {
let request = tonic::Request::new(CheckTxidInclusionRequest {
txid: txid.to_vec(),
Command::CheckChainState => {
let request = tonic::Request::new(CheckChainStateRequest {});

let _response = client.check_chain_state(request).await?;
}
Command::GenerateTxInclusionProof { txid } => {
let request = tonic::Request::new(GenerateTxInclusionProofRequest {
txid: txid
});

let _response = client.check_txid_inclusion(request).await?;
if let Ok(response) = client.generate_tx_inclusion_proof(request).await {
println!("tx inclusion proof: {}", response.into_inner().merkle_block);
}
}
}
Ok(())
Expand Down
12 changes: 6 additions & 6 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ impl Default for Config {
base_pubkey: "031dd94c5262454986a2f0a6c557d2cbe41ec5a8131c588b9367c9310125a8a7dc".to_string(),
chain_code: "0a090f710e47968aee906804f211cf10cde9a11e14908ca0f78cc55dd190ceaa".to_string(),
},
bitcoind_params: BitcoindParams {
host: "http://127.0.0.1".to_string(),
port: "18443".to_string(), // regtest
rpc_user: "civkitd_client".to_string(),
rpc_password: "hello_world".to_string(),
}
bitcoind_params: BitcoindParams {
host: "https://127.0.0.1".to_string(),
port: "18443".to_string(), // regtest
rpc_user: "civkitd_client".to_string(),
rpc_password: "hello_world".to_string(),
}
}
}
}
56 changes: 42 additions & 14 deletions src/credentialgateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ use bitcoin::network::constants::Network;
use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
use bitcoin::secp256k1;

use nostr::{Event, Kind};
use nostr::{Event, Kind, Tag};

use staking_credentials::common::msgs::{AssetProofFeatures, CredentialsFeatures, CredentialPolicy, ServicePolicy};
use staking_credentials::common::utils::Proof;
use staking_credentials::issuance::issuerstate::IssuerState;

use staking_credentials::common::msgs::{CredentialAuthenticationResult, ServiceDeliveranceResult};
use staking_credentials::common::msgs::{CredentialAuthenticationResult, CredentialAuthenticationPayload, Decodable, ServiceDeliveranceResult};
use staking_credentials::common::utils::Credentials;

use crate::events::ClientEvents;
use crate::bitcoind_client::BitcoindClient;
Expand Down Expand Up @@ -52,24 +54,50 @@ impl Default for GatewayConfig {
}
}

struct IssuanceRequest {
client_id: u64,
pending_credentials: Vec<Credentials>,
}

enum IssuanceError {
InvalidDataCarrier,
Parse,
Policy
}

const MAX_CREDENTIALS_PER_REQUEST: usize = 100;

//TODO: protect denial-of-service from client id requests congestion rate
struct IssuanceManager {
request_counter: u64,
table_signing_requests: HashMap<u64, u64>,//TODO: add Txid
table_signing_requests: HashMap<u64, IssuanceRequest>,

issuance_engine: IssuerState,
}

impl IssuanceManager {
fn register_authentication_request(&mut self, client_id: u64, ev: Event) -> Result<(u64, Txid), ()> {
fn register_authentication_request(&mut self, client_id: u64, ev: Event) -> Result<(u64, Proof), IssuanceError> {
let request_id = self.request_counter;
self.table_signing_requests.insert(self.request_counter, client_id);

if ev.tags.len() == 1 {
return Err(IssuanceError::InvalidDataCarrier);
}
let credential_msg_bytes = match &ev.tags[0] {
Tag::Credential(credential_bytes) => { credential_bytes },
_ => { return Err(IssuanceError::InvalidDataCarrier); },
};
let credential_authentication = if let Ok(credential_authentication) = CredentialAuthenticationPayload::decode(&credential_msg_bytes) {
credential_authentication
} else { return Err(IssuanceError::Parse); };

if credential_authentication.credentials.len() > MAX_CREDENTIALS_PER_REQUEST {
return Err(IssuanceError::Policy);
}

self.table_signing_requests.insert(self.request_counter, IssuanceRequest { client_id, pending_credentials: credential_authentication.credentials });
self.request_counter += 1;

//TODO: verify we hash 32 byte from event
let mut enc = Txid::engine();
enc.input(ev.content.as_bytes());
//TODO: verify we support the proof and credentials
Ok((request_id, Txid::from_engine(enc)))
Ok((request_id, credential_authentication.proof))
}

fn validate_authentication_request(&mut self, request_id: u64, result: bool) -> Result<CredentialAuthenticationResult, ()> {
Expand All @@ -85,8 +113,8 @@ impl IssuanceManager {
Err(())
}
fn get_client_id(&self, request_id: u64) -> u64 {
if let Some(client_id) = self.table_signing_requests.get(&request_id) {
*client_id
if let Some(issuance_request) = self.table_signing_requests.get(&request_id) {
issuance_request.client_id
} else { 0 }
}
}
Expand Down Expand Up @@ -188,9 +216,9 @@ impl CredentialGateway {
match event {
ClientEvents::Credential { client_id, event } => {
if event.kind == Kind::CredentialAuthenticationRequest {
if let Ok(txid) = self.issuance_manager.register_authentication_request(client_id, event) {
if let Ok(proof) = self.issuance_manager.register_authentication_request(client_id, event) {
println!("[CIVKITD] - CREDENTIAL: txid to verify");
proofs_to_verify.push(txid);
proofs_to_verify.push(proof);
}
} else if event.kind == Kind::ServiceDeliveranceRequest {
// For now validate directly are all information self-contained in redemption manager.
Expand Down
16 changes: 12 additions & 4 deletions src/proto/adminctrl.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ service AdminCtrl {
rpc PublishInvoice (SendInvoice) returns (ReceivedInvoice);
rpc ListDbEvents (ListDbEventsRequest) returns (ListDbEventsReply);
rpc ListDbClients (ListDbClientsRequest) returns (ListDbClientsReply);
rpc CheckTxidInclusion (CheckTxidInclusionRequest) returns (CheckTxidInclusionReply);
rpc CheckChainState (CheckChainStateRequest) returns (CheckChainStateReply);
rpc GenerateTxInclusionProof (GenerateTxInclusionProofRequest) returns (GenerateTxInclusionProofReply);
}

message PingRequest {
Expand Down Expand Up @@ -129,9 +130,16 @@ message ListDbClientsRequest {
message ListDbClientsReply {
}

message CheckTxidInclusionRequest {
bytes txid = 1;
message CheckChainStateRequest {
}

message CheckTxidInclusionReply {
message CheckChainStateReply {
}

message GenerateTxInclusionProofRequest {
string txid = 1;
}

message GenerateTxInclusionProofReply {
string merkle_block = 1;
}
15 changes: 10 additions & 5 deletions src/rpcclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
/// Simple utilities to query bitcoin RPC API. Inspired by the bitcoin-rpc
/// crate.

use jsonrpc;

#[derive(Clone, Debug, Hash, Eq, PartialEq)]
Expand All @@ -34,6 +35,7 @@ pub enum Error {
Json(serde_json::error::Error),
}


pub struct Client {
client: jsonrpc::client::Client,
}
Expand All @@ -49,20 +51,23 @@ impl Client {
} else { return Err(Error::InvalidUserPass) }
}

pub fn call(&self, cmd: &str, args: &[serde_json::Value]) -> Result<(), ()> {
pub fn call(&self, cmd: &str, args: &[serde_json::Value]) -> Result<jsonrpc::Response, ()> {

if let Ok(raw_args) = args.iter().map(|a| {
let json_string = serde_json::to_string(a)?;
serde_json::value::RawValue::from_string(json_string)
}).map(|a| a.map_err(|e| Error::Json(e))).collect::<Result<Vec<_>, Error>>() {

let req = self.client.build_request(&cmd, &raw_args);

let resp = self.client.send_request(req);

println!("resp {:?}", resp.unwrap());
println!("req {:?}", req);

if let Ok(resp) = self.client.send_request(req) {
//println!("resp {:?}", resp);
return Ok(resp);
}
}

Ok(())
Err(())
}
}
Loading

0 comments on commit 622478d

Please sign in to comment.