2019-08-20 16:48:33 +00:00
package full
import (
2019-10-22 19:29:05 +00:00
"bytes"
2019-08-20 16:48:33 +00:00
"context"
2020-07-14 12:32:17 +00:00
"errors"
2020-01-30 01:23:16 +00:00
"fmt"
2020-09-17 01:56:02 +00:00
"github.com/filecoin-project/go-state-types/network"
2019-10-22 19:29:05 +00:00
"strconv"
2019-09-03 04:36:07 +00:00
2020-09-10 06:30:47 +00:00
"github.com/filecoin-project/go-state-types/dline"
2019-09-19 20:25:18 +00:00
cid "github.com/ipfs/go-cid"
2020-02-04 22:19:05 +00:00
cbor "github.com/ipfs/go-ipld-cbor"
2019-10-22 19:29:05 +00:00
cbg "github.com/whyrusleeping/cbor-gen"
2019-09-16 20:11:17 +00:00
"go.uber.org/fx"
"golang.org/x/xerrors"
2019-12-19 20:13:17 +00:00
"github.com/filecoin-project/go-address"
2020-07-14 12:32:17 +00:00
"github.com/filecoin-project/go-bitfield"
2020-09-07 03:49:10 +00:00
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
2020-08-17 13:26:18 +00:00
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
2020-06-26 13:49:39 +00:00
"github.com/filecoin-project/specs-actors/actors/builtin"
2020-09-15 23:47:58 +00:00
v0miner "github.com/filecoin-project/specs-actors/actors/builtin/miner"
2020-07-06 20:47:39 +00:00
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
2020-07-14 12:32:17 +00:00
"github.com/filecoin-project/specs-actors/actors/util/adt"
2020-09-15 23:47:58 +00:00
"github.com/filecoin-project/specs-actors/actors/util/smoothing"
2020-06-26 13:49:39 +00:00
2019-10-18 04:47:41 +00:00
"github.com/filecoin-project/lotus/api"
2020-09-15 11:04:45 +00:00
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
2020-09-15 21:44:03 +00:00
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
2020-09-15 23:47:58 +00:00
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
2020-04-30 22:11:14 +00:00
"github.com/filecoin-project/lotus/chain/beacon"
2019-10-18 04:47:41 +00:00
"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/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/lib/bufbstore"
2020-04-13 21:05:34 +00:00
"github.com/filecoin-project/lotus/node/modules/dtypes"
2020-09-15 23:47:58 +00:00
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
2019-08-20 16:48:33 +00:00
)
2020-07-14 12:32:17 +00:00
var errBreakForeach = errors . New ( "break" )
2019-08-20 16:48:33 +00:00
type StateAPI struct {
fx . In
2019-09-06 06:26:02 +00:00
// TODO: the wallet here is only needed because we have the MinerCreateBlock
// API attached to the state API. It probably should live somewhere better
Wallet * wallet . Wallet
2020-04-17 23:36:54 +00:00
ProofVerifier ffiwrapper . Verifier
StateManager * stmgr . StateManager
Chain * store . ChainStore
2020-09-08 20:28:06 +00:00
Beacon beacon . Schedule
2019-08-20 16:48:33 +00:00
}
2020-03-31 23:13:37 +00:00
func ( a * StateAPI ) StateNetworkName ( ctx context . Context ) ( dtypes . NetworkName , error ) {
return stmgr . GetNetworkName ( ctx , a . StateManager , a . Chain . GetHeaviestTipSet ( ) . ParentState ( ) )
}
2020-09-15 11:04:45 +00:00
func ( a * StateAPI ) StateMinerSectors ( ctx context . Context , addr address . Address , filter * bitfield . BitField , filterOut bool , tsk types . TipSetKey ) ( [ ] * miner . ChainSectorInfo , error ) {
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2020-04-21 17:22:53 +00:00
return stmgr . GetMinerSectorSet ( ctx , a . StateManager , ts , addr , filter , filterOut )
2019-08-21 16:31:14 +00:00
}
2019-09-03 04:36:07 +00:00
2020-09-15 11:04:45 +00:00
func ( a * StateAPI ) StateMinerActiveSectors ( ctx context . Context , maddr address . Address , tsk types . TipSetKey ) ( [ ] * miner . ChainSectorInfo , error ) { // TODO: only used in cli
2020-09-15 13:29:25 +00:00
act , err := a . StateManager . LoadActorTsk ( ctx , maddr , tsk )
2020-07-17 14:21:00 +00:00
if err != nil {
2020-09-15 13:29:25 +00:00
return nil , xerrors . Errorf ( "failed to load miner actor: %w" , err )
2020-07-17 14:21:00 +00:00
}
2020-09-15 13:29:25 +00:00
mas , err := miner . Load ( a . StateManager . ChainStore ( ) . Store ( ctx ) , act )
if err != nil {
return nil , xerrors . Errorf ( "failed to load miner actor state: %w" , err )
}
2020-04-15 20:40:46 +00:00
2020-09-15 13:29:25 +00:00
activeSectors , err := miner . AllPartSectors ( mas , miner . Partition . ActiveSectors )
2020-02-11 23:29:45 +00:00
if err != nil {
2020-09-15 13:29:25 +00:00
return nil , xerrors . Errorf ( "merge partition active sets: %w" , err )
2020-02-11 23:29:45 +00:00
}
2020-06-09 01:03:44 +00:00
2020-09-15 13:29:25 +00:00
return mas . LoadSectorsFromSet ( & activeSectors , false )
}
2020-09-12 03:07:52 +00:00
2020-09-15 13:29:25 +00:00
func ( a * StateAPI ) StateMinerInfo ( ctx context . Context , actor address . Address , tsk types . TipSetKey ) ( miner . MinerInfo , error ) {
act , err := a . StateManager . LoadActorTsk ( ctx , actor , tsk )
2020-06-09 01:03:44 +00:00
if err != nil {
2020-09-15 13:29:25 +00:00
return miner . MinerInfo { } , xerrors . Errorf ( "failed to load miner actor: %w" , err )
2020-06-09 01:03:44 +00:00
}
2020-09-15 13:29:25 +00:00
mas , err := miner . Load ( a . StateManager . ChainStore ( ) . Store ( ctx ) , act )
if err != nil {
return miner . MinerInfo { } , xerrors . Errorf ( "failed to load miner actor state: %w" , err )
}
return mas . Info ( )
2019-10-16 07:07:16 +00:00
}
2020-09-12 03:07:52 +00:00
func ( a * StateAPI ) StateMinerDeadlines ( ctx context . Context , m address . Address , tsk types . TipSetKey ) ( [ ] miner . Deadline , error ) {
2020-09-15 13:29:25 +00:00
act , err := a . StateManager . LoadActorTsk ( ctx , m , tsk )
2020-09-12 03:07:52 +00:00
if err != nil {
2020-09-15 13:29:25 +00:00
return nil , xerrors . Errorf ( "failed to load miner actor: %w" , err )
2020-09-12 03:07:52 +00:00
}
2020-09-15 13:29:25 +00:00
mas , err := miner . Load ( a . StateManager . ChainStore ( ) . Store ( ctx ) , act )
2020-09-12 03:07:52 +00:00
if err != nil {
2020-09-15 13:29:25 +00:00
return nil , xerrors . Errorf ( "failed to load miner actor state: %w" , err )
2020-09-12 03:07:52 +00:00
}
2020-09-15 13:29:25 +00:00
deadlines , err := mas . NumDeadlines ( )
2020-09-12 03:07:52 +00:00
if err != nil {
2020-09-15 13:29:25 +00:00
return nil , xerrors . Errorf ( "getting deadline count: %w" , err )
2020-09-12 03:07:52 +00:00
}
2020-09-15 13:29:25 +00:00
out := make ( [ ] miner . Deadline , deadlines )
if err := mas . ForEachDeadline ( func ( i uint64 , dl miner . Deadline ) error {
out [ i ] = dl
2020-09-12 03:07:52 +00:00
return nil
} ) ; err != nil {
2020-09-15 13:29:25 +00:00
return nil , err
2020-09-12 03:07:52 +00:00
}
2020-09-15 13:29:25 +00:00
return out , nil
2020-07-14 17:10:31 +00:00
}
func ( a * StateAPI ) StateMinerPartitions ( ctx context . Context , m address . Address , dlIdx uint64 , tsk types . TipSetKey ) ( [ ] * miner . Partition , error ) {
2020-09-15 13:29:25 +00:00
act , err := a . StateManager . LoadActorTsk ( ctx , m , tsk )
if err != nil {
return nil , xerrors . Errorf ( "failed to load miner actor: %w" , err )
}
mas , err := miner . Load ( a . StateManager . ChainStore ( ) . Store ( ctx ) , act )
if err != nil {
return nil , xerrors . Errorf ( "failed to load miner actor state: %w" , err )
}
dl , err := mas . LoadDeadline ( dlIdx )
if err != nil {
return nil , xerrors . Errorf ( "failed to load the deadline: %w" , err )
}
2020-07-14 17:10:31 +00:00
var out [ ] * miner . Partition
2020-09-15 13:29:25 +00:00
err = dl . ForEachPartition ( func ( _ uint64 , part miner . Partition ) error {
p := part
out = append ( out , & p )
return nil
} )
return out , err
2020-04-15 20:22:58 +00:00
}
2020-09-10 06:30:47 +00:00
func ( a * StateAPI ) StateMinerProvingDeadline ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( * dline . Info , error ) {
2020-09-15 13:29:25 +00:00
ts , err := a . StateManager . ChainStore ( ) . GetTipSetFromKey ( tsk )
2020-04-24 17:12:30 +00:00
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2020-09-15 13:29:25 +00:00
act , err := a . StateManager . LoadActor ( ctx , addr , ts )
2020-04-24 17:12:30 +00:00
if err != nil {
2020-09-15 13:29:25 +00:00
return nil , xerrors . Errorf ( "failed to load miner actor: %w" , err )
}
mas , err := miner . Load ( a . StateManager . ChainStore ( ) . Store ( ctx ) , act )
if err != nil {
return nil , xerrors . Errorf ( "failed to load miner actor state: %w" , err )
2020-04-24 17:12:30 +00:00
}
2020-07-15 09:06:14 +00:00
return mas . DeadlineInfo ( ts . Height ( ) ) . NextNotElapsed ( ) , nil
2020-04-24 17:12:30 +00:00
}
2020-09-07 03:49:10 +00:00
func ( a * StateAPI ) StateMinerFaults ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( bitfield . BitField , error ) {
2020-09-15 13:29:25 +00:00
act , err := a . StateManager . LoadActorTsk ( ctx , addr , tsk )
2020-02-11 23:29:45 +00:00
if err != nil {
2020-09-15 13:29:25 +00:00
return bitfield . BitField { } , xerrors . Errorf ( "failed to load miner actor: %w" , err )
2020-02-11 23:29:45 +00:00
}
2020-07-14 11:45:45 +00:00
2020-09-15 13:29:25 +00:00
mas , err := miner . Load ( a . StateManager . ChainStore ( ) . Store ( ctx ) , act )
if err != nil {
return bitfield . BitField { } , xerrors . Errorf ( "failed to load miner actor state: %w" , err )
}
return miner . AllPartSectors ( mas , miner . Partition . FaultySectors )
2020-01-30 00:50:58 +00:00
}
2020-05-21 20:28:59 +00:00
func ( a * StateAPI ) StateAllMinerFaults ( ctx context . Context , lookback abi . ChainEpoch , endTsk types . TipSetKey ) ( [ ] * api . Fault , error ) {
2020-07-14 11:45:45 +00:00
return nil , xerrors . Errorf ( "fixme" )
/ * endTs , err := a . Chain . GetTipSetFromKey ( endTsk )
2020-05-21 20:28:59 +00:00
if err != nil {
return nil , xerrors . Errorf ( "loading end tipset %s: %w" , endTsk , err )
}
cutoff := endTs . Height ( ) - lookback
miners , err := stmgr . ListMinerActors ( ctx , a . StateManager , endTs )
if err != nil {
return nil , xerrors . Errorf ( "loading miners: %w" , err )
}
var allFaults [ ] * api . Fault
for _ , m := range miners {
var mas miner . State
_ , err := a . StateManager . LoadActorState ( ctx , m , & mas , endTs )
if err != nil {
return nil , xerrors . Errorf ( "failed to load miner actor state %s: %w" , m , err )
}
2020-08-05 07:37:28 +00:00
err = mas . ForEachFaultEpoch ( a . Chain . Store ( ctx ) , func ( faultStart abi . ChainEpoch , faults abi . BitField ) error {
2020-05-21 20:28:59 +00:00
if faultStart >= cutoff {
allFaults = append ( allFaults , & api . Fault {
Miner : m ,
Epoch : faultStart ,
} )
return nil
}
return nil
} )
if err != nil {
return nil , xerrors . Errorf ( "failure when iterating over miner states: %w" , err )
}
}
2020-07-14 11:45:45 +00:00
return allFaults , nil * /
2020-05-21 20:28:59 +00:00
}
2020-09-07 03:49:10 +00:00
func ( a * StateAPI ) StateMinerRecoveries ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( bitfield . BitField , error ) {
2020-09-15 13:29:25 +00:00
act , err := a . StateManager . LoadActorTsk ( ctx , addr , tsk )
2020-05-16 21:50:50 +00:00
if err != nil {
2020-09-15 13:29:25 +00:00
return bitfield . BitField { } , xerrors . Errorf ( "failed to load miner actor: %w" , err )
2020-05-16 21:50:50 +00:00
}
2020-07-14 11:45:45 +00:00
2020-09-15 13:29:25 +00:00
mas , err := miner . Load ( a . StateManager . ChainStore ( ) . Store ( ctx ) , act )
if err != nil {
return bitfield . BitField { } , xerrors . Errorf ( "failed to load miner actor state: %w" , err )
}
return miner . AllPartSectors ( mas , miner . Partition . RecoveringSectors )
2020-05-16 21:50:50 +00:00
}
2020-04-15 20:40:46 +00:00
func ( a * StateAPI ) StateMinerPower ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( * api . MinerPower , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2020-09-16 05:47:24 +00:00
m , net , hmp , err := stmgr . GetPower ( ctx , a . StateManager , ts , addr )
2020-04-15 20:40:46 +00:00
if err != nil {
return nil , err
}
return & api . MinerPower {
MinerPower : m ,
TotalPower : net ,
2020-09-16 05:47:24 +00:00
HasMinPower : hmp ,
2020-04-15 20:40:46 +00:00
} , nil
}
2020-03-03 23:32:17 +00:00
func ( a * StateAPI ) StateCall ( ctx context . Context , msg * types . Message , tsk types . TipSetKey ) ( * api . InvocResult , error ) {
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2019-09-09 20:03:10 +00:00
return a . StateManager . Call ( ctx , msg , ts )
2019-09-06 06:26:02 +00:00
}
2020-03-03 23:32:17 +00:00
func ( a * StateAPI ) StateReplay ( ctx context . Context , tsk types . TipSetKey , mc cid . Cid ) ( * api . InvocResult , error ) {
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2019-09-19 20:25:18 +00:00
m , r , err := a . StateManager . Replay ( ctx , ts , mc )
if err != nil {
return nil , err
}
var errstr string
if r . ActorErr != nil {
errstr = r . ActorErr . Error ( )
}
2020-03-03 23:32:17 +00:00
return & api . InvocResult {
2020-06-11 00:47:28 +00:00
Msg : m ,
MsgRct : & r . MessageReceipt ,
ExecutionTrace : r . ExecutionTrace ,
Error : errstr ,
Duration : r . Duration ,
2019-09-19 20:25:18 +00:00
} , nil
}
2019-10-10 11:13:26 +00:00
func ( a * StateAPI ) stateForTs ( ctx context . Context , ts * types . TipSet ) ( * state . StateTree , error ) {
2019-09-06 06:26:02 +00:00
if ts == nil {
ts = a . Chain . GetHeaviestTipSet ( )
}
2019-10-10 11:13:26 +00:00
st , _ , err := a . StateManager . TipSetState ( ctx , ts )
2019-09-06 06:26:02 +00:00
if err != nil {
return nil , err
}
buf := bufbstore . NewBufferedBstore ( a . Chain . Blockstore ( ) )
2020-02-04 22:19:05 +00:00
cst := cbor . NewCborStore ( buf )
2020-09-14 22:43:12 +00:00
return state . LoadStateTree ( cst , st )
2019-09-06 06:26:02 +00:00
}
2020-02-11 23:29:45 +00:00
func ( a * StateAPI ) StateGetActor ( ctx context . Context , actor address . Address , tsk types . TipSetKey ) ( * types . Actor , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2019-10-10 11:13:26 +00:00
state , err := a . stateForTs ( ctx , ts )
2019-09-06 06:26:02 +00:00
if err != nil {
2019-12-07 16:24:42 +00:00
return nil , xerrors . Errorf ( "computing tipset state failed: %w" , err )
2019-09-06 06:26:02 +00:00
}
return state . GetActor ( actor )
}
2020-02-11 23:29:45 +00:00
func ( a * StateAPI ) StateLookupID ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( address . Address , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return address . Undef , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2019-11-15 16:39:43 +00:00
state , err := a . stateForTs ( ctx , ts )
if err != nil {
return address . Undef , err
}
return state . LookupID ( addr )
}
2020-04-16 20:38:42 +00:00
func ( a * StateAPI ) StateAccountKey ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( address . Address , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return address . Undef , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
return a . StateManager . ResolveToKeyAddress ( ctx , addr , ts )
}
2020-06-17 05:10:29 +00:00
func ( a * StateAPI ) StateReadState ( ctx context . Context , actor address . Address , tsk types . TipSetKey ) ( * api . ActorState , error ) {
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2019-10-10 11:13:26 +00:00
state , err := a . stateForTs ( ctx , ts )
2019-09-06 06:26:02 +00:00
if err != nil {
2020-08-07 14:07:34 +00:00
return nil , xerrors . Errorf ( "getting state for tipset: %w" , err )
2019-09-06 06:26:02 +00:00
}
2020-06-17 05:10:29 +00:00
act , err := state . GetActor ( actor )
if err != nil {
2020-08-07 14:07:34 +00:00
return nil , xerrors . Errorf ( "getting actor: %w" , err )
2020-06-17 05:10:29 +00:00
}
2020-02-04 22:19:05 +00:00
blk , err := state . Store . ( * cbor . BasicIpldStore ) . Blocks . Get ( act . Head )
2019-09-06 06:26:02 +00:00
if err != nil {
2020-08-07 14:07:34 +00:00
return nil , xerrors . Errorf ( "getting actor head: %w" , err )
2019-09-06 06:26:02 +00:00
}
oif , err := vm . DumpActorState ( act . Code , blk . RawData ( ) )
if err != nil {
2020-08-07 14:07:34 +00:00
return nil , xerrors . Errorf ( "dumping actor state (a:%s): %w" , actor , err )
2019-09-06 06:26:02 +00:00
}
return & api . ActorState {
Balance : act . Balance ,
State : oif ,
} , nil
}
2020-04-02 01:10:28 +00:00
// This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner
2020-04-17 23:36:54 +00:00
func ( a * StateAPI ) MinerGetBaseInfo ( ctx context . Context , maddr address . Address , epoch abi . ChainEpoch , tsk types . TipSetKey ) ( * api . MiningBaseInfo , error ) {
2020-04-30 22:11:14 +00:00
return stmgr . MinerGetBaseInfo ( ctx , a . StateManager , a . Beacon , tsk , epoch , maddr , a . ProofVerifier )
2020-04-02 01:10:28 +00:00
}
2020-04-09 00:24:10 +00:00
func ( a * StateAPI ) MinerCreateBlock ( ctx context . Context , bt * api . BlockTemplate ) ( * types . BlockMsg , error ) {
fblk , err := gen . MinerCreateBlock ( ctx , a . StateManager , a . Wallet , bt )
2019-09-06 06:26:02 +00:00
if err != nil {
return nil , err
}
2019-09-18 02:50:03 +00:00
var out types . BlockMsg
2019-09-06 06:26:02 +00:00
out . Header = fblk . Header
for _ , msg := range fblk . BlsMessages {
out . BlsMessages = append ( out . BlsMessages , msg . Cid ( ) )
}
for _ , msg := range fblk . SecpkMessages {
out . SecpkMessages = append ( out . SecpkMessages , msg . Cid ( ) )
}
return & out , nil
}
2019-10-08 05:51:34 +00:00
2020-06-03 21:42:06 +00:00
func ( a * StateAPI ) StateWaitMsg ( ctx context . Context , msg cid . Cid , confidence uint64 ) ( * api . MsgLookup , error ) {
2020-08-10 12:55:27 +00:00
ts , recpt , found , err := a . StateManager . WaitForMessage ( ctx , msg , confidence )
2019-10-08 05:51:34 +00:00
if err != nil {
return nil , err
}
2020-07-03 16:57:58 +00:00
var returndec interface { }
if recpt . ExitCode == 0 && len ( recpt . Return ) > 0 {
cmsg , err := a . Chain . GetCMessage ( msg )
if err != nil {
return nil , xerrors . Errorf ( "failed to load message after successful receipt search: %w" , err )
}
vmsg := cmsg . VMMessage ( )
t , err := stmgr . GetReturnType ( ctx , a . StateManager , vmsg . To , vmsg . Method , ts )
if err != nil {
return nil , xerrors . Errorf ( "failed to get return type: %w" , err )
}
if err := t . UnmarshalCBOR ( bytes . NewReader ( recpt . Return ) ) ; err != nil {
return nil , err
}
returndec = t
}
2020-03-18 23:06:53 +00:00
return & api . MsgLookup {
2020-08-10 12:55:27 +00:00
Message : found ,
2020-07-03 16:57:58 +00:00
Receipt : * recpt ,
ReturnDec : returndec ,
2020-07-12 03:54:25 +00:00
TipSet : ts . Key ( ) ,
Height : ts . Height ( ) ,
2019-10-08 05:51:34 +00:00
} , nil
}
2019-10-12 06:45:48 +00:00
2020-03-18 23:06:53 +00:00
func ( a * StateAPI ) StateSearchMsg ( ctx context . Context , msg cid . Cid ) ( * api . MsgLookup , error ) {
2020-08-10 12:55:27 +00:00
ts , recpt , found , err := a . StateManager . SearchForMessage ( ctx , msg )
2020-03-18 23:06:53 +00:00
if err != nil {
return nil , err
}
if ts != nil {
return & api . MsgLookup {
2020-08-10 12:55:27 +00:00
Message : found ,
2020-03-18 23:06:53 +00:00
Receipt : * recpt ,
2020-07-12 03:54:25 +00:00
TipSet : ts . Key ( ) ,
Height : ts . Height ( ) ,
2020-03-18 23:06:53 +00:00
} , nil
}
2020-08-20 04:49:10 +00:00
return nil , nil
2020-03-18 23:06:53 +00:00
}
2020-02-11 23:29:45 +00:00
func ( a * StateAPI ) StateGetReceipt ( ctx context . Context , msg cid . Cid , tsk types . TipSetKey ) ( * types . MessageReceipt , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2019-11-19 21:27:25 +00:00
return a . StateManager . GetReceipt ( ctx , msg , ts )
}
2020-02-11 23:29:45 +00:00
func ( a * StateAPI ) StateListMiners ( ctx context . Context , tsk types . TipSetKey ) ( [ ] address . Address , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2019-12-17 06:51:41 +00:00
return stmgr . ListMinerActors ( ctx , a . StateManager , ts )
2019-10-12 06:45:48 +00:00
}
2020-02-11 23:29:45 +00:00
func ( a * StateAPI ) StateListActors ( ctx context . Context , tsk types . TipSetKey ) ( [ ] address . Address , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2019-10-12 06:45:48 +00:00
return a . StateManager . ListAllActors ( ctx , ts )
}
2019-10-22 10:09:36 +00:00
2020-02-24 17:32:02 +00:00
func ( a * StateAPI ) StateMarketBalance ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( api . MarketBalance , error ) {
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
2020-02-24 17:32:02 +00:00
return api . MarketBalance { } , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
2020-02-11 23:29:45 +00:00
}
2019-10-23 17:39:14 +00:00
return a . StateManager . MarketBalance ( ctx , addr , ts )
2019-10-22 10:09:36 +00:00
}
2019-10-22 19:29:05 +00:00
2020-02-24 17:32:02 +00:00
func ( a * StateAPI ) StateMarketParticipants ( ctx context . Context , tsk types . TipSetKey ) ( map [ string ] api . MarketBalance , error ) {
2020-02-08 02:18:32 +00:00
out := map [ string ] api . MarketBalance { }
2019-10-22 19:29:05 +00:00
2020-02-25 20:35:15 +00:00
var state market . State
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2020-02-25 20:54:58 +00:00
if _ , err := a . StateManager . LoadActorState ( ctx , builtin . StorageMarketActorAddr , & state , ts ) ; err != nil {
2019-10-22 19:29:05 +00:00
return nil , err
}
2020-07-23 00:14:54 +00:00
store := a . StateManager . ChainStore ( ) . Store ( ctx )
escrow , err := adt . AsMap ( store , state . EscrowTable )
2020-02-08 02:18:32 +00:00
if err != nil {
return nil , err
}
2020-07-23 00:14:54 +00:00
locked , err := adt . AsMap ( store , state . LockedTable )
2019-10-22 19:29:05 +00:00
if err != nil {
return nil , err
}
2020-07-23 00:14:54 +00:00
var es , lk abi . TokenAmount
err = escrow . ForEach ( & es , func ( k string ) error {
2019-10-22 19:29:05 +00:00
a , err := address . NewFromBytes ( [ ] byte ( k ) )
if err != nil {
return err
}
2020-02-08 02:18:32 +00:00
2020-09-14 20:31:03 +00:00
if found , err := locked . Get ( abi . AddrKey ( a ) , & lk ) ; err != nil {
2019-10-22 19:29:05 +00:00
return err
2020-07-23 00:14:54 +00:00
} else if ! found {
return fmt . Errorf ( "locked funds not found" )
2019-10-22 19:29:05 +00:00
}
2020-02-08 02:18:32 +00:00
out [ a . String ( ) ] = api . MarketBalance {
Escrow : es ,
Locked : lk ,
}
2019-10-22 19:29:05 +00:00
return nil
} )
if err != nil {
return nil , err
}
return out , nil
}
2020-02-24 17:32:02 +00:00
func ( a * StateAPI ) StateMarketDeals ( ctx context . Context , tsk types . TipSetKey ) ( map [ string ] api . MarketDeal , error ) {
2020-02-09 06:06:32 +00:00
out := map [ string ] api . MarketDeal { }
2019-10-22 19:29:05 +00:00
2020-02-25 20:35:15 +00:00
var state market . State
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2020-02-25 20:54:58 +00:00
if _ , err := a . StateManager . LoadActorState ( ctx , builtin . StorageMarketActorAddr , & state , ts ) ; err != nil {
2019-10-22 19:29:05 +00:00
return nil , err
}
2020-07-23 00:14:54 +00:00
store := a . StateManager . ChainStore ( ) . Store ( ctx )
da , err := adt . AsArray ( store , state . Proposals )
2019-10-22 19:29:05 +00:00
if err != nil {
return nil , err
}
2020-07-23 00:14:54 +00:00
sa , err := adt . AsArray ( store , state . States )
2020-02-09 06:06:32 +00:00
if err != nil {
return nil , err
}
2020-07-23 00:14:54 +00:00
var d market . DealProposal
if err := da . ForEach ( & d , func ( i int64 ) error {
2020-02-09 06:06:32 +00:00
var s market . DealState
2020-07-23 00:14:54 +00:00
if found , err := sa . Get ( uint64 ( i ) , & s ) ; err != nil {
return xerrors . Errorf ( "failed to get state for deal in proposals array: %w" , err )
} else if ! found {
2020-06-23 18:55:13 +00:00
s . SectorStartEpoch = - 1
2020-02-09 06:06:32 +00:00
}
2020-08-20 04:49:10 +00:00
out [ strconv . FormatInt ( i , 10 ) ] = api . MarketDeal {
2020-02-09 06:06:32 +00:00
Proposal : d ,
State : s ,
}
2019-10-22 19:29:05 +00:00
return nil
} ) ; err != nil {
return nil , err
}
return out , nil
}
2019-11-07 07:57:10 +00:00
2020-02-24 17:32:02 +00:00
func ( a * StateAPI ) StateMarketStorageDeal ( ctx context . Context , dealId abi . DealID , tsk types . TipSetKey ) ( * api . MarketDeal , error ) {
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2019-11-07 09:06:06 +00:00
return stmgr . GetStorageDeal ( ctx , a . StateManager , dealId , ts )
2019-11-07 07:57:10 +00:00
}
2019-11-15 18:38:09 +00:00
func ( a * StateAPI ) StateChangedActors ( ctx context . Context , old cid . Cid , new cid . Cid ) ( map [ string ] types . Actor , error ) {
2020-07-23 00:14:54 +00:00
store := adt . WrapStore ( ctx , cbor . NewCborStore ( a . Chain . Blockstore ( ) ) )
2019-11-15 18:38:09 +00:00
2020-07-23 00:14:54 +00:00
nh , err := adt . AsMap ( store , new )
2019-11-15 18:38:09 +00:00
if err != nil {
return nil , err
}
2020-07-23 00:14:54 +00:00
oh , err := adt . AsMap ( store , old )
2019-11-15 18:38:09 +00:00
if err != nil {
return nil , err
}
out := map [ string ] types . Actor { }
2020-07-23 00:14:54 +00:00
var (
ncval , ocval cbg . Deferred
buf = bytes . NewReader ( nil )
)
err = nh . ForEach ( & ncval , func ( k string ) error {
2019-11-15 18:38:09 +00:00
var act types . Actor
2020-07-23 00:14:54 +00:00
addr , err := address . NewFromBytes ( [ ] byte ( k ) )
if err != nil {
return xerrors . Errorf ( "address in state tree was not valid: %w" , err )
}
2019-11-15 18:38:09 +00:00
2020-09-14 20:31:03 +00:00
found , err := oh . Get ( abi . AddrKey ( addr ) , & ocval )
2020-07-23 00:14:54 +00:00
if err != nil {
return err
}
2019-11-15 18:38:09 +00:00
2020-07-23 00:14:54 +00:00
if found && bytes . Equal ( ocval . Raw , ncval . Raw ) {
return nil // not changed
}
2019-11-15 18:38:09 +00:00
2020-07-23 00:14:54 +00:00
buf . Reset ( ncval . Raw )
err = act . UnmarshalCBOR ( buf )
buf . Reset ( nil )
if err != nil {
2019-11-15 18:38:09 +00:00
return err
}
2020-07-23 00:14:54 +00:00
out [ addr . String ( ) ] = act
2019-11-15 18:38:09 +00:00
return nil
} )
if err != nil {
return nil , err
}
return out , nil
}
2019-12-11 23:31:59 +00:00
2020-02-11 23:29:45 +00:00
func ( a * StateAPI ) StateMinerSectorCount ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( api . MinerSectors , error ) {
2020-09-15 19:09:39 +00:00
act , err := a . StateManager . LoadActorTsk ( ctx , addr , tsk )
2020-07-18 12:54:21 +00:00
if err != nil {
return api . MinerSectors { } , err
}
2020-09-15 19:09:39 +00:00
mas , err := miner . Load ( a . Chain . Store ( ctx ) , act )
if err != nil {
return api . MinerSectors { } , err
}
var activeCount , liveCount , faultyCount uint64
if err := mas . ForEachDeadline ( func ( _ uint64 , dl miner . Deadline ) error {
return dl . ForEachPartition ( func ( _ uint64 , part miner . Partition ) error {
if active , err := part . ActiveSectors ( ) ; err != nil {
return err
} else if count , err := active . Count ( ) ; err != nil {
return err
} else {
activeCount += count
}
if live , err := part . LiveSectors ( ) ; err != nil {
return err
} else if count , err := live . Count ( ) ; err != nil {
return err
} else {
liveCount += count
}
if faulty , err := part . FaultySectors ( ) ; err != nil {
return err
} else if count , err := faulty . Count ( ) ; err != nil {
return err
} else {
faultyCount += count
}
return nil
} )
} ) ; err != nil {
return api . MinerSectors { } , err
}
return api . MinerSectors { Live : liveCount , Active : activeCount , Faulty : faultyCount } , nil
2019-12-11 23:31:59 +00:00
}
2020-01-07 19:03:11 +00:00
2020-09-15 19:09:39 +00:00
func ( a * StateAPI ) StateSectorPreCommitInfo ( ctx context . Context , maddr address . Address , n abi . SectorNumber , tsk types . TipSetKey ) ( * miner . SectorPreCommitOnChainInfo , error ) {
2020-04-04 02:55:19 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
2020-09-15 19:09:39 +00:00
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
2020-04-04 02:55:19 +00:00
}
return stmgr . PreCommitInfo ( ctx , a . StateManager , maddr , n , ts )
}
2020-05-28 00:06:29 +00:00
func ( a * StateAPI ) StateSectorGetInfo ( ctx context . Context , maddr address . Address , n abi . SectorNumber , tsk types . TipSetKey ) ( * miner . SectorOnChainInfo , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
return stmgr . MinerSectorInfo ( ctx , a . StateManager , maddr , n , ts )
}
2020-09-15 19:09:39 +00:00
func ( a * StateAPI ) StateSectorExpiration ( ctx context . Context , maddr address . Address , sectorNumber abi . SectorNumber , tsk types . TipSetKey ) ( * miner . SectorExpiration , error ) {
2020-09-15 17:44:44 +00:00
act , err := a . StateManager . LoadActorTsk ( ctx , maddr , tsk )
2020-07-16 15:24:41 +00:00
if err != nil {
return nil , err
}
2020-09-15 17:44:44 +00:00
mas , err := miner . Load ( a . StateManager . ChainStore ( ) . Store ( ctx ) , act )
if err != nil {
return nil , err
2020-07-16 15:24:41 +00:00
}
2020-09-15 17:44:44 +00:00
return mas . GetSectorExpiration ( sectorNumber )
2020-07-16 15:24:41 +00:00
}
2020-09-15 19:09:39 +00:00
func ( a * StateAPI ) StateSectorPartition ( ctx context . Context , maddr address . Address , sectorNumber abi . SectorNumber , tsk types . TipSetKey ) ( * miner . SectorLocation , error ) {
2020-09-15 17:44:44 +00:00
act , err := a . StateManager . LoadActorTsk ( ctx , maddr , tsk )
2020-07-14 12:32:17 +00:00
if err != nil {
return nil , err
}
2020-09-15 17:44:44 +00:00
mas , err := miner . Load ( a . StateManager . ChainStore ( ) . Store ( ctx ) , act )
if err != nil {
return nil , err
}
return mas . FindSector ( sectorNumber )
2020-07-14 12:32:17 +00:00
}
2020-02-24 17:32:02 +00:00
func ( a * StateAPI ) StateListMessages ( ctx context . Context , match * types . Message , tsk types . TipSetKey , toheight abi . ChainEpoch ) ( [ ] cid . Cid , error ) {
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2020-01-07 19:03:11 +00:00
if ts == nil {
ts = a . Chain . GetHeaviestTipSet ( )
}
if match . To == address . Undef && match . From == address . Undef {
return nil , xerrors . Errorf ( "must specify at least To or From in message filter" )
}
matchFunc := func ( msg * types . Message ) bool {
if match . From != address . Undef && match . From != msg . From {
return false
}
if match . To != address . Undef && match . To != msg . To {
return false
}
return true
}
var out [ ] cid . Cid
for ts . Height ( ) >= toheight {
msgs , err := a . Chain . MessagesForTipset ( ts )
if err != nil {
return nil , xerrors . Errorf ( "failed to get messages for tipset (%s): %w" , ts . Key ( ) , err )
}
for _ , msg := range msgs {
if matchFunc ( msg . VMMessage ( ) ) {
out = append ( out , msg . Cid ( ) )
}
}
if ts . Height ( ) == 0 {
break
}
next , err := a . Chain . LoadTipSet ( ts . Parents ( ) )
if err != nil {
return nil , xerrors . Errorf ( "loading next tipset: %w" , err )
}
ts = next
}
return out , nil
}
2020-01-17 02:33:43 +00:00
2020-03-08 02:31:36 +00:00
func ( a * StateAPI ) StateCompute ( ctx context . Context , height abi . ChainEpoch , msgs [ ] * types . Message , tsk types . TipSetKey ) ( * api . ComputeStateOutput , error ) {
2020-02-11 23:29:45 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
2020-03-08 02:31:36 +00:00
return nil , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
st , t , err := stmgr . ComputeState ( ctx , a . StateManager , height , msgs , ts )
if err != nil {
return nil , err
2020-02-11 23:29:45 +00:00
}
2020-03-08 02:31:36 +00:00
return & api . ComputeStateOutput {
Root : st ,
Trace : t ,
} , nil
2020-01-17 02:33:43 +00:00
}
2020-01-30 01:23:16 +00:00
2020-02-11 23:29:45 +00:00
func ( a * StateAPI ) MsigGetAvailableBalance ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( types . BigInt , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
2020-01-30 01:23:16 +00:00
}
2020-09-15 21:44:03 +00:00
act , err := a . StateManager . LoadActor ( ctx , addr , ts )
2020-01-30 01:23:16 +00:00
if err != nil {
2020-09-15 21:44:03 +00:00
return types . EmptyInt , xerrors . Errorf ( "failed to load multisig actor: %w" , err )
2020-01-30 01:23:16 +00:00
}
2020-09-15 21:44:03 +00:00
msas , err := multisig . Load ( a . Chain . Store ( ctx ) , act )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "failed to load multisig actor state: %w" , err )
2020-01-30 01:23:16 +00:00
}
2020-09-15 21:44:03 +00:00
locked , err := msas . LockedBalance ( ts . Height ( ) )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "failed to compute locked multisig balance: %w" , err )
2020-01-30 01:23:16 +00:00
}
2020-09-15 21:44:03 +00:00
return types . BigSub ( act . Balance , locked ) , nil
2020-01-30 01:23:16 +00:00
}
2020-04-23 19:39:34 +00:00
2020-09-06 00:29:26 +00:00
func ( a * StateAPI ) MsigGetVested ( ctx context . Context , addr address . Address , start types . TipSetKey , end types . TipSetKey ) ( types . BigInt , error ) {
startTs , err := a . Chain . GetTipSetFromKey ( start )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "loading start tipset %s: %w" , start , err )
}
endTs , err := a . Chain . GetTipSetFromKey ( end )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "loading end tipset %s: %w" , end , err )
}
if startTs . Height ( ) > endTs . Height ( ) {
return types . EmptyInt , xerrors . Errorf ( "start tipset %d is after end tipset %d" , startTs . Height ( ) , endTs . Height ( ) )
} else if startTs . Height ( ) == endTs . Height ( ) {
return big . Zero ( ) , nil
}
2020-09-15 21:44:03 +00:00
act , err := a . StateManager . LoadActor ( ctx , addr , endTs )
2020-09-06 00:29:26 +00:00
if err != nil {
2020-09-15 21:44:03 +00:00
return types . EmptyInt , xerrors . Errorf ( "failed to load multisig actor at end epoch: %w" , err )
2020-09-06 00:29:26 +00:00
}
2020-09-15 21:44:03 +00:00
msas , err := multisig . Load ( a . Chain . Store ( ctx ) , act )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "failed to load multisig actor state: %w" , err )
2020-09-06 00:29:26 +00:00
}
2020-09-15 21:44:03 +00:00
startLk , err := msas . LockedBalance ( startTs . Height ( ) )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "failed to compute locked balance at start height: %w" , err )
2020-09-06 00:29:26 +00:00
}
2020-09-15 21:44:03 +00:00
endLk , err := msas . LockedBalance ( endTs . Height ( ) )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "failed to compute locked balance at end height: %w" , err )
2020-09-06 00:29:26 +00:00
}
2020-09-15 21:44:03 +00:00
return types . BigSub ( startLk , endLk ) , nil
2020-09-06 00:29:26 +00:00
}
2020-07-30 00:06:22 +00:00
var initialPledgeNum = types . NewInt ( 110 )
2020-05-15 14:53:35 +00:00
var initialPledgeDen = types . NewInt ( 100 )
2020-07-28 18:55:20 +00:00
func ( a * StateAPI ) StateMinerPreCommitDepositForPower ( ctx context . Context , maddr address . Address , pci miner . SectorPreCommitInfo , tsk types . TipSetKey ) ( types . BigInt , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2020-09-15 23:47:58 +00:00
state , err := a . StateManager . ParentState ( ts )
2020-07-28 18:55:20 +00:00
if err != nil {
2020-09-15 23:47:58 +00:00
return types . EmptyInt , xerrors . Errorf ( "loading state %s: %w" , tsk , err )
2020-07-28 18:55:20 +00:00
}
2020-09-15 23:47:58 +00:00
ssize , err := pci . SealProof . SectorSize ( )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "failed to get resolve size: %w" , err )
2020-07-28 18:55:20 +00:00
}
2020-09-15 23:47:58 +00:00
store := a . Chain . Store ( ctx )
2020-07-28 18:55:20 +00:00
2020-09-15 23:47:58 +00:00
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 ( )
2020-07-28 18:55:20 +00:00
2020-09-15 23:47:58 +00:00
// TODO: handle changes to this function across actor upgrades.
sectorWeight = v0miner . QAPowerForWeight ( ssize , duration , w , vw )
2020-07-28 18:55:20 +00:00
}
2020-09-15 23:47:58 +00:00
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
2020-07-28 18:55:20 +00:00
}
2020-09-15 23:47:58 +00:00
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
}
2020-07-28 18:55:20 +00:00
2020-09-15 23:47:58 +00:00
// TODO: abstract over network upgrades.
deposit := v0miner . PreCommitDepositForPower ( rewardSmoothed , powerSmoothed , sectorWeight )
2020-07-28 18:55:20 +00:00
return types . BigDiv ( types . BigMul ( deposit , initialPledgeNum ) , initialPledgeDen ) , nil
}
2020-06-26 15:59:34 +00:00
func ( a * StateAPI ) StateMinerInitialPledgeCollateral ( ctx context . Context , maddr address . Address , pci miner . SectorPreCommitInfo , tsk types . TipSetKey ) ( types . BigInt , error ) {
2020-09-16 01:05:33 +00:00
// TODO: this repeats a lot of the previous function. Fix that.
2020-04-23 19:39:34 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2020-09-16 01:05:33 +00:00
state , err := a . StateManager . ParentState ( ts )
2020-07-14 11:45:45 +00:00
if err != nil {
2020-09-16 01:05:33 +00:00
return types . EmptyInt , xerrors . Errorf ( "loading state %s: %w" , tsk , err )
2020-04-23 19:39:34 +00:00
}
2020-09-16 01:05:33 +00:00
ssize , err := pci . SealProof . SectorSize ( )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "failed to get resolve size: %w" , err )
2020-07-24 22:21:34 +00:00
}
2020-09-16 01:05:33 +00:00
store := a . Chain . Store ( ctx )
2020-04-23 19:39:34 +00:00
2020-09-16 01:05:33 +00:00
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 ( )
2020-04-23 19:39:34 +00:00
2020-09-16 01:05:33 +00:00
// TODO: handle changes to this function across actor upgrades.
sectorWeight = v0miner . QAPowerForWeight ( ssize , duration , w , vw )
2020-04-23 19:39:34 +00:00
}
2020-09-16 01:05:33 +00:00
var (
powerSmoothed smoothing . FilterEstimate
pledgeCollerateral abi . TokenAmount
)
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 c , err := s . TotalLocked ( ) ; err != nil {
return types . EmptyInt , xerrors . Errorf ( "failed to determine pledge collateral: %w" , err )
} else {
powerSmoothed = p
pledgeCollateral = c
2020-06-26 13:49:39 +00:00
}
2020-04-23 19:39:34 +00:00
2020-09-16 01:05:33 +00:00
var (
rewardSmoothed smoothing . FilterEstimate
baselinePower abi . StoragePower
)
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 p , err := s . BaselinePower ( ) ; err != nil {
return types . EmptyInt , xerrors . Errorf ( "failed to determine baseline power: %w" , err )
} else {
rewardSmoothed = r
baselinePower = p
}
2020-07-24 22:21:34 +00:00
2020-09-16 01:05:33 +00:00
// TODO: abstract over network upgrades.
2020-04-23 19:39:34 +00:00
2020-08-09 23:21:21 +00:00
circSupply , err := a . StateCirculatingSupply ( ctx , ts . Key ( ) )
2020-06-26 13:49:39 +00:00
if err != nil {
return big . Zero ( ) , xerrors . Errorf ( "getting circulating supply: %w" , err )
2020-04-23 19:39:34 +00:00
}
2020-07-28 14:36:32 +00:00
initialPledge := miner . InitialPledgeForPower (
sectorWeight ,
2020-09-16 01:05:33 +00:00
baselinePower ,
pledgeCollateral ,
rewardSmoothed ,
powerSmoothed ,
2020-08-14 20:44:33 +00:00
circSupply . FilCirculating ,
2020-07-28 18:55:20 +00:00
)
2020-06-26 13:49:39 +00:00
2020-05-15 14:53:35 +00:00
return types . BigDiv ( types . BigMul ( initialPledge , initialPledgeNum ) , initialPledgeDen ) , nil
2020-04-23 19:39:34 +00:00
}
func ( a * StateAPI ) StateMinerAvailableBalance ( ctx context . Context , maddr address . Address , tsk types . TipSetKey ) ( types . BigInt , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return types . EmptyInt , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
2020-07-14 11:45:45 +00:00
var act * types . Actor
var mas miner . State
2020-04-23 19:39:34 +00:00
2020-07-14 11:45:45 +00:00
if err := a . StateManager . WithParentState ( ts , a . StateManager . WithActor ( maddr , func ( actor * types . Actor ) error {
act = actor
return a . StateManager . WithActorState ( ctx , & mas ) ( actor )
} ) ) ; err != nil {
return types . BigInt { } , xerrors . Errorf ( "getting miner state: %w" , err )
2020-04-23 19:39:34 +00:00
}
2020-07-14 11:45:45 +00:00
as := store . ActorStore ( ctx , a . Chain . Blockstore ( ) )
2020-04-23 19:39:34 +00:00
2020-07-14 11:45:45 +00:00
vested , err := mas . CheckVestedFunds ( as , ts . Height ( ) )
2020-04-23 19:39:34 +00:00
if err != nil {
return types . EmptyInt , err
}
2020-07-14 11:45:45 +00:00
return types . BigAdd ( mas . GetAvailableBalance ( act . Balance ) , vested ) , nil
2020-04-23 19:39:34 +00:00
}
2020-07-02 15:57:10 +00:00
2020-07-02 18:49:08 +00:00
// StateVerifiedClientStatus returns the data cap for the given address.
2020-07-07 13:59:14 +00:00
// Returns nil if there is no entry in the data cap table for the
2020-07-02 18:49:08 +00:00
// address.
2020-07-07 13:59:14 +00:00
func ( a * StateAPI ) StateVerifiedClientStatus ( ctx context . Context , addr address . Address , tsk types . TipSetKey ) ( * verifreg . DataCap , error ) {
2020-07-02 15:57:10 +00:00
act , err := a . StateGetActor ( ctx , builtin . VerifiedRegistryActorAddr , tsk )
if err != nil {
2020-07-07 13:59:14 +00:00
return nil , err
2020-07-02 15:57:10 +00:00
}
2020-08-19 12:27:50 +00:00
aid , err := a . StateLookupID ( ctx , addr , tsk )
if err != nil {
log . Warnf ( "lookup failure %v" , err )
return nil , err
}
2020-07-23 00:14:54 +00:00
store := a . StateManager . ChainStore ( ) . Store ( ctx )
2020-07-02 15:57:10 +00:00
var st verifreg . State
2020-07-23 00:14:54 +00:00
if err := store . Get ( ctx , act . Head , & st ) ; err != nil {
2020-07-07 13:59:14 +00:00
return nil , err
2020-07-02 15:57:10 +00:00
}
2020-07-23 00:14:54 +00:00
vh , err := adt . AsMap ( store , st . VerifiedClients )
2020-07-02 15:57:10 +00:00
if err != nil {
2020-07-07 13:59:14 +00:00
return nil , err
2020-07-02 15:57:10 +00:00
}
2020-07-07 14:01:08 +00:00
2020-07-02 15:57:10 +00:00
var dcap verifreg . DataCap
2020-09-14 20:31:03 +00:00
if found , err := vh . Get ( abi . AddrKey ( aid ) , & dcap ) ; err != nil {
2020-07-07 13:59:14 +00:00
return nil , err
2020-07-23 00:14:54 +00:00
} else if ! found {
return nil , nil
2020-07-02 15:57:10 +00:00
}
2020-07-07 13:59:14 +00:00
return & dcap , nil
2020-07-06 20:47:39 +00:00
}
2020-07-30 04:55:37 +00:00
var dealProviderCollateralNum = types . NewInt ( 110 )
var dealProviderCollateralDen = types . NewInt ( 100 )
// StateDealProviderCollateralBounds returns the min and max collateral a storage provider
// can issue. It takes the deal size and verified status as parameters.
2020-07-30 12:31:31 +00:00
func ( a * StateAPI ) StateDealProviderCollateralBounds ( ctx context . Context , size abi . PaddedPieceSize , verified bool , tsk types . TipSetKey ) ( api . DealCollateralBounds , error ) {
2020-07-30 04:55:37 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
2020-07-30 12:31:31 +00:00
return api . DealCollateralBounds { } , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
2020-07-30 04:55:37 +00:00
}
var powerState power . State
var rewardState reward . State
err = a . StateManager . WithParentStateTsk ( ts . Key ( ) , func ( state * state . StateTree ) error {
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
} )
if err != nil {
2020-08-20 04:49:10 +00:00
return api . DealCollateralBounds { } , xerrors . Errorf ( "getting power and reward actor states: %w" , err )
2020-07-30 04:55:37 +00:00
}
2020-08-09 23:21:21 +00:00
circ , err := a . StateCirculatingSupply ( ctx , ts . Key ( ) )
2020-07-30 04:55:37 +00:00
if err != nil {
2020-08-20 04:49:10 +00:00
return api . DealCollateralBounds { } , xerrors . Errorf ( "getting total circulating supply: %w" , err )
2020-07-30 04:55:37 +00:00
}
2020-09-07 20:01:09 +00:00
min , max := market . DealProviderCollateralBounds ( size ,
verified ,
powerState . TotalRawBytePower ,
powerState . ThisEpochQualityAdjPower ,
rewardState . ThisEpochBaselinePower ,
circ . FilCirculating ,
a . StateManager . GetNtwkVersion ( ctx , ts . Height ( ) ) )
2020-07-30 12:31:31 +00:00
return api . DealCollateralBounds {
Min : types . BigDiv ( types . BigMul ( min , dealProviderCollateralNum ) , dealProviderCollateralDen ) ,
Max : max ,
} , nil
2020-07-30 04:55:37 +00:00
}
2020-08-07 19:57:03 +00:00
2020-08-14 20:44:33 +00:00
func ( a * StateAPI ) StateCirculatingSupply ( ctx context . Context , tsk types . TipSetKey ) ( api . CirculatingSupply , error ) {
2020-08-07 19:57:03 +00:00
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
2020-08-14 20:44:33 +00:00
return api . CirculatingSupply { } , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
2020-08-07 19:57:03 +00:00
}
2020-09-12 03:07:52 +00:00
sTree , err := a . stateForTs ( ctx , ts )
2020-08-20 04:49:10 +00:00
if err != nil {
return api . CirculatingSupply { } , err
}
2020-08-14 20:44:33 +00:00
return a . StateManager . GetCirculatingSupplyDetailed ( ctx , ts . Height ( ) , sTree )
2020-08-07 19:57:03 +00:00
}
2020-09-17 01:56:02 +00:00
func ( a * StateAPI ) StateNetworkVersion ( ctx context . Context , tsk types . TipSetKey ) ( network . Version , error ) {
ts , err := a . Chain . GetTipSetFromKey ( tsk )
if err != nil {
return - 1 , xerrors . Errorf ( "loading tipset %s: %w" , tsk , err )
}
return a . StateManager . GetNtwkVersion ( ctx , ts . Height ( ) ) , nil
}