Skip to content

Commit 0c73c90

Browse files
committed
[FAB-15488] Refactor viper in gossip/privdata
Refactor viper calls in gossip/privdata package, creating privdataConfig structure to hold all viper configurations. Change-Id: I5749213b961378e6435bf2e8092f91c15de009db Signed-off-by: Chongxin Luo <Chongxin.Luo@ibm.com>
1 parent f7808d6 commit 0c73c90

File tree

11 files changed

+237
-128
lines changed

11 files changed

+237
-128
lines changed

gossip/privdata/config.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package privdata
8+
9+
import (
10+
"time"
11+
12+
"github.com/spf13/viper"
13+
)
14+
15+
const (
16+
reconcileSleepIntervalDefault = time.Minute * 1
17+
reconcileBatchSizeDefault = 10
18+
)
19+
20+
// PrivdataConfig is the struct that defines the Gossip Privdata configurations.
21+
type PrivdataConfig struct {
22+
// ReconcileSleepInterval determines the time reconciler sleeps from end of an interation until the beginning of the next
23+
// reconciliation iteration.
24+
ReconcileSleepInterval time.Duration
25+
// ReconcileBatchSize determines the maximum batch size of missing private data that will be reconciled in a single iteration.
26+
ReconcileBatchSize int
27+
// ReconciliationEnabled is a flag that indicates whether private data reconciliation is enabled or not.
28+
ReconciliationEnabled bool
29+
}
30+
31+
// GlobalConfig obtains a set of configuration from viper, build and returns the config struct.
32+
func GlobalConfig() *PrivdataConfig {
33+
c := &PrivdataConfig{}
34+
c.loadPrivDataConfig()
35+
return c
36+
}
37+
38+
func (c *PrivdataConfig) loadPrivDataConfig() {
39+
c.ReconcileSleepInterval = viper.GetDuration("peer.gossip.pvtData.reconcileSleepInterval")
40+
if c.ReconcileSleepInterval == 0 {
41+
logger.Warning("Configuration key peer.gossip.pvtData.reconcileSleepInterval isn't set, defaulting to", reconcileSleepIntervalDefault)
42+
c.ReconcileSleepInterval = reconcileSleepIntervalDefault
43+
}
44+
45+
c.ReconcileBatchSize = viper.GetInt("peer.gossip.pvtData.reconcileBatchSize")
46+
if c.ReconcileBatchSize == 0 {
47+
logger.Warning("Configuration key peer.gossip.pvtData.reconcileBatchSize isn't set, defaulting to", reconcileBatchSizeDefault)
48+
c.ReconcileBatchSize = reconcileBatchSizeDefault
49+
}
50+
51+
c.ReconciliationEnabled = viper.GetBool("peer.gossip.pvtData.reconciliationEnabled")
52+
53+
}

gossip/privdata/config_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package privdata_test
8+
9+
import (
10+
"testing"
11+
"time"
12+
13+
"github.com/hyperledger/fabric/gossip/privdata"
14+
"github.com/spf13/viper"
15+
"github.com/stretchr/testify/assert"
16+
)
17+
18+
func TestGlobalConfig(t *testing.T) {
19+
viper.Reset()
20+
// Capture the configuration from viper
21+
viper.Set("peer.gossip.pvtData.reconcileSleepInterval", "10s")
22+
viper.Set("peer.gossip.pvtData.reconcileBatchSize", 10)
23+
viper.Set("peer.gossip.pvtData.reconciliationEnabled", true)
24+
25+
coreConfig := privdata.GlobalConfig()
26+
27+
expectedConfig := &privdata.PrivdataConfig{
28+
ReconcileSleepInterval: 10 * time.Second,
29+
ReconcileBatchSize: 10,
30+
ReconciliationEnabled: true,
31+
}
32+
33+
assert.Equal(t, coreConfig, expectedConfig)
34+
}
35+
36+
func TestGlobalConfigDefaults(t *testing.T) {
37+
viper.Reset()
38+
39+
coreConfig := privdata.GlobalConfig()
40+
41+
expectedConfig := &privdata.PrivdataConfig{
42+
ReconcileSleepInterval: time.Minute,
43+
ReconcileBatchSize: 10,
44+
ReconciliationEnabled: false,
45+
}
46+
47+
assert.Equal(t, coreConfig, expectedConfig)
48+
}

gossip/privdata/coordinator_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func init() {
4646

4747
var testConfig = CoordinatorConfig{
4848
PullRetryThreshold: time.Second * 3,
49-
TransientBlockRetention: TransientBlockRetentionDefault,
49+
TransientBlockRetention: 1000,
5050
}
5151

5252
// CollectionCriteria aggregates criteria of

gossip/privdata/reconcile.go

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,15 @@ type PvtDataReconciler interface {
5555
}
5656

5757
type Reconciler struct {
58-
channel string
59-
metrics *metrics.PrivdataMetrics
60-
config *ReconcilerConfig
58+
channel string
59+
metrics *metrics.PrivdataMetrics
60+
ReconcileSleepInterval time.Duration
61+
ReconcileBatchSize int
62+
stopChan chan struct{}
63+
startOnce sync.Once
64+
stopOnce sync.Once
6165
ReconciliationFetcher
6266
committer.Committer
63-
stopChan chan struct{}
64-
startOnce sync.Once
65-
stopOnce sync.Once
6667
}
6768

6869
// NoOpReconciler non functional reconciler to be used
@@ -79,24 +80,18 @@ func (*NoOpReconciler) Stop() {
7980
// do nothing
8081
}
8182

82-
// ReconcilerConfig holds config flags that are read from core.yaml
83-
type ReconcilerConfig struct {
84-
SleepInterval time.Duration
85-
BatchSize int
86-
IsEnabled bool
87-
}
88-
8983
// NewReconciler creates a new instance of reconciler
9084
func NewReconciler(channel string, metrics *metrics.PrivdataMetrics, c committer.Committer,
91-
fetcher ReconciliationFetcher, config *ReconcilerConfig) *Reconciler {
85+
fetcher ReconciliationFetcher, config *PrivdataConfig) *Reconciler {
9286
logger.Debug("Private data reconciliation is enabled")
9387
return &Reconciler{
94-
channel: channel,
95-
metrics: metrics,
96-
config: config,
97-
Committer: c,
98-
ReconciliationFetcher: fetcher,
99-
stopChan: make(chan struct{}),
88+
channel: channel,
89+
metrics: metrics,
90+
ReconcileSleepInterval: config.ReconcileSleepInterval,
91+
ReconcileBatchSize: config.ReconcileBatchSize,
92+
Committer: c,
93+
ReconciliationFetcher: fetcher,
94+
stopChan: make(chan struct{}),
10095
}
10196
}
10297

@@ -117,7 +112,7 @@ func (r *Reconciler) run() {
117112
select {
118113
case <-r.stopChan:
119114
return
120-
case <-time.After(r.config.SleepInterval):
115+
case <-time.After(r.ReconcileSleepInterval):
121116
logger.Debug("Start reconcile missing private info")
122117
if err := r.reconcile(); err != nil {
123118
logger.Error("Failed to reconcile missing private info, error: ", err.Error())
@@ -143,7 +138,7 @@ func (r *Reconciler) reconcile() error {
143138
defer r.reportReconciliationDuration(time.Now())
144139

145140
for {
146-
missingPvtDataInfo, err := missingPvtDataTracker.GetMissingPvtDataInfoForMostRecentBlocks(r.config.BatchSize)
141+
missingPvtDataInfo, err := missingPvtDataTracker.GetMissingPvtDataInfoForMostRecentBlocks(r.ReconcileBatchSize)
147142
if err != nil {
148143
logger.Error("reconciliation error when trying to get missing pvt data info recent blocks:", err)
149144
return err

gossip/privdata/reconcile_test.go

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,13 @@ func TestNoItemsToReconcile(t *testing.T) {
4040
committer.On("GetMissingPvtDataTracker").Return(missingPvtDataTracker, nil)
4141
fetcher.On("FetchReconciledItems", mock.Anything).Return(nil, errors.New("this function shouldn't be called"))
4242

43-
r := &Reconciler{channel: "", metrics: metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics,
44-
config: &ReconcilerConfig{SleepInterval: time.Minute, BatchSize: 1, IsEnabled: true},
45-
ReconciliationFetcher: fetcher, Committer: committer}
43+
r := &Reconciler{
44+
channel: "",
45+
metrics: metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics,
46+
ReconcileSleepInterval: time.Minute,
47+
ReconcileBatchSize: 1,
48+
ReconciliationFetcher: fetcher, Committer: committer,
49+
}
4650
err := r.reconcile()
4751

4852
assert.NoError(t, err)
@@ -78,9 +82,13 @@ func TestNotReconcilingWhenCollectionConfigNotAvailable(t *testing.T) {
7882
fetchCalled = true
7983
}).Return(nil, errors.New("called with no digests"))
8084

81-
r := &Reconciler{channel: "", metrics: metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics,
82-
config: &ReconcilerConfig{SleepInterval: time.Minute, BatchSize: 1, IsEnabled: true},
83-
ReconciliationFetcher: fetcher, Committer: committer}
85+
r := &Reconciler{
86+
channel: "",
87+
metrics: metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics,
88+
ReconcileSleepInterval: time.Minute,
89+
ReconcileBatchSize: 1,
90+
ReconciliationFetcher: fetcher, Committer: committer,
91+
}
8492
err := r.reconcile()
8593

8694
assert.Error(t, err)
@@ -160,9 +168,13 @@ func TestReconciliationHappyPathWithoutScheduler(t *testing.T) {
160168
testMetricProvider := gmetricsmocks.TestUtilConstructMetricProvider()
161169
metrics := metrics.NewGossipMetrics(testMetricProvider.FakeProvider).PrivdataMetrics
162170

163-
r := &Reconciler{channel: "mychannel", metrics: metrics,
164-
config: &ReconcilerConfig{SleepInterval: time.Minute, BatchSize: 1, IsEnabled: true},
165-
ReconciliationFetcher: fetcher, Committer: committer}
171+
r := &Reconciler{
172+
channel: "mychannel",
173+
metrics: metrics,
174+
ReconcileSleepInterval: time.Minute,
175+
ReconcileBatchSize: 1,
176+
ReconciliationFetcher: fetcher, Committer: committer,
177+
}
166178
err := r.reconcile()
167179

168180
assert.NoError(t, err)
@@ -247,8 +259,16 @@ func TestReconciliationHappyPathWithScheduler(t *testing.T) {
247259
wg.Done()
248260
}).Return([]*ledger.PvtdataHashMismatch{}, nil)
249261

250-
r := NewReconciler("", metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics, committer, fetcher,
251-
&ReconcilerConfig{SleepInterval: time.Millisecond * 100, BatchSize: 1, IsEnabled: true})
262+
r := NewReconciler(
263+
"",
264+
metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics,
265+
committer,
266+
fetcher,
267+
&PrivdataConfig{
268+
ReconcileSleepInterval: time.Millisecond * 100,
269+
ReconcileBatchSize: 1,
270+
ReconciliationEnabled: true,
271+
})
252272
r.Start()
253273
wg.Wait()
254274
r.Stop()
@@ -357,8 +377,16 @@ func TestReconciliationPullingMissingPrivateDataAtOnePass(t *testing.T) {
357377
wg.Done()
358378
}).Return([]*ledger.PvtdataHashMismatch{}, nil)
359379

360-
r := NewReconciler("", metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics, committer, fetcher,
361-
&ReconcilerConfig{SleepInterval: time.Millisecond * 100, BatchSize: 1, IsEnabled: true})
380+
r := NewReconciler(
381+
"",
382+
metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics,
383+
committer,
384+
fetcher,
385+
&PrivdataConfig{
386+
ReconcileSleepInterval: time.Millisecond * 100,
387+
ReconcileBatchSize: 1,
388+
ReconciliationEnabled: true,
389+
})
362390
r.Start()
363391
<-stopC
364392
r.Stop()
@@ -437,9 +465,13 @@ func TestReconciliationFailedToCommit(t *testing.T) {
437465

438466
committer.On("CommitPvtDataOfOldBlocks", mock.Anything).Return(nil, errors.New("failed to commit"))
439467

440-
r := &Reconciler{channel: "", metrics: metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics,
441-
config: &ReconcilerConfig{SleepInterval: time.Minute, BatchSize: 1, IsEnabled: true},
442-
ReconciliationFetcher: fetcher, Committer: committer}
468+
r := &Reconciler{
469+
channel: "",
470+
metrics: metrics.NewGossipMetrics(&disabled.Provider{}).PrivdataMetrics,
471+
ReconcileSleepInterval: time.Minute,
472+
ReconcileBatchSize: 1,
473+
ReconciliationFetcher: fetcher, Committer: committer,
474+
}
443475
err := r.reconcile()
444476

445477
assert.Error(t, err)
@@ -452,16 +484,24 @@ func TestFailuresWhileReconcilingMissingPvtData(t *testing.T) {
452484
fetcher := &mocks.ReconciliationFetcher{}
453485
committer.On("GetMissingPvtDataTracker").Return(nil, errors.New("failed to obtain missing pvt data tracker"))
454486

455-
r := NewReconciler("", metrics, committer, fetcher,
456-
&ReconcilerConfig{SleepInterval: time.Millisecond * 100, BatchSize: 1, IsEnabled: true})
487+
r := NewReconciler(
488+
"",
489+
metrics,
490+
committer,
491+
fetcher,
492+
&PrivdataConfig{
493+
ReconcileSleepInterval: time.Millisecond * 100,
494+
ReconcileBatchSize: 1,
495+
ReconciliationEnabled: true,
496+
})
457497
err := r.reconcile()
458498
assert.Error(t, err)
459499
assert.Contains(t, "failed to obtain missing pvt data tracker", err.Error())
460500

461501
committer.Mock = mock.Mock{}
462502
committer.On("GetMissingPvtDataTracker").Return(nil, nil)
463503
r = NewReconciler("", metrics, committer, fetcher,
464-
&ReconcilerConfig{SleepInterval: time.Millisecond * 100, BatchSize: 1, IsEnabled: true})
504+
&PrivdataConfig{ReconcileSleepInterval: time.Millisecond * 100, ReconcileBatchSize: 1, ReconciliationEnabled: true})
465505
err = r.reconcile()
466506
assert.Error(t, err)
467507
assert.Contains(t, "got nil as MissingPvtDataTracker, exiting...", err.Error())
@@ -472,7 +512,7 @@ func TestFailuresWhileReconcilingMissingPvtData(t *testing.T) {
472512
committer.Mock = mock.Mock{}
473513
committer.On("GetMissingPvtDataTracker").Return(missingPvtDataTracker, nil)
474514
r = NewReconciler("", metrics, committer, fetcher,
475-
&ReconcilerConfig{SleepInterval: time.Millisecond * 100, BatchSize: 1, IsEnabled: true})
515+
&PrivdataConfig{ReconcileSleepInterval: time.Millisecond * 100, ReconcileBatchSize: 1, ReconciliationEnabled: true})
476516
err = r.reconcile()
477517
assert.Error(t, err)
478518
assert.Contains(t, "failed get missing pvt data for recent blocks", err.Error())

gossip/privdata/util.go

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ package privdata
88

99
import (
1010
"fmt"
11-
"time"
1211

1312
"github.com/golang/protobuf/proto"
1413
"github.com/hyperledger/fabric/core/ledger"
@@ -19,7 +18,6 @@ import (
1918
"github.com/hyperledger/fabric/protos/ledger/rwset/kvrwset"
2019
"github.com/hyperledger/fabric/protos/msp"
2120
"github.com/hyperledger/fabric/protos/peer"
22-
"github.com/spf13/viper"
2321
)
2422

2523
type txValidationFlags []uint8
@@ -303,41 +301,3 @@ func (f *digestsAndSourceFactory) toSources(peers ...string) *digestsAndSourceFa
303301
func (f *digestsAndSourceFactory) create() dig2sources {
304302
return f.d2s
305303
}
306-
307-
const (
308-
rreconcileSleepIntervalConfigKey = "peer.gossip.pvtData.reconcileSleepInterval"
309-
reconcileSleepIntervalDefault = time.Minute * 1
310-
reconcileBatchSizeConfigKey = "peer.gossip.pvtData.reconcileBatchSize"
311-
reconcileBatchSizeDefault = 10
312-
reconciliationEnabledConfigKey = "peer.gossip.pvtData.reconciliationEnabled"
313-
)
314-
315-
// this func reads reconciler configuration values from core.yaml and returns ReconcilerConfig
316-
func GetReconcilerConfig() *ReconcilerConfig {
317-
reconcileSleepInterval := viper.GetDuration(rreconcileSleepIntervalConfigKey)
318-
if reconcileSleepInterval == 0 {
319-
logger.Warning("Configuration key", rreconcileSleepIntervalConfigKey, "isn't set, defaulting to", reconcileSleepIntervalDefault)
320-
reconcileSleepInterval = reconcileSleepIntervalDefault
321-
}
322-
reconcileBatchSize := viper.GetInt(reconcileBatchSizeConfigKey)
323-
if reconcileBatchSize == 0 {
324-
logger.Warning("Configuration key", reconcileBatchSizeConfigKey, "isn't set, defaulting to", reconcileBatchSizeDefault)
325-
reconcileBatchSize = reconcileBatchSizeDefault
326-
}
327-
isEnabled := viper.GetBool(reconciliationEnabledConfigKey)
328-
return &ReconcilerConfig{SleepInterval: reconcileSleepInterval, BatchSize: reconcileBatchSize, IsEnabled: isEnabled}
329-
}
330-
331-
const (
332-
transientBlockRetentionConfigKey = "peer.gossip.pvtData.transientstoreMaxBlockRetention"
333-
TransientBlockRetentionDefault = 1000
334-
)
335-
336-
func GetTransientBlockRetention() uint64 {
337-
transientBlockRetention := uint64(viper.GetInt(transientBlockRetentionConfigKey))
338-
if transientBlockRetention == 0 {
339-
logger.Warning("Configuration key", transientBlockRetentionConfigKey, "isn't set, defaulting to", TransientBlockRetentionDefault)
340-
transientBlockRetention = TransientBlockRetentionDefault
341-
}
342-
return transientBlockRetention
343-
}

0 commit comments

Comments
 (0)