182 lines
4.9 KiB
Markdown
182 lines
4.9 KiB
Markdown
# Chain Reorganization (Reorg) Support
|
|
|
|
HyperIndex automatically handles chain reorganizations to keep your indexed data consistent with the blockchain's canonical state.
|
|
|
|
## What Are Reorgs?
|
|
|
|
Chain reorganizations occur when the blockchain temporarily forks and then resolves to a single chain. When this happens:
|
|
|
|
- Some previously confirmed blocks get replaced
|
|
- Transactions may be dropped or reordered
|
|
- Indexed data may no longer be valid
|
|
|
|
HyperIndex detects reorgs and automatically rolls back affected data.
|
|
|
|
## Configuration
|
|
|
|
### Enable/Disable (Default: Enabled)
|
|
|
|
```yaml
|
|
# config.yaml
|
|
rollback_on_reorg: true # Default - recommended for production
|
|
```
|
|
|
|
### Confirmation Threshold
|
|
|
|
Configure how many blocks must pass before data is considered "final":
|
|
|
|
```yaml
|
|
# config.yaml
|
|
rollback_on_reorg: true
|
|
networks:
|
|
- id: 1 # Ethereum
|
|
confirmed_block_threshold: 250 # Higher for Ethereum mainnet
|
|
|
|
- id: 137 # Polygon
|
|
confirmed_block_threshold: 150 # Lower for faster chains
|
|
|
|
- id: 42161 # Arbitrum
|
|
# Uses default: 200 blocks
|
|
```
|
|
|
|
**Default threshold:** 200 blocks for all networks.
|
|
|
|
## What Gets Rolled Back
|
|
|
|
When a reorg is detected:
|
|
|
|
| Rolled Back | NOT Rolled Back |
|
|
|-------------|-----------------|
|
|
| All entity data | External API calls |
|
|
| Schema entities | Webhooks sent |
|
|
| Database writes | Logs written to files |
|
|
| | Analytics events |
|
|
|
|
## Example Configuration
|
|
|
|
```yaml
|
|
# Production config with reorg handling
|
|
name: my-indexer
|
|
rollback_on_reorg: true
|
|
|
|
networks:
|
|
- id: 1 # Ethereum Mainnet
|
|
confirmed_block_threshold: 250
|
|
start_block: 18000000
|
|
contracts:
|
|
- name: MyContract
|
|
address: "0x..."
|
|
handler: src/EventHandlers.ts
|
|
events:
|
|
- event: Transfer(address indexed from, address indexed to, uint256 value)
|
|
|
|
- id: 10 # Optimism
|
|
confirmed_block_threshold: 100 # Faster finality
|
|
start_block: 100000000
|
|
contracts:
|
|
- name: MyContract
|
|
address: "0x..."
|
|
handler: src/EventHandlers.ts
|
|
events:
|
|
- event: Transfer(address indexed from, address indexed to, uint256 value)
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### 1. Keep Reorg Support Enabled
|
|
|
|
```yaml
|
|
rollback_on_reorg: true # Always for production
|
|
```
|
|
|
|
Only disable for development/testing when you need faster iteration.
|
|
|
|
### 2. Use HyperSync for Guaranteed Detection
|
|
|
|
Reorg detection is **guaranteed** when using HyperSync (the default data source).
|
|
|
|
With custom RPC endpoints, edge cases may go undetected depending on the provider.
|
|
|
|
### 3. Avoid Non-Rollbackable Side Effects
|
|
|
|
```typescript
|
|
// BAD - Can't be rolled back if reorg happens
|
|
MyContract.Event.handler(async ({ event, context }) => {
|
|
await sendWebhook(event); // This stays even if block is reorged
|
|
await postToAnalytics(event);
|
|
});
|
|
|
|
// BETTER - Use Effect API with caching
|
|
// Or guard side effects appropriately
|
|
MyContract.Event.handler(async ({ event, context }) => {
|
|
// Entity writes ARE rolled back
|
|
context.Transfer.set({
|
|
id: `${event.chainId}_${event.transactionHash}_${event.logIndex}`,
|
|
// ...
|
|
});
|
|
|
|
// For critical external calls, consider confirmation delay
|
|
// or handle in a separate system that reads from your indexed data
|
|
});
|
|
```
|
|
|
|
### 4. Higher Thresholds for High-Value Apps
|
|
|
|
For financial applications or high-stakes data:
|
|
|
|
```yaml
|
|
networks:
|
|
- id: 1
|
|
confirmed_block_threshold: 300 # Extra conservative
|
|
```
|
|
|
|
### 5. Adjust Per Network
|
|
|
|
Different networks have different reorg characteristics:
|
|
|
|
| Network | Typical Reorg Depth | Recommended Threshold |
|
|
|---------|---------------------|----------------------|
|
|
| Ethereum | Rare, shallow | 200-300 |
|
|
| Polygon | More frequent | 150-200 |
|
|
| Arbitrum | Very rare (L2) | 100-150 |
|
|
| Optimism | Very rare (L2) | 100-150 |
|
|
| BSC | Occasional | 150-200 |
|
|
|
|
## Reorg Handling in Code
|
|
|
|
You generally don't need special code for reorgs - HyperIndex handles it automatically. However, be aware:
|
|
|
|
```typescript
|
|
MyContract.Event.handler(async ({ event, context }) => {
|
|
// This entity write will be rolled back if the block is reorged
|
|
context.Transfer.set({
|
|
id: `${event.chainId}_${event.block.number}_${event.logIndex}`,
|
|
from: event.params.from,
|
|
to: event.params.to,
|
|
amount: event.params.value,
|
|
// Include block info for debugging
|
|
blockNumber: BigInt(event.block.number),
|
|
blockHash: event.block.hash,
|
|
});
|
|
});
|
|
```
|
|
|
|
## Debugging Reorg Issues
|
|
|
|
If you suspect reorg-related data inconsistencies:
|
|
|
|
1. Check if `rollback_on_reorg: true` is set
|
|
2. Verify you're using HyperSync (not custom RPC)
|
|
3. Check block explorer for the affected block range
|
|
4. Look for "reorg detected" in indexer logs
|
|
|
|
## Summary
|
|
|
|
| Setting | Value | Use Case |
|
|
|---------|-------|----------|
|
|
| `rollback_on_reorg` | `true` | Production (default) |
|
|
| `rollback_on_reorg` | `false` | Dev/testing only |
|
|
| `confirmed_block_threshold` | 200 | Default for all networks |
|
|
| `confirmed_block_threshold` | 250-300 | High-value Ethereum apps |
|
|
| `confirmed_block_threshold` | 100-150 | L2s with fast finality |
|