diff --git a/CHANGELOG.md b/CHANGELOG.md index f27622c5f03..be8b0693423 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,17 +8,10 @@ > * [CHANGELOG_1.2x.md](./documentation/changelog/CHANGELOG_1.2x.md) - v1.20.0 to v1.29.2 # UNRELEASED -- feat(api): add StateMinerCreationDeposit API method for FIP-0077 - calculates the deposit required for creating a new miner ([filecoin-project/lotus#13308](https://github.com/filecoin-project/lotus/pull/13308)) -- feat(net): add LOTUS_ENABLE_MESSAGE_FETCH_INSTRUMENTATION=1 to turn on metrics and debugging for local vs bitswap message fetching during block validation ([filecoin-project/lotus#13221](https://github.com/filecoin-project/lotus/pull/13221)) -- chore(docs): mark v0 API as "deprecated" and v1 as "stable" ([filecoin-project/lotus#13264](https://github.com/filecoin-project/lotus/pull/13264)) -- fix(api): `eth_getCode` and `eth_getStorageAt` now return state after the specified block rather than before it ([filecoin-project/lotus#13274](https://github.com/filecoin-project/lotus/pull/13274)) -- fix(api): `eth_getTransactionCount` now returns state after the specified block rather than before it ([filecoin-project/lotus#13275](https://github.com/filecoin-project/lotus/pull/13275)) -- feat: support for F3-aware snapshot v2 format per [FRC-0108](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0108.md) ([filecoin-project/lotus#13282](https://github.com/filecoin-project/lotus/pull/13282)) - - snapshot export now defaults to v2 format with embedded F3 finality certificates, dramatically reducing F3 catchup time from ~8 hours - - transparently imports both v1 and v2 snapshot formats - - to export v1 snapshots, use `lotus chain export --skip-old-msgs --recent-stateroots=2001 --snapshot-version=1 ` -- feat(eth): use F3 for "finalized" and "safe" resolution in v1 APIs. This switches the /v1 Ethereum APIs to have the same resolution rules as /v2, enabling F3 awareness for all Ethereum calls where `"finalized"` or `"safe"` is supplied. See [F3-aware Ethereum APIs via `/v2` endpoint and improvements to existing `/v1` APIs](#f3-aware-ethereum-apis-via-v2-endpoint-and-improvements-to-existing-v1-apis) below for details of how the /v2 APIs work as introduced in the 1.33.0 release. Set the environment variable `LOTUS_ETH_V1_DISABLE_F3_FINALITY_RESOLUTION` to `1` to revert this behaviour but note that the option to revert will likely be removed in a future release. ([filecoin-project/lotus#13298](https://github.com/filecoin-project/lotus/pull/13298)) -- feat(f3): expose simple ChainGetFinalizedTipSet API on v1 (and gateway) that just returns the latest F3 finalized tipset, or falls back to EC finality if F3 is not operational on the node or if the F3 finalized tipset is further back than EC finalized tipset. This API can be used for follow-up state calls that clamp to a specific tipset to have assurance of state finality. ([filecoin-project/lotus#13299](https://github.com/filecoin-project/lotus/pull/13299)) + +# UNRELEASED v1.34.0 + +See https://github.com/filecoin-project/lotus/blob/release/v1.34.0/CHANGELOG.md # Node v1.33.1 / 2025-07-31 This is the Lotus v1.33.1 release, which introduces performance improvements and operational enhancements. This release focuses on improving F3 subsystem performance, and enhancing CLI tools for better storage provider operations. Notable improvements include up to 6-10x performance gains in F3 power table calculations, ensuring that PreCommit and ProveCommit operations are aggregating to get optimal gas usage after FIP-100, and a enhanced sector management tool with CSV output support. These improvements collectively enhance the stability and efficiency of Lotus operations for both node operators and storage providers. diff --git a/api/types.go b/api/types.go index 864b735665e..3dc8352f6d6 100644 --- a/api/types.go +++ b/api/types.go @@ -195,7 +195,7 @@ type ForkUpgradeParams struct { UpgradeTuktukHeight abi.ChainEpoch UpgradeTeepHeight abi.ChainEpoch UpgradeTockHeight abi.ChainEpoch - UpgradeXxHeight abi.ChainEpoch + UpgradeGoldenWeekHeight abi.ChainEpoch } // ChainExportConfig holds configuration for chain ranged exports. diff --git a/build/buildconstants/params_2k.go b/build/buildconstants/params_2k.go index f262596616a..8a4fa7f7551 100644 --- a/build/buildconstants/params_2k.go +++ b/build/buildconstants/params_2k.go @@ -96,7 +96,7 @@ var UpgradeTockHeight = abi.ChainEpoch(-30) const UpgradeTockFixHeight = -103 -var UpgradeXxHeight = abi.ChainEpoch(200) +var UpgradeGoldenWeekHeight = abi.ChainEpoch(200) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandQuicknet, @@ -177,7 +177,7 @@ func init() { UpgradeTeepHeight = getUpgradeHeight("LOTUS_TEEP_HEIGHT", UpgradeTeepHeight) UpgradeTockHeight = getUpgradeHeight("LOTUS_TOCK_HEIGHT", UpgradeTockHeight) // UpgradeTockFixHeight = getUpgradeHeight("LOTUS_TOCK_FIX_HEIGHT", UpgradeTockFixHeight) - UpgradeXxHeight = getUpgradeHeight("LOTUS_XX_HEIGHT", UpgradeXxHeight) + UpgradeGoldenWeekHeight = getUpgradeHeight("LOTUS_GOLDEN_WEEK_HEIGHT", UpgradeGoldenWeekHeight) DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandQuicknet, diff --git a/build/buildconstants/params_butterfly.go b/build/buildconstants/params_butterfly.go index 52b8524554b..92dd64fc12c 100644 --- a/build/buildconstants/params_butterfly.go +++ b/build/buildconstants/params_butterfly.go @@ -84,7 +84,7 @@ const UpgradeTockHeight = -30 const UpgradeTockFixHeight = -103 // ?????? -const UpgradeXxHeight = 999999999999999 +const UpgradeGoldenWeekHeight = 999999999999999 var ConsensusMinerMinPower = abi.NewStoragePower(2 << 30) var PreCommitChallengeDelay = abi.ChainEpoch(150) diff --git a/build/buildconstants/params_calibnet.go b/build/buildconstants/params_calibnet.go index 1b81753f161..e182fa0e677 100644 --- a/build/buildconstants/params_calibnet.go +++ b/build/buildconstants/params_calibnet.go @@ -126,7 +126,7 @@ var UpgradeTockHeight abi.ChainEpoch = UpgradeTeepHeight + builtin.EpochsInDay*7 const UpgradeTockFixHeight abi.ChainEpoch = 2558014 // ?????? -const UpgradeXxHeight = 999999999999999 +const UpgradeGoldenWeekHeight = 999999999999999 var ConsensusMinerMinPower = abi.NewStoragePower(32 << 30) var PreCommitChallengeDelay = abi.ChainEpoch(150) diff --git a/build/buildconstants/params_interop.go b/build/buildconstants/params_interop.go index 2f3179a96dd..58ced6e1bab 100644 --- a/build/buildconstants/params_interop.go +++ b/build/buildconstants/params_interop.go @@ -82,7 +82,7 @@ var UpgradeTockHeight = abi.ChainEpoch(-30) // This fix upgrade only ran on calibrationnet const UpgradeTockFixHeight abi.ChainEpoch = -4 -const UpgradeXxHeight = 50 +const UpgradeGoldenWeekHeight = 50 var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandQuicknet, diff --git a/build/buildconstants/params_mainnet.go b/build/buildconstants/params_mainnet.go index f72109cf4ab..919231cf9bb 100644 --- a/build/buildconstants/params_mainnet.go +++ b/build/buildconstants/params_mainnet.go @@ -139,7 +139,7 @@ var UpgradeTockHeight = UpgradeTeepHeight + builtin.EpochsInDay*90 var UpgradeTockFixHeight = abi.ChainEpoch(-1) // ?????? -var UpgradeXxHeight = abi.ChainEpoch(9999999999) +var UpgradeGoldenWeekHeight = abi.ChainEpoch(9999999999) var UpgradeTeepInitialFilReserved = InitialFilReserved // FIP-0100: no change for mainnet @@ -158,8 +158,8 @@ func init() { } SetAddressNetwork(addrNetwork) - if os.Getenv("LOTUS_DISABLE_XX") == "1" { - UpgradeXxHeight = math.MaxInt64 - 1 + if os.Getenv("LOTUS_DISABLE_GOLDEN_WEEK") == "1" { + UpgradeGoldenWeekHeight = math.MaxInt64 - 1 } // NOTE: DO NOT change this unless you REALLY know what you're doing. This is not consensus critical, however, diff --git a/build/buildconstants/params_testground.go b/build/buildconstants/params_testground.go index c355e0a866e..67686ee27cf 100644 --- a/build/buildconstants/params_testground.go +++ b/build/buildconstants/params_testground.go @@ -110,7 +110,7 @@ var ( UpgradeTeepInitialFilReserved *big.Int = wholeFIL(300_000_000) UpgradeTockHeight abi.ChainEpoch = -32 UpgradeTockFixHeight abi.ChainEpoch = -33 - UpgradeXxHeight abi.ChainEpoch = -34 + UpgradeGoldenWeekHeight abi.ChainEpoch = -34 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/openrpc/full.json b/build/openrpc/full.json index cc5b5afe2a6..4994641fb95 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -2,7 +2,7 @@ "openrpc": "1.2.6", "info": { "title": "Lotus RPC API", - "version": "1.33.2-dev" + "version": "1.34.1-dev" }, "methods": [ { @@ -20700,7 +20700,7 @@ "UpgradeTuktukHeight": 10101, "UpgradeTeepHeight": 10101, "UpgradeTockHeight": 10101, - "UpgradeXxHeight": 10101 + "UpgradeGoldenWeekHeight": 10101 }, "Eip155ChainID": 123, "GenesisTimestamp": 42 @@ -20751,6 +20751,10 @@ "title": "number", "type": "number" }, + "UpgradeGoldenWeekHeight": { + "title": "number", + "type": "number" + }, "UpgradeHyggeHeight": { "title": "number", "type": "number" @@ -20846,10 +20850,6 @@ "UpgradeWatermelonHeight": { "title": "number", "type": "number" - }, - "UpgradeXxHeight": { - "title": "number", - "type": "number" } }, "type": "object" diff --git a/build/openrpc/gateway.json b/build/openrpc/gateway.json index 4fc1fb9080b..520720ca200 100644 --- a/build/openrpc/gateway.json +++ b/build/openrpc/gateway.json @@ -2,7 +2,7 @@ "openrpc": "1.2.6", "info": { "title": "Lotus RPC API", - "version": "1.33.2-dev" + "version": "1.34.1-dev" }, "methods": [ { @@ -9510,7 +9510,7 @@ "UpgradeTuktukHeight": 10101, "UpgradeTeepHeight": 10101, "UpgradeTockHeight": 10101, - "UpgradeXxHeight": 10101 + "UpgradeGoldenWeekHeight": 10101 }, "Eip155ChainID": 123, "GenesisTimestamp": 42 @@ -9561,6 +9561,10 @@ "title": "number", "type": "number" }, + "UpgradeGoldenWeekHeight": { + "title": "number", + "type": "number" + }, "UpgradeHyggeHeight": { "title": "number", "type": "number" @@ -9656,10 +9660,6 @@ "UpgradeWatermelonHeight": { "title": "number", "type": "number" - }, - "UpgradeXxHeight": { - "title": "number", - "type": "number" } }, "type": "object" diff --git a/build/openrpc/miner.json b/build/openrpc/miner.json index 6ea090b540d..d6dcff042c6 100644 --- a/build/openrpc/miner.json +++ b/build/openrpc/miner.json @@ -2,7 +2,7 @@ "openrpc": "1.2.6", "info": { "title": "Lotus RPC API", - "version": "1.33.2-dev" + "version": "1.34.1-dev" }, "methods": [ { diff --git a/build/openrpc/v0/gateway.json b/build/openrpc/v0/gateway.json index 8c6ca693c18..15f053a8057 100644 --- a/build/openrpc/v0/gateway.json +++ b/build/openrpc/v0/gateway.json @@ -2,7 +2,7 @@ "openrpc": "1.2.6", "info": { "title": "Lotus RPC API", - "version": "1.33.2-dev" + "version": "1.34.1-dev" }, "methods": [ { diff --git a/build/openrpc/v2/full.json b/build/openrpc/v2/full.json index a66296e8990..839f86b5f48 100644 --- a/build/openrpc/v2/full.json +++ b/build/openrpc/v2/full.json @@ -2,7 +2,7 @@ "openrpc": "1.2.6", "info": { "title": "Lotus RPC API", - "version": "1.33.2-dev" + "version": "1.34.1-dev" }, "methods": [ { diff --git a/build/openrpc/v2/gateway.json b/build/openrpc/v2/gateway.json index 2678abdf37a..2fcbe094372 100644 --- a/build/openrpc/v2/gateway.json +++ b/build/openrpc/v2/gateway.json @@ -2,7 +2,7 @@ "openrpc": "1.2.6", "info": { "title": "Lotus RPC API", - "version": "1.33.2-dev" + "version": "1.34.1-dev" }, "methods": [ { diff --git a/build/openrpc/worker.json b/build/openrpc/worker.json index d15f93a547e..0f096a79def 100644 --- a/build/openrpc/worker.json +++ b/build/openrpc/worker.json @@ -2,7 +2,7 @@ "openrpc": "1.2.6", "info": { "title": "Lotus RPC API", - "version": "1.33.2-dev" + "version": "1.34.1-dev" }, "methods": [ { diff --git a/build/version.go b/build/version.go index 93bcd521c19..a3cf0a2b142 100644 --- a/build/version.go +++ b/build/version.go @@ -7,7 +7,7 @@ import ( ) // NodeBuildVersion is the local build version of the Lotus daemon -const NodeBuildVersion string = "1.33.2-dev" +const NodeBuildVersion string = "1.34.1-dev" func NodeUserVersion() BuildVersion { if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { @@ -18,7 +18,7 @@ func NodeUserVersion() BuildVersion { } // MinerBuildVersion is the local build version of the Lotus miner -const MinerBuildVersion = "1.33.2-dev" +const MinerBuildVersion = "v1.34.1-dev" func MinerUserVersion() BuildVersion { if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { diff --git a/chain/consensus/filcns/upgrades.go b/chain/consensus/filcns/upgrades.go index afd34cccdbc..cc27c876bc9 100644 --- a/chain/consensus/filcns/upgrades.go +++ b/chain/consensus/filcns/upgrades.go @@ -351,7 +351,7 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule { Network: network.Version26, Migration: UpgradeActorsV16Fix, }, { - Height: buildconstants.UpgradeXxHeight, + Height: buildconstants.UpgradeGoldenWeekHeight, Network: network.Version27, Migration: UpgradeActorsV17, PreMigrations: []stmgr.PreMigration{{ diff --git a/documentation/en/api-methods-v0-deprecated.md b/documentation/en/api-methods-v0-deprecated.md index 5db8374ac8c..e4258e12901 100644 --- a/documentation/en/api-methods-v0-deprecated.md +++ b/documentation/en/api-methods-v0-deprecated.md @@ -4917,7 +4917,7 @@ Response: "UpgradeTuktukHeight": 10101, "UpgradeTeepHeight": 10101, "UpgradeTockHeight": 10101, - "UpgradeXxHeight": 10101 + "UpgradeGoldenWeekHeight": 10101 }, "Eip155ChainID": 123, "GenesisTimestamp": 42 diff --git a/documentation/en/api-methods-v1-stable.md b/documentation/en/api-methods-v1-stable.md index cb123291d33..3945e910b0b 100644 --- a/documentation/en/api-methods-v1-stable.md +++ b/documentation/en/api-methods-v1-stable.md @@ -7473,7 +7473,7 @@ Response: "UpgradeTuktukHeight": 10101, "UpgradeTeepHeight": 10101, "UpgradeTockHeight": 10101, - "UpgradeXxHeight": 10101 + "UpgradeGoldenWeekHeight": 10101 }, "Eip155ChainID": 123, "GenesisTimestamp": 42 diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 07703ec18e8..346ed01105f 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -8,7 +8,7 @@ USAGE: lotus-miner [global options] command [command options] VERSION: - 1.33.2-dev + v1.34.1-dev COMMANDS: init Initialize a lotus miner repo diff --git a/documentation/en/cli-lotus-worker.md b/documentation/en/cli-lotus-worker.md index 2ae4a96f0a8..809e201414e 100644 --- a/documentation/en/cli-lotus-worker.md +++ b/documentation/en/cli-lotus-worker.md @@ -8,7 +8,7 @@ USAGE: lotus-worker [global options] command [command options] VERSION: - 1.33.2-dev + v1.34.1-dev COMMANDS: run Start lotus worker diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index b7f865662e1..bf6241efa5c 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -8,7 +8,7 @@ USAGE: lotus [global options] command [command options] VERSION: - 1.33.2-dev + 1.34.1-dev COMMANDS: daemon Start a lotus daemon process diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 2159b023934..ab59d9c7fac 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -2163,7 +2163,7 @@ func (a *StateAPI) StateGetNetworkParams(ctx context.Context) (*api.NetworkParam UpgradeTuktukHeight: buildconstants.UpgradeTuktukHeight, UpgradeTeepHeight: buildconstants.UpgradeTeepHeight, UpgradeTockHeight: buildconstants.UpgradeTockHeight, - UpgradeXxHeight: buildconstants.UpgradeXxHeight, + UpgradeGoldenWeekHeight: buildconstants.UpgradeGoldenWeekHeight, }, }, nil } diff --git a/storage/sealer/fr32/readers.go b/storage/sealer/fr32/readers.go index 8c5a8ad1242..b499bc422cf 100644 --- a/storage/sealer/fr32/readers.go +++ b/storage/sealer/fr32/readers.go @@ -101,11 +101,37 @@ func (r *unpadReader) readInner(out []byte) (int, error) { r.left -= uint64(todo) n, err := io.ReadAtLeast(r.src, r.work[:todo], int(todo)) - if err != nil && err != io.EOF { - return n, err + if err == io.ErrUnexpectedEOF { + // We got a partial read. This happens when the underlying reader + // doesn't have as much data as expected (e.g., non-power-of-2 pieces). + // Process what we got. + if n > 0 { + // Round down to complete 128-byte chunks + completeChunks := n / 128 + if completeChunks > 0 { + validBytes := completeChunks * 128 + Unpad(r.work[:validBytes], out[:completeChunks*127]) + // Adjust left to reflect that we couldn't read everything + r.left = 0 + return completeChunks * 127, io.EOF + } + } + // Not enough data for even one chunk + return 0, io.EOF + } + if err == io.EOF { + // Clean EOF with no data + if n == 0 { + return 0, io.EOF + } + // Got some data with EOF - shouldn't happen with ReadAtLeast but handle it + return 0, xerrors.Errorf("unexpected EOF with partial read: %d bytes", n) + } + if err != nil { + return 0, err } if n < int(todo) { - return 0, xerrors.Errorf("didn't read enough: %d / %d, left %d, out %d", n, todo, r.left, len(out)) + return 0, xerrors.Errorf("short read without EOF: got %d, expected %d", n, todo) } Unpad(r.work[:todo], out[:todo.Unpadded()]) diff --git a/storage/sealer/fr32/readers_test.go b/storage/sealer/fr32/readers_test.go index 7a61b80f8d2..f6d23782080 100644 --- a/storage/sealer/fr32/readers_test.go +++ b/storage/sealer/fr32/readers_test.go @@ -196,3 +196,50 @@ func TestUnpadReaderLargeReads(t *testing.T) { require.Equal(t, unpadded, result) } + +// TestUnpadReaderPartialPiece tests the edge case where the underlying reader +// has less data than UnpadReader expects. This happens when dealing with pieces +// that are not exact power-of-2 sizes. +// This test captures the fix for the EOF errors that occurred after PR #12884. +func TestUnpadReaderPartialPiece(t *testing.T) { + actualUnpadded := abi.UnpaddedPieceSize(127 * 100) // 100 chunks = 12700 bytes + declaredSize := abi.PaddedPieceSize(128 * 128) // Declare 128 chunks but only have 100 + + // Generate test data + unpadded := make([]byte, actualUnpadded) + n, err := rand.Read(unpadded) + require.NoError(t, err) + require.Equal(t, int(actualUnpadded), n) + + // Pad the data + paddedActual := actualUnpadded.Padded() + padded := make([]byte, paddedActual) + fr32.Pad(unpadded, padded) + + // Create a reader that returns EOF after the actual data + limitedReader := bytes.NewReader(padded) + + // Create UnpadReader with the larger declared size + unpadReader, err := fr32.NewUnpadReader(limitedReader, declaredSize) + require.NoError(t, err) + + // Read all data + result := make([]byte, 0, actualUnpadded*2) + buf := make([]byte, 1024) + + for { + n, err := unpadReader.Read(buf) + if n > 0 { + result = append(result, buf[:n]...) + } + if err == io.EOF { + break + } + // The fix allows UnpadReader to handle partial reads gracefully + require.NoError(t, err, "UnpadReader should handle partial pieces without error") + } + + // Verify we got the correct data + require.Equal(t, int(actualUnpadded), len(result), "Should read all available data") + require.Equal(t, unpadded, result, "Data should match original") +}