diff --git a/chain/stmgr/supply.go b/chain/stmgr/supply.go index b48f9af43da..9486cb93622 100644 --- a/chain/stmgr/supply.go +++ b/chain/stmgr/supply.go @@ -388,6 +388,14 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha circ := big.Zero() unCirc := big.Zero() err := st.ForEach(func(a address.Address, actor *types.Actor) error { + // this can be a lengthy operation, we need to cancel early when + // the context is cancelled to avoid resource exhaustion + select { + case <-ctx.Done(): + // this will cause ForEach to return + return ctx.Err() + default: + } switch { case actor.Balance.IsZero(): // Do nothing for zero-balance actors diff --git a/chain/store/store.go b/chain/store/store.go index e930d6652a5..8304a797223 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -948,6 +948,14 @@ func ReorgOps(ctx context.Context, lts func(ctx context.Context, _ types.TipSetK var leftChain, rightChain []*types.TipSet for !left.Equals(right) { + // this can take a long time and lot of memory if the tipsets are far apart + // since it can be reached through remote calls, we need to + // cancel early when possible to prevent resource exhaustion. + select { + case <-ctx.Done(): + return nil, nil, ctx.Err() + default: + } if left.Height() > right.Height() { leftChain = append(leftChain, left) par, err := lts(ctx, left.Parents()) @@ -1004,7 +1012,7 @@ func (cs *ChainStore) AddToTipSetTracker(ctx context.Context, b *types.BlockHead // This means that we ideally want to keep only most recent 900 epochs in here // Golang's map iteration starts at a random point in a map. // With 5 tries per epoch, and 900 entries to keep, on average we will have - // ~136 garbage entires in the `cs.tipsets` map. (solve for 1-(1-x/(900+x))^5 == 0.5) + // ~136 garbage entries in the `cs.tipsets` map. (solve for 1-(1-x/(900+x))^5 == 0.5) // Seems good enough to me for height := range cs.tipsets {