From 3dd3476bfd6e0b7b30fe88958f8ea09ac72fc130 Mon Sep 17 00:00:00 2001 From: llifezou Date: Wed, 30 Jun 2021 16:32:44 +0800 Subject: [PATCH 1/4] fix ticket expiration check, otherwise it may cause a large number of loops to retry GetTicket when retrying PreCommit1 --- extern/storage-sealing/states_sealing.go | 38 ++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index 360eeafa632..b6df0f79d7e 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -105,6 +105,10 @@ func checkTicketExpired(ticket, head abi.ChainEpoch) bool { return head-ticket > MaxTicketAge // TODO: allow configuring expected seal durations } +func checkProveCommitExpired(preCommitEpoch, msd abi.ChainEpoch, currEpoch abi.ChainEpoch) bool { + return currEpoch > preCommitEpoch+msd +} + func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.SealRandomness, abi.ChainEpoch, error) { tok, epoch, err := m.api.ChainHead(ctx.Context()) if err != nil { @@ -126,7 +130,14 @@ func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.Se if pci != nil { ticketEpoch = pci.Info.SealRandEpoch - if checkTicketExpired(ticketEpoch, epoch) { + nv, err := m.api.StateNetworkVersion(ctx.Context(), tok) + if err != nil { + return nil, 0, xerrors.Errorf("getTicket: StateNetworkVersion: api error, not proceeding: %+v", err) + } + + msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), sector.SectorType) + + if checkProveCommitExpired(pci.PreCommitEpoch, msd, epoch) { return nil, 0, xerrors.Errorf("ticket expired for precommitted sector") } } @@ -182,14 +193,35 @@ func (m *Sealing) handlePreCommit1(ctx statemachine.Context, sector SectorInfo) } } - _, height, err := m.api.ChainHead(ctx.Context()) + tok, height, err := m.api.ChainHead(ctx.Context()) if err != nil { log.Errorf("handlePreCommit1: api error, not proceeding: %+v", err) return nil } if checkTicketExpired(sector.TicketEpoch, height) { - return ctx.Send(SectorOldTicket{}) // go get new ticket + pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorNumber, tok) + if err != nil { + log.Errorf("handlePreCommit1: StateSectorPreCommitInfo: api error, not proceeding: %+v", err) + return nil + } + + if pci == nil { + return ctx.Send(SectorOldTicket{}) // go get new ticket + } + + nv, err := m.api.StateNetworkVersion(ctx.Context(), tok) + if err != nil { + log.Errorf("handlePreCommit1: StateNetworkVersion: api error, not proceeding: %+v", err) + return nil + } + + msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), sector.SectorType) + + // if height > PreCommitEpoch + msd, there is no need to recalculate + if checkProveCommitExpired(pci.PreCommitEpoch, msd, height) { + return ctx.Send(SectorOldTicket{}) // will be removed + } } pc1o, err := m.sealer.SealPreCommit1(sector.sealingCtx(ctx.Context()), m.minerSector(sector.SectorType, sector.SectorNumber), sector.TicketValue, sector.pieceInfos()) From 73e58f7af1636d54db8b9b2ac532bc7f61ec183d Mon Sep 17 00:00:00 2001 From: llifezou Date: Thu, 1 Jul 2021 10:53:42 +0800 Subject: [PATCH 2/4] fix getTicket: sector precommitted but expired case --- extern/storage-sealing/states_sealing.go | 37 ++++++++++++++---------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index b6df0f79d7e..e8e8c760107 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -109,22 +109,30 @@ func checkProveCommitExpired(preCommitEpoch, msd abi.ChainEpoch, currEpoch abi.C return currEpoch > preCommitEpoch+msd } -func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.SealRandomness, abi.ChainEpoch, error) { +func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.SealRandomness, abi.ChainEpoch, bool, error) { tok, epoch, err := m.api.ChainHead(ctx.Context()) if err != nil { - log.Errorf("handlePreCommit1: api error, not proceeding: %+v", err) - return nil, 0, nil + log.Errorf("getTicket: api error, not proceeding: %+v", err) + return nil, 0, false, nil + } + + // the reason why the StateMinerSectorAllocated function is placed here, if it is outside, + // if the MarshalCBOR function and StateSectorPreCommitInfo function return err, it will be executed + allocated, aerr := m.api.StateMinerSectorAllocated(ctx.Context(), m.maddr, sector.SectorNumber, nil) + if aerr != nil { + log.Errorf("getTicket: api error, checking if sector is allocated: %+v", aerr) + return nil, 0, false, nil } ticketEpoch := epoch - policy.SealRandomnessLookback buf := new(bytes.Buffer) if err := m.maddr.MarshalCBOR(buf); err != nil { - return nil, 0, err + return nil, 0, allocated, err } pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorNumber, tok) if err != nil { - return nil, 0, xerrors.Errorf("getting precommit info: %w", err) + return nil, 0, allocated, xerrors.Errorf("getting precommit info: %w", err) } if pci != nil { @@ -132,32 +140,31 @@ func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.Se nv, err := m.api.StateNetworkVersion(ctx.Context(), tok) if err != nil { - return nil, 0, xerrors.Errorf("getTicket: StateNetworkVersion: api error, not proceeding: %+v", err) + return nil, 0, allocated, xerrors.Errorf("getTicket: StateNetworkVersion: api error, not proceeding: %+v", err) } msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), sector.SectorType) if checkProveCommitExpired(pci.PreCommitEpoch, msd, epoch) { - return nil, 0, xerrors.Errorf("ticket expired for precommitted sector") + return nil, 0, allocated, xerrors.Errorf("ticket expired for precommitted sector") } } + if allocated { // allocated is true, sector precommitted but expired, will SectorCommitFailed or SectorRemove + return nil, 0, allocated, xerrors.Errorf("Sector %s precommitted but expired", sector.SectorNumber) + } + rand, err := m.api.ChainGetRandomnessFromTickets(ctx.Context(), tok, crypto.DomainSeparationTag_SealRandomness, ticketEpoch, buf.Bytes()) if err != nil { - return nil, 0, err + return nil, 0, allocated, err } - return abi.SealRandomness(rand), ticketEpoch, nil + return abi.SealRandomness(rand), ticketEpoch, allocated, nil } func (m *Sealing) handleGetTicket(ctx statemachine.Context, sector SectorInfo) error { - ticketValue, ticketEpoch, err := m.getTicket(ctx, sector) + ticketValue, ticketEpoch, allocated, err := m.getTicket(ctx, sector) if err != nil { - allocated, aerr := m.api.StateMinerSectorAllocated(ctx.Context(), m.maddr, sector.SectorNumber, nil) - if aerr != nil { - log.Errorf("error checking if sector is allocated: %+v", aerr) - } - if allocated { if sector.CommitMessage != nil { // Some recovery paths with unfortunate timing lead here From fe3ad4fd60515ad68243b83a564182fd40d0975c Mon Sep 17 00:00:00 2001 From: llifezou <46102475+llifezou@users.noreply.github.com> Date: Fri, 2 Jul 2021 11:38:04 +0800 Subject: [PATCH 3/4] Update extern/storage-sealing/states_sealing.go fix log Co-authored-by: Aayush Rajasekaran --- extern/storage-sealing/states_sealing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index e8e8c760107..3273ff76ef4 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -151,7 +151,7 @@ func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.Se } if allocated { // allocated is true, sector precommitted but expired, will SectorCommitFailed or SectorRemove - return nil, 0, allocated, xerrors.Errorf("Sector %s precommitted but expired", sector.SectorNumber) + return nil, 0, allocated, xerrors.Errorf("sector %s precommitted but expired", sector.SectorNumber) } rand, err := m.api.ChainGetRandomnessFromTickets(ctx.Context(), tok, crypto.DomainSeparationTag_SealRandomness, ticketEpoch, buf.Bytes()) From df53b97fe4d1cf19f1fcf07f5b1a8fc483161d1f Mon Sep 17 00:00:00 2001 From: llifezou <46102475+llifezou@users.noreply.github.com> Date: Fri, 2 Jul 2021 11:44:46 +0800 Subject: [PATCH 4/4] Update extern/storage-sealing/states_sealing.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix sector precommitted but expired judgment Co-authored-by: Ɓukasz Magiera --- extern/storage-sealing/states_sealing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index 3273ff76ef4..570b248846c 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -150,7 +150,7 @@ func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.Se } } - if allocated { // allocated is true, sector precommitted but expired, will SectorCommitFailed or SectorRemove + if pci == nil && allocated { // allocated is true, sector precommitted but expired, will SectorCommitFailed or SectorRemove return nil, 0, allocated, xerrors.Errorf("sector %s precommitted but expired", sector.SectorNumber) }