From ae326ce65de2ad3973ac625226d80dac0f1ccf8f Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 15 Sep 2020 15:43:37 +0100 Subject: [PATCH 01/10] feat: add inspect runtime method to chaos actor --- conformance/chaos/actor.go | 32 ++++++ conformance/chaos/actor_test.go | 26 +++++ conformance/chaos/cbor_gen.go | 198 +++++++++++++++++++++++++++++++- conformance/chaos/gen/gen.go | 1 + 4 files changed, 254 insertions(+), 3 deletions(-) diff --git a/conformance/chaos/actor.go b/conformance/chaos/actor.go index daff26694..526dac64c 100644 --- a/conformance/chaos/actor.go +++ b/conformance/chaos/actor.go @@ -64,6 +64,9 @@ const ( // MethodAbortWith is the identifier for the method that panics optionally with // a passed exit code. MethodAbortWith + // MethodInspectRuntime is the identifier for the method that returns the + // current runtime values. + MethodInspectRuntime ) // Exports defines the methods this actor exposes publicly. @@ -77,6 +80,7 @@ func (a Actor) Exports() []interface{} { MethodSend: a.Send, MethodMutateState: a.MutateState, MethodAbortWith: a.AbortWith, + MethodInspectRuntime: a.InspectRuntime, } } @@ -247,3 +251,31 @@ func (a Actor) AbortWith(rt runtime.Runtime, args *AbortWithArgs) *abi.EmptyValu } return nil } + +// InspectRuntimeReturn is the return value for the Actor.InspectRuntime method. +type InspectRuntimeReturn struct { + NetworkVersion int64 + Caller address.Address + Receiver address.Address + ValueReceived abi.TokenAmount + CurrEpoch abi.ChainEpoch + CurrentBalance abi.TokenAmount + State State + TotalFilCircSupply abi.TokenAmount +} + +// InspectRuntime returns a copy of the serializable values available in the Runtime. +func (a Actor) InspectRuntime(rt runtime.Runtime, _ *abi.EmptyValue) *InspectRuntimeReturn { + rt.ValidateImmediateCallerAcceptAny() + var st State + rt.StateReadonly(&st) + return &InspectRuntimeReturn{ + NetworkVersion: int64(rt.NetworkVersion()), + Caller: rt.Caller(), + Receiver: rt.Receiver(), + ValueReceived: rt.ValueReceived(), + CurrentBalance: rt.CurrentBalance(), + State: st, + TotalFilCircSupply: rt.TotalFilCircSupply(), + } +} diff --git a/conformance/chaos/actor_test.go b/conformance/chaos/actor_test.go index 67ced2899..2e899980d 100644 --- a/conformance/chaos/actor_test.go +++ b/conformance/chaos/actor_test.go @@ -6,6 +6,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" + "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/support/mock" atesting "github.com/filecoin-project/specs-actors/support/testing" ) @@ -151,3 +152,28 @@ func TestAbortWithUncontrolled(t *testing.T) { }) rt.Verify() } + +func TestInspectRuntime(t *testing.T) { + caller := atesting.NewIDAddr(t, 100) + receiver := atesting.NewIDAddr(t, 101) + builder := mock.NewBuilder(context.Background(), receiver) + + rt := builder.Build(t) + rt.SetCaller(caller, builtin.AccountActorCodeID) + rt.StateCreate(&State{}) + var a Actor + + rt.ExpectValidateCallerAny() + ret := rt.Call(a.InspectRuntime, abi.Empty) + rtr, ok := ret.(*InspectRuntimeReturn) + if !ok { + t.Fatal("invalid return value") + } + if rtr.Caller != caller { + t.Fatal("unexpected runtime caller") + } + if rtr.Receiver != receiver { + t.Fatal("unexpected runtime receiver") + } + rt.Verify() +} diff --git a/conformance/chaos/cbor_gen.go b/conformance/chaos/cbor_gen.go index 710b84b93..96b707386 100644 --- a/conformance/chaos/cbor_gen.go +++ b/conformance/chaos/cbor_gen.go @@ -6,10 +6,10 @@ import ( "fmt" "io" - abi "github.com/filecoin-project/go-state-types/abi" - exitcode "github.com/filecoin-project/go-state-types/exitcode" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/exitcode" cbg "github.com/whyrusleeping/cbor-gen" - xerrors "golang.org/x/xerrors" + "golang.org/x/xerrors" ) var _ = xerrors.Errorf @@ -730,3 +730,195 @@ func (t *AbortWithArgs) UnmarshalCBOR(r io.Reader) error { } return nil } + +var lengthBufInspectRuntimeReturn = []byte{136} + +func (t *InspectRuntimeReturn) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write(lengthBufInspectRuntimeReturn); err != nil { + return err + } + + scratch := make([]byte, 9) + + // t.NetworkVersion (int64) (int64) + if t.NetworkVersion >= 0 { + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.NetworkVersion)); err != nil { + return err + } + } else { + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.NetworkVersion-1)); err != nil { + return err + } + } + + // t.Caller (address.Address) (struct) + if err := t.Caller.MarshalCBOR(w); err != nil { + return err + } + + // t.Receiver (address.Address) (struct) + if err := t.Receiver.MarshalCBOR(w); err != nil { + return err + } + + // t.ValueReceived (big.Int) (struct) + if err := t.ValueReceived.MarshalCBOR(w); err != nil { + return err + } + + // t.CurrEpoch (abi.ChainEpoch) (int64) + if t.CurrEpoch >= 0 { + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.CurrEpoch)); err != nil { + return err + } + } else { + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.CurrEpoch-1)); err != nil { + return err + } + } + + // t.CurrentBalance (big.Int) (struct) + if err := t.CurrentBalance.MarshalCBOR(w); err != nil { + return err + } + + // t.State (chaos.State) (struct) + if err := t.State.MarshalCBOR(w); err != nil { + return err + } + + // t.TotalFilCircSupply (big.Int) (struct) + if err := t.TotalFilCircSupply.MarshalCBOR(w); err != nil { + return err + } + return nil +} + +func (t *InspectRuntimeReturn) UnmarshalCBOR(r io.Reader) error { + *t = InspectRuntimeReturn{} + + br := cbg.GetPeeker(r) + scratch := make([]byte, 8) + + maj, extra, err := cbg.CborReadHeaderBuf(br, scratch) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 8 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.NetworkVersion (int64) (int64) + { + maj, extra, err := cbg.CborReadHeaderBuf(br, scratch) + 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.NetworkVersion = int64(extraI) + } + // t.Caller (address.Address) (struct) + + { + + if err := t.Caller.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.Caller: %w", err) + } + + } + // t.Receiver (address.Address) (struct) + + { + + if err := t.Receiver.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.Receiver: %w", err) + } + + } + // t.ValueReceived (big.Int) (struct) + + { + + if err := t.ValueReceived.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.ValueReceived: %w", err) + } + + } + // t.CurrEpoch (abi.ChainEpoch) (int64) + { + maj, extra, err := cbg.CborReadHeaderBuf(br, scratch) + 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.CurrEpoch = abi.ChainEpoch(extraI) + } + // t.CurrentBalance (big.Int) (struct) + + { + + if err := t.CurrentBalance.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.CurrentBalance: %w", err) + } + + } + // t.State (chaos.State) (struct) + + { + + if err := t.State.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.State: %w", err) + } + + } + // t.TotalFilCircSupply (big.Int) (struct) + + { + + if err := t.TotalFilCircSupply.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.TotalFilCircSupply: %w", err) + } + + } + return nil +} diff --git a/conformance/chaos/gen/gen.go b/conformance/chaos/gen/gen.go index 97ea98dc8..496cc3d35 100644 --- a/conformance/chaos/gen/gen.go +++ b/conformance/chaos/gen/gen.go @@ -15,6 +15,7 @@ func main() { chaos.SendReturn{}, chaos.MutateStateArgs{}, chaos.AbortWithArgs{}, + chaos.InspectRuntimeReturn{}, ); err != nil { panic(err) } From ed4caac9bff516ffd16544641c5fcc3b17c9c88f Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 15 Sep 2020 22:24:09 +0100 Subject: [PATCH 02/10] fix: remove network version and total fil --- conformance/chaos/actor.go | 27 ++++++++---------- conformance/chaos/cbor_gen.go | 54 ++--------------------------------- 2 files changed, 14 insertions(+), 67 deletions(-) diff --git a/conformance/chaos/actor.go b/conformance/chaos/actor.go index 526dac64c..005a06f0d 100644 --- a/conformance/chaos/actor.go +++ b/conformance/chaos/actor.go @@ -254,14 +254,12 @@ func (a Actor) AbortWith(rt runtime.Runtime, args *AbortWithArgs) *abi.EmptyValu // InspectRuntimeReturn is the return value for the Actor.InspectRuntime method. type InspectRuntimeReturn struct { - NetworkVersion int64 - Caller address.Address - Receiver address.Address - ValueReceived abi.TokenAmount - CurrEpoch abi.ChainEpoch - CurrentBalance abi.TokenAmount - State State - TotalFilCircSupply abi.TokenAmount + Caller address.Address + Receiver address.Address + ValueReceived abi.TokenAmount + CurrEpoch abi.ChainEpoch + CurrentBalance abi.TokenAmount + State State } // InspectRuntime returns a copy of the serializable values available in the Runtime. @@ -270,12 +268,11 @@ func (a Actor) InspectRuntime(rt runtime.Runtime, _ *abi.EmptyValue) *InspectRun var st State rt.StateReadonly(&st) return &InspectRuntimeReturn{ - NetworkVersion: int64(rt.NetworkVersion()), - Caller: rt.Caller(), - Receiver: rt.Receiver(), - ValueReceived: rt.ValueReceived(), - CurrentBalance: rt.CurrentBalance(), - State: st, - TotalFilCircSupply: rt.TotalFilCircSupply(), + Caller: rt.Caller(), + Receiver: rt.Receiver(), + ValueReceived: rt.ValueReceived(), + CurrEpoch: rt.CurrEpoch(), + CurrentBalance: rt.CurrentBalance(), + State: st, } } diff --git a/conformance/chaos/cbor_gen.go b/conformance/chaos/cbor_gen.go index 96b707386..2d9deec93 100644 --- a/conformance/chaos/cbor_gen.go +++ b/conformance/chaos/cbor_gen.go @@ -731,7 +731,7 @@ func (t *AbortWithArgs) UnmarshalCBOR(r io.Reader) error { return nil } -var lengthBufInspectRuntimeReturn = []byte{136} +var lengthBufInspectRuntimeReturn = []byte{134} func (t *InspectRuntimeReturn) MarshalCBOR(w io.Writer) error { if t == nil { @@ -744,17 +744,6 @@ func (t *InspectRuntimeReturn) MarshalCBOR(w io.Writer) error { scratch := make([]byte, 9) - // t.NetworkVersion (int64) (int64) - if t.NetworkVersion >= 0 { - if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.NetworkVersion)); err != nil { - return err - } - } else { - if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.NetworkVersion-1)); err != nil { - return err - } - } - // t.Caller (address.Address) (struct) if err := t.Caller.MarshalCBOR(w); err != nil { return err @@ -790,11 +779,6 @@ func (t *InspectRuntimeReturn) MarshalCBOR(w io.Writer) error { if err := t.State.MarshalCBOR(w); err != nil { return err } - - // t.TotalFilCircSupply (big.Int) (struct) - if err := t.TotalFilCircSupply.MarshalCBOR(w); err != nil { - return err - } return nil } @@ -812,35 +796,10 @@ func (t *InspectRuntimeReturn) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 8 { + if extra != 6 { return fmt.Errorf("cbor input had wrong number of fields") } - // t.NetworkVersion (int64) (int64) - { - maj, extra, err := cbg.CborReadHeaderBuf(br, scratch) - 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.NetworkVersion = int64(extraI) - } // t.Caller (address.Address) (struct) { @@ -910,15 +869,6 @@ func (t *InspectRuntimeReturn) UnmarshalCBOR(r io.Reader) error { return xerrors.Errorf("unmarshaling t.State: %w", err) } - } - // t.TotalFilCircSupply (big.Int) (struct) - - { - - if err := t.TotalFilCircSupply.UnmarshalCBOR(br); err != nil { - return xerrors.Errorf("unmarshaling t.TotalFilCircSupply: %w", err) - } - } return nil } From 952f2c2f1e2659ebe4fb4f5940832d02e5da6c4e Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 9 Sep 2020 05:13:51 -0400 Subject: [PATCH 03/10] Sever chainstore's dependence on the state tree --- chain/store/store.go | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/chain/store/store.go b/chain/store/store.go index 20a7e3031..ad30e0324 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -18,7 +18,6 @@ import ( "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/journal" bstore "github.com/filecoin-project/lotus/lib/blockstore" @@ -767,32 +766,16 @@ type BlockMessages struct { func (cs *ChainStore) BlockMsgsForTipset(ts *types.TipSet) ([]BlockMessages, error) { applied := make(map[address.Address]uint64) - cst := cbor.NewCborStore(cs.bs) - st, err := state.LoadStateTree(cst, ts.Blocks()[0].ParentStateRoot) - if err != nil { - return nil, xerrors.Errorf("failed to load state tree") - } - - preloadAddr := func(a address.Address) error { - if _, ok := applied[a]; !ok { - act, err := st.GetActor(a) - if err != nil { - return err - } - - applied[a] = act.Nonce - } - return nil - } - selectMsg := func(m *types.Message) (bool, error) { - if err := preloadAddr(m.From); err != nil { - return false, err + // The first match for a sender is guaranteed to have correct nonce -- the block isn't valid otherwise + if _, ok := applied[m.From]; !ok { + applied[m.From] = m.Nonce } if applied[m.From] != m.Nonce { return false, nil } + applied[m.From]++ return true, nil From 937ff4e9aef0273c7ec4b9edadd3d3dea4610f82 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 15 Sep 2020 20:55:11 -0400 Subject: [PATCH 04/10] Add a sync test around blocks with bad nonce messages --- chain/sync_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/chain/sync_test.go b/chain/sync_test.go index 0b0d1ed00..f4c83341f 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -662,6 +662,49 @@ func TestDuplicateNonce(t *testing.T) { require.Equal(t, includedMsg, mft[0].VMMessage().Cid(), "messages for tipset didn't contain expected message") } +// This test asserts that a block that includes a message with bad nonce can't be synced. A nonce is "bad" if it can't +// be applied on the parent state. +func TestBadNonce(t *testing.T) { + H := 10 + tu := prepSyncTest(t, H) + + base := tu.g.CurTipset + + // Produce a message from the banker with a bad nonce + makeBadMsg := func() *types.SignedMessage { + + ba, err := tu.nds[0].StateGetActor(context.TODO(), tu.g.Banker(), base.TipSet().Key()) + require.NoError(t, err) + msg := types.Message{ + To: tu.g.Banker(), + From: tu.g.Banker(), + + Nonce: ba.Nonce + 5, + + Value: types.NewInt(1), + + Method: 0, + + GasLimit: 100_000_000, + GasFeeCap: types.NewInt(0), + GasPremium: types.NewInt(0), + } + + sig, err := tu.g.Wallet().Sign(context.TODO(), tu.g.Banker(), msg.Cid().Bytes()) + require.NoError(t, err) + + return &types.SignedMessage{ + Message: msg, + Signature: *sig, + } + } + + msgs := make([][]*types.SignedMessage, 1) + msgs[0] = []*types.SignedMessage{makeBadMsg()} + + tu.mineOnBlock(base, 0, []int{0}, true, true, msgs) +} + func BenchmarkSyncBasic(b *testing.B) { for i := 0; i < b.N; i++ { runSyncBenchLength(b, 100) From fa9be9a627385da6a6c4a36d94f9b0b9bd811a43 Mon Sep 17 00:00:00 2001 From: zgfzgf <1901989065@qq.com> Date: Wed, 16 Sep 2020 09:14:56 +0800 Subject: [PATCH 05/10] Replace fx.Extract with fx.Populate --- node/builder.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/builder.go b/node/builder.go index 8c7674ffd..c37a5db58 100644 --- a/node/builder.go +++ b/node/builder.go @@ -382,7 +382,7 @@ func StorageMiner(out *api.StorageMiner) Option { func(s *Settings) error { resAPI := &impl.StorageMinerAPI{} - s.invokes[ExtractApiKey] = fx.Extract(resAPI) + s.invokes[ExtractApiKey] = fx.Populate(resAPI) *out = resAPI return nil }, @@ -509,7 +509,7 @@ func FullAPI(out *api.FullNode) Option { }, func(s *Settings) error { resAPI := &impl.FullNodeAPI{} - s.invokes[ExtractApiKey] = fx.Extract(resAPI) + s.invokes[ExtractApiKey] = fx.Populate(resAPI) *out = resAPI return nil }, From 5c69249ba36caf130c1fa5aa1c6937c7d86e34ae Mon Sep 17 00:00:00 2001 From: jennijuju Date: Tue, 15 Sep 2020 21:19:27 -0400 Subject: [PATCH 06/10] Use `window post` for window PoSt related log messages. --- chain/stmgr/utils.go | 2 +- chain/sync.go | 2 +- cmd/lotus-bench/main.go | 4 ++-- storage/addresses.go | 2 +- storage/wdpost_run.go | 20 ++++++++++---------- storage/wdpost_sched.go | 14 +++++++------- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 27b71f358..c09f2b22a 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -554,7 +554,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule sectors, err := GetSectorsForWinningPoSt(ctx, pv, sm, lbst, maddr, prand) if err != nil { - return nil, xerrors.Errorf("getting wpost proving set: %w", err) + return nil, xerrors.Errorf("getting winning post proving set: %w", err) } if len(sectors) == 0 { diff --git a/chain/sync.go b/chain/sync.go index f7530f556..b5716a343 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -991,7 +991,7 @@ func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.Block rand, err := store.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, h.Height, buf.Bytes()) if err != nil { - return xerrors.Errorf("failed to get randomness for verifying winningPost proof: %w", err) + return xerrors.Errorf("failed to get randomness for verifying winning post proof: %w", err) } mid, err := address.IDFromAddress(h.Miner) diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 431bfdd44..7da754415 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -387,7 +387,7 @@ var sealBenchCmd = &cli.Command{ return err } if !ok { - log.Error("post verification failed") + log.Error("window post verification failed") } verifyWindowpost1 := time.Now() @@ -403,7 +403,7 @@ var sealBenchCmd = &cli.Command{ return err } if !ok { - log.Error("post verification failed") + log.Error("window post verification failed") } verifyWindowpost2 := time.Now() diff --git a/storage/addresses.go b/storage/addresses.go index bef845367..2388b9fca 100644 --- a/storage/addresses.go +++ b/storage/addresses.go @@ -60,7 +60,7 @@ func AddressFor(ctx context.Context, a addrSelectApi, mi api.MinerInfo, use Addr return addr, nil } - log.Warnw("control address didn't have enough funds for PoSt message", "address", addr, "required", types.FIL(minFunds), "balance", types.FIL(b)) + log.Warnw("control address didn't have enough funds for window post message", "address", addr, "required", types.FIL(minFunds), "balance", types.FIL(b)) } // Try to use the owner account if we can, fallback to worker if we can't diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 7aa90bbba..17b567440 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -78,7 +78,7 @@ func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *dline.Info, posts, err := s.runPost(ctx, *deadline, ts) if err != nil { - log.Errorf("runPost failed: %+v", err) + log.Errorf("run window post failed: %+v", err) s.failPost(err, deadline) return } @@ -92,7 +92,7 @@ func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *dline.Info, post := &posts[i] sm, err := s.submitPost(ctx, post) if err != nil { - log.Errorf("submitPost failed: %+v", err) + log.Errorf("submit window post failed: %+v", err) s.failPost(err, deadline) } else { recordProofsEvent(post.Partitions, sm.Cid()) @@ -397,7 +397,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty rand, err := s.api.ChainGetRandomnessFromBeacon(ctx, ts.Key(), crypto.DomainSeparationTag_WindowedPoStChallengeSeed, di.Challenge, buf.Bytes()) if err != nil { - return nil, xerrors.Errorf("failed to get chain randomness for windowPost (ts=%d; deadline=%d): %w", ts.Height(), di, err) + return nil, xerrors.Errorf("failed to get chain randomness for window post (ts=%d; deadline=%d): %w", ts.Height(), di, err) } // Get the partitions for the given deadline @@ -490,7 +490,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty } // Generate proof - log.Infow("running windowPost", + log.Infow("running window post", "chain-random", rand, "deadline", di, "height", ts.Height(), @@ -507,7 +507,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty postOut, ps, err = s.prover.GenerateWindowPoSt(ctx, abi.ActorID(mid), sinfos, abi.PoStRandomness(rand)) elapsed := time.Since(tsStart) - log.Infow("computing window PoSt", "batch", batchIdx, "elapsed", elapsed) + log.Infow("computing window post", "batch", batchIdx, "elapsed", elapsed) if err == nil { // Proof generation successful, stop retrying @@ -517,10 +517,10 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty // Proof generation failed, so retry if len(ps) == 0 { - return nil, xerrors.Errorf("running post failed: %w", err) + return nil, xerrors.Errorf("running window post failed: %w", err) } - log.Warnw("generate window PoSt skipped sectors", "sectors", ps, "error", err, "try", retries) + log.Warnw("generate window post skipped sectors", "sectors", ps, "error", err, "try", retries) skipCount += uint64(len(ps)) for _, sector := range ps { @@ -547,7 +547,7 @@ func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *ty commEpoch := di.Open commRand, err := s.api.ChainGetRandomnessFromTickets(ctx, ts.Key(), crypto.DomainSeparationTag_PoStChainCommit, commEpoch, nil) if err != nil { - return nil, xerrors.Errorf("failed to get chain randomness for windowPost (ts=%d; deadline=%d): %w", ts.Height(), commEpoch, err) + return nil, xerrors.Errorf("failed to get chain randomness for window post (ts=%d; deadline=%d): %w", ts.Height(), commEpoch, err) } for i := range posts { @@ -644,7 +644,7 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi enc, aerr := actors.SerializeParams(proof) if aerr != nil { - return nil, xerrors.Errorf("could not serialize submit post parameters: %w", aerr) + return nil, xerrors.Errorf("could not serialize submit window post parameters: %w", aerr) } msg := &types.Message{ @@ -705,7 +705,7 @@ func (s *WindowPoStScheduler) setSender(ctx context.Context, msg *types.Message, pa, err := AddressFor(ctx, s.api, mi, PoStAddr, minFunds) if err != nil { - log.Errorw("error selecting address for post", "error", err) + log.Errorw("error selecting address for window post", "error", err) msg.From = s.worker return } diff --git a/storage/wdpost_sched.go b/storage/wdpost_sched.go index 037f4e481..d130d801c 100644 --- a/storage/wdpost_sched.go +++ b/storage/wdpost_sched.go @@ -110,7 +110,7 @@ func (s *WindowPoStScheduler) Run(ctx context.Context) { select { case changes, ok := <-notifs: if !ok { - log.Warn("WindowPoStScheduler notifs channel closed") + log.Warn("window post scheduler notifs channel closed") notifs = nil continue } @@ -151,10 +151,10 @@ func (s *WindowPoStScheduler) Run(ctx context.Context) { } if err := s.revert(ctx, lowest); err != nil { - log.Error("handling head reverts in windowPost sched: %+v", err) + log.Error("handling head reverts in window post sched: %+v", err) } if err := s.update(ctx, highest); err != nil { - log.Error("handling head updates in windowPost sched: %+v", err) + log.Error("handling head updates in window post sched: %+v", err) } span.End() @@ -184,7 +184,7 @@ func (s *WindowPoStScheduler) revert(ctx context.Context, newLowest *types.TipSe func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) error { if new == nil { - return xerrors.Errorf("no new tipset in WindowPoStScheduler.update") + return xerrors.Errorf("no new tipset in window post sched update") } di, err := s.api.StateMinerProvingDeadline(ctx, s.actor, new.Key()) @@ -206,7 +206,7 @@ func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) err // (Need to get correct deadline above, which is tricky) if di.Open+StartConfidence >= new.Height() { - log.Info("not starting windowPost yet, waiting for startconfidence", di.Open, di.Open+StartConfidence, new.Height()) + log.Info("not starting window post yet, waiting for startconfidence", di.Open, di.Open+StartConfidence, new.Height()) return nil } @@ -216,7 +216,7 @@ func (s *WindowPoStScheduler) update(ctx context.Context, new *types.TipSet) err s.activeEPS = 0 } s.failLk.Unlock()*/ - log.Infof("at %d, doPost for P %d, dd %d", new.Height(), di.PeriodStart, di.Index) + log.Infof("at %d, do window post for P %d, dd %d", new.Height(), di.PeriodStart, di.Index) s.doPost(ctx, di, new) @@ -238,7 +238,7 @@ func (s *WindowPoStScheduler) abortActivePoSt() { } }) - log.Warnf("Aborting Window PoSt (Deadline: %+v)", s.activeDeadline) + log.Warnf("Aborting window post (Deadline: %+v)", s.activeDeadline) } s.activeDeadline = nil From e2cf0c4d4c0659931960982205c349e75e65c9c4 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 15 Sep 2020 21:24:30 -0400 Subject: [PATCH 07/10] Make interactive deal CLI reject deals shorter than minimum duration --- cli/client.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cli/client.go b/cli/client.go index e68f98791..d9ce9251e 100644 --- a/cli/client.go +++ b/cli/client.go @@ -12,6 +12,8 @@ import ( "text/tabwriter" "time" + "github.com/filecoin-project/specs-actors/actors/builtin" + tm "github.com/buger/goterm" "github.com/docker/go-units" "github.com/fatih/color" @@ -527,6 +529,11 @@ func interactiveDeal(cctx *cli.Context) error { continue } + if days < int(build.MinDealDuration/builtin.EpochsInDay) { + printErr(xerrors.Errorf("minimum duration is %d days", int(build.MinDealDuration/builtin.EpochsInDay))) + continue + } + state = "miner" case "miner": fmt.Print("Miner Address (t0..): ") From 362fc180ec5ea053047a04ad39984cbfdcc5cc88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Wed, 16 Sep 2020 10:53:15 +0100 Subject: [PATCH 08/10] fix a regression caused by #3800. --- chain/vm/burn.go | 19 ++++++++++++------- chain/vm/vm.go | 30 +++++++++++++++--------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/chain/vm/burn.go b/chain/vm/burn.go index eb0611349..9f9b95755 100644 --- a/chain/vm/burn.go +++ b/chain/vm/burn.go @@ -22,6 +22,17 @@ type GasOutputs struct { GasBurned int64 } +// ZeroGasOutputs returns a logically zeroed GasOutputs. +func ZeroGasOutputs() GasOutputs { + return GasOutputs{ + BaseFeeBurn: big.Zero(), + OverEstimationBurn: big.Zero(), + MinerPenalty: big.Zero(), + MinerTip: big.Zero(), + Refund: big.Zero(), + } +} + // ComputeGasOverestimationBurn computes amount of gas to be refunded and amount of gas to be burned // Result is (refund, burn) func ComputeGasOverestimationBurn(gasUsed, gasLimit int64) (int64, int64) { @@ -58,13 +69,7 @@ func ComputeGasOverestimationBurn(gasUsed, gasLimit int64) (int64, int64) { func ComputeGasOutputs(gasUsed, gasLimit int64, baseFee, feeCap, gasPremium abi.TokenAmount) GasOutputs { gasUsedBig := big.NewInt(gasUsed) - out := GasOutputs{ - BaseFeeBurn: big.Zero(), - OverEstimationBurn: big.Zero(), - MinerPenalty: big.Zero(), - MinerTip: big.Zero(), - Refund: big.Zero(), - } + out := ZeroGasOutputs() baseFeeToPay := baseFee if baseFee.Cmp(feeCap.Int) > 0 { diff --git a/chain/vm/vm.go b/chain/vm/vm.go index f245bb2b0..a90856a1b 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -355,14 +355,14 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, msgGasCost := msgGas.Total() // this should never happen, but is currently still exercised by some tests if msgGasCost > msg.GasLimit { + gasOutputs := ZeroGasOutputs() + gasOutputs.MinerPenalty = types.BigMul(vm.baseFee, abi.NewTokenAmount(msgGasCost)) return &ApplyRet{ MessageReceipt: types.MessageReceipt{ ExitCode: exitcode.SysErrOutOfGas, GasUsed: 0, }, - GasCosts: GasOutputs{ - MinerPenalty: types.BigMul(vm.baseFee, abi.NewTokenAmount(msgGasCost)), - }, + GasCosts: gasOutputs, Duration: time.Since(start), }, nil } @@ -374,15 +374,15 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, // this should never happen, but is currently still exercised by some tests if err != nil { if xerrors.Is(err, types.ErrActorNotFound) { + gasOutputs := ZeroGasOutputs() + gasOutputs.MinerPenalty = minerPenaltyAmount return &ApplyRet{ MessageReceipt: types.MessageReceipt{ ExitCode: exitcode.SysErrSenderInvalid, GasUsed: 0, }, ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "actor not found: %s", msg.From), - GasCosts: GasOutputs{ - MinerPenalty: minerPenaltyAmount, - }, + GasCosts: gasOutputs, Duration: time.Since(start), }, nil } @@ -391,20 +391,22 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, // this should never happen, but is currently still exercised by some tests if !fromActor.Code.Equals(builtin.AccountActorCodeID) { + gasOutputs := ZeroGasOutputs() + gasOutputs.MinerPenalty = minerPenaltyAmount return &ApplyRet{ MessageReceipt: types.MessageReceipt{ ExitCode: exitcode.SysErrSenderInvalid, GasUsed: 0, }, ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "send from not account actor: %s", fromActor.Code), - GasCosts: GasOutputs{ - MinerPenalty: minerPenaltyAmount, - }, + GasCosts: gasOutputs, Duration: time.Since(start), }, nil } if msg.Nonce != fromActor.Nonce { + gasOutputs := ZeroGasOutputs() + gasOutputs.MinerPenalty = minerPenaltyAmount return &ApplyRet{ MessageReceipt: types.MessageReceipt{ ExitCode: exitcode.SysErrSenderStateInvalid, @@ -413,15 +415,15 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid, "actor nonce invalid: msg:%d != state:%d", msg.Nonce, fromActor.Nonce), - GasCosts: GasOutputs{ - MinerPenalty: minerPenaltyAmount, - }, + GasCosts: gasOutputs, Duration: time.Since(start), }, nil } gascost := types.BigMul(types.NewInt(uint64(msg.GasLimit)), msg.GasFeeCap) if fromActor.Balance.LessThan(gascost) { + gasOutputs := ZeroGasOutputs() + gasOutputs.MinerPenalty = minerPenaltyAmount return &ApplyRet{ MessageReceipt: types.MessageReceipt{ ExitCode: exitcode.SysErrSenderStateInvalid, @@ -429,9 +431,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, }, ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid, "actor balance less than needed: %s < %s", types.FIL(fromActor.Balance), types.FIL(gascost)), - GasCosts: GasOutputs{ - MinerPenalty: minerPenaltyAmount, - }, + GasCosts: gasOutputs, Duration: time.Since(start), }, nil } From d870c74a5e22115517f8fb74905001b014f97ea8 Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 16 Sep 2020 19:08:47 +0800 Subject: [PATCH 09/10] add lotus-pcr to ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 940f37b3f..05f762d8d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ /lotus-stats /lotus-bench /lotus-gateway +/lotus-pcr /bench.json /lotuspond/front/node_modules /lotuspond/front/build From b4115021c5063ec5c12a44f3b4d62c055f79d8e5 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Tue, 15 Sep 2020 15:02:14 +0200 Subject: [PATCH 10/10] make sure lotus compiles with +testground build flag --- tools/stats/metrics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/stats/metrics.go b/tools/stats/metrics.go index ae79d9273..e50ac953f 100644 --- a/tools/stats/metrics.go +++ b/tools/stats/metrics.go @@ -189,7 +189,7 @@ func RecordTipsetPoints(ctx context.Context, api api.FullNode, pl *PointList, ti pl.AddPoint(p) } { - blks := len(cids) + blks := int64(len(cids)) p = NewPoint("chain.gas_fill_ratio", float64(totalGasLimit)/float64(blks*build.BlockGasTarget)) pl.AddPoint(p) p = NewPoint("chain.gas_capacity_ratio", float64(totalUniqGasLimit)/float64(blks*build.BlockGasTarget))