feat: events: version the MessageReceipt structure. (#9636)
This commit is contained in:
parent
ae7847d097
commit
c75d0c4bd1
@ -344,12 +344,8 @@ func fakeReceipt(tb testing.TB, rng *pseudo.Rand, st adt.Store, events []*types.
|
||||
eventsRoot, err := arr.Root()
|
||||
require.NoError(tb, err, "flush events amt")
|
||||
|
||||
return &types.MessageReceipt{
|
||||
ExitCode: exitcode.Ok,
|
||||
Return: randomBytes(32, rng),
|
||||
GasUsed: rng.Int63(),
|
||||
Events: eventsRoot,
|
||||
}
|
||||
rec := types.NewMessageReceiptV1(exitcode.Ok, randomBytes(32, rng), rng.Int63(), &eventsRoot)
|
||||
return &rec
|
||||
}
|
||||
|
||||
func fakeTipSet(tb testing.TB, rng *pseudo.Rand, h abi.ChainEpoch, parents []cid.Cid) *types.TipSet {
|
||||
|
@ -15,7 +15,6 @@ import (
|
||||
address "github.com/filecoin-project/go-address"
|
||||
abi "github.com/filecoin-project/go-state-types/abi"
|
||||
crypto "github.com/filecoin-project/go-state-types/crypto"
|
||||
exitcode "github.com/filecoin-project/go-state-types/exitcode"
|
||||
proof "github.com/filecoin-project/go-state-types/proof"
|
||||
)
|
||||
|
||||
@ -1289,189 +1288,6 @@ func (t *ActorV5) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufMessageReceipt = []byte{132}
|
||||
|
||||
func (t *MessageReceipt) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
|
||||
cw := cbg.NewCborWriter(w)
|
||||
|
||||
if _, err := cw.Write(lengthBufMessageReceipt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.ExitCode (exitcode.ExitCode) (int64)
|
||||
if t.ExitCode >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ExitCode)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.ExitCode-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.Return ([]uint8) (slice)
|
||||
if len(t.Return) > cbg.ByteArrayMaxLen {
|
||||
return xerrors.Errorf("Byte array in field t.Return was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Return))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := cw.Write(t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.GasUsed (int64) (int64)
|
||||
if t.GasUsed >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.GasUsed)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.GasUsed-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.EventsRoot (cid.Cid) (struct)
|
||||
|
||||
if t.EventsRoot == nil {
|
||||
if _, err := cw.Write(cbg.CborNull); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteCid(cw, *t.EventsRoot); err != nil {
|
||||
return xerrors.Errorf("failed to write cid field t.EventsRoot: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *MessageReceipt) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
*t = MessageReceipt{}
|
||||
|
||||
cr := cbg.NewCborReader(r)
|
||||
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err == io.EOF {
|
||||
err = io.ErrUnexpectedEOF
|
||||
}
|
||||
}()
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 4 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.ExitCode (exitcode.ExitCode) (int64)
|
||||
{
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.ExitCode = exitcode.ExitCode(extraI)
|
||||
}
|
||||
// t.Return ([]uint8) (slice)
|
||||
|
||||
maj, extra, err = cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.ByteArrayMaxLen {
|
||||
return fmt.Errorf("t.Return: byte array too large (%d)", extra)
|
||||
}
|
||||
if maj != cbg.MajByteString {
|
||||
return fmt.Errorf("expected byte array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Return = make([]uint8, extra)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(cr, t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
// t.GasUsed (int64) (int64)
|
||||
{
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.GasUsed = int64(extraI)
|
||||
}
|
||||
// t.EventsRoot (cid.Cid) (struct)
|
||||
|
||||
{
|
||||
|
||||
b, err := cr.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b != cbg.CborNull[0] {
|
||||
if err := cr.UnreadByte(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := cbg.ReadCid(cr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.EventsRoot: %w", err)
|
||||
}
|
||||
|
||||
t.EventsRoot = &c
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufBlockMsg = []byte{131}
|
||||
|
||||
func (t *BlockMsg) MarshalCBOR(w io.Writer) error {
|
||||
|
@ -8,14 +8,52 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
)
|
||||
|
||||
type MessageReceiptVersion byte
|
||||
|
||||
const (
|
||||
// MessageReceiptV0 refers to pre FIP-0049 receipts.
|
||||
MessageReceiptV0 MessageReceiptVersion = 0
|
||||
// MessageReceiptV1 refers to post FIP-0049 receipts.
|
||||
MessageReceiptV1 MessageReceiptVersion = 1
|
||||
)
|
||||
|
||||
type MessageReceipt struct {
|
||||
version MessageReceiptVersion
|
||||
|
||||
ExitCode exitcode.ExitCode
|
||||
Return []byte
|
||||
GasUsed int64
|
||||
EventsRoot *cid.Cid // Root of Event AMT
|
||||
}
|
||||
|
||||
// NewMessageReceiptV0 creates a new pre FIP-0049 receipt with no capability to
|
||||
// convey events.
|
||||
func NewMessageReceiptV0(exitcode exitcode.ExitCode, ret []byte, gasUsed int64) MessageReceipt {
|
||||
return MessageReceipt{
|
||||
version: MessageReceiptV0,
|
||||
ExitCode: exitcode,
|
||||
Return: ret,
|
||||
GasUsed: gasUsed,
|
||||
}
|
||||
}
|
||||
|
||||
// NewMessageReceiptV1 creates a new pre FIP-0049 receipt with the ability to
|
||||
// convey events.
|
||||
func NewMessageReceiptV1(exitcode exitcode.ExitCode, ret []byte, gasUsed int64, eventsRoot *cid.Cid) MessageReceipt {
|
||||
return MessageReceipt{
|
||||
version: MessageReceiptV1,
|
||||
ExitCode: exitcode,
|
||||
Return: ret,
|
||||
GasUsed: gasUsed,
|
||||
EventsRoot: eventsRoot,
|
||||
}
|
||||
}
|
||||
|
||||
func (mr *MessageReceipt) Version() MessageReceiptVersion {
|
||||
return mr.version
|
||||
}
|
||||
|
||||
func (mr *MessageReceipt) Equals(o *MessageReceipt) bool {
|
||||
return mr.ExitCode == o.ExitCode && bytes.Equal(mr.Return, o.Return) && mr.GasUsed == o.GasUsed &&
|
||||
return mr.version == mr.version && mr.ExitCode == o.ExitCode && bytes.Equal(mr.Return, o.Return) && mr.GasUsed == o.GasUsed &&
|
||||
(mr.EventsRoot == o.EventsRoot || (mr.EventsRoot != nil && o.EventsRoot != nil && *mr.EventsRoot == *o.EventsRoot))
|
||||
}
|
||||
|
359
chain/types/message_receipt_cbor.go
Normal file
359
chain/types/message_receipt_cbor.go
Normal file
@ -0,0 +1,359 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
)
|
||||
|
||||
// This file contains custom CBOR serde logic to deal with the new versioned
|
||||
// MessageReceipt resulting from the introduction of actor events (FIP-0049).
|
||||
|
||||
type messageReceiptV0 struct{ *MessageReceipt }
|
||||
|
||||
type messageReceiptV1 struct{ *MessageReceipt }
|
||||
|
||||
func (mr *MessageReceipt) MarshalCBOR(w io.Writer) error {
|
||||
if mr == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
|
||||
var m cbor.Marshaler
|
||||
switch mr.version {
|
||||
case MessageReceiptV0:
|
||||
m = &messageReceiptV0{mr}
|
||||
case MessageReceiptV1:
|
||||
m = &messageReceiptV1{mr}
|
||||
default:
|
||||
return xerrors.Errorf("invalid message receipt version: %d", mr.version)
|
||||
}
|
||||
|
||||
return m.MarshalCBOR(w)
|
||||
}
|
||||
|
||||
func (mr *MessageReceipt) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
*mr = MessageReceipt{}
|
||||
|
||||
cr := cbg.NewCborReader(r)
|
||||
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err == io.EOF {
|
||||
err = io.ErrUnexpectedEOF
|
||||
}
|
||||
}()
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
var u cbor.Unmarshaler
|
||||
switch extra {
|
||||
case 3:
|
||||
mr.version = MessageReceiptV0
|
||||
u = &messageReceiptV0{mr}
|
||||
case 4:
|
||||
mr.version = MessageReceiptV1
|
||||
u = &messageReceiptV1{mr}
|
||||
default:
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// Ok to pass a CBOR reader since cbg.NewCborReader will return itself when
|
||||
// already a CBOR reader.
|
||||
return u.UnmarshalCBOR(cr)
|
||||
}
|
||||
|
||||
var lengthBufAMessageReceiptV0 = []byte{131}
|
||||
|
||||
func (t *messageReceiptV0) MarshalCBOR(w io.Writer) error {
|
||||
// eliding null check since nulls were already handled in the dispatcher
|
||||
|
||||
cw := cbg.NewCborWriter(w)
|
||||
|
||||
if _, err := cw.Write(lengthBufAMessageReceiptV0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.ExitCode (exitcode.ExitCode) (int64)
|
||||
if t.ExitCode >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ExitCode)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.ExitCode-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.Return ([]uint8) (slice)
|
||||
if len(t.Return) > cbg.ByteArrayMaxLen {
|
||||
return xerrors.Errorf("Byte array in field t.Return was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Return))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := cw.Write(t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.GasUsed (int64) (int64)
|
||||
if t.GasUsed >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.GasUsed)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.GasUsed-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *messageReceiptV0) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
cr := cbg.NewCborReader(r)
|
||||
|
||||
// t.ExitCode (exitcode.ExitCode) (int64)
|
||||
{
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.ExitCode = exitcode.ExitCode(extraI)
|
||||
}
|
||||
// t.Return ([]uint8) (slice)
|
||||
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.ByteArrayMaxLen {
|
||||
return fmt.Errorf("t.Return: byte array too large (%d)", extra)
|
||||
}
|
||||
if maj != cbg.MajByteString {
|
||||
return fmt.Errorf("expected byte array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Return = make([]uint8, extra)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(cr, t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
// t.GasUsed (int64) (int64)
|
||||
{
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.GasUsed = extraI
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufBMessageReceiptV1 = []byte{132}
|
||||
|
||||
func (t *messageReceiptV1) MarshalCBOR(w io.Writer) error {
|
||||
// eliding null check since nulls were already handled in the dispatcher
|
||||
|
||||
cw := cbg.NewCborWriter(w)
|
||||
|
||||
if _, err := cw.Write(lengthBufBMessageReceiptV1); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.ExitCode (exitcode.ExitCode) (int64)
|
||||
if t.ExitCode >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ExitCode)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.ExitCode-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.Return ([]uint8) (slice)
|
||||
if len(t.Return) > cbg.ByteArrayMaxLen {
|
||||
return xerrors.Errorf("Byte array in field t.Return was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Return))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := cw.Write(t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.GasUsed (int64) (int64)
|
||||
if t.GasUsed >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.GasUsed)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.GasUsed-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.EventsRoot (cid.Cid) (struct)
|
||||
|
||||
if t.EventsRoot == nil {
|
||||
if _, err := cw.Write(cbg.CborNull); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteCid(cw, *t.EventsRoot); err != nil {
|
||||
return xerrors.Errorf("failed to write cid field t.EventsRoot: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *messageReceiptV1) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
cr := cbg.NewCborReader(r)
|
||||
|
||||
// t.ExitCode (exitcode.ExitCode) (int64)
|
||||
{
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.ExitCode = exitcode.ExitCode(extraI)
|
||||
}
|
||||
// t.Return ([]uint8) (slice)
|
||||
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.ByteArrayMaxLen {
|
||||
return fmt.Errorf("t.Return: byte array too large (%d)", extra)
|
||||
}
|
||||
if maj != cbg.MajByteString {
|
||||
return fmt.Errorf("expected byte array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Return = make([]uint8, extra)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(cr, t.Return[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
// t.GasUsed (int64) (int64)
|
||||
{
|
||||
maj, extra, err := cr.ReadHeader()
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.GasUsed = extraI
|
||||
}
|
||||
// t.EventsRoot (cid.Cid) (struct)
|
||||
|
||||
{
|
||||
|
||||
b, err := cr.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b != cbg.CborNull[0] {
|
||||
if err := cr.UnreadByte(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := cbg.ReadCid(cr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.EventsRoot: %w", err)
|
||||
}
|
||||
|
||||
t.EventsRoot = &c
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
75
chain/types/message_receipt_test.go
Normal file
75
chain/types/message_receipt_test.go
Normal file
@ -0,0 +1,75 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMessageReceiptSerdeRoundrip(t *testing.T) {
|
||||
var (
|
||||
assert = assert.New(t)
|
||||
buf = new(bytes.Buffer)
|
||||
err error
|
||||
)
|
||||
|
||||
randomCid, err := cid.Decode("bafy2bzacecu7n7wbtogznrtuuvf73dsz7wasgyneqasksdblxupnyovmtwxxu")
|
||||
assert.NoError(err)
|
||||
|
||||
//
|
||||
// Version 0
|
||||
//
|
||||
mr := NewMessageReceiptV0(0, []byte{0x00, 0x01, 0x02, 0x04}, 42)
|
||||
|
||||
// marshal
|
||||
err = mr.MarshalCBOR(buf)
|
||||
assert.NoError(err)
|
||||
|
||||
t.Logf("version 0: %s\n", hex.EncodeToString(buf.Bytes()))
|
||||
|
||||
// unmarshal
|
||||
var mr2 MessageReceipt
|
||||
err = mr2.UnmarshalCBOR(buf)
|
||||
assert.NoError(err)
|
||||
assert.Equal(mr, mr2)
|
||||
|
||||
// version 0 with an events root -- should not serialize the events root!
|
||||
mr.EventsRoot = &randomCid
|
||||
|
||||
buf.Reset()
|
||||
|
||||
// marshal
|
||||
err = mr.MarshalCBOR(buf)
|
||||
assert.NoError(err)
|
||||
|
||||
t.Logf("version 0 (with root): %s\n", hex.EncodeToString(buf.Bytes()))
|
||||
|
||||
// unmarshal
|
||||
mr2 = MessageReceipt{}
|
||||
err = mr2.UnmarshalCBOR(buf)
|
||||
assert.NoError(err)
|
||||
assert.NotEqual(mr, mr2)
|
||||
assert.Nil(mr2.EventsRoot)
|
||||
|
||||
//
|
||||
// Version 1
|
||||
//
|
||||
buf.Reset()
|
||||
mr = NewMessageReceiptV1(0, []byte{0x00, 0x01, 0x02, 0x04}, 42, &randomCid)
|
||||
|
||||
// marshal
|
||||
err = mr.MarshalCBOR(buf)
|
||||
assert.NoError(err)
|
||||
|
||||
t.Logf("version 1: %s\n", hex.EncodeToString(buf.Bytes()))
|
||||
|
||||
// unmarshal
|
||||
mr2 = MessageReceipt{}
|
||||
err = mr2.UnmarshalCBOR(buf)
|
||||
assert.NoError(err)
|
||||
assert.Equal(mr, mr2)
|
||||
assert.NotNil(mr2.EventsRoot)
|
||||
}
|
@ -23,6 +23,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/lotus/blockstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@ -275,6 +276,7 @@ func (x *FvmExtern) workerKeyAtLookback(ctx context.Context, minerId address.Add
|
||||
|
||||
type FVM struct {
|
||||
fvm *ffi.FVM
|
||||
nv network.Version
|
||||
}
|
||||
|
||||
func defaultFVMOpts(ctx context.Context, opts *VMOpts) (*ffi.FVMOpts, error) {
|
||||
@ -337,6 +339,7 @@ func NewFVM(ctx context.Context, opts *VMOpts) (*FVM, error) {
|
||||
|
||||
return &FVM{
|
||||
fvm: fvm,
|
||||
nv: opts.NetworkVersion,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -439,6 +442,7 @@ func NewDebugFVM(ctx context.Context, opts *VMOpts) (*FVM, error) {
|
||||
|
||||
return &FVM{
|
||||
fvm: fvm,
|
||||
nv: opts.NetworkVersion,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -457,10 +461,12 @@ func (vm *FVM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet
|
||||
}
|
||||
|
||||
duration := time.Since(start)
|
||||
receipt := types.MessageReceipt{
|
||||
Return: ret.Return,
|
||||
ExitCode: exitcode.ExitCode(ret.ExitCode),
|
||||
GasUsed: ret.GasUsed,
|
||||
|
||||
var receipt types.MessageReceipt
|
||||
if vm.nv >= network.Version18 {
|
||||
receipt = types.NewMessageReceiptV1(exitcode.ExitCode(ret.ExitCode), ret.Return, ret.GasUsed, ret.EventsRoot)
|
||||
} else {
|
||||
receipt = types.NewMessageReceiptV0(exitcode.ExitCode(ret.ExitCode), ret.Return, ret.GasUsed)
|
||||
}
|
||||
|
||||
var aerr aerrors.ActorError
|
||||
@ -521,10 +527,12 @@ func (vm *FVM) ApplyImplicitMessage(ctx context.Context, cmsg *types.Message) (*
|
||||
}
|
||||
|
||||
duration := time.Since(start)
|
||||
receipt := types.MessageReceipt{
|
||||
Return: ret.Return,
|
||||
ExitCode: exitcode.ExitCode(ret.ExitCode),
|
||||
GasUsed: ret.GasUsed,
|
||||
|
||||
var receipt types.MessageReceipt
|
||||
if vm.nv >= network.Version18 {
|
||||
receipt = types.NewMessageReceiptV1(exitcode.ExitCode(ret.ExitCode), ret.Return, ret.GasUsed, ret.EventsRoot)
|
||||
} else {
|
||||
receipt = types.NewMessageReceiptV0(exitcode.ExitCode(ret.ExitCode), ret.Return, ret.GasUsed)
|
||||
}
|
||||
|
||||
var aerr aerrors.ActorError
|
||||
|
@ -28,7 +28,7 @@ func main() {
|
||||
types.MsgMeta{},
|
||||
types.ActorV4{},
|
||||
types.ActorV5{},
|
||||
types.MessageReceipt{},
|
||||
// types.MessageReceipt{}, // Custom serde to deal with versioning.
|
||||
types.BlockMsg{},
|
||||
types.ExpTipSet{},
|
||||
types.BeaconEntry{},
|
||||
|
Loading…
Reference in New Issue
Block a user