Skip to content

Commit

Permalink
Merge pull request #4219 from filecoin-project/merge-master-to-next
Browse files Browse the repository at this point in the history
Merge branch 'master' into merge-master-to-next
  • Loading branch information
magik6k authored Oct 7, 2020
2 parents f6eb530 + df4b068 commit 5ef929f
Show file tree
Hide file tree
Showing 15 changed files with 607 additions and 135 deletions.
6 changes: 5 additions & 1 deletion build/params_testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package build

import (
"os"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors/policy"
Expand Down Expand Up @@ -39,7 +41,9 @@ func init() {
abi.RegisteredSealProof_StackedDrg64GiBV1,
)

SetAddressNetwork(address.Mainnet)
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {
SetAddressNetwork(address.Mainnet)
}

Devnet = false
}
Expand Down
180 changes: 180 additions & 0 deletions chain/actors/builtin/miner/diff_deadlines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package miner

import (
"errors"

"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-state-types/exitcode"
)

type DeadlinesDiff map[uint64]*DeadlineDiff

func DiffDeadlines(pre, cur State) (*DeadlinesDiff, error) {
changed, err := pre.DeadlinesChanged(cur)
if err != nil {
return nil, err
}
if !changed {
return nil, nil
}

numDl, err := pre.NumDeadlines()
if err != nil {
return nil, err
}
dlDiff := make(DeadlinesDiff, numDl)
if err := pre.ForEachDeadline(func(idx uint64, preDl Deadline) error {
curDl, err := cur.LoadDeadline(idx)
if err != nil {
return err
}

diff, err := DiffDeadline(preDl, curDl)
if err != nil {
return err
}

dlDiff[idx] = diff
return nil
}); err != nil {
return nil, err
}
return &dlDiff, nil
}

type DeadlineDiff map[uint64]*PartitionDiff

func DiffDeadline(pre, cur Deadline) (*DeadlineDiff, error) {
changed, err := pre.PartitionsChanged(cur)
if err != nil {
return nil, err
}
if !changed {
return nil, nil
}

partDiff := make(DeadlineDiff)
if err := pre.ForEachPartition(func(idx uint64, prePart Partition) error {
// try loading current partition at this index
curPart, err := cur.LoadPartition(idx)
if err != nil {
if errors.Is(err, exitcode.ErrNotFound) {
// TODO correctness?
return nil // the partition was removed.
}
return err
}

// compare it with the previous partition
diff, err := DiffPartition(prePart, curPart)
if err != nil {
return err
}

partDiff[idx] = diff
return nil
}); err != nil {
return nil, err
}

// all previous partitions have been walked.
// all partitions in cur and not in prev are new... can they be faulty already?
// TODO is this correct?
if err := cur.ForEachPartition(func(idx uint64, curPart Partition) error {
if _, found := partDiff[idx]; found {
return nil
}
faults, err := curPart.FaultySectors()
if err != nil {
return err
}
recovering, err := curPart.RecoveringSectors()
if err != nil {
return err
}
partDiff[idx] = &PartitionDiff{
Removed: bitfield.New(),
Recovered: bitfield.New(),
Faulted: faults,
Recovering: recovering,
}

return nil
}); err != nil {
return nil, err
}

return &partDiff, nil
}

type PartitionDiff struct {
Removed bitfield.BitField
Recovered bitfield.BitField
Faulted bitfield.BitField
Recovering bitfield.BitField
}

func DiffPartition(pre, cur Partition) (*PartitionDiff, error) {
prevLiveSectors, err := pre.LiveSectors()
if err != nil {
return nil, err
}
curLiveSectors, err := cur.LiveSectors()
if err != nil {
return nil, err
}

removed, err := bitfield.SubtractBitField(prevLiveSectors, curLiveSectors)
if err != nil {
return nil, err
}

prevRecoveries, err := pre.RecoveringSectors()
if err != nil {
return nil, err
}

curRecoveries, err := cur.RecoveringSectors()
if err != nil {
return nil, err
}

recovering, err := bitfield.SubtractBitField(curRecoveries, prevRecoveries)
if err != nil {
return nil, err
}

prevFaults, err := pre.FaultySectors()
if err != nil {
return nil, err
}

curFaults, err := cur.FaultySectors()
if err != nil {
return nil, err
}

faulted, err := bitfield.SubtractBitField(curFaults, prevFaults)
if err != nil {
return nil, err
}

// all current good sectors
curActiveSectors, err := cur.ActiveSectors()
if err != nil {
return nil, err
}

// sectors that were previously fault and are now currently active are considered recovered.
recovered, err := bitfield.IntersectBitField(prevFaults, curActiveSectors)
if err != nil {
return nil, err
}

return &PartitionDiff{
Removed: removed,
Recovered: recovered,
Faulted: faulted,
Recovering: recovering,
}, nil
}
9 changes: 5 additions & 4 deletions chain/vm/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ func (m *Message) ValueReceived() abi.TokenAmount {
return m.msg.Value
}

// EnableGasTracing, if true, outputs gas tracing in execution traces.
var EnableGasTracing = false

type Runtime struct {
rt0.Message
rt0.Syscalls
Expand Down Expand Up @@ -477,7 +480,7 @@ func (rt *Runtime) stateCommit(oldh, newh cid.Cid) aerrors.ActorError {
}

func (rt *Runtime) finilizeGasTracing() {
if enableTracing {
if EnableGasTracing {
if rt.lastGasCharge != nil {
rt.lastGasCharge.TimeTaken = time.Since(rt.lastGasChargeTime)
}
Expand Down Expand Up @@ -509,11 +512,9 @@ func (rt *Runtime) chargeGasFunc(skip int) func(GasCharge) {

}

var enableTracing = false

func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError {
toUse := gas.Total()
if enableTracing {
if EnableGasTracing {
var callers [10]uintptr

cout := 0 //gruntime.Callers(2+skip, callers[:])
Expand Down
20 changes: 20 additions & 0 deletions chain/vm/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,23 @@ func TestRuntimePutErrors(t *testing.T) {
rt.StorePut(&NotAVeryGoodMarshaler{})
t.Error("expected panic")
}

func BenchmarkRuntime_CreateRuntimeChargeGas_TracingDisabled(b *testing.B) {
var (
cst = cbor.NewCborStore(nil)
gch = newGasCharge("foo", 1000, 1000)
)

b.ResetTimer()

EnableGasTracing = false
noop := func() bool { return EnableGasTracing }
for n := 0; n < b.N; n++ {
// flip the value and access it to make sure
// the compiler doesn't optimize away
EnableGasTracing = true
_ = noop()
EnableGasTracing = false
_ = (&Runtime{cst: cst}).chargeGasInternal(gch, 0)
}
}
2 changes: 1 addition & 1 deletion chain/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
}

rt := vm.makeRuntime(ctx, msg, origin, on, gasUsed, nac)
if enableTracing {
if EnableGasTracing {
rt.lastGasChargeTime = start
if parent != nil {
rt.lastGasChargeTime = parent.lastGasChargeTime
Expand Down
69 changes: 69 additions & 0 deletions cli/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ var stateCmd = &cli.Command{
stateMsgCostCmd,
stateMinerInfo,
stateMarketCmd,
stateExecTraceCmd,
},
}

Expand Down Expand Up @@ -313,6 +314,74 @@ var stateActiveSectorsCmd = &cli.Command{
},
}

var stateExecTraceCmd = &cli.Command{
Name: "exec-trace",
Usage: "Get the execution trace of a given message",
ArgsUsage: "<messageCid>",
Action: func(cctx *cli.Context) error {
if !cctx.Args().Present() {
return ShowHelp(cctx, fmt.Errorf("must pass message cid"))
}

mcid, err := cid.Decode(cctx.Args().First())
if err != nil {
return fmt.Errorf("message cid was invalid: %s", err)
}

capi, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()

ctx := ReqContext(cctx)

msg, err := capi.ChainGetMessage(ctx, mcid)
if err != nil {
return err
}

lookup, err := capi.StateSearchMsg(ctx, mcid)
if err != nil {
return err
}

ts, err := capi.ChainGetTipSet(ctx, lookup.TipSet)
if err != nil {
return err
}

pts, err := capi.ChainGetTipSet(ctx, ts.Parents())
if err != nil {
return err
}

cso, err := capi.StateCompute(ctx, pts.Height(), nil, pts.Key())
if err != nil {
return err
}

var trace *api.InvocResult
for _, t := range cso.Trace {
if t.Msg.From == msg.From && t.Msg.Nonce == msg.Nonce {
trace = t
break
}
}
if trace == nil {
return fmt.Errorf("failed to find message in tipset trace output")
}

out, err := json.MarshalIndent(trace, "", " ")
if err != nil {
return err
}

fmt.Println(string(out))
return nil
},
}

var stateReplaySetCmd = &cli.Command{
Name: "replay",
Usage: "Replay a particular message within a tipset",
Expand Down
Loading

0 comments on commit 5ef929f

Please sign in to comment.