diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 2db04c695..eb98029c6 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -2,6 +2,7 @@ package stmgr import ( "context" + "math/big" amt "github.com/filecoin-project/go-amt-ipld/v2" "github.com/filecoin-project/lotus/build" @@ -35,12 +36,69 @@ func (sm *StateManager) handleStateForks(ctx context.Context, pstate cid.Cid, he if err != nil { return cid.Undef, xerrors.Errorf("booty bay bug fix failed: %w", err) } + case build.ForkMissingSnowballs: + log.Warnw("Adding more snow to the world", "height", i) + pstate, err = fixTooFewSnowballs(ctx, sm, pstate) + if err != nil { + return cid.Undef, xerrors.Errorf("booty bay bug fix failed: %w", err) + } } } return pstate, nil } +func fixTooFewSnowballs(ctx context.Context, sm *StateManager, pstate cid.Cid) (cid.Cid, error) { + cst := hamt.CSTFromBstore(sm.cs.Blockstore()) + st, err := state.LoadStateTree(cst, pstate) + if err != nil { + return cid.Undef, err + } + + spa, err := st.GetActor(actors.StoragePowerAddress) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to get storage power actor: %w", err) + } + + var spast actors.StoragePowerState + if err := cst.Get(ctx, spa.Head, &spast); err != nil { + return cid.Undef, err + } + + miners, err := actors.MinerSetList(ctx, cst, spast.Miners) + if err != nil { + return cid.Undef, err + } + + sum := new(big.Int) + for _, m := range miners { + mact, err := st.GetActor(m) + if err != nil { + return cid.Undef, xerrors.Errorf("getting miner actor to fix: %w", err) + } + + var mstate actors.StorageMinerActorState + if err := cst.Get(ctx, mact.Head, &mstate); err != nil { + return cid.Undef, xerrors.Errorf("failed to load miner actor state: %w", err) + } + + if mstate.SlashedAt != 0 { + continue + } + sum = sum.Add(sum, mstate.Power.Int) + } + + spast.TotalStorage.Int = sum + nspahead, err := cst.Put(ctx, spast) + if err != nil { + return cid.Undef, err + } + + spa.Head = nspahead + + return st.Flush(ctx) +} + /* 1) Iterate through each miner in the chain: 1.1) Fixup their sector set and proving set