Skip to content

Commit

Permalink
Merge pull request #38 from dusk-network/issue-32
Browse files Browse the repository at this point in the history
Separate interactive CLIs for user, SP, LP
  • Loading branch information
miloszm authored Nov 10, 2023
2 parents d942110 + efeab2e commit 34e463f
Show file tree
Hide file tree
Showing 47 changed files with 2,495 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[workspace]
members = ["moat-cli", "moat-request-cli", "moat-core", "wallet-accessor", "integration-tests", "license-provider", "macros/code-hasher"]
members = ["moat-cli", "moat-cli-user", "moat-cli-lp", "moat-cli-sp", "moat-cli-request", "moat-core", "wallet-accessor", "integration-tests", "license-provider", "macros/code-hasher"]
2 changes: 1 addition & 1 deletion integration-tests/tests/blockchain/stake_add_owner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use wallet_accessor::Password::PwdHash;

const WALLET_PATH: &str = concat!(env!("HOME"), "/.dusk/rusk-wallet");
const PWD_HASH: &str =
"7f2611ba158b6dcea4a69c229c303358c5e04493abeadee106a4bfa464d55787";
"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8";
const GAS_LIMIT: u64 = 5_000_000_000;
const GAS_PRICE: u64 = 1;

Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/citadel/int_test_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use zk_citadel::license::Request;

const WALLET_PATH: &str = concat!(env!("HOME"), "/.dusk/rusk-wallet");
const PWD_HASH: &str =
"7f2611ba158b6dcea4a69c229c303358c5e04493abeadee106a4bfa464d55787";
"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8";
const GAS_LIMIT: u64 = 5_000_000_000;
const GAS_PRICE: u64 = 1;

Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/citadel/issue_license.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use wallet_accessor::Password::PwdHash;

const WALLET_PATH: &str = concat!(env!("HOME"), "/.dusk/rusk-wallet");
const PWD_HASH: &str =
"7f2611ba158b6dcea4a69c229c303358c5e04493abeadee106a4bfa464d55787";
"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8";
const GAS_LIMIT: u64 = 5_000_000_000;
const GAS_PRICE: u64 = 1;

Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/citadel/send_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use zk_citadel::license::Request;

const WALLET_PATH: &str = concat!(env!("HOME"), "/.dusk/rusk-wallet");
const PWD_HASH: &str =
"7f2611ba158b6dcea4a69c229c303358c5e04493abeadee106a4bfa464d55787";
"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8";
const GAS_LIMIT: u64 = 5_000_000_000;
const GAS_PRICE: u64 = 1;

Expand Down
11 changes: 9 additions & 2 deletions license-provider/src/reference_lp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,15 @@ impl ReferenceLP {

pub fn create<P: AsRef<Path>>(lp_config_path: P) -> Result<Self, Error> {
let lp_config: LPConfig = LPConfig::from_file(lp_config_path)?;
let psk_bytes = hex::decode(lp_config.psk_lp)?;
let ssk_bytes = hex::decode(lp_config.ssk_lp)?;
Self::create_with_ssk_psk(lp_config.ssk_lp, lp_config.psk_lp)
}

pub fn create_with_ssk_psk<S>(ssk_lp: S, psk_lp: S) -> Result<Self, Error>
where
S: AsRef<str>,
{
let psk_bytes = hex::decode(psk_lp.as_ref())?;
let ssk_bytes = hex::decode(ssk_lp.as_ref())?;
let psk_lp = PublicSpendKey::from_slice(psk_bytes.as_slice())?;
let ssk_lp = SecretSpendKey::from_slice(ssk_bytes.as_slice())?;
let vk_lp = ssk_lp.view_key();
Expand Down
28 changes: 28 additions & 0 deletions moat-cli-lp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "moat-cli-lp"
version = "0.1.0"
edition = "2021"

[dependencies]
dusk-wallet = "0.20.0-rc.0"
wallet-accessor = { path = "../wallet-accessor" }
moat-core = { path = "../moat-core" }
license-provider = { path = "../license-provider" }
zk-citadel = "0.5"
rkyv = { version = "=0.7.39" }
toml-base-config = "0.1"
clap = { version = "4.0", features = ["derive", "env"] }
tokio = { version = "1.21", features = ["full"] }
serde = { version = "1", features = ["derive"] }
tracing = "0.1"
tracing-subscriber = "0.3"
rand = "0.8"
requestty = "0.4.1"
hex = "0.4"
dusk-bytes = "0.1"
group = "0.13"
bytes = "1.4"
futures-core = "0.3"
reqwest = "0.11"
bytecheck = "0.6"
sha3 = "0.10"
31 changes: 31 additions & 0 deletions moat-cli-lp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Moat CLI LP

Command line interface to Dusk Citadel License Provider

Available commands:

- list relevant license requests
- issue license for a given request
- list licenses

## Retrieve relevant license requests (LP)

arguments:
- scope: either an entire blockchain, or block range, or N last blocks
- data for Rusk cluster connection
- LP's view key (created from LP's SSK)

## Issue license for a given request (LP)

arguments:
- data for wallet connection
- data for Rusk cluster connection
- gas limit
- gas price
- license (created from the relevant request and LP's SSK)

## List licenses

arguments:
- scope: block height range
- data for Rusk cluster connection
6 changes: 6 additions & 0 deletions moat-cli-lp/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
rusk_address = "http://127.0.0.1:8080"
prover_address = "http://127.0.0.1:8080"
#rusk_address = "http://devnet.nodes.dusk.network:8585"
#prover_address = "http://devnet.provers.dusk.network:8686"
psk_lp = "136d747ff489bd06077f937508b9237ac093ff868dc2e232ab3af0ecd038873288560dbd8aa851e055bc408ebeb89509b26eb6e34b4b43214de467e3ef09594e"
ssk_lp = "fd611dc2cfe15488e3cb94b410fadd3a5e77057be64574eb9b6acaf967a37d0514d0ce88727a24d3756a08bb8ae072d8aaaa88f88768c8a9487fb50678ba5204"
38 changes: 38 additions & 0 deletions moat-cli-lp/src/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use std::path::PathBuf;

use clap::Parser;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
pub struct Args {
/// Wallet directory [default: `$HOME/.dusk/rusk-wallet`]
#[clap(short, long)]
pub wallet_path: PathBuf,

/// Blockchain access config directory
#[clap(short, long)]
pub config_path: PathBuf,

/// Password for the wallet
#[clap(long, default_value_t = String::from(""), env = "RUSK_WALLET_PWD")]
pub password: String,

/// Hash of the password for the wallet [default: ``]
#[clap(short, long, default_value_t = String::from(""))]
pub pwd_hash: String,

/// Gas limit [default: `500000000`]
#[clap(long, default_value_t = 500000000)]
pub gas_limit: u64,

/// Gas price [default: `1`]
#[clap(long, default_value_t = 1)]
pub gas_price: u64,
}
164 changes: 164 additions & 0 deletions moat-cli-lp/src/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::run_result::{
IssueLicenseSummary, LicenseContractSummary, RequestsLPSummary, RunResult,
};
use crate::{LPCliConfig, SeedableRng};
use dusk_wallet::{RuskHttpClient, WalletPath};
use license_provider::{LicenseIssuer, ReferenceLP};
use moat_core::{BcInquirer, CitadelInquirer, Error};
use rand::rngs::StdRng;
use wallet_accessor::{BlockchainAccessConfig, Password};

/// Commands that can be run against the Moat
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
pub(crate) enum Command {
/// List requests
ListRequestsLP,
/// Issue license
IssueLicenseLP { request_hash: String },
/// List licenses (User)
ListLicenses,
/// Show state
ShowState,
}

impl Command {
#[allow(clippy::too_many_arguments)]
pub async fn run(
self,
wallet_path: &WalletPath,
psw: &Password,
blockchain_access_config: &BlockchainAccessConfig,
config: &LPCliConfig,
gas_limit: u64,
gas_price: u64,
) -> Result<RunResult, Error> {
let run_result = match self {
Command::ListRequestsLP => {
Self::list_requests_lp(blockchain_access_config, config).await?
}
Command::IssueLicenseLP { request_hash } => {
Self::issue_license_lp(
wallet_path,
psw,
blockchain_access_config,
config,
gas_limit,
gas_price,
request_hash,
)
.await?
}
Command::ListLicenses => {
Self::list_licenses(blockchain_access_config).await?
}
Command::ShowState => {
Self::show_state(blockchain_access_config).await?
}
};
Ok(run_result)
}

/// Command: List Requests LP
async fn list_requests_lp(
blockchain_access_config: &BlockchainAccessConfig,
config: &LPCliConfig,
) -> Result<RunResult, Error> {
let mut reference_lp = ReferenceLP::create_with_ssk_psk::<&str>(
config.ssk_lp.as_ref(),
config.psk_lp.as_ref(),
)?;
let (found_total, found_owned) =
reference_lp.scan(blockchain_access_config).await?;
let summary = RequestsLPSummary {
found_total,
found_owned,
};
Ok(RunResult::RequestsLP(
summary,
reference_lp.requests_to_process,
))
}

#[allow(clippy::too_many_arguments)]
/// Command: Issue License LP
async fn issue_license_lp(
wallet_path: &WalletPath,
psw: &Password,
blockchain_access_config: &BlockchainAccessConfig,
config: &LPCliConfig,
gas_limit: u64,
gas_price: u64,
request_hash: String,
) -> Result<RunResult, Error> {
let mut rng = StdRng::from_entropy();
let mut reference_lp = ReferenceLP::create_with_ssk_psk::<&str>(
config.ssk_lp.as_ref(),
config.psk_lp.as_ref(),
)?;
let (_total_count, _this_lp_count) =
reference_lp.scan(blockchain_access_config).await?;

let request = reference_lp.get_request(&request_hash);
Ok(match request {
Some(request) => {
let license_issuer = LicenseIssuer::new(
blockchain_access_config.clone(),
wallet_path.clone(),
psw.clone(),
gas_limit,
gas_price,
);
let (tx_id, license_blob) = license_issuer
.issue_license(&mut rng, &request, &reference_lp.ssk_lp)
.await?;
let summary = IssueLicenseSummary {
request,
tx_id: hex::encode(tx_id.to_bytes()),
license_blob,
};
RunResult::IssueLicense(Some(summary))
}
_ => RunResult::IssueLicense(None),
})
}

/// Command: List Licenses
async fn list_licenses(
blockchain_access_config: &BlockchainAccessConfig,
) -> Result<RunResult, Error> {
let client =
RuskHttpClient::new(blockchain_access_config.rusk_address.clone());
let end_height = BcInquirer::block_height(&client).await?;
let block_range = 0..(end_height + 1);

let mut licenses_stream =
CitadelInquirer::get_licenses(&client, block_range.clone()).await?;

let pairs = CitadelInquirer::find_all_licenses(&mut licenses_stream)?;
Ok(RunResult::ListLicenses(
block_range,
pairs.into_iter().map(|(_, l)| l).collect(),
))
}

/// Command: Show State
async fn show_state(
blockchain_access_config: &BlockchainAccessConfig,
) -> Result<RunResult, Error> {
let client =
RuskHttpClient::new(blockchain_access_config.rusk_address.clone());
let (num_licenses, _, num_sessions) =
CitadelInquirer::get_info(&client).await?;
let summary = LicenseContractSummary {
num_licenses,
num_sessions,
};
Ok(RunResult::ShowState(summary))
}
}
20 changes: 20 additions & 0 deletions moat-cli-lp/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use serde::{Deserialize, Serialize};
use toml_base_config::BaseConfig;

#[derive(Debug, Default, Deserialize, Serialize, Clone)]
pub struct LPCliConfig {
pub rusk_address: String,
pub prover_address: String,
pub ssk_lp: String,
pub psk_lp: String,
}

impl BaseConfig for LPCliConfig {
const PACKAGE: &'static str = env!("CARGO_PKG_NAME");
}
43 changes: 43 additions & 0 deletions moat-cli-lp/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use std::sync::Arc;

#[derive(Debug)]
pub enum CliError {
/// Moat core error
Moat(Arc<moat_core::Error>),
/// Interaction error
Interaction(Arc<requestty::ErrorKind>),
/// Parsing error
Parsing(Arc<clap::error::ErrorKind>),
/// IO Error
IO(Arc<std::io::Error>),
}

impl From<moat_core::Error> for CliError {
fn from(e: moat_core::Error) -> Self {
CliError::Moat(Arc::from(e))
}
}

impl From<requestty::ErrorKind> for CliError {
fn from(e: requestty::ErrorKind) -> Self {
CliError::Interaction(Arc::from(e))
}
}

impl From<clap::error::ErrorKind> for CliError {
fn from(e: clap::error::ErrorKind) -> Self {
CliError::Parsing(Arc::from(e))
}
}

impl From<std::io::Error> for CliError {
fn from(e: std::io::Error) -> Self {
CliError::IO(Arc::from(e))
}
}
Loading

0 comments on commit 34e463f

Please sign in to comment.