diff --git a/CHANGELOG.md b/CHANGELOG.md index 3141a80ad7a..f8f271a91d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ - fix(deps): fix Ledger hardware wallet support ([filecoin-project/lotus#13048](https://github.com/filecoin-project/lotus/pull/13048)) - fix(eth): always return nil for eth transactions not found ([filecoin-project/lotus#12999](https://github.com/filecoin-project/lotus/pull/12999)) - feat: add gas to application metric reporting `vm/applyblocks_early_gas`, `vm/applyblocks_messages_gas`, `vm/applyblocks_cron_gas` ([filecoin-project/lotus#13030](https://github.com/filecoin-project/lotus/pull/13030)) +- feat: fall back to EC if F3 finalized tipeset is older than 900 epochs ([filecoin-project/lotus#13066](https://github.com/filecoin-project/lotus/pull/13066)) + ### Experimental v2 APIs with F3 awareness diff --git a/itests/api_v2_test.go b/itests/api_v2_test.go index 4e3888e085c..70778e9cf1b 100644 --- a/itests/api_v2_test.go +++ b/itests/api_v2_test.go @@ -133,6 +133,18 @@ func TestAPIV2_ThroughRPC(t *testing.T) { wantTipSet: tipSetAtHeight(f3FinalizedEpoch), wantResponseStatus: http.StatusOK, }, + { + name: "old f3 finalized falls back to ec", + when: func(t *testing.T) { + mockF3.Running = true + mockF3.Finalizing = true + mockF3.LatestCertErr = nil + mockF3.LatestCert = plausibleCertAt(t, targetHeight-policy.ChainFinality-5) + }, + request: `{"jsonrpc":"2.0","method":"Filecoin.ChainGetTipSet","params":[{"tag":"finalized"}],"id":1}`, + wantTipSet: tipSetAtHeight(targetHeight - policy.ChainFinality), + wantResponseStatus: http.StatusOK, + }, { name: "safe tag is ec safe distance when more recent than f3 finalized", when: func(t *testing.T) { diff --git a/node/impl/full/chain_v2.go b/node/impl/full/chain_v2.go index d128e302e89..60642306120 100644 --- a/node/impl/full/chain_v2.go +++ b/node/impl/full/chain_v2.go @@ -8,6 +8,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-f3" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build/buildconstants" @@ -107,7 +108,21 @@ func (cm *ChainModuleV2) getLatestFinalizedTipset(ctx context.Context) (*types.T } // Extract the finalized tipeset from the certificate. - tsk, err := types.TipSetKeyFromBytes(cert.ECChain.Head().Key) + latestF3FinalizedTipSet := cert.ECChain.Head() + + // Fall back to EC finality if the latest F3 finalized tipset is older than EC finality. + latestF3FinalizedEpoch := abi.ChainEpoch(latestF3FinalizedTipSet.Epoch) + head := cm.Chain.GetHeaviestTipSet() + if head == nil { + return nil, xerrors.New("no known heaviest tipset") + } + if head.Height()-latestF3FinalizedEpoch > policy.ChainFinality { + log.Debugw("Latest F3 finalized tipset is older than EC finality, falling back to EC finality", "headEpoch", head.Height(), "latestF3FinalizedEpoch", latestF3FinalizedEpoch) + return cm.getECFinalized(ctx) + } + + // All good, load the latest F3 finalized tipset. + tsk, err := types.TipSetKeyFromBytes(latestF3FinalizedTipSet.Key) if err != nil { return nil, xerrors.Errorf("decoding latest f3 cert tipset key: %w", err) }