[WIP] Network upgrade support
This patch starts adding support for network upgrades. * It adds an actors abstraction layer for loading abstract (cross-version) actors. * It starts switching over to a shared deadline type. * It adds an abstraction for ADTs (hamt/amt). * It removes the callback-based API in the StateManager (difficult to abstract across actor versions). * It _does not_ actually add support for actors v2. We can do that in a followup patch but that should be relatively easy. This patch is heavily WIP and does not compile. Feel free to push changes directly to this branch. Notes: * State tree access now needs a network version, because the HAMT type will change. * I haven't figured out a nice way to abstract over changes to the _message_ types. However, many of them will be type aliased to actors v0 in actors v2 so we can likely continue using the v0 versions (or use the v2 versions everywhere). I've been renaming imports to `v0*` to make it clear that we're importing types from a _specific_ actors version. TODO: * Consider merging incremental improvements? We'd have to get this compiling again first but we could merge in the new abstractions, and slowly switch over. * Finish migrating to the new abstractions. * Remove all actor state types from the public API. See `miner.State.Info()` for the planned approach here. * Fix the tests. This is likely going to be a massive pain.
This commit is contained in:
parent
a2f1e76fea
commit
d3594835c4
@ -18,6 +18,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
@ -312,15 +313,11 @@ type FullNode interface {
|
||||
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||
// StateMinerProvingDeadline calculates the deadline at some epoch for a proving period
|
||||
// and returns the deadline-related calculations.
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error)
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
|
||||
// StateMinerPower returns the power of the indicated miner
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||
// StateMinerInfo returns info about the indicated miner
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (MinerInfo, error)
|
||||
// StateMinerDeadlines returns all the proving deadlines for the given miner
|
||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]*miner.Deadline, error)
|
||||
// StateMinerPartitions loads miner partitions for the specified miner/deadline
|
||||
StateMinerPartitions(context.Context, address.Address, uint64, types.TipSetKey) ([]*miner.Partition, error)
|
||||
// StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner
|
||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
|
||||
// StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset
|
||||
|
47
api/types.go
47
api/types.go
@ -8,9 +8,10 @@ import (
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
v0miner "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
@ -49,48 +50,6 @@ type PubsubScore struct {
|
||||
Score *pubsub.PeerScoreSnapshot
|
||||
}
|
||||
|
||||
type MinerInfo struct {
|
||||
Owner address.Address // Must be an ID-address.
|
||||
Worker address.Address // Must be an ID-address.
|
||||
NewWorker address.Address // Must be an ID-address.
|
||||
ControlAddresses []address.Address // Must be an ID-addresses.
|
||||
WorkerChangeEpoch abi.ChainEpoch
|
||||
PeerId *peer.ID
|
||||
Multiaddrs []abi.Multiaddrs
|
||||
SealProofType abi.RegisteredSealProof
|
||||
SectorSize abi.SectorSize
|
||||
WindowPoStPartitionSectors uint64
|
||||
}
|
||||
|
||||
func NewApiMinerInfo(info *miner.MinerInfo) MinerInfo {
|
||||
var pid *peer.ID
|
||||
if peerID, err := peer.IDFromBytes(info.PeerId); err == nil {
|
||||
pid = &peerID
|
||||
}
|
||||
|
||||
mi := MinerInfo{
|
||||
Owner: info.Owner,
|
||||
Worker: info.Worker,
|
||||
ControlAddresses: info.ControlAddresses,
|
||||
|
||||
NewWorker: address.Undef,
|
||||
WorkerChangeEpoch: -1,
|
||||
|
||||
PeerId: pid,
|
||||
Multiaddrs: info.Multiaddrs,
|
||||
SealProofType: info.SealProofType,
|
||||
SectorSize: info.SectorSize,
|
||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||
}
|
||||
|
||||
if info.PendingWorkerKey != nil {
|
||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||
}
|
||||
|
||||
return mi
|
||||
}
|
||||
|
||||
type MessageSendSpec struct {
|
||||
MaxFee abi.TokenAmount
|
||||
}
|
||||
@ -151,3 +110,5 @@ func NewDataTransferChannel(hostID peer.ID, channelState datatransfer.ChannelSta
|
||||
}
|
||||
return channel
|
||||
}
|
||||
|
||||
type
|
||||
|
57
chain/actors/adt/adt.go
Normal file
57
chain/actors/adt/adt.go
Normal file
@ -0,0 +1,57 @@
|
||||
package adt
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
v0adt "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
type Map interface {
|
||||
Root() (cid.Cid, error)
|
||||
|
||||
Put(k abi.Keyer, v cbor.Marshaler) error
|
||||
Get(k abi.Keyer, v cbor.Unmarshaler) (bool, error)
|
||||
Delete(k abi.Keyer) error
|
||||
|
||||
ForEach(v cbor.Unmarshaler, fn func(key string) error) error
|
||||
}
|
||||
|
||||
func AsMap(store Store, root cid.Cid, version network.Version) (Map, error) {
|
||||
switch builtin.VersionForNetwork(version) {
|
||||
case builtin.Version0:
|
||||
return v0adt.AsMap(store, root)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
||||
|
||||
func NewMap(store Store, version network.Version) (Map, error) {
|
||||
switch builtin.VersionForNetwork(version) {
|
||||
case builtin.Version0:
|
||||
return v0adt.MakeEmptyMap(store)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
||||
|
||||
type Array interface {
|
||||
Root() (cid.Cid, error)
|
||||
|
||||
Set(idx uint64, v cbor.Marshaler) error
|
||||
Get(idx uint64, v cbor.Unmarshaler) (bool, error)
|
||||
Delete(idx uint64) error
|
||||
Length() uint64
|
||||
|
||||
ForEach(v cbor.Unmarshaler, fn func(idx int) error) error
|
||||
}
|
||||
|
||||
func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) {
|
||||
switch builtin.VersionForNetwork(version) {
|
||||
case builtin.Version0:
|
||||
return v0adt.AsArray(store, root)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
17
chain/actors/adt/store.go
Normal file
17
chain/actors/adt/store.go
Normal file
@ -0,0 +1,17 @@
|
||||
package adt
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
adt "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
Context() context.Context
|
||||
cbor.IpldStore
|
||||
}
|
||||
|
||||
func WrapStore(ctx context.Context, store cbor.IpldStore) Store {
|
||||
return adt.WrapStore(ctx, store)
|
||||
}
|
29
chain/actors/builtin/README.md
Normal file
29
chain/actors/builtin/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Actors
|
||||
|
||||
This package contains shims for abstracting over different actor versions.
|
||||
|
||||
## Design
|
||||
|
||||
Shims in this package follow a few common design principles.
|
||||
|
||||
### Structure Agnostic
|
||||
|
||||
Shims interfaces defined in this package should (ideally) not change even if the
|
||||
structure of the underlying data changes. For example:
|
||||
|
||||
* All shims store an internal "store" object. That way, state can be moved into
|
||||
a separate object without needing to add a store to the function signature.
|
||||
* All functions must return an error, even if unused for now.
|
||||
|
||||
### Minimal
|
||||
|
||||
These interfaces should be expanded only as necessary to reduce maintenance burden.
|
||||
|
||||
### Queries, not field assessors.
|
||||
|
||||
When possible, functions should query the state instead of simply acting as
|
||||
field assessors. These queries are more likely to remain stable across
|
||||
specs-actor upgrades than specific state fields.
|
||||
|
||||
Note: there is a trade-off here. Avoid implementing _complicated_ query logic
|
||||
inside these shims, as it will need to be replicated in every shim.
|
23
chain/actors/builtin/builtin.go
Normal file
23
chain/actors/builtin/builtin.go
Normal file
@ -0,0 +1,23 @@
|
||||
package builtin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
)
|
||||
|
||||
type Version int
|
||||
|
||||
const (
|
||||
Version0 = iota
|
||||
)
|
||||
|
||||
// Converts a network version into a specs-actors version.
|
||||
func VersionForNetwork(version network.Version) Version {
|
||||
switch version {
|
||||
case network.Version0, network.Version1:
|
||||
return Version
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported network version %d", version))
|
||||
}
|
||||
}
|
32
chain/actors/builtin/init/init.go
Normal file
32
chain/actors/builtin/init/init.go
Normal file
@ -0,0 +1,32 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
v0builtin "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case v0builtin.InitActorCodeID:
|
||||
out := v0State{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
ResolveAddress(address addr.Address) (address.Address, bool, error)
|
||||
MapAddressToNewID(address addr.Address) (address.Address, error)
|
||||
}
|
22
chain/actors/builtin/init/v0.go
Normal file
22
chain/actors/builtin/init/v0.go
Normal file
@ -0,0 +1,22 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
)
|
||||
|
||||
type v0State struct {
|
||||
init.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *v0State) ResolveAddress(address address.Address) (address.Address, bool, error) {
|
||||
return s.State.ResolveAddress(s.store, address)
|
||||
}
|
||||
|
||||
func (s *v0State) MapAddressToNewID(address address.Address) (address.Address, error) {
|
||||
return s.State.MapAddressToNewID(s.store, address)
|
||||
}
|
32
chain/actors/builtin/market/market.go
Normal file
32
chain/actors/builtin/market/market.go
Normal file
@ -0,0 +1,32 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case v0builtin.MarketActorCodeID:
|
||||
out := v0State{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
EscrowTable() (BalanceTable, error)
|
||||
LockedTable() (BalanceTable, error)
|
||||
TotalLocked() (abi.TokenAmount, error)
|
||||
}
|
||||
|
||||
type BalanceTable interface {
|
||||
Get(key address.Address) (abi.TokenAmount, error)
|
||||
}
|
25
chain/actors/builtin/market/v0.go
Normal file
25
chain/actors/builtin/market/v0.go
Normal file
@ -0,0 +1,25 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
type v0State struct {
|
||||
market.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *v0State) TotalLocked() (abi.TokenAmount, error) {
|
||||
fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
|
||||
fml = types.BigAdd(fml, s.TotalClientStorageFee)
|
||||
return fml, nil
|
||||
}
|
||||
|
||||
func (s *v0State) EscrowTable() (BalanceTable, error) {
|
||||
return adt.AsBalanceTable(s.store, s.State.EscrowTable)
|
||||
}
|
||||
|
||||
func (s *v0State) Lockedtable() (BalanceTable, error) {
|
||||
return adt.AsBalanceTable(s.store, s.State.LockedTable)
|
||||
}
|
59
chain/actors/builtin/miner/miner.go
Normal file
59
chain/actors/builtin/miner/miner.go
Normal file
@ -0,0 +1,59 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
v0builtin "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case v0builtin.StorageMinerActorCodeID:
|
||||
out := v0State{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
LoadDeadline(idx uint64) (Deadline, error)
|
||||
ForEachDeadline(cb func(idx uint64, dl Deadline) error) error
|
||||
NumDeadlines() (uint64, error)
|
||||
}
|
||||
|
||||
type Deadline interface {
|
||||
LoadPartition(idx uint64) (Partition, error)
|
||||
ForEachPartition(cb func(idx uint64, part Partition) error) error
|
||||
}
|
||||
|
||||
type Partition interface {
|
||||
AllSectors() (bitfield.BitField, error)
|
||||
FaultySectors() (bitfield.BitField, error)
|
||||
RecoveringSectors() (bitfield.BitField, error)
|
||||
LiveSectors() (bitfield.BitField, error)
|
||||
ActiveSectors() (bitfield.BitField, error)
|
||||
}
|
||||
|
||||
type MinerInfo struct {
|
||||
Owner address.Address // Must be an ID-address.
|
||||
Worker address.Address // Must be an ID-address.
|
||||
NewWorker address.Address // Must be an ID-address.
|
||||
ControlAddresses []address.Address // Must be an ID-addresses.
|
||||
WorkerChangeEpoch abi.ChainEpoch
|
||||
PeerId *peer.ID
|
||||
Multiaddrs []abi.Multiaddrs
|
||||
SealProofType abi.RegisteredSealProof
|
||||
SectorSize abi.SectorSize
|
||||
WindowPoStPartitionSectors uint64
|
||||
}
|
112
chain/actors/builtin/miner/v0.go
Normal file
112
chain/actors/builtin/miner/v0.go
Normal file
@ -0,0 +1,112 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
)
|
||||
|
||||
type v0State struct {
|
||||
miner.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
type v0Deadline struct {
|
||||
miner.Deadline
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
type v0Partition struct {
|
||||
miner.Partition
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *v0State) LoadDeadline(idx uint64) (Deadline, error) {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dl, err := dls.LoadDeadline(s.store, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v0Deadline{*dl, s.store}, nil
|
||||
}
|
||||
|
||||
func (s *v0State) ForEachDeadline(cb func(uint64, Deadline) error) error {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return dls.ForEach(s.store, func(i uint64, dl *miner.Deadline) error {
|
||||
return cb(i, &v0Deadline{*dl, s.store})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *v0State) NumDeadlines() (uint64, error) {
|
||||
return miner.WPoStPeriodDeadlines, nil
|
||||
}
|
||||
|
||||
func (s *v0State) Info() (MinerInfo, error) {
|
||||
info, err := s.State.GetInfo(s.store)
|
||||
|
||||
var pid *peer.ID
|
||||
if peerID, err := peer.IDFromBytes(info.PeerId); err == nil {
|
||||
pid = &peerID
|
||||
}
|
||||
|
||||
mi := MinerInfo{
|
||||
Owner: info.Owner,
|
||||
Worker: info.Worker,
|
||||
ControlAddresses: info.ControlAddresses,
|
||||
|
||||
NewWorker: address.Undef,
|
||||
WorkerChangeEpoch: -1,
|
||||
|
||||
PeerId: pid,
|
||||
Multiaddrs: info.Multiaddrs,
|
||||
SealProofType: info.SealProofType,
|
||||
SectorSize: info.SectorSize,
|
||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||
}
|
||||
|
||||
if info.PendingWorkerKey != nil {
|
||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||
}
|
||||
|
||||
return mi
|
||||
}
|
||||
|
||||
func (d *v0Deadline) LoadPartition(idx uint64) (Partition, error) {
|
||||
p, err := d.Deadline.LoadPartition(d.store, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v0Partition{*p, d.store}, nil
|
||||
}
|
||||
|
||||
func (d *v0Deadline) ForEachPartition(cb func(uint64, Partition) error) error {
|
||||
ps, err := d.Deadline.PartitionsArray(d.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var part miner.Partition
|
||||
return ps.ForEach(&part, func(i int64) error {
|
||||
return cb(uint64(i), &v0Partition{part, d.store})
|
||||
})
|
||||
}
|
||||
|
||||
func (p *v0Partition) AllSectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Sectors, nil
|
||||
}
|
||||
|
||||
func (p *v0Partition) FaultySectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Faults, nil
|
||||
}
|
||||
|
||||
func (p *v0Partition) RecoveringSectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Recoveries, nil
|
||||
}
|
28
chain/actors/builtin/power/power.go
Normal file
28
chain/actors/builtin/power/power.go
Normal file
@ -0,0 +1,28 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case v0builtin.PowerActorCodeID:
|
||||
out := v0State{store: store}
|
||||
err := store.Get(store.Context(), act.Head, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
TotalLocked() (abi.TokenAmount, error)
|
||||
}
|
16
chain/actors/builtin/power/v0.go
Normal file
16
chain/actors/builtin/power/v0.go
Normal file
@ -0,0 +1,16 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
)
|
||||
|
||||
type v0State struct {
|
||||
power.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *v0State) TotalLocked() (abi.TokenAmount, error) {
|
||||
return s.TotalPledgeCollateral, nil
|
||||
}
|
24
chain/actors/version.go
Normal file
24
chain/actors/version.go
Normal file
@ -0,0 +1,24 @@
|
||||
package actors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
)
|
||||
|
||||
type Version int
|
||||
|
||||
const (
|
||||
Version0 = iota
|
||||
Version1
|
||||
)
|
||||
|
||||
// VersionForNetwork resolves the network version into an specs-actors version.
|
||||
func VersionForNetwork(v network.Version) Version {
|
||||
switch v {
|
||||
case network.Version0, network.Version1:
|
||||
return Version0
|
||||
default:
|
||||
panic(fmt.Sprintf("unimplemented network version: %d", v))
|
||||
}
|
||||
}
|
@ -52,8 +52,8 @@ func (mpp *mpoolProvider) GetActorAfter(addr address.Address, ts *types.TipSet)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("computing tipset state for GetActor: %w", err)
|
||||
}
|
||||
|
||||
return &act, mpp.sm.WithStateTree(stcid, mpp.sm.WithActor(addr, stmgr.GetActor(&act)))
|
||||
version := mpp.sm.GetNtwkVersion(context.TODO(), ts.Height())
|
||||
return &act, mpp.sm.WithStateTree(stcid, version, mpp.sm.WithActor(addr, stmgr.GetActor(&act)))
|
||||
}
|
||||
|
||||
func (mpp *mpoolProvider) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
|
@ -4,10 +4,12 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
@ -22,7 +24,7 @@ var log = logging.Logger("statetree")
|
||||
|
||||
// StateTree stores actors state by their ID.
|
||||
type StateTree struct {
|
||||
root *adt.Map
|
||||
root adt.Map
|
||||
Store cbor.IpldStore
|
||||
|
||||
snaps *stateSnaps
|
||||
@ -115,17 +117,18 @@ func (ss *stateSnaps) deleteActor(addr address.Address) {
|
||||
ss.layers[len(ss.layers)-1].actors[addr] = streeOp{Delete: true}
|
||||
}
|
||||
|
||||
func NewStateTree(cst cbor.IpldStore) (*StateTree, error) {
|
||||
func NewStateTree(cst cbor.IpldStore, version network.Version) (*StateTree, error) {
|
||||
|
||||
return &StateTree{
|
||||
root: adt.MakeEmptyMap(adt.WrapStore(context.TODO(), cst)),
|
||||
root: adt.NewMap(adt.WrapStore(context.TODO(), cst), version),
|
||||
Store: cst,
|
||||
snaps: newStateSnaps(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
|
||||
nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), c)
|
||||
func LoadStateTree(cst cbor.IpldStore, c cid.Cid, version network.Version) (*StateTree, error) {
|
||||
// NETUPGRADE: switch map adt type on version upgrade.
|
||||
nd, err := adt.AsMap(adt.WrapStore(context.TODO(), cst), c, version)
|
||||
if err != nil {
|
||||
log.Errorf("loading hamt node %s failed: %s", c, err)
|
||||
return nil, err
|
||||
@ -165,12 +168,12 @@ func (st *StateTree) LookupID(addr address.Address) (address.Address, error) {
|
||||
return address.Undef, xerrors.Errorf("getting init actor: %w", err)
|
||||
}
|
||||
|
||||
var ias init_.State
|
||||
if err := st.Store.Get(context.TODO(), act.Head, &ias); err != nil {
|
||||
ias, err := init.Load(&AdtStore{st.Store}, &act)
|
||||
if err != nil {
|
||||
return address.Undef, xerrors.Errorf("loading init actor state: %w", err)
|
||||
}
|
||||
|
||||
a, found, err := ias.ResolveAddress(&AdtStore{st.Store}, addr)
|
||||
a, found, err := ias.ResolveAddress(addr)
|
||||
if err == nil && !found {
|
||||
err = types.ErrActorNotFound
|
||||
}
|
||||
@ -283,18 +286,18 @@ func (st *StateTree) ClearSnapshot() {
|
||||
func (st *StateTree) RegisterNewAddress(addr address.Address) (address.Address, error) {
|
||||
var out address.Address
|
||||
err := st.MutateActor(builtin.InitActorAddr, func(initact *types.Actor) error {
|
||||
var ias init_.State
|
||||
if err := st.Store.Get(context.TODO(), initact.Head, &ias); err != nil {
|
||||
ias, err := init.Load(&AdtStore{st.Store}, initact)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oaddr, err := ias.MapAddressToNewID(&AdtStore{st.Store}, addr)
|
||||
oaddr, err := ias.MapAddressToNewID(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out = oaddr
|
||||
|
||||
ncid, err := st.Store.Put(context.TODO(), &ias)
|
||||
ncid, err := st.Store.Put(context.TODO(), ias)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -10,146 +10,54 @@ import (
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
type StateTreeCB func(state *state.StateTree) error
|
||||
|
||||
func (sm *StateManager) WithParentStateTsk(tsk types.TipSetKey, cb StateTreeCB) error {
|
||||
func (sm *StateManager) ParentStateTsk(tsk types.TipSetKey) (*state.StateTree, error) {
|
||||
ts, err := sm.cs.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
return sm.ParentState(ts, cb)
|
||||
}
|
||||
|
||||
func (sm *StateManager) ParentState(ts *types.TipSet) (*state.StateTree, error) {
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
state, err := state.LoadStateTree(cst, sm.parentState(ts))
|
||||
version := sm.GetNtwkVersion(context.TODO(), ts.Height()-1)
|
||||
state, err := state.LoadStateTree(cst, sm.parentState(ts), version)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("load state tree: %w", err)
|
||||
return nil, xerrors.Errorf("load state tree: %w", err)
|
||||
}
|
||||
|
||||
return cb(state)
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) WithParentState(ts *types.TipSet, cb StateTreeCB) error {
|
||||
func (sm *StateManager) StateTree(st cid.Cid, ntwkVersion network.Version) (*state.StateTree, error) {
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
state, err := state.LoadStateTree(cst, sm.parentState(ts))
|
||||
state, err := state.LoadStateTree(cst, st, ntwkVersion)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("load state tree: %w", err)
|
||||
return nil, xerrors.Errorf("load state tree: %w", err)
|
||||
}
|
||||
|
||||
return cb(state)
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) WithStateTree(st cid.Cid, cb StateTreeCB) error {
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
state, err := state.LoadStateTree(cst, st)
|
||||
func (sm *StateManager) LoadActor(_ context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
state, err := sm.ParentState(ts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("load state tree: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
return state.GetActor(addr)
|
||||
}
|
||||
|
||||
return cb(state)
|
||||
}
|
||||
|
||||
type ActorCB func(act *types.Actor) error
|
||||
|
||||
func GetActor(out *types.Actor) ActorCB {
|
||||
return func(act *types.Actor) error {
|
||||
*out = *act
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (sm *StateManager) WithActor(addr address.Address, cb ActorCB) StateTreeCB {
|
||||
return func(state *state.StateTree) error {
|
||||
act, err := state.GetActor(addr)
|
||||
func (sm *StateManager) LoadActorTsk(_ context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
state, err := sm.ParentStateTsk(tsk)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get actor: %w", err)
|
||||
}
|
||||
|
||||
return cb(act)
|
||||
}
|
||||
}
|
||||
|
||||
// WithActorState usage:
|
||||
// Option 1: WithActorState(ctx, idAddr, func(store adt.Store, st *ActorStateType) error {...})
|
||||
// Option 2: WithActorState(ctx, idAddr, actorStatePtr)
|
||||
func (sm *StateManager) WithActorState(ctx context.Context, out interface{}) ActorCB {
|
||||
return func(act *types.Actor) error {
|
||||
store := sm.cs.Store(ctx)
|
||||
|
||||
outCallback := reflect.TypeOf(out).Kind() == reflect.Func
|
||||
|
||||
var st reflect.Value
|
||||
if outCallback {
|
||||
st = reflect.New(reflect.TypeOf(out).In(1).Elem())
|
||||
} else {
|
||||
st = reflect.ValueOf(out)
|
||||
}
|
||||
if err := store.Get(ctx, act.Head, st.Interface()); err != nil {
|
||||
return xerrors.Errorf("read actor head: %w", err)
|
||||
}
|
||||
|
||||
if outCallback {
|
||||
out := reflect.ValueOf(out).Call([]reflect.Value{reflect.ValueOf(store), st})
|
||||
if !out[0].IsNil() && out[0].Interface().(error) != nil {
|
||||
return out[0].Interface().(error)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type DeadlinesCB func(store adt.Store, deadlines *miner.Deadlines) error
|
||||
|
||||
func (sm *StateManager) WithDeadlines(cb DeadlinesCB) func(store adt.Store, mas *miner.State) error {
|
||||
return func(store adt.Store, mas *miner.State) error {
|
||||
deadlines, err := mas.LoadDeadlines(store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cb(store, deadlines)
|
||||
}
|
||||
}
|
||||
|
||||
type DeadlineCB func(store adt.Store, idx uint64, deadline *miner.Deadline) error
|
||||
|
||||
func (sm *StateManager) WithDeadline(idx uint64, cb DeadlineCB) DeadlinesCB {
|
||||
return func(store adt.Store, deadlines *miner.Deadlines) error {
|
||||
d, err := deadlines.LoadDeadline(store, idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cb(store, idx, d)
|
||||
}
|
||||
}
|
||||
|
||||
func (sm *StateManager) WithEachDeadline(cb DeadlineCB) DeadlinesCB {
|
||||
return func(store adt.Store, deadlines *miner.Deadlines) error {
|
||||
return deadlines.ForEach(store, func(dlIdx uint64, dl *miner.Deadline) error {
|
||||
return cb(store, dlIdx, dl)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type PartitionCB func(store adt.Store, idx uint64, partition *miner.Partition) error
|
||||
|
||||
func (sm *StateManager) WithEachPartition(cb PartitionCB) DeadlineCB {
|
||||
return func(store adt.Store, idx uint64, deadline *miner.Deadline) error {
|
||||
parts, err := deadline.PartitionsArray(store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var partition miner.Partition
|
||||
return parts.ForEach(&partition, func(i int64) error {
|
||||
p := partition
|
||||
return cb(store, uint64(i), &p)
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
return state.GetActor(addr)
|
||||
}
|
||||
|
@ -7,14 +7,14 @@ import (
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -23,7 +23,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"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/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
@ -201,6 +200,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
||||
|
||||
for i := parentEpoch; i < epoch; i++ {
|
||||
// handle state forks
|
||||
// XXX: The state tre
|
||||
err = sm.handleStateForks(ctx, vmi.StateTree(), i, ts)
|
||||
if err != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err)
|
||||
@ -711,11 +711,14 @@ func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([]
|
||||
}
|
||||
|
||||
func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (api.MarketBalance, error) {
|
||||
var state market.State
|
||||
_, err := sm.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts)
|
||||
st, err := sm.ParentState(ts)
|
||||
if err != nil {
|
||||
return api.MarketBalance{}, err
|
||||
}
|
||||
act, err := st.GetActor(builtin.StorageMarketActorAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, err = sm.LookupID(ctx, addr, ts)
|
||||
if err != nil {
|
||||
@ -1016,19 +1019,17 @@ func GetFilMined(ctx context.Context, st *state.StateTree) (abi.TokenAmount, err
|
||||
}
|
||||
|
||||
func getFilMarketLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
||||
mactor, err := st.GetActor(builtin.StorageMarketActorAddr)
|
||||
act, err := st.GetActor(builtin.StorageMarketActorAddr)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load market actor: %w", err)
|
||||
}
|
||||
|
||||
var mst market.State
|
||||
if err := st.Store.Get(ctx, mactor.Head, &mst); err != nil {
|
||||
mst, err := market.Load(adt.WrapStore(ctx, st.Store), act)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load market state: %w", err)
|
||||
}
|
||||
|
||||
fml := types.BigAdd(mst.TotalClientLockedCollateral, mst.TotalProviderLockedCollateral)
|
||||
fml = types.BigAdd(fml, mst.TotalClientStorageFee)
|
||||
return fml, nil
|
||||
return mst.TotalLocked()
|
||||
}
|
||||
|
||||
func getFilPowerLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
||||
@ -1037,11 +1038,12 @@ func getFilPowerLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmoun
|
||||
return big.Zero(), xerrors.Errorf("failed to load power actor: %w", err)
|
||||
}
|
||||
|
||||
var pst power.State
|
||||
if err := st.Store.Get(ctx, pactor.Head, &pst); err != nil {
|
||||
pst, err := power.Load(adt.WrapStore(ctx, st.Store), act)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to load power state: %w", err)
|
||||
}
|
||||
return pst.TotalPledgeCollateral, nil
|
||||
|
||||
return pst.TotalLocked(), nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetFilLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
||||
|
@ -56,30 +56,6 @@ func GetNetworkName(ctx context.Context, sm *StateManager, st cid.Cid) (dtypes.N
|
||||
return dtypes.NetworkName(state.NetworkName), nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) LoadActorState(ctx context.Context, addr address.Address, out interface{}, ts *types.TipSet) (*types.Actor, error) {
|
||||
var a *types.Actor
|
||||
if err := sm.WithParentState(ts, sm.WithActor(addr, func(act *types.Actor) error {
|
||||
a = act
|
||||
return sm.WithActorState(ctx, out)(act)
|
||||
})); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) LoadActorStateRaw(ctx context.Context, addr address.Address, out interface{}, st cid.Cid) (*types.Actor, error) {
|
||||
var a *types.Actor
|
||||
if err := sm.WithStateTree(st, sm.WithActor(addr, func(act *types.Actor) error {
|
||||
a = act
|
||||
return sm.WithActorState(ctx, out)(act)
|
||||
})); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func GetMinerWorkerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (address.Address, error) {
|
||||
var mas miner.State
|
||||
_, err := sm.LoadActorStateRaw(ctx, maddr, &mas, st)
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
address "github.com/filecoin-project/go-address"
|
||||
miner "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
@ -28,6 +27,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
@ -432,9 +432,10 @@ func (bv *BlockValidator) checkPowerAndGetWorkerKey(ctx context.Context, bh *typ
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
buf := bufbstore.NewBufferedBstore(bv.chain.Blockstore())
|
||||
cst := cbor.NewCborStore(buf)
|
||||
state, err := state.LoadStateTree(cst, st)
|
||||
state, err := state.LoadStateTree(cst, st, bv.stmgr.GetNtwkVersion(ctx, ts.Height()))
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
@ -443,19 +444,12 @@ func (bv *BlockValidator) checkPowerAndGetWorkerKey(ctx context.Context, bh *typ
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
blk, err := bv.chain.Blockstore().Get(act.Head)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
aso := blk.RawData()
|
||||
|
||||
var mst miner.State
|
||||
err = mst.UnmarshalCBOR(bytes.NewReader(aso))
|
||||
mst, err := miner.Load(bv.chain.Store(ctx), act)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
||||
info, err := mst.GetInfo(adt.WrapStore(ctx, cst))
|
||||
info, err := mst.Info()
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
}
|
||||
|
@ -1027,9 +1027,10 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nwVersion := syncer.sm.GetNtwkVersion(ctx, baseTs.Height())
|
||||
|
||||
cst := cbor.NewCborStore(syncer.store.Blockstore())
|
||||
st, err := state.LoadStateTree(cst, stateroot)
|
||||
st, err := state.LoadStateTree(cst, stateroot, nwVersion)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to load base state tree: %w", err)
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ func NewInvoker() *Invoker {
|
||||
}
|
||||
|
||||
// add builtInCode using: register(cid, singleton)
|
||||
// NETUPGRADE: register code IDs for v2, etc.
|
||||
inv.Register(builtin.SystemActorCodeID, system.Actor{}, adt.EmptyValue{})
|
||||
inv.Register(builtin.InitActorCodeID, init_.Actor{}, init_.State{})
|
||||
inv.Register(builtin.RewardActorCodeID, reward.Actor{}, reward.State{})
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
@ -170,7 +171,9 @@ var chainBalanceStateCmd = &cli.Command{
|
||||
|
||||
sm := stmgr.NewStateManager(cs)
|
||||
|
||||
tree, err := state.LoadStateTree(cst, sroot)
|
||||
// NETUPGRADE: FIXME.
|
||||
// Options: (a) encode the version in the chain or (b) pass a flag.
|
||||
tree, err := state.LoadStateTree(cst, sroot, network.Version0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ var genesisVerifyCmd = &cli.Command{
|
||||
|
||||
cst := cbor.NewCborStore(bs)
|
||||
|
||||
stree, err := state.LoadStateTree(cst, ts.ParentState())
|
||||
stree, err := state.LoadStateTree(cst, ts.ParentState(), sm.GetNtwkVersion())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -12,9 +12,11 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
)
|
||||
@ -49,54 +51,41 @@ var provingFaultsCmd = &cli.Command{
|
||||
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
stor := store.ActorStore(ctx, apibstore.NewAPIBlockstore(api))
|
||||
|
||||
maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var mas miner.State
|
||||
{
|
||||
mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rmas, err := api.ChainReadObj(ctx, mact.Head)
|
||||
|
||||
mas, err := miner.Load(stor, mact)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := mas.UnmarshalCBOR(bytes.NewReader(rmas)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Miner: %s\n", color.BlueString("%s", maddr))
|
||||
|
||||
head, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting chain head: %w", err)
|
||||
}
|
||||
deadlines, err := api.StateMinerDeadlines(ctx, maddr, head.Key())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner deadlines: %w", err)
|
||||
}
|
||||
tw := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
|
||||
_, _ = fmt.Fprintln(tw, "deadline\tpartition\tsectors")
|
||||
for dlIdx := range deadlines {
|
||||
partitions, err := api.StateMinerPartitions(ctx, maddr, uint64(dlIdx), types.EmptyTSK)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading partitions for deadline %d: %w", dlIdx, err)
|
||||
}
|
||||
|
||||
for partIdx, partition := range partitions {
|
||||
faulty, err := partition.Faults.All(10000000)
|
||||
err = mas.ForEachDeadline(func(dlIdx uint64, dl miner.Deadline) error {
|
||||
dl.ForEachPartition(func(partIdx uint64, part miner.Partition) error {
|
||||
faults, err := part.Faults()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, num := range faulty {
|
||||
faults.ForEach(func(num uint64) error {
|
||||
_, _ = fmt.Fprintf(tw, "%d\t%d\t%d\n", dlIdx, partIdx, num)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tw.Flush()
|
||||
},
|
||||
@ -132,67 +121,61 @@ var provingInfoCmd = &cli.Command{
|
||||
return xerrors.Errorf("getting chain head: %w", err)
|
||||
}
|
||||
|
||||
mact, err := api.StateGetActor(ctx, maddr, head.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stor := store.ActorStore(ctx, apibstore.NewAPIBlockstore(api))
|
||||
|
||||
mas, err := miner.Load(stor, mact)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cd, err := api.StateMinerProvingDeadline(ctx, maddr, head.Key())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner info: %w", err)
|
||||
}
|
||||
|
||||
deadlines, err := api.StateMinerDeadlines(ctx, maddr, head.Key())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner deadlines: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Miner: %s\n", color.BlueString("%s", maddr))
|
||||
|
||||
var mas miner.State
|
||||
{
|
||||
mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rmas, err := api.ChainReadObj(ctx, mact.Head)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := mas.UnmarshalCBOR(bytes.NewReader(rmas)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
parts := map[uint64][]*miner.Partition{}
|
||||
for dlIdx := range deadlines {
|
||||
part, err := api.StateMinerPartitions(ctx, maddr, uint64(dlIdx), types.EmptyTSK)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner partition: %w", err)
|
||||
}
|
||||
|
||||
parts[uint64(dlIdx)] = part
|
||||
}
|
||||
|
||||
proving := uint64(0)
|
||||
faults := uint64(0)
|
||||
recovering := uint64(0)
|
||||
curDeadlineSectors := uint64(0)
|
||||
|
||||
for _, partitions := range parts {
|
||||
for _, partition := range partitions {
|
||||
sc, err := partition.Sectors.Count()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("count partition sectors: %w", err)
|
||||
if err := mas.ForEachDeadline(func(dlIdx uint64, dl miner.Deadline) error {
|
||||
return dl.ForEachPartition(func(partIdx uint64, part miner.Partition) error {
|
||||
if bf, err := part.LiveSectors(); err != nil {
|
||||
return err
|
||||
} else if count, err := bf.Count(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
proving += count
|
||||
if dlIdx == cd.Index {
|
||||
curDeadlineSectors += count
|
||||
}
|
||||
}
|
||||
proving += sc
|
||||
|
||||
fc, err := partition.Faults.Count()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("count partition faults: %w", err)
|
||||
if bf, err := part.Faults(); err != nil {
|
||||
return err
|
||||
} else if count, err := bf.Count(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
faults += count
|
||||
}
|
||||
faults += fc
|
||||
|
||||
rc, err := partition.Recoveries.Count()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("count partition recoveries: %w", err)
|
||||
}
|
||||
recovering += rc
|
||||
if bf, err := part.Recovering(); err != nil {
|
||||
return err
|
||||
} else if count, err := bf.Count(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
recovering += count
|
||||
}
|
||||
})
|
||||
}); err != nil {
|
||||
return xerrors.Errorf("walking miner deadlines and partitions: %w", err)
|
||||
}
|
||||
|
||||
var faultPerc float64
|
||||
@ -202,28 +185,15 @@ var provingInfoCmd = &cli.Command{
|
||||
|
||||
fmt.Printf("Current Epoch: %d\n", cd.CurrentEpoch)
|
||||
|
||||
fmt.Printf("Proving Period Boundary: %d\n", cd.PeriodStart%miner.WPoStProvingPeriod)
|
||||
fmt.Printf("Proving Period Boundary: %d\n", cd.PeriodStart%cd.WPoStProvingPeriod)
|
||||
fmt.Printf("Proving Period Start: %s\n", epochTime(cd.CurrentEpoch, cd.PeriodStart))
|
||||
fmt.Printf("Next Period Start: %s\n\n", epochTime(cd.CurrentEpoch, cd.PeriodStart+miner.WPoStProvingPeriod))
|
||||
fmt.Printf("Next Period Start: %s\n\n", epochTime(cd.CurrentEpoch, cd.PeriodStart+cd.WPoStProvingPeriod))
|
||||
|
||||
fmt.Printf("Faults: %d (%.2f%%)\n", faults, faultPerc)
|
||||
fmt.Printf("Recovering: %d\n", recovering)
|
||||
|
||||
fmt.Printf("Deadline Index: %d\n", cd.Index)
|
||||
|
||||
if cd.Index < miner.WPoStPeriodDeadlines {
|
||||
curDeadlineSectors := uint64(0)
|
||||
for _, partition := range parts[cd.Index] {
|
||||
sc, err := partition.Sectors.Count()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("counting current deadline sectors: %w", err)
|
||||
}
|
||||
curDeadlineSectors += sc
|
||||
}
|
||||
|
||||
fmt.Printf("Deadline Sectors: %d\n", curDeadlineSectors)
|
||||
}
|
||||
|
||||
fmt.Printf("Deadline Open: %s\n", epochTime(cd.CurrentEpoch, cd.Open))
|
||||
fmt.Printf("Deadline Close: %s\n", epochTime(cd.CurrentEpoch, cd.Close))
|
||||
fmt.Printf("Deadline Challenge: %s\n", epochTime(cd.CurrentEpoch, cd.Challenge))
|
||||
@ -286,6 +256,7 @@ var provingDeadlinesCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
miner.Load
|
||||
rmas, err := api.ChainReadObj(ctx, mact.Head)
|
||||
if err != nil {
|
||||
return err
|
||||
|
4
extern/storage-sealing/checks.go
vendored
4
extern/storage-sealing/checks.go
vendored
@ -4,7 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
saproof "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
v0proof "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -170,7 +170,7 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte,
|
||||
log.Warn("on-chain sealed CID doesn't match!")
|
||||
}
|
||||
|
||||
ok, err := m.verif.VerifySeal(saproof.SealVerifyInfo{
|
||||
ok, err := m.verif.VerifySeal(v0proof.SealVerifyInfo{
|
||||
SectorID: m.minerSector(si.SectorNumber),
|
||||
SealedCID: pci.Info.SealedCID,
|
||||
SealProof: spt,
|
||||
|
4
go.mod
4
go.mod
@ -34,11 +34,11 @@ require (
|
||||
github.com/filecoin-project/go-multistore v0.0.3
|
||||
github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20
|
||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200911004822-964d6c679cfc
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370
|
||||
github.com/filecoin-project/go-statestore v0.1.0
|
||||
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
|
||||
github.com/filecoin-project/specs-actors v0.9.7
|
||||
github.com/filecoin-project/specs-actors v0.9.9-0.20200911231631-727cd8845d30
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796
|
||||
github.com/filecoin-project/test-vectors/schema v0.0.1
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||
|
6
go.sum
6
go.sum
@ -226,6 +226,8 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f h1
|
||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
|
||||
github.com/filecoin-project/go-fil-markets v0.6.0 h1:gfxMweUHo4u+2BZh2Q7/7+cV0/ttikuJfhkkxLRsE2Q=
|
||||
github.com/filecoin-project/go-fil-markets v0.6.0/go.mod h1:LhSFYLkjaoe0vFRKABGYyw1Jz+9jCpF1sPA7yOftLTw=
|
||||
github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM=
|
||||
github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24=
|
||||
github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52 h1:FXtCp0ybqdQL9knb3OGDpkNTaBbPxgkqPeWKotUwkH0=
|
||||
github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4=
|
||||
github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI=
|
||||
@ -238,6 +240,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df h1:m2esXSuGBkuXlRyCsl1a/7/FkFam63o1OzIgzaHtOfI=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200911004822-964d6c679cfc h1:1vr/LoqGq5m5g37Q3sNSAjfwF1uJY0zmiHcvnxY6hik=
|
||||
github.com/filecoin-project/go-state-types v0.0.0-20200911004822-964d6c679cfc/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370 h1:Jbburj7Ih2iaJ/o5Q9A+EAeTabME6YII7FLi9SKUf5c=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||
@ -248,6 +252,8 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/
|
||||
github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4=
|
||||
github.com/filecoin-project/specs-actors v0.9.7 h1:7PAZ8kdqwBdmgf/23FCkQZLCXcVu02XJrkpkhBikiA8=
|
||||
github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU=
|
||||
github.com/filecoin-project/specs-actors v0.9.9-0.20200911231631-727cd8845d30 h1:6Kn6y3TpJbk5BsvhVha+3jr7C3gAAJq0rCnwUYOWRl0=
|
||||
github.com/filecoin-project/specs-actors v0.9.9-0.20200911231631-727cd8845d30/go.mod h1:czlvLQGEX0fjLLfdNHD7xLymy6L3n7aQzRWzsYGf+ys=
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk=
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g=
|
||||
github.com/filecoin-project/test-vectors/schema v0.0.1 h1:5fNF76nl4qolEvcIsjc0kUADlTMVHO73tW4kXXPnsus=
|
||||
|
@ -20,7 +20,6 @@ import (
|
||||
"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/miner"
|
||||
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
@ -33,6 +32,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
@ -112,6 +112,8 @@ func (a *StateAPI) StateMinerInfo(ctx context.Context, actor address.Address, ts
|
||||
return api.MinerInfo{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
|
||||
a.StateManager.LoadActorStateRaw(ctx context.Context, addr address.Address, out interface{}, st cid.Cid)
|
||||
|
||||
mi, err := stmgr.StateMinerInfo(ctx, a.StateManager, ts, actor)
|
||||
if err != nil {
|
||||
return api.MinerInfo{}, err
|
||||
@ -119,17 +121,28 @@ func (a *StateAPI) StateMinerInfo(ctx context.Context, actor address.Address, ts
|
||||
return api.NewApiMinerInfo(mi), nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) ([]*miner.Deadline, error) {
|
||||
func (a *StateAPI) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) ([]miner.Deadline, error) {
|
||||
var out []*miner.Deadline
|
||||
return out, a.StateManager.WithParentStateTsk(tsk,
|
||||
a.StateManager.WithActor(m,
|
||||
a.StateManager.WithActorState(ctx,
|
||||
a.StateManager.WithDeadlines(
|
||||
a.StateManager.WithEachDeadline(
|
||||
func(store adt.Store, idx uint64, deadline *miner.Deadline) error {
|
||||
out = append(out, deadline)
|
||||
state, err := a.StateManager.LoadParentStateTsk(tsk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
act, err := state.GetActor(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mas, err := miner.Load(a.Chain.Store(ctx), act)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var deadlines []miner.Deadline
|
||||
if err := mas.ForEachDeadline(func(_ uint64, dl miner.Deadline) error {
|
||||
deadlines = append(deadlines, dl)
|
||||
return nil
|
||||
})))))
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return deadlines, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]*miner.Partition, error) {
|
||||
@ -302,7 +315,7 @@ func (a *StateAPI) stateForTs(ctx context.Context, ts *types.TipSet) (*state.Sta
|
||||
|
||||
buf := bufbstore.NewBufferedBstore(a.Chain.Blockstore())
|
||||
cst := cbor.NewCborStore(buf)
|
||||
return state.LoadStateTree(cst, st)
|
||||
return state.LoadStateTree(cst, st, a.StateManager.GetNtwkVersion(ctx, ts.Height()))
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
@ -1169,16 +1182,9 @@ func (a *StateAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetK
|
||||
return api.CirculatingSupply{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
}
|
||||
|
||||
st, _, err := a.StateManager.TipSetState(ctx, ts)
|
||||
sTree, err := a.stateForTs(ctx, ts)
|
||||
if err != nil {
|
||||
return api.CirculatingSupply{}, err
|
||||
}
|
||||
|
||||
cst := cbor.NewCborStore(a.Chain.Blockstore())
|
||||
sTree, err := state.LoadStateTree(cst, st)
|
||||
if err != nil {
|
||||
return api.CirculatingSupply{}, err
|
||||
}
|
||||
|
||||
return a.StateManager.GetCirculatingSupplyDetailed(ctx, ts.Height(), sTree)
|
||||
}
|
||||
|
@ -16,13 +16,13 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"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/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
@ -179,14 +179,11 @@ func (s SealingAPIAdapter) StateSectorPreCommitInfo(ctx context.Context, maddr a
|
||||
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: %+v", sectorNumber, err)
|
||||
}
|
||||
|
||||
st, err := s.delegate.ChainReadObj(ctx, act.Head)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: %+v", sectorNumber, err)
|
||||
}
|
||||
stor := store.ActorStore(ctx, apibstore.NewAPIBlockstore(s.delegate))
|
||||
|
||||
var state miner.State
|
||||
if err := state.UnmarshalCBOR(bytes.NewReader(st)); err != nil {
|
||||
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: unmarshaling miner state: %+v", sectorNumber, err)
|
||||
state, err := miner.Load(stor, act)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: loading miner state: %+v", sectorNumber, err)
|
||||
}
|
||||
stor := store.ActorStore(ctx, apibstore.NewAPIBlockstore(s.delegate))
|
||||
precommits, err := adt.AsMap(stor, state.PreCommittedSectors)
|
||||
|
@ -6,28 +6,32 @@ import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
v0miner "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
v0proof "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var errNoPartitions = errors.New("no partitions")
|
||||
|
||||
func (s *WindowPoStScheduler) failPost(deadline *miner.DeadlineInfo) {
|
||||
func (s *WindowPoStScheduler) failPost(deadline *dline.Info) {
|
||||
log.Errorf("TODO")
|
||||
/*s.failLk.Lock()
|
||||
if eps > s.failed {
|
||||
@ -36,7 +40,7 @@ func (s *WindowPoStScheduler) failPost(deadline *miner.DeadlineInfo) {
|
||||
s.failLk.Unlock()*/
|
||||
}
|
||||
|
||||
func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *miner.DeadlineInfo, ts *types.TipSet) {
|
||||
func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *dline.Info, ts *types.TipSet) {
|
||||
ctx, abort := context.WithCancel(ctx)
|
||||
|
||||
s.abort = abort
|
||||
@ -111,18 +115,26 @@ func (s *WindowPoStScheduler) checkSectors(ctx context.Context, check bitfield.B
|
||||
return sbf, nil
|
||||
}
|
||||
|
||||
func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uint64, partitions []*miner.Partition) error {
|
||||
func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uint64, partitions []miner.Partition) error {
|
||||
ctx, span := trace.StartSpan(ctx, "storage.checkNextRecoveries")
|
||||
defer span.End()
|
||||
|
||||
params := &miner.DeclareFaultsRecoveredParams{
|
||||
Recoveries: []miner.RecoveryDeclaration{},
|
||||
params := &v0miner.DeclareFaultsRecoveredParams{
|
||||
Recoveries: []v0miner.RecoveryDeclaration{},
|
||||
}
|
||||
|
||||
faulty := uint64(0)
|
||||
|
||||
for partIdx, partition := range partitions {
|
||||
unrecovered, err := bitfield.SubtractBitField(partition.Faults, partition.Recoveries)
|
||||
faults, err := partition.FaultySectors()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting faults: %w", err)
|
||||
}
|
||||
recovering, err := partition.RecoveringSectors()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting recovering: %w", err)
|
||||
}
|
||||
unrecovered, err := bitfield.SubtractBitField(faults, recovering)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("subtracting recovered set from fault set: %w", err)
|
||||
}
|
||||
@ -153,7 +165,7 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uin
|
||||
continue
|
||||
}
|
||||
|
||||
params.Recoveries = append(params.Recoveries, miner.RecoveryDeclaration{
|
||||
params.Recoveries = append(params.Recoveries, v0miner.RecoveryDeclaration{
|
||||
Deadline: dlIdx,
|
||||
Partition: uint64(partIdx),
|
||||
Sectors: recovered,
|
||||
@ -202,17 +214,17 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64, partitions []*miner.Partition) error {
|
||||
func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64, partitions []miner.Partition) error {
|
||||
ctx, span := trace.StartSpan(ctx, "storage.checkNextFaults")
|
||||
defer span.End()
|
||||
|
||||
params := &miner.DeclareFaultsParams{
|
||||
Faults: []miner.FaultDeclaration{},
|
||||
params := &v0miner.DeclareFaultsParams{
|
||||
Faults: []v0miner.FaultDeclaration{},
|
||||
}
|
||||
|
||||
bad := uint64(0)
|
||||
|
||||
for partIdx, partition := range partitions {
|
||||
for _, partition := range partitions {
|
||||
toCheck, err := partition.ActiveSectors()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting active sectors: %w", err)
|
||||
@ -239,7 +251,7 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64,
|
||||
|
||||
bad += c
|
||||
|
||||
params.Faults = append(params.Faults, miner.FaultDeclaration{
|
||||
params.Faults = append(params.Faults, v0miner.FaultDeclaration{
|
||||
Deadline: dlIdx,
|
||||
Partition: uint64(partIdx),
|
||||
Sectors: faulty,
|
||||
@ -286,20 +298,40 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo, ts *types.TipSet) (*miner.SubmitWindowedPoStParams, error) {
|
||||
func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *types.TipSet) (*v0miner.SubmitWindowedPoStParams, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "storage.runPost")
|
||||
defer span.End()
|
||||
|
||||
stor := store.ActorStore(ctx, apibstore.NewAPIBlockstore(s.api))
|
||||
act, err := s.api.StateGetActor(context.TODO(), s.actor, ts.Key())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("resolving actor: %w", err)
|
||||
}
|
||||
|
||||
mas, err := miner.Load(stor, act)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting miner state: %w", err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
// TODO: extract from runPost, run on fault cutoff boundaries
|
||||
|
||||
// check faults / recoveries for the *next* deadline. It's already too
|
||||
// late to declare them for this deadline
|
||||
declDeadline := (di.Index + 2) % miner.WPoStPeriodDeadlines
|
||||
declDeadline := (di.Index + 2) % di.WPoStPeriodDeadlines
|
||||
|
||||
partitions, err := s.api.StateMinerPartitions(context.TODO(), s.actor, declDeadline, ts.Key())
|
||||
dl, err := mas.LoadDeadline(declDeadline)
|
||||
if err != nil {
|
||||
log.Errorf("getting partitions: %v", err)
|
||||
log.Errorf("loading deadline: %v", err)
|
||||
return
|
||||
}
|
||||
var partitions []miner.Partition
|
||||
err = dl.ForEachPartition(func(_ uint64, part miner.Partition) error {
|
||||
partitions = append(partitions, part)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("loading partitions: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -324,18 +356,27 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo
|
||||
return nil, xerrors.Errorf("failed to get chain randomness for windowPost (ts=%d; deadline=%d): %w", ts.Height(), di, err)
|
||||
}
|
||||
|
||||
partitions, err := s.api.StateMinerPartitions(ctx, s.actor, di.Index, ts.Key())
|
||||
dl, err := mas.LoadDeadline(di.Index)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting partitions: %w", err)
|
||||
return nil, xerrors.Errorf("loading deadline: %w", err)
|
||||
}
|
||||
|
||||
params := &miner.SubmitWindowedPoStParams{
|
||||
var partitions []miner.Partitions
|
||||
err = dl.ForEachPartition(func(_ uint64, part miner.Partition) error {
|
||||
partitions = apppend(partitions, part)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading partitions: %w", err)
|
||||
}
|
||||
|
||||
params := &v0miner.SubmitWindowedPoStParams{
|
||||
Deadline: di.Index,
|
||||
Partitions: make([]miner.PoStPartition, 0, len(partitions)),
|
||||
Partitions: make([]v0miner.PoStPartition, 0, len(partitions)),
|
||||
Proofs: nil,
|
||||
}
|
||||
|
||||
var sinfos []proof.SectorInfo
|
||||
var sinfos []v0proof.SectorInfo
|
||||
sidToPart := map[abi.SectorNumber]uint64{}
|
||||
skipCount := uint64(0)
|
||||
|
||||
@ -382,7 +423,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo
|
||||
sidToPart[si.SectorNumber] = uint64(partIdx)
|
||||
}
|
||||
|
||||
params.Partitions = append(params.Partitions, miner.PoStPartition{
|
||||
params.Partitions = append(params.Partitions, v0miner.PoStPartition{
|
||||
Index: uint64(partIdx),
|
||||
Skipped: skipped,
|
||||
})
|
||||
@ -436,7 +477,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (s *WindowPoStScheduler) sectorsForProof(ctx context.Context, goodSectors, allSectors bitfield.BitField, ts *types.TipSet) ([]proof.SectorInfo, error) {
|
||||
func (s *WindowPoStScheduler) sectorsForProof(ctx context.Context, goodSectors, allSectors bitfield.BitField, ts *types.TipSet) ([]v0proof.SectorInfo, error) {
|
||||
sset, err := s.api.StateMinerSectors(ctx, s.actor, &goodSectors, false, ts.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -446,22 +487,22 @@ func (s *WindowPoStScheduler) sectorsForProof(ctx context.Context, goodSectors,
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
substitute := proof.SectorInfo{
|
||||
substitute := v0proof.SectorInfo{
|
||||
SectorNumber: sset[0].ID,
|
||||
SealedCID: sset[0].Info.SealedCID,
|
||||
SealProof: sset[0].Info.SealProof,
|
||||
}
|
||||
|
||||
sectorByID := make(map[uint64]proof.SectorInfo, len(sset))
|
||||
sectorByID := make(map[uint64]v0proof.SectorInfo, len(sset))
|
||||
for _, sector := range sset {
|
||||
sectorByID[uint64(sector.ID)] = proof.SectorInfo{
|
||||
sectorByID[uint64(sector.ID)] = v0proof.SectorInfo{
|
||||
SectorNumber: sector.ID,
|
||||
SealedCID: sector.Info.SealedCID,
|
||||
SealProof: sector.Info.SealProof,
|
||||
}
|
||||
}
|
||||
|
||||
proofSectors := make([]proof.SectorInfo, 0, len(sset))
|
||||
proofSectors := make([]v0proof.SectorInfo, 0, len(sset))
|
||||
if err := allSectors.ForEach(func(sectorNo uint64) error {
|
||||
if info, found := sectorByID[sectorNo]; found {
|
||||
proofSectors = append(proofSectors, info)
|
||||
@ -476,7 +517,7 @@ func (s *WindowPoStScheduler) sectorsForProof(ctx context.Context, goodSectors,
|
||||
return proofSectors, nil
|
||||
}
|
||||
|
||||
func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.SubmitWindowedPoStParams) error {
|
||||
func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *v0miner.SubmitWindowedPoStParams) error {
|
||||
ctx, span := trace.StartSpan(ctx, "storage.commitPost")
|
||||
defer span.End()
|
||||
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
@ -37,7 +37,7 @@ type WindowPoStScheduler struct {
|
||||
cur *types.TipSet
|
||||
|
||||
// if a post is in progress, this indicates for which ElectionPeriodStart
|
||||
activeDeadline *miner.DeadlineInfo
|
||||
activeDeadline *dline.Info
|
||||
abort context.CancelFunc
|
||||
|
||||
//failed abi.ChainEpoch // eps
|
||||
@ -68,7 +68,7 @@ func NewWindowedPoStScheduler(api storageMinerApi, fc config.MinerFeeConfig, sb
|
||||
}, nil
|
||||
}
|
||||
|
||||
func deadlineEquals(a, b *miner.DeadlineInfo) bool {
|
||||
func deadlineEquals(a, b *dline.Info) bool {
|
||||
if a == nil || b == nil {
|
||||
return b == a
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user