Skip to content

Commit

Permalink
Merge pull request #43 from dusk-network/request-service-29
Browse files Browse the repository at this point in the history
Service request implementation
  • Loading branch information
miloszm authored Nov 17, 2023
2 parents 82b9a27 + 971accd commit 0fbc8f2
Show file tree
Hide file tree
Showing 26 changed files with 168 additions and 63 deletions.
2 changes: 1 addition & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ license-provider = { path = "../license-provider" }

[dev-dependencies]
dusk-wallet = "0.20.1-rc.0"
zk-citadel = "0.5"
zk-citadel = "0.5.2-rc.0"
phoenix-core = { version = "0.21", features = ["alloc"] }
poseidon-merkle = { version = "0.3", features = ["rkyv-impl"] }
dusk-pki = { version = "0.13", default-features = false, features = ["rkyv-impl"] }
Expand Down
6 changes: 3 additions & 3 deletions integration-tests/tests/citadel/send_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async fn send_request() -> Result<(), Error> {
rng,
)?;
let request_vec = rkyv::to_bytes::<_, MAX_REQUEST_SIZE>(&request)
.unwrap()
.expect("Serializing should be infallible")
.to_vec();

let config = BlockchainAccessConfig::load_path(config_path)?;
Expand Down Expand Up @@ -79,7 +79,7 @@ async fn send_request() -> Result<(), Error> {
assert_eq!(
request_vec,
rkyv::to_bytes::<_, MAX_REQUEST_SIZE>(&retrieved_request)
.unwrap()
.expect("Serializing should be infallible")
.to_vec(),
"requests not equal"
);
Expand All @@ -89,7 +89,7 @@ async fn send_request() -> Result<(), Error> {
assert_eq!(
request_vec,
rkyv::to_bytes::<_, MAX_REQUEST_SIZE>(&retrieved_request)
.unwrap()
.expect("Serializing should be infallible")
.to_vec(),
"requests not equal"
);
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/tests/websocket/ws_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ async fn accept_connection(stream: TcpStream) {
public_inputs: vec![BlsScalar::zero()],
});
rkyv::to_bytes::<_, MAX_RESPONSE_SIZE>(&response_data)
.expect("Data should serialize correctly")
.expect("Serializing should be infallible")
.to_vec()
}
"get_licenses" => {
let response_data = vec![vec![1u8], vec![2u8]];
rkyv::to_bytes::<_, MAX_RESPONSE_SIZE>(&response_data)
.expect("Data should serialize correctly")
.expect("Serializing should be infallible")
.to_vec()
}
_ => vec![],
Expand Down
2 changes: 1 addition & 1 deletion license-provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"

[dependencies]
dusk-wallet = "0.20.1-rc.0"
zk-citadel = "0.5"
zk-citadel = "0.5.2-rc.0"
moat-core={ path = "../moat-core" }
wallet-accessor = { path = "../wallet-accessor" }
dusk-poseidon = { version = "0.31", default-features = false, features = ["rkyv-impl", "alloc"] }
Expand Down
2 changes: 1 addition & 1 deletion license-provider/src/license_issuer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl LicenseIssuer {
let attr = JubJubScalar::from(ATTRIBUTE_DATA);
let license = License::new(&attr, ssk_lp, request, rng);
let license_blob = rkyv::to_bytes::<_, MAX_LICENSE_SIZE>(&license)
.expect("License should serialize correctly")
.expect("Serializing should be infallible")
.to_vec();
let lpk = JubJubAffine::from(license.lsa.pk_r().as_ref());
let license_hash = sponge::hash(&[lpk.get_u(), lpk.get_v()]);
Expand Down
4 changes: 2 additions & 2 deletions license-provider/src/reference_lp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ impl ReferenceLP {
fn hash_request(request: &Request) -> [u8; OUT_LEN] {
*blake3::hash(
rkyv::to_bytes::<_, MAX_REQUEST_SIZE>(request)
.expect("Request should serialize correctly")
.expect("Serializing should be infallible")
.as_slice(),
)
.as_bytes()
Expand All @@ -167,7 +167,7 @@ impl ReferenceLP {
T: rkyv::Serialize<AllocSerializer<16386>>,
{
let blob = rkyv::to_bytes::<_, 16386>(object)
.expect("type should serialize correctly")
.expect("Serializing should be infallible")
.to_vec();
Self::blob_to_hash_hex(blob.as_slice())
}
Expand Down
2 changes: 1 addition & 1 deletion moat-cli-lp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ wallet-accessor = { path = "../wallet-accessor" }
moat-core = { path = "../moat-core" }
dusk-pki = "0.13"
license-provider = { path = "../license-provider" }
zk-citadel = "0.5"
zk-citadel = "0.5.2-rc.0"
rkyv = { version = "=0.7.39" }
toml-base-config = "0.1"
clap = { version = "4.0", features = ["derive", "env"] }
Expand Down
2 changes: 1 addition & 1 deletion moat-cli-lp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ async fn main() -> Result<(), CliError> {
WalletAccessor::create(wallet_path.clone(), psw.clone()).unwrap();
let wallet = Wallet::from_file(wallet_accessor).unwrap();

let (_psk, ssk) = wallet.spending_keys(&wallet.default_address()).unwrap();
let (_psk, ssk) = wallet.spending_keys(wallet.default_address()).unwrap();

let mut interactor = Interactor {
wallet_path,
Expand Down
2 changes: 1 addition & 1 deletion moat-cli-lp/src/run_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl RunResult {
T: rkyv::Serialize<AllocSerializer<16386>>,
{
let blob = rkyv::to_bytes::<_, 16386>(object)
.expect("type should serialize correctly")
.expect("Serializing should be infallible")
.to_vec();
Self::blob_to_hash_hex(blob.as_slice())
}
Expand Down
5 changes: 5 additions & 0 deletions moat-cli-sp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ edition = "2021"
dusk-wallet = "0.20.1-rc.0"
wallet-accessor = { path = "../wallet-accessor" }
moat-core = { path = "../moat-core" }
zk-citadel = "0.5.2-rc.0"
rkyv = { version = "=0.7.39" }
dusk-bls12_381 = "0.12"
dusk-jubjub = { version = "0.13", default-features = false, features = ["rkyv-impl", "alloc"] }
dusk-pki = "0.13"
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"
Expand All @@ -24,3 +28,4 @@ futures-core = "0.3"
reqwest = "0.11"
bytecheck = "0.6"
sha3 = "0.10"
thiserror = "1.0"
3 changes: 3 additions & 0 deletions moat-cli-sp/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
rusk_address = "http://127.0.0.1:8080"
prover_address = "http://127.0.0.1:8080"
psk_lp = "136d747ff489bd06077f937508b9237ac093ff868dc2e232ab3af0ecd038873288560dbd8aa851e055bc408ebeb89509b26eb6e34b4b43214de467e3ef09594e"
66 changes: 58 additions & 8 deletions moat-cli-sp/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::run_result::{LicenseContractSummary, RunResult, SessionSummary};
use crate::config::SPCliConfig;
use crate::run_result::{
LicenseContractSummary, RunResult, ServiceRequestSummery, SessionSummary,
};
use crate::Error;
use dusk_bls12_381::BlsScalar;
use dusk_bytes::DeserializableSlice;
use dusk_jubjub::JubJubAffine;
use dusk_pki::PublicSpendKey;
use dusk_wallet::RuskHttpClient;
use moat_core::{CitadelInquirer, Error, LicenseSessionId};
use moat_core::{CitadelInquirer, LicenseSessionId};
use wallet_accessor::BlockchainAccessConfig;
use zk_citadel::license::{Session, SessionCookie};

/// Commands that can be run against the Moat
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
Expand All @@ -27,11 +34,16 @@ impl Command {
pub async fn run(
self,
blockchain_access_config: &BlockchainAccessConfig,
config: &SPCliConfig,
) -> Result<RunResult, Error> {
let run_result = match self {
Command::RequestService { session_cookie: _ } => {
println!("Off-chain request service to be placed here");
RunResult::Empty
Command::RequestService { session_cookie } => {
Self::request_service(
blockchain_access_config,
&session_cookie,
config,
)
.await?
}
Command::GetSession { session_id } => {
Self::get_session(blockchain_access_config, session_id).await?
Expand All @@ -43,17 +55,55 @@ impl Command {
Ok(run_result)
}

/// Command: Request Service
async fn request_service(
blockchain_access_config: &BlockchainAccessConfig,
session_cookie: &str,
config: &SPCliConfig,
) -> Result<RunResult, Error> {
let client =
RuskHttpClient::new(blockchain_access_config.rusk_address.clone());

let bytes = hex::decode(session_cookie)
.map_err(|_| Error::InvalidEntry("session cookie".into()))?;
let sc: SessionCookie = rkyv::from_bytes(bytes.as_slice())
.map_err(|_| Error::InvalidEntry("session cookie".into()))?;
let psk_lp: &str = &config.psk_lp;
let psk_lp_bytes = hex::decode(psk_lp.as_bytes()).map_err(|_| {
Error::InvalidConfigValue("license provider psk".into())
})?;
let psk_lp = PublicSpendKey::from_slice(psk_lp_bytes.as_slice())
.map_err(|_| {
Error::InvalidConfigValue("license provider psk".into())
})?;
let pk_lp = JubJubAffine::from(*psk_lp.A());

let session_id = LicenseSessionId { id: sc.session_id };
let session = CitadelInquirer::get_session(&client, session_id)
.await?
.ok_or(Error::NotFound("Session not found".into()))?;

let session = Session::from(&session.public_inputs);
let granted = session.verifies_ok(sc, pk_lp);
println!("session id={}", hex::encode(session_id.id.to_bytes()));
let service_request_summary = ServiceRequestSummery {
service_granted: granted,
};
Ok(RunResult::RequestService(service_request_summary))
}

/// Command: Get Session
async fn get_session(
blockchain_access_config: &BlockchainAccessConfig,
session_id: String,
) -> Result<RunResult, Error> {
let client =
RuskHttpClient::new(blockchain_access_config.rusk_address.clone());
let session_id_bytes = hex::decode(session_id.clone())
.map_err(|_| Error::InvalidEntry("session id".into()))?;
let id = LicenseSessionId {
id: BlsScalar::from_slice(
hex::decode(session_id.clone())?.as_slice(),
)?,
id: BlsScalar::from_slice(session_id_bytes.as_slice())
.map_err(|_| Error::InvalidEntry("session id".into()))?,
};
Ok(match CitadelInquirer::get_session(&client, id).await? {
Some(session) => {
Expand Down
19 changes: 19 additions & 0 deletions moat-cli-sp/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// 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 SPCliConfig {
pub rusk_address: String,
pub prover_address: String,
pub psk_lp: String,
}

impl BaseConfig for SPCliConfig {
const PACKAGE: &'static str = env!("CARGO_PKG_NAME");
}
38 changes: 28 additions & 10 deletions moat-cli-sp/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,58 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use std::borrow::Cow;
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug)]
pub enum CliError {
// todo: rename CliError to Error
// todo: make sure it is used in other CLIs as well

#[derive(Error, Debug, Clone)]
pub enum Error {
/// Moat core error
#[error(transparent)]
Moat(Arc<moat_core::Error>),
/// Interaction error
#[error(transparent)]
Interaction(Arc<requestty::ErrorKind>),
/// Parsing error
#[error("Parsing error occurred: {0:?}")]
Parsing(Arc<clap::error::ErrorKind>),
/// IO Error
#[error(transparent)]
IO(Arc<std::io::Error>),
/// Not found error
#[error("Not found: {0:?}")]
NotFound(Cow<'static, str>),
/// Invalid entry
#[error("Invalid entry: {0:?}")]
InvalidEntry(Cow<'static, str>),
/// Invalid config value
#[error("Invalid config value: {0:?}")]
InvalidConfigValue(Cow<'static, str>),
}

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

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

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

impl From<std::io::Error> for CliError {
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
CliError::IO(Arc::from(e))
Error::IO(Arc::from(e))
}
}
24 changes: 9 additions & 15 deletions moat-cli-sp/src/interactor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::error::CliError;
use crate::config::SPCliConfig;
use crate::error::Error;
use crate::prompt;
use crate::{Command, Menu};
use dusk_wallet::WalletPath;
use moat_core::Error;
use requestty::{ErrorKind, Question};
use wallet_accessor::{BlockchainAccessConfig, Password};

Expand Down Expand Up @@ -66,34 +66,28 @@ pub struct Interactor {
pub wallet_path: WalletPath,
pub psw: Password,
pub blockchain_access_config: BlockchainAccessConfig,
pub config: SPCliConfig,
pub gas_limit: u64,
pub gas_price: u64,
}

impl Interactor {
pub async fn run_loop(&mut self) -> Result<(), CliError> {
pub async fn run_loop(&mut self) -> Result<(), Error> {
loop {
let op = menu_operation()?;
match op {
OpSelection::Exit => return Ok(()),
OpSelection::Run(command) => {
let result =
command.run(&self.blockchain_access_config).await;
let result = command
.run(&self.blockchain_access_config, &self.config)
.await;
match result {
Ok(run_result) => {
println!("{}", run_result);
}
Err(error) => match error {
Error::IO(arc) => {
println!("{}", arc.as_ref().to_string());
Err(error) => {
println!("{}", error.to_string());
}
Error::Transaction(bx) => {
println!("{}", bx.as_ref().to_string());
}
_ => {
println!("{:?}", error);
}
},
}
continue;
}
Expand Down
Loading

0 comments on commit 0fbc8f2

Please sign in to comment.