keep genesis-linked state hot
This commit is contained in:
parent
e9f531b4aa
commit
7cf75e667d
@ -101,6 +101,7 @@ type Config struct {
|
||||
// ChainAccessor allows the Splitstore to access the chain. It will most likely
|
||||
// be a ChainStore at runtime.
|
||||
type ChainAccessor interface {
|
||||
GetGenesis() (*types.BlockHeader, error)
|
||||
GetTipsetByHeight(context.Context, abi.ChainEpoch, *types.TipSet, bool) (*types.TipSet, error)
|
||||
GetHeaviestTipSet() *types.TipSet
|
||||
SubscribeHeadChanges(change func(revert []*types.TipSet, apply []*types.TipSet) error)
|
||||
@ -127,6 +128,8 @@ type SplitStore struct {
|
||||
cold bstore.Blockstore
|
||||
tracker TrackingStore
|
||||
|
||||
genesis, genesisStateRoot cid.Cid
|
||||
|
||||
env MarkSetEnv
|
||||
|
||||
markSetSize int64
|
||||
@ -326,6 +329,60 @@ func (s *SplitStore) Start(chain ChainAccessor) error {
|
||||
s.chain = chain
|
||||
s.curTs = chain.GetHeaviestTipSet()
|
||||
|
||||
// make sure the genesis and its state root are hot
|
||||
gb, err := chain.GetGenesis()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error getting genesis: %w", err)
|
||||
}
|
||||
|
||||
s.genesis = gb.Cid()
|
||||
s.genesisStateRoot = gb.ParentStateRoot
|
||||
|
||||
has, err := s.hot.Has(s.genesis)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error checking hotstore for genesis: %w", err)
|
||||
}
|
||||
|
||||
if !has {
|
||||
blk, err := gb.ToStorageBlock()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error converting genesis block to storage block: %w", err)
|
||||
}
|
||||
|
||||
err = s.hot.Put(blk)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error putting genesis block to hotstore: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = s.walkLinks(s.genesisStateRoot, cid.NewSet(), func(c cid.Cid) error {
|
||||
has, err = s.hot.Has(c)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error checking hotstore for genesis state root: %w", err)
|
||||
}
|
||||
|
||||
if !has {
|
||||
blk, err := s.cold.Get(c)
|
||||
if err != nil {
|
||||
if err == bstore.ErrNotFound {
|
||||
return nil
|
||||
}
|
||||
|
||||
return xerrors.Errorf("error retrieving genesis state linked object from coldstore: %w", err)
|
||||
}
|
||||
|
||||
err = s.hot.Put(blk)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error putting genesis state linked object to hotstore: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error walking genesis state root links: %w", err)
|
||||
}
|
||||
|
||||
// load base epoch from metadata ds
|
||||
// if none, then use current epoch because it's a fresh start
|
||||
bs, err := s.ds.Get(baseEpochKey)
|
||||
|
@ -149,8 +149,8 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
||||
t.Errorf("expected %d cold blocks, but got %d", 7, coldCnt)
|
||||
}
|
||||
|
||||
if hotCnt != 4 {
|
||||
t.Errorf("expected %d hot blocks, but got %d", 4, hotCnt)
|
||||
if hotCnt != 5 {
|
||||
t.Errorf("expected %d hot blocks, but got %d", 5, hotCnt)
|
||||
}
|
||||
|
||||
// Make sure we can revert without panicking.
|
||||
@ -165,6 +165,7 @@ type mockChain struct {
|
||||
t testing.TB
|
||||
|
||||
sync.Mutex
|
||||
genesis *types.BlockHeader
|
||||
tipsets []*types.TipSet
|
||||
listener func(revert []*types.TipSet, apply []*types.TipSet) error
|
||||
}
|
||||
@ -172,6 +173,9 @@ type mockChain struct {
|
||||
func (c *mockChain) push(ts *types.TipSet) {
|
||||
c.Lock()
|
||||
c.tipsets = append(c.tipsets, ts)
|
||||
if c.genesis == nil {
|
||||
c.genesis = ts.Blocks()[0]
|
||||
}
|
||||
c.Unlock()
|
||||
|
||||
if c.listener != nil {
|
||||
@ -201,6 +205,10 @@ func (c *mockChain) revert(count int) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *mockChain) GetGenesis() (*types.BlockHeader, error) {
|
||||
return c.genesis, nil
|
||||
}
|
||||
|
||||
func (c *mockChain) GetTipsetByHeight(_ context.Context, epoch abi.ChainEpoch, _ *types.TipSet, _ bool) (*types.TipSet, error) {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
Loading…
Reference in New Issue
Block a user