Appearance
Unfold an array into rows
Expand an array a call returned into one row per element, then call the contract again with each element.
Lido's staking router keeps its modules as a list of ids. One call returns the list; expand makes a row of each id, and the calls that follow use the row's id as their argument.
cql
let router = ethereum:0xFdDf38947aFB03C621C71b06C9C70bce73f12999;
from router as r
| expand r.getStakingModuleIds() as moduleId index i
| project { i, moduleId, active: r.getStakingModuleIsActive(moduleId), validators: r.getStakingModuleActiveValidatorsCount(moduleId) }| i | moduleId | active | validators |
|---|---|---|---|
| 0 | 1 | true | 258795 |
| 1 | 2 | true | 5000 |
| 2 | 3 | true | 25246 |
| 3 | 4 | true | 4609 |
Four rows, one per module: its position i in the list, the moduleId, whether it is active, and how many validators it runs.
How it reads
getStakingModuleIds() returns uint256[]; without expand it would be one array cell in one row. expand … as moduleId turns each element into a row of its own, repeating every other column, and index i numbers them from zero — a column worth keeping when the position in the list means something.
After the expand, moduleId is an ordinary column, and r.getStakingModuleIsActive(moduleId) calls the router once per row with that row's value. Both calls in the project are answered at the block of the source row — the newest, since there is no at — so the four rows describe one moment.
Variations
- Only the active ones.
| where activeafter theproject. - Total the validators.
| summarize validators = sum(validators)after theproject; the router's whole validator count in one row. - Over time.
from router at latest-50400..latest every 7200 as r, and each sampled block contributes as many rows as the router had modules then; addblock: $blockto the projection to tell them apart.