Skip to content

Commit

Permalink
docs: align readme rpc docs (#631)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mirko-von-Leipzig authored Jan 21, 2025
1 parent e8f8314 commit fc35e17
Show file tree
Hide file tree
Showing 12 changed files with 285 additions and 239 deletions.
53 changes: 36 additions & 17 deletions crates/block-producer/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,54 @@
# Miden block producer

The **Block producer** receives transactions from the RPC component, processes them, creates block containing those transactions before sending created blocks to the store.
Contains code definining the [Miden node's block-producer](/README.md#architecture) component. It is responsible for
ordering transactions into blocks and submitting these for inclusion in the blockchain.

**Block Producer** is one of components of the [Miden node](..).
It serves a small [rRPC](htts://grpc.io) API which the node's RPC component uses to submit new transactions. In turn,
the `block-producer` uses the store's gRPC API to submit blocks and query chain state.

## Architecture
For more information on the installation and operation of this component, please see the [node's readme](/README.md).

`TODO`
## API

## Usage
The full gRPC API can be found [here](../../proto/block_producer.proto).

### Installing the Block Producer
---

The Block Producer can be installed and run as part of [Miden node](../README.md#installing-the-node).
### SubmitProvenTransaction

## API
Submits a proven transaction to the block-producer, returning the current chain height if successful.

The **Block Producer** serves connections using the [gRPC protocol](https://grpc.io) on a port, set in the previously mentioned configuration file.
Here is a brief description of supported methods.
The block-producer does _not_ verify the transaction's proof as it assumes the RPC component has done so. This is done
to minimize the performance impact of new transactions on the block-producer.

### SubmitProvenTransaction
Transactions are verified before being added to the block-producer's mempool. Transaction which fail verification are
rejected and an error is returned. Possible reasons for verification failure include

Submits proven transaction to the Miden network.
- current account state does not match the transaction's initial account state
- transaction attempts to consume non-existing, or already consumed notes
- transaction attempts to create a duplicate note
- invalid transaction proof (checked by the RPC component)

**Parameters**
Verified transactions are added to the mempool however they are still _not guaranteed_ to make it into a block.
Transactions may be evicted from the mempool if their preconditions no longer hold. Currently the only precondition is
transaction expiration height. Furthermore, as a defense against bugs the mempool may evict transactions it deems buggy
e.g. cause block proofs to fail due to some bug in the VM, compiler, prover etc.

* `transaction`: `bytes` - transaction encoded using [winter_utils::Serializable](https://github.com/facebook/winterfell/blob/main/utils/core/src/serde/mod.rs#L26) implementation for [miden_objects::transaction::proven_tx::ProvenTransaction](https://github.com/0xPolygonMiden/miden-base/blob/main/objects/src/transaction/proven_tx.rs#L22).
Since transactions can depend on other transactions in the mempool this means a specific transaction may be evicted if:

**Returns**
- it's own expiration height is exceeded, or
- it is deemed buggy by the mempool, or
- any ancestor transaction in the mempool is evicted

This method doesn't return any data.
This list will be extended in the future e.g. eviction due to gas price fluctuations.

Note that since the RPC response only indicates admission into the mempool, its not directly possible to know if the
transaction was evicted. The best way to ensure this is to effectively add a timeout to the transaction by setting the
transaction's expiration height. Once the blockchain advances beyond this point without including the transaction you
can know for certain it was evicted.

---

## License
This project is [MIT licensed](../../LICENSE).

This project is [MIT licensed](../../LICENSE).
2 changes: 1 addition & 1 deletion crates/proto/src/generated/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct CheckNullifiersByPrefixRequest {
#[prost(uint32, repeated, tag = "2")]
pub nullifiers: ::prost::alloc::vec::Vec<u32>,
}
/// Get a list of proofs for given nullifier hashes, each proof as a sparse Merkle Tree.
/// Returns a nullifier proof for each of the requested nullifiers.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CheckNullifiersRequest {
/// List of nullifiers to return proofs for.
Expand Down
34 changes: 24 additions & 10 deletions crates/proto/src/generated/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub mod api_client {
self.inner = self.inner.max_encoding_message_size(limit);
self
}
/// Gets a list of proofs for given nullifier hashes, each proof as a sparse Merkle Tree.
/// Returns a nullifier proof for each of the requested nullifiers.
pub async fn check_nullifiers(
&mut self,
request: impl tonic::IntoRequest<
Expand All @@ -115,6 +115,8 @@ pub mod api_client {
self.inner.unary(req, path, codec).await
}
/// Returns a list of nullifiers that match the specified prefixes and are recorded in the node.
///
/// Note that only 16-bit prefixes are supported at this time.
pub async fn check_nullifiers_by_prefix(
&mut self,
request: impl tonic::IntoRequest<
Expand Down Expand Up @@ -219,7 +221,7 @@ pub mod api_client {
.insert(GrpcMethod::new("rpc.Api", "GetAccountStateDelta"));
self.inner.unary(req, path, codec).await
}
/// Retrieves block data by given block number.
/// Returns raw block data for the specified block number.
pub async fn get_block_by_number(
&mut self,
request: impl tonic::IntoRequest<
Expand Down Expand Up @@ -320,10 +322,15 @@ pub mod api_client {
.insert(GrpcMethod::new("rpc.Api", "SubmitProvenTransaction"));
self.inner.unary(req, path, codec).await
}
/// Note synchronization request.
/// Returns info which can be used by the client to sync up to the tip of chain for the notes they are interested in.
///
/// Client specifies the `note_tags` they are interested in, and the block height from which to search for new for
/// matching notes for. The request will then return the next block containing any note matching the provided tags.
///
/// The response includes each note's metadata and inclusion proof.
///
/// Specifies note tags that client is interested in. The server will return the first block which
/// contains a note matching `note_tags` or the chain tip.
/// A basic note sync can be implemented by repeatedly requesting the previous response's block until reaching the
/// tip of the chain.
pub async fn sync_notes(
&mut self,
request: impl tonic::IntoRequest<super::super::requests::SyncNoteRequest>,
Expand Down Expand Up @@ -396,7 +403,7 @@ pub mod api_server {
/// Generated trait containing gRPC methods that should be implemented for use with ApiServer.
#[async_trait]
pub trait Api: std::marker::Send + std::marker::Sync + 'static {
/// Gets a list of proofs for given nullifier hashes, each proof as a sparse Merkle Tree.
/// Returns a nullifier proof for each of the requested nullifiers.
async fn check_nullifiers(
&self,
request: tonic::Request<super::super::requests::CheckNullifiersRequest>,
Expand All @@ -405,6 +412,8 @@ pub mod api_server {
tonic::Status,
>;
/// Returns a list of nullifiers that match the specified prefixes and are recorded in the node.
///
/// Note that only 16-bit prefixes are supported at this time.
async fn check_nullifiers_by_prefix(
&self,
request: tonic::Request<
Expand Down Expand Up @@ -439,7 +448,7 @@ pub mod api_server {
tonic::Response<super::super::responses::GetAccountStateDeltaResponse>,
tonic::Status,
>;
/// Retrieves block data by given block number.
/// Returns raw block data for the specified block number.
async fn get_block_by_number(
&self,
request: tonic::Request<super::super::requests::GetBlockByNumberRequest>,
Expand Down Expand Up @@ -476,10 +485,15 @@ pub mod api_server {
tonic::Response<super::super::responses::SubmitProvenTransactionResponse>,
tonic::Status,
>;
/// Note synchronization request.
/// Returns info which can be used by the client to sync up to the tip of chain for the notes they are interested in.
///
/// Client specifies the `note_tags` they are interested in, and the block height from which to search for new for
/// matching notes for. The request will then return the next block containing any note matching the provided tags.
///
/// The response includes each note's metadata and inclusion proof.
///
/// Specifies note tags that client is interested in. The server will return the first block which
/// contains a note matching `note_tags` or the chain tip.
/// A basic note sync can be implemented by repeatedly requesting the previous response's block until reaching the
/// tip of the chain.
async fn sync_notes(
&self,
request: tonic::Request<super::super::requests::SyncNoteRequest>,
Expand Down
34 changes: 24 additions & 10 deletions crates/proto/src/generated/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub mod api_client {
req.extensions_mut().insert(GrpcMethod::new("store.Api", "ApplyBlock"));
self.inner.unary(req, path, codec).await
}
/// Gets a list of proofs for given nullifier hashes, each proof as a sparse Merkle Tree.
/// Returns a nullifier proof for each of the requested nullifiers.
pub async fn check_nullifiers(
&mut self,
request: impl tonic::IntoRequest<
Expand All @@ -139,6 +139,8 @@ pub mod api_client {
self.inner.unary(req, path, codec).await
}
/// Returns a list of nullifiers that match the specified prefixes and are recorded in the node.
///
/// Note that only 16-bit prefixes are supported at this time.
pub async fn check_nullifiers_by_prefix(
&mut self,
request: impl tonic::IntoRequest<
Expand Down Expand Up @@ -247,7 +249,7 @@ pub mod api_client {
.insert(GrpcMethod::new("store.Api", "GetAccountStateDelta"));
self.inner.unary(req, path, codec).await
}
/// Retrieves block data by given block number.
/// Returns raw block data for the specified block number.
pub async fn get_block_by_number(
&mut self,
request: impl tonic::IntoRequest<
Expand Down Expand Up @@ -402,10 +404,15 @@ pub mod api_client {
.insert(GrpcMethod::new("store.Api", "GetTransactionInputs"));
self.inner.unary(req, path, codec).await
}
/// Note synchronization request.
/// Returns info which can be used by the client to sync up to the tip of chain for the notes they are interested in.
///
/// Client specifies the `note_tags` they are interested in, and the block height from which to search for new for
/// matching notes for. The request will then return the next block containing any note matching the provided tags.
///
/// The response includes each note's metadata and inclusion proof.
///
/// Specifies note tags that client is interested in. The server will return the first block which
/// contains a note matching `note_tags` or the chain tip.
/// A basic note sync can be implemented by repeatedly requesting the previous response's block until reaching the
/// tip of the chain.
pub async fn sync_notes(
&mut self,
request: impl tonic::IntoRequest<super::super::requests::SyncNoteRequest>,
Expand Down Expand Up @@ -486,7 +493,7 @@ pub mod api_server {
tonic::Response<super::super::responses::ApplyBlockResponse>,
tonic::Status,
>;
/// Gets a list of proofs for given nullifier hashes, each proof as a sparse Merkle Tree.
/// Returns a nullifier proof for each of the requested nullifiers.
async fn check_nullifiers(
&self,
request: tonic::Request<super::super::requests::CheckNullifiersRequest>,
Expand All @@ -495,6 +502,8 @@ pub mod api_server {
tonic::Status,
>;
/// Returns a list of nullifiers that match the specified prefixes and are recorded in the node.
///
/// Note that only 16-bit prefixes are supported at this time.
async fn check_nullifiers_by_prefix(
&self,
request: tonic::Request<
Expand Down Expand Up @@ -529,7 +538,7 @@ pub mod api_server {
tonic::Response<super::super::responses::GetAccountStateDeltaResponse>,
tonic::Status,
>;
/// Retrieves block data by given block number.
/// Returns raw block data for the specified block number.
async fn get_block_by_number(
&self,
request: tonic::Request<super::super::requests::GetBlockByNumberRequest>,
Expand Down Expand Up @@ -582,10 +591,15 @@ pub mod api_server {
tonic::Response<super::super::responses::GetTransactionInputsResponse>,
tonic::Status,
>;
/// Note synchronization request.
/// Returns info which can be used by the client to sync up to the tip of chain for the notes they are interested in.
///
/// Client specifies the `note_tags` they are interested in, and the block height from which to search for new for
/// matching notes for. The request will then return the next block containing any note matching the provided tags.
///
/// The response includes each note's metadata and inclusion proof.
///
/// Specifies note tags that client is interested in. The server will return the first block which
/// contains a note matching `note_tags` or the chain tip.
/// A basic note sync can be implemented by repeatedly requesting the previous response's block until reaching the
/// tip of the chain.
async fn sync_notes(
&self,
request: tonic::Request<super::super::requests::SyncNoteRequest>,
Expand Down
2 changes: 1 addition & 1 deletion crates/rpc-proto/proto/requests.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ message CheckNullifiersByPrefixRequest {
repeated uint32 nullifiers = 2;
}

// Get a list of proofs for given nullifier hashes, each proof as a sparse Merkle Tree.
// Returns a nullifier proof for each of the requested nullifiers.
message CheckNullifiersRequest {
// List of nullifiers to return proofs for.
repeated digest.Digest nullifiers = 1;
Expand Down
17 changes: 12 additions & 5 deletions crates/rpc-proto/proto/rpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import "requests.proto";
import "responses.proto";

service Api {
// Gets a list of proofs for given nullifier hashes, each proof as a sparse Merkle Tree.
// Returns a nullifier proof for each of the requested nullifiers.
rpc CheckNullifiers(requests.CheckNullifiersRequest) returns (responses.CheckNullifiersResponse) {}

// Returns a list of nullifiers that match the specified prefixes and are recorded in the node.
//
// Note that only 16-bit prefixes are supported at this time.
rpc CheckNullifiersByPrefix(requests.CheckNullifiersByPrefixRequest) returns (responses.CheckNullifiersByPrefixResponse) {}

// Returns the latest state of an account with the specified ID.
Expand All @@ -22,7 +24,7 @@ service Api {
// `to_block_num` (inclusive).
rpc GetAccountStateDelta(requests.GetAccountStateDeltaRequest) returns (responses.GetAccountStateDeltaResponse) {}

// Retrieves block data by given block number.
// Returns raw block data for the specified block number.
rpc GetBlockByNumber(requests.GetBlockByNumberRequest) returns (responses.GetBlockByNumberResponse) {}

// Retrieves block header by given block number. Optionally, it also returns the MMR path
Expand All @@ -35,10 +37,15 @@ service Api {
// Submits proven transaction to the Miden network.
rpc SubmitProvenTransaction(requests.SubmitProvenTransactionRequest) returns (responses.SubmitProvenTransactionResponse) {}

// Note synchronization request.
// Returns info which can be used by the client to sync up to the tip of chain for the notes they are interested in.
//
// Client specifies the `note_tags` they are interested in, and the block height from which to search for new for
// matching notes for. The request will then return the next block containing any note matching the provided tags.
//
// The response includes each note's metadata and inclusion proof.
//
// Specifies note tags that client is interested in. The server will return the first block which
// contains a note matching `note_tags` or the chain tip.
// A basic note sync can be implemented by repeatedly requesting the previous response's block until reaching the
// tip of the chain.
rpc SyncNotes(requests.SyncNoteRequest) returns (responses.SyncNoteResponse) {}

// Returns info which can be used by the client to sync up to the latest state of the chain
Expand Down
17 changes: 12 additions & 5 deletions crates/rpc-proto/proto/store.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ service Api {
// Applies changes of a new block to the DB and in-memory data structures.
rpc ApplyBlock(requests.ApplyBlockRequest) returns (responses.ApplyBlockResponse) {}

// Gets a list of proofs for given nullifier hashes, each proof as a sparse Merkle Tree.
// Returns a nullifier proof for each of the requested nullifiers.
rpc CheckNullifiers(requests.CheckNullifiersRequest) returns (responses.CheckNullifiersResponse) {}

// Returns a list of nullifiers that match the specified prefixes and are recorded in the node.
//
// Note that only 16-bit prefixes are supported at this time.
rpc CheckNullifiersByPrefix(requests.CheckNullifiersByPrefixRequest) returns (responses.CheckNullifiersByPrefixResponse) {}

// Returns the latest state of an account with the specified ID.
Expand All @@ -27,7 +29,7 @@ service Api {
// `to_block_num` (inclusive).
rpc GetAccountStateDelta(requests.GetAccountStateDeltaRequest) returns (responses.GetAccountStateDeltaResponse) {}

// Retrieves block data by given block number.
// Returns raw block data for the specified block number.
rpc GetBlockByNumber(requests.GetBlockByNumberRequest) returns (responses.GetBlockByNumberResponse) {}

// Retrieves block header by given block number. Optionally, it also returns the MMR path
Expand All @@ -46,10 +48,15 @@ service Api {
// Returns data required to validate a new transaction.
rpc GetTransactionInputs(requests.GetTransactionInputsRequest) returns (responses.GetTransactionInputsResponse) {}

// Note synchronization request.
// Returns info which can be used by the client to sync up to the tip of chain for the notes they are interested in.
//
// Client specifies the `note_tags` they are interested in, and the block height from which to search for new for
// matching notes for. The request will then return the next block containing any note matching the provided tags.
//
// The response includes each note's metadata and inclusion proof.
//
// Specifies note tags that client is interested in. The server will return the first block which
// contains a note matching `note_tags` or the chain tip.
// A basic note sync can be implemented by repeatedly requesting the previous response's block until reaching the
// tip of the chain.
rpc SyncNotes(requests.SyncNoteRequest) returns (responses.SyncNoteResponse) {}

// Returns info which can be used by the client to sync up to the latest state of the chain
Expand Down
Loading

0 comments on commit fc35e17

Please sign in to comment.