Skip to main content

Overview

The Request Stream pattern continuously submits proof requests to the Boundless Market based on blockchain events. Use this pattern when your application proves properties about each block or block range: monitoring block hashes, tracking state transitions, or verifying computations across multiple blocks.
The Request Stream example source code can be found at: boundless/examples/request-stream

How It Works

The pattern monitors the blockchain for new blocks. Every N blocks (configurable; default is 2), it collects block hashes and constructs a proof request with them as input. The request is submitted to the Boundless Market, and the pattern waits for a prover to fulfill it before repeating for the next block range.

Setting Up

Environment Variables

You’ll need the same environment variables as a standard request:
For more details on storage providers, see Storage Providers.

CLI Arguments

The request stream example accepts the following arguments:

Creating a Block Range Stream

The core of the request stream pattern is creating an async stream that monitors the blockchain and emits events when new block ranges are ready.

Stream Pattern Benefits

Streams process events as they arrive, give consumers control over processing rate (backpressure), and compose with other stream operations like filter and map.

Implementation

Processing Events and Submitting Requests

Once you have a stream of block range events, you can process them and submit proof requests:

Main Processing Loop

Input Construction

The input data must be prepared in a format that your guest program can understand. In this example, we concatenate block hashes:
In production, you might want to serialize data in a structured format (e.g., using bincode, serde) or include additional metadata. Ensure your guest program can deserialize this format.

Request IDs

A Request ID is a 256-bit value containing your address and a 32-bit index. Bits 0-31 hold the index (u32), bits 32-191 hold the requestor address (160 bits), and bits 192+ hold flags such as the smart contract signature flag.

Choosing an Index

In this example, we use the start block number as the index:
Each block range receives a unique, deterministic request ID, making it straightforward to identify which block range a request corresponds to.
The index must be unique per requestor address. If you submit multiple requests with the same index, only one will be accepted.

Full Example

Use Cases

This pattern suits applications that prove properties about each block or block range, verify state transitions continuously, process data in batches as new blocks arrive, or generate proofs for events as they occur onchain.

Next Steps

See request configuration for fine-tuning requests, using proofs for integrating proofs into your application, and callbacks for automatic proof delivery.