grandpa_roundState - Moonbeam RPC Method
Get the current GRANDPA finality round state on Moonbeam. Monitor consensus progress, validator voting participation, and finality health across the the cross-chain connected EVM platform on Polkadot with $65M+ TVL and 100+ projects network.
Returns the state of the current GRANDPA finality round on Moonbeam when the endpoint exposes validator-round internals. GRANDPA (GHOST-based Recursive ANcestor Deriving Prefix Agreement) is the finality gadget used by many Substrate-based chains to provide deterministic finality, but some public endpoints do not surface grandpa_roundState and instead return a method-not-found style error.
Why Moonbeam? Build on the cross-chain connected EVM platform on Polkadot with $65M+ TVL and 100+ projects with full EVM compatibility on Polkadot, native XCM cross-chain messaging, 10K+ TPS, 24% staking APR, and $0.015 transaction costs.
When to Use This Method
grandpa_roundState is essential for cross-chain dApp developers, Polkadot builders, and teams requiring multi-chain interoperability:
- Finality Monitoring -- Track whether GRANDPA rounds are progressing normally or stalling on Moonbeam, critical for cross-chain DeFi, multi-chain dApps, and Ethereum-to-Polkadot bridging via XCM, Axelar, LayerZero, and Wormhole
- Consensus Health Checks -- Detect finality delays by comparing prevote/precommit counts against the supermajority threshold weight
- Validator Participation Analysis -- Monitor which validators are actively voting and whether the authority set has sufficient online weight
- Authority Set Tracking -- Observe
setIdchanges after validator set rotations to verify smooth authority transitions - Capability Detection -- Confirm whether the shared endpoint exposes GRANDPA round internals before you build monitoring around them
Code Examples
curl -X POST https://api-moonbeam.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "grandpa_roundState",
"params": [],
"id": 1
}'Common Use Cases
1. Finality Health Monitoring
Periodically check whether GRANDPA rounds are progressing and alert on stalls:
import { ApiPromise, WsProvider } from '@polkadot/api';
async function monitorFinality(api, intervalMs = 10000) {
let lastRound = 0;
let lastSetId = 0;
let stallCount = 0;
setInterval(async () => {
const state = await api.rpc.grandpa.roundState();
const best = state.best;
const round = best.round.toNumber();
const setId = state.setId.toNumber();
const prevoteProgress = best.prevotes.currentWeight.toNumber();
const precommitProgress = best.precommits.currentWeight.toNumber();
const threshold = best.thresholdWeight.toNumber();
if (setId !== lastSetId) {
console.log(`Authority set changed: ${lastSetId} -> ${setId}`);
lastSetId = setId;
}
if (round === lastRound) {
stallCount++;
if (stallCount >= 3) {
console.warn(`GRANDPA round ${round} stalled for ${stallCount} checks`);
console.warn(` Prevotes: ${prevoteProgress}/${threshold}`);
console.warn(` Precommits: ${precommitProgress}/${threshold}`);
console.warn(` Missing voters: ${best.precommits.missing.length}`);
}
} else {
stallCount = 0;
console.log(`Round ${round} | prevotes=${prevoteProgress}/${threshold} precommits=${precommitProgress}/${threshold}`);
}
lastRound = round;
}, intervalMs);
}2. Validator Participation Report
Generate a report of which validators are consistently missing votes:
async function trackMissingVoters(api, samples = 20, delayMs = 6000) {
const missingCounts = {};
for (let i = 0; i < samples; i++) {
const state = await api.rpc.grandpa.roundState();
const missing = state.best.precommits.missing;
missing.forEach((authority) => {
const key = authority.toString();
missingCounts[key] = (missingCounts[key] || 0) + 1;
});
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
// Sort by most frequently missing
const sorted = Object.entries(missingCounts)
.sort(([, a], [, b]) => b - a);
console.log('Validator participation report:');
sorted.forEach(([authority, count]) => {
const missRate = ((count / samples) * 100).toFixed(1);
console.log(` ${authority}: missed ${count}/${samples} (${missRate}%)`);
});
return sorted;
}3. Supported-Fallback Check
If the endpoint does not expose GRANDPA round internals, fall back to finalized-head tracking:
async function getFinalitySignal(api) {
try {
return { supported: true, roundState: await api.rpc.grandpa.roundState() };
} catch (error) {
return {
supported: false,
finalizedHead: (await api.rpc.chain.getFinalizedHead()).toHex(),
message: error.message
};
}
}3. Finality Lag Detection
Compare the finalized head with the best block to measure finality lag:
async function getFinalityLag(api) {
const [roundState, finalizedHash, bestHeader] = await Promise.all([
api.rpc.grandpa.roundState(),
api.rpc.chain.getFinalizedHead(),
api.rpc.chain.getHeader()
]);
const finalizedHeader = await api.rpc.chain.getHeader(finalizedHash);
const bestNumber = bestHeader.number.toNumber();
const finalizedNumber = finalizedHeader.number.toNumber();
const lag = bestNumber - finalizedNumber;
return {
bestBlock: bestNumber,
finalizedBlock: finalizedNumber,
lagBlocks: lag,
grandpaRound: roundState.best.round.toNumber(),
setId: roundState.setId.toNumber(),
prevoteReached: roundState.best.prevotes.currentWeight.toNumber() >= roundState.best.thresholdWeight.toNumber(),
precommitReached: roundState.best.precommits.currentWeight.toNumber() >= roundState.best.thresholdWeight.toNumber()
};
}Understanding GRANDPA Rounds
GRANDPA achieves finality through a two-phase voting protocol:
-
Prevote Phase -- Each authority broadcasts a prevote for the highest block they consider best. Once prevotes reach the
thresholdWeight(supermajority), the protocol derives the highest block that is an ancestor of all supermajority prevotes. -
Precommit Phase -- Authorities that observe a supermajority of prevotes issue precommits for the block derived in the prevote phase. When precommits reach the threshold, that block and all its ancestors are finalized.
-
Authority Sets -- The
setIdincrements each time the authority set changes (e.g., after a session rotation). A new authority set starts a new round sequence from round 1.
| Concept | Description |
|---|---|
| totalWeight | Sum of all authority weights in the current set |
| thresholdWeight | ⌊totalWeight × 2/3⌋ + 1 -- minimum for supermajority |
| Healthy round | prevotes.currentWeight >= thresholdWeight AND precommits.currentWeight >= thresholdWeight |
| Stalled round | Neither prevotes nor precommits reach threshold for an extended period |
Error Handling
Common errors and solutions:
| Error Code | Description | Solution |
|---|---|---|
| -32603 | Internal error | The node may not be running the GRANDPA protocol (e.g., light client or parachain collator) -- verify node type |
| -32601 | Method not found | GRANDPA RPC is not enabled on this node -- check the node's --rpc-methods configuration |
| -32005 | Rate limit exceeded | Reduce polling frequency or implement client-side rate limiting |
| Empty response | No round data | Node may still be syncing or the GRANDPA voter has not started -- wait for sync completion |
Related Methods
chain_getFinalizedHead-- Get the hash of the latest finalized blockchain_subscribeFinalizedHeads-- Subscribe to new finalized block headersgrandpa_proveFinality-- Get a finality proof for a specific block numberbeefy_getFinalizedHead-- Get the latest BEEFY finalized block (if BEEFY is enabled)system_health-- Check overall node health including sync and peer status
payment_queryFeeDetails
Get a detailed fee breakdown for an extrinsic on Moonbeam. Analyze base fee, length fee, and adjusted weight fee components to optimize transaction costs for cross-chain DeFi, multi-chain dApps, and Ethereum-to-Polkadot bridging via XCM, Axelar, LayerZero, and Wormhole.
beefy_getFinalizedHead
Get the BEEFY finalized block hash on Moonbeam. Bridge-optimized finality proofs for cross-chain communication and light client verification on the cross-chain connected EVM platform on Polkadot with $65M+ TVL and 100+ projects.