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 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.
The request stream example accepts the following arguments:
struct Args { /// URL of the Ethereum RPC endpoint rpc_url: Url, /// Private key used to interact with the Boundless Market private_key: PrivateKeySigner, /// Number of blocks to include in each request blocks_per_request: u64, // default: 2 /// Storage provider configuration storage_config: StorageProviderConfig, /// Boundless Market deployment (optional) deployment: Option<Deployment>,}
Streams process events as they arrive, give consumers control over processing rate (backpressure), and compose with other stream operations like filter and map.
The input data must be prepared in a format that your guest program can understand. In this example, we concatenate block hashes:
fn input_function(block_hashes: &[B256]) -> RequestInput { let mut input = Vec::new(); // Concatenate all block hashes into a single byte vector // Each hash is 32 bytes (B256) for hash in block_hashes { input.extend_from_slice(hash.as_slice()); } RequestInput::builder().write_slice(&input).build_inline().unwrap()}
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.
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.
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.