-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Bug report
When using graphman copy create with a large offset on a pruned source, the destination deployment ends up with an earliest_block_number higher than its head block, resulting in an invalid/corrupted state.
Root cause
At the end of a copy operation, copy_earliest_block() (store/postgres/src/deployment.rs:1336) unconditionally copies the earliest_block_number from source to destination:
update(d::table.filter(d::id.eq(dst.id)))
.set(d::earliest_block_number.eq(sql(&query)))
.execute(conn)?;This is called from deployment_store.rs:1619, after the copy is finalized.
When the source has been pruned (e.g. earliest_block_number = 38545619) and the copy uses a large offset that results in a destination head below that value (e.g. head at 35583707), the destination inherits the source's pruned earliest_block_number.
Consequences
The destination deployment ends up in an inconsistent state:
head = 35583707earliest_block_number = 38545619(from the pruned source)
This blocks graphman rewind with:
The block number 35522000 is not safe to rewind to for deployment QmXXX[6103].
The earliest block number of this deployment is 38545619.
Steps to reproduce
- Have a subgraph
sgd2027that has been pruned (earliest_block_numberadvanced to e.g. 38545619) - Run
graphman copy createwith a large offset, so the copy is taken at a block below the source'searliest_block_number - Observe that the destination
sgd6103hasearliest_block_number = 38545619but its head is at ~35.5M - Try to rewind
sgd6103— blocked by the safety check
Expected behavior
The copy should be refused when the target block (head - offset) is below the source's earliest_block_number, as the resulting deployment would be in an invalid state.