Merge pull request #8332 from filecoin-project/feat/fvm
FVM integration
This commit is contained in:
commit
ff244fba6c
@ -2,6 +2,7 @@ package filcns
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"os"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/rand"
|
"github.com/filecoin-project/lotus/chain/rand"
|
||||||
@ -94,7 +95,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
ctx = blockstore.WithHotView(ctx)
|
ctx = blockstore.WithHotView(ctx)
|
||||||
makeVmWithBaseStateAndEpoch := func(base cid.Cid, e abi.ChainEpoch) (*vm.VM, error) {
|
makeVmWithBaseStateAndEpoch := func(base cid.Cid, e abi.ChainEpoch) (vm.Interface, error) {
|
||||||
vmopt := &vm.VMOpts{
|
vmopt := &vm.VMOpts{
|
||||||
StateBase: base,
|
StateBase: base,
|
||||||
Epoch: e,
|
Epoch: e,
|
||||||
@ -108,10 +109,23 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
|
|||||||
LookbackState: stmgr.LookbackStateGetterForTipset(sm, ts),
|
LookbackState: stmgr.LookbackStateGetterForTipset(sm, ts),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if os.Getenv("LOTUS_USE_FVM_EXPERIMENTAL") == "1" {
|
||||||
|
// This is needed so that the FVM does not have to duplicate the genesis vesting schedule, one
|
||||||
|
// of the components of the circ supply calc.
|
||||||
|
// This field is NOT needed by the LegacyVM, and also NOT needed by the FVM from v15 onwards.
|
||||||
|
filVested, err := sm.GetFilVested(ctx, e)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
vmopt.FilVested = filVested
|
||||||
|
return vm.NewFVM(ctx, vmopt)
|
||||||
|
}
|
||||||
|
|
||||||
return sm.VMConstructor()(ctx, vmopt)
|
return sm.VMConstructor()(ctx, vmopt)
|
||||||
}
|
}
|
||||||
|
|
||||||
runCron := func(vmCron *vm.VM, epoch abi.ChainEpoch) error {
|
runCron := func(vmCron vm.Interface, epoch abi.ChainEpoch) error {
|
||||||
cronMsg := &types.Message{
|
cronMsg := &types.Message{
|
||||||
To: cron.Address,
|
To: cron.Address,
|
||||||
From: builtin.SystemActorAddr,
|
From: builtin.SystemActorAddr,
|
||||||
|
@ -491,12 +491,13 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, sys vm.Sysca
|
|||||||
Actors: filcns.NewActorRegistry(),
|
Actors: filcns.NewActorRegistry(),
|
||||||
Syscalls: mkFakedSigSyscalls(sys),
|
Syscalls: mkFakedSigSyscalls(sys),
|
||||||
CircSupplyCalc: csc,
|
CircSupplyCalc: csc,
|
||||||
|
FilVested: big.Zero(),
|
||||||
NetworkVersion: nv,
|
NetworkVersion: nv,
|
||||||
BaseFee: types.NewInt(0),
|
BaseFee: big.Zero(),
|
||||||
}
|
}
|
||||||
vm, err := vm.NewVM(ctx, &vmopt)
|
vm, err := vm.NewLegacyVM(ctx, &vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create NewLegacyVM: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for mi, m := range template.Miners {
|
for mi, m := range template.Miners {
|
||||||
|
@ -95,12 +95,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
|
|||||||
Syscalls: mkFakedSigSyscalls(sys),
|
Syscalls: mkFakedSigSyscalls(sys),
|
||||||
CircSupplyCalc: csc,
|
CircSupplyCalc: csc,
|
||||||
NetworkVersion: nv,
|
NetworkVersion: nv,
|
||||||
BaseFee: types.NewInt(0),
|
BaseFee: big.Zero(),
|
||||||
|
FilVested: big.Zero(),
|
||||||
}
|
}
|
||||||
|
|
||||||
vm, err := vm.NewVM(ctx, vmopt)
|
vm, err := vm.NewLegacyVM(ctx, vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create NewLegacyVM: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(miners) == 0 {
|
if len(miners) == 0 {
|
||||||
@ -520,7 +521,7 @@ func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization cry
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
|
func currentTotalPower(ctx context.Context, vm *vm.LegacyVM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
|
||||||
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin0.MethodsPower.CurrentTotalPower, nil)
|
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin0.MethodsPower.CurrentTotalPower, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -533,7 +534,7 @@ func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*
|
|||||||
return &pwr, nil
|
return &pwr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch, av actors.Version) (abi.DealWeight, abi.DealWeight, error) {
|
func dealWeight(ctx context.Context, vm *vm.LegacyVM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch, av actors.Version) (abi.DealWeight, abi.DealWeight, error) {
|
||||||
// TODO: This hack should move to market actor wrapper
|
// TODO: This hack should move to market actor wrapper
|
||||||
if av <= actors.Version2 {
|
if av <= actors.Version2 {
|
||||||
params := &market0.VerifyDealsForActivationParams{
|
params := &market0.VerifyDealsForActivationParams{
|
||||||
@ -593,7 +594,7 @@ func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs [
|
|||||||
return dealWeights.Sectors[0].DealWeight, dealWeights.Sectors[0].VerifiedDealWeight, nil
|
return dealWeights.Sectors[0].DealWeight, dealWeights.Sectors[0].VerifiedDealWeight, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address, av actors.Version) (abi.StoragePower, builtin.FilterEstimate, error) {
|
func currentEpochBlockReward(ctx context.Context, vm *vm.LegacyVM, maddr address.Address, av actors.Version) (abi.StoragePower, builtin.FilterEstimate, error) {
|
||||||
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), reward.Methods.ThisEpochReward, nil)
|
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), reward.Methods.ThisEpochReward, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return big.Zero(), builtin.FilterEstimate{}, err
|
return big.Zero(), builtin.FilterEstimate{}, err
|
||||||
@ -628,7 +629,7 @@ func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Addre
|
|||||||
return epochReward.ThisEpochBaselinePower, builtin.FilterEstimate(epochReward.ThisEpochRewardSmoothed), nil
|
return epochReward.ThisEpochBaselinePower, builtin.FilterEstimate(epochReward.ThisEpochRewardSmoothed), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.TokenAmount {
|
func circSupply(ctx context.Context, vmi *vm.LegacyVM, maddr address.Address) abi.TokenAmount {
|
||||||
unsafeVM := &vm.UnsafeVM{VM: vmi}
|
unsafeVM := &vm.UnsafeVM{VM: vmi}
|
||||||
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
|
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
|
||||||
GasLimit: 1_000_000_000,
|
GasLimit: 1_000_000_000,
|
||||||
|
@ -21,7 +21,7 @@ func mustEnc(i cbg.CBORMarshaler) []byte {
|
|||||||
return enc
|
return enc
|
||||||
}
|
}
|
||||||
|
|
||||||
func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value types.BigInt, method abi.MethodNum, params []byte) ([]byte, error) {
|
func doExecValue(ctx context.Context, vm *vm.LegacyVM, to, from address.Address, value types.BigInt, method abi.MethodNum, params []byte) ([]byte, error) {
|
||||||
act, err := vm.StateTree().GetActor(from)
|
act, err := vm.StateTree().GetActor(from)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("doExec failed to get from actor (%s): %w", from, err)
|
return nil, xerrors.Errorf("doExec failed to get from actor (%s): %w", from, err)
|
||||||
|
@ -5,6 +5,12 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/blockstore"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/rand"
|
"github.com/filecoin-project/lotus/chain/rand"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
@ -64,6 +70,8 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
|
|||||||
pheight = ts.Height() - 1
|
pheight = ts.Height() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since we're simulating a future message, pretend we're applying it in the "next" tipset
|
||||||
|
vmHeight := pheight + 1
|
||||||
bstate := ts.ParentState()
|
bstate := ts.ParentState()
|
||||||
|
|
||||||
// Run the (not expensive) migration.
|
// Run the (not expensive) migration.
|
||||||
@ -72,9 +80,14 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
|
|||||||
return nil, fmt.Errorf("failed to handle fork: %w", err)
|
return nil, fmt.Errorf("failed to handle fork: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filVested, err := sm.GetFilVested(ctx, vmHeight)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
vmopt := &vm.VMOpts{
|
vmopt := &vm.VMOpts{
|
||||||
StateBase: bstate,
|
StateBase: bstate,
|
||||||
Epoch: pheight + 1,
|
Epoch: vmHeight,
|
||||||
Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion),
|
Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion),
|
||||||
Bstore: sm.cs.StateBlockstore(),
|
Bstore: sm.cs.StateBlockstore(),
|
||||||
Actors: sm.tsExec.NewActorRegistry(),
|
Actors: sm.tsExec.NewActorRegistry(),
|
||||||
@ -82,6 +95,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
|
|||||||
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
||||||
NetworkVersion: sm.GetNetworkVersion(ctx, pheight+1),
|
NetworkVersion: sm.GetNetworkVersion(ctx, pheight+1),
|
||||||
BaseFee: types.NewInt(0),
|
BaseFee: types.NewInt(0),
|
||||||
|
FilVested: filVested,
|
||||||
LookbackState: LookbackStateGetterForTipset(sm, ts),
|
LookbackState: LookbackStateGetterForTipset(sm, ts),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +126,12 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fromActor, err := vmi.StateTree().GetActor(msg.From)
|
stTree, err := sm.StateTree(bstate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to load state tree: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fromActor, err := stTree.GetActor(msg.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("call raw get actor: %s", err)
|
return nil, xerrors.Errorf("call raw get actor: %s", err)
|
||||||
}
|
}
|
||||||
@ -175,13 +194,16 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state, _, err := sm.TipSetState(ctx, ts)
|
// Since we're simulating a future message, pretend we're applying it in the "next" tipset
|
||||||
|
vmHeight := ts.Height() + 1
|
||||||
|
|
||||||
|
stateCid, _, err := sm.TipSetState(ctx, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("computing tipset state: %w", err)
|
return nil, xerrors.Errorf("computing tipset state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Technically, the tipset we're passing in here should be ts+1, but that may not exist.
|
// Technically, the tipset we're passing in here should be ts+1, but that may not exist.
|
||||||
state, err = sm.HandleStateForks(ctx, state, ts.Height(), nil, ts)
|
stateCid, err = sm.HandleStateForks(ctx, stateCid, ts.Height(), nil, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to handle fork: %w", err)
|
return nil, fmt.Errorf("failed to handle fork: %w", err)
|
||||||
}
|
}
|
||||||
@ -196,16 +218,23 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filVested, err := sm.GetFilVested(ctx, vmHeight)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buffStore := blockstore.NewBuffered(sm.cs.StateBlockstore())
|
||||||
vmopt := &vm.VMOpts{
|
vmopt := &vm.VMOpts{
|
||||||
StateBase: state,
|
StateBase: stateCid,
|
||||||
Epoch: ts.Height() + 1,
|
Epoch: vmHeight,
|
||||||
Rand: r,
|
Rand: r,
|
||||||
Bstore: sm.cs.StateBlockstore(),
|
Bstore: buffStore,
|
||||||
Actors: sm.tsExec.NewActorRegistry(),
|
Actors: sm.tsExec.NewActorRegistry(),
|
||||||
Syscalls: sm.Syscalls,
|
Syscalls: sm.Syscalls,
|
||||||
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
||||||
NetworkVersion: sm.GetNetworkVersion(ctx, ts.Height()+1),
|
NetworkVersion: sm.GetNetworkVersion(ctx, ts.Height()+1),
|
||||||
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
||||||
|
FilVested: filVested,
|
||||||
LookbackState: LookbackStateGetterForTipset(sm, ts),
|
LookbackState: LookbackStateGetterForTipset(sm, ts),
|
||||||
}
|
}
|
||||||
vmi, err := sm.newVM(ctx, vmopt)
|
vmi, err := sm.newVM(ctx, vmopt)
|
||||||
@ -219,7 +248,19 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fromActor, err := vmi.StateTree().GetActor(msg.From)
|
// We flush to get the VM's view of the state tree after applying the above messages
|
||||||
|
// This is needed to get the correct nonce from the actor state to match the VM
|
||||||
|
stateCid, err = vmi.Flush(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("flushing vm: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stTree, err := state.LoadStateTree(cbor.NewCborStore(buffStore), stateCid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("loading state tree: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fromActor, err := stTree.GetActor(msg.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("call raw get actor: %s", err)
|
return nil, xerrors.Errorf("call raw get actor: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -166,8 +166,8 @@ func TestForkHeightTriggers(t *testing.T) {
|
|||||||
inv := filcns.NewActorRegistry()
|
inv := filcns.NewActorRegistry()
|
||||||
inv.Register(nil, testActor{})
|
inv.Register(nil, testActor{})
|
||||||
|
|
||||||
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) {
|
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
|
||||||
nvm, err := vm.NewVM(ctx, vmopt)
|
nvm, err := vm.NewLegacyVM(ctx, vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -281,8 +281,8 @@ func testForkRefuseCall(t *testing.T, nullsBefore, nullsAfter int) {
|
|||||||
inv := filcns.NewActorRegistry()
|
inv := filcns.NewActorRegistry()
|
||||||
inv.Register(nil, testActor{})
|
inv.Register(nil, testActor{})
|
||||||
|
|
||||||
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) {
|
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
|
||||||
nvm, err := vm.NewVM(ctx, vmopt)
|
nvm, err := vm.NewLegacyVM(ctx, vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -500,8 +500,8 @@ func TestForkPreMigration(t *testing.T) {
|
|||||||
inv := filcns.NewActorRegistry()
|
inv := filcns.NewActorRegistry()
|
||||||
inv.Register(nil, testActor{})
|
inv.Register(nil, testActor{})
|
||||||
|
|
||||||
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) {
|
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
|
||||||
nvm, err := vm.NewVM(ctx, vmopt)
|
nvm, err := vm.NewLegacyVM(ctx, vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ type StateManager struct {
|
|||||||
compWait map[string]chan struct{}
|
compWait map[string]chan struct{}
|
||||||
stlk sync.Mutex
|
stlk sync.Mutex
|
||||||
genesisMsigLk sync.Mutex
|
genesisMsigLk sync.Mutex
|
||||||
newVM func(context.Context, *vm.VMOpts) (*vm.VM, error)
|
newVM func(context.Context, *vm.VMOpts) (vm.Interface, error)
|
||||||
Syscalls vm.SyscallBuilder
|
Syscalls vm.SyscallBuilder
|
||||||
preIgnitionVesting []msig0.State
|
preIgnitionVesting []msig0.State
|
||||||
postIgnitionVesting []msig0.State
|
postIgnitionVesting []msig0.State
|
||||||
@ -347,12 +347,12 @@ func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) SetVMConstructor(nvm func(context.Context, *vm.VMOpts) (*vm.VM, error)) {
|
func (sm *StateManager) SetVMConstructor(nvm func(context.Context, *vm.VMOpts) (vm.Interface, error)) {
|
||||||
sm.newVM = nvm
|
sm.newVM = nvm
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) VMConstructor() func(context.Context, *vm.VMOpts) (*vm.VM, error) {
|
func (sm *StateManager) VMConstructor() func(context.Context, *vm.VMOpts) (vm.Interface, error) {
|
||||||
return func(ctx context.Context, opts *vm.VMOpts) (*vm.VM, error) {
|
return func(ctx context.Context, opts *vm.VMOpts) (vm.Interface, error) {
|
||||||
return sm.newVM(ctx, opts)
|
return sm.newVM(ctx, opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,8 +196,32 @@ func (sm *StateManager) setupPostCalicoVesting(ctx context.Context) error {
|
|||||||
// GetVestedFunds returns all funds that have "left" actors that are in the genesis state:
|
// 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 Multisigs, it counts the actual amounts that have vested at the given epoch
|
||||||
// - For Accounts, it counts max(currentBalance - genesisBalance, 0).
|
// - For Accounts, it counts max(currentBalance - genesisBalance, 0).
|
||||||
func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
|
func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||||
vf := big.Zero()
|
vf := big.Zero()
|
||||||
|
|
||||||
|
sm.genesisMsigLk.Lock()
|
||||||
|
defer sm.genesisMsigLk.Unlock()
|
||||||
|
|
||||||
|
// TODO: combine all this?
|
||||||
|
if sm.preIgnitionVesting == nil || sm.genesisPledge.IsZero() || sm.genesisMarketFunds.IsZero() {
|
||||||
|
err := sm.setupGenesisVestingSchedule(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return vf, xerrors.Errorf("failed to setup pre-ignition vesting schedule: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sm.postIgnitionVesting == nil {
|
||||||
|
err := sm.setupPostIgnitionVesting(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return vf, xerrors.Errorf("failed to setup post-ignition vesting schedule: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sm.postCalicoVesting == nil {
|
||||||
|
err := sm.setupPostCalicoVesting(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return vf, xerrors.Errorf("failed to setup post-calico vesting schedule: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if height <= build.UpgradeIgnitionHeight {
|
if height <= build.UpgradeIgnitionHeight {
|
||||||
for _, v := range sm.preIgnitionVesting {
|
for _, v := range sm.preIgnitionVesting {
|
||||||
au := big.Sub(v.InitialBalance, v.AmountLocked(height))
|
au := big.Sub(v.InitialBalance, v.AmountLocked(height))
|
||||||
@ -282,7 +306,7 @@ func getFilPowerLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmoun
|
|||||||
return pst.TotalLocked()
|
return pst.TotalLocked()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) GetFilLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
func GetFilLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
|
||||||
|
|
||||||
filMarketLocked, err := getFilMarketLocked(ctx, st)
|
filMarketLocked, err := getFilMarketLocked(ctx, st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -316,28 +340,7 @@ func (sm *StateManager) GetVMCirculatingSupply(ctx context.Context, height abi.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) GetVMCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (api.CirculatingSupply, error) {
|
func (sm *StateManager) GetVMCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (api.CirculatingSupply, error) {
|
||||||
sm.genesisMsigLk.Lock()
|
filVested, err := sm.GetFilVested(ctx, height)
|
||||||
defer sm.genesisMsigLk.Unlock()
|
|
||||||
if sm.preIgnitionVesting == nil || sm.genesisPledge.IsZero() || sm.genesisMarketFunds.IsZero() {
|
|
||||||
err := sm.setupGenesisVestingSchedule(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup pre-ignition vesting schedule: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if sm.postIgnitionVesting == nil {
|
|
||||||
err := sm.setupPostIgnitionVesting(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup post-ignition vesting schedule: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if sm.postCalicoVesting == nil {
|
|
||||||
err := sm.setupPostCalicoVesting(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup post-calico vesting schedule: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filVested, err := sm.GetFilVested(ctx, height, st)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filVested: %w", err)
|
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filVested: %w", err)
|
||||||
}
|
}
|
||||||
@ -360,7 +363,7 @@ func (sm *StateManager) GetVMCirculatingSupplyDetailed(ctx context.Context, heig
|
|||||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filBurnt: %w", err)
|
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filBurnt: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
filLocked, err := sm.GetFilLocked(ctx, st)
|
filLocked, err := GetFilLocked(ctx, st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filLocked: %w", err)
|
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filLocked: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,11 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
|
|||||||
// future. It's not guaranteed to be accurate... but that's fine.
|
// future. It's not guaranteed to be accurate... but that's fine.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filVested, err := sm.GetFilVested(ctx, height)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion)
|
r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion)
|
||||||
vmopt := &vm.VMOpts{
|
vmopt := &vm.VMOpts{
|
||||||
StateBase: base,
|
StateBase: base,
|
||||||
@ -90,6 +95,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
|
|||||||
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
||||||
NetworkVersion: sm.GetNetworkVersion(ctx, height),
|
NetworkVersion: sm.GetNetworkVersion(ctx, height),
|
||||||
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
||||||
|
FilVested: filVested,
|
||||||
LookbackState: LookbackStateGetterForTipset(sm, ts),
|
LookbackState: LookbackStateGetterForTipset(sm, ts),
|
||||||
}
|
}
|
||||||
vmi, err := sm.newVM(ctx, vmopt)
|
vmi, err := sm.newVM(ctx, vmopt)
|
||||||
|
312
chain/vm/fvm.go
Normal file
312
chain/vm/fvm.go
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
package vm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/blockstore"
|
||||||
|
|
||||||
|
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||||
|
ffi_cgo "github.com/filecoin-project/filecoin-ffi/cgo"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ Interface = (*FVM)(nil)
|
||||||
|
var _ ffi_cgo.Externs = (*FvmExtern)(nil)
|
||||||
|
|
||||||
|
type FvmExtern struct {
|
||||||
|
Rand
|
||||||
|
blockstore.Blockstore
|
||||||
|
epoch abi.ChainEpoch
|
||||||
|
lbState LookbackStateGetter
|
||||||
|
base cid.Cid
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyConsensusFault is similar to the one in syscalls.go used by the LegacyVM, except it never errors
|
||||||
|
// Errors are logged and "no fault" is returned, which is functionally what go-actors does anyway
|
||||||
|
func (x *FvmExtern) VerifyConsensusFault(ctx context.Context, a, b, extra []byte) (*ffi_cgo.ConsensusFault, int64) {
|
||||||
|
totalGas := int64(0)
|
||||||
|
ret := &ffi_cgo.ConsensusFault{
|
||||||
|
Type: ffi_cgo.ConsensusFaultNone,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that block syntax is not validated. Any validly signed block will be accepted pursuant to the below conditions.
|
||||||
|
// Whether or not it could ever have been accepted in a chain is not checked/does not matter here.
|
||||||
|
// for that reason when checking block parent relationships, rather than instantiating a Tipset to do so
|
||||||
|
// (which runs a syntactic check), we do it directly on the CIDs.
|
||||||
|
|
||||||
|
// (0) cheap preliminary checks
|
||||||
|
|
||||||
|
// can blocks be decoded properly?
|
||||||
|
var blockA, blockB types.BlockHeader
|
||||||
|
if decodeErr := blockA.UnmarshalCBOR(bytes.NewReader(a)); decodeErr != nil {
|
||||||
|
log.Info("invalid consensus fault: cannot decode first block header: %w", decodeErr)
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
|
||||||
|
if decodeErr := blockB.UnmarshalCBOR(bytes.NewReader(b)); decodeErr != nil {
|
||||||
|
log.Info("invalid consensus fault: cannot decode second block header: %w", decodeErr)
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
|
||||||
|
// are blocks the same?
|
||||||
|
if blockA.Cid().Equals(blockB.Cid()) {
|
||||||
|
log.Info("invalid consensus fault: submitted blocks are the same")
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
// (1) check conditions necessary to any consensus fault
|
||||||
|
|
||||||
|
// were blocks mined by same miner?
|
||||||
|
if blockA.Miner != blockB.Miner {
|
||||||
|
log.Info("invalid consensus fault: blocks not mined by the same miner")
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
|
||||||
|
// block a must be earlier or equal to block b, epoch wise (ie at least as early in the chain).
|
||||||
|
if blockB.Height < blockA.Height {
|
||||||
|
log.Info("invalid consensus fault: first block must not be of higher height than second")
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.Epoch = blockB.Height
|
||||||
|
|
||||||
|
faultType := ffi_cgo.ConsensusFaultNone
|
||||||
|
|
||||||
|
// (2) check for the consensus faults themselves
|
||||||
|
// (a) double-fork mining fault
|
||||||
|
if blockA.Height == blockB.Height {
|
||||||
|
faultType = ffi_cgo.ConsensusFaultDoubleForkMining
|
||||||
|
}
|
||||||
|
|
||||||
|
// (b) time-offset mining fault
|
||||||
|
// strictly speaking no need to compare heights based on double fork mining check above,
|
||||||
|
// but at same height this would be a different fault.
|
||||||
|
if types.CidArrsEqual(blockA.Parents, blockB.Parents) && blockA.Height != blockB.Height {
|
||||||
|
faultType = ffi_cgo.ConsensusFaultTimeOffsetMining
|
||||||
|
}
|
||||||
|
|
||||||
|
// (c) parent-grinding fault
|
||||||
|
// Here extra is the "witness", a third block that shows the connection between A and B as
|
||||||
|
// A's sibling and B's parent.
|
||||||
|
// Specifically, since A is of lower height, it must be that B was mined omitting A from its tipset
|
||||||
|
//
|
||||||
|
// B
|
||||||
|
// |
|
||||||
|
// [A, C]
|
||||||
|
var blockC types.BlockHeader
|
||||||
|
if len(extra) > 0 {
|
||||||
|
if decodeErr := blockC.UnmarshalCBOR(bytes.NewReader(extra)); decodeErr != nil {
|
||||||
|
log.Info("invalid consensus fault: cannot decode extra: %w", decodeErr)
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
|
||||||
|
if types.CidArrsEqual(blockA.Parents, blockC.Parents) && blockA.Height == blockC.Height &&
|
||||||
|
types.CidArrsContains(blockB.Parents, blockC.Cid()) && !types.CidArrsContains(blockB.Parents, blockA.Cid()) {
|
||||||
|
faultType = ffi_cgo.ConsensusFaultParentGrinding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// (3) return if no consensus fault by now
|
||||||
|
if faultType == ffi_cgo.ConsensusFaultNone {
|
||||||
|
log.Info("invalid consensus fault: no fault detected")
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
|
||||||
|
// else
|
||||||
|
// (4) expensive final checks
|
||||||
|
|
||||||
|
// check blocks are properly signed by their respective miner
|
||||||
|
// note we do not need to check extra's: it is a parent to block b
|
||||||
|
// which itself is signed, so it was willingly included by the miner
|
||||||
|
gasA, sigErr := x.VerifyBlockSig(ctx, &blockA)
|
||||||
|
totalGas += gasA
|
||||||
|
if sigErr != nil {
|
||||||
|
log.Info("invalid consensus fault: cannot verify first block sig: %w", sigErr)
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
|
||||||
|
gas2, sigErr := x.VerifyBlockSig(ctx, &blockB)
|
||||||
|
totalGas += gas2
|
||||||
|
if sigErr != nil {
|
||||||
|
log.Info("invalid consensus fault: cannot verify second block sig: %w", sigErr)
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.Type = faultType
|
||||||
|
ret.Target = blockA.Miner
|
||||||
|
|
||||||
|
return ret, totalGas
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *FvmExtern) VerifyBlockSig(ctx context.Context, blk *types.BlockHeader) (int64, error) {
|
||||||
|
waddr, gasUsed, err := x.workerKeyAtLookback(ctx, blk.Miner, blk.Height)
|
||||||
|
if err != nil {
|
||||||
|
return gasUsed, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gasUsed, sigs.CheckBlockSignature(ctx, blk, waddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *FvmExtern) workerKeyAtLookback(ctx context.Context, minerId address.Address, height abi.ChainEpoch) (address.Address, int64, error) {
|
||||||
|
gasUsed := int64(0)
|
||||||
|
gasAdder := func(gc GasCharge) {
|
||||||
|
// technically not overflow safe, but that's fine
|
||||||
|
gasUsed += gc.Total()
|
||||||
|
}
|
||||||
|
|
||||||
|
cstWithoutGas := cbor.NewCborStore(x.Blockstore)
|
||||||
|
cbb := &gasChargingBlocks{gasAdder, PricelistByEpoch(x.epoch), x.Blockstore}
|
||||||
|
cstWithGas := cbor.NewCborStore(cbb)
|
||||||
|
|
||||||
|
lbState, err := x.lbState(ctx, height)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, gasUsed, err
|
||||||
|
}
|
||||||
|
// get appropriate miner actor
|
||||||
|
act, err := lbState.GetActor(minerId)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, gasUsed, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// use that to get the miner state
|
||||||
|
mas, err := miner.Load(adt.WrapStore(ctx, cstWithGas), act)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, gasUsed, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := mas.Info()
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, gasUsed, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stateTree, err := state.LoadStateTree(cstWithoutGas, x.base)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, gasUsed, err
|
||||||
|
}
|
||||||
|
|
||||||
|
raddr, err := ResolveToKeyAddr(stateTree, cstWithGas, info.Worker)
|
||||||
|
if err != nil {
|
||||||
|
return address.Undef, gasUsed, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return raddr, gasUsed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type FVM struct {
|
||||||
|
fvm *ffi.FVM
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFVM(ctx context.Context, opts *VMOpts) (*FVM, error) {
|
||||||
|
circToReport := opts.FilVested
|
||||||
|
// For v14 (and earlier), we perform the FilVested portion of the calculation, and let the FVM dynamically do the rest
|
||||||
|
// v15 and after, the circ supply is always constant per epoch, so we calculate the base and report it at creation
|
||||||
|
if opts.NetworkVersion >= network.Version15 {
|
||||||
|
state, err := state.LoadStateTree(cbor.NewCborStore(opts.Bstore), opts.StateBase)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
circToReport, err = opts.CircSupplyCalc(ctx, opts.Epoch, state)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fvm, err := ffi.CreateFVM(0,
|
||||||
|
&FvmExtern{Rand: opts.Rand, Blockstore: opts.Bstore, lbState: opts.LookbackState, base: opts.StateBase, epoch: opts.Epoch},
|
||||||
|
opts.Epoch, opts.BaseFee, circToReport, opts.NetworkVersion, opts.StateBase,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &FVM{
|
||||||
|
fvm: fvm,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *FVM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, error) {
|
||||||
|
start := build.Clock.Now()
|
||||||
|
msgBytes, err := cmsg.VMMessage().Serialize()
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("serializing msg: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, err := vm.fvm.ApplyMessage(msgBytes, uint(cmsg.ChainLength()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("applying msg: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ApplyRet{
|
||||||
|
MessageReceipt: types.MessageReceipt{
|
||||||
|
Return: ret.Return,
|
||||||
|
ExitCode: exitcode.ExitCode(ret.ExitCode),
|
||||||
|
GasUsed: ret.GasUsed,
|
||||||
|
},
|
||||||
|
GasCosts: &GasOutputs{
|
||||||
|
// TODO: do the other optional fields eventually
|
||||||
|
BaseFeeBurn: big.Zero(),
|
||||||
|
OverEstimationBurn: big.Zero(),
|
||||||
|
MinerPenalty: ret.MinerPenalty,
|
||||||
|
MinerTip: ret.MinerTip,
|
||||||
|
Refund: big.Zero(),
|
||||||
|
GasRefund: 0,
|
||||||
|
GasBurned: 0,
|
||||||
|
},
|
||||||
|
// TODO: do these eventually, not consensus critical
|
||||||
|
// https://github.com/filecoin-project/ref-fvm/issues/318
|
||||||
|
ActorErr: nil,
|
||||||
|
ExecutionTrace: types.ExecutionTrace{},
|
||||||
|
Duration: time.Since(start),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *FVM) ApplyImplicitMessage(ctx context.Context, cmsg *types.Message) (*ApplyRet, error) {
|
||||||
|
start := build.Clock.Now()
|
||||||
|
msgBytes, err := cmsg.VMMessage().Serialize()
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("serializing msg: %w", err)
|
||||||
|
}
|
||||||
|
ret, err := vm.fvm.ApplyImplicitMessage(msgBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("applying msg: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ApplyRet{
|
||||||
|
MessageReceipt: types.MessageReceipt{
|
||||||
|
Return: ret.Return,
|
||||||
|
ExitCode: exitcode.ExitCode(ret.ExitCode),
|
||||||
|
GasUsed: ret.GasUsed,
|
||||||
|
},
|
||||||
|
GasCosts: nil,
|
||||||
|
// TODO: do these eventually, not consensus critical
|
||||||
|
// https://github.com/filecoin-project/ref-fvm/issues/318
|
||||||
|
ActorErr: nil,
|
||||||
|
ExecutionTrace: types.ExecutionTrace{},
|
||||||
|
Duration: time.Since(start),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *FVM) Flush(ctx context.Context) (cid.Cid, error) {
|
||||||
|
return vm.fvm.Flush()
|
||||||
|
}
|
@ -50,7 +50,7 @@ func newGasCharge(name string, computeGas int64, storageGas int64) GasCharge {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pricelist provides prices for operations in the VM.
|
// Pricelist provides prices for operations in the LegacyVM.
|
||||||
//
|
//
|
||||||
// Note: this interface should be APPEND ONLY since last chain checkpoint
|
// Note: this interface should be APPEND ONLY since last chain checkpoint
|
||||||
type Pricelist interface {
|
type Pricelist interface {
|
||||||
|
@ -50,7 +50,7 @@ type pricelistV0 struct {
|
|||||||
// whether it succeeds or fails in application) is given by:
|
// whether it succeeds or fails in application) is given by:
|
||||||
// OnChainMessageBase + len(serialized message)*OnChainMessagePerByte
|
// OnChainMessageBase + len(serialized message)*OnChainMessagePerByte
|
||||||
// Together, these account for the cost of message propagation and validation,
|
// Together, these account for the cost of message propagation and validation,
|
||||||
// up to but excluding any actual processing by the VM.
|
// up to but excluding any actual processing by the LegacyVM.
|
||||||
// This is the cost a block producer burns when including an invalid message.
|
// This is the cost a block producer burns when including an invalid message.
|
||||||
onChainMessageComputeBase int64
|
onChainMessageComputeBase int64
|
||||||
onChainMessageStorageBase int64
|
onChainMessageStorageBase int64
|
||||||
@ -83,11 +83,11 @@ type pricelistV0 struct {
|
|||||||
sendInvokeMethod int64
|
sendInvokeMethod int64
|
||||||
|
|
||||||
// Gas cost for any Get operation to the IPLD store
|
// Gas cost for any Get operation to the IPLD store
|
||||||
// in the runtime VM context.
|
// in the runtime LegacyVM context.
|
||||||
ipldGetBase int64
|
ipldGetBase int64
|
||||||
|
|
||||||
// Gas cost (Base + len*PerByte) for any Put operation to the IPLD store
|
// Gas cost (Base + len*PerByte) for any Put operation to the IPLD store
|
||||||
// in the runtime VM context.
|
// in the runtime LegacyVM context.
|
||||||
//
|
//
|
||||||
// Note: these costs should be significantly higher than the costs for Get
|
// Note: these costs should be significantly higher than the costs for Get
|
||||||
// operations, since they reflect not only serialization/deserialization
|
// operations, since they reflect not only serialization/deserialization
|
||||||
|
@ -135,7 +135,7 @@ func TestInvokerBasic(t *testing.T) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
_, aerr := code[1](&Runtime{
|
_, aerr := code[1](&Runtime{
|
||||||
vm: &VM{networkVersion: network.Version0},
|
vm: &LegacyVM{networkVersion: network.Version0},
|
||||||
Message: &basicRtMessage{},
|
Message: &basicRtMessage{},
|
||||||
}, []byte{99})
|
}, []byte{99})
|
||||||
if aerrors.IsFatal(aerr) {
|
if aerrors.IsFatal(aerr) {
|
||||||
@ -146,7 +146,7 @@ func TestInvokerBasic(t *testing.T) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
_, aerr := code[1](&Runtime{
|
_, aerr := code[1](&Runtime{
|
||||||
vm: &VM{networkVersion: network.Version7},
|
vm: &LegacyVM{networkVersion: network.Version7},
|
||||||
Message: &basicRtMessage{},
|
Message: &basicRtMessage{},
|
||||||
}, []byte{99})
|
}, []byte{99})
|
||||||
if aerrors.IsFatal(aerr) {
|
if aerrors.IsFatal(aerr) {
|
||||||
|
@ -65,7 +65,7 @@ type Runtime struct {
|
|||||||
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
|
||||||
vm *VM
|
vm *LegacyVM
|
||||||
state *state.StateTree
|
state *state.StateTree
|
||||||
height abi.ChainEpoch
|
height abi.ChainEpoch
|
||||||
cst ipldcbor.IpldStore
|
cst ipldcbor.IpldStore
|
||||||
@ -158,7 +158,7 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
|
|||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
if ar, ok := r.(aerrors.ActorError); ok {
|
if ar, ok := r.(aerrors.ActorError); ok {
|
||||||
log.Warnf("VM.Call failure in call from: %s to %s: %+v", rt.Caller(), rt.Receiver(), ar)
|
log.Warnf("LegacyVM.Call failure in call from: %s to %s: %+v", rt.Caller(), rt.Receiver(), ar)
|
||||||
aerr = ar
|
aerr = ar
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ func (bs *gasChargingBlocks) Put(ctx context.Context, blk block.Block) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runtime) *Runtime {
|
func (vm *LegacyVM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runtime) *Runtime {
|
||||||
rt := &Runtime{
|
rt := &Runtime{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
vm: vm,
|
vm: vm,
|
||||||
@ -188,7 +188,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runti
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UnsafeVM struct {
|
type UnsafeVM struct {
|
||||||
VM *VM
|
VM *LegacyVM
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message) *Runtime {
|
func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message) *Runtime {
|
||||||
@ -201,7 +201,9 @@ type (
|
|||||||
LookbackStateGetter func(context.Context, abi.ChainEpoch) (*state.StateTree, error)
|
LookbackStateGetter func(context.Context, abi.ChainEpoch) (*state.StateTree, error)
|
||||||
)
|
)
|
||||||
|
|
||||||
type VM struct {
|
var _ Interface = (*LegacyVM)(nil)
|
||||||
|
|
||||||
|
type LegacyVM struct {
|
||||||
cstate *state.StateTree
|
cstate *state.StateTree
|
||||||
cst *cbor.BasicIpldStore
|
cst *cbor.BasicIpldStore
|
||||||
buf *blockstore.BufferedBlockstore
|
buf *blockstore.BufferedBlockstore
|
||||||
@ -225,12 +227,14 @@ type VMOpts struct {
|
|||||||
Actors *ActorRegistry
|
Actors *ActorRegistry
|
||||||
Syscalls SyscallBuilder
|
Syscalls SyscallBuilder
|
||||||
CircSupplyCalc CircSupplyCalculator
|
CircSupplyCalc CircSupplyCalculator
|
||||||
|
// Amount of FIL vested from genesis actors.
|
||||||
|
FilVested abi.TokenAmount
|
||||||
NetworkVersion network.Version
|
NetworkVersion network.Version
|
||||||
BaseFee abi.TokenAmount
|
BaseFee abi.TokenAmount
|
||||||
LookbackState LookbackStateGetter
|
LookbackState LookbackStateGetter
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) {
|
func NewLegacyVM(ctx context.Context, opts *VMOpts) (*LegacyVM, error) {
|
||||||
buf := blockstore.NewBuffered(opts.Bstore)
|
buf := blockstore.NewBuffered(opts.Bstore)
|
||||||
cst := cbor.NewCborStore(buf)
|
cst := cbor.NewCborStore(buf)
|
||||||
state, err := state.LoadStateTree(cst, opts.StateBase)
|
state, err := state.LoadStateTree(cst, opts.StateBase)
|
||||||
@ -243,7 +247,7 @@ func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &VM{
|
return &LegacyVM{
|
||||||
cstate: state,
|
cstate: state,
|
||||||
cst: cst,
|
cst: cst,
|
||||||
buf: buf,
|
buf: buf,
|
||||||
@ -272,7 +276,7 @@ type ApplyRet struct {
|
|||||||
GasCosts *GasOutputs
|
GasCosts *GasOutputs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
func (vm *LegacyVM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
||||||
gasCharge *GasCharge, start time.Time) ([]byte, aerrors.ActorError, *Runtime) {
|
gasCharge *GasCharge, start time.Time) ([]byte, aerrors.ActorError, *Runtime) {
|
||||||
defer atomic.AddUint64(&StatSends, 1)
|
defer atomic.AddUint64(&StatSends, 1)
|
||||||
|
|
||||||
@ -391,7 +395,7 @@ func checkMessage(msg *types.Message) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error) {
|
func (vm *LegacyVM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error) {
|
||||||
start := build.Clock.Now()
|
start := build.Clock.Now()
|
||||||
defer atomic.AddUint64(&StatApplied, 1)
|
defer atomic.AddUint64(&StatApplied, 1)
|
||||||
ret, actorErr, rt := vm.send(ctx, msg, nil, nil, start)
|
ret, actorErr, rt := vm.send(ctx, msg, nil, nil, start)
|
||||||
@ -409,7 +413,7 @@ func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*Ap
|
|||||||
}, actorErr
|
}, actorErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, error) {
|
func (vm *LegacyVM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, error) {
|
||||||
start := build.Clock.Now()
|
start := build.Clock.Now()
|
||||||
ctx, span := trace.StartSpan(ctx, "vm.ApplyMessage")
|
ctx, span := trace.StartSpan(ctx, "vm.ApplyMessage")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@ -616,7 +620,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) ShouldBurn(ctx context.Context, st *state.StateTree, msg *types.Message, errcode exitcode.ExitCode) (bool, error) {
|
func (vm *LegacyVM) ShouldBurn(ctx context.Context, st *state.StateTree, msg *types.Message, errcode exitcode.ExitCode) (bool, error) {
|
||||||
if vm.networkVersion <= network.Version12 {
|
if vm.networkVersion <= network.Version12 {
|
||||||
// Check to see if we should burn funds. We avoid burning on successful
|
// Check to see if we should burn funds. We avoid burning on successful
|
||||||
// window post. This won't catch _indirect_ window post calls, but this
|
// window post. This won't catch _indirect_ window post calls, but this
|
||||||
@ -646,7 +650,7 @@ func (vm *VM) ShouldBurn(ctx context.Context, st *state.StateTree, msg *types.Me
|
|||||||
|
|
||||||
type vmFlushKey struct{}
|
type vmFlushKey struct{}
|
||||||
|
|
||||||
func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
|
func (vm *LegacyVM) Flush(ctx context.Context) (cid.Cid, error) {
|
||||||
_, span := trace.StartSpan(ctx, "vm.Flush")
|
_, span := trace.StartSpan(ctx, "vm.Flush")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@ -665,9 +669,9 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
|
|||||||
return root, nil
|
return root, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the buffered blockstore associated with the VM. This includes any temporary blocks produced
|
// Get the buffered blockstore associated with the LegacyVM. This includes any temporary blocks produced
|
||||||
// during this VM's execution.
|
// during this LegacyVM's execution.
|
||||||
func (vm *VM) ActorStore(ctx context.Context) adt.Store {
|
func (vm *LegacyVM) ActorStore(ctx context.Context) adt.Store {
|
||||||
return adt.WrapStore(ctx, vm.cst)
|
return adt.WrapStore(ctx, vm.cst)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,11 +824,11 @@ func copyRec(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) StateTree() types.StateTree {
|
func (vm *LegacyVM) StateTree() types.StateTree {
|
||||||
return vm.cstate
|
return vm.cstate
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) Invoke(act *types.Actor, rt *Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
|
func (vm *LegacyVM) Invoke(act *types.Actor, rt *Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
|
||||||
ctx, span := trace.StartSpan(rt.ctx, "vm.Invoke")
|
ctx, span := trace.StartSpan(rt.ctx, "vm.Invoke")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
if span.IsRecordingEvents() {
|
if span.IsRecordingEvents() {
|
||||||
@ -847,11 +851,11 @@ func (vm *VM) Invoke(act *types.Actor, rt *Runtime, method abi.MethodNum, params
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) SetInvoker(i *ActorRegistry) {
|
func (vm *LegacyVM) SetInvoker(i *ActorRegistry) {
|
||||||
vm.areg = i
|
vm.areg = i
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) GetCircSupply(ctx context.Context) (abi.TokenAmount, error) {
|
func (vm *LegacyVM) GetCircSupply(ctx context.Context) (abi.TokenAmount, error) {
|
||||||
// Before v15, this was recalculated on each invocation as the state tree was mutated
|
// Before v15, this was recalculated on each invocation as the state tree was mutated
|
||||||
if vm.networkVersion <= network.Version14 {
|
if vm.networkVersion <= network.Version14 {
|
||||||
return vm.circSupplyCalc(ctx, vm.blockHeight, vm.cstate)
|
return vm.circSupplyCalc(ctx, vm.blockHeight, vm.cstate)
|
||||||
@ -860,14 +864,14 @@ func (vm *VM) GetCircSupply(ctx context.Context) (abi.TokenAmount, error) {
|
|||||||
return vm.baseCircSupply, nil
|
return vm.baseCircSupply, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) incrementNonce(addr address.Address) error {
|
func (vm *LegacyVM) incrementNonce(addr address.Address) error {
|
||||||
return vm.cstate.MutateActor(addr, func(a *types.Actor) error {
|
return vm.cstate.MutateActor(addr, func(a *types.Actor) error {
|
||||||
a.Nonce++
|
a.Nonce++
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) transfer(from, to address.Address, amt types.BigInt, networkVersion network.Version) aerrors.ActorError {
|
func (vm *LegacyVM) transfer(from, to address.Address, amt types.BigInt, networkVersion network.Version) aerrors.ActorError {
|
||||||
var f *types.Actor
|
var f *types.Actor
|
||||||
var fromID, toID address.Address
|
var fromID, toID address.Address
|
||||||
var err error
|
var err error
|
||||||
@ -955,7 +959,7 @@ func (vm *VM) transfer(from, to address.Address, amt types.BigInt, networkVersio
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) transferToGasHolder(addr address.Address, gasHolder *types.Actor, amt types.BigInt) error {
|
func (vm *LegacyVM) transferToGasHolder(addr address.Address, gasHolder *types.Actor, amt types.BigInt) error {
|
||||||
if amt.LessThan(types.NewInt(0)) {
|
if amt.LessThan(types.NewInt(0)) {
|
||||||
return xerrors.Errorf("attempted to transfer negative value to gas holder")
|
return xerrors.Errorf("attempted to transfer negative value to gas holder")
|
||||||
}
|
}
|
||||||
@ -969,7 +973,7 @@ func (vm *VM) transferToGasHolder(addr address.Address, gasHolder *types.Actor,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) transferFromGasHolder(addr address.Address, gasHolder *types.Actor, amt types.BigInt) error {
|
func (vm *LegacyVM) transferFromGasHolder(addr address.Address, gasHolder *types.Actor, amt types.BigInt) error {
|
||||||
if amt.LessThan(types.NewInt(0)) {
|
if amt.LessThan(types.NewInt(0)) {
|
||||||
return xerrors.Errorf("attempted to transfer negative value from gas holder")
|
return xerrors.Errorf("attempted to transfer negative value from gas holder")
|
||||||
}
|
}
|
||||||
|
27
chain/vm/vmi.go
Normal file
27
chain/vm/vmi.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package vm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Interface interface {
|
||||||
|
// Applies the given message onto the VM's current state, returning the result of the execution
|
||||||
|
ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, error)
|
||||||
|
// Same as above but for system messages (the Cron invocation and block reward payments).
|
||||||
|
// Must NEVER fail.
|
||||||
|
ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error)
|
||||||
|
// Flush all buffered objects into the state store provided to the VM at construction.
|
||||||
|
Flush(ctx context.Context) (cid.Cid, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewVM(ctx context.Context, opts *VMOpts) (Interface, error) {
|
||||||
|
if os.Getenv("LOTUS_USE_FVM_EXPERIMENTAL") == "1" {
|
||||||
|
return NewFVM(ctx, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewLegacyVM(ctx, opts)
|
||||||
|
}
|
@ -44,7 +44,7 @@ type BlockBuilder struct {
|
|||||||
|
|
||||||
parentTs *types.TipSet
|
parentTs *types.TipSet
|
||||||
parentSt *state.StateTree
|
parentSt *state.StateTree
|
||||||
vm *vm.VM
|
vm *vm.LegacyVM
|
||||||
sm *stmgr.StateManager
|
sm *stmgr.StateManager
|
||||||
|
|
||||||
gasTotal int64
|
gasTotal int64
|
||||||
@ -73,9 +73,9 @@ func NewBlockBuilder(ctx context.Context, logger *zap.SugaredLogger, sm *stmgr.S
|
|||||||
parentSt: parentSt,
|
parentSt: parentSt,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then we construct a VM to execute messages for gas estimation.
|
// Then we construct a LegacyVM to execute messages for gas estimation.
|
||||||
//
|
//
|
||||||
// Most parts of this VM are "real" except:
|
// Most parts of this LegacyVM are "real" except:
|
||||||
// 1. We don't charge a fee.
|
// 1. We don't charge a fee.
|
||||||
// 2. The runtime has "fake" proof logic.
|
// 2. The runtime has "fake" proof logic.
|
||||||
// 3. We don't actually save any of the results.
|
// 3. We don't actually save any of the results.
|
||||||
@ -92,7 +92,7 @@ func NewBlockBuilder(ctx context.Context, logger *zap.SugaredLogger, sm *stmgr.S
|
|||||||
BaseFee: abi.NewTokenAmount(0),
|
BaseFee: abi.NewTokenAmount(0),
|
||||||
LookbackState: stmgr.LookbackStateGetterForTipset(sm, parentTs),
|
LookbackState: stmgr.LookbackStateGetterForTipset(sm, parentTs),
|
||||||
}
|
}
|
||||||
bb.vm, err = vm.NewVM(bb.ctx, vmopt)
|
bb.vm, err = vm.NewLegacyVM(bb.ctx, vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -190,12 +190,12 @@ func (bb *BlockBuilder) PushMessage(msg *types.Message) (*types.MessageReceipt,
|
|||||||
return &ret.MessageReceipt, nil
|
return &ret.MessageReceipt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActorStore returns the VM's current (pending) blockstore.
|
// ActorStore returns the LegacyVM's current (pending) blockstore.
|
||||||
func (bb *BlockBuilder) ActorStore() adt.Store {
|
func (bb *BlockBuilder) ActorStore() adt.Store {
|
||||||
return bb.vm.ActorStore(bb.ctx)
|
return bb.vm.ActorStore(bb.ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StateTree returns the VM's current (pending) state-tree. This includes any changes made by
|
// StateTree returns the LegacyVM's current (pending) state-tree. This includes any changes made by
|
||||||
// successfully pushed messages.
|
// successfully pushed messages.
|
||||||
//
|
//
|
||||||
// You probably want ParentStateTree
|
// You probably want ParentStateTree
|
||||||
|
@ -155,12 +155,12 @@ func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, params
|
|||||||
results: []*vm.ApplyRet{},
|
results: []*vm.ApplyRet{},
|
||||||
}
|
}
|
||||||
|
|
||||||
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (*vm.VM, error) {
|
sm.SetVMConstructor(func(ctx context.Context, vmopt *vm.VMOpts) (vm.Interface, error) {
|
||||||
vmopt.CircSupplyCalc = func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) {
|
vmopt.CircSupplyCalc = func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) {
|
||||||
return big.Zero(), nil
|
return big.Zero(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm.NewVM(ctx, vmopt)
|
return vm.NewLegacyVM(ctx, vmopt)
|
||||||
})
|
})
|
||||||
|
|
||||||
postcid, receiptsroot, err := tse.ApplyBlocks(context.Background(),
|
postcid, receiptsroot, err := tse.ApplyBlocks(context.Background(),
|
||||||
@ -226,7 +226,7 @@ func (d *Driver) ExecuteMessage(bs blockstore.Blockstore, params ExecuteMessageP
|
|||||||
NetworkVersion: params.NetworkVersion,
|
NetworkVersion: params.NetworkVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
lvm, err := vm.NewVM(context.TODO(), vmOpts)
|
lvm, err := vm.NewLegacyVM(context.TODO(), vmOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cid.Undef, err
|
return nil, cid.Undef, err
|
||||||
}
|
}
|
||||||
|
2
extern/filecoin-ffi
vendored
2
extern/filecoin-ffi
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 5ec5d805c01ea85224f6448dd6c6fa0a2a73c028
|
Subproject commit c2668aa67ec589a773153022348b9c0ed6ed4d5d
|
5
go.sum
5
go.sum
@ -330,7 +330,6 @@ github.com/filecoin-project/go-data-transfer v1.15.0/go.mod h1:RaJIYjh6x6z+FXKNv
|
|||||||
github.com/filecoin-project/go-ds-versioning v0.0.0-20211206185234-508abd7c2aff/go.mod h1:C9/l9PnB1+mwPa26BBVpCjG/XQCB0yj/q5CK2J8X1I4=
|
github.com/filecoin-project/go-ds-versioning v0.0.0-20211206185234-508abd7c2aff/go.mod h1:C9/l9PnB1+mwPa26BBVpCjG/XQCB0yj/q5CK2J8X1I4=
|
||||||
github.com/filecoin-project/go-ds-versioning v0.1.1 h1:JiyBqaQlwC+UM0WhcBtVEeT3XrX59mQhT8U3p7nu86o=
|
github.com/filecoin-project/go-ds-versioning v0.1.1 h1:JiyBqaQlwC+UM0WhcBtVEeT3XrX59mQhT8U3p7nu86o=
|
||||||
github.com/filecoin-project/go-ds-versioning v0.1.1/go.mod h1:C9/l9PnB1+mwPa26BBVpCjG/XQCB0yj/q5CK2J8X1I4=
|
github.com/filecoin-project/go-ds-versioning v0.1.1/go.mod h1:C9/l9PnB1+mwPa26BBVpCjG/XQCB0yj/q5CK2J8X1I4=
|
||||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
|
|
||||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
|
github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
|
||||||
github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88OqLYEo6roi+GiIeOh8=
|
github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88OqLYEo6roi+GiIeOh8=
|
||||||
github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
|
github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
|
||||||
@ -390,8 +389,8 @@ github.com/filecoin-project/specs-actors/v5 v5.0.4/go.mod h1:5BAKRAMsOOlD8+qCw4U
|
|||||||
github.com/filecoin-project/specs-actors/v6 v6.0.0/go.mod h1:V1AYfi5GkHXipx1mnVivoICZh3wtwPxDVuds+fbfQtk=
|
github.com/filecoin-project/specs-actors/v6 v6.0.0/go.mod h1:V1AYfi5GkHXipx1mnVivoICZh3wtwPxDVuds+fbfQtk=
|
||||||
github.com/filecoin-project/specs-actors/v6 v6.0.1 h1:laxvHNsvrq83Y9n+W7znVCePi3oLyRf0Rkl4jFO8Wew=
|
github.com/filecoin-project/specs-actors/v6 v6.0.1 h1:laxvHNsvrq83Y9n+W7znVCePi3oLyRf0Rkl4jFO8Wew=
|
||||||
github.com/filecoin-project/specs-actors/v6 v6.0.1/go.mod h1:V1AYfi5GkHXipx1mnVivoICZh3wtwPxDVuds+fbfQtk=
|
github.com/filecoin-project/specs-actors/v6 v6.0.1/go.mod h1:V1AYfi5GkHXipx1mnVivoICZh3wtwPxDVuds+fbfQtk=
|
||||||
github.com/filecoin-project/specs-actors/v7 v7.0.0-20211117170924-fd07a4c7dff9/go.mod h1:p6LIOFezA1rgRLMewbvdi3Pp6SAu+q9FtJ9CAleSjrE=
|
|
||||||
github.com/filecoin-project/specs-actors/v7 v7.0.0-20211222192039-c83bea50c402/go.mod h1:p6LIOFezA1rgRLMewbvdi3Pp6SAu+q9FtJ9CAleSjrE=
|
github.com/filecoin-project/specs-actors/v7 v7.0.0-20211222192039-c83bea50c402/go.mod h1:p6LIOFezA1rgRLMewbvdi3Pp6SAu+q9FtJ9CAleSjrE=
|
||||||
|
github.com/filecoin-project/specs-actors/v7 v7.0.0-rc1.0.20220118005651-2470cb39827e/go.mod h1:TA5FwCna+Yi36POaT7SLKXsgEDvJwc0V/L6ZsO19B9M=
|
||||||
github.com/filecoin-project/specs-actors/v7 v7.0.0 h1:FQN7tjt3o68hfb3qLFSJBoLMuOFY0REkFVLO/zXj8RU=
|
github.com/filecoin-project/specs-actors/v7 v7.0.0 h1:FQN7tjt3o68hfb3qLFSJBoLMuOFY0REkFVLO/zXj8RU=
|
||||||
github.com/filecoin-project/specs-actors/v7 v7.0.0/go.mod h1:TA5FwCna+Yi36POaT7SLKXsgEDvJwc0V/L6ZsO19B9M=
|
github.com/filecoin-project/specs-actors/v7 v7.0.0/go.mod h1:TA5FwCna+Yi36POaT7SLKXsgEDvJwc0V/L6ZsO19B9M=
|
||||||
github.com/filecoin-project/specs-storage v0.2.0 h1:Y4UDv0apRQ3zI2GiPPubi8JblpUZZphEdaJUxCutfyg=
|
github.com/filecoin-project/specs-storage v0.2.0 h1:Y4UDv0apRQ3zI2GiPPubi8JblpUZZphEdaJUxCutfyg=
|
||||||
@ -1943,6 +1942,7 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163/go.mod h1:f
|
|||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20210303213153-67a261a1d291/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20210303213153-67a261a1d291/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||||
|
github.com/whyrusleeping/cbor-gen v0.0.0-20210713220151-be142a5ae1a8/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20220224212727-7a699437a831/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20220224212727-7a699437a831/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20220302191723-37c43cae8e14 h1:vo2wkP2ceHyGyZwFFtAabpot03EeSxxwAe57pOI9E/4=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20220302191723-37c43cae8e14 h1:vo2wkP2ceHyGyZwFFtAabpot03EeSxxwAe57pOI9E/4=
|
||||||
github.com/whyrusleeping/cbor-gen v0.0.0-20220302191723-37c43cae8e14/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
github.com/whyrusleeping/cbor-gen v0.0.0-20220302191723-37c43cae8e14/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
|
||||||
@ -2447,7 +2447,6 @@ golang.org/x/tools v0.0.0-20200711155855-7342f9734a7d/go.mod h1:njjCfa9FT2d7l9Bc
|
|||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
|
@ -65,7 +65,7 @@ var ChainNode = Options(
|
|||||||
Override(new(ffiwrapper.Verifier), ffiwrapper.ProofVerifier),
|
Override(new(ffiwrapper.Verifier), ffiwrapper.ProofVerifier),
|
||||||
Override(new(ffiwrapper.Prover), ffiwrapper.ProofProver),
|
Override(new(ffiwrapper.Prover), ffiwrapper.ProofProver),
|
||||||
|
|
||||||
// Consensus: VM
|
// Consensus: LegacyVM
|
||||||
Override(new(vm.SyscallBuilder), vm.Syscalls),
|
Override(new(vm.SyscallBuilder), vm.Syscalls),
|
||||||
|
|
||||||
// Consensus: Chain storage/access
|
// Consensus: Chain storage/access
|
||||||
|
Loading…
Reference in New Issue
Block a user