Skip to content

Commit 7403f84

Browse files
committed
merge origin/master into feat/test-slog-interop
resolved conflicts in go.sum files by keeping slog integration version
2 parents 06ecb3b + ae86672 commit 7403f84

File tree

20 files changed

+507
-232
lines changed

20 files changed

+507
-232
lines changed

.github/workflows/gateway-conformance.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,13 @@ jobs:
109109
run: cat output.md >> $GITHUB_STEP_SUMMARY
110110
- name: Upload HTML report
111111
if: failure() || success()
112-
uses: actions/upload-artifact@v4
112+
uses: actions/upload-artifact@v5
113113
with:
114114
name: gateway-conformance.html
115115
path: output.html
116116
- name: Upload JSON report
117117
if: failure() || success()
118-
uses: actions/upload-artifact@v4
118+
uses: actions/upload-artifact@v5
119119
with:
120120
name: gateway-conformance.json
121121
path: output.json
@@ -214,13 +214,13 @@ jobs:
214214
run: cat output.md >> $GITHUB_STEP_SUMMARY
215215
- name: Upload HTML report
216216
if: failure() || success()
217-
uses: actions/upload-artifact@v4
217+
uses: actions/upload-artifact@v5
218218
with:
219219
name: gateway-conformance-libp2p.html
220220
path: output.html
221221
- name: Upload JSON report
222222
if: failure() || success()
223-
uses: actions/upload-artifact@v4
223+
uses: actions/upload-artifact@v5
224224
with:
225225
name: gateway-conformance-libp2p.json
226226
path: output.json

.github/workflows/gotest.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
output: test/unit/gotest.junit.xml
7979
if: failure() || success()
8080
- name: Archive the JUnit XML report
81-
uses: actions/upload-artifact@v4
81+
uses: actions/upload-artifact@v5
8282
with:
8383
name: unit
8484
path: test/unit/gotest.junit.xml
@@ -91,7 +91,7 @@ jobs:
9191
output: test/unit/gotest.html
9292
if: failure() || success()
9393
- name: Archive the HTML report
94-
uses: actions/upload-artifact@v4
94+
uses: actions/upload-artifact@v5
9595
with:
9696
name: html
9797
path: test/unit/gotest.html

.github/workflows/interop.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
with:
3838
go-version-file: 'go.mod'
3939
- run: make build
40-
- uses: actions/upload-artifact@v4
40+
- uses: actions/upload-artifact@v5
4141
with:
4242
name: kubo
4343
path: cmd/ipfs/ipfs
@@ -49,10 +49,10 @@ jobs:
4949
run:
5050
shell: bash
5151
steps:
52-
- uses: actions/setup-node@v5
52+
- uses: actions/setup-node@v6
5353
with:
5454
node-version: lts/*
55-
- uses: actions/download-artifact@v5
55+
- uses: actions/download-artifact@v6
5656
with:
5757
name: kubo
5858
path: cmd/ipfs
@@ -84,10 +84,10 @@ jobs:
8484
run:
8585
shell: bash
8686
steps:
87-
- uses: actions/setup-node@v5
87+
- uses: actions/setup-node@v6
8888
with:
8989
node-version: 20.x
90-
- uses: actions/download-artifact@v5
90+
- uses: actions/download-artifact@v6
9191
with:
9292
name: kubo
9393
path: cmd/ipfs

.github/workflows/sharness.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
destination: sharness.html
8989
- name: Upload one-page HTML report
9090
if: github.repository != 'ipfs/kubo' && (failure() || success())
91-
uses: actions/upload-artifact@v4
91+
uses: actions/upload-artifact@v5
9292
with:
9393
name: sharness.html
9494
path: kubo/test/sharness/test-results/sharness.html
@@ -108,7 +108,7 @@ jobs:
108108
destination: sharness-html/
109109
- name: Upload full HTML report
110110
if: github.repository != 'ipfs/kubo' && (failure() || success())
111-
uses: actions/upload-artifact@v4
111+
uses: actions/upload-artifact@v5
112112
with:
113113
name: sharness-html
114114
path: kubo/test/sharness/test-results/sharness-html

.github/workflows/sync-release-assets.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- uses: ipfs/start-ipfs-daemon-action@v1
2323
with:
2424
args: --init --init-profile=flatfs,server --enable-gc=false
25-
- uses: actions/setup-node@v5
25+
- uses: actions/setup-node@v6
2626
with:
2727
node-version: 14
2828
- name: Sync the latest 5 github releases

.github/workflows/test-migrations.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
7878
- name: Upload test results
7979
if: always()
80-
uses: actions/upload-artifact@v4
80+
uses: actions/upload-artifact@v5
8181
with:
8282
name: ${{ matrix.os }}-test-results
8383
path: |

config/provide.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const (
1616
DefaultProvideDHTInterval = 22 * time.Hour // https://github.com/ipfs/kubo/pull/9326
1717
DefaultProvideDHTMaxWorkers = 16 // Unified default for both sweep and legacy providers
1818
DefaultProvideDHTSweepEnabled = false
19+
DefaultProvideDHTResumeEnabled = true
1920
DefaultProvideDHTDedicatedPeriodicWorkers = 2
2021
DefaultProvideDHTDedicatedBurstWorkers = 1
2122
DefaultProvideDHTMaxProvideConnsPerWorker = 20
@@ -86,6 +87,12 @@ type ProvideDHT struct {
8687
// OfflineDelay sets the delay after which the provider switches from Disconnected to Offline state (sweep mode only).
8788
// Default: DefaultProvideDHTOfflineDelay
8889
OfflineDelay *OptionalDuration `json:",omitempty"`
90+
91+
// ResumeEnabled controls whether the provider resumes from its previous state on restart.
92+
// When enabled, the provider persists its reprovide cycle state and provide queue to the datastore,
93+
// and restores them on restart. When disabled, the provider starts fresh on each restart.
94+
// Default: true
95+
ResumeEnabled Flag `json:",omitempty"`
8996
}
9097

9198
func ParseProvideStrategy(s string) ProvideStrategy {

core/commands/provide.go

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ NOTES:
348348
}
349349
sectionTitle := func(col int, title string) {
350350
if !brief && showHeadings {
351+
//nolint:govet // dynamic format string is intentional
351352
formatLine(col, title+":")
352353
}
353354
}
@@ -372,8 +373,8 @@ NOTES:
372373
// Queues
373374
if all || queues || brief {
374375
sectionTitle(1, "Queues")
375-
formatLine(1, "%sProvide queue: %s CIDs, %s regions", indent, humanNumber(s.Sweep.Queues.PendingKeyProvides), humanNumber(s.Sweep.Queues.PendingRegionProvides))
376-
formatLine(1, "%sReprovide queue: %s regions", indent, humanNumber(s.Sweep.Queues.PendingRegionReprovides))
376+
formatLine(1, "%sProvide queue: %s CIDs, %s regions", indent, humanSI(s.Sweep.Queues.PendingKeyProvides, 1), humanSI(s.Sweep.Queues.PendingRegionProvides, 1))
377+
formatLine(1, "%sReprovide queue: %s regions", indent, humanSI(s.Sweep.Queues.PendingRegionReprovides, 1))
377378
addBlankLine(1)
378379
}
379380

@@ -413,12 +414,12 @@ NOTES:
413414
sectionTitle(0, "Network")
414415
formatLine(0, "%sAvg record holders: %s", indent, humanFloatOrNA(s.Sweep.Network.AvgHolders))
415416
if !brief {
416-
formatLine(0, "%sPeers swept: %s", indent, humanNumber(s.Sweep.Network.Peers))
417+
formatLine(0, "%sPeers swept: %s", indent, humanInt(s.Sweep.Network.Peers))
417418
formatLine(0, "%sFull keyspace coverage: %t", indent, s.Sweep.Network.CompleteKeyspaceCoverage)
418419
if s.Sweep.Network.Peers > 0 {
419-
formatLine(0, "%sReachable peers: %s (%s%%)", indent, humanNumber(s.Sweep.Network.Reachable), humanNumber(100*s.Sweep.Network.Reachable/s.Sweep.Network.Peers))
420+
formatLine(0, "%sReachable peers: %s (%s%%)", indent, humanInt(s.Sweep.Network.Reachable), humanNumber(100*s.Sweep.Network.Reachable/s.Sweep.Network.Peers))
420421
} else {
421-
formatLine(0, "%sReachable peers: %s", indent, humanNumber(s.Sweep.Network.Reachable))
422+
formatLine(0, "%sReachable peers: %s", indent, humanInt(s.Sweep.Network.Reachable))
422423
}
423424
formatLine(0, "%sAvg region size: %s", indent, humanFloatOrNA(s.Sweep.Network.AvgRegionSize))
424425
formatLine(0, "%sReplication factor: %s", indent, humanNumber(s.Sweep.Network.ReplicationFactor))
@@ -430,15 +431,15 @@ NOTES:
430431
if all || operations || brief {
431432
sectionTitle(1, "Operations")
432433
// Ongoing operations
433-
formatLine(1, "%sOngoing provides: %s CIDs, %s regions", indent, humanNumber(s.Sweep.Operations.Ongoing.KeyProvides), humanNumber(s.Sweep.Operations.Ongoing.RegionProvides))
434-
formatLine(1, "%sOngoing reprovides: %s CIDs, %s regions", indent, humanNumber(s.Sweep.Operations.Ongoing.KeyReprovides), humanNumber(s.Sweep.Operations.Ongoing.RegionReprovides))
434+
formatLine(1, "%sOngoing provides: %s CIDs, %s regions", indent, humanSI(s.Sweep.Operations.Ongoing.KeyProvides, 1), humanSI(s.Sweep.Operations.Ongoing.RegionProvides, 1))
435+
formatLine(1, "%sOngoing reprovides: %s CIDs, %s regions", indent, humanSI(s.Sweep.Operations.Ongoing.KeyReprovides, 1), humanSI(s.Sweep.Operations.Ongoing.RegionReprovides, 1))
435436
// Past operations summary
436437
formatLine(1, "%sTotal CIDs provided: %s", indent, humanNumber(s.Sweep.Operations.Past.KeysProvided))
437438
if !brief {
438439
formatLine(1, "%sTotal records provided: %s", indent, humanNumber(s.Sweep.Operations.Past.RecordsProvided))
439440
formatLine(1, "%sTotal provide errors: %s", indent, humanNumber(s.Sweep.Operations.Past.KeysFailed))
440-
formatLine(1, "%sCIDs provided/min: %s", indent, humanFloatOrNA(s.Sweep.Operations.Past.KeysProvidedPerMinute))
441-
formatLine(1, "%sCIDs reprovided/min: %s", indent, humanFloatOrNA(s.Sweep.Operations.Past.KeysReprovidedPerMinute))
441+
formatLine(1, "%sCIDs provided/min/worker: %s", indent, humanFloatOrNA(s.Sweep.Operations.Past.KeysProvidedPerMinute))
442+
formatLine(1, "%sCIDs reprovided/min/worker: %s", indent, humanFloatOrNA(s.Sweep.Operations.Past.KeysReprovidedPerMinute))
442443
formatLine(1, "%sRegion reprovide duration: %s", indent, humanDurationOrNA(s.Sweep.Operations.Past.RegionReprovideDuration))
443444
formatLine(1, "%sAvg CIDs/reprovide: %s", indent, humanFloatOrNA(s.Sweep.Operations.Past.AvgKeysPerReprovide))
444445
formatLine(1, "%sRegions reprovided (last cycle): %s", indent, humanNumber(s.Sweep.Operations.Past.RegionReprovidedLastCycle))
@@ -451,7 +452,7 @@ NOTES:
451452
if displayWorkers || brief {
452453
availableReservedBurst := max(0, s.Sweep.Workers.DedicatedBurst-s.Sweep.Workers.ActiveBurst)
453454
availableReservedPeriodic := max(0, s.Sweep.Workers.DedicatedPeriodic-s.Sweep.Workers.ActivePeriodic)
454-
availableFreeWorkers := s.Sweep.Workers.Max - max(s.Sweep.Workers.DedicatedBurst, s.Sweep.Workers.ActiveBurst) - max(s.Sweep.Workers.DedicatedPeriodic, s.Sweep.Workers.ActivePeriodic)
455+
availableFreeWorkers := max(0, s.Sweep.Workers.Max-max(s.Sweep.Workers.DedicatedBurst, s.Sweep.Workers.ActiveBurst)-max(s.Sweep.Workers.DedicatedPeriodic, s.Sweep.Workers.ActivePeriodic))
455456
availableBurst := availableFreeWorkers + availableReservedBurst
456457
availablePeriodic := availableFreeWorkers + availableReservedPeriodic
457458

@@ -463,21 +464,21 @@ NOTES:
463464
if compactMode {
464465
specifyWorkers = ""
465466
}
466-
formatLine(0, "%sActive%s: %s / %s (max)", indent, specifyWorkers, humanNumber(s.Sweep.Workers.Active), humanNumber(s.Sweep.Workers.Max))
467+
formatLine(0, "%sActive%s: %s / %s (max)", indent, specifyWorkers, humanInt(s.Sweep.Workers.Active), humanInt(s.Sweep.Workers.Max))
467468
if brief {
468469
// Brief mode - show condensed worker info
469470
formatLine(0, "%sPeriodic%s: %s active, %s available, %s queued", indent, specifyWorkers,
470-
humanNumber(s.Sweep.Workers.ActivePeriodic), humanNumber(availablePeriodic), humanNumber(s.Sweep.Workers.QueuedPeriodic))
471+
humanInt(s.Sweep.Workers.ActivePeriodic), humanInt(availablePeriodic), humanInt(s.Sweep.Workers.QueuedPeriodic))
471472
formatLine(0, "%sBurst%s: %s active, %s available, %s queued\n", indent, specifyWorkers,
472-
humanNumber(s.Sweep.Workers.ActiveBurst), humanNumber(availableBurst), humanNumber(s.Sweep.Workers.QueuedBurst))
473+
humanInt(s.Sweep.Workers.ActiveBurst), humanInt(availableBurst), humanInt(s.Sweep.Workers.QueuedBurst))
473474
} else {
474-
formatLine(0, "%sFree%s: %s", indent, specifyWorkers, humanNumber(availableFreeWorkers))
475-
formatLine(0, "%sWorkers stats:%s %-9s %s", indent, " ", "Periodic", "Burst")
476-
formatLine(0, "%s %-14s %-9s %s", indent, "Active:", humanNumber(s.Sweep.Workers.ActivePeriodic), humanNumber(s.Sweep.Workers.ActiveBurst))
477-
formatLine(0, "%s %-14s %-9s %s", indent, "Dedicated:", humanNumber(s.Sweep.Workers.DedicatedPeriodic), humanNumber(s.Sweep.Workers.DedicatedBurst))
478-
formatLine(0, "%s %-14s %-9s %s", indent, "Available:", humanNumber(availablePeriodic), humanNumber(availableBurst))
479-
formatLine(0, "%s %-14s %-9s %s", indent, "Queued:", humanNumber(s.Sweep.Workers.QueuedPeriodic), humanNumber(s.Sweep.Workers.QueuedBurst))
480-
formatLine(0, "%sMax connections/worker: %s", indent, humanNumber(s.Sweep.Workers.MaxProvideConnsPerWorker))
475+
formatLine(0, "%sFree%s: %s", indent, specifyWorkers, humanInt(availableFreeWorkers))
476+
formatLine(0, "%s %-14s %-9s %s", indent, "Workers stats:", "Periodic", "Burst")
477+
formatLine(0, "%s %-14s %-9s %s", indent, "Active:", humanInt(s.Sweep.Workers.ActivePeriodic), humanInt(s.Sweep.Workers.ActiveBurst))
478+
formatLine(0, "%s %-14s %-9s %s", indent, "Dedicated:", humanInt(s.Sweep.Workers.DedicatedPeriodic), humanInt(s.Sweep.Workers.DedicatedBurst))
479+
formatLine(0, "%s %-14s %-9s %s", indent, "Available:", humanInt(availablePeriodic), humanInt(availableBurst))
480+
formatLine(0, "%s %-14s %-9s %s", indent, "Queued:", humanInt(s.Sweep.Workers.QueuedPeriodic), humanInt(s.Sweep.Workers.QueuedBurst))
481+
formatLine(0, "%sMax connections/worker: %s", indent, humanInt(s.Sweep.Workers.MaxProvideConnsPerWorker))
481482
addBlankLine(0)
482483
}
483484
}
@@ -559,14 +560,18 @@ func humanFloatOrNA(val float64) string {
559560
if val <= 0 {
560561
return "N/A"
561562
}
562-
return fmt.Sprintf("%.1f", val)
563+
return humanFull(val, 1)
563564
}
564565

565-
func humanSI(val float64, decimals int) string {
566-
v, unit := humanize.ComputeSI(val)
566+
func humanSI[T constraints.Float | constraints.Integer](val T, decimals int) string {
567+
v, unit := humanize.ComputeSI(float64(val))
567568
return fmt.Sprintf("%s%s", humanFull(v, decimals), unit)
568569
}
569570

571+
func humanInt[T constraints.Integer](val T) string {
572+
return humanFull(float64(val), 0)
573+
}
574+
570575
func humanFull(val float64, decimals int) string {
571576
return humanize.CommafWithDigits(val, decimals)
572577
}

core/node/provider.go

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/ipfs/boxo/provider"
1515
"github.com/ipfs/go-cid"
1616
"github.com/ipfs/go-datastore"
17+
"github.com/ipfs/go-datastore/namespace"
1718
"github.com/ipfs/go-datastore/query"
1819
"github.com/ipfs/kubo/config"
1920
"github.com/ipfs/kubo/repo"
@@ -36,14 +37,21 @@ import (
3637
"go.uber.org/fx"
3738
)
3839

39-
// The size of a batch that will be used for calculating average announcement
40-
// time per CID, inside of boxo/provider.ThroughputReport
41-
// and in 'ipfs stats provide' report.
42-
// Used when Provide.DHT.SweepEnabled=false
43-
const sampledBatchSize = 1000
40+
const (
41+
// The size of a batch that will be used for calculating average announcement
42+
// time per CID, inside of boxo/provider.ThroughputReport
43+
// and in 'ipfs stats provide' report.
44+
// Used when Provide.DHT.SweepEnabled=false
45+
sampledBatchSize = 1000
4446

45-
// Datastore key used to store previous reprovide strategy.
46-
const reprovideStrategyKey = "/reprovideStrategy"
47+
// Datastore key used to store previous reprovide strategy.
48+
reprovideStrategyKey = "/reprovideStrategy"
49+
50+
// Datastore namespace prefix for provider data.
51+
providerDatastorePrefix = "provider"
52+
// Datastore path for the provider keystore.
53+
keystoreDatastorePath = "keystore"
54+
)
4755

4856
// Interval between reprovide queue monitoring checks for slow reprovide alerts.
4957
// Used when Provide.DHT.SweepEnabled=true
@@ -324,10 +332,10 @@ func SweepingProviderOpt(cfg *config.Config) fx.Option {
324332
Repo repo.Repo
325333
}
326334
sweepingReprovider := fx.Provide(func(in providerInput) (DHTProvider, *keystore.ResettableKeystore, error) {
327-
ds := in.Repo.Datastore()
335+
ds := namespace.Wrap(in.Repo.Datastore(), datastore.NewKey(providerDatastorePrefix))
328336
ks, err := keystore.NewResettableKeystore(ds,
329337
keystore.WithPrefixBits(16),
330-
keystore.WithDatastorePath("/provider/keystore"),
338+
keystore.WithDatastorePath(keystoreDatastorePath),
331339
keystore.WithBatchSize(int(cfg.Provide.DHT.KeystoreBatchSize.WithDefault(config.DefaultProvideDHTKeystoreBatchSize))),
332340
)
333341
if err != nil {
@@ -370,6 +378,8 @@ func SweepingProviderOpt(cfg *config.Config) fx.Option {
370378
if inDht != nil {
371379
prov, err := ddhtprovider.New(inDht,
372380
ddhtprovider.WithKeystore(ks),
381+
ddhtprovider.WithDatastore(ds),
382+
ddhtprovider.WithResumeCycle(cfg.Provide.DHT.ResumeEnabled.WithDefault(config.DefaultProvideDHTResumeEnabled)),
373383

374384
ddhtprovider.WithReprovideInterval(reprovideInterval),
375385
ddhtprovider.WithMaxReprovideDelay(time.Hour),
@@ -403,7 +413,9 @@ func SweepingProviderOpt(cfg *config.Config) fx.Option {
403413
}
404414
opts := []dhtprovider.Option{
405415
dhtprovider.WithKeystore(ks),
406-
dhtprovider.WithPeerID(impl.Host().ID()),
416+
dhtprovider.WithDatastore(ds),
417+
dhtprovider.WithResumeCycle(cfg.Provide.DHT.ResumeEnabled.WithDefault(config.DefaultProvideDHTResumeEnabled)),
418+
dhtprovider.WithHost(impl.Host()),
407419
dhtprovider.WithRouter(impl),
408420
dhtprovider.WithMessageSender(impl.MessageSender()),
409421
dhtprovider.WithSelfAddrs(selfAddrsFunc),
@@ -542,6 +554,9 @@ func SweepingProviderOpt(cfg *config.Config) fx.Option {
542554
}
543555
reprovideAlert := fx.Invoke(func(lc fx.Lifecycle, in alertInput) {
544556
prov := extractSweepingProvider(in.Provider)
557+
if prov == nil {
558+
return
559+
}
545560

546561
var (
547562
cancel context.CancelFunc
@@ -550,9 +565,6 @@ func SweepingProviderOpt(cfg *config.Config) fx.Option {
550565

551566
lc.Append(fx.Hook{
552567
OnStart: func(ctx context.Context) error {
553-
if prov == nil {
554-
return nil
555-
}
556568
gcCtx, c := context.WithCancel(context.Background())
557569
cancel = c
558570
go func() {
@@ -562,7 +574,7 @@ func SweepingProviderOpt(cfg *config.Config) fx.Option {
562574
defer ticker.Stop()
563575

564576
var (
565-
queueSize, prevQueueSize int
577+
queueSize, prevQueueSize int64
566578
queuedWorkers, prevQueuedWorkers bool
567579
count int
568580
)
@@ -576,7 +588,7 @@ func SweepingProviderOpt(cfg *config.Config) fx.Option {
576588

577589
stats := prov.Stats()
578590
queuedWorkers = stats.Workers.QueuedPeriodic > 0
579-
queueSize = stats.Queues.PendingRegionReprovides
591+
queueSize = int64(stats.Queues.PendingRegionReprovides)
580592

581593
// Alert if reprovide queue keeps growing and all periodic workers are busy.
582594
// Requires consecutiveAlertsThreshold intervals of sustained growth.

0 commit comments

Comments
 (0)