-
Notifications
You must be signed in to change notification settings - Fork 8.8k
/
expiry_schedule_builder.go
100 lines (85 loc) · 3.7 KB
/
expiry_schedule_builder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package pvtstatepurgemgmt
import (
math "math"
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/privacyenabledstate"
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb"
"github.com/hyperledger/fabric/core/ledger/pvtdatapolicy"
"github.com/hyperledger/fabric/core/ledger/util"
)
type expiryScheduleBuilder struct {
btlPolicy pvtdatapolicy.BTLPolicy
scheduleEntries map[expiryInfoKey]*PvtdataKeys
}
func newExpiryScheduleBuilder(btlPolicy pvtdatapolicy.BTLPolicy) *expiryScheduleBuilder {
return &expiryScheduleBuilder{btlPolicy, make(map[expiryInfoKey]*PvtdataKeys)}
}
func (builder *expiryScheduleBuilder) add(ns, coll, key string, keyHash []byte, versionedValue *statedb.VersionedValue) error {
committingBlk := versionedValue.Version.BlockNum
expiryBlk, err := builder.btlPolicy.GetExpiringBlock(ns, coll, committingBlk)
if err != nil {
return err
}
if isDelete(versionedValue) || neverExpires(expiryBlk) {
return nil
}
expinfoKey := expiryInfoKey{committingBlk: committingBlk, expiryBlk: expiryBlk}
pvtdataKeys, ok := builder.scheduleEntries[expinfoKey]
if !ok {
pvtdataKeys = newPvtdataKeys()
builder.scheduleEntries[expinfoKey] = pvtdataKeys
}
pvtdataKeys.add(ns, coll, key, keyHash)
return nil
}
func isDelete(versionedValue *statedb.VersionedValue) bool {
return versionedValue.Value == nil
}
func neverExpires(expiryBlk uint64) bool {
return expiryBlk == math.MaxUint64
}
func (builder *expiryScheduleBuilder) getExpiryInfo() []*expiryInfo {
var listExpinfo []*expiryInfo
for expinfoKey, pvtdataKeys := range builder.scheduleEntries {
expinfoKeyCopy := expinfoKey
listExpinfo = append(listExpinfo, &expiryInfo{expiryInfoKey: &expinfoKeyCopy, pvtdataKeys: pvtdataKeys})
}
return listExpinfo
}
func buildExpirySchedule(
btlPolicy pvtdatapolicy.BTLPolicy,
pvtUpdates *privacyenabledstate.PvtUpdateBatch,
hashedUpdates *privacyenabledstate.HashedUpdateBatch) ([]*expiryInfo, error) {
hashedUpdateKeys := hashedUpdates.ToCompositeKeyMap()
expiryScheduleBuilder := newExpiryScheduleBuilder(btlPolicy)
logger.Debugf("Building the expiry schedules based on the update batch")
// Iterate through the private data updates and for each key add into the expiry schedule
// i.e., when these private data key and it's hashed-keys are going to be expired
// Note that the 'hashedUpdateKeys' may be superset of the pvtUpdates. This is because,
// the peer may not receive all the private data either because the peer is not eligible for certain private data
// or because we allow proceeding with the missing private data data
for pvtUpdateKey, vv := range pvtUpdates.ToCompositeKeyMap() {
keyHash := util.ComputeStringHash(pvtUpdateKey.Key)
hashedCompisiteKey := privacyenabledstate.HashedCompositeKey{
Namespace: pvtUpdateKey.Namespace,
CollectionName: pvtUpdateKey.CollectionName,
KeyHash: string(keyHash),
}
logger.Debugf("Adding expiry schedule for key and key hash [%s]", &hashedCompisiteKey)
if err := expiryScheduleBuilder.add(pvtUpdateKey.Namespace, pvtUpdateKey.CollectionName, pvtUpdateKey.Key, keyHash, vv); err != nil {
return nil, err
}
delete(hashedUpdateKeys, hashedCompisiteKey)
}
// Add entries for the leftover key hashes i.e., the hashes corresponding to which there is not private key is present
for hashedUpdateKey, vv := range hashedUpdateKeys {
logger.Debugf("Adding expiry schedule for key hash [%s]", &hashedUpdateKey)
if err := expiryScheduleBuilder.add(hashedUpdateKey.Namespace, hashedUpdateKey.CollectionName, "", []byte(hashedUpdateKey.KeyHash), vv); err != nil {
return nil, err
}
}
return expiryScheduleBuilder.getExpiryInfo(), nil
}