@@ -11,6 +11,7 @@ import (
11
11
"fmt"
12
12
"hash"
13
13
"math/big"
14
+ "runtime"
14
15
"sort"
15
16
"sync"
16
17
"testing"
@@ -41,67 +42,6 @@ type Sample struct {
41
42
Items []SampleItem
42
43
}
43
44
44
- // RandSample returns Sample with random values.
45
- func RandSample (t * testing.T , anchor []byte ) Sample {
46
- t .Helper ()
47
-
48
- chunks := make ([]swarm.Chunk , SampleSize )
49
- for i := 0 ; i < SampleSize ; i ++ {
50
- ch := chunk .GenerateTestRandomChunk ()
51
- if i % 3 == 0 {
52
- ch = chunk .GenerateTestRandomSoChunk (t , ch )
53
- }
54
- chunks [i ] = ch
55
- }
56
-
57
- sample , err := MakeSampleUsingChunks (chunks , anchor )
58
- if err != nil {
59
- t .Fatal (err )
60
- }
61
-
62
- return sample
63
- }
64
-
65
- // MakeSampleUsingChunks returns Sample constructed using supplied chunks.
66
- func MakeSampleUsingChunks (chunks []swarm.Chunk , anchor []byte ) (Sample , error ) {
67
- prefixHasherFactory := func () hash.Hash {
68
- return swarm .NewPrefixHasher (anchor )
69
- }
70
- items := make ([]SampleItem , len (chunks ))
71
- for i , ch := range chunks {
72
- tr , err := transformedAddress (bmt .NewHasher (prefixHasherFactory ), ch , getChunkType (ch ))
73
- if err != nil {
74
- return Sample {}, err
75
- }
76
-
77
- items [i ] = SampleItem {
78
- TransformedAddress : tr ,
79
- ChunkAddress : ch .Address (),
80
- ChunkData : ch .Data (),
81
- Stamp : newStamp (ch .Stamp ()),
82
- }
83
- }
84
-
85
- sort .Slice (items , func (i , j int ) bool {
86
- return items [i ].TransformedAddress .Compare (items [j ].TransformedAddress ) == - 1
87
- })
88
-
89
- return Sample {Items : items }, nil
90
- }
91
-
92
- func newStamp (s swarm.Stamp ) * postage.Stamp {
93
- return postage .NewStamp (s .BatchID (), s .Index (), s .Timestamp (), s .Sig ())
94
- }
95
-
96
- func getChunkType (chunk swarm.Chunk ) swarm.ChunkType {
97
- if cac .Valid (chunk ) {
98
- return swarm .ChunkTypeContentAddressed
99
- } else if soc .Valid (chunk ) {
100
- return swarm .ChunkTypeSingleOwner
101
- }
102
- return swarm .ChunkTypeUnspecified
103
- }
104
-
105
45
// ReserveSample generates the sample of reserve storage of a node required for the
106
46
// storage incentives agent to participate in the lottery round. In order to generate
107
47
// this sample we need to iterate through all the chunks in the node's reserve and
@@ -125,8 +65,9 @@ func (db *DB) ReserveSample(
125
65
consensusTime uint64 ,
126
66
minBatchBalance * big.Int ,
127
67
) (Sample , error ) {
68
+
128
69
g , ctx := errgroup .WithContext (ctx )
129
- chunkC := make ( chan * reserve. ChunkBinItem , 64 )
70
+
130
71
allStats := & SampleStats {}
131
72
statsLock := sync.Mutex {}
132
73
addStats := func (stats SampleStats ) {
@@ -144,6 +85,8 @@ func (db *DB) ReserveSample(
144
85
145
86
allStats .BatchesBelowValueDuration = time .Since (t )
146
87
88
+ chunkC := make (chan * reserve.ChunkBinItem )
89
+
147
90
// Phase 1: Iterate chunk addresses
148
91
g .Go (func () error {
149
92
start := time .Now ()
@@ -170,13 +113,14 @@ func (db *DB) ReserveSample(
170
113
})
171
114
172
115
// Phase 2: Get the chunk data and calculate transformed hash
173
- sampleItemChan := make (chan SampleItem , 64 )
116
+ sampleItemChan := make (chan SampleItem )
174
117
175
118
prefixHasherFactory := func () hash.Hash {
176
119
return swarm .NewPrefixHasher (anchor )
177
120
}
178
121
179
- const workers = 6
122
+ workers := max (4 , runtime .NumCPU ())
123
+ db .logger .Debug ("reserve sampler workers" , "count" , workers )
180
124
181
125
for i := 0 ; i < workers ; i ++ {
182
126
g .Go (func () error {
@@ -241,6 +185,7 @@ func (db *DB) ReserveSample(
241
185
}()
242
186
243
187
sampleItems := make ([]SampleItem , 0 , SampleSize )
188
+
244
189
// insert function will insert the new item in its correct place. If the sample
245
190
// size goes beyond what we need we omit the last item.
246
191
insert := func (item SampleItem ) {
@@ -376,20 +321,20 @@ func transformedAddressCAC(hasher *bmt.Hasher, chunk swarm.Chunk) (swarm.Address
376
321
return swarm .NewAddress (taddr ), nil
377
322
}
378
323
379
- func transformedAddressSOC (hasher * bmt.Hasher , chunk swarm.Chunk ) (swarm.Address , error ) {
324
+ func transformedAddressSOC (hasher * bmt.Hasher , socChunk swarm.Chunk ) (swarm.Address , error ) {
380
325
// Calculate transformed address from wrapped chunk
381
- sChunk , err := soc .FromChunk ( chunk )
326
+ cacChunk , err := soc .UnwrapCAC ( socChunk )
382
327
if err != nil {
383
328
return swarm .ZeroAddress , err
384
329
}
385
- taddrCac , err := transformedAddressCAC (hasher , sChunk . WrappedChunk () )
330
+ taddrCac , err := transformedAddressCAC (hasher , cacChunk )
386
331
if err != nil {
387
332
return swarm .ZeroAddress , err
388
333
}
389
334
390
335
// Hash address and transformed address to make transformed address for this SOC
391
336
sHasher := swarm .NewHasher ()
392
- if _ , err := sHasher .Write (chunk .Address ().Bytes ()); err != nil {
337
+ if _ , err := sHasher .Write (socChunk .Address ().Bytes ()); err != nil {
393
338
return swarm .ZeroAddress , err
394
339
}
395
340
if _ , err := sHasher .Write (taddrCac .Bytes ()); err != nil {
@@ -432,3 +377,64 @@ func (s *SampleStats) add(other SampleStats) {
432
377
s .ChunkLoadFailed += other .ChunkLoadFailed
433
378
s .StampLoadFailed += other .StampLoadFailed
434
379
}
380
+
381
+ // RandSample returns Sample with random values.
382
+ func RandSample (t * testing.T , anchor []byte ) Sample {
383
+ t .Helper ()
384
+
385
+ chunks := make ([]swarm.Chunk , SampleSize )
386
+ for i := 0 ; i < SampleSize ; i ++ {
387
+ ch := chunk .GenerateTestRandomChunk ()
388
+ if i % 3 == 0 {
389
+ ch = chunk .GenerateTestRandomSoChunk (t , ch )
390
+ }
391
+ chunks [i ] = ch
392
+ }
393
+
394
+ sample , err := MakeSampleUsingChunks (chunks , anchor )
395
+ if err != nil {
396
+ t .Fatal (err )
397
+ }
398
+
399
+ return sample
400
+ }
401
+
402
+ // MakeSampleUsingChunks returns Sample constructed using supplied chunks.
403
+ func MakeSampleUsingChunks (chunks []swarm.Chunk , anchor []byte ) (Sample , error ) {
404
+ prefixHasherFactory := func () hash.Hash {
405
+ return swarm .NewPrefixHasher (anchor )
406
+ }
407
+ items := make ([]SampleItem , len (chunks ))
408
+ for i , ch := range chunks {
409
+ tr , err := transformedAddress (bmt .NewHasher (prefixHasherFactory ), ch , getChunkType (ch ))
410
+ if err != nil {
411
+ return Sample {}, err
412
+ }
413
+
414
+ items [i ] = SampleItem {
415
+ TransformedAddress : tr ,
416
+ ChunkAddress : ch .Address (),
417
+ ChunkData : ch .Data (),
418
+ Stamp : newStamp (ch .Stamp ()),
419
+ }
420
+ }
421
+
422
+ sort .Slice (items , func (i , j int ) bool {
423
+ return items [i ].TransformedAddress .Compare (items [j ].TransformedAddress ) == - 1
424
+ })
425
+
426
+ return Sample {Items : items }, nil
427
+ }
428
+
429
+ func newStamp (s swarm.Stamp ) * postage.Stamp {
430
+ return postage .NewStamp (s .BatchID (), s .Index (), s .Timestamp (), s .Sig ())
431
+ }
432
+
433
+ func getChunkType (chunk swarm.Chunk ) swarm.ChunkType {
434
+ if cac .Valid (chunk ) {
435
+ return swarm .ChunkTypeContentAddressed
436
+ } else if soc .Valid (chunk ) {
437
+ return swarm .ChunkTypeSingleOwner
438
+ }
439
+ return swarm .ChunkTypeUnspecified
440
+ }
0 commit comments