chain_getFinalizedHead - JSON-RPC Method
Description#
Returns the hash of the latest finalized block. On Moonriver (a Kusama parachain), blocks are finalized via the relay chain’s GRANDPA finality gadget, providing deterministic finality. This method is crucial for applications that need to ensure transactions are irreversible.
Parameters#
This method does not require any parameters.
Returns#
| Field | Type | Description |
|---|---|---|
result | string | Hex-encoded hash of the latest finalized block |
Request Example#
{
"jsonrpc": "2.0",
"method": "chain_getFinalizedHead",
"params": [],
"id": 1
}
Response Example#
{
"jsonrpc": "2.0",
"result": "0xa39d25f8cf7ad27e6a739dc15d4d013bdc48b6e2819bb74c72822a930adb5649",
"id": 1
}
Code Examples#
- cURL
- Python
- JavaScript
- TypeScript (@polkadot/api)
curl https://api-moonriver.n.dwellir.com/YOUR_API_KEY \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "chain_getFinalizedHead",
"params": [],
"id": 1
}'
import requests
import json
def get_finalized_head():
url = "https://api-moonriver.n.dwellir.com/YOUR_API_KEY"
headers = {
"Content-Type": "application/json"
}
payload = {
"jsonrpc": "2.0",
"method": "chain_getFinalizedHead",
"params": [],
"id": 1
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
data = response.json()
if "error" in data:
raise Exception(f"RPC Error: {data['error']}")
return data["result"]
# Monitor finalization
finalized_hash = get_finalized_head()
print(f"Finalized block hash: {finalized_hash}")
const getFinalizedHead = async () => {
const response = await fetch('https://api-moonriver.n.dwellir.com/YOUR_API_KEY', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
jsonrpc: '2.0',
method: 'chain_getFinalizedHead',
params: [],
id: 1
})
});
const data = await response.json();
return data.result;
};
// Get finalized block details
const finalizedHash = await getFinalizedHead();
console.log('Latest finalized block:', finalizedHash);
// Get full block data
const blockData = await getBlock(finalizedHash);
console.log('Finalized block number:', parseInt(blockData.block.header.number, 16));
import { ApiPromise, WsProvider } from '@polkadot/api';
async function trackFinalization() {
const provider = new WsProvider('wss://api-moonriver.n.dwellir.com/YOUR_API_KEY');
const api = await ApiPromise.create({ provider });
// Get current finalized head
const finalizedHash = await api.rpc.chain.getFinalizedHead();
console.log('Finalized hash:', finalizedHash.toHex());
// Get finalized block details
const finalizedBlock = await api.rpc.chain.getBlock(finalizedHash);
const blockNumber = finalizedBlock.block.header.number.toNumber();
console.log('Finalized block number:', blockNumber);
// Calculate finalization lag
const latestHeader = await api.rpc.chain.getHeader();
const latestNumber = latestHeader.number.toNumber();
const lag = latestNumber - blockNumber;
console.log(`Finalization lag: ${lag} blocks`);
await api.disconnect();
}
Finality in Moonriver#
GRANDPA Finality#
- Deterministic: Once finalized, blocks cannot be reverted
- Fast: Typically finalizes within 12-60 seconds
- Byzantine Fault Tolerant: Secure with up to 1/3 malicious validators
Finalization Process#
- Block is produced by BABE
- Block propagates through network
- GRANDPA validators vote on chains
- Super-majority agreement finalizes block
Use Cases#
- Exchange Deposits: Wait for finalization before crediting
- Smart Contract Events: Ensure events are permanent
- Cross-chain Bridges: Transfer assets after finalization
- Block Explorers: Display finalized vs unfinalized blocks
- Monitoring Tools: Track finalization performance
Finalization Monitoring#
// Monitor finalization progress
async function monitorFinalization() {
let lastFinalized = await getFinalizedHead();
setInterval(async () => {
const currentFinalized = await getFinalizedHead();
if (currentFinalized !== lastFinalized) {
console.log('New finalized block:', currentFinalized);
// Check how many blocks were finalized
const oldBlock = await getBlock(lastFinalized);
const newBlock = await getBlock(currentFinalized);
const oldNumber = parseInt(oldBlock.block.header.number, 16);
const newNumber = parseInt(newBlock.block.header.number, 16);
console.log(`Finalized ${newNumber - oldNumber} blocks`);
lastFinalized = currentFinalized;
}
}, 6000); // Check every 6 seconds
}
Notes#
- Finalized blocks are immutable and cannot be reverted
- Finalization typically lags 2-10 blocks behind the latest block
- During network issues, finalization may stall temporarily
- Always use finalized blocks for critical operations
- Finalization provides stronger guarantees than probabilistic finality
Related Methods#
chain_getBlock- Get full block datachain_getBlockHash- Get block hash by numberstate_getMetadata- Get runtime metadatasystem_health- Check node status