-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
What is the current behavior?
Currently when deploying a subgraph, there is a piece of code that resolve the current start block. The current logic is to do the following:
// If the minimum start block is 0 (i.e. the genesis block),
// return `None` to start indexing from the genesis block. Otherwise
// return a block pointer for the block with number `min_start_block - 1`.
let start_block_ptr = match manifest
.start_blocks()
.into_iter()
.min()
.expect("cannot identify minimum start block because there are no data sources")
{
0 => None,
min_start_block => chain
.block_pointer_from_number(logger, min_start_block - 1)
.await
.map(Some)
.map_err(move |_| {
SubgraphRegistrarError::ManifestValidationError(vec![
SubgraphManifestValidationError::BlockNotFound(min_start_block.to_string()),
])
})?,
};
We go find the block before the start block because inside graph node, the block_ptr
is inclusive and represents the currently last processed block.
The logic of doing -1
is flawed for chains that has the ability to skip blocks, like NEAR and Solana. For example, imagine the user's start block is defined as 1000
but the chain only produced block 998
and 1002
(so blocks 999
, 1000
, 1001
do not exist).
If you do block_pointer_from_number(1000 - 1)
(e.g. block_pointer_from_number(1000 - 1)
), with the current implementation on NEAR, the resolved block with be 1002
(because Firehose stream is going to give the next following block of 999
which in our case here is 1002
.
This will ultimately lead to a block being missed because when FirehoseBlockStream starts from the existing block_ptr
, it does + 1
to it so start from the block just after the block_ptr
.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.
Would need to find a block for which it's parent is not directly num - 1
and use that as a start block.
What is the expected behavior?
The correct behavior is I think to introduce a parent_block_from_number
(might not be a pretty good name because could be confused, maybe parent_block_of_block_number
?).
This would be implemented by each chain. If the chain cannot skip block num, then it could simply forward to block_pointer_from_number(num - 1)
, on chain that would skip blocks, a two step process would be required:
- Fetch current block at
num
- Extract
parent_num
from block received - Fetch block for
parent_num
.