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:
parent
9746b88bb3
commit
e720f5d3a6
@ -58,6 +58,7 @@ type Invokee interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tUnmarhsalCBOR = reflect.TypeOf((*unmarshalCBOR)(nil)).Elem()
|
var tUnmarhsalCBOR = reflect.TypeOf((*unmarshalCBOR)(nil)).Elem()
|
||||||
|
var tVMContext = reflect.TypeOf((*types.VMContext)(nil)).Elem()
|
||||||
var tError = reflect.TypeOf((*error)(nil)).Elem()
|
var tError = reflect.TypeOf((*error)(nil)).Elem()
|
||||||
|
|
||||||
func (*invoker) transform(instance Invokee) (nativeCode, error) {
|
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{}) {
|
if t.In(0) != reflect.TypeOf(&types.Actor{}) {
|
||||||
return nil, newErr("first arguemnt should be *types.Actor")
|
return nil, newErr("first arguemnt should be *types.Actor")
|
||||||
}
|
}
|
||||||
if t.In(1) != reflect.TypeOf(&VMContext{}) {
|
if t.In(1) != tVMContext {
|
||||||
return nil, newErr("second argument should be *VMContext")
|
return nil, newErr("second argument should be types.VMContext")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !t.In(2).Implements(tUnmarhsalCBOR) {
|
if !t.In(2).Implements(tUnmarhsalCBOR) {
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type basicContract struct{}
|
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) {
|
params *basicParams) (InvokeRet, error) {
|
||||||
return InvokeRet{
|
return InvokeRet{
|
||||||
returnCode: params.b,
|
returnCode: params.b,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
func (basicContract) InvokeSomething10(act *Actor, vmctx *VMContext,
|
func (basicContract) InvokeSomething10(act *types.Actor, vmctx types.VMContext,
|
||||||
params *basicParams) (InvokeRet, error) {
|
params *basicParams) (InvokeRet, error) {
|
||||||
return InvokeRet{
|
return InvokeRet{
|
||||||
returnCode: params.b + 10,
|
returnCode: params.b + 10,
|
||||||
@ -53,7 +55,7 @@ func TestInvokerBasic(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, byte(1), ret.returnCode, "return code should be 1")
|
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.NoError(t, err)
|
||||||
assert.Equal(t, byte(12), ret.returnCode, "return code should be 1")
|
assert.Equal(t, byte(12), ret.returnCode, "return code should be 1")
|
||||||
}
|
}
|
||||||
|
109
chain/types.go
109
chain/types.go
@ -5,8 +5,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
|
||||||
|
|
||||||
block "github.com/ipfs/go-block-format"
|
block "github.com/ipfs/go-block-format"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
@ -14,6 +12,7 @@ import (
|
|||||||
"github.com/multiformats/go-multihash"
|
"github.com/multiformats/go-multihash"
|
||||||
"github.com/polydawn/refmt/obj/atlas"
|
"github.com/polydawn/refmt/obj/atlas"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,7 +44,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return SignedMessage{
|
return SignedMessage{
|
||||||
Message: x[0].(Message),
|
Message: x[0].(types.Message),
|
||||||
Signature: sig,
|
Signature: sig,
|
||||||
}, nil
|
}, nil
|
||||||
})).
|
})).
|
||||||
@ -62,63 +61,6 @@ func init() {
|
|||||||
return SignatureFromBytes(x)
|
return SignatureFromBytes(x)
|
||||||
})).
|
})).
|
||||||
Complete())
|
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().
|
cbor.RegisterCborType(atlas.BuildEntry(BlockHeader{}).UseTag(43).Transform().
|
||||||
TransformMarshal(atlas.MakeMarshalTransformFunc(
|
TransformMarshal(atlas.MakeMarshalTransformFunc(
|
||||||
func(blk BlockHeader) ([]interface{}, error) {
|
func(blk BlockHeader) ([]interface{}, error) {
|
||||||
@ -240,49 +182,6 @@ func (blk *BlockHeader) Serialize() ([]byte, error) {
|
|||||||
return cbor.DumpObject(blk)
|
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) {
|
func (m *SignedMessage) ToStorageBlock() (block.Block, error) {
|
||||||
data, err := m.Serialize()
|
data, err := m.Serialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -308,7 +207,7 @@ func (m *SignedMessage) Cid() cid.Cid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SignedMessage struct {
|
type SignedMessage struct {
|
||||||
Message Message
|
Message types.Message
|
||||||
Signature Signature
|
Signature Signature
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,7 +358,7 @@ func (f *filecoinIpldNode) Links() []*ipld.Link {
|
|||||||
Cid: t.MessageReceipts,
|
Cid: t.MessageReceipts,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
case Message:
|
case types.Message:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
panic("whats going on")
|
panic("whats going on")
|
||||||
|
116
chain/types/message.go
Normal file
116
chain/types/message.go
Normal 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
16
chain/types/vmcontext.go
Normal 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
|
||||||
|
}
|
@ -19,13 +19,13 @@ import (
|
|||||||
|
|
||||||
type VMContext struct {
|
type VMContext struct {
|
||||||
state *StateTree
|
state *StateTree
|
||||||
msg *Message
|
msg *types.Message
|
||||||
height uint64
|
height uint64
|
||||||
cst *hamt.CborIpldStore
|
cst *hamt.CborIpldStore
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message is the message that kicked off the current invocation
|
// Message is the message that kicked off the current invocation
|
||||||
func (vmc *VMContext) Message() *Message {
|
func (vmc *VMContext) Message() *types.Message {
|
||||||
return vmc.msg
|
return vmc.msg
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ func (vmc *VMContext) GasUsed() types.BigInt {
|
|||||||
return types.NewInt(0)
|
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{
|
return &VMContext{
|
||||||
state: state,
|
state: state,
|
||||||
msg: msg,
|
msg: msg,
|
||||||
@ -91,7 +91,7 @@ func NewVM(base cid.Cid, height uint64, maddr address.Address, cs *ChainStore) (
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) ApplyMessage(msg *Message) (*types.MessageReceipt, error) {
|
func (vm *VM) ApplyMessage(msg *types.Message) (*types.MessageReceipt, error) {
|
||||||
st := vm.cstate
|
st := vm.cstate
|
||||||
st.Snapshot()
|
st.Snapshot()
|
||||||
fromActor, err := st.GetActor(msg.From)
|
fromActor, err := st.GetActor(msg.From)
|
||||||
|
Loading…
Reference in New Issue
Block a user