This reverts commit f6add2f723
.
This commit is contained in:
parent
752b961483
commit
d2906e2dc7
154
CHANGELOG.md
154
CHANGELOG.md
@ -36,160 +36,6 @@ This is something we've safely done before. The second upgrade is something of a
|
||||
This release candidate sets the calibration-net nv19 Lighting upgrade at epoch 489394, 2023-04-20T16:30:00Z and nv20 Thunder upgrade will be triggered automatically 11520 epoch later. The bundle the network will be using is [v10.0.0 actors](https://github.com/filecoin-project/builtin-actors/releases/tag/v10.0.0-rc.1)
|
||||
(located at `build/actors/v11.tar.zst`) upon/post migration, manifest CID `bafy2bzacedyne7vbddp2inj64ubztcvkmfkdnahwo353sltkqtsyzckioneuu`.
|
||||
|
||||
# UNRELEASED
|
||||
|
||||
## Execution Trace Format Changes
|
||||
|
||||
Execution traces (returned from `lotus state exec-trace`, `lotus state replay`, etc.), has changed to account for changes introduced by the FVM. Specifically:
|
||||
|
||||
- The `Msg` field no longer matches the Filecoin message format as many of the message fields didn't make sense in on-chain sub-calls. Instead, it now has the fields `To`, `From`, `Value`, `Method`, `Params`, and `ParamsCodec` where `ParamsCodec` is a new field indicating the IPLD codec of the parameters.
|
||||
- Importantly, the `Msg.CID` field has been removed. This field is still present in top-level invocation results, just not inside the execution trace itself.
|
||||
- The `MsgRct` field no longer includes a `GasUsed` field and now has a `ReturnCodec` field to indicating the IPLD codec of the return value.
|
||||
- The `Error` and `Duration` fields have been removed as these are not set by the FVM. The top-level message "invocation result" retains the `Error` and `Duration` fields, they've only been removed from the trace itself.
|
||||
- Gas Charges no longer include "virtual" gas fields (those starting with `v...`) or source location information (`loc`) as neither field is set by the FVM.
|
||||
|
||||
A note on "codecs": FVM parameters and return values are IPLD blocks where the "codec" specifies the data encoding. The codec will generally be one of:
|
||||
|
||||
- `0x51`, `0x71` - CBOR or DagCBOR. You should generally treat these as equivalent.
|
||||
- `0x55` - Raw bytes.
|
||||
- `0x00` - Nothing. If the codec is `0x00`, the parameter and/or return value should be empty and should be treated as "void" (not specified).
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
Old <code>ExecutionTrace</code>:
|
||||
</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"Msg": {
|
||||
"Version": 0,
|
||||
"To": "f01234",
|
||||
"From": "f04321",
|
||||
"Nonce": 1,
|
||||
"Value": "0",
|
||||
"GasLimit": 0,
|
||||
"GasFeeCap": "1234",
|
||||
"GasPremium": "1234",
|
||||
"Method": 42,
|
||||
"Params": "<base64-data-or-null>",
|
||||
"CID": {
|
||||
"/": "bafyxyz....."
|
||||
},
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "<base64-data-or-null>",
|
||||
"GasUsed": 12345,
|
||||
},
|
||||
"Error": "",
|
||||
"Duration": 568191845,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "OnMethodInvocation",
|
||||
"loc": null,
|
||||
"tg": 23856,
|
||||
"cg": 23856,
|
||||
"sg": 0,
|
||||
"vtg": 0,
|
||||
"vcg": 0,
|
||||
"vsg": 0,
|
||||
"tt": 0
|
||||
},
|
||||
{
|
||||
"Name": "wasm_exec",
|
||||
"loc": null,
|
||||
"tg": 1764,
|
||||
"cg": 1764,
|
||||
"sg": 0,
|
||||
"vtg": 0,
|
||||
"vcg": 0,
|
||||
"vsg": 0,
|
||||
"tt": 0
|
||||
},
|
||||
{
|
||||
"Name": "OnSyscall",
|
||||
"loc": null,
|
||||
"tg": 14000,
|
||||
"cg": 14000,
|
||||
"sg": 0,
|
||||
"vtg": 0,
|
||||
"vcg": 0,
|
||||
"vsg": 0,
|
||||
"tt": 0
|
||||
},
|
||||
],
|
||||
"Subcalls": [
|
||||
{
|
||||
"Msg": { },
|
||||
"MsgRct": { },
|
||||
"Error": "",
|
||||
"Duration": 1235,
|
||||
"GasCharges": [],
|
||||
"Subcalls": [],
|
||||
},
|
||||
]
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
New <code>ExecutionTrace</code>:
|
||||
</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"Msg": {
|
||||
"To": "f01234",
|
||||
"From": "f04321",
|
||||
"Value": "0",
|
||||
"Method": 42,
|
||||
"Params": "<base64-data-or-null>",
|
||||
"ParamsCodec": 81
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "<base64-data-or-null>",
|
||||
"ReturnCodec": 81
|
||||
},
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "OnMethodInvocation",
|
||||
"loc": null,
|
||||
"tg": 23856,
|
||||
"cg": 23856,
|
||||
"tt": 0
|
||||
},
|
||||
{
|
||||
"Name": "wasm_exec",
|
||||
"loc": null,
|
||||
"tg": 1764,
|
||||
"cg": 1764,
|
||||
"sg": 0,
|
||||
"tt": 0
|
||||
},
|
||||
{
|
||||
"Name": "OnSyscall",
|
||||
"loc": null,
|
||||
"tg": 14000,
|
||||
"cg": 14000,
|
||||
"sg": 0,
|
||||
"tt": 0
|
||||
},
|
||||
],
|
||||
"Subcalls": [
|
||||
{
|
||||
"Msg": { },
|
||||
"MsgRct": { },
|
||||
"GasCharges": [],
|
||||
"Subcalls": [],
|
||||
},
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
# v1.20.4 / 2023-03-17
|
||||
|
||||
This is a patch release intended to alleviate performance issues reported by some users since the nv18 upgrade.
|
||||
|
@ -152,8 +152,8 @@ func init() {
|
||||
addExample(map[string]int{"name": 42})
|
||||
addExample(map[string]time.Time{"name": time.Unix(1615243938, 0).UTC()})
|
||||
addExample(&types.ExecutionTrace{
|
||||
Msg: ExampleValue("init", reflect.TypeOf(types.MessageTrace{}), nil).(types.MessageTrace),
|
||||
MsgRct: ExampleValue("init", reflect.TypeOf(types.ReturnTrace{}), nil).(types.ReturnTrace),
|
||||
Msg: ExampleValue("init", reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: ExampleValue("init", reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
})
|
||||
addExample(map[string]types.Actor{
|
||||
"t01236": ExampleValue("init", reflect.TypeOf(types.Actor{}), nil).(types.Actor),
|
||||
|
Binary file not shown.
Binary file not shown.
@ -533,11 +533,12 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *stmgr.StateManager, _ st
|
||||
MessageReceipt: *stmgr.MakeFakeRct(),
|
||||
ActorErr: nil,
|
||||
ExecutionTrace: types.ExecutionTrace{
|
||||
Msg: types.MessageTrace{
|
||||
To: fakeMsg.To,
|
||||
From: fakeMsg.From,
|
||||
},
|
||||
Subcalls: subcalls,
|
||||
Msg: fakeMsg,
|
||||
MsgRct: stmgr.MakeFakeRct(),
|
||||
Error: "",
|
||||
Duration: 0,
|
||||
GasCharges: nil,
|
||||
Subcalls: subcalls,
|
||||
},
|
||||
Duration: 0,
|
||||
GasCosts: nil,
|
||||
@ -710,11 +711,12 @@ func splitGenesisMultisig0(ctx context.Context, em stmgr.ExecMonitor, addr addre
|
||||
MessageReceipt: *stmgr.MakeFakeRct(),
|
||||
ActorErr: nil,
|
||||
ExecutionTrace: types.ExecutionTrace{
|
||||
Msg: types.MessageTrace{
|
||||
From: fakeMsg.From,
|
||||
To: fakeMsg.To,
|
||||
},
|
||||
Subcalls: subcalls,
|
||||
Msg: fakeMsg,
|
||||
MsgRct: stmgr.MakeFakeRct(),
|
||||
Error: "",
|
||||
Duration: 0,
|
||||
GasCharges: nil,
|
||||
Subcalls: subcalls,
|
||||
},
|
||||
Duration: 0,
|
||||
GasCosts: nil,
|
||||
|
@ -347,11 +347,12 @@ func DoTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmo
|
||||
// record the transfer in execution traces
|
||||
|
||||
cb(types.ExecutionTrace{
|
||||
Msg: types.MessageTrace{
|
||||
From: from,
|
||||
To: to,
|
||||
Value: amt,
|
||||
},
|
||||
Msg: MakeFakeMsg(from, to, amt, 0),
|
||||
MsgRct: MakeFakeRct(),
|
||||
Error: "",
|
||||
Duration: 0,
|
||||
GasCharges: nil,
|
||||
Subcalls: nil,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"io"
|
||||
"math"
|
||||
"sort"
|
||||
time "time"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@ -16,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"
|
||||
)
|
||||
|
||||
@ -2080,659 +2078,3 @@ func (t *EventEntry) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufGasTrace = []byte{133}
|
||||
|
||||
func (t *GasTrace) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
|
||||
cw := cbg.NewCborWriter(w)
|
||||
|
||||
if _, err := cw.Write(lengthBufGasTrace); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Name (string) (string)
|
||||
if len(t.Name) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field t.Name was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Name))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string(t.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.TotalGas (int64) (int64)
|
||||
if t.TotalGas >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.TotalGas)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.TotalGas-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.ComputeGas (int64) (int64)
|
||||
if t.ComputeGas >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ComputeGas)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.ComputeGas-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.StorageGas (int64) (int64)
|
||||
if t.StorageGas >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.StorageGas)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.StorageGas-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.TimeTaken (time.Duration) (int64)
|
||||
if t.TimeTaken >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.TimeTaken)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.TimeTaken-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *GasTrace) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
*t = GasTrace{}
|
||||
|
||||
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 != 5 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Name (string) (string)
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadString(cr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Name = string(sval)
|
||||
}
|
||||
// t.TotalGas (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.TotalGas = int64(extraI)
|
||||
}
|
||||
// t.ComputeGas (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.ComputeGas = int64(extraI)
|
||||
}
|
||||
// t.StorageGas (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.StorageGas = int64(extraI)
|
||||
}
|
||||
// t.TimeTaken (time.Duration) (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.TimeTaken = time.Duration(extraI)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufMessageTrace = []byte{134}
|
||||
|
||||
func (t *MessageTrace) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
|
||||
cw := cbg.NewCborWriter(w)
|
||||
|
||||
if _, err := cw.Write(lengthBufMessageTrace); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.From (address.Address) (struct)
|
||||
if err := t.From.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.To (address.Address) (struct)
|
||||
if err := t.To.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Value (big.Int) (struct)
|
||||
if err := t.Value.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Method (abi.MethodNum) (uint64)
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Method)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Params ([]uint8) (slice)
|
||||
if len(t.Params) > cbg.ByteArrayMaxLen {
|
||||
return xerrors.Errorf("Byte array in field t.Params was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Params))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := cw.Write(t.Params[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.ParamsCodec (uint64) (uint64)
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ParamsCodec)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *MessageTrace) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
*t = MessageTrace{}
|
||||
|
||||
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 != 6 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.From (address.Address) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.From.UnmarshalCBOR(cr); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.From: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.To (address.Address) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.To.UnmarshalCBOR(cr); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.To: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.Value (big.Int) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Value.UnmarshalCBOR(cr); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Value: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.Method (abi.MethodNum) (uint64)
|
||||
|
||||
{
|
||||
|
||||
maj, extra, err = cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.Method = abi.MethodNum(extra)
|
||||
|
||||
}
|
||||
// t.Params ([]uint8) (slice)
|
||||
|
||||
maj, extra, err = cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > cbg.ByteArrayMaxLen {
|
||||
return fmt.Errorf("t.Params: byte array too large (%d)", extra)
|
||||
}
|
||||
if maj != cbg.MajByteString {
|
||||
return fmt.Errorf("expected byte array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Params = make([]uint8, extra)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(cr, t.Params[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
// t.ParamsCodec (uint64) (uint64)
|
||||
|
||||
{
|
||||
|
||||
maj, extra, err = cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.ParamsCodec = uint64(extra)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufReturnTrace = []byte{131}
|
||||
|
||||
func (t *ReturnTrace) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
|
||||
cw := cbg.NewCborWriter(w)
|
||||
|
||||
if _, err := cw.Write(lengthBufReturnTrace); 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.ReturnCodec (uint64) (uint64)
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ReturnCodec)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ReturnTrace) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
*t = ReturnTrace{}
|
||||
|
||||
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 != 3 {
|
||||
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.ReturnCodec (uint64) (uint64)
|
||||
|
||||
{
|
||||
|
||||
maj, extra, err = cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.ReturnCodec = uint64(extra)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufExecutionTrace = []byte{132}
|
||||
|
||||
func (t *ExecutionTrace) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
|
||||
cw := cbg.NewCborWriter(w)
|
||||
|
||||
if _, err := cw.Write(lengthBufExecutionTrace); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Msg (types.MessageTrace) (struct)
|
||||
if err := t.Msg.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.MsgRct (types.ReturnTrace) (struct)
|
||||
if err := t.MsgRct.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.GasCharges ([]*types.GasTrace) (slice)
|
||||
if len(t.GasCharges) > 1000000000 {
|
||||
return xerrors.Errorf("Slice value in field t.GasCharges was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.GasCharges))); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range t.GasCharges {
|
||||
if err := v.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.Subcalls ([]types.ExecutionTrace) (slice)
|
||||
if len(t.Subcalls) > 1000000000 {
|
||||
return xerrors.Errorf("Slice value in field t.Subcalls was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Subcalls))); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range t.Subcalls {
|
||||
if err := v.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ExecutionTrace) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
*t = ExecutionTrace{}
|
||||
|
||||
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.Msg (types.MessageTrace) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Msg.UnmarshalCBOR(cr); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Msg: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.MsgRct (types.ReturnTrace) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.MsgRct.UnmarshalCBOR(cr); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.MsgRct: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.GasCharges ([]*types.GasTrace) (slice)
|
||||
|
||||
maj, extra, err = cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > 1000000000 {
|
||||
return fmt.Errorf("t.GasCharges: array too large (%d)", extra)
|
||||
}
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("expected cbor array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.GasCharges = make([]*GasTrace, extra)
|
||||
}
|
||||
|
||||
for i := 0; i < int(extra); i++ {
|
||||
|
||||
var v GasTrace
|
||||
if err := v.UnmarshalCBOR(cr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.GasCharges[i] = &v
|
||||
}
|
||||
|
||||
// t.Subcalls ([]types.ExecutionTrace) (slice)
|
||||
|
||||
maj, extra, err = cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > 1000000000 {
|
||||
return fmt.Errorf("t.Subcalls: array too large (%d)", extra)
|
||||
}
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("expected cbor array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Subcalls = make([]ExecutionTrace, extra)
|
||||
}
|
||||
|
||||
for i := 0; i < int(extra); i++ {
|
||||
|
||||
var v ExecutionTrace
|
||||
if err := v.UnmarshalCBOR(cr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Subcalls[i] = v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -2,41 +2,44 @@ package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
)
|
||||
|
||||
type GasTrace struct {
|
||||
Name string
|
||||
TotalGas int64 `json:"tg"`
|
||||
ComputeGas int64 `json:"cg"`
|
||||
StorageGas int64 `json:"sg"`
|
||||
TimeTaken time.Duration `json:"tt"`
|
||||
}
|
||||
|
||||
type MessageTrace struct {
|
||||
From address.Address
|
||||
To address.Address
|
||||
Value abi.TokenAmount
|
||||
Method abi.MethodNum
|
||||
Params []byte
|
||||
ParamsCodec uint64
|
||||
}
|
||||
|
||||
type ReturnTrace struct {
|
||||
ExitCode exitcode.ExitCode
|
||||
Return []byte
|
||||
ReturnCodec uint64
|
||||
}
|
||||
|
||||
type ExecutionTrace struct {
|
||||
Msg MessageTrace
|
||||
MsgRct ReturnTrace
|
||||
GasCharges []*GasTrace `cborgen:"maxlen=1000000000"`
|
||||
Subcalls []ExecutionTrace `cborgen:"maxlen=1000000000"`
|
||||
Msg *Message
|
||||
MsgRct *MessageReceipt
|
||||
Error string
|
||||
Duration time.Duration
|
||||
GasCharges []*GasTrace
|
||||
|
||||
Subcalls []ExecutionTrace
|
||||
}
|
||||
|
||||
type GasTrace struct {
|
||||
Name string
|
||||
|
||||
Location []Loc `json:"loc"`
|
||||
TotalGas int64 `json:"tg"`
|
||||
ComputeGas int64 `json:"cg"`
|
||||
StorageGas int64 `json:"sg"`
|
||||
TotalVirtualGas int64 `json:"vtg"`
|
||||
VirtualComputeGas int64 `json:"vcg"`
|
||||
VirtualStorageGas int64 `json:"vsg"`
|
||||
|
||||
TimeTaken time.Duration `json:"tt"`
|
||||
Extra interface{} `json:"ex,omitempty"`
|
||||
|
||||
Callers []uintptr `json:"-"`
|
||||
}
|
||||
|
||||
type Loc struct {
|
||||
File string
|
||||
Line int
|
||||
Function string
|
||||
}
|
||||
|
||||
func (et ExecutionTrace) SumGas() GasTrace {
|
||||
@ -49,13 +52,71 @@ func SumGas(charges []*GasTrace) GasTrace {
|
||||
out.TotalGas += gc.TotalGas
|
||||
out.ComputeGas += gc.ComputeGas
|
||||
out.StorageGas += gc.StorageGas
|
||||
|
||||
out.TotalVirtualGas += gc.TotalVirtualGas
|
||||
out.VirtualComputeGas += gc.VirtualComputeGas
|
||||
out.VirtualStorageGas += gc.VirtualStorageGas
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (l Loc) Show() bool {
|
||||
ignorePrefix := []string{
|
||||
"reflect.",
|
||||
"github.com/filecoin-project/lotus/chain/vm.(*Invoker).transform",
|
||||
"github.com/filecoin-project/go-amt-ipld/",
|
||||
}
|
||||
for _, pre := range ignorePrefix {
|
||||
if strings.HasPrefix(l.Function, pre) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (l Loc) String() string {
|
||||
file := strings.Split(l.File, "/")
|
||||
|
||||
fn := strings.Split(l.Function, "/")
|
||||
var fnpkg string
|
||||
if len(fn) > 2 {
|
||||
fnpkg = strings.Join(fn[len(fn)-2:], "/")
|
||||
} else {
|
||||
fnpkg = l.Function
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s@%s:%d", fnpkg, file[len(file)-1], l.Line)
|
||||
}
|
||||
|
||||
var importantRegex = regexp.MustCompile(`github.com/filecoin-project/specs-actors/(v\d+/)?actors/builtin`)
|
||||
|
||||
func (l Loc) Important() bool {
|
||||
return importantRegex.MatchString(l.Function)
|
||||
}
|
||||
|
||||
func (gt *GasTrace) MarshalJSON() ([]byte, error) {
|
||||
type GasTraceCopy GasTrace
|
||||
if len(gt.Location) == 0 {
|
||||
if len(gt.Callers) != 0 {
|
||||
frames := runtime.CallersFrames(gt.Callers)
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
if frame.Function == "github.com/filecoin-project/lotus/chain/vm.(*VM).ApplyMessage" {
|
||||
break
|
||||
}
|
||||
l := Loc{
|
||||
File: frame.File,
|
||||
Line: frame.Line,
|
||||
Function: frame.Function,
|
||||
}
|
||||
gt.Location = append(gt.Location, l)
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cpy := (*GasTraceCopy)(gt)
|
||||
return json.Marshal(cpy)
|
||||
}
|
||||
|
391
chain/vm/cbor_gen.go
Normal file
391
chain/vm/cbor_gen.go
Normal file
@ -0,0 +1,391 @@
|
||||
// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
|
||||
|
||||
package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var _ = xerrors.Errorf
|
||||
var _ = cid.Undef
|
||||
var _ = math.E
|
||||
var _ = sort.Sort
|
||||
|
||||
var lengthBufFvmExecutionTrace = []byte{133}
|
||||
|
||||
func (t *FvmExecutionTrace) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
|
||||
cw := cbg.NewCborWriter(w)
|
||||
|
||||
if _, err := cw.Write(lengthBufFvmExecutionTrace); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Msg (types.Message) (struct)
|
||||
if err := t.Msg.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.MsgRct (types.MessageReceipt) (struct)
|
||||
if err := t.MsgRct.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Error (string) (string)
|
||||
if len(t.Error) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field t.Error was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Error))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string(t.Error)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.GasCharges ([]vm.FvmGasCharge) (slice)
|
||||
if len(t.GasCharges) > 1000000000 {
|
||||
return xerrors.Errorf("Slice value in field t.GasCharges was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.GasCharges))); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range t.GasCharges {
|
||||
if err := v.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.Subcalls ([]vm.FvmExecutionTrace) (slice)
|
||||
if len(t.Subcalls) > 1000000000 {
|
||||
return xerrors.Errorf("Slice value in field t.Subcalls was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Subcalls))); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range t.Subcalls {
|
||||
if err := v.MarshalCBOR(cw); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *FvmExecutionTrace) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
*t = FvmExecutionTrace{}
|
||||
|
||||
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 != 5 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Msg (types.Message) (struct)
|
||||
|
||||
{
|
||||
|
||||
b, err := cr.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b != cbg.CborNull[0] {
|
||||
if err := cr.UnreadByte(); err != nil {
|
||||
return err
|
||||
}
|
||||
t.Msg = new(types.Message)
|
||||
if err := t.Msg.UnmarshalCBOR(cr); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Msg pointer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// t.MsgRct (types.MessageReceipt) (struct)
|
||||
|
||||
{
|
||||
|
||||
b, err := cr.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b != cbg.CborNull[0] {
|
||||
if err := cr.UnreadByte(); err != nil {
|
||||
return err
|
||||
}
|
||||
t.MsgRct = new(types.MessageReceipt)
|
||||
if err := t.MsgRct.UnmarshalCBOR(cr); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.MsgRct pointer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// t.Error (string) (string)
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadString(cr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Error = string(sval)
|
||||
}
|
||||
// t.GasCharges ([]vm.FvmGasCharge) (slice)
|
||||
|
||||
maj, extra, err = cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > 1000000000 {
|
||||
return fmt.Errorf("t.GasCharges: array too large (%d)", extra)
|
||||
}
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("expected cbor array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.GasCharges = make([]FvmGasCharge, extra)
|
||||
}
|
||||
|
||||
for i := 0; i < int(extra); i++ {
|
||||
|
||||
var v FvmGasCharge
|
||||
if err := v.UnmarshalCBOR(cr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.GasCharges[i] = v
|
||||
}
|
||||
|
||||
// t.Subcalls ([]vm.FvmExecutionTrace) (slice)
|
||||
|
||||
maj, extra, err = cr.ReadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if extra > 1000000000 {
|
||||
return fmt.Errorf("t.Subcalls: array too large (%d)", extra)
|
||||
}
|
||||
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("expected cbor array")
|
||||
}
|
||||
|
||||
if extra > 0 {
|
||||
t.Subcalls = make([]FvmExecutionTrace, extra)
|
||||
}
|
||||
|
||||
for i := 0; i < int(extra); i++ {
|
||||
|
||||
var v FvmExecutionTrace
|
||||
if err := v.UnmarshalCBOR(cr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Subcalls[i] = v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var lengthBufFvmGasCharge = []byte{132}
|
||||
|
||||
func (t *FvmGasCharge) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
|
||||
cw := cbg.NewCborWriter(w)
|
||||
|
||||
if _, err := cw.Write(lengthBufFvmGasCharge); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Name (string) (string)
|
||||
if len(t.Name) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field t.Name was too long")
|
||||
}
|
||||
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Name))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string(t.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.TotalGas (int64) (int64)
|
||||
if t.TotalGas >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.TotalGas)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.TotalGas-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.ComputeGas (int64) (int64)
|
||||
if t.ComputeGas >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ComputeGas)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.ComputeGas-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.StorageGas (int64) (int64)
|
||||
if t.StorageGas >= 0 {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.StorageGas)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.StorageGas-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *FvmGasCharge) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
*t = FvmGasCharge{}
|
||||
|
||||
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.Name (string) (string)
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadString(cr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Name = string(sval)
|
||||
}
|
||||
// t.TotalGas (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.TotalGas = int64(extraI)
|
||||
}
|
||||
// t.ComputeGas (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.ComputeGas = int64(extraI)
|
||||
}
|
||||
// t.StorageGas (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.StorageGas = int64(extraI)
|
||||
}
|
||||
return nil
|
||||
}
|
@ -51,6 +51,57 @@ type FvmExtern struct {
|
||||
base cid.Cid
|
||||
}
|
||||
|
||||
type FvmGasCharge struct {
|
||||
Name string
|
||||
TotalGas int64
|
||||
ComputeGas int64
|
||||
StorageGas int64
|
||||
}
|
||||
|
||||
// This may eventually become identical to ExecutionTrace, but we can make incremental progress towards that
|
||||
type FvmExecutionTrace struct {
|
||||
Msg *types.Message
|
||||
MsgRct *types.MessageReceipt
|
||||
Error string
|
||||
GasCharges []FvmGasCharge `cborgen:"maxlen=1000000000"`
|
||||
Subcalls []FvmExecutionTrace `cborgen:"maxlen=1000000000"`
|
||||
}
|
||||
|
||||
func (t *FvmExecutionTrace) ToExecutionTrace() types.ExecutionTrace {
|
||||
if t == nil {
|
||||
return types.ExecutionTrace{}
|
||||
}
|
||||
|
||||
ret := types.ExecutionTrace{
|
||||
Msg: t.Msg,
|
||||
MsgRct: t.MsgRct,
|
||||
Error: t.Error,
|
||||
Subcalls: nil, // Should be nil when there are no subcalls for backwards compatibility
|
||||
}
|
||||
|
||||
if len(t.GasCharges) > 0 {
|
||||
ret.GasCharges = make([]*types.GasTrace, len(t.GasCharges))
|
||||
for i, v := range t.GasCharges {
|
||||
ret.GasCharges[i] = &types.GasTrace{
|
||||
Name: v.Name,
|
||||
TotalGas: v.TotalGas,
|
||||
ComputeGas: v.ComputeGas,
|
||||
StorageGas: v.StorageGas,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(t.Subcalls) > 0 {
|
||||
ret.Subcalls = make([]types.ExecutionTrace, len(t.Subcalls))
|
||||
|
||||
for i, v := range t.Subcalls {
|
||||
ret.Subcalls[i] = v.ToExecutionTrace()
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (x *FvmExtern) TipsetCid(ctx context.Context, epoch abi.ChainEpoch) (cid.Cid, error) {
|
||||
tsk, err := x.tsGet(ctx, epoch)
|
||||
if err != nil {
|
||||
@ -436,9 +487,19 @@ func (vm *FVM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet
|
||||
|
||||
var et types.ExecutionTrace
|
||||
if len(ret.ExecTraceBytes) != 0 {
|
||||
if err = et.UnmarshalCBOR(bytes.NewReader(ret.ExecTraceBytes)); err != nil {
|
||||
var fvmEt FvmExecutionTrace
|
||||
if err = fvmEt.UnmarshalCBOR(bytes.NewReader(ret.ExecTraceBytes)); err != nil {
|
||||
return nil, xerrors.Errorf("failed to unmarshal exectrace: %w", err)
|
||||
}
|
||||
et = fvmEt.ToExecutionTrace()
|
||||
}
|
||||
|
||||
// Set the top-level exectrace info from the message and receipt for backwards compatibility
|
||||
et.Msg = vmMsg
|
||||
et.MsgRct = &receipt
|
||||
et.Duration = duration
|
||||
if aerr != nil {
|
||||
et.Error = aerr.Error()
|
||||
}
|
||||
|
||||
applyRet := &ApplyRet{
|
||||
@ -501,9 +562,18 @@ func (vm *FVM) ApplyImplicitMessage(ctx context.Context, cmsg *types.Message) (*
|
||||
|
||||
var et types.ExecutionTrace
|
||||
if len(ret.ExecTraceBytes) != 0 {
|
||||
if err = et.UnmarshalCBOR(bytes.NewReader(ret.ExecTraceBytes)); err != nil {
|
||||
var fvmEt FvmExecutionTrace
|
||||
if err = fvmEt.UnmarshalCBOR(bytes.NewReader(ret.ExecTraceBytes)); err != nil {
|
||||
return nil, xerrors.Errorf("failed to unmarshal exectrace: %w", err)
|
||||
}
|
||||
et = fvmEt.ToExecutionTrace()
|
||||
} else {
|
||||
et.Msg = vmMsg
|
||||
et.MsgRct = &receipt
|
||||
et.Duration = duration
|
||||
if aerr != nil {
|
||||
et.Error = aerr.Error()
|
||||
}
|
||||
}
|
||||
|
||||
applyRet := &ApplyRet{
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os"
|
||||
gruntime "runtime"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -570,18 +571,35 @@ func (rt *Runtime) chargeGasFunc(skip int) func(GasCharge) {
|
||||
func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError {
|
||||
toUse := gas.Total()
|
||||
if EnableDetailedTracing {
|
||||
var callers [10]uintptr
|
||||
|
||||
cout := gruntime.Callers(2+skip, callers[:])
|
||||
|
||||
now := build.Clock.Now()
|
||||
if rt.lastGasCharge != nil {
|
||||
rt.lastGasCharge.TimeTaken = now.Sub(rt.lastGasChargeTime)
|
||||
}
|
||||
|
||||
gasTrace := types.GasTrace{
|
||||
Name: gas.Name,
|
||||
Name: gas.Name,
|
||||
Extra: gas.Extra,
|
||||
|
||||
TotalGas: toUse,
|
||||
ComputeGas: gas.ComputeGas,
|
||||
StorageGas: gas.StorageGas,
|
||||
|
||||
VirtualComputeGas: gas.VirtualCompute,
|
||||
VirtualStorageGas: gas.VirtualStorage,
|
||||
|
||||
Callers: callers[:cout],
|
||||
}
|
||||
if gasTrace.VirtualStorageGas == 0 {
|
||||
gasTrace.VirtualStorageGas = gasTrace.StorageGas
|
||||
}
|
||||
if gasTrace.VirtualComputeGas == 0 {
|
||||
gasTrace.VirtualComputeGas = gasTrace.ComputeGas
|
||||
}
|
||||
gasTrace.TotalVirtualGas = gasTrace.VirtualComputeGas + gasTrace.VirtualStorageGas
|
||||
|
||||
rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace)
|
||||
rt.lastGasChargeTime = now
|
||||
|
@ -38,7 +38,6 @@ import (
|
||||
)
|
||||
|
||||
const MaxCallDepth = 4096
|
||||
const CborCodec = 0x51
|
||||
|
||||
var (
|
||||
log = logging.Logger("vm")
|
||||
@ -126,10 +125,6 @@ func (bs *gasChargingBlocks) Put(ctx context.Context, blk block.Block) error {
|
||||
}
|
||||
|
||||
func (vm *LegacyVM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runtime) *Runtime {
|
||||
paramsCodec := uint64(0)
|
||||
if len(msg.Params) > 0 {
|
||||
paramsCodec = CborCodec
|
||||
}
|
||||
rt := &Runtime{
|
||||
ctx: ctx,
|
||||
vm: vm,
|
||||
@ -145,14 +140,7 @@ func (vm *LegacyVM) makeRuntime(ctx context.Context, msg *types.Message, parent
|
||||
pricelist: PricelistByEpoch(vm.blockHeight),
|
||||
allowInternal: true,
|
||||
callerValidated: false,
|
||||
executionTrace: types.ExecutionTrace{Msg: types.MessageTrace{
|
||||
From: msg.From,
|
||||
To: msg.To,
|
||||
Value: msg.Value,
|
||||
Method: msg.Method,
|
||||
Params: msg.Params,
|
||||
ParamsCodec: paramsCodec,
|
||||
}},
|
||||
executionTrace: types.ExecutionTrace{Msg: msg},
|
||||
}
|
||||
|
||||
if parent != nil {
|
||||
@ -381,14 +369,15 @@ func (vm *LegacyVM) send(ctx context.Context, msg *types.Message, parent *Runtim
|
||||
return nil, nil
|
||||
}()
|
||||
|
||||
retCodec := uint64(0)
|
||||
if len(ret) > 0 {
|
||||
retCodec = CborCodec
|
||||
mr := types.MessageReceipt{
|
||||
ExitCode: aerrors.RetCode(err),
|
||||
Return: ret,
|
||||
GasUsed: rt.gasUsed,
|
||||
}
|
||||
rt.executionTrace.MsgRct = types.ReturnTrace{
|
||||
ExitCode: aerrors.RetCode(err),
|
||||
Return: ret,
|
||||
ReturnCodec: retCodec,
|
||||
rt.executionTrace.MsgRct = &mr
|
||||
rt.executionTrace.Duration = time.Since(start)
|
||||
if err != nil {
|
||||
rt.executionTrace.Error = err.Error()
|
||||
}
|
||||
|
||||
return ret, err, rt
|
||||
|
102
cli/state.go
102
cli/state.go
@ -22,6 +22,7 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/multiformats/go-multihash"
|
||||
"github.com/urfave/cli/v2"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
@ -1227,7 +1228,7 @@ var compStateTemplate = `
|
||||
<div>State CID: <b>{{.Comp.Root}}</b></div>
|
||||
<div>Calls</div>
|
||||
{{range .Comp.Trace}}
|
||||
{{template "message" (Call .ExecutionTrace false .MsgCid.String)}}
|
||||
{{template "message" (Call .ExecutionTrace false .Msg.Cid.String)}}
|
||||
{{end}}
|
||||
</body>
|
||||
</html>
|
||||
@ -1252,12 +1253,16 @@ var compStateMsg = `
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div><b>{{.Msg.From}}</b> -> <b>{{.Msg.To}}</b> ({{ToFil .Msg.Value}}), M{{.Msg.Method}}</div>
|
||||
{{if not .Subcall}}<div><small>Msg CID: {{.Hash}}</small></div>{{end}}
|
||||
<div><b>{{.Msg.From}}</b> -> <b>{{.Msg.To}}</b> ({{ToFil .Msg.Value}} FIL), M{{.Msg.Method}}</div>
|
||||
{{if not .Subcall}}<div><small>Msg CID: {{.Msg.Cid}}</small></div>{{end}}
|
||||
{{if gt (len .Msg.Params) 0}}
|
||||
<div><pre class="params">{{JsonParams ($code) (.Msg.Method) (.Msg.Params) | html}}</pre></div>
|
||||
{{end}}
|
||||
{{if PrintTiming}}
|
||||
<div><span class="slow-{{IsSlow .Duration}}-{{IsVerySlow .Duration}}">Took {{.Duration}}</span>, <span class="exit{{IntExit .MsgRct.ExitCode}}">Exit: <b>{{.MsgRct.ExitCode}}</b></span>{{if gt (len .MsgRct.Return) 0}}, Return{{end}}</div>
|
||||
{{else}}
|
||||
<div><span class="exit{{IntExit .MsgRct.ExitCode}}">Exit: <b>{{.MsgRct.ExitCode}}</b></span>{{if gt (len .MsgRct.Return) 0}}, Return{{end}}</div>
|
||||
{{end}}
|
||||
{{if gt (len .MsgRct.Return) 0}}
|
||||
<div><pre class="ret">{{JsonReturn ($code) (.Msg.Method) (.MsgRct.Return) | html}}</pre></div>
|
||||
{{end}}
|
||||
@ -1269,26 +1274,62 @@ var compStateMsg = `
|
||||
<details>
|
||||
<summary>Gas Trace</summary>
|
||||
<table>
|
||||
<tr><th>Name</th><th>Total/Compute/Storage</th><th>Time Taken</th></tr>
|
||||
<tr><th>Name</th><th>Total/Compute/Storage</th><th>Time Taken</th><th>Location</th></tr>
|
||||
{{define "virt" -}}
|
||||
{{- if . -}}
|
||||
<span class="deemp">+({{.}})</span>
|
||||
{{- end -}}
|
||||
{{- end}}
|
||||
|
||||
{{define "gasC" -}}
|
||||
<td>{{.TotalGas}}/{{.ComputeGas}}/{{.StorageGas}}</td>
|
||||
<td>{{.TotalGas}}{{template "virt" .TotalVirtualGas }}/{{.ComputeGas}}{{template "virt" .VirtualComputeGas}}/{{.StorageGas}}{{template "virt" .VirtualStorageGas}}</td>
|
||||
{{- end}}
|
||||
|
||||
{{range .GasCharges}}
|
||||
<tr>
|
||||
<td>{{.Name}}</td>
|
||||
{{template "gasC" .}}
|
||||
<td>{{if PrintTiming}}{{.TimeTaken}}{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{with sumGas .GasCharges}}
|
||||
<tr class="sum">
|
||||
<td><b>Sum</b></td>
|
||||
{{template "gasC" .}}
|
||||
<td>{{if PrintTiming}}{{.TimeTaken}}{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
<tr><td>{{.Name}}{{if .Extra}}:{{.Extra}}{{end}}</td>
|
||||
{{template "gasC" .}}
|
||||
<td>{{if PrintTiming}}{{.TimeTaken}}{{end}}</td>
|
||||
<td>
|
||||
{{ $fImp := FirstImportant .Location }}
|
||||
{{ if $fImp }}
|
||||
<details>
|
||||
<summary>{{ $fImp }}</summary><hr />
|
||||
{{ $elipOn := false }}
|
||||
{{ range $index, $ele := .Location -}}
|
||||
{{- if $index }}<br />{{end -}}
|
||||
{{- if .Show -}}
|
||||
{{ if $elipOn }}
|
||||
{{ $elipOn = false }}
|
||||
</span></label>
|
||||
{{end}}
|
||||
|
||||
{{- if .Important }}<b>{{end -}}
|
||||
{{- . -}}
|
||||
{{if .Important }}</b>{{end}}
|
||||
{{else}}
|
||||
{{ if not $elipOn }}
|
||||
{{ $elipOn = true }}
|
||||
<label class="ellipsis-toggle"><input type="checkbox" /><span class="ellipsis">[…]<br /></span>
|
||||
<span class="ellipsis-content">
|
||||
{{end}}
|
||||
{{- "" -}}
|
||||
{{- . -}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{ if $elipOn }}
|
||||
{{ $elipOn = false }}
|
||||
</span></label>
|
||||
{{end}}
|
||||
</details>
|
||||
{{end}}
|
||||
</td></tr>
|
||||
{{end}}
|
||||
{{with sumGas .GasCharges}}
|
||||
<tr class="sum"><td><b>Sum</b></td>
|
||||
{{template "gasC" .}}
|
||||
<td>{{if PrintTiming}}{{.TimeTaken}}{{end}}</td>
|
||||
<td></td></tr>
|
||||
{{end}}
|
||||
</table>
|
||||
</details>
|
||||
|
||||
@ -1296,8 +1337,8 @@ var compStateMsg = `
|
||||
{{if gt (len .Subcalls) 0}}
|
||||
<div>Subcalls:</div>
|
||||
{{$hash := .Hash}}
|
||||
{{range $i, $call := .Subcalls}}
|
||||
{{template "message" (Call $call true (printf "%s-%d" $hash $i))}}
|
||||
{{range .Subcalls}}
|
||||
{{template "message" (Call . true (printf "%s-%s" $hash .Msg.Cid.String))}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>`
|
||||
@ -1318,9 +1359,20 @@ func ComputeStateHTMLTempl(w io.Writer, ts *types.TipSet, o *api.ComputeStateOut
|
||||
"IsVerySlow": isVerySlow,
|
||||
"IntExit": func(i exitcode.ExitCode) int64 { return int64(i) },
|
||||
"sumGas": types.SumGas,
|
||||
"CodeStr": builtin.ActorNameByCode,
|
||||
"CodeStr": codeStr,
|
||||
"Call": call,
|
||||
"PrintTiming": func() bool { return printTiming },
|
||||
"FirstImportant": func(locs []types.Loc) *types.Loc {
|
||||
if len(locs) != 0 {
|
||||
for _, l := range locs {
|
||||
if l.Important() {
|
||||
return &l
|
||||
}
|
||||
}
|
||||
return &locs[0]
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}).Parse(compStateTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1350,6 +1402,14 @@ func call(e types.ExecutionTrace, subcall bool, hash string) callMeta {
|
||||
}
|
||||
}
|
||||
|
||||
func codeStr(c cid.Cid) string {
|
||||
cmh, err := multihash.Decode(c.Hash())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(cmh.Digest)
|
||||
}
|
||||
|
||||
func getMethod(code cid.Cid, method abi.MethodNum) string {
|
||||
return filcns.NewActorRegistry().Methods[code][method].Name // todo: use remote
|
||||
}
|
||||
|
@ -466,11 +466,14 @@ var importBenchCmd = &cli.Command{
|
||||
Duration: time.Since(start),
|
||||
}
|
||||
if enc != nil {
|
||||
stripCallers(tse.Trace)
|
||||
|
||||
if err := enc.Encode(tse); err != nil {
|
||||
return xerrors.Errorf("failed to write out tipsetexec: %w", err)
|
||||
}
|
||||
}
|
||||
if inverseChain[i-1].ParentState() != st {
|
||||
stripCallers(tse.Trace)
|
||||
lastTrace := tse.Trace
|
||||
d, err := json.MarshalIndent(lastTrace, "", " ")
|
||||
if err != nil {
|
||||
@ -489,6 +492,21 @@ var importBenchCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func walkExecutionTrace(et *types.ExecutionTrace) {
|
||||
for _, gc := range et.GasCharges {
|
||||
gc.Callers = nil
|
||||
}
|
||||
for _, sub := range et.Subcalls {
|
||||
walkExecutionTrace(&sub) //nolint:scopelint,gosec
|
||||
}
|
||||
}
|
||||
|
||||
func stripCallers(trace []*api.InvocResult) {
|
||||
for _, t := range trace {
|
||||
walkExecutionTrace(&t.ExecutionTrace)
|
||||
}
|
||||
}
|
||||
|
||||
type Invocation struct {
|
||||
TipSet types.TipSetKey
|
||||
Invoc *api.InvocResult
|
||||
@ -496,24 +514,28 @@ type Invocation struct {
|
||||
|
||||
const GasPerNs = 10
|
||||
|
||||
func countGasCosts(et *types.ExecutionTrace) int64 {
|
||||
var cgas int64
|
||||
func countGasCosts(et *types.ExecutionTrace) (int64, int64) {
|
||||
var cgas, vgas int64
|
||||
|
||||
for _, gc := range et.GasCharges {
|
||||
cgas += gc.ComputeGas
|
||||
vgas += gc.VirtualComputeGas
|
||||
}
|
||||
|
||||
for _, sub := range et.Subcalls {
|
||||
c := countGasCosts(&sub) //nolint
|
||||
c, v := countGasCosts(&sub) //nolint
|
||||
cgas += c
|
||||
vgas += v
|
||||
}
|
||||
|
||||
return cgas
|
||||
return cgas, vgas
|
||||
}
|
||||
|
||||
type stats struct {
|
||||
timeTaken meanVar
|
||||
gasRatio meanVar
|
||||
|
||||
extraCovar *covar
|
||||
}
|
||||
|
||||
type covar struct {
|
||||
@ -658,8 +680,32 @@ func (v1 *meanVar) Combine(v2 *meanVar) {
|
||||
v1.m2 = m2
|
||||
}
|
||||
|
||||
func getExtras(ex interface{}) (*string, *float64) {
|
||||
if t, ok := ex.(string); ok {
|
||||
return &t, nil
|
||||
}
|
||||
if size, ok := ex.(float64); ok {
|
||||
return nil, &size
|
||||
}
|
||||
if exMap, ok := ex.(map[string]interface{}); ok {
|
||||
t, tok := exMap["type"].(string)
|
||||
size, sok := exMap["size"].(float64)
|
||||
if tok && sok {
|
||||
return &t, &size
|
||||
}
|
||||
if tok {
|
||||
return &t, nil
|
||||
}
|
||||
if sok {
|
||||
return nil, &size
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) {
|
||||
for _, gc := range et.GasCharges {
|
||||
for i, gc := range et.GasCharges {
|
||||
name := gc.Name
|
||||
if name == "OnIpldGetEnd" {
|
||||
continue
|
||||
@ -670,18 +716,45 @@ func tallyGasCharges(charges map[string]*stats, et types.ExecutionTrace) {
|
||||
// discard initial very long OnVerifyPost
|
||||
continue
|
||||
}
|
||||
eType, eSize := getExtras(gc.Extra)
|
||||
|
||||
if name == "OnIpldGet" {
|
||||
next := &types.GasTrace{}
|
||||
if i+1 < len(et.GasCharges) {
|
||||
next = et.GasCharges[i+1]
|
||||
}
|
||||
if next.Name != "OnIpldGetEnd" {
|
||||
log.Warn("OnIpldGet without OnIpldGetEnd")
|
||||
} else {
|
||||
_, size := getExtras(next.Extra)
|
||||
eSize = size
|
||||
}
|
||||
}
|
||||
if eType != nil {
|
||||
name += "-" + *eType
|
||||
}
|
||||
compGas := gc.ComputeGas
|
||||
if compGas == 0 {
|
||||
compGas = gc.VirtualComputeGas
|
||||
}
|
||||
if compGas == 0 {
|
||||
compGas = 1
|
||||
}
|
||||
s := charges[name]
|
||||
if s == nil {
|
||||
s = new(stats)
|
||||
charges[name] = s
|
||||
}
|
||||
|
||||
if eSize != nil {
|
||||
if s.extraCovar == nil {
|
||||
s.extraCovar = &covar{}
|
||||
}
|
||||
s.extraCovar.AddPoint(*eSize, tt)
|
||||
}
|
||||
|
||||
s.timeTaken.AddPoint(tt)
|
||||
|
||||
if compGas == 0 {
|
||||
compGas = 1
|
||||
}
|
||||
ratio := tt / float64(compGas) * GasPerNs
|
||||
s.gasRatio.AddPoint(ratio)
|
||||
}
|
||||
@ -807,6 +880,13 @@ var importAnalyzeCmd = &cli.Command{
|
||||
}
|
||||
s.timeTaken.Combine(&v.timeTaken)
|
||||
s.gasRatio.Combine(&v.gasRatio)
|
||||
|
||||
if v.extraCovar != nil {
|
||||
if s.extraCovar == nil {
|
||||
s.extraCovar = &covar{}
|
||||
}
|
||||
s.extraCovar.Combine(v.extraCovar)
|
||||
}
|
||||
}
|
||||
totalTime += res.totalTime
|
||||
}
|
||||
@ -822,6 +902,13 @@ var importAnalyzeCmd = &cli.Command{
|
||||
s := charges[k]
|
||||
fmt.Printf("%s: incr by %.4f~%.4f; tt %.4f~%.4f\n", k, s.gasRatio.Mean(), s.gasRatio.Stddev(),
|
||||
s.timeTaken.Mean(), s.timeTaken.Stddev())
|
||||
if s.extraCovar != nil {
|
||||
fmt.Printf("\t correll: %.2f, tt = %.2f * extra + %.2f\n", s.extraCovar.Correl(),
|
||||
s.extraCovar.A(), s.extraCovar.B())
|
||||
fmt.Printf("\t covar: %.2f, extra: %.2f~%.2f, tt2: %.2f~%.2f, count %.0f\n",
|
||||
s.extraCovar.Covariance(), s.extraCovar.meanX, s.extraCovar.StddevX(),
|
||||
s.extraCovar.meanY, s.extraCovar.StddevY(), s.extraCovar.n)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(invocs, func(i, j int) bool {
|
||||
|
@ -4866,49 +4866,95 @@ Response:
|
||||
},
|
||||
"ExecutionTrace": {
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": [
|
||||
{
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": null
|
||||
@ -5096,49 +5142,95 @@ Response:
|
||||
},
|
||||
"ExecutionTrace": {
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": [
|
||||
{
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": null
|
||||
@ -6484,49 +6576,95 @@ Response:
|
||||
},
|
||||
"ExecutionTrace": {
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": [
|
||||
{
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": null
|
||||
|
@ -6136,49 +6136,95 @@ Response:
|
||||
},
|
||||
"ExecutionTrace": {
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": [
|
||||
{
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": null
|
||||
@ -6366,49 +6412,95 @@ Response:
|
||||
},
|
||||
"ExecutionTrace": {
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": [
|
||||
{
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": null
|
||||
@ -7837,49 +7929,95 @@ Response:
|
||||
},
|
||||
"ExecutionTrace": {
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": [
|
||||
{
|
||||
"Msg": {
|
||||
"From": "f01234",
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"ParamsCodec": 42
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"ReturnCodec": 42
|
||||
"GasUsed": 9,
|
||||
"EventsRoot": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": [
|
||||
{
|
||||
"Name": "string value",
|
||||
"loc": [
|
||||
{
|
||||
"File": "string value",
|
||||
"Line": 123,
|
||||
"Function": "string value"
|
||||
}
|
||||
],
|
||||
"tg": 9,
|
||||
"cg": 9,
|
||||
"sg": 9,
|
||||
"tt": 60000000000
|
||||
"vtg": 9,
|
||||
"vcg": 9,
|
||||
"vsg": 9,
|
||||
"tt": 60000000000,
|
||||
"ex": {}
|
||||
}
|
||||
],
|
||||
"Subcalls": null
|
||||
|
2
extern/filecoin-ffi
vendored
2
extern/filecoin-ffi
vendored
@ -1 +1 @@
|
||||
Subproject commit 41a1e40fb22fb589e5cdb17b4c41e01013656812
|
||||
Subproject commit ca72a82aedb3330dcb75067a42ff7e8dd252c78d
|
15
gen/main.go
15
gen/main.go
@ -11,6 +11,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/exchange"
|
||||
"github.com/filecoin-project/lotus/chain/market"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/cmd/lotus-shed/shedgen"
|
||||
"github.com/filecoin-project/lotus/node/hello"
|
||||
"github.com/filecoin-project/lotus/paychmgr"
|
||||
@ -36,11 +37,15 @@ func main() {
|
||||
types.StateInfo0{},
|
||||
types.Event{},
|
||||
types.EventEntry{},
|
||||
// Tracing
|
||||
types.GasTrace{},
|
||||
types.MessageTrace{},
|
||||
types.ReturnTrace{},
|
||||
types.ExecutionTrace{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = gen.WriteTupleEncodersToFile("./chain/vm/cbor_gen.go", "vm",
|
||||
vm.FvmExecutionTrace{},
|
||||
vm.FvmGasCharge{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
Loading…
Reference in New Issue
Block a user