:Hook up the FVM
This commit is contained in:
parent
d9c763437e
commit
2a669b95fb
@ -2,6 +2,7 @@ package filcns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/rand"
|
||||
@ -92,7 +93,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
|
||||
partDone()
|
||||
}()
|
||||
|
||||
makeVmWithBaseStateAndEpoch := func(base cid.Cid, e abi.ChainEpoch) (*vm.VM, error) {
|
||||
makeVmWithBaseStateAndEpoch := func(base cid.Cid, e abi.ChainEpoch) (vm.VMI, error) {
|
||||
vmopt := &vm.VMOpts{
|
||||
StateBase: base,
|
||||
Epoch: e,
|
||||
@ -106,10 +107,14 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
|
||||
LookbackState: stmgr.LookbackStateGetterForTipset(sm, ts),
|
||||
}
|
||||
|
||||
if os.Getenv("LOTUS_USE_FVM_DOESNT_WORK_YET") == "1" {
|
||||
return vm.NewFVM(ctx, vmopt)
|
||||
}
|
||||
|
||||
return sm.VMConstructor()(ctx, vmopt)
|
||||
}
|
||||
|
||||
runCron := func(vmCron *vm.VM, epoch abi.ChainEpoch) error {
|
||||
runCron := func(vmCron vm.VMI, epoch abi.ChainEpoch) error {
|
||||
cronMsg := &types.Message{
|
||||
To: cron.Address,
|
||||
From: builtin.SystemActorAddr,
|
||||
|
154
chain/vm/fvm.go
Normal file
154
chain/vm/fvm.go
Normal file
@ -0,0 +1,154 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/specs-actors/v7/actors/runtime"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/blockstore"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
var _ VMI = (*FVM)(nil)
|
||||
|
||||
type Extern interface {
|
||||
GetRandomnessFromTickets(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness
|
||||
GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness
|
||||
VerifyConsensusFault(a, b, extra []byte) (address.Address, abi.ChainEpoch, runtime.ConsensusFaultType)
|
||||
}
|
||||
type FvmExtern struct {
|
||||
rand Rand
|
||||
}
|
||||
|
||||
func (e *FvmExtern) GetRandomnessFromTickets(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
|
||||
res, err := e.rand.GetChainRandomness(context.Background(), personalization, randEpoch, entropy)
|
||||
|
||||
if err != nil {
|
||||
panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (e *FvmExtern) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
|
||||
res, err := e.rand.GetBeaconRandomness(context.Background(), personalization, randEpoch, entropy)
|
||||
|
||||
if err != nil {
|
||||
panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
type FVM struct {
|
||||
machineId uint64
|
||||
extern FvmExtern
|
||||
}
|
||||
|
||||
func NewFVM(ctx context.Context, opts *VMOpts) (*FVM, error) {
|
||||
buf := blockstore.NewBuffered(opts.Bstore)
|
||||
cst := cbor.NewCborStore(buf)
|
||||
state, err := state.LoadStateTree(cst, opts.StateBase)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseCirc, err := opts.CircSupplyCalc(ctx, opts.Epoch, state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
id, err := ffi.CreateFVM(0, opts.Epoch, opts.BaseFee, baseCirc, opts.NetworkVersion, opts.StateBase)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &FVM{
|
||||
extern: FvmExtern{rand: opts.Rand},
|
||||
machineId: id,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (vm *FVM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, error) {
|
||||
msgBytes, err := cmsg.VMMessage().Serialize()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("serializing msg: %w", err)
|
||||
}
|
||||
|
||||
ret, err := ffi.ApplyMessage(vm.machineId, 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: &GasOutputs{
|
||||
// TODO: do the other optional fields eventually
|
||||
BaseFeeBurn: abi.TokenAmount{},
|
||||
OverEstimationBurn: abi.TokenAmount{},
|
||||
MinerPenalty: ret.MinerPenalty,
|
||||
MinerTip: ret.MinerTip,
|
||||
Refund: abi.TokenAmount{},
|
||||
GasRefund: 0,
|
||||
GasBurned: 0,
|
||||
},
|
||||
// TODO: do these eventually, not consensus critical
|
||||
ActorErr: nil,
|
||||
ExecutionTrace: types.ExecutionTrace{},
|
||||
Duration: 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (vm *FVM) ApplyImplicitMessage(ctx context.Context, cmsg *types.Message) (*ApplyRet, error) {
|
||||
msgBytes, err := cmsg.VMMessage().Serialize()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("serializing msg: %w", err)
|
||||
}
|
||||
|
||||
ret, err := ffi.ApplyMessage(vm.machineId, 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: &GasOutputs{
|
||||
// TODO: do the other optional fields eventually
|
||||
BaseFeeBurn: abi.TokenAmount{},
|
||||
OverEstimationBurn: abi.TokenAmount{},
|
||||
MinerPenalty: ret.MinerPenalty,
|
||||
MinerTip: ret.MinerTip,
|
||||
Refund: abi.TokenAmount{},
|
||||
GasRefund: 0,
|
||||
GasBurned: 0,
|
||||
},
|
||||
// TODO: do these eventually, not consensus critical
|
||||
ActorErr: nil,
|
||||
ExecutionTrace: types.ExecutionTrace{},
|
||||
Duration: 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (vm *FVM) Flush(ctx context.Context) (cid.Cid, error) {
|
||||
return cid.Undef, nil
|
||||
}
|
@ -201,6 +201,8 @@ type (
|
||||
LookbackStateGetter func(context.Context, abi.ChainEpoch) (*state.StateTree, error)
|
||||
)
|
||||
|
||||
var _ VMI = (*VM)(nil)
|
||||
|
||||
type VM struct {
|
||||
cstate *state.StateTree
|
||||
cst *cbor.BasicIpldStore
|
||||
|
14
chain/vm/vmi.go
Normal file
14
chain/vm/vmi.go
Normal file
@ -0,0 +1,14 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
type VMI interface {
|
||||
ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, error)
|
||||
ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error)
|
||||
Flush(ctx context.Context) (cid.Cid, error)
|
||||
}
|
2
extern/filecoin-ffi
vendored
2
extern/filecoin-ffi
vendored
@ -1 +1 @@
|
||||
Subproject commit e660df5616e397b2d8ac316f45ddfa7a44637971
|
||||
Subproject commit 7e1f3a991e410a71ed9ef33becee8d56d5cb9d26
|
Loading…
Reference in New Issue
Block a user