Move GetCircSupply out of the vm, and into stmgr

This commit is contained in:
Aayush Rajasekaran 2020-08-09 18:49:38 -04:00
parent 5933e64de1
commit fe2da35a45
9 changed files with 181 additions and 171 deletions

View File

@ -323,13 +323,13 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
var sum abi.PaddedPieceSize
vmopt := vm.VMOpts{
StateBase: stateroot,
Epoch: 0,
Rand: &fakeRand{},
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
VestedCalc: nil,
BaseFee: types.NewInt(0),
StateBase: stateroot,
Epoch: 0,
Rand: &fakeRand{},
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
CircSupplyCalc: nil,
BaseFee: types.NewInt(0),
}
vm, err := vm.NewVM(&vmopt)
if err != nil {

View File

@ -57,18 +57,18 @@ func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder {
}
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner) (cid.Cid, error) {
vc := func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) {
csc := func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) {
return big.Zero(), nil
}
vmopt := &vm.VMOpts{
StateBase: sroot,
Epoch: 0,
Rand: &fakeRand{},
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
VestedCalc: vc,
BaseFee: types.NewInt(0),
StateBase: sroot,
Epoch: 0,
Rand: &fakeRand{},
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
CircSupplyCalc: csc,
BaseFee: types.NewInt(0),
}
vm, err := vm.NewVM(vmopt)

View File

@ -23,13 +23,13 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
defer span.End()
vmopt := &vm.VMOpts{
StateBase: bstate,
Epoch: bheight,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: types.NewInt(0),
StateBase: bstate,
Epoch: bheight,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
BaseFee: types.NewInt(0),
}
vmi, err := vm.NewVM(vmopt)
@ -124,13 +124,13 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
}
vmopt := &vm.VMOpts{
StateBase: state,
Epoch: ts.Height() + 1,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: ts.Blocks()[0].ParentBaseFee,
StateBase: state,
Epoch: ts.Height() + 1,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
if err != nil {

View File

@ -3,6 +3,7 @@ package stmgr
import (
"context"
"fmt"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"sync"
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
@ -148,13 +149,13 @@ type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error
func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []store.BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback, baseFee abi.TokenAmount) (cid.Cid, cid.Cid, error) {
vmopt := &vm.VMOpts{
StateBase: pstate,
Epoch: epoch,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: baseFee,
StateBase: pstate,
Epoch: epoch,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
BaseFee: baseFee,
}
vmi, err := sm.newVM(vmopt)
@ -873,7 +874,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
// GetVestedFunds returns all funds that have "left" actors that are in the genesis state:
// - For Multisigs, it counts the actual amounts that have vested at the given epoch
// - For Accounts, it counts max(currentBalance - genesisBalance, 0).
func (sm *StateManager) GetVestedFunds(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
sm.genesisMsigLk.Lock()
defer sm.genesisMsigLk.Unlock()
if sm.genesisMsigs == nil || sm.genesisActors == nil {
@ -903,3 +904,84 @@ func (sm *StateManager) GetVestedFunds(ctx context.Context, height abi.ChainEpoc
return vf, nil
}
func GetFilMined(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
rew, err := st.GetActor(builtin.RewardActorAddr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load reward actor state: %w", err)
}
fm := types.BigSub(types.FromFil(build.FilAllocStorageMining), rew.Balance)
if fm.LessThan(big.Zero()) {
fm = big.Zero()
}
return fm, nil
}
func GetFilLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
mactor, 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 {
return big.Zero(), xerrors.Errorf("failed to load market state: %w", err)
}
filMarketLocked := types.BigAdd(mst.TotalClientLockedCollateral, mst.TotalProviderLockedCollateral)
filMarketLocked = types.BigAdd(filMarketLocked, mst.TotalClientStorageFee)
pactor, err := st.GetActor(builtin.StoragePowerActorAddr)
if err != nil {
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 {
return big.Zero(), xerrors.Errorf("failed to load power state: %w", err)
}
return types.BigAdd(filMarketLocked, pst.TotalPledgeCollateral), nil
}
func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
burnt, err := st.GetActor(builtin.BurntFundsActorAddr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load burnt actor: %w", err)
}
return burnt.Balance, nil
}
func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
filVested, err := sm.GetFilVested(ctx, height, st)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to calculate filVested: %w", err)
}
filMined, err := GetFilMined(ctx, st)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to calculate filMined: %w", err)
}
filBurnt, err := GetFilBurnt(ctx, st)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to calculate filBurnt: %w", err)
}
filLocked, err := GetFilLocked(ctx, st)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to calculate filLocked: %w", err)
}
ret := types.BigAdd(filVested, filMined)
ret = types.BigSub(ret, filBurnt)
ret = types.BigSub(ret, filLocked)
if ret.LessThan(big.Zero()) {
ret = big.Zero()
}
return ret, nil
}

View File

@ -441,13 +441,13 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
r := store.NewChainRand(sm.cs, ts.Cids(), height)
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: height,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: ts.Blocks()[0].ParentBaseFee,
StateBase: base,
Epoch: height,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
if err != nil {
@ -605,13 +605,13 @@ func (sm *StateManager) CirculatingSupply(ctx context.Context, ts *types.TipSet)
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
vmopt := &vm.VMOpts{
StateBase: st,
Epoch: ts.Height(),
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: ts.Blocks()[0].ParentBaseFee,
StateBase: st,
Epoch: ts.Height(),
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
if err != nil {
@ -693,30 +693,3 @@ func MinerHasMinPower(ctx context.Context, sm *StateManager, addr address.Addres
return ps.MinerNominalPowerMeetsConsensusMinimum(sm.ChainStore().Store(ctx), addr)
}
func GetCirculatingSupply(ctx context.Context, sm *StateManager, ts *types.TipSet) (abi.TokenAmount, error) {
if ts == nil {
ts = sm.cs.GetHeaviestTipSet()
}
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
vmopt := &vm.VMOpts{
StateBase: ts.ParentState(),
Epoch: ts.Height(),
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
if err != nil {
return abi.NewTokenAmount(0), err
}
uvm := &vm.UnsafeVM{vmi}
rt := uvm.MakeRuntime(ctx, &types.Message{From: builtin.InitActorAddr, GasLimit: 10000000}, builtin.InitActorAddr, 0, 0, 0)
return rt.TotalFilCircSupply(), nil
}

View File

@ -148,13 +148,13 @@ func (a *Applier) applyMessage(epoch abi.ChainEpoch, lm types.ChainMsg) (vtypes.
base := a.stateWrapper.Root()
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: epoch,
Rand: &vmRand{},
Bstore: a.stateWrapper.bs,
Syscalls: a.syscalls,
VestedCalc: nil,
BaseFee: abi.NewTokenAmount(100),
StateBase: base,
Epoch: epoch,
Rand: &vmRand{},
Bstore: a.stateWrapper.bs,
Syscalls: a.syscalls,
CircSupplyCalc: nil,
BaseFee: abi.NewTokenAmount(100),
}
lotusVM, err := vm.NewVM(vmopt)

View File

@ -8,13 +8,10 @@ import (
gruntime "runtime"
"time"
samarket "github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
sapower "github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime"
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
@ -61,62 +58,12 @@ type Runtime struct {
}
func (rt *Runtime) TotalFilCircSupply() abi.TokenAmount {
filVested, err := rt.vm.GetVestedFunds(rt.ctx)
cs, err := rt.vm.GetCircSupply(rt.ctx)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get vested funds for computing total supply: %s", err)
rt.Abortf(exitcode.ErrIllegalState, "failed to get total circ supply: %s", err)
}
rew, err := rt.state.GetActor(builtin.RewardActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
filMined := types.BigSub(types.FromFil(build.FilAllocStorageMining), rew.Balance)
if filMined.LessThan(big.Zero()) {
filMined = big.Zero()
}
burnt, err := rt.state.GetActor(builtin.BurntFundsActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
filBurned := burnt.Balance
market, err := rt.state.GetActor(builtin.StorageMarketActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
var mst samarket.State
if err := rt.cst.Get(rt.ctx, market.Head, &mst); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get market state: %s", err)
}
filMarketLocked := types.BigAdd(mst.TotalClientLockedCollateral, mst.TotalProviderLockedCollateral)
filMarketLocked = types.BigAdd(filMarketLocked, mst.TotalClientStorageFee)
power, err := rt.state.GetActor(builtin.StoragePowerActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
var pst sapower.State
if err := rt.cst.Get(rt.ctx, power.Head, &pst); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get storage power state: %s", err)
}
filLocked := types.BigAdd(filMarketLocked, pst.TotalPledgeCollateral)
ret := types.BigAdd(filVested, filMined)
ret = types.BigSub(ret, filBurned)
ret = types.BigSub(ret, filLocked)
if ret.LessThan(big.Zero()) {
ret = big.Zero()
}
return ret
return cs
}
func (rt *Runtime) ResolveAddress(addr address.Address) (ret address.Address, ok bool) {

View File

@ -140,30 +140,30 @@ func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message, origin
return vm.VM.makeRuntime(ctx, msg, origin, originNonce, usedGas, nac)
}
type VestedCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
type VM struct {
cstate *state.StateTree
base cid.Cid
cst *cbor.BasicIpldStore
buf *bufbstore.BufferedBS
blockHeight abi.ChainEpoch
inv *Invoker
rand Rand
vc VestedCalculator
baseFee abi.TokenAmount
cstate *state.StateTree
base cid.Cid
cst *cbor.BasicIpldStore
buf *bufbstore.BufferedBS
blockHeight abi.ChainEpoch
inv *Invoker
rand Rand
circSupplyCalc CircSupplyCalculator
baseFee abi.TokenAmount
Syscalls SyscallBuilder
}
type VMOpts struct {
StateBase cid.Cid
Epoch abi.ChainEpoch
Rand Rand
Bstore bstore.Blockstore
Syscalls SyscallBuilder
VestedCalc VestedCalculator
BaseFee abi.TokenAmount
StateBase cid.Cid
Epoch abi.ChainEpoch
Rand Rand
Bstore bstore.Blockstore
Syscalls SyscallBuilder
CircSupplyCalc CircSupplyCalculator
BaseFee abi.TokenAmount
}
func NewVM(opts *VMOpts) (*VM, error) {
@ -175,16 +175,16 @@ func NewVM(opts *VMOpts) (*VM, error) {
}
return &VM{
cstate: state,
base: opts.StateBase,
cst: cst,
buf: buf,
blockHeight: opts.Epoch,
inv: NewInvoker(),
rand: opts.Rand, // TODO: Probably should be a syscall
vc: opts.VestedCalc,
Syscalls: opts.Syscalls,
baseFee: opts.BaseFee,
cstate: state,
base: opts.StateBase,
cst: cst,
buf: buf,
blockHeight: opts.Epoch,
inv: NewInvoker(),
rand: opts.Rand, // TODO: Probably should be a syscall
circSupplyCalc: opts.CircSupplyCalc,
Syscalls: opts.Syscalls,
baseFee: opts.BaseFee,
}, nil
}
@ -714,8 +714,8 @@ func (vm *VM) SetInvoker(i *Invoker) {
vm.inv = i
}
func (vm *VM) GetVestedFunds(ctx context.Context) (abi.TokenAmount, error) {
return vm.vc(ctx, vm.blockHeight, vm.cstate)
func (vm *VM) GetCircSupply(ctx context.Context) (abi.TokenAmount, error) {
return vm.circSupplyCalc(ctx, vm.blockHeight, vm.cstate)
}
func (vm *VM) incrementNonce(addr address.Address) error {

View File

@ -1193,5 +1193,13 @@ func (a *StateAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSetK
return abi.TokenAmount{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
return stmgr.GetCirculatingSupply(ctx, a.StateManager, ts)
st, _, err := a.StateManager.TipSetState(ctx, ts)
if err != nil {
return big.Zero(), err
}
cst := cbor.NewCborStore(a.Chain.Blockstore())
sTree, err := state.LoadStateTree(cst, st)
return a.StateManager.GetCirculatingSupply(ctx, ts.Height(), sTree)
}