lotus/chain/vm/fvm.go

121 lines
3.0 KiB
Go
Raw Normal View History

2021-12-17 03:38:13 +00:00
package vm
import (
"context"
"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"
ffi "github.com/filecoin-project/filecoin-ffi"
2022-01-31 10:31:58 +00:00
ffi_cgo "github.com/filecoin-project/filecoin-ffi/cgo"
2021-12-17 03:38:13 +00:00
"github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid"
)
var _ VMI = (*FVM)(nil)
type FvmExtern struct {
2022-01-31 10:31:58 +00:00
Rand
blockstore.Blockstore
2021-12-17 03:38:13 +00:00
}
2022-01-31 10:31:58 +00:00
func (x *FvmExtern) VerifyConsensusFault(ctx context.Context, h1, h2, extra []byte) (*ffi_cgo.ConsensusFault, error) {
// TODO
panic("unimplemented")
2021-12-17 03:38:13 +00:00
}
type FVM struct {
2022-01-31 10:31:58 +00:00
fvm *ffi.FVM
2021-12-17 03:38:13 +00:00
}
func NewFVM(ctx context.Context, opts *VMOpts) (*FVM, error) {
2022-01-31 10:31:58 +00:00
fvm, err := ffi.CreateFVM(0,
&FvmExtern{Rand: opts.Rand, Blockstore: opts.Bstore},
opts.Epoch, opts.BaseFee, opts.BaseCircSupply, opts.NetworkVersion, opts.StateBase,
2022-01-31 10:31:58 +00:00
)
2021-12-17 03:38:13 +00:00
if err != nil {
return nil, err
}
return &FVM{
2022-01-31 10:31:58 +00:00
fvm: fvm,
2021-12-17 03:38:13 +00:00
}, 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 := vm.fvm.ApplyMessage(msgBytes, uint(cmsg.ChainLength()))
2021-12-17 03:38:13 +00:00
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 := vm.fvm.ApplyImplicitMessage(msgBytes)
2021-12-17 03:38:13 +00:00
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) {
2022-01-31 10:31:58 +00:00
return vm.fvm.Flush()
2021-12-17 03:38:13 +00:00
}