Skip to content

Commit

Permalink
test: add test for proving service
Browse files Browse the repository at this point in the history
  • Loading branch information
SantiagoPittella committed Sep 20, 2024
1 parent 2cc447b commit debb0e7
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 39 deletions.
5 changes: 5 additions & 0 deletions bin/miden-tx-prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ path = "src/bin.rs"
[features]
default = ["std"]
std = []
testing = ["miden-objects/testing", "miden-lib/testing", "miden-tx/testing"]

[dependencies]
miden-lib = { workspace = true }
Expand Down Expand Up @@ -47,3 +48,7 @@ prost = { version = "0.12" }
prost-build = { version = "0.12" }
protox = { version = "0.6" }
tonic-build = { version = "0.11" }

[dev-dependencies]
tokio = { version = "1.38", features = ["full"] }
tonic = "0.11"
41 changes: 2 additions & 39 deletions bin/miden-tx-prover/src/bin.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,9 @@
use std::env;

use miden_objects::transaction::TransactionWitness;
use miden_tx::{
utils::{Deserializable, Serializable},
LocalTransactionProver, TransactionProver,
};
use miden_tx_prover::{
server::generated::api::api_server, ProveTransactionRequest, ProveTransactionResponse,
};
use miden_tx_prover::server::Rpc;
use tokio::net::TcpListener;
use tokio_stream::wrappers::TcpListenerStream;
use tonic::{Request, Response};
use tracing::info;
use winter_maybe_async::maybe_await;

pub struct Rpc {
pub(crate) api_service: api_server::ApiServer<RpcApi>,
pub(crate) listener: TcpListener,
}
#[derive(Clone)]
struct RpcApi;

#[tonic::async_trait]
impl api_server::Api for RpcApi {
async fn prove_transaction(
&self,
request: Request<ProveTransactionRequest>,
) -> Result<Response<ProveTransactionResponse>, tonic::Status> {
info!("Received request to prove transaction");
let prover = LocalTransactionProver::default();

let transaction_witness =
TransactionWitness::read_from_bytes(&request.get_ref().transaction_witness).unwrap();

let proof = maybe_await!(prover.prove(transaction_witness)).unwrap();

Ok(Response::new(ProveTransactionResponse { proven_transaction: proof.to_bytes() }))
}
}

#[tokio::main]
async fn main() {
Expand All @@ -48,10 +14,7 @@ async fn main() {
let port = env::var("PROVER_SERVICE_PORT").unwrap_or_else(|_| "50051".to_string());
let addr = format!("{}:{}", host, port);

let rpc = Rpc {
listener: tokio::net::TcpListener::bind(addr).await.unwrap(),
api_service: api_server::ApiServer::new(RpcApi),
};
let rpc = Rpc::new(TcpListener::bind(addr).await.unwrap());

info!("Server listening on {}", rpc.listener.local_addr().unwrap());

Expand Down
46 changes: 46 additions & 0 deletions bin/miden-tx-prover/src/server/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,47 @@
use generated::api::api_server;
use miden_objects::transaction::TransactionWitness;
use miden_tx::{
utils::{Deserializable, Serializable},
LocalTransactionProver, TransactionProver,
};
use tokio::net::TcpListener;
use tonic::{Request, Response};
use tracing::info;
use winter_maybe_async::maybe_await;

use crate::{ProveTransactionRequest, ProveTransactionResponse};

pub mod generated;

pub struct Rpc {
pub api_service: api_server::ApiServer<RpcApi>,
pub listener: TcpListener,
}

impl Rpc {
pub fn new(listener: TcpListener) -> Self {
let api_service = api_server::ApiServer::new(RpcApi);
Self { listener, api_service }
}
}

#[derive(Clone)]
pub struct RpcApi;

#[tonic::async_trait]
impl api_server::Api for RpcApi {
async fn prove_transaction(
&self,
request: Request<ProveTransactionRequest>,
) -> Result<Response<ProveTransactionResponse>, tonic::Status> {
info!("Received request to prove transaction");
let prover = LocalTransactionProver::default();

let transaction_witness =
TransactionWitness::read_from_bytes(&request.get_ref().transaction_witness).unwrap();

let proof = maybe_await!(prover.prove(transaction_witness)).unwrap();

Ok(Response::new(ProveTransactionResponse { proven_transaction: proof.to_bytes() }))
}
}
88 changes: 88 additions & 0 deletions bin/miden-tx-prover/tests/server_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use std::time::Duration;

use miden_lib::transaction::TransactionKernel;
use miden_objects::{
accounts::account_id::testing::{ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN, ACCOUNT_ID_SENDER},
assets::{Asset, FungibleAsset},
notes::NoteType,
testing::account_code::DEFAULT_AUTH_SCRIPT,
transaction::{TransactionScript, TransactionWitness},
};
use miden_tx::{
testing::mock_chain::{Auth, MockChain},
utils::Serializable,
};
use miden_tx_prover::server::{
generated::api::{api_server::ApiServer, ProveTransactionRequest, ProveTransactionResponse},
RpcApi,
};
use tokio::net::TcpListener;
use tonic::{Request, Response}; // Import RpcApi

#[tokio::test]
async fn test_prove_transaction() {
// Start the server in the background
let listener = TcpListener::bind("127.0.0.1:50052").await.unwrap();
let api_service = ApiServer::new(RpcApi); // Assuming RpcApi implements Default

// Spawn the server as a background task
tokio::spawn(async move {
tonic::transport::Server::builder()
.accept_http1(true)
.add_service(tonic_web::enable(api_service))
.serve_with_incoming(tokio_stream::wrappers::TcpListenerStream::new(listener))
.await
.unwrap();
});

// Give the server some time to start
tokio::time::sleep(Duration::from_secs(1)).await;

// Set up a gRPC client to send the request
let mut client = miden_tx_prover::server::generated::api::api_client::ApiClient::connect(
"http://127.0.0.1:50052",
)
.await
.unwrap();

// Create a mock transaction to send to the server
let mut mock_chain = MockChain::new();
let account = mock_chain.add_existing_wallet(Auth::BasicAuth, vec![]);

let fungible_asset_1: Asset =
FungibleAsset::new(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN.try_into().unwrap(), 100)
.unwrap()
.into();
let note_1 = mock_chain
.add_p2id_note(
ACCOUNT_ID_SENDER.try_into().unwrap(),
account.id(),
&[fungible_asset_1],
NoteType::Private,
)
.unwrap();

let tx_script =
TransactionScript::compile(DEFAULT_AUTH_SCRIPT, vec![], TransactionKernel::assembler())
.unwrap();
let tx_context = mock_chain
.build_tx_context(account.id())
.input_notes(vec![note_1])
.tx_script(tx_script)
.build();

let executed_transaction = tx_context.execute().unwrap();

let transaction_witness = TransactionWitness::from(executed_transaction);

let request = Request::new(ProveTransactionRequest {
transaction_witness: transaction_witness.to_bytes(),
});

// Send the request to the server
let response: Response<ProveTransactionResponse> =
client.prove_transaction(request).await.unwrap();

// Check the response
assert!(!response.get_ref().proven_transaction.is_empty(), "Proof generation failed");
}

0 comments on commit debb0e7

Please sign in to comment.