The kate_queryRows method retrieves complete rows from the Kate commitment data availability matrix for a specified block.
Method Signature
async fn query_rows(
&self,
rows: Rows,
at: Option<HashOf<Block>>
) -> RpcResult<Vec<GRow>>
Parameters
Array of row indices to query from the data matrix.Type: BoundedVec<u32, MaxRows> where MaxRows = 64Maximum: 64 rows per requestExample: [0, 1, 5] to query rows 0, 1, and 5
Block hash at which to query the rows. If not provided, uses the best (latest finalized) block.Format: 32-byte hexadecimal hash prefixed with 0xExample: "0x1234...abcd"
Returns
Array of rows, where each row is a vector of 256-bit scalars representing the data cells.Type Definition:pub type GRawScalar = U256;
pub type GRow = Vec<GRawScalar>;
Each GRow contains the complete data for one row of the matrix, with each element representing a cell in that row.
Example Request
curl -X POST http://localhost:9944 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "kate_queryRows",
"params": [
[0, 1],
"0xa1b2c3d4e5f6789012345678901234567890123456789012345678901234567890"
],
"id": 1
}'
Example Response
{
"jsonrpc": "2.0",
"result": [
[
"0x1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890",
"0x234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12",
"0x34567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234"
// ... more cells in row 0
],
[
"0x4567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef123456",
"0x567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567",
"0x67890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12345678"
// ... more cells in row 1
]
],
"id": 1
}
Query Without Block Hash
If you don’t specify a block hash, the method queries the latest finalized block:
{
"jsonrpc": "2.0",
"method": "kate_queryRows",
"params": [[0]],
"id": 1
}
Error Responses
Block Not Finalized
If the requested block is not yet finalized:
{
"jsonrpc": "2.0",
"error": {
"code": 1,
"message": "Requested block 0xa1b2...7890 is not finalized"
},
"id": 1
}
Empty Commitments
If the block has no data commitments (e.g., contains only system extrinsics):
{
"jsonrpc": "2.0",
"error": {
"code": 1,
"message": "Requested block 0xa1b2...7890 has empty commitments"
},
"id": 1
}
Invalid Block Number
If the block hash doesn’t exist:
{
"jsonrpc": "2.0",
"error": {
"code": 1,
"message": "Invalid block number: ..."
},
"id": 1
}
Missing Block
If the block is not available:
{
"jsonrpc": "2.0",
"error": {
"code": 1,
"message": "Missing block 0xa1b2...7890"
},
"id": 1
}
Too Many Rows
If requesting more than 64 rows:
{
"jsonrpc": "2.0",
"error": {
"code": -32602,
"message": "Invalid params: rows exceeds maximum length"
},
"id": 1
}
Implementation Details
Source Code Reference
From /rpc/kate-rpc/src/lib.rs:205-224:
async fn query_rows(&self, rows: Rows, at: Option<HashOf<Block>>) -> RpcResult<Vec<GRow>> {
let _metric_observer = MetricObserver::new(ObserveKind::KateQueryRows);
let (api, at, number, block_len, extrinsics, header) = self.scope(at)?;
match header.extension() {
HeaderExtension::V3(ext) => {
if ext.commitment.commitment.is_empty() {
return Err(internal_err!("Requested block {at} has empty commitments"));
}
},
};
let grid_rows = api
.rows(at, number, extrinsics, block_len, rows.into())
.map_err(|kate_err| internal_err!("Failed Kate rows: {kate_err:?}"))?
.map_err(|api_err| internal_err!("Failed API: {api_err:?}"))?;
Ok(grid_rows)
}
Validation Steps
- Block Finalization: Ensures the requested block is finalized
- Commitment Check: Verifies the block has non-empty data commitments
- Row Retrieval: Fetches the requested rows from the Kate API
- Metrics: Records query performance metrics (if enabled)
Use Cases
Data Availability Sampling
Validators can sample entire rows to verify data availability:
// Sample rows 0, 5, and 10 from the latest block
const rows = await rpc('kate_queryRows', [[0, 5, 10]]);
Block Reconstruction
Light clients can reconstruct portions of a block:
// Retrieve first 4 rows for reconstruction
const blockHash = '0x...';
const rows = await rpc('kate_queryRows', [[0, 1, 2, 3], blockHash]);
Row Verification
Verify specific rows against commitments:
// Query row and verify against header commitment
const [row] = await rpc('kate_queryRows', [[rowIndex], blockHash]);
const header = await rpc('chain_getHeader', [blockHash]);
// Verify row against header.extension.commitment