Extract most of the rest and make VMContext an interface

License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
This commit is contained in:
Jakub Sztandera 2019-07-12 12:43:15 +02:00
parent 9746b88bb3
commit e720f5d3a6
6 changed files with 148 additions and 114 deletions

View File

@ -58,6 +58,7 @@ type Invokee interface {
}
var tUnmarhsalCBOR = reflect.TypeOf((*unmarshalCBOR)(nil)).Elem()
var tVMContext = reflect.TypeOf((*types.VMContext)(nil)).Elem()
var tError = reflect.TypeOf((*error)(nil)).Elem()
func (*invoker) transform(instance Invokee) (nativeCode, error) {
@ -83,8 +84,8 @@ func (*invoker) transform(instance Invokee) (nativeCode, error) {
if t.In(0) != reflect.TypeOf(&types.Actor{}) {
return nil, newErr("first arguemnt should be *types.Actor")
}
if t.In(1) != reflect.TypeOf(&VMContext{}) {
return nil, newErr("second argument should be *VMContext")
if t.In(1) != tVMContext {
return nil, newErr("second argument should be types.VMContext")
}
if !t.In(2).Implements(tUnmarhsalCBOR) {

View File

@ -4,6 +4,8 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/filecoin-project/go-lotus/chain/types"
)
type basicContract struct{}
@ -32,13 +34,13 @@ func (b basicContract) Exports() []interface{} {
}
}
func (basicContract) InvokeSomething0(act *Actor, vmctx *VMContext,
func (basicContract) InvokeSomething0(act *types.Actor, vmctx types.VMContext,
params *basicParams) (InvokeRet, error) {
return InvokeRet{
returnCode: params.b,
}, nil
}
func (basicContract) InvokeSomething10(act *Actor, vmctx *VMContext,
func (basicContract) InvokeSomething10(act *types.Actor, vmctx types.VMContext,
params *basicParams) (InvokeRet, error) {
return InvokeRet{
returnCode: params.b + 10,
@ -53,7 +55,7 @@ func TestInvokerBasic(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, byte(1), ret.returnCode, "return code should be 1")
ret, err = code[10](nil, nil, []byte{2})
ret, err = code[10](nil, &VMContext{}, []byte{2})
assert.NoError(t, err)
assert.Equal(t, byte(12), ret.returnCode, "return code should be 1")
}

View File

@ -5,8 +5,6 @@ import (
"encoding/json"
"fmt"
"github.com/filecoin-project/go-lotus/chain/address"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
@ -14,6 +12,7 @@ import (
"github.com/multiformats/go-multihash"
"github.com/polydawn/refmt/obj/atlas"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/filecoin-project/go-lotus/chain/types"
)
@ -45,7 +44,7 @@ func init() {
}
return SignedMessage{
Message: x[0].(Message),
Message: x[0].(types.Message),
Signature: sig,
}, nil
})).
@ -62,63 +61,6 @@ func init() {
return SignatureFromBytes(x)
})).
Complete())
cbor.RegisterCborType(atlas.BuildEntry(Message{}).UseTag(44).Transform().
TransformMarshal(atlas.MakeMarshalTransformFunc(
func(m Message) ([]interface{}, error) {
return []interface{}{
m.To.Bytes(),
m.From.Bytes(),
m.Nonce,
m.Value,
m.GasPrice,
m.GasLimit,
m.Method,
m.Params,
}, nil
})).
TransformUnmarshal(atlas.MakeUnmarshalTransformFunc(
func(arr []interface{}) (Message, error) {
to, err := address.NewFromBytes(arr[0].([]byte))
if err != nil {
return Message{}, err
}
from, err := address.NewFromBytes(arr[1].([]byte))
if err != nil {
return Message{}, err
}
nonce, ok := arr[2].(uint64)
if !ok {
return Message{}, fmt.Errorf("expected uint64 nonce at index 2")
}
value := arr[3].(types.BigInt)
gasPrice := arr[4].(types.BigInt)
gasLimit := arr[5].(types.BigInt)
method, _ := arr[6].(uint64)
params, _ := arr[7].([]byte)
if gasPrice.Nil() {
gasPrice = types.NewInt(0)
}
if gasLimit.Nil() {
gasLimit = types.NewInt(0)
}
return Message{
To: to,
From: from,
Nonce: nonce,
Value: value,
GasPrice: gasPrice,
GasLimit: gasLimit,
Method: method,
Params: params,
}, nil
})).
Complete())
cbor.RegisterCborType(atlas.BuildEntry(BlockHeader{}).UseTag(43).Transform().
TransformMarshal(atlas.MakeMarshalTransformFunc(
func(blk BlockHeader) ([]interface{}, error) {
@ -240,49 +182,6 @@ func (blk *BlockHeader) Serialize() ([]byte, error) {
return cbor.DumpObject(blk)
}
type Message struct {
To address.Address
From address.Address
Nonce uint64
Value types.BigInt
GasPrice types.BigInt
GasLimit types.BigInt
Method uint64
Params []byte
}
func DecodeMessage(b []byte) (*Message, error) {
var msg Message
if err := cbor.DecodeInto(b, &msg); err != nil {
return nil, err
}
return &msg, nil
}
func (m *Message) Serialize() ([]byte, error) {
return cbor.DumpObject(m)
}
func (m *Message) ToStorageBlock() (block.Block, error) {
data, err := m.Serialize()
if err != nil {
return nil, err
}
pref := cid.NewPrefixV1(0x1f, multihash.BLAKE2B_MIN+31)
c, err := pref.Sum(data)
if err != nil {
return nil, err
}
return block.NewBlockWithCid(data, c)
}
func (m *SignedMessage) ToStorageBlock() (block.Block, error) {
data, err := m.Serialize()
if err != nil {
@ -308,7 +207,7 @@ func (m *SignedMessage) Cid() cid.Cid {
}
type SignedMessage struct {
Message Message
Message types.Message
Signature Signature
}
@ -459,7 +358,7 @@ func (f *filecoinIpldNode) Links() []*ipld.Link {
Cid: t.MessageReceipts,
},
}
case Message:
case types.Message:
return nil
default:
panic("whats going on")

116
chain/types/message.go Normal file
View File

@ -0,0 +1,116 @@
package types
import (
"fmt"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/multiformats/go-multihash"
"github.com/polydawn/refmt/obj/atlas"
"github.com/filecoin-project/go-lotus/chain/address"
)
func init() {
cbor.RegisterCborType(atlas.BuildEntry(Message{}).UseTag(44).Transform().
TransformMarshal(atlas.MakeMarshalTransformFunc(
func(m Message) ([]interface{}, error) {
return []interface{}{
m.To.Bytes(),
m.From.Bytes(),
m.Nonce,
m.Value,
m.GasPrice,
m.GasLimit,
m.Method,
m.Params,
}, nil
})).
TransformUnmarshal(atlas.MakeUnmarshalTransformFunc(
func(arr []interface{}) (Message, error) {
to, err := address.NewFromBytes(arr[0].([]byte))
if err != nil {
return Message{}, err
}
from, err := address.NewFromBytes(arr[1].([]byte))
if err != nil {
return Message{}, err
}
nonce, ok := arr[2].(uint64)
if !ok {
return Message{}, fmt.Errorf("expected uint64 nonce at index 2")
}
value := arr[3].(BigInt)
gasPrice := arr[4].(BigInt)
gasLimit := arr[5].(BigInt)
method, _ := arr[6].(uint64)
params, _ := arr[7].([]byte)
if gasPrice.Nil() {
gasPrice = NewInt(0)
}
if gasLimit.Nil() {
gasLimit = NewInt(0)
}
return Message{
To: to,
From: from,
Nonce: nonce,
Value: value,
GasPrice: gasPrice,
GasLimit: gasLimit,
Method: method,
Params: params,
}, nil
})).
Complete())
}
type Message struct {
To address.Address
From address.Address
Nonce uint64
Value BigInt
GasPrice BigInt
GasLimit BigInt
Method uint64
Params []byte
}
func DecodeMessage(b []byte) (*Message, error) {
var msg Message
if err := cbor.DecodeInto(b, &msg); err != nil {
return nil, err
}
return &msg, nil
}
func (m *Message) Serialize() ([]byte, error) {
return cbor.DumpObject(m)
}
func (m *Message) ToStorageBlock() (block.Block, error) {
data, err := m.Serialize()
if err != nil {
return nil, err
}
pref := cid.NewPrefixV1(0x1f, multihash.BLAKE2B_MIN+31)
c, err := pref.Sum(data)
if err != nil {
return nil, err
}
return block.NewBlockWithCid(data, c)
}

16
chain/types/vmcontext.go Normal file
View File

@ -0,0 +1,16 @@
package types
import (
"math/big"
"github.com/filecoin-project/go-lotus/chain/address"
"github.com/ipfs/go-hamt-ipld"
)
type VMContext interface {
Message() *Message
Ipld() *hamt.CborIpldStore
Send(to address.Address, method string, value *big.Int, params []interface{}) ([][]byte, uint8, error)
BlockHeight() uint64
GasUsed() BigInt
}

View File

@ -19,13 +19,13 @@ import (
type VMContext struct {
state *StateTree
msg *Message
msg *types.Message
height uint64
cst *hamt.CborIpldStore
}
// Message is the message that kicked off the current invocation
func (vmc *VMContext) Message() *Message {
func (vmc *VMContext) Message() *types.Message {
return vmc.msg
}
@ -54,7 +54,7 @@ func (vmc *VMContext) GasUsed() types.BigInt {
return types.NewInt(0)
}
func makeVMContext(state *StateTree, msg *Message, height uint64) *VMContext {
func makeVMContext(state *StateTree, msg *types.Message, height uint64) *VMContext {
return &VMContext{
state: state,
msg: msg,
@ -91,7 +91,7 @@ func NewVM(base cid.Cid, height uint64, maddr address.Address, cs *ChainStore) (
}, nil
}
func (vm *VM) ApplyMessage(msg *Message) (*types.MessageReceipt, error) {
func (vm *VM) ApplyMessage(msg *types.Message) (*types.MessageReceipt, error) {
st := vm.cstate
st.Snapshot()
fromActor, err := st.GetActor(msg.From)