Correct calculation of TotalCircSupply
This commit is contained in:
parent
58629db7f3
commit
de867d7a9a
@ -321,7 +321,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
verifNeeds := make(map[address.Address]abi.PaddedPieceSize)
|
||||
var sum abi.PaddedPieceSize
|
||||
|
||||
vm, err := vm.NewVM(stateroot, 0, &fakeRand{}, cs.Blockstore(), mkFakedSigSyscalls(cs.VMSys()))
|
||||
vm, err := vm.NewVM(stateroot, 0, &fakeRand{}, cs.Blockstore(), mkFakedSigSyscalls(cs.VMSys()), nil)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||
}
|
||||
|
@ -56,7 +56,11 @@ func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder {
|
||||
}
|
||||
|
||||
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner) (cid.Cid, error) {
|
||||
vm, err := vm.NewVM(sroot, 0, &fakeRand{}, cs.Blockstore(), mkFakedSigSyscalls(cs.VMSys()))
|
||||
vc := func(context.Context, abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
return big.Zero(), nil
|
||||
}
|
||||
|
||||
vm, err := vm.NewVM(sroot, 0, &fakeRand{}, cs.Blockstore(), mkFakedSigSyscalls(cs.VMSys()), vc)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
|
||||
ctx, span := trace.StartSpan(ctx, "statemanager.CallRaw")
|
||||
defer span.End()
|
||||
|
||||
vmi, err := vm.NewVM(bstate, bheight, r, sm.cs.Blockstore(), sm.cs.VMSys())
|
||||
vmi, err := vm.NewVM(bstate, bheight, r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||
}
|
||||
@ -106,7 +106,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
|
||||
)
|
||||
}
|
||||
|
||||
vmi, err := vm.NewVM(state, ts.Height(), r, sm.cs.Blockstore(), sm.cs.VMSys())
|
||||
vmi, err := vm.NewVM(state, ts.Height(), r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||
}
|
||||
|
@ -151,8 +151,8 @@ func TestForkHeightTriggers(t *testing.T) {
|
||||
}
|
||||
|
||||
inv.Register(builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{})
|
||||
sm.SetVMConstructor(func(c cid.Cid, h abi.ChainEpoch, r vm.Rand, b blockstore.Blockstore, s vm.SyscallBuilder) (*vm.VM, error) {
|
||||
nvm, err := vm.NewVM(c, h, r, b, s)
|
||||
sm.SetVMConstructor(func(c cid.Cid, h abi.ChainEpoch, r vm.Rand, b blockstore.Blockstore, s vm.SyscallBuilder, vc vm.VestedCalculator) (*vm.VM, error) {
|
||||
nvm, err := vm.NewVM(c, h, r, b, s, sm.GetVestedFunds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package stmgr
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@ -38,7 +39,8 @@ type StateManager struct {
|
||||
stCache map[string][]cid.Cid
|
||||
compWait map[string]chan struct{}
|
||||
stlk sync.Mutex
|
||||
newVM func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, vm.SyscallBuilder) (*vm.VM, error)
|
||||
newVM func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, vm.SyscallBuilder, vm.VestedCalculator) (*vm.VM, error)
|
||||
genesisMsigs []multisig.State
|
||||
}
|
||||
|
||||
func NewStateManager(cs *store.ChainStore) *StateManager {
|
||||
@ -147,7 +149,7 @@ type BlockMessages struct {
|
||||
type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error
|
||||
|
||||
func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback) (cid.Cid, cid.Cid, error) {
|
||||
vmi, err := sm.newVM(pstate, parentEpoch, r, sm.cs.Blockstore(), sm.cs.VMSys())
|
||||
vmi, err := sm.newVM(pstate, parentEpoch, r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
||||
if err != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
|
||||
}
|
||||
@ -777,6 +779,90 @@ func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) SetVMConstructor(nvm func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, vm.SyscallBuilder) (*vm.VM, error)) {
|
||||
func (sm *StateManager) SetVMConstructor(nvm func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, vm.SyscallBuilder, vm.VestedCalculator) (*vm.VM, error)) {
|
||||
sm.newVM = nvm
|
||||
}
|
||||
|
||||
type GenesisMsigEntry struct {
|
||||
totalFunds abi.TokenAmount
|
||||
unitVest abi.TokenAmount
|
||||
}
|
||||
|
||||
func (sm *StateManager) setupGenesisMsigs(ctx context.Context) error {
|
||||
gb, err := sm.cs.GetGenesis()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis block: %w", err)
|
||||
}
|
||||
|
||||
gts, err := types.NewTipSet([]*types.BlockHeader{gb})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis tipset: %w", err)
|
||||
}
|
||||
|
||||
st, _, err := sm.TipSetState(ctx, gts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis tipset state: %w", err)
|
||||
}
|
||||
|
||||
r, err := adt.AsMap(sm.cs.Store(ctx), st)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis actors: %w", err)
|
||||
}
|
||||
|
||||
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
|
||||
var act types.Actor
|
||||
err = r.ForEach(&act, func(k string) error {
|
||||
if act.Code == builtin.MultisigActorCodeID {
|
||||
var s multisig.State
|
||||
err := sm.cs.Store(ctx).Get(ctx, act.Head, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if s.StartEpoch != 0 {
|
||||
return xerrors.New("genesis multisig doesn't start vesting at epoch 0!")
|
||||
}
|
||||
|
||||
ot, f := totalsByEpoch[s.UnlockDuration]
|
||||
if f {
|
||||
totalsByEpoch[s.UnlockDuration] = big.Add(ot, s.InitialBalance)
|
||||
} else {
|
||||
totalsByEpoch[s.UnlockDuration] = s.InitialBalance
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error setting up composite genesis multisigs: %w", err)
|
||||
}
|
||||
|
||||
sm.genesisMsigs = make([]multisig.State, 0, len(totalsByEpoch))
|
||||
for k, v := range totalsByEpoch {
|
||||
ns := multisig.State{
|
||||
InitialBalance: v,
|
||||
UnlockDuration: k,
|
||||
PendingTxns: cid.Undef,
|
||||
}
|
||||
sm.genesisMsigs = append(sm.genesisMsigs, ns)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) GetVestedFunds(ctx context.Context, height abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
|
||||
if sm.genesisMsigs == nil {
|
||||
err := sm.setupGenesisMsigs(ctx)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to setup genesis msig entries: %w", err)
|
||||
}
|
||||
}
|
||||
vf := big.Zero()
|
||||
for _, v := range sm.genesisMsigs {
|
||||
au := big.Sub(v.InitialBalance, v.AmountLocked(height))
|
||||
vf = big.Add(vf, au)
|
||||
}
|
||||
return vf, nil
|
||||
}
|
||||
|
@ -440,7 +440,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
|
||||
}
|
||||
|
||||
r := store.NewChainRand(sm.cs, ts.Cids(), height)
|
||||
vmi, err := vm.NewVM(base, height, r, sm.cs.Blockstore(), sm.cs.VMSys())
|
||||
vmi, err := vm.NewVM(base, height, r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
||||
if err != nil {
|
||||
return cid.Undef, nil, err
|
||||
}
|
||||
@ -589,7 +589,7 @@ func (sm *StateManager) CirculatingSupply(ctx context.Context, ts *types.TipSet)
|
||||
}
|
||||
|
||||
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
|
||||
vmi, err := vm.NewVM(st, ts.Height(), r, sm.cs.Blockstore(), sm.cs.VMSys())
|
||||
vmi, err := vm.NewVM(st, ts.Height(), r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
||||
if err != nil {
|
||||
return big.Zero(), err
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
big2 "github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
@ -73,44 +72,3 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
|
||||
|
||||
return types.BigInt{Int: out}, nil
|
||||
}
|
||||
|
||||
// todo: dedupe with state manager
|
||||
func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||
bstate := ts.ParentState()
|
||||
|
||||
r := NewChainRand(cs, ts.Cids(), ts.Height())
|
||||
|
||||
vmi, err := vm.NewVM(bstate, ts.Height(), r, cs.bs, cs.vmcalls)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||
}
|
||||
|
||||
if msg.GasLimit == 0 {
|
||||
msg.GasLimit = 10000000000
|
||||
}
|
||||
if msg.GasPrice == types.EmptyInt {
|
||||
msg.GasPrice = types.NewInt(0)
|
||||
}
|
||||
if msg.Value == types.EmptyInt {
|
||||
msg.Value = types.NewInt(0)
|
||||
}
|
||||
|
||||
fromActor, err := vmi.StateTree().GetActor(msg.From)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("call raw get actor: %s", err)
|
||||
}
|
||||
|
||||
msg.Nonce = fromActor.Nonce
|
||||
|
||||
// TODO: maybe just use the invoker directly?
|
||||
// TODO: use signed message length for secp messages
|
||||
ret, err := vmi.ApplyMessage(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("apply message failed: %w", err)
|
||||
}
|
||||
|
||||
if ret.ActorErr != nil {
|
||||
log.Warnf("chain call failed: %s", ret.ActorErr)
|
||||
}
|
||||
return &ret.MessageReceipt, nil
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ func (a *Applier) applyMessage(epoch abi.ChainEpoch, lm types.ChainMsg) (vtypes.
|
||||
ctx := context.TODO()
|
||||
base := a.stateWrapper.Root()
|
||||
|
||||
lotusVM, err := vm.NewVM(base, epoch, &vmRand{}, a.stateWrapper.bs, a.syscalls)
|
||||
lotusVM, err := vm.NewVM(base, epoch, &vmRand{}, a.stateWrapper.bs, a.syscalls, nil)
|
||||
// need to modify the VM invoker to add the puppet actor
|
||||
chainValInvoker := vm.NewInvoker()
|
||||
chainValInvoker.Register(puppet.PuppetActorCodeID, puppet.Actor{}, puppet.State{})
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
samarket "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
gruntime "runtime"
|
||||
"time"
|
||||
|
||||
@ -60,38 +61,55 @@ type Runtime struct {
|
||||
}
|
||||
|
||||
func (rt *Runtime) TotalFilCircSupply() abi.TokenAmount {
|
||||
total := types.FromFil(build.TotalFilecoin)
|
||||
|
||||
filVested, err := rt.vm.GetVestedFunds(rt.ctx)
|
||||
if err != nil {
|
||||
rt.Abortf(exitcode.ErrIllegalState, "failed to get vested funds for computing total 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.TotalFilecoin), rew.Balance)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
total = types.BigSub(total, rew.Balance)
|
||||
total = types.BigSub(total, burnt.Balance)
|
||||
total = types.BigSub(total, market.Balance)
|
||||
|
||||
var st sapower.State
|
||||
if err := rt.cst.Get(rt.ctx, power.Head, &st); err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
return types.BigSub(total, st.TotalPledgeCollateral)
|
||||
filLocked := types.BigAdd(filMarketLocked, pst.TotalPledgeCollateral)
|
||||
|
||||
ret := types.BigAdd(filVested, filMined)
|
||||
ret = types.BigSub(ret, filBurned)
|
||||
ret = types.BigSub(ret, filLocked)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (rt *Runtime) ResolveAddress(addr address.Address) (ret address.Address, ok bool) {
|
||||
|
@ -138,6 +138,8 @@ 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) (abi.TokenAmount, error)
|
||||
|
||||
type VM struct {
|
||||
cstate *state.StateTree
|
||||
base cid.Cid
|
||||
@ -146,11 +148,12 @@ type VM struct {
|
||||
blockHeight abi.ChainEpoch
|
||||
inv *Invoker
|
||||
rand Rand
|
||||
vc VestedCalculator
|
||||
|
||||
Syscalls SyscallBuilder
|
||||
}
|
||||
|
||||
func NewVM(base cid.Cid, height abi.ChainEpoch, r Rand, cbs blockstore.Blockstore, syscalls SyscallBuilder) (*VM, error) {
|
||||
func NewVM(base cid.Cid, height abi.ChainEpoch, r Rand, cbs blockstore.Blockstore, syscalls SyscallBuilder, vestedCalc VestedCalculator) (*VM, error) {
|
||||
buf := bufbstore.NewBufferedBstore(cbs)
|
||||
cst := cbor.NewCborStore(buf)
|
||||
state, err := state.LoadStateTree(cst, base)
|
||||
@ -166,6 +169,7 @@ func NewVM(base cid.Cid, height abi.ChainEpoch, r Rand, cbs blockstore.Blockstor
|
||||
blockHeight: height,
|
||||
inv: NewInvoker(),
|
||||
rand: r, // TODO: Probably should be a syscall
|
||||
vc: vestedCalc,
|
||||
Syscalls: syscalls,
|
||||
}, nil
|
||||
}
|
||||
@ -662,6 +666,10 @@ 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)
|
||||
}
|
||||
|
||||
func (vm *VM) incrementNonce(addr address.Address) error {
|
||||
return vm.cstate.MutateActor(addr, func(a *types.Actor) error {
|
||||
a.Nonce++
|
||||
|
Loading…
Reference in New Issue
Block a user