diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index accc4e7e6..517f0d70c 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/filecoin-project/go-state-types/network" + + v0smoothing "github.com/filecoin-project/specs-actors/actors/util/smoothing" ) type Version int @@ -21,3 +23,6 @@ func VersionForNetwork(version network.Version) Version { panic(fmt.Sprintf("unsupported network version %d", version)) } } + +// TODO: find some way to abstract over this. +type FilterEstimate = v0smoothing.FilterEstimate diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index 3d12ac9a8..99cca9879 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -12,6 +12,8 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +var Address = v0builtin.StorageMarketActorAddr + func Load(store adt.Store, act *types.Actor) (st State, err error) { switch act.Code { case v0builtin.StorageMarketActorCodeID: @@ -30,6 +32,9 @@ type State interface { EscrowTable() (BalanceTable, error) LockedTable() (BalanceTable, error) TotalLocked() (abi.TokenAmount, error) + VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, + ) (weight, verifiedWeight abi.DealWeight, err error) } type BalanceTable interface { diff --git a/chain/actors/builtin/market/v0.go b/chain/actors/builtin/market/v0.go index da86cda0f..fb67902da 100644 --- a/chain/actors/builtin/market/v0.go +++ b/chain/actors/builtin/market/v0.go @@ -1,6 +1,7 @@ package market import ( + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/actors/builtin/market" @@ -25,3 +26,9 @@ func (s *v0State) EscrowTable() (BalanceTable, error) { func (s *v0State) LockedTable() (BalanceTable, error) { return adt.AsBalanceTable(s.store, s.State.LockedTable) } + +func (s *v0State) VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, +) (weight, verifiedWeight abi.DealWeight, err error) { + return market.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) +} diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index 9e35e52ab..07399e1bf 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -9,6 +9,7 @@ import ( v0builtin "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" ) @@ -32,6 +33,8 @@ type State interface { TotalLocked() (abi.TokenAmount, error) TotalPower() (Claim, error) + TotalPowerSmoothed() (builtin.FilterEstimate, error) + MinerPower(address.Address) (Claim, bool, error) MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error) } diff --git a/chain/actors/builtin/power/v0.go b/chain/actors/builtin/power/v0.go index 12eb318e5..45dd570f6 100644 --- a/chain/actors/builtin/power/v0.go +++ b/chain/actors/builtin/power/v0.go @@ -3,6 +3,7 @@ package power import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/power" "github.com/filecoin-project/specs-actors/actors/util/adt" ) @@ -42,3 +43,7 @@ func (s *v0State) MinerPower(addr address.Address) (Claim, bool, error) { func (s *v0State) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) { return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a) } + +func (s *v0State) TotalPowerSmoothed() (builtin.FilterEstimate, error) { + return *s.State.ThisEpochQAPowerSmoothed, nil +} diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index a1a7cac5d..ba03feced 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -7,6 +7,7 @@ import ( v0builtin "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" ) @@ -27,4 +28,6 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) { type State interface { cbor.Marshaler + + RewardSmoothed() (builtin.FilterEstimate, error) } diff --git a/chain/actors/builtin/reward/v0.go b/chain/actors/builtin/reward/v0.go index 8fef3756c..a894fa752 100644 --- a/chain/actors/builtin/reward/v0.go +++ b/chain/actors/builtin/reward/v0.go @@ -1,6 +1,7 @@ package reward import ( + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/reward" "github.com/filecoin-project/specs-actors/actors/util/adt" ) @@ -9,3 +10,7 @@ type v0State struct { reward.State store adt.Store } + +func (s *v0State) RewardSmoothed() (builtin.FilterEstimate, error) { + return *s.State.ThisEpochRewardSmoothed, nil +} diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 10b5de82b..3ea40388f 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -21,16 +21,17 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/market" - "github.com/filecoin-project/specs-actors/actors/builtin/power" - "github.com/filecoin-project/specs-actors/actors/builtin/reward" + v0miner "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/specs-actors/actors/util/smoothing" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" + "github.com/filecoin-project/lotus/chain/actors/builtin/power" + "github.com/filecoin-project/lotus/chain/actors/builtin/reward" "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/state" @@ -41,6 +42,7 @@ import ( "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/lib/bufbstore" "github.com/filecoin-project/lotus/node/modules/dtypes" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" ) var errBreakForeach = errors.New("break") @@ -854,74 +856,57 @@ func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - var minerState miner.State - var powerState power.State - var rewardState reward.State - - err = a.StateManager.WithParentStateTsk(tsk, func(state *state.StateTree) error { - if err := a.StateManager.WithActor(maddr, a.StateManager.WithActorState(ctx, &minerState))(state); err != nil { - return xerrors.Errorf("getting miner state: %w", err) - } - - if err := a.StateManager.WithActor(builtin.StoragePowerActorAddr, a.StateManager.WithActorState(ctx, &powerState))(state); err != nil { - return xerrors.Errorf("getting power state: %w", err) - } - - if err := a.StateManager.WithActor(builtin.RewardActorAddr, a.StateManager.WithActorState(ctx, &rewardState))(state); err != nil { - return xerrors.Errorf("getting reward state: %w", err) - } - - return nil - }) + state, err := a.StateManager.ParentState(ts) if err != nil { - return types.EmptyInt, err + return types.EmptyInt, xerrors.Errorf("loading state %s: %w", tsk, err) } - dealWeights := market.VerifyDealsForActivationReturn{ - DealWeight: big.Zero(), - VerifiedDealWeight: big.Zero(), - } - - if len(pci.DealIDs) != 0 { - var err error - params, err := actors.SerializeParams(&market.VerifyDealsForActivationParams{ - DealIDs: pci.DealIDs, - SectorExpiry: pci.Expiration, - }) - if err != nil { - return types.EmptyInt, err - } - - ret, err := a.StateManager.Call(ctx, &types.Message{ - From: maddr, - To: builtin.StorageMarketActorAddr, - Method: builtin.MethodsMarket.VerifyDealsForActivation, - Params: params, - }, ts) - if err != nil { - return types.EmptyInt, err - } - - if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret.MsgRct.Return)); err != nil { - return types.BigInt{}, err - } - } - - mi, err := a.StateMinerInfo(ctx, maddr, tsk) + ssize, err := pci.SealProof.SectorSize() if err != nil { - return types.EmptyInt, err + return types.EmptyInt, xerrors.Errorf("failed to get resolve size: %w", err) } - ssize := mi.SectorSize + store := a.Chain.Store(ctx) - duration := pci.Expiration - ts.Height() // NB: not exactly accurate, but should always lead us to *over* estimate, not under + var sectorWeight abi.StoragePower + if act, err := state.GetActor(market.Address); err != nil { + return types.EmptyInt, xerrors.Errorf("loading miner actor %s: %w", maddr, err) + } else s, err := market.Load(store, act); err != nil { + return types.EmptyInt, xerrors.Errorf("loading market actor state %s: %w", maddr, err) + } else if w, vw, err := s.VerifyDealsForActivation(maddr, pci.DealIDs, ts.Height(), pci.Expiration); err != nil { + return types.EmptyInt, xerrors.Errorf("verifying deals for activation: %w", err) + } else { + // NB: not exactly accurate, but should always lead us to *over* estimate, not under + duration := pci.Expiration - ts.Height() - sectorWeight := miner.QAPowerForWeight(ssize, duration, dealWeights.DealWeight, dealWeights.VerifiedDealWeight) - deposit := miner.PreCommitDepositForPower( - rewardState.ThisEpochRewardSmoothed, - powerState.ThisEpochQAPowerSmoothed, - sectorWeight, - ) + // TODO: handle changes to this function across actor upgrades. + sectorWeight = v0miner.QAPowerForWeight(ssize, duration, w, vw) + } + + var powerSmoothed smoothing.FilterEstimate + if act, err := state.GetActor(power.Address); err != nil { + return types.EmptyInt, xerrors.Errorf("loading miner actor: %w", err) + } else s, err := power.Load(store, act); err != nil { + return types.EmptyInt, xerrors.Errorf("loading power actor state: %w", err) + } else p, err := s.TotalPowerSmoothed(); err != nil { + return types.EmptyInt, xerrors.Errorf("failed to determine total power: %w", err) + } else { + powerSmoothed = p + } + + var rewardSmoothed smoothing.FilterEstimate + if act, err := state.GetActor(reward.Address); err != nil { + return types.EmptyInt, xerrors.Errorf("loading miner actor: %w", err) + } else s, err := reward.Load(store, act); err != nil { + return types.EmptyInt, xerrors.Errorf("loading reward actor state: %w", err) + } else r, err := s.RewardSmoothed(); err != nil { + return types.EmptyInt, xerrors.Errorf("failed to determine total reward: %w", err) + } else { + rewardSmoothed = r + } + + // TODO: abstract over network upgrades. + deposit := v0miner.PreCommitDepositForPower(rewardSmoothed, powerSmoothed, sectorWeight) return types.BigDiv(types.BigMul(deposit, initialPledgeNum), initialPledgeDen), nil }