package stmgr import ( "context" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" "github.com/ipfs/go-cid" ) type ExecMonitor interface { // MessageApplied is called after a message has been applied. Returning an error will halt execution of any further messages. MessageApplied(ctx context.Context, ts *types.TipSet, mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet, implicit bool) error } var _ ExecMonitor = (*InvocationTracer)(nil) type InvocationTracer struct { trace *[]*api.InvocResult } func (i *InvocationTracer) MessageApplied(ctx context.Context, ts *types.TipSet, mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet, implicit bool) error { ir := &api.InvocResult{ MsgCid: mcid, Msg: msg, MsgRct: &ret.MessageReceipt, ExecutionTrace: ret.ExecutionTrace, Duration: ret.Duration, } if ret.ActorErr != nil { ir.Error = ret.ActorErr.Error() } if ret.GasCosts != nil { ir.GasCost = MakeMsgGasCost(msg, ret) } *i.trace = append(*i.trace, ir) return nil } var _ ExecMonitor = (*messageFinder)(nil) type messageFinder struct { mcid cid.Cid // the message cid to find outm *types.Message outr *vm.ApplyRet } func (m *messageFinder) MessageApplied(ctx context.Context, ts *types.TipSet, mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet, implicit bool) error { if m.mcid == mcid { m.outm = msg m.outr = ret return errHaltExecution // message was found, no need to continue } return nil }