package types import ( "bytes" "fmt" "github.com/filecoin-project/specs-actors/actors/abi" block "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/multiformats/go-multihash" "github.com/filecoin-project/go-address" ) type ChainMsg interface { Cid() cid.Cid VMMessage() *Message ToStorageBlock() (block.Block, error) ChainLength() int } type Message struct { To address.Address From address.Address Nonce uint64 Value BigInt GasPrice BigInt GasLimit int64 Method abi.MethodNum Params []byte } func (t *Message) BlockMiner() address.Address { panic("implement me") } func (t *Message) Caller() address.Address { return t.From } func (t *Message) Receiver() address.Address { return t.To } func (t *Message) ValueReceived() abi.TokenAmount { return t.Value } func DecodeMessage(b []byte) (*Message, error) { var msg Message if err := msg.UnmarshalCBOR(bytes.NewReader(b)); err != nil { return nil, err } return &msg, nil } func (m *Message) Serialize() ([]byte, error) { buf := new(bytes.Buffer) if err := m.MarshalCBOR(buf); err != nil { return nil, err } return buf.Bytes(), nil } func (m *Message) ChainLength() int { ser, err := m.Serialize() if err != nil { panic(err) } return len(ser) } func (m *Message) ToStorageBlock() (block.Block, error) { data, err := m.Serialize() if err != nil { return nil, err } pref := cid.NewPrefixV1(cid.DagCBOR, multihash.BLAKE2B_MIN+31) c, err := pref.Sum(data) if err != nil { return nil, err } return block.NewBlockWithCid(data, c) } func (m *Message) Cid() cid.Cid { b, err := m.ToStorageBlock() if err != nil { panic(fmt.Sprintf("failed to marshal message: %s", err)) // I think this is maybe sketchy, what happens if we try to serialize a message with an undefined address in it? } return b.Cid() } func (m *Message) RequiredFunds() BigInt { return BigAdd( m.Value, BigMul(m.GasPrice, NewInt(uint64(m.GasLimit))), ) } func (m *Message) VMMessage() *Message { return m } func (m *Message) Equals(o *Message) bool { return m.Cid() == o.Cid() }