Closed riemannulus closed 2 years ago
After some research, I found out, it's not just a snapshot issue 😅.
RocksDBStore.ForkBlockIndexes()
will fork from the previous chain rather than the current chain if the branch point to fork is within the coverage of the previous chain (i.e. if there are no new blocks in the current chain) to avoid unnecessary references. (See also).
Under this behavior, if a chain A is deleted immediately after it is forked to B, and if you try to fork this chain B back to C, it will try to refer to the previously deleted chain A, but the genesis will not be found and a problem will occur. Moving this to a test case on the Libplanet side, it looks something like this:
[SkippableFact]
public void ForkFromChainWithDeletion()
{
IStore store = Fx.Store;
Guid chainA = Guid.NewGuid();
Guid chainB = Guid.NewGuid();
Guid chainC = Guid.NewGuid();
// We need `Block<T>`s because `IStore` can't retrive index(long) by block hash without
// actual block...
store.PutBlock(Fx.GenesisBlock);
store.PutBlock(Fx.Block1);
store.AppendIndex(chainA, Fx.GenesisBlock.Hash);
store.AppendIndex(chainA, Fx.Block1.Hash);
store.ForkBlockIndexes(chainA, chainB, Fx.Block1.Hash);
store.DeleteChainId(chainA);
store.ForkBlockIndexes(chainB, chainC, Fx.Block1.Hash); // will raise here
}
There is a phenomenon that the preload fails because the chain ID is erased incorrectly.