Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement moat interactive cli #34

Merged
merged 51 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
080aa4d
renamed moat-cli to moat-request-cli
miloszm Oct 24, 2023
523440a
Insipient interaction
miloszm Oct 25, 2023
bcc19cf
Incipient command
miloszm Oct 25, 2023
6ec8e5e
Sumbitting request WIP
miloszm Oct 25, 2023
f5b41ae
Incipient submit request and list requests
miloszm Oct 26, 2023
4d93c75
Scanning the entire blockchain for requests
miloszm Oct 26, 2023
b2c8174
Added interactor struct and cli error enum
miloszm Oct 26, 2023
ffb0984
Filtering only relevant user transactions
miloszm Oct 30, 2023
a2125ad
Added listing requests for an LP
miloszm Oct 30, 2023
99efb08
Added prompt for psk when submitting request
miloszm Oct 30, 2023
9e6c476
Possibility of listing requests for a different LP
miloszm Oct 30, 2023
46d02fb
Added issue license
miloszm Oct 30, 2023
177f3d2
Get licenses - single license version
miloszm Oct 30, 2023
7a14269
Returning multiple licenses in get_licenses
miloszm Oct 30, 2023
1d00bca
Added use license
miloszm Oct 31, 2023
d1fc0ab
Added show state
miloszm Oct 31, 2023
5b528fc
Added total requests count in addition to owned requests
miloszm Oct 31, 2023
1e4d8b1
Added getting a session
miloszm Oct 31, 2023
031619e
Possibility of entering alternative request
miloszm Oct 31, 2023
2514e0d
UI improvements and make challenge constant
miloszm Oct 31, 2023
ff6688d
Corrected counters, displaying shas of licenses and requests
miloszm Oct 31, 2023
1d35347
Show license hash after issuing license
miloszm Nov 2, 2023
879198d
possibility of entering license to use
miloszm Nov 2, 2023
bd10771
Showing if license is owned
miloszm Nov 2, 2023
9d3fd69
listing licenses for specific user
miloszm Nov 2, 2023
3c76246
Issuing particular request
miloszm Nov 2, 2023
7dd0afa
Fixed the secondary flow
miloszm Nov 2, 2023
794e0ab
Performing setup only once
miloszm Nov 2, 2023
5876907
Displaying cookie
miloszm Nov 3, 2023
2a52993
Added request service
miloszm Nov 3, 2023
c8e6603
Improved error processing
miloszm Nov 3, 2023
642f9ae
Cosmetic - better display of session cookie
miloszm Nov 3, 2023
fde8236
Improved request extractor, filters out not noop calls
miloszm Nov 3, 2023
35ef5f1
Setup holder to hold setup, prover and verifier
miloszm Nov 3, 2023
9b17045
Refactored proving and using license into LicenseUser
miloszm Nov 7, 2023
01608c3
Reused proving license and sending use licensed from core in cli command
miloszm Nov 7, 2023
dde8cf0
Refactored commands submit-request and list-requests
miloszm Nov 7, 2023
bc2d353
Refactored list requests lp command
miloszm Nov 7, 2023
e0da726
Refactored issue license lp command
miloszm Nov 7, 2023
e5ddf97
Refactored list licenses
miloszm Nov 7, 2023
51a8547
Refactored use license command
miloszm Nov 7, 2023
ff3c201
Refactored get session and show state commands
miloszm Nov 7, 2023
332c483
Introduced run result implementing Display
miloszm Nov 7, 2023
4b14cca
Run result based display for submit request and list requests lp
miloszm Nov 7, 2023
05d54c3
Run result based display for issue license
miloszm Nov 7, 2023
8f1f1af
Run result based display for list licenses
miloszm Nov 7, 2023
70e0691
Run result based display for get session and show state commands
miloszm Nov 7, 2023
b3f8561
Run result based display for the use license command
miloszm Nov 7, 2023
8cd61b1
Pushed find owner licenses code from int test and cli to the core lib
miloszm Nov 7, 2023
80a05f4
Cosmetic - removed todo
miloszm Nov 7, 2023
923f07c
Adjusted to zk-citadel 0.5.1
miloszm Nov 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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-core", "wallet-accessor", "integration-tests", "license-provider", "macros/code-hasher"]
members = ["moat-cli", "moat-request-cli", "moat-core", "wallet-accessor", "integration-tests", "license-provider", "macros/code-hasher"]
164 changes: 23 additions & 141 deletions integration-tests/tests/citadel/int_test_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,25 @@
//! nullifier (or session id) in a collection which stops us from double
//! usage of the license)

use bytecheck::CheckBytes;
use bytes::Bytes;
use dusk_bls12_381::BlsScalar;
use dusk_bytes::DeserializableSlice;
use dusk_pki::{PublicSpendKey, SecretSpendKey};
use dusk_pki::SecretSpendKey;
use dusk_plonk::prelude::*;
use dusk_wallet::{RuskHttpClient, WalletPath};
use license_provider::{LicenseIssuer, ReferenceLP};
use moat_core::Error::InvalidQueryResponse;
use moat_core::{
BcInquirer, CitadelInquirer, Error, JsonLoader, LicenseCircuit,
LicenseSessionId, PayloadRetriever, PayloadSender, RequestCreator,
RequestJson, RequestSender, StreamAux, TxAwaiter, ARITY, DEPTH,
LICENSE_CONTRACT_ID, USE_LICENSE_METHOD_NAME,
LicenseSessionId, LicenseUser, PayloadRetriever, RequestCreator,
RequestJson, RequestSender, TxAwaiter,
};
use poseidon_merkle::Opening;
use rand::rngs::StdRng;
use rand::SeedableRng;
use rkyv::{check_archived_root, Archive, Deserialize, Infallible, Serialize};
use std::path::PathBuf;
use toml_base_config::BaseConfig;
use tracing::{info, Level};
use wallet_accessor::BlockchainAccessConfig;
use wallet_accessor::Password::PwdHash;
use zk_citadel::license::{
CitadelProverParameters, License, Request, SessionCookie,
};
use zk_citadel::license::Request;

const WALLET_PATH: &str = concat!(env!("HOME"), "/.dusk/rusk-wallet");
const PWD_HASH: &str =
Expand All @@ -56,34 +48,6 @@ const GAS_PRICE: u64 = 1;
static LABEL: &[u8] = b"dusk-network";
const CAPACITY: usize = 17; // capacity required for the setup

/// Use License Argument.
#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
#[archive_attr(derive(CheckBytes))]
pub struct UseLicenseArg {
pub proof: Proof,
pub public_inputs: Vec<BlsScalar>,
}

fn compute_citadel_parameters(
rng: &mut StdRng,
ssk: SecretSpendKey,
psk_lp: PublicSpendKey,
lic: &License,
merkle_proof: Opening<(), DEPTH, ARITY>,
challenge: &JubJubScalar,
) -> (CitadelProverParameters<DEPTH, ARITY>, SessionCookie) {
let (cpp, sc) = CitadelProverParameters::compute_parameters(
&ssk,
&lic,
&psk_lp,
&psk_lp,
challenge,
rng,
merkle_proof,
);
(cpp, sc)
}

/// Calls license contract's issue license method.
/// Awaits for confirmation of the contract-calling transaction.
async fn issue_license(
Expand All @@ -101,81 +65,10 @@ async fn issue_license(
GAS_PRICE,
);

license_issuer
let (tx_id, _) = license_issuer
.issue_license(rng, &request, &reference_lp.ssk_lp)
.await
}

/// Calculates and verified proof, sends proof along with public parameters
/// as arguments to the license contract's use_license method.
/// Awaits for confirmation of the contract-calling transaction.
async fn prove_and_send_use_license(
client: &RuskHttpClient,
blockchain_config: &BlockchainAccessConfig,
wallet_path: &WalletPath,
reference_lp: &ReferenceLP,
ssk_user: SecretSpendKey,
prover: &Prover,
verifier: &Verifier,
license: &License,
opening: Opening<(), DEPTH, ARITY>,
rng: &mut StdRng,
challenge: &JubJubScalar,
) -> Result<BlsScalar, Error> {
let (cpp, sc) = compute_citadel_parameters(
rng,
ssk_user,
reference_lp.psk_lp,
license,
opening,
&challenge,
);
let circuit = LicenseCircuit::new(&cpp, &sc);

info!("calculating proof");
let (proof, public_inputs) =
prover.prove(rng, &circuit).expect("Proving should succeed");

assert!(!public_inputs.is_empty());
let session_id = public_inputs[0];

verifier
.verify(&proof, &public_inputs)
.expect("Verifying the circuit should succeed");
info!("proof validated locally");

let use_license_arg = UseLicenseArg {
proof,
public_inputs,
};

info!("calling license contract's use_license");
let tx_id = PayloadSender::execute_contract_method(
use_license_arg,
&blockchain_config,
&wallet_path,
&PwdHash(PWD_HASH.to_string()),
GAS_LIMIT,
GAS_PRICE,
LICENSE_CONTRACT_ID,
USE_LICENSE_METHOD_NAME,
)
.await?;
TxAwaiter::wait_for(&client, tx_id).await?;
Ok(session_id)
}

/// Deserializes license, panics if deserialization fails.
fn deserialise_license(v: &Vec<u8>) -> License {
let response_data = check_archived_root::<License>(v.as_slice())
.map_err(|_| {
InvalidQueryResponse(Box::from("rkyv deserialization error"))
})
.expect("License should deserialize correctly");
let license: License = response_data
.deserialize(&mut Infallible)
.expect("Infallible");
license
.await?;
Ok(tx_id)
}

/// Displays license contract current state summary.
Expand All @@ -195,24 +88,6 @@ async fn show_state(
Ok(())
}

/// Finds owned license in a stream of licenses.
/// It searches in a reverse order to return a newest license.
fn find_owned_license(
ssk_user: SecretSpendKey,
stream: impl futures_core::Stream<Item = Result<Bytes, reqwest::Error>>
+ std::marker::Unpin,
) -> Result<(u64, License), Error> {
const ITEM_LEN: usize = CitadelInquirer::GET_LICENSES_ITEM_LEN;
let (pos, lic_ser) = StreamAux::find_item::<(u64, Vec<u8>), ITEM_LEN>(
|(_, lic_vec)| {
let license = deserialise_license(lic_vec);
Ok(ssk_user.view_key().owns(&license.lsa))
},
stream,
)?;
Ok((pos, deserialise_license(&lic_ser)))
}

///
/// test user_round_trip realizes the following scenario:
/// - creates request (User)
Expand Down Expand Up @@ -332,11 +207,12 @@ async fn user_round_trip() -> Result<(), Error> {
"calling get_licenses with range {:?} (as a user)",
block_heights
);
let licenses_stream =
let mut licenses_stream =
CitadelInquirer::get_licenses(&client, block_heights).await?;

let (pos, license) = find_owned_license(ssk_user, licenses_stream)
.expect("owned license found");
let owned_licenses =
CitadelInquirer::find_owned_licenses(ssk_user, &mut licenses_stream)?;
let (pos, license) = owned_licenses.last().expect("owned license found");

// as a User, call get_merkle_opening, obtain opening
info!("calling get_merkle_opening (as a user)");
Expand All @@ -350,23 +226,29 @@ async fn user_round_trip() -> Result<(), Error> {
// so that it is different every time we run the test
let (_, _, num_sessions) = CitadelInquirer::get_info(&client).await?;
let challenge = JubJubScalar::from(num_sessions as u64 + 1);
info!("calling use_license (as a user)");
let session_id = prove_and_send_use_license(
&client,
info!("proving license and calling use_license (as a user)");
let (tx_id, session_cookie) = LicenseUser::prove_and_use_license(
&blockchain_config,
&wallet_path,
&reference_lp,
ssk_user,
&PwdHash(PWD_HASH.to_string()),
&ssk_user,
&reference_lp.psk_lp,
&prover,
&verifier,
&license,
opening.unwrap(),
&mut rng,
&challenge,
GAS_LIMIT,
GAS_PRICE,
)
.await?;
TxAwaiter::wait_for(&client, tx_id).await?;

show_state(&client, "after use_license").await?;
let session_id = LicenseSessionId { id: session_id };
let session_id = LicenseSessionId {
id: session_cookie.session_id,
};

// as an SP, call get_session
info!("calling get_session (as an SP)");
Expand Down
31 changes: 28 additions & 3 deletions integration-tests/tests/citadel/send_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

use dusk_wallet::{RuskHttpClient, WalletPath};
use moat_core::{
Error, PayloadRetriever, RequestCreator, RequestJson, RequestSender,
MAX_REQUEST_SIZE,
Error, PayloadExtractor, PayloadRetriever, RequestCreator, RequestJson,
RequestSender, TxInquirer, MAX_REQUEST_SIZE,
};
use moat_core::{JsonLoader, TxAwaiter};
use rand::rngs::StdRng;
Expand Down Expand Up @@ -73,7 +73,17 @@ async fn send_request() -> Result<(), Error> {
let tx_id_hex = hex::encode(tx_id.to_bytes());

let retrieved_request =
get_request_from_blockchain(tx_id_hex, &client).await?;
get_request_from_blockchain(&tx_id_hex, &client).await?;
assert_eq!(
request_vec,
rkyv::to_bytes::<_, MAX_REQUEST_SIZE>(&retrieved_request)
.unwrap()
.to_vec(),
"requests not equal"
);

let retrieved_request =
get_request_from_blockchain_bulk(&tx_id_hex, &client).await?;
assert_eq!(
request_vec,
rkyv::to_bytes::<_, MAX_REQUEST_SIZE>(&retrieved_request)
Expand Down Expand Up @@ -102,3 +112,18 @@ async fn get_request_from_blockchain<S: AsRef<str>>(
}
unreachable!()
}

async fn get_request_from_blockchain_bulk<S: AsRef<str>>(
tx_id: S,
client: &RuskHttpClient,
) -> Result<Request, Error> {
const LAST_N_BLOCKS: usize = 1000;
let txs =
TxInquirer::txs_from_last_n_blocks(&client, LAST_N_BLOCKS).await?;
for tx in txs.transactions.iter() {
if tx.id == tx_id.as_ref() {
return PayloadExtractor::payload_from_tx(&tx);
}
}
unreachable!()
}
1 change: 1 addition & 0 deletions license-provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ rand = "0.8"
dusk-bytes = "0.1"
blake3 = "1.3"
tracing = "0.1"
sha3 = "0.10"

[dev-dependencies]
tokio = { version = "1.15", features = ["rt-multi-thread", "time", "fs", "macros"] }
10 changes: 5 additions & 5 deletions license-provider/src/license_issuer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct LicenseIssuer {
gas_price: u64,
}

const USER_ATTRIBUTES: u64 = 1 << 17;
const ATTRIBUTE_DATA: u64 = 1 << 17;

impl LicenseIssuer {
pub fn new(
Expand All @@ -50,15 +50,15 @@ impl LicenseIssuer {
rng: &mut R,
request: &Request,
ssk_lp: &SecretSpendKey,
) -> Result<BlsScalar, Error> {
let attr = JubJubScalar::from(USER_ATTRIBUTES);
) -> Result<(BlsScalar, Vec<u8>), Error> {
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")
.to_vec();
let lpk = JubJubAffine::from(license.lsa.pk_r().as_ref());
let license_hash = sponge::hash(&[lpk.get_u(), lpk.get_v()]);
let tuple = (license_blob, license_hash);
let tuple = (license_blob.clone(), license_hash);
trace!(
"sending issue license with license blob size={}",
tuple.0.len()
Expand All @@ -76,6 +76,6 @@ impl LicenseIssuer {
.await?;
let client = RuskHttpClient::new(self.config.rusk_address.clone());
TxAwaiter::wait_for(&client, tx_id).await?;
Ok(tx_id)
Ok((tx_id, license_blob))
}
}
Loading
Loading