Skip to content

Commit

Permalink
feat: move idn_connect, fix feature gating
Browse files Browse the repository at this point in the history
  • Loading branch information
driemworks committed Oct 24, 2024
1 parent 563c876 commit fe641cf
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 54 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions core/src/murmur.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ impl MurmurStore {
/// * `seed`: The value written to the transcript
/// * `rng`: A CSPRNG
///
#[cfg(feature = "client")]
fn generate_witness<R: Rng + CryptoRng + Sized>(mut seed: Vec<u8>, mut rng: R) -> [u8; 32] {
let mut transcript = Transcript::new_labeled(MURMUR_PROTO);
transcript.write_bytes(&seed);
Expand All @@ -259,6 +260,7 @@ fn generate_witness<R: Rng + CryptoRng + Sized>(mut seed: Vec<u8>, mut rng: R) -
/// * `message`: The message to be timelock encrypted
/// * `rng`: A CSPRNG
///
#[cfg(feature = "client")]
fn timelock_encrypt<E: EngineBLS, R: CryptoRng + Rng + Sized>(
identity: Identity,
pk: E::PublicKeyGroup,
Expand Down Expand Up @@ -335,17 +337,19 @@ pub mod verifier {
/// * `nonce`: A nonce value
///
pub fn verify_update<E: EngineBLS>(
serialized_proof: Vec<u8>,
serialized_proof: Vec<u8>,
serialized_pubkey: Vec<u8>,
nonce: u64,
) -> Result<bool, VerificationError> {
// build transcript
let mut transcript = Transcript::new_labeled(MURMUR_PROTO);
transcript.write_bytes(&nonce.to_be_bytes());
// deserialize proof and pubkey

// deserialize proof and pubkey
let proof = ThinVrfProof::<<E::SignatureGroup as CurveGroup>::Affine>::
deserialize_compressed(&mut &serialized_proof[..])
.map_err(|_| VerificationError::UnserializableProof)?;

let pk = PublicKey::<<E::SignatureGroup as CurveGroup>::Affine>::
deserialize_compressed(&mut &serialized_pubkey[..])
.map_err(|_| VerificationError::UnserializablePubkey)?;
Expand Down
1 change: 0 additions & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ ark-serialize = "0.4.0"
w3f-bls = "0.1.3"
murmur-core = { path = "../core/", features = ["client"] }
zeroize = "1.8.1"
hkdf = "0.12.4"


[dev-dependencies]
Expand Down
46 changes: 39 additions & 7 deletions lib/src/bin/murmur/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@

use clap::{Parser, Subcommand};
use murmur_lib::{
create, etf, idn_connect, prepare_execute, BlockNumber, BoundedVec, MurmurStore, RuntimeCall,
create, etf, prepare_execute, BlockNumber, BoundedVec, MurmurStore, RuntimeCall,
};

use rand_core::{OsRng, SeedableRng};
use rand_chacha::ChaCha20Rng;
use sp_core::crypto::Ss58Codec;
use std::{fs::File, time::Instant};
use subxt::{
backend::rpc::RpcClient, client::OnlineClient, config::SubstrateConfig,
};
use subxt_signer::sr25519::dev;
use thiserror::Error;

Expand Down Expand Up @@ -105,22 +109,21 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}

// 2. create mmr
let create_data = create(
let mmr_store = create(
args.seed.as_bytes().to_vec(),
0,
schedule,
round_pubkey_bytes,
&mut rng,
)
.map_err(|_| CLIError::MurmurCreationFailed)?;
).map_err(|_| CLIError::MurmurCreationFailed)?;

// 3. add to storage
write_mmr_store(create_data.mmr_store.clone(), MMR_STORE_FILEPATH);
write_mmr_store(mmr_store.clone(), MMR_STORE_FILEPATH);

// 4. build the call
let call = etf::tx().murmur().create(
create_data.root,
create_data.size,
mmr_store.root.0,
mmr_store.metadata.keys().len() as u64,
BoundedVec(args.name.as_bytes().to_vec()),
);

Expand Down Expand Up @@ -175,6 +178,35 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

/// Async connection to the Ideal Network
/// if successful then fetch data
/// else error if unreachable
async fn idn_connect(
) -> Result<(OnlineClient<SubstrateConfig>, BlockNumber, Vec<u8>), Box<dyn std::error::Error>> {
println!("🎲 Connecting to Ideal network (local node)");
let ws_url = std::env::var("WS_URL").unwrap_or_else(|_| {
let fallback_url = "ws://localhost:9944".to_string();
println!("⚠️ WS_URL environment variable not set. Using fallback URL: {}", fallback_url);
fallback_url
});

let rpc_client = RpcClient::from_url(&ws_url).await?;
let client = OnlineClient::<SubstrateConfig>::from_rpc_client(rpc_client.clone()).await?;
println!("🔗 RPC Client: connection established");

// fetch the round public key from etf runtime storage
let round_key_query = subxt::dynamic::storage("Etf", "RoundPublic", ());
let result = client.storage().at_latest().await?.fetch(&round_key_query).await?;
let round_pubkey_bytes = result.unwrap().as_type::<Vec<u8>>()?;

println!("🔑 Successfully retrieved the round public key.");

let current_block = client.blocks().at_latest().await?;
let current_block_number: BlockNumber = current_block.header().number;
println!("🧊 Current block number: #{:?}", current_block_number);
Ok((client, current_block_number, round_pubkey_bytes))
}

/// read an MMR from a file
fn load_mmr_store(path: &str) -> Result<MurmurStore, CLIError> {
let mmr_store_file = File::open(path).expect("Unable to open file");
Expand Down
59 changes: 16 additions & 43 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@
*/

use beefy::{known_payloads, Commitment, Payload};
use hkdf::Hkdf;
use murmur_core::types::{Identity, IdentityBuilder};
use serde::Serialize;
use subxt::{
backend::rpc::RpcClient, client::OnlineClient, config::SubstrateConfig, ext::codec::Encode,
};
use w3f_bls::{DoublePublicKey, SerializableToBytes, TinyBLS377};
use zeroize::Zeroize;

Expand All @@ -32,6 +28,7 @@ pub use murmur_core::{
types::BlockNumber,
};
use rand_chacha::ChaCha20Rng;
use subxt::ext::codec::Encode;

// Generate an interface that we can use from the node's metadata.
#[subxt::subxt(runtime_metadata_path = "artifacts/metadata.scale")]
Expand Down Expand Up @@ -60,7 +57,12 @@ pub struct CreateData {
pub root: Vec<u8>,
/// The size of the MMR
pub size: u64,
/// The murmur store (map of block nubmer to ciphertext)
pub mmr_store: MurmurStore,
/// The serialized VRF public key
pub public_key_bytes: Vec<u8>,
/// The serialized Schnorr signature
pub proof_bytes: Vec<u8>,
}

#[derive(Serialize)]
Expand All @@ -69,8 +71,11 @@ pub struct ProxyData {
pub position: u64,
/// The hash of the commitment
pub hash: Vec<u8>,
/// The timelocked ciphertext
pub ciphertext: Vec<u8>,
/// The Merkle proof items
pub proof_items: Vec<Vec<u8>>,
/// The size of the Merkle proof
pub size: u64,
}

Expand All @@ -85,7 +90,7 @@ pub fn create(
block_schedule: Vec<BlockNumber>,
round_pubkey_bytes: Vec<u8>,
rng: &mut ChaCha20Rng,
) -> Result<CreateData, Error> {
) -> Result<MurmurStore, Error> {
let round_pubkey = DoublePublicKey::<TinyBLS377>::from_bytes(&round_pubkey_bytes)
.map_err(|_| Error::InvalidPubkey)?;

Expand All @@ -97,10 +102,7 @@ pub fn create(
rng,
)?;
seed.zeroize();

let root = mmr_store.root.clone();

Ok(CreateData { root: root.0, size: mmr_store.metadata.len() as u64, mmr_store })
Ok(mmr_store)
}

/// Return the data needed for the immediate execution of the proxied call.
Expand Down Expand Up @@ -133,35 +135,6 @@ pub fn prepare_execute(
Ok(ProxyData { position: pos, hash: commitment, ciphertext, proof_items, size })
}

/// Async connection to the Ideal Network
/// if successful then fetch data
/// else error if unreachable
pub async fn idn_connect(
) -> Result<(OnlineClient<SubstrateConfig>, BlockNumber, Vec<u8>), Box<dyn std::error::Error>> {
println!("🎲 Connecting to Ideal network (local node)");
let ws_url = std::env::var("WS_URL").unwrap_or_else(|_| {
let fallback_url = "ws://localhost:9944".to_string();
println!("⚠️ WS_URL environment variable not set. Using fallback URL: {}", fallback_url);
fallback_url
});

let rpc_client = RpcClient::from_url(&ws_url).await?;
let client = OnlineClient::<SubstrateConfig>::from_rpc_client(rpc_client.clone()).await?;
println!("🔗 RPC Client: connection established");

// fetch the round public key from etf runtime storage
let round_key_query = subxt::dynamic::storage("Etf", "RoundPublic", ());
let result = client.storage().at_latest().await?.fetch(&round_key_query).await?;
let round_pubkey_bytes = result.unwrap().as_type::<Vec<u8>>()?;

println!("🔑 Successfully retrieved the round public key.");

let current_block = client.blocks().at_latest().await?;
let current_block_number: BlockNumber = current_block.header().number;
println!("🧊 Current block number: #{:?}", current_block_number);
Ok((client, current_block_number, round_pubkey_bytes))
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -176,7 +149,7 @@ mod tests {
let block_schedule = vec![1, 2, 3, 4, 5, 6, 7];
let double_public_bytes = murmur_test_utils::get_dummy_beacon_pubkey();
let mut rng = ChaCha20Rng::from_rng(&mut OsRng).unwrap();
let create_data =
let mmr_store =
create(seed.clone(), 0, block_schedule.clone(), double_public_bytes.clone(), &mut rng)
.unwrap();

Expand All @@ -188,8 +161,8 @@ mod tests {
// &mut rng,
// ).unwrap();

assert_eq!(create_data.mmr_store.root.0.len(), 32);
assert_eq!(create_data.size, 7);
assert_eq!(mmr_store.root.0.len(), 32);
assert_eq!(mmr_store.size, 7);
}

#[test]
Expand All @@ -199,7 +172,7 @@ mod tests {
let block_schedule = vec![1, 2, 3, 4, 5, 6, 7];
let double_public_bytes = murmur_test_utils::get_dummy_beacon_pubkey();
let mut rng = ChaCha20Rng::from_rng(&mut OsRng).unwrap();
let create_data = create(
let mmr_store = create(
seed.clone(),
0,
block_schedule,
Expand Down Expand Up @@ -234,7 +207,7 @@ mod tests {
let proxy_data = prepare_execute(
seed.clone(),
when,
create_data.mmr_store.clone(),
mmr_store.clone(),
&balance_transfer_call,
&mut rng,
)
Expand Down

0 comments on commit fe641cf

Please sign in to comment.