Add an endpoint for precise circulating supply
This commit is contained in:
parent
8d769f0c07
commit
96e1dfd8d7
@ -416,8 +416,12 @@ type FullNode interface {
|
|||||||
// can issue. It takes the deal size and verified status as parameters.
|
// can issue. It takes the deal size and verified status as parameters.
|
||||||
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
|
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
|
||||||
|
|
||||||
// StateCirculatingSupply returns the circulating supply of Filecoin at the given tipset
|
// StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset.
|
||||||
StateCirculatingSupply(context.Context, types.TipSetKey) (CirculatingSupply, error)
|
// This is not used anywhere in the protocol itself, and is only for external consumption.
|
||||||
|
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error)
|
||||||
|
// StateVMCirculatingSupply returns an approximation of the circulating supply of Filecoin at the given tipset.
|
||||||
|
// This is the value reported by the runtime interface to actors code.
|
||||||
|
StateVMCirculatingSupply(context.Context, types.TipSetKey) (CirculatingSupply, error)
|
||||||
// StateNetworkVersion returns the network version at the given tipset
|
// StateNetworkVersion returns the network version at the given tipset
|
||||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||||
|
|
||||||
|
@ -210,7 +210,8 @@ type FullNodeStruct struct {
|
|||||||
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||||
StateVerifiedRegistryRootKey func(ctx context.Context, tsk types.TipSetKey) (address.Address, error) `perm:"read"`
|
StateVerifiedRegistryRootKey func(ctx context.Context, tsk types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||||
StateDealProviderCollateralBounds func(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"`
|
StateDealProviderCollateralBounds func(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"`
|
||||||
StateCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
StateCirculatingSupply func(context.Context, types.TipSetKey) (abi.TokenAmount, error) `perm:"read"`
|
||||||
|
StateVMCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
||||||
StateNetworkVersion func(context.Context, types.TipSetKey) (stnetwork.Version, error) `perm:"read"`
|
StateNetworkVersion func(context.Context, types.TipSetKey) (stnetwork.Version, error) `perm:"read"`
|
||||||
|
|
||||||
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||||
@ -963,10 +964,14 @@ func (c *FullNodeStruct) StateDealProviderCollateralBounds(ctx context.Context,
|
|||||||
return c.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
|
return c.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
|
func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) {
|
||||||
return c.Internal.StateCirculatingSupply(ctx, tsk)
|
return c.Internal.StateCirculatingSupply(ctx, tsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) StateVMCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
|
||||||
|
return c.Internal.StateVMCirculatingSupply(ctx, tsk)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) {
|
func (c *FullNodeStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) {
|
||||||
return c.Internal.StateNetworkVersion(ctx, tsk)
|
return c.Internal.StateNetworkVersion(ctx, tsk)
|
||||||
}
|
}
|
||||||
|
@ -2,25 +2,28 @@ package builtin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var SystemActorAddr = builtin0.SystemActorAddr
|
var SystemActorAddr = builtin0.SystemActorAddr
|
||||||
var BurntFundsActorAddr = builtin0.BurntFundsActorAddr
|
var BurntFundsActorAddr = builtin0.BurntFundsActorAddr
|
||||||
|
var CronActorAddr = builtin0.CronActorAddr
|
||||||
|
var SaftAddress = makeAddress("t0122")
|
||||||
var ReserveAddress = makeAddress("t090")
|
var ReserveAddress = makeAddress("t090")
|
||||||
var RootVerifierAddress = makeAddress("t080")
|
var RootVerifierAddress = makeAddress("t080")
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package miner
|
package miner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
@ -196,3 +197,7 @@ type LockedFunds struct {
|
|||||||
InitialPledgeRequirement abi.TokenAmount
|
InitialPledgeRequirement abi.TokenAmount
|
||||||
PreCommitDeposits abi.TokenAmount
|
PreCommitDeposits abi.TokenAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount {
|
||||||
|
return big.Add(lf.VestingFunds, big.Add(lf.InitialPledgeRequirement, lf.PreCommitDeposits))
|
||||||
|
}
|
||||||
|
@ -47,8 +47,16 @@ type partition0 struct {
|
|||||||
store adt.Store
|
store adt.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) {
|
func (s *state0) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
|
||||||
return s.GetAvailableBalance(bal), nil
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = xerrors.Errorf("failed to get available balance: %w", r)
|
||||||
|
available = abi.NewTokenAmount(0)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||||
|
available = s.GetAvailableBalance(bal)
|
||||||
|
return available, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
func (s *state0) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||||
|
@ -45,8 +45,16 @@ type partition2 struct {
|
|||||||
store adt.Store
|
store adt.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state2) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) {
|
func (s *state2) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
|
||||||
return s.GetAvailableBalance(bal)
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = xerrors.Errorf("failed to get available balance: %w", r)
|
||||||
|
available = abi.NewTokenAmount(0)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||||
|
available, err = s.GetAvailableBalance(bal)
|
||||||
|
return available, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state2) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
func (s *state2) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||||
|
@ -61,7 +61,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
|
|||||||
Rand: store.NewChainRand(sm.cs, ts.Cids()),
|
Rand: store.NewChainRand(sm.cs, ts.Cids()),
|
||||||
Bstore: sm.cs.Blockstore(),
|
Bstore: sm.cs.Blockstore(),
|
||||||
Syscalls: sm.cs.VMSys(),
|
Syscalls: sm.cs.VMSys(),
|
||||||
CircSupplyCalc: sm.GetCirculatingSupply,
|
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
||||||
NtwkVersion: sm.GetNtwkVersion,
|
NtwkVersion: sm.GetNtwkVersion,
|
||||||
BaseFee: types.NewInt(0),
|
BaseFee: types.NewInt(0),
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
|
|||||||
Rand: r,
|
Rand: r,
|
||||||
Bstore: sm.cs.Blockstore(),
|
Bstore: sm.cs.Blockstore(),
|
||||||
Syscalls: sm.cs.VMSys(),
|
Syscalls: sm.cs.VMSys(),
|
||||||
CircSupplyCalc: sm.GetCirculatingSupply,
|
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
||||||
NtwkVersion: sm.GetNtwkVersion,
|
NtwkVersion: sm.GetNtwkVersion,
|
||||||
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
||||||
}
|
}
|
||||||
|
@ -265,11 +265,6 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
|
|||||||
return cid.Undef, xerrors.Errorf("loading state tree failed: %w", err)
|
return cid.Undef, xerrors.Errorf("loading state tree failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ReserveAddress, err := address.NewFromString("t090")
|
|
||||||
if err != nil {
|
|
||||||
return cid.Undef, xerrors.Errorf("failed to parse reserve address: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tree, err := sm.StateTree(root)
|
tree, err := sm.StateTree(root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
|
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
|
||||||
@ -295,7 +290,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
|
|||||||
if !sysAcc {
|
if !sysAcc {
|
||||||
transfers = append(transfers, transfer{
|
transfers = append(transfers, transfer{
|
||||||
From: addr,
|
From: addr,
|
||||||
To: ReserveAddress,
|
To: builtin.ReserveAddress,
|
||||||
Amt: act.Balance,
|
Amt: act.Balance,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -319,7 +314,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
|
|||||||
|
|
||||||
transfers = append(transfers, transfer{
|
transfers = append(transfers, transfer{
|
||||||
From: addr,
|
From: addr,
|
||||||
To: ReserveAddress,
|
To: builtin.ReserveAddress,
|
||||||
Amt: available,
|
Amt: available,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -370,7 +365,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
|
|||||||
nbalance := big.Min(prevBalance, AccountCap)
|
nbalance := big.Min(prevBalance, AccountCap)
|
||||||
if nbalance.Sign() != 0 {
|
if nbalance.Sign() != 0 {
|
||||||
transfersBack = append(transfersBack, transfer{
|
transfersBack = append(transfersBack, transfer{
|
||||||
From: ReserveAddress,
|
From: builtin.ReserveAddress,
|
||||||
To: addr,
|
To: addr,
|
||||||
Amt: nbalance,
|
Amt: nbalance,
|
||||||
})
|
})
|
||||||
@ -397,7 +392,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
|
|||||||
|
|
||||||
mfunds := minerFundsAlloc(power, totalPower)
|
mfunds := minerFundsAlloc(power, totalPower)
|
||||||
transfersBack = append(transfersBack, transfer{
|
transfersBack = append(transfersBack, transfer{
|
||||||
From: ReserveAddress,
|
From: builtin.ReserveAddress,
|
||||||
To: minfo.Worker,
|
To: minfo.Worker,
|
||||||
Amt: mfunds,
|
Amt: mfunds,
|
||||||
})
|
})
|
||||||
@ -417,7 +412,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
|
|||||||
|
|
||||||
if lbsectors.Length() > 0 {
|
if lbsectors.Length() > 0 {
|
||||||
transfersBack = append(transfersBack, transfer{
|
transfersBack = append(transfersBack, transfer{
|
||||||
From: ReserveAddress,
|
From: builtin.ReserveAddress,
|
||||||
To: minfo.Worker,
|
To: minfo.Worker,
|
||||||
Amt: BaseMinerBalance,
|
Amt: BaseMinerBalance,
|
||||||
})
|
})
|
||||||
@ -444,7 +439,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to load burnt funds actor: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to load burnt funds actor: %w", err)
|
||||||
}
|
}
|
||||||
if err := doTransfer(cb, tree, builtin0.BurntFundsActorAddr, ReserveAddress, burntAct.Balance); err != nil {
|
if err := doTransfer(cb, tree, builtin0.BurntFundsActorAddr, builtin.ReserveAddress, burntAct.Balance); err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to unburn funds: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to unburn funds: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +455,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
|
|||||||
}
|
}
|
||||||
|
|
||||||
difference := types.BigSub(DesiredReimbursementBalance, reimb.Balance)
|
difference := types.BigSub(DesiredReimbursementBalance, reimb.Balance)
|
||||||
if err := doTransfer(cb, tree, ReserveAddress, reimbAddr, difference); err != nil {
|
if err := doTransfer(cb, tree, builtin.ReserveAddress, reimbAddr, difference); err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to top up reimbursement account: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to top up reimbursement account: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,12 +540,7 @@ func UpgradeRefuel(ctx context.Context, sm *StateManager, cb ExecCallback, root
|
|||||||
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
|
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, err := address.NewFromString("t0122")
|
err = resetMultisigVesting(ctx, store, tree, builtin.SaftAddress, 0, 0, big.Zero())
|
||||||
if err != nil {
|
|
||||||
return cid.Undef, xerrors.Errorf("getting address: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = resetMultisigVesting(ctx, store, tree, addr, 0, 0, big.Zero())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err)
|
return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,11 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||||
|
|
||||||
|
_init "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
@ -229,7 +234,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
|||||||
Rand: r,
|
Rand: r,
|
||||||
Bstore: sm.cs.Blockstore(),
|
Bstore: sm.cs.Blockstore(),
|
||||||
Syscalls: sm.cs.VMSys(),
|
Syscalls: sm.cs.VMSys(),
|
||||||
CircSupplyCalc: sm.GetCirculatingSupply,
|
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
||||||
NtwkVersion: sm.GetNtwkVersion,
|
NtwkVersion: sm.GetNtwkVersion,
|
||||||
BaseFee: baseFee,
|
BaseFee: baseFee,
|
||||||
}
|
}
|
||||||
@ -1294,7 +1299,16 @@ func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, err
|
|||||||
return burnt.Balance, nil
|
return burnt.Balance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) GetCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (api.CirculatingSupply, error) {
|
func (sm *StateManager) GetVMCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
|
||||||
|
cs, err := sm.GetVMCirculatingSupplyDetailed(ctx, height, st)
|
||||||
|
if err != nil {
|
||||||
|
return types.EmptyInt, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cs.FilCirculating, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *StateManager) GetVMCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (api.CirculatingSupply, error) {
|
||||||
sm.genesisMsigLk.Lock()
|
sm.genesisMsigLk.Lock()
|
||||||
defer sm.genesisMsigLk.Unlock()
|
defer sm.genesisMsigLk.Unlock()
|
||||||
if sm.preIgnitionGenInfos == nil {
|
if sm.preIgnitionGenInfos == nil {
|
||||||
@ -1357,12 +1371,91 @@ func (sm *StateManager) GetCirculatingSupplyDetailed(ctx context.Context, height
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
|
func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
|
||||||
csi, err := sm.GetCirculatingSupplyDetailed(ctx, height, st)
|
circ := big.Zero()
|
||||||
|
unCirc := big.Zero()
|
||||||
|
err := st.ForEach(func(a address.Address, actor *types.Actor) error {
|
||||||
|
switch {
|
||||||
|
case actor.Balance.IsZero():
|
||||||
|
// Do nothing for zero-balance actors
|
||||||
|
break
|
||||||
|
case a == _init.Address ||
|
||||||
|
a == reward.Address ||
|
||||||
|
a == verifreg.Address ||
|
||||||
|
// The power actor itself should never receive funds
|
||||||
|
a == power.Address ||
|
||||||
|
a == builtin.SystemActorAddr ||
|
||||||
|
a == builtin.CronActorAddr ||
|
||||||
|
a == builtin.BurntFundsActorAddr ||
|
||||||
|
a == builtin.SaftAddress ||
|
||||||
|
a == builtin.ReserveAddress:
|
||||||
|
|
||||||
|
unCirc = big.Add(unCirc, actor.Balance)
|
||||||
|
|
||||||
|
case a == market.Address:
|
||||||
|
mst, err := market.Load(sm.cs.Store(ctx), actor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return big.Zero(), err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return csi.FilCirculating, nil
|
lb, err := mst.TotalLocked()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
circ = big.Add(circ, big.Sub(actor.Balance, lb))
|
||||||
|
unCirc = big.Add(unCirc, lb)
|
||||||
|
|
||||||
|
case builtin.IsAccountActor(actor.Code) || builtin.IsPaymentChannelActor(actor.Code):
|
||||||
|
circ = big.Add(circ, actor.Balance)
|
||||||
|
|
||||||
|
case builtin.IsStorageMinerActor(actor.Code):
|
||||||
|
mst, err := miner.Load(sm.cs.Store(ctx), actor)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ab, err := mst.AvailableBalance(actor.Balance)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
circ = big.Add(circ, ab)
|
||||||
|
unCirc = big.Add(unCirc, big.Sub(actor.Balance, ab))
|
||||||
|
} else {
|
||||||
|
// Assume any error is because the miner state is "broken" (lower actor balance than locked funds)
|
||||||
|
// In this case, the actor's entire balance is considered "uncirculating"
|
||||||
|
unCirc = big.Add(unCirc, actor.Balance)
|
||||||
|
}
|
||||||
|
|
||||||
|
case builtin.IsMultisigActor(actor.Code):
|
||||||
|
mst, err := multisig.Load(sm.cs.Store(ctx), actor)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
lb, err := mst.LockedBalance(height)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ab := big.Sub(actor.Balance, lb)
|
||||||
|
circ = big.Add(circ, big.Max(ab, big.Zero()))
|
||||||
|
unCirc = big.Add(unCirc, big.Min(actor.Balance, lb))
|
||||||
|
default:
|
||||||
|
return xerrors.Errorf("unexpected actor: %s", a)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return types.EmptyInt, err
|
||||||
|
}
|
||||||
|
|
||||||
|
total := big.Add(circ, unCirc)
|
||||||
|
if !total.Equals(types.TotalFilecoinInt) {
|
||||||
|
return types.EmptyInt, xerrors.Errorf("total filecoin didn't add to expected amount: %s != %s", total, types.TotalFilecoinInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
return circ, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
|
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
|
||||||
|
@ -383,7 +383,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
|
|||||||
Rand: r,
|
Rand: r,
|
||||||
Bstore: sm.cs.Blockstore(),
|
Bstore: sm.cs.Blockstore(),
|
||||||
Syscalls: sm.cs.VMSys(),
|
Syscalls: sm.cs.VMSys(),
|
||||||
CircSupplyCalc: sm.GetCirculatingSupply,
|
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
||||||
NtwkVersion: sm.GetNtwkVersion,
|
NtwkVersion: sm.GetNtwkVersion,
|
||||||
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
||||||
}
|
}
|
||||||
|
21
cli/state.go
21
cli/state.go
@ -1688,7 +1688,14 @@ func parseParamsForMethod(act cid.Cid, method uint64, args []string) ([]byte, er
|
|||||||
|
|
||||||
var stateCircSupplyCmd = &cli.Command{
|
var stateCircSupplyCmd = &cli.Command{
|
||||||
Name: "circulating-supply",
|
Name: "circulating-supply",
|
||||||
Usage: "Get the current circulating supply of filecoin",
|
Usage: "Get the exact current circulating supply of Filecoin",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "vm-supply",
|
||||||
|
Usage: "calculates the approximation of the circulating supply used internally by the VM (instead of the exact amount)",
|
||||||
|
Value: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1703,7 +1710,8 @@ var stateCircSupplyCmd = &cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
circ, err := api.StateCirculatingSupply(ctx, ts.Key())
|
if cctx.IsSet("vm-supply") {
|
||||||
|
circ, err := api.StateVMCirculatingSupply(ctx, ts.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1713,6 +1721,15 @@ var stateCircSupplyCmd = &cli.Command{
|
|||||||
fmt.Println("Vested: ", types.FIL(circ.FilVested))
|
fmt.Println("Vested: ", types.FIL(circ.FilVested))
|
||||||
fmt.Println("Burnt: ", types.FIL(circ.FilBurnt))
|
fmt.Println("Burnt: ", types.FIL(circ.FilBurnt))
|
||||||
fmt.Println("Locked: ", types.FIL(circ.FilLocked))
|
fmt.Println("Locked: ", types.FIL(circ.FilLocked))
|
||||||
|
} else {
|
||||||
|
circ, err := api.StateCirculatingSupply(ctx, ts.Key())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Exact circulating supply: ", types.FIL(circ))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -316,7 +316,7 @@ limit 1
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Syncer) storeCirculatingSupply(ctx context.Context, tipset *types.TipSet) error {
|
func (s *Syncer) storeCirculatingSupply(ctx context.Context, tipset *types.TipSet) error {
|
||||||
supply, err := s.node.StateCirculatingSupply(ctx, tipset.Key())
|
supply, err := s.node.StateVMCirculatingSupply(ctx, tipset.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -372,7 +372,7 @@ var chainPledgeCmd = &cli.Command{
|
|||||||
pledgeCollateral = c
|
pledgeCollateral = c
|
||||||
}
|
}
|
||||||
|
|
||||||
circ, err := sm.GetCirculatingSupplyDetailed(ctx, abi.ChainEpoch(epoch), state)
|
circ, err := sm.GetVMCirculatingSupplyDetailed(ctx, abi.ChainEpoch(epoch), state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ func doExtract(ctx context.Context, fapi api.FullNode, opts extractOpts) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the circulating supply before the message was executed.
|
// get the circulating supply before the message was executed.
|
||||||
circSupplyDetail, err := fapi.StateCirculatingSupply(ctx, incTs.Key())
|
circSupplyDetail, err := fapi.StateVMCirculatingSupply(ctx, incTs.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed while fetching circulating supply: %w", err)
|
return fmt.Errorf("failed while fetching circulating supply: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -165,6 +165,7 @@
|
|||||||
* [StateSectorGetInfo](#StateSectorGetInfo)
|
* [StateSectorGetInfo](#StateSectorGetInfo)
|
||||||
* [StateSectorPartition](#StateSectorPartition)
|
* [StateSectorPartition](#StateSectorPartition)
|
||||||
* [StateSectorPreCommitInfo](#StateSectorPreCommitInfo)
|
* [StateSectorPreCommitInfo](#StateSectorPreCommitInfo)
|
||||||
|
* [StateVMCirculatingSupply](#StateVMCirculatingSupply)
|
||||||
* [StateVerifiedClientStatus](#StateVerifiedClientStatus)
|
* [StateVerifiedClientStatus](#StateVerifiedClientStatus)
|
||||||
* [StateVerifiedRegistryRootKey](#StateVerifiedRegistryRootKey)
|
* [StateVerifiedRegistryRootKey](#StateVerifiedRegistryRootKey)
|
||||||
* [StateVerifierStatus](#StateVerifierStatus)
|
* [StateVerifierStatus](#StateVerifierStatus)
|
||||||
@ -3094,7 +3095,8 @@ Response:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### StateCirculatingSupply
|
### StateCirculatingSupply
|
||||||
StateCirculatingSupply returns the circulating supply of Filecoin at the given tipset
|
StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset.
|
||||||
|
This is not used anywhere in the protocol itself, and is only for external consumption.
|
||||||
|
|
||||||
|
|
||||||
Perms: read
|
Perms: read
|
||||||
@ -3113,16 +3115,7 @@ Inputs:
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
Response:
|
Response: `"0"`
|
||||||
```json
|
|
||||||
{
|
|
||||||
"FilVested": "0",
|
|
||||||
"FilMined": "0",
|
|
||||||
"FilBurnt": "0",
|
|
||||||
"FilLocked": "0",
|
|
||||||
"FilCirculating": "0"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### StateCompute
|
### StateCompute
|
||||||
StateCompute is a flexible command that applies the given messages on the given tipset.
|
StateCompute is a flexible command that applies the given messages on the given tipset.
|
||||||
@ -4265,6 +4258,38 @@ Response:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### StateVMCirculatingSupply
|
||||||
|
StateVMCirculatingSupply returns an approximation of the circulating supply of Filecoin at the given tipset.
|
||||||
|
This is the value reported by the runtime interface to actors code.
|
||||||
|
|
||||||
|
|
||||||
|
Perms: read
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"FilVested": "0",
|
||||||
|
"FilMined": "0",
|
||||||
|
"FilBurnt": "0",
|
||||||
|
"FilLocked": "0",
|
||||||
|
"FilCirculating": "0"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### StateVerifiedClientStatus
|
### StateVerifiedClientStatus
|
||||||
StateVerifiedClientStatus returns the data cap for the given address.
|
StateVerifiedClientStatus returns the data cap for the given address.
|
||||||
Returns nil if there is no entry in the data cap table for the
|
Returns nil if there is no entry in the data cap table for the
|
||||||
|
@ -1049,7 +1049,7 @@ func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr
|
|||||||
return types.EmptyInt, xerrors.Errorf("loading reward actor state: %w", err)
|
return types.EmptyInt, xerrors.Errorf("loading reward actor state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
circSupply, err := a.StateCirculatingSupply(ctx, ts.Key())
|
circSupply, err := a.StateVMCirculatingSupply(ctx, ts.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return big.Zero(), xerrors.Errorf("getting circulating supply: %w", err)
|
return big.Zero(), xerrors.Errorf("getting circulating supply: %w", err)
|
||||||
}
|
}
|
||||||
@ -1203,7 +1203,7 @@ func (a *StateAPI) StateDealProviderCollateralBounds(ctx context.Context, size a
|
|||||||
return api.DealCollateralBounds{}, xerrors.Errorf("failed to load reward actor state: %w", err)
|
return api.DealCollateralBounds{}, xerrors.Errorf("failed to load reward actor state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
circ, err := a.StateCirculatingSupply(ctx, ts.Key())
|
circ, err := a.StateVMCirculatingSupply(ctx, ts.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.DealCollateralBounds{}, xerrors.Errorf("getting total circulating supply: %w", err)
|
return api.DealCollateralBounds{}, xerrors.Errorf("getting total circulating supply: %w", err)
|
||||||
}
|
}
|
||||||
@ -1231,7 +1231,20 @@ func (a *StateAPI) StateDealProviderCollateralBounds(ctx context.Context, size a
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *StateAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
|
func (a *StateAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) {
|
||||||
|
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||||
|
if err != nil {
|
||||||
|
return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sTree, err := a.stateForTs(ctx, ts)
|
||||||
|
if err != nil {
|
||||||
|
return types.EmptyInt, err
|
||||||
|
}
|
||||||
|
return a.StateManager.GetCirculatingSupply(ctx, ts.Height(), sTree)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *StateAPI) StateVMCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
|
||||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.CirculatingSupply{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
return api.CirculatingSupply{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||||
@ -1241,7 +1254,7 @@ func (a *StateAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetK
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return api.CirculatingSupply{}, err
|
return api.CirculatingSupply{}, err
|
||||||
}
|
}
|
||||||
return a.StateManager.GetCirculatingSupplyDetailed(ctx, ts.Height(), sTree)
|
return a.StateManager.GetVMCirculatingSupplyDetailed(ctx, ts.Height(), sTree)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *StateAPI) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) {
|
func (a *StateAPI) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user