Skip to content

Commit 80581df

Browse files
committed
fix: allow dag import of 1MiB chunks wrapped in dag-pb
IPIP-499's unixfs-v1-2025 profile uses 1MiB chunks. with --raw-leaves=false, protobuf wrapping pushes blocks slightly over 1MiB. the previous 1MiB SoftBlockLimit rejected these blocks on dag import. raise SoftBlockLimit to 2MiB to match the bitswap spec, which requires implementations to support blocks up to 2MiB. - raise SoftBlockLimit to 2MiB per the bitswap spec - update error messages and help text - bump boxo to main with ipfs/boxo#1101 (raised ChunkSizeLimit/BlockSizeLimit, 256-byte overhead budget) - update sharness tests for 2MiB boundary - add test/cli boundary tests for block put, dag put, dag import, ipfs add (raw and wrapped leaves), and bitswap exchange including regression tests for the libp2p message size hard limit
1 parent f57d13c commit 80581df

File tree

15 files changed

+466
-35
lines changed

15 files changed

+466
-35
lines changed

core/commands/add.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,16 @@ Buzhash or Rabin fingerprint chunker for content defined chunking by
172172
specifying buzhash or rabin-[min]-[avg]-[max] (where min/avg/max refer
173173
to the desired chunk sizes in bytes), e.g. 'rabin-262144-524288-1048576'.
174174
175+
The maximum accepted value for 'size-N' and rabin 'max' parameter is
176+
2MiB minus 256 bytes (2096896 bytes). The 256-byte overhead budget is
177+
reserved for protobuf/UnixFS framing so that serialized blocks stay
178+
within the 2MiB block size limit from the bitswap spec. The buzhash
179+
chunker uses a fixed internal maximum of 512KiB and is not affected.
180+
181+
Only the fixed-size chunker ('size-N') guarantees that the same data
182+
will always produce the same CID. The rabin and buzhash chunkers may
183+
change their internal parameters in a future release.
184+
175185
The following examples use very small byte sizes to demonstrate the
176186
properties of the different chunkers on a small file. You'll likely
177187
want to use a 1024 times larger chunk sizes for most files.

core/commands/cmdutils/utils.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ import (
1414

1515
const (
1616
AllowBigBlockOptionName = "allow-big-block"
17-
SoftBlockLimit = 1024 * 1024 // https://github.com/ipfs/kubo/issues/7421#issuecomment-910833499
18-
MaxPinNameBytes = 255 // Maximum number of bytes allowed for a pin name
17+
// SoftBlockLimit is the maximum block size for bitswap transfer.
18+
// If this value changes, update the "2MiB" strings in error messages below.
19+
SoftBlockLimit = 2 * 1024 * 1024 // https://specs.ipfs.tech/bitswap-protocol/#block-sizes
20+
MaxPinNameBytes = 255 // Maximum number of bytes allowed for a pin name
1921
)
2022

2123
var AllowBigBlockOption cmds.Option
2224

2325
func init() {
24-
AllowBigBlockOption = cmds.BoolOption(AllowBigBlockOptionName, "Disable block size check and allow creation of blocks bigger than 1MiB. WARNING: such blocks won't be transferable over the standard bitswap.").WithDefault(false)
26+
AllowBigBlockOption = cmds.BoolOption(AllowBigBlockOptionName, "Disable block size check and allow creation of blocks bigger than 2MiB. WARNING: such blocks won't be transferable over the standard bitswap.").WithDefault(false)
2527
}
2628

2729
func CheckCIDSize(req *cmds.Request, c cid.Cid, dagAPI coreiface.APIDagService) error {
@@ -44,11 +46,10 @@ func CheckBlockSize(req *cmds.Request, size uint64) error {
4446
return nil
4547
}
4648

47-
// We do not allow producing blocks bigger than 1 MiB to avoid errors
48-
// when transmitting them over BitSwap. The 1 MiB constant is an
49-
// unenforced and undeclared rule of thumb hard-coded here.
49+
// Block size is limited to SoftBlockLimit (2MiB) as defined in the bitswap spec.
50+
// https://specs.ipfs.tech/bitswap-protocol/#block-sizes
5051
if size > SoftBlockLimit {
51-
return fmt.Errorf("produced block is over 1MiB: big blocks can't be exchanged with other peers. consider using UnixFS for automatic chunking of bigger files, or pass --allow-big-block to override")
52+
return fmt.Errorf("produced block is over 2MiB: big blocks can't be exchanged with other peers. consider using UnixFS for automatic chunking of bigger files, or pass --allow-big-block to override")
5253
}
5354
return nil
5455
}

docs/changelogs/v0.40.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ The `test-cid-v1` and `test-cid-v1-wide` profiles have been removed. Use `unixfs
6767

6868
When writing to MFS directories that use CIDv1 (via `--cid-version=1` or `ipfs files chcid`), single-block files now produce raw block CIDs (like `bafkrei...`), matching the behavior of `ipfs add --raw-leaves`. Previously, MFS would wrap single-block files in dag-pb even when raw leaves were enabled. CIDv0 directories continue to use dag-pb.
6969

70+
**Block size limit raised to 2MiB**
71+
72+
`ipfs block put`, `ipfs dag put`, and `ipfs dag import` now accept blocks up to 2MiB without `--allow-big-block`, matching the [bitswap spec](https://specs.ipfs.tech/bitswap-protocol/#block-sizes). The previous 1MiB limit was too restrictive and broke `ipfs dag import` of 1MiB-chunked non-raw-leaf data (protobuf wrapping pushes blocks slightly over 1MiB). The max `--chunker` value for `ipfs add` is `2MiB - 256 bytes` to leave room for protobuf framing. IPIP-499 profiles use lower chunk sizes (256KiB and 1MiB) and are not affected.
73+
7074
**HAMT Threshold Fix**
7175

7276
HAMT directory sharding threshold changed from `>=` to `>` to match the Go docs and JS implementation ([ipfs/boxo@6707376](https://github.com/ipfs/boxo/commit/6707376002a3d4ba64895749ce9be2e00d265ed5)). A directory exactly at 256 KiB now stays as a basic directory instead of converting to HAMT. This is a theoretical breaking change, but unlikely to impact real-world users as it requires a directory to be exactly at the threshold boundary. If you depend on the old behavior, adjust [`Import.UnixFSHAMTShardingSize`](https://github.com/ipfs/kubo/blob/master/docs/config.md#importunixfshamtshardingsize) to be 1 byte lower.

docs/config.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3716,9 +3716,21 @@ The default UnixFS chunker. Commands affected: `ipfs add`.
37163716
Valid formats:
37173717

37183718
- `size-<bytes>` - fixed size chunker
3719-
- `rabin-<min>-<avg>-<max>` - rabin fingerprint chunker
3719+
- `rabin-<min>-<avg>-<max>` - rabin fingerprint chunker
37203720
- `buzhash` - buzhash chunker
37213721

3722+
The maximum accepted value for `size-<bytes>` and rabin `max` parameter is
3723+
`2MiB - 256 bytes` (2096896 bytes). The 256-byte overhead budget is reserved
3724+
for protobuf/UnixFS framing so that serialized blocks stay within the 2MiB
3725+
block size limit defined by the
3726+
[bitswap spec](https://specs.ipfs.tech/bitswap-protocol/#block-sizes).
3727+
The `buzhash` chunker uses a fixed internal maximum of 512KiB and is not
3728+
affected by this limit.
3729+
3730+
Only the fixed-size chunker (`size-<bytes>`) guarantees that the same data
3731+
will always produce the same CID. The `rabin` and `buzhash` chunkers may
3732+
change their internal parameters in a future release.
3733+
37223734
Default: `size-262144`
37233735

37243736
Type: `optionalString`

docs/examples/kubo-as-a-library/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ go 1.25
77
replace github.com/ipfs/kubo => ./../../..
88

99
require (
10-
github.com/ipfs/boxo v0.36.1-0.20260205235512-2a942e3e1a75
10+
github.com/ipfs/boxo v0.36.1-0.20260206224221-77bd614971f0
1111
github.com/ipfs/kubo v0.0.0-00010101000000-000000000000
1212
github.com/libp2p/go-libp2p v0.47.0
1313
github.com/multiformats/go-multiaddr v0.16.1

docs/examples/kubo-as-a-library/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd
267267
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU=
268268
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
269269
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
270-
github.com/ipfs/boxo v0.36.1-0.20260205235512-2a942e3e1a75 h1:1UoSAzXwwgOrCZm5cu6v6bL4OGYIzcaOew9Rl6ZycqQ=
271-
github.com/ipfs/boxo v0.36.1-0.20260205235512-2a942e3e1a75/go.mod h1:92hnRXfP5ScKEIqlq9Ns7LR1dFXEVADKWVGH0fjk83k=
270+
github.com/ipfs/boxo v0.36.1-0.20260206224221-77bd614971f0 h1:tC8iJdzsCy/npaez/gtQqNDLpl7DBqCARj9AECmYmoI=
271+
github.com/ipfs/boxo v0.36.1-0.20260206224221-77bd614971f0/go.mod h1:92hnRXfP5ScKEIqlq9Ns7LR1dFXEVADKWVGH0fjk83k=
272272
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
273273
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
274274
github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk=

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ require (
2121
github.com/hashicorp/go-version v1.8.0
2222
github.com/ipfs-shipyard/nopfs v0.0.14
2323
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0
24-
github.com/ipfs/boxo v0.36.1-0.20260205235512-2a942e3e1a75
24+
github.com/ipfs/boxo v0.36.1-0.20260206224221-77bd614971f0
2525
github.com/ipfs/go-block-format v0.2.3
2626
github.com/ipfs/go-cid v0.6.0
2727
github.com/ipfs/go-cidutil v0.1.0
@@ -274,6 +274,7 @@ require (
274274
)
275275

276276
// Exclude ancient +incompatible versions that confuse Dependabot.
277+
277278
// These pre-Go-modules versions reference packages that no longer exist.
278279
exclude (
279280
github.com/ipfs/go-ipfs-cmds v2.0.1+incompatible

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd
337337
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU=
338338
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
339339
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
340-
github.com/ipfs/boxo v0.36.1-0.20260205235512-2a942e3e1a75 h1:1UoSAzXwwgOrCZm5cu6v6bL4OGYIzcaOew9Rl6ZycqQ=
341-
github.com/ipfs/boxo v0.36.1-0.20260205235512-2a942e3e1a75/go.mod h1:92hnRXfP5ScKEIqlq9Ns7LR1dFXEVADKWVGH0fjk83k=
340+
github.com/ipfs/boxo v0.36.1-0.20260206224221-77bd614971f0 h1:tC8iJdzsCy/npaez/gtQqNDLpl7DBqCARj9AECmYmoI=
341+
github.com/ipfs/boxo v0.36.1-0.20260206224221-77bd614971f0/go.mod h1:92hnRXfP5ScKEIqlq9Ns7LR1dFXEVADKWVGH0fjk83k=
342342
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
343343
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
344344
github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk=

0 commit comments

Comments
 (0)