diff --git a/src/main/java/org/hyperledger/fabric/sdk/ServiceDiscovery.java b/src/main/java/org/hyperledger/fabric/sdk/ServiceDiscovery.java index ae73230a..05e0a69a 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/ServiceDiscovery.java +++ b/src/main/java/org/hyperledger/fabric/sdk/ServiceDiscovery.java @@ -1016,14 +1016,14 @@ public Collection getEndorsers() { boolean ignoreList(Collection names) { HashSet bnames = new HashSet<>(names); endorsers.removeIf(endorser -> bnames.contains(endorser.getEndpoint())); - return endorsers.size() >= required; + return endorsers.size() >= getStillRequired(); } //returns true if there are still sufficent endorsers for this group. boolean ignoreListSDEndorser(Collection sdEndorsers) { HashSet bnames = new HashSet<>(sdEndorsers); endorsers.removeIf(bnames::contains); - return endorsers.size() >= required; + return endorsers.size() >= getStillRequired(); } // retrun true if th endorsements have been meet. @@ -1041,7 +1041,7 @@ boolean endorsedList(Collection sdEndorsers) { endorsers.removeIf(endorser -> { if (enames.contains(endorser.getEndpoint())) { - endorsed = Math.min(required, endorsed++); + endorsed = Math.min(required, endorsed + 1); return true; // remove it. } return false; // needs to stay in the list. diff --git a/src/test/java/org/hyperledger/fabric/sdk/ServiceDiscoveryTest.java b/src/test/java/org/hyperledger/fabric/sdk/ServiceDiscoveryTest.java index 1756bbee..1640de26 100755 --- a/src/test/java/org/hyperledger/fabric/sdk/ServiceDiscoveryTest.java +++ b/src/test/java/org/hyperledger/fabric/sdk/ServiceDiscoveryTest.java @@ -32,6 +32,7 @@ import static org.hyperledger.fabric.sdk.ServiceDiscovery.SDEndorserState; import static org.hyperledger.fabric.sdk.ServiceDiscovery.SDLayout; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -335,6 +336,48 @@ public void twoLayoutTwoTwoEachExtrasCommonRandom() throws Exception { } + /** + * Test to ensure layouts and groups are correctly classified + * as (un)satisfied and (un)satisfiable during proposal response + * collection by the methods `endorsedList` and `ignoreListSDEndorser`. + */ + @Test + public void loopGoodAndBadTest() { + + // Let's say we have a group with 3 endorsers of which we require 2. + final int requiredInGroup = 2; + SDEndorser endorser1 = new MockSDEndorser("org1", "localhost:81", 0); + SDEndorser endorser2 = new MockSDEndorser("org1", "localhost:82", 0); + SDEndorser endorser3 = new MockSDEndorser("org1", "localhost:83", 0); + LinkedList endorsers = new LinkedList<>(); + endorsers.add(endorser1); + endorsers.add(endorser2); + endorsers.add(endorser3); + SDLayout layout = new SDLayout(); + layout.addGroup("G0", requiredInGroup, endorsers); + SDLayout.SDGroup group = layout.getSDLGroups().iterator().next(); + + // If 'endorser1' endorses successfully call `endorsedList`, + // the group should not be satisfied as we still require 1 more endorser. + LinkedList loopGood = new LinkedList<>(); + loopGood.add(endorser1); + assertFalse(layout.endorsedList(loopGood)); // false i.e. not yet satisfied. + assertEquals(1, group.getStillRequired()); + + // If 'endorser2' fails to endorse call `ignoreListSDEndorser`, + // the group should still be satisfiable as we still have 1 more endorser to try. + LinkedList loopBad = new LinkedList<>(); + loopBad.add(endorser2); + assertTrue(layout.ignoreListSDEndorser(loopBad)); // true i.e. still possible to satisfy. + assertEquals(1, group.getStillRequired()); + + // If 'endorser3' endorses, then the group should be satisfied. + loopGood = new LinkedList<>(); + loopGood.add(endorser3); + assertTrue(layout.endorsedList(loopGood)); // true i.e .satisfied. + assertEquals(0, group.getStillRequired()); + } + private static class MockSDEndorser extends SDEndorser { private MockSDEndorser(String mspid, String endpoint, long ledgerHeight) { super();