@@ -1363,17 +1363,14 @@ public SDOrdererAddition setSDOrdererAddition(SDOrdererAddition sdOrdererAdditio
13631363
13641364 }
13651365
1366- static byte [] combineCerts (Collection <byte []>... certCollections ) throws IOException {
1366+ private static byte [] combineCerts (Collection <byte []>... certCollections ) throws IOException {
13671367 try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream ()) {
13681368 for (Collection <byte []> certCollection : certCollections ) {
13691369
13701370 for (byte [] cert : certCollection ) {
13711371 outputStream .write (cert );
1372-
13731372 }
1374-
13751373 }
1376-
13771374 return outputStream .toByteArray ();
13781375 }
13791376 }
@@ -3176,6 +3173,28 @@ public Collection<ProposalResponse> sendTransactionProposal(TransactionProposalR
31763173 return sendProposal (transactionProposalRequest , getEndorsingPeers ());
31773174 }
31783175
3176+ private static class PeerExactMatch { // use original equals of Peer and not what's overrident
3177+ final Peer peer ;
3178+
3179+ private PeerExactMatch (Peer peer ) {
3180+ this .peer = peer ;
3181+ }
3182+
3183+ @ Override
3184+ public boolean equals (Object obj ) {
3185+ if (!(obj instanceof PeerExactMatch )) {
3186+ return false ;
3187+ }
3188+
3189+ return peer == ((PeerExactMatch ) obj ).peer ;
3190+ }
3191+
3192+ @ Override
3193+ public int hashCode () {
3194+ return System .identityHashCode (peer );
3195+ }
3196+ }
3197+
31793198 /**
31803199 * Send a transaction proposal.
31813200 *
@@ -3247,30 +3266,45 @@ public Collection<ProposalResponse> sendTransactionProposalToEndorsers(Transacti
32473266 throw new ServiceDiscoveryException (format ("Channel %s failed to find and endorsers for chaincode %s no layouts found." , name , chaincodeName ));
32483267 }
32493268
3250- SDChaindcode sdChaindcodeNI = new SDChaindcode (sdChaindcode ); //copy. no ignored.
3269+ SDChaindcode sdChaindcodeEndorsementCopy = new SDChaindcode (sdChaindcode ); //copy. no ignored.
32513270
32523271 final boolean inspectResults = discoveryOptions .inspectResults ;
32533272
3254- if (sdChaindcodeNI .ignoreList (discoveryOptions .getIgnoreList ()) < 1 ) { // apply ignore list
3273+ if (sdChaindcodeEndorsementCopy .ignoreList (discoveryOptions .getIgnoreList ()) < 1 ) { // apply ignore list
32553274 throw new ServiceDiscoveryException ("Applying ignore list reduced to no available endorser options." );
32563275 }
32573276
32583277 if (IS_TRACE_LEVEL && null != discoveryOptions .getIgnoreList () && !discoveryOptions .getIgnoreList ().isEmpty ()) {
3259- logger .trace (format ("SDchaincode after ignore list: %s" , sdChaindcodeNI ));
3278+ logger .trace (format ("SDchaincode after ignore list: %s" , sdChaindcodeEndorsementCopy ));
32603279 }
3261- final EndorsementSelector lendorsementSelector = discoveryOptions .endorsementSelector != null ?
3280+ final ServiceDiscovery . EndorsementSelector lendorsementSelector = discoveryOptions .endorsementSelector != null ?
32623281 discoveryOptions .endorsementSelector : this .endorsementSelector ;
32633282 try {
32643283
3265- final Map <String , ProposalResponse > goodResponses = new HashMap <>(); // all good endorsements by endpoint
3266- final Map <String , ProposalResponse > allTried = new HashMap <>(); // all tried by endpoint
3284+ final Map <SDEndorser , ProposalResponse > goodResponses = new HashMap <>(); // all good endorsements by endpoint
3285+ final Map <SDEndorser , ProposalResponse > allTried = new HashMap <>(); // all tried by endpoint
32673286
32683287 boolean done = false ;
32693288 int attempts = 1 ; //safety valve
32703289
32713290 do {
3272- logger .trace (format ("Attempts: %d, chaincode discovery state: %s" , attempts , sdChaindcodeNI ));
3273- final SDEndorserState sdEndorserState = lendorsementSelector .endorserSelector (sdChaindcodeNI );
3291+ if (IS_TRACE_LEVEL ) {
3292+ logger .trace (format ("Attempts: %d, chaincode discovery state: %s" , attempts , sdChaindcodeEndorsementCopy ));
3293+ }
3294+ final SDEndorserState sdEndorserState = lendorsementSelector .endorserSelector (sdChaindcodeEndorsementCopy );
3295+
3296+ if (IS_TRACE_LEVEL ) {
3297+
3298+ StringBuilder sb = new StringBuilder (1000 );
3299+ String sep = "" ;
3300+ for (SDEndorser sdEndorser : sdEndorserState .getSdEndorsers ()) {
3301+ sb .append (sep ).append (sdEndorser );
3302+ sep = ", " ;
3303+ }
3304+
3305+ logger .trace (format ("Attempts: %d, chaincode discovery state: %s. Endorser selector picked: %s. With selected endorsers: %s" , attempts , sdChaindcodeEndorsementCopy .name , sdEndorserState .getPickedLayout (), sb .toString ()));
3306+
3307+ }
32743308
32753309 Collection <SDEndorser > ep = sdEndorserState .getSdEndorsers ();
32763310 ep = new ArrayList <>(ep ); // just in case it's not already a copy
@@ -3286,11 +3320,13 @@ public Collection<ProposalResponse> sendTransactionProposalToEndorsers(Transacti
32863320 }
32873321
32883322 //Safety check make sure the selector isn't giving back endpoints to retry
3289- ep .removeIf (sdEndorser -> goodResponses .keySet ().contains (sdEndorser . getEndpoint () ));
3323+ ep .removeIf (sdEndorser -> goodResponses .keySet ().contains (sdEndorser ));
32903324
32913325 if (ep .isEmpty ()) { // this would be odd but lets go with it.
3292- Set <String > needed = sdChaindcode .meetsEndorsmentPolicy (goodResponses .keySet ());
3293- if (needed != null ) {
3326+ logger .debug (format ("Channel %s, chaincode %s attempts: %d endorser selector returned no additional endorements needed." , name , chaincodeName , attempts ));
3327+
3328+ Collection <SDEndorser > needed = sdChaindcode .meetsEndorsmentPolicy (goodResponses .keySet ());
3329+ if (needed != null ) { // means endorsment meet with those in the needed.
32943330 ArrayList <ProposalResponse > ret = new ArrayList <>(needed .size ());
32953331 needed .forEach (s -> ret .add (goodResponses .get (s )));
32963332
@@ -3319,16 +3355,17 @@ public Collection<ProposalResponse> sendTransactionProposalToEndorsers(Transacti
33193355 }
33203356 }
33213357
3322- HashMap <String , Peer > stringPeerHashMap = new HashMap <>(peerEndpointMap );
3323- ArrayList <Peer > endorsers = new ArrayList <>(ep .size ());
3324- for (SDEndorser endpoint : ep ) {
3358+ Map <String , Peer > lpeerEndpointMap = new HashMap <>(peerEndpointMap );
3359+ Map <SDEndorser , Peer > endorsers = new HashMap <>(ep .size ());
3360+ Map <PeerExactMatch , SDEndorser > peer2sdEndorser = new HashMap <>(ep .size ());
3361+ for (SDEndorser sdEndorser : ep ) {
33253362
3326- Peer epeer = stringPeerHashMap .get (endpoint .getEndpoint ());
3363+ Peer epeer = lpeerEndpointMap .get (sdEndorser .getEndpoint ());
33273364 if (epeer != null && !epeer .hasConnected ()) {
33283365 // mostly because gossip may have malicious data so if we've not connected update TLS props from chaincode discovery.
33293366 final Properties properties = epeer .getProperties ();
33303367
3331- final byte [] bytes = combineCerts (endpoint .getTLSCerts (), endpoint .getTLSIntermediateCerts ());
3368+ final byte [] bytes = combineCerts (sdEndorser .getTLSCerts (), sdEndorser .getTLSIntermediateCerts ());
33323369 properties .put ("pemBytes" , bytes );
33333370 epeer .setProperties (properties );
33343371
@@ -3337,12 +3374,12 @@ public Collection<ProposalResponse> sendTransactionProposalToEndorsers(Transacti
33373374
33383375 @ Override
33393376 public String getMspId () {
3340- return endpoint .getMspid ();
3377+ return sdEndorser .getMspid ();
33413378 }
33423379
33433380 @ Override
33443381 public String getEndpoint () {
3345- return endpoint .getEndpoint ();
3382+ return sdEndorser .getEndpoint ();
33463383 }
33473384
33483385 @ Override
@@ -3358,12 +3395,12 @@ public HFClient getClient() {
33583395 @ Override
33593396 public byte [][] getTLSCerts () {
33603397
3361- return endpoint .getTLSCerts ().toArray (new byte [endpoint .getTLSCerts ().size ()][]);
3398+ return sdEndorser .getTLSCerts ().toArray (new byte [sdEndorser .getTLSCerts ().size ()][]);
33623399 }
33633400
33643401 @ Override
33653402 public byte [][] getTLSIntermediateCerts () {
3366- return endpoint .getTLSIntermediateCerts ().toArray (new byte [endpoint .getTLSIntermediateCerts ().size ()][]);
3403+ return sdEndorser .getTLSIntermediateCerts ().toArray (new byte [sdEndorser .getTLSIntermediateCerts ().size ()][]);
33673404 }
33683405
33693406 @ Override
@@ -3372,36 +3409,37 @@ public Map<String, Peer> getEndpointMap() {
33723409 }
33733410 });
33743411 }
3375- endorsers .add (epeer );
3412+ endorsers .put (sdEndorser , epeer );
3413+ peer2sdEndorser .put (new PeerExactMatch (epeer ), sdEndorser ); // reverse
33763414 }
33773415
3378- final Collection <ProposalResponse > proposalResponses = sendProposalToPeers (endorsers , invokeProposal , transactionContext );
3379- HashSet <String > loopGood = new HashSet <>();
3380- HashSet <String > loopBad = new HashSet <>();
3416+ final Collection <ProposalResponse > proposalResponses = sendProposalToPeers (endorsers . values () , invokeProposal , transactionContext );
3417+ HashSet <SDEndorser > loopGood = new HashSet <>();
3418+ HashSet <SDEndorser > loopBad = new HashSet <>();
33813419
33823420 for (ProposalResponse proposalResponse : proposalResponses ) {
3383- final String endpoint = proposalResponse .getPeer (). getEndpoint ( );
3384- allTried .put (endpoint , proposalResponse );
3421+ final SDEndorser sdEndorser = peer2sdEndorser . get ( new PeerExactMatch ( proposalResponse .getPeer ()) );
3422+ allTried .put (sdEndorser , proposalResponse );
33853423
33863424 final ChaincodeResponse .Status status = proposalResponse .getStatus ();
33873425
33883426 if (ChaincodeResponse .Status .SUCCESS .equals (status )) {
33893427
3390- goodResponses .put (endpoint , proposalResponse );
3391- logger .trace (format ("Channel %s, chaincode %s attempts %d good endorsements: %s" , name , chaincodeName , attempts , endpoint ));
3392- loopGood .add (endpoint );
3428+ goodResponses .put (sdEndorser , proposalResponse );
3429+ logger .trace (format ("Channel %s, chaincode %s attempts %d good endorsements: %s" , name , chaincodeName , attempts , sdEndorser ));
3430+ loopGood .add (sdEndorser );
33933431
33943432 } else {
3395- logger .debug (format ("Channel %s, chaincode %s attempts %d bad endorsements: %s" , name , chaincodeName , attempts , endpoint ));
3396- loopBad .add (endpoint );
3433+ logger .debug (format ("Channel %s, chaincode %s attempts %d bad endorsements: %s" , name , chaincodeName , attempts , sdEndorser ));
3434+ loopBad .add (sdEndorser );
33973435 }
33983436 }
33993437
34003438 //Always check on original
3401- Set < String > needed = sdChaindcode .meetsEndorsmentPolicy (goodResponses .keySet ());
3402- if (needed != null ) {
3403- ArrayList <ProposalResponse > ret = new ArrayList <>(needed .size ());
3404- needed .forEach (s -> ret .add (goodResponses .get (s )));
3439+ Collection < SDEndorser > required = sdChaindcode .meetsEndorsmentPolicy (goodResponses .keySet ());
3440+ if (required != null ) {
3441+ ArrayList <ProposalResponse > ret = new ArrayList <>(required .size ());
3442+ required .forEach (s -> ret .add (goodResponses .get (s )));
34053443
34063444 if (IS_DEBUG_LEVEL ) {
34073445
@@ -3410,26 +3448,22 @@ public Map<String, Peer> getEndpointMap() {
34103448 for (ProposalResponse proposalResponse : ret ) {
34113449 sb .append (sep ).append (proposalResponse .getPeer ());
34123450 sep = ", " ;
3413-
34143451 }
3415-
34163452 logger .debug (format ("Channel %s, chaincode %s got all needed endorsements: %s" , name , chaincodeName , sb .toString ()));
3417-
34183453 }
3419-
34203454 return ret ; // the happy path :)!
34213455
34223456 } else { //still don't have the needed endorsements.
34233457
3424- sdChaindcodeNI .endorsedList (loopGood );
3458+ sdChaindcodeEndorsementCopy .endorsedList (loopGood ); // mark the good ones in the working copy.
34253459
3426- if (sdChaindcodeNI . ignoreList (loopBad ) < 1 ) { // apply ignore list
3460+ if (sdChaindcodeEndorsementCopy . ignoreListSDEndorser (loopBad ) < 1 ) { // apply ignore list
34273461 done = true ; // no more layouts
34283462 }
34293463 }
34303464
34313465 } while (!done && ++attempts <= 5 );
3432- logger .trace (format ("Endorsements not achieved chaincode: %s, done: %b, attempts: %d" , chaincodeName , done , attempts ));
3466+ logger .debug (format ("Endorsements not achieved chaincode: %s, done: %b, attempts: %d" , chaincodeName , done , attempts ));
34333467 if (inspectResults ) {
34343468 return allTried .values ();
34353469 } else {
@@ -3598,10 +3632,10 @@ private Collection<ProposalResponse> sendProposal(TransactionRequest proposalReq
35983632 }
35993633 }
36003634
3601- private transient EndorsementSelector endorsementSelector = ServiceDiscovery .DEFAULT_ENDORSEMENT_SELECTION ;
3635+ private transient ServiceDiscovery . EndorsementSelector endorsementSelector = ServiceDiscovery .DEFAULT_ENDORSEMENT_SELECTION ;
36023636
3603- public EndorsementSelector setSDEndorserSelector (EndorsementSelector endorsementSelector ) {
3604- EndorsementSelector ret = this .endorsementSelector ;
3637+ public ServiceDiscovery . EndorsementSelector setSDEndorserSelector (ServiceDiscovery . EndorsementSelector endorsementSelector ) {
3638+ ServiceDiscovery . EndorsementSelector ret = this .endorsementSelector ;
36053639 this .endorsementSelector = endorsementSelector ;
36063640 return ret ;
36073641
@@ -4204,7 +4238,7 @@ List<String> getCollections() {
42044238 */
42054239 public static class DiscoveryOptions {
42064240 Set <String > ignoreList = new HashSet <>();
4207- EndorsementSelector endorsementSelector = null ;
4241+ ServiceDiscovery . EndorsementSelector endorsementSelector = null ;
42084242 boolean inspectResults = false ;
42094243 boolean forceDiscovery = false ;
42104244
@@ -4245,7 +4279,7 @@ public DiscoveryOptions setInspectResults(boolean inspectResults) {
42454279 * @return
42464280 * @throws InvalidArgumentException
42474281 */
4248- public DiscoveryOptions setEndorsementSelector (EndorsementSelector endorsementSelector ) throws InvalidArgumentException {
4282+ public DiscoveryOptions setEndorsementSelector (ServiceDiscovery . EndorsementSelector endorsementSelector ) throws InvalidArgumentException {
42494283 if (endorsementSelector == null ) {
42504284 throw new InvalidArgumentException ("endorsementSelector parameter is null." );
42514285 }
0 commit comments