diff --git a/chain/deals/asks.go b/chain/deals/asks.go index fe586abc0..c4e40af9d 100644 --- a/chain/deals/asks.go +++ b/chain/deals/asks.go @@ -143,10 +143,7 @@ func (h *Handler) saveAsk(a *types.SignedStorageAsk) error { } func (c *Client) checkAskSignature(ask *types.SignedStorageAsk) error { - tss, _, err := c.sm.TipSetState(c.sm.ChainStore().GetHeaviestTipSet().Cids()) - if err != nil { - return xerrors.Errorf("failed to get tipsetstate to query for miner worker: %w", err) - } + tss := c.sm.ChainStore().GetHeaviestTipSet().ParentState() w, err := stmgr.GetMinerWorker(context.TODO(), c.sm, tss, ask.Ask.Miner) if err != nil { diff --git a/chain/gen/gen.go b/chain/gen/gen.go index f1f267f77..48e0653d7 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -201,10 +201,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, m address.Address, ticks lastTicket = ticks[len(ticks)-1] } - st, _, err := cg.sm.TipSetState(pts.Cids()) - if err != nil { - return nil, nil, err - } + st := cg.curTipset.TipSet().ParentState() worker, err := stmgr.GetMinerWorker(ctx, cg.sm, st, m) if err != nil { @@ -376,12 +373,7 @@ func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, ts *t } func (mca mca) StateMinerWorker(ctx context.Context, maddr address.Address, ts *types.TipSet) (address.Address, error) { - st, _, err := mca.sm.TipSetState(ts.Cids()) - if err != nil { - return address.Undef, err - } - - return stmgr.GetMinerWorker(ctx, mca.sm, st, maddr) + return stmgr.GetMinerWorker(ctx, mca.sm, ts.ParentState(), maddr) } func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*types.Signature, error) { diff --git a/chain/gen/mining.go b/chain/gen/mining.go index 05904b7af..dcff62df8 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -20,7 +20,7 @@ import ( ) func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, miner address.Address, parents *types.TipSet, tickets []*types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage, timestamp uint64) (*types.FullBlock, error) { - st, recpts, err := sm.TipSetState(parents.Cids()) + st, recpts, err := sm.TipSetState(parents) if err != nil { return nil, errors.Wrap(err, "failed to load tipset state") } diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index ec9ba79a2..de6f36f43 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -53,10 +53,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. ts = sm.cs.GetHeaviestTipSet() } - state, _, err := sm.TipSetState(ts.Cids()) - if err != nil { - return nil, xerrors.Errorf("getting tipset state: %w", err) - } + state := ts.ParentState() r := vm.NewChainRand(sm.cs, ts.Cids(), ts.Height(), nil) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 7361f363a..ee8eb0b46 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -43,10 +43,10 @@ func cidsToKey(cids []cid.Cid) string { return out } -func (sm *StateManager) TipSetState(cids []cid.Cid) (cid.Cid, cid.Cid, error) { +func (sm *StateManager) TipSetState(ts *types.TipSet) (cid.Cid, cid.Cid, error) { ctx := context.TODO() - ck := cidsToKey(cids) + ck := cidsToKey(ts.Cids()) sm.stlk.Lock() cached, ok := sm.stCache[ck] sm.stlk.Unlock() @@ -54,11 +54,6 @@ func (sm *StateManager) TipSetState(cids []cid.Cid) (cid.Cid, cid.Cid, error) { return cached[0], cached[1], nil } - ts, err := sm.cs.LoadTipSet(cids) - if err != nil { - return cid.Undef, cid.Undef, err - } - if ts.Height() == 0 { // NB: Genesis block is a weird case here... return ts.Blocks()[0].ParentStateRoot, ts.Blocks()[0].ParentMessageReceipts, nil @@ -198,10 +193,7 @@ func (sm *StateManager) GetActor(addr address.Address, ts *types.TipSet) (*types ts = sm.cs.GetHeaviestTipSet() } - stcid, _, err := sm.TipSetState(ts.Cids()) - if err != nil { - return nil, xerrors.Errorf("tipset state: %w", err) - } + stcid := ts.ParentState() cst := hamt.CSTFromBstore(sm.cs.Blockstore()) state, err := state.LoadStateTree(cst, stcid) diff --git a/chain/sync.go b/chain/sync.go index c1616ef92..d3028f057 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -381,7 +381,13 @@ func (syncer *Syncer) validateTickets(ctx context.Context, mworker address.Addre // Should match up with 'Semantical Validation' in validation.md in the spec func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error { h := b.Header - stateroot, precp, err := syncer.sm.TipSetState(h.Parents) + + baseTs, err := syncer.store.LoadTipSet(h.Parents) + if err != nil { + return xerrors.Errorf("load tipset failed: %w", err) + } + + stateroot, precp, err := syncer.sm.TipSetState(baseTs) if err != nil { return xerrors.Errorf("get tipsetstate(%d, %s) failed: %w", h.Height, h.Parents, err) } @@ -394,11 +400,6 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err return xerrors.Errorf("parent receipts root did not match computed value (%s != %s)", precp, h.ParentMessageReceipts) } - baseTs, err := syncer.store.LoadTipSet(h.Parents) - if err != nil { - return xerrors.Errorf("load tipset failed: %w", err) - } - if h.Timestamp > uint64(time.Now().Unix()+build.AllowableClockDrift) { return xerrors.Errorf("block was from the future") } diff --git a/chain/types/tipset.go b/chain/types/tipset.go index 3337a823e..688edacd4 100644 --- a/chain/types/tipset.go +++ b/chain/types/tipset.go @@ -150,6 +150,10 @@ func (ts *TipSet) MinTicketBlock() *BlockHeader { return min } +func (ts *TipSet) ParentState() cid.Cid { + return ts.blks[0].ParentStateRoot +} + func (ts *TipSet) Contains(oc cid.Cid) bool { for _, c := range ts.cids { if c == oc { diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 3955a7581..13dbf5cb7 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -134,7 +134,7 @@ func (a *StateAPI) stateForTs(ts *types.TipSet) (*state.StateTree, error) { ts = a.Chain.GetHeaviestTipSet() } - st, _, err := a.StateManager.TipSetState(ts.Cids()) + st, _, err := a.StateManager.TipSetState(ts) if err != nil { return nil, err }