@@ -9,6 +9,7 @@ package privdata
99import (
1010 "encoding/hex"
1111 "fmt"
12+ "github.com/hyperledger/fabric/internal/peer/protos"
1213 "math"
1314 "sync"
1415 "time"
@@ -53,6 +54,9 @@ type PvtDataReconciler interface {
5354 Start ()
5455 // Stop function stops reconciler
5556 Stop ()
57+
58+ //Reconcile performs on demand reconcilation a block or transaction
59+ Reconcile (uint65 uint64 ) (protos.ReconcileResponse , error )
5660}
5761
5862type Reconciler struct {
@@ -68,6 +72,25 @@ type Reconciler struct {
6872 committer.Committer
6973}
7074
75+ var ReconcilerServiceRegistry = make (map [string ]PvtDataReconciler )
76+
77+ // SetOnDemandReconcilerService sets a reconciler service by name
78+ func SetOnDemandReconcilerService (name string , reconciler PvtDataReconciler ) {
79+ ReconcilerServiceRegistry [name ] = reconciler
80+ }
81+
82+ func GetOnDemandReconcilerService (name string ) PvtDataReconciler {
83+
84+ if len (ReconcilerServiceRegistry ) == 0 {
85+ return nil
86+ }
87+ if ReconcilerServiceRegistry [name ] == nil {
88+ return nil
89+ }
90+
91+ return ReconcilerServiceRegistry [name ]
92+ }
93+
7194// NoOpReconciler non functional reconciler to be used
7295// in case reconciliation has been disabled
7396type NoOpReconciler struct {
@@ -82,6 +105,11 @@ func (*NoOpReconciler) Stop() {
82105 // do nothing
83106}
84107
108+ func (* NoOpReconciler ) Reconcile (num uint64 ) (protos.ReconcileResponse , error ) {
109+ logger .Debug ("Private data reconciliation has been disabled" )
110+ return protos.ReconcileResponse {Success : false , Message : "got nil as MissingPvtDataTracker, exiting..." }, nil
111+ }
112+
85113// NewReconciler creates a new instance of reconciler
86114func NewReconciler (channel string , metrics * metrics.PrivdataMetrics , c committer.Committer ,
87115 fetcher ReconciliationFetcher , config * PrivdataConfig ) * Reconciler {
@@ -111,6 +139,10 @@ func (r *Reconciler) Start() {
111139 })
112140}
113141
142+ func (r * Reconciler ) Reconcile (num uint64 ) (protos.ReconcileResponse , error ) {
143+ return r .reconcileSpecific (num )
144+ }
145+
114146func (r * Reconciler ) run () {
115147 for {
116148 select {
@@ -126,6 +158,60 @@ func (r *Reconciler) run() {
126158 }
127159}
128160
161+ // ReconcileSpecific initiates a reconcilation for specific block and returns the number of items that were reconciled , minBlock, maxBlock (blocks range) and an error
162+ func (r * Reconciler ) reconcileSpecific (num uint64 ) (protos.ReconcileResponse , error ) {
163+ missingPvtDataTracker , err := r .GetMissingPvtDataTracker ()
164+ if err != nil {
165+ r .logger .Error ("reconciliation error when trying to get missingPvtDataTracker:" , err )
166+ return protos.ReconcileResponse {Success : false , Message : err .Error ()}, err
167+ }
168+ if missingPvtDataTracker == nil {
169+ r .logger .Error ("got nil as MissingPvtDataTracker, exiting..." )
170+ return protos.ReconcileResponse {Success : false , Message : "got nil as MissingPvtDataTracker, exiting..." }, nil
171+ }
172+ totalReconciled := 0
173+
174+ defer r .reportReconciliationDuration (time .Now ())
175+
176+ // for {
177+ missingPvtDataInfo , err := missingPvtDataTracker .GetMissingPvtDataInfoForSpecificBlock (num )
178+ if err != nil {
179+ r .logger .Errorf ("reconciliation error when trying to get missing pvt data info for the block [%d] blocks: error %v" , num , err .Error ())
180+ return protos.ReconcileResponse {Success : false , Message : err .Error ()}, err
181+ }
182+ // if missingPvtDataInfo is nil, len will return 0
183+ if len (missingPvtDataInfo ) == 0 {
184+ r .logger .Debug ("Reconciliation cycle finished successfully. no items to reconcile" )
185+ return protos.ReconcileResponse {Success : true , Message : fmt .Sprintf ("Reconciliation cycle finished successfully. nothing to reconcile for blocks range [%d]" , num )}, nil
186+ }
187+
188+ r .logger .Debug ("got from ledger" , len (missingPvtDataInfo ), "blocks with missing private data, trying to reconcile..." )
189+
190+ dig2collectionCfg , _ , _ := r .getDig2CollectionConfig (missingPvtDataInfo )
191+ fetchedData , err := r .FetchReconciledItems (dig2collectionCfg )
192+ if err != nil {
193+ r .logger .Error ("reconciliation error when trying to fetch missing items from different peers:" , err )
194+ return protos.ReconcileResponse {Success : false , Message : err .Error ()}, err
195+ }
196+
197+ pvtDataToCommit := r .preparePvtDataToCommit (fetchedData .AvailableElements )
198+ unreconciled := constructUnreconciledMissingData (dig2collectionCfg , fetchedData .AvailableElements )
199+ pvtdataHashMismatch , err := r .CommitPvtDataOfOldBlocks (pvtDataToCommit , unreconciled )
200+ if err != nil {
201+ return protos.ReconcileResponse {Success : false , Message : "failed to commit private data" }, err
202+ }
203+ r .logMismatched (pvtdataHashMismatch )
204+ //if minB < minBlock {
205+ // minBlock = minB
206+ //}
207+ //if maxB > maxBlock {
208+ // maxBlock = maxB
209+ //}
210+ totalReconciled += len (fetchedData .AvailableElements )
211+ // }
212+ return protos.ReconcileResponse {Success : true , Message : fmt .Sprintf ("Reconciliation cycle finished successfully. reconciled %d private data keys from blocks range [%d]" , totalReconciled , num )}, nil
213+ }
214+
129215// returns the number of items that were reconciled , minBlock, maxBlock (blocks range) and an error
130216func (r * Reconciler ) reconcile () error {
131217 missingPvtDataTracker , err := r .GetMissingPvtDataTracker ()
0 commit comments