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

Refactorings, enriching round trip test #21

Merged
merged 7 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,86 @@ This is a low-level crate which provides wallet (Blockchain) connectivity for fu
Users of moat-core do not need to be aware of this crate, yet for maintainers and extenders, the crate
provides a convenient low level interface between the higher-level moat-core library and the blockchain.
Note that this crate deals only with contract method calling, it does not deal with contract queries.

## moat-core

### citadel requests

Class: RequestCreator
Methods:
create,
create_from_hex_args
Both methods allow for creation of a request, given user's secret spend key and license provider's public spend key.
The request can then be sent to license provider, off-chain or on-chain.

Class: RequestSender
Methods: send_request
Submits the request into blockchain.
It does so by calling a dummy contract method with request as an argument.

Class: RequestScanner
Methods:
scan_transactions,
scan_last_blocks,
scan_block_range
Scan requests in a given collection of transactions,
contained in a given range of blocks or in a given number of most recent blocks.

### citadel queries

Class: CitadelInquirer
Methods:
get_licenses,
get_merkle_opening,
get_session,
get_info
Execute citadel-specific query methods of the license contract method.

### blockchain payloads

Class: PayloadExtractor
Methods: payload_from_tx
Extracts a payload from the given transaction,
errors if payload of a given type is not present or the transaction is not a contract calling transaction.

Class: PayloadRetriever
Methods: retrieve_payload
Retrieves payload of a given transaction id,
errors if transaction is not found, or it does not contain a payload
(for example, given transaction is not a contract calling transaction)

Class: PayloadSender
Methods: execute_contract_method
Executes given method of a given contract (identified by a contract id), passing to it the payload as an argument.

### contract queries

Class: ContractInquirer
Methods:
query_contract,
query_contract_with_feeder
query_contract - accepts a generic argument, contract id and contract query method name, returns a generic value result
query_contract_with_feeder - accepts a generic argument, contract id and method name, returns result as a Stream of bytes

### blockchain queries

Class: BcInquirer
Methods:
gql_query,
block_height
gql_query - executes a GQL query and returns result as a vector of bytes
block_height - returns the current block height as u64

Class: TxAwaiter
Methods:
wait_for,
wait_for_tx
Waits for a transaction identified by transaction id to be confirmed on the blockchain.

Class: TxInquirer
Methods:
txs_from_block,
txs_from_block_range,
txs_from_last_n_blocks,
retrieve_tx
Retrieve transaction identified by transaction id, or transactions contained in a given block, or a collection of blocks.
2 changes: 1 addition & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ phoenix-core = { version = "0.20.0-rc.0", features = ["alloc"] }
poseidon-merkle = { version = "0.2.1-rc.0", features = ["rkyv-impl"] }
dusk-pki = { version = "0.12", default-features = false, features = ["rkyv-impl"] }
dusk-plonk = { version = "0.14", default-features = false, features = ["rkyv-impl", "alloc"] }
dusk-jubjub = { version = "0.12", default-features = false }
dusk-bls12_381 = "0.11"
wallet-accessor = { path = "../wallet-accessor" }
rkyv = { version = "=0.7.39" }
tokio = { version = "1.15", features = ["rt-multi-thread", "time", "fs", "macros"] }
Expand Down
8 changes: 8 additions & 0 deletions integration-tests/tests/blockchain/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// 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.

mod retrieve_txs;
mod stake_add_owner;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Copyright (c) DUSK NETWORK. All rights reserved.

use dusk_wallet::RuskHttpClient;
use moat_core::{Error, TxRetriever};
use moat_core::{Error, TxInquirer};
use toml_base_config::BaseConfig;
use tracing::trace;
use wallet_accessor::BlockchainAccessConfig;
Expand All @@ -22,7 +22,7 @@ async fn retrieve_txs_from_block() -> Result<(), Error> {

const BLOCK_HEIGHT: u64 = 110;

let txs = TxRetriever::txs_from_block(&client, BLOCK_HEIGHT).await?;
let txs = TxInquirer::txs_from_block(&client, BLOCK_HEIGHT).await?;

trace!("transactions retrieved={}", txs.transactions.len());

Expand All @@ -42,7 +42,7 @@ async fn retrieve_txs_from_block_range() -> Result<(), Error> {
const BLOCK_HEIGHT_BEG: u64 = 1;
const BLOCK_HEIGHT_END: u64 = 1000;

let (txs, top_block) = TxRetriever::txs_from_block_range(
let (txs, top_block) = TxInquirer::txs_from_block_range(
&client,
BLOCK_HEIGHT_BEG,
BLOCK_HEIGHT_END,
Expand All @@ -66,7 +66,7 @@ async fn retrieve_txs_from_last_n_blocks() -> Result<(), Error> {
let client = RuskHttpClient::new(cfg.rusk_address);

const N: usize = 10000;
let txs = TxRetriever::txs_from_last_n_blocks(&client, N).await?;
let txs = TxInquirer::txs_from_last_n_blocks(&client, N).await?;

trace!("transactions={}", txs.transactions.len());

Expand All @@ -86,7 +86,7 @@ async fn retrieve_tx_by_id() -> Result<(), Error> {

let client = RuskHttpClient::new(config.rusk_address);

let (tx, height) = TxRetriever::retrieve_tx(TXID, &client).await?;
let (tx, height) = TxInquirer::retrieve_tx(TXID, &client).await?;

trace!("tx={:?}, block_height={}", tx, height);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async fn stake_add_owner() -> Result<(), Error> {
PathBuf::from(WALLET_PATH).as_path().join("wallet.dat"),
);

let tx_id = PayloadSender::send_to_contract_method(
let tx_id = PayloadSender::execute_contract_method(
request_json.provider_psk,
&blockchain_config,
&wallet_path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ async fn lp_scan() -> Result<(), Error> {
let blockchain_config =
BlockchainAccessConfig::load_path(blockchain_config_path)?;

let mut reference_lp = ReferenceLP::init(&lp_config_path)?;
let mut reference_lp = ReferenceLP::create(&lp_config_path)?;

reference_lp.scan(&blockchain_config).await?;
Ok(())
Expand All @@ -37,7 +37,7 @@ async fn lp_scan_last_blocks() -> Result<(), Error> {
let blockchain_config =
BlockchainAccessConfig::load_path(blockchain_config_path)?;

let mut reference_lp = ReferenceLP::init(&lp_config_path)?;
let mut reference_lp = ReferenceLP::create(&lp_config_path)?;

let (_total, _owned) = reference_lp
.scan_last_blocks(10000, &blockchain_config)
Expand All @@ -58,8 +58,8 @@ async fn lp_scan_2_lps() -> Result<(), Error> {
let blockchain_config =
BlockchainAccessConfig::load_path(blockchain_config_path)?;

let mut reference_lp1 = ReferenceLP::init(&lp1_config_path)?;
let mut reference_lp2 = ReferenceLP::init(&lp2_config_path)?;
let mut reference_lp1 = ReferenceLP::create(&lp1_config_path)?;
let mut reference_lp2 = ReferenceLP::create(&lp2_config_path)?;
let (_, _lp1_count) = reference_lp1.scan(&blockchain_config).await?;
let (_, _lp2_count) = reference_lp2.scan(&blockchain_config).await?;
Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@

use bytecheck::CheckBytes;
use bytes::Bytes;
use dusk_bls12_381::BlsScalar;
use dusk_bytes::{DeserializableSlice, Serializable};
use dusk_jubjub::BlsScalar;
use dusk_pki::{PublicSpendKey, 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, PayloadSender, RequestCreator, RequestJson, StreamAux,
TxAwaiter, ARITY, DEPTH, LICENSE_CONTRACT_ID, USE_LICENSE_METHOD_NAME,
LicenseSessionId, PayloadRetriever, PayloadSender, RequestCreator,
RequestJson, RequestSender, StreamAux, TxAwaiter, ARITY, DEPTH,
LICENSE_CONTRACT_ID, USE_LICENSE_METHOD_NAME,
};
use poseidon_merkle::Opening;
use rand::rngs::StdRng;
Expand Down Expand Up @@ -69,15 +70,14 @@ fn compute_citadel_parameters(
psk_lp: PublicSpendKey,
lic: &License,
merkle_proof: Opening<(), DEPTH, ARITY>,
challenge: &JubJubScalar,
) -> (CitadelProverParameters<DEPTH, ARITY>, SessionCookie) {
const CHALLENGE: u64 = 20221127u64;
let c = JubJubScalar::from(CHALLENGE);
let (cpp, sc) = CitadelProverParameters::compute_parameters(
&ssk,
&lic,
&psk_lp,
&psk_lp,
&c,
challenge,
rng,
merkle_proof,
);
Expand Down Expand Up @@ -120,13 +120,15 @@ async fn prove_and_send_use_license(
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);

Expand All @@ -146,7 +148,7 @@ async fn prove_and_send_use_license(
public_inputs,
};

let tx_id = PayloadSender::send_to_contract_method(
let tx_id = PayloadSender::execute_contract_method(
use_license_arg,
&blockchain_config,
&wallet_path,
Expand Down Expand Up @@ -258,7 +260,7 @@ async fn user_round_trip() -> Result<(), Error> {
let lp_config_path =
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/config/lp2.json");

let reference_lp = ReferenceLP::init(&lp_config_path)?;
let reference_lp = ReferenceLP::create(&lp_config_path)?;

let blockchain_config =
BlockchainAccessConfig::load_path(blockchain_config_path)?;
Expand All @@ -270,20 +272,36 @@ async fn user_round_trip() -> Result<(), Error> {
let client = RuskHttpClient::new(blockchain_config.rusk_address.clone());

// create request

let request_json: RequestJson = RequestJson::from_file(request_path)?;
let ssk_user_bytes = hex::decode(request_json.user_ssk.clone())?;
let ssk_user = SecretSpendKey::from_slice(ssk_user_bytes.as_slice())?;

let request = RequestCreator::create_from_hex_args(
request_json.user_ssk.clone(),
request_json.user_ssk,
request_json.provider_psk,
rng,
)?;

let ssk_user_bytes = hex::decode(request_json.user_ssk)?;
let ssk_user = SecretSpendKey::from_slice(ssk_user_bytes.as_slice())?;
// as a User, submit request to blockchain
info!("submitting request to blockchain (as a User)");
let tx_id = RequestSender::send_request(
request,
&blockchain_config,
&wallet_path,
&PwdHash(PWD_HASH.to_string()),
GAS_LIMIT,
GAS_PRICE,
)
.await?;
TxAwaiter::wait_for(&client, tx_id).await?;

// as a LP, call issue license, wait for tx to confirm
// as a LP, retrieve request from blockchain
info!("retrieving request from blockchain (as an LP)");
let tx_id = format!("{:X}", tx_id);
let request: Request =
PayloadRetriever::retrieve_payload(tx_id, &client).await?;

// as a LP, call issue license, wait for tx to confirm
show_state(&client, "before issue_license").await?;
info!("calling issue_license (as an LP)");
let issue_license_txid = issue_license(
Expand All @@ -300,7 +318,6 @@ async fn user_round_trip() -> Result<(), Error> {
info!("end_height={}", end_height);

// as a User, call get_licenses, obtain license and pos

let start_height = if end_height > BLOCK_RANGE {
end_height - BLOCK_RANGE
} else {
Expand All @@ -319,14 +336,17 @@ async fn user_round_trip() -> Result<(), Error> {
.expect("owned license found");

// as a User, call get_merkle_opening, obtain opening

info!("calling get_merkle_opening (as a user)");
let opening = CitadelInquirer::get_merkle_opening(&client, pos).await?;
let opening =
CitadelInquirer::get_merkle_opening(&client, pos.clone()).await?;
assert!(opening.is_some());

// as a User, compute proof, call use_license, wait for tx to confirm

show_state(&client, "before use_license").await?;
// for test purposes we make challenge dependent on the number of sessions,
// 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,
Expand All @@ -339,13 +359,13 @@ async fn user_round_trip() -> Result<(), Error> {
&license,
opening.unwrap(),
rng,
&challenge,
)
.await?;
show_state(&client, "after use_license").await?;
let session_id = LicenseSessionId { id: session_id };

// as an SP, call get_session

info!("calling get_session (as an SP)");
let session = CitadelInquirer::get_session(&client, session_id).await?;
assert!(session.is_some());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async fn issue_license() -> Result<(), Error> {
let lp_config_path =
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/config/lp2.json");

let reference_lp = ReferenceLP::init(&lp_config_path)?;
let reference_lp = ReferenceLP::create(&lp_config_path)?;

let request_json: RequestJson = RequestJson::from_file(request_path)?;

Expand Down
Loading
Loading