mosaic-contracts
mosaic-contracts copied to clipboard
AuxiliaryBlockStore should validate against known hashes
User Story
As an auxiliary block store I want to validate block reports against known block hashes Because I want to prevent invalid block reports.
Scenario
Given that I observed a block on auxiliary When I report a valid block And its height is within the most recent 256 blocks Then the auxiliary block store should validate and accept it.
Given that I observed a block on auxiliary When I report an invalid block And its height is within the most recent 256 blocks Then the auxiliary block store should validate and decline it.
Given that I observed a block on auxiliary When I report any block And it is not within the most recent 256 blocks Then the auxiliary block store should accept it And should not treat it as reported.
Given that I fell behind in reporting When I report a valid block And it is now within the most recent 256 blocks Then the auxiliary block store should accept it And treat all previously reported blocks in this chain as reported.
Info
As long as reported blocks are within the last 256 blocks, the smart contract has access to the block hashes and can verify that the block hash corresponds to what is known to the node.
However, the validators could fall behind more than 256 blocks and should still be able to "catch up". That is why the auxiliary block store will accept any blocks (and branches) from before the most recent 256 blocks (it cannot verify). It stays true that a block can only be reported if its parent was reported, so that only "full chains" (forks) can be reported.
If the reporting falls behind head more than 256 blocks, then the validators can catch up by reporting older blocks. However, they should "catch up" to within 256 blocks again (report more than one block per generated block on the chain). As soon as they reach the 256 blocks where the auxiliary block store can verify, it should.
Any reported block should only be visible by external callers, if it was at any point within a chain that reaches into the most recent 256 blocks. (If a block is an ancestor of a reported block that was at one point verified)
If the reporting does not fall behind, every reported block should be regarded as reported. If the reporting does fall behind, the reported blocks should not be regarded as reported until the reporting catches up. Once the reporting catches up, all reported blocks in that chain should be regarded reported.
That means voting is not possible on blocks that have been reported, but weren't able to be verified by the smart contract, yet.
An optional optimization would be to prune unused forks once the reporting caught up. If the optimization won't be done within this issue, the implementer should create a follow-up issue.
⚠️ Do not update/delete incorrectly reported blocks as that opens up an attack vector where someone could report many invalid blocks and cleaning them up would lead to "out-of-gas"!
Contracts:
- AuxiliaryBlockStore
To validate a block report, you always have to recalculate the block hash from the header values