/** * Endorsement selection by random layout group and random endorsers there in. */ public static SDEndorserState ENDORSEMENT_SELECTION_RANDOM(SDChaindcode sdChaindcode) { List <SDLayout> layouts = sdChaindcode.Layouts; SDLayout pickedLayout = layouts[0]; if (layouts.Count > 1) { // more than one pick a random one. pickedLayout = layouts[random.Next(layouts.Count)]; } Dictionary <string, SDEndorser> retMap = new Dictionary <string, SDEndorser>(); //hold results. foreach (SDGroup group in pickedLayout.Groups) { // go through groups getting random required endorsers List <SDEndorser> endorsers = group.Endorsers.Shuffle().ToList(); // randomize. int required = group.StillRequired; // what's needed in that group. List <SDEndorser> sdEndorsers = endorsers.GetRange(0, required).ToList(); // pick top endorsers. sdEndorsers.ForEach(sdEndorser => { if (!retMap.ContainsKey(sdEndorser.Endpoint)) { retMap.Add(sdEndorser.Endpoint, sdEndorser); } }); } SDEndorserState sdEndorserState = new SDEndorserState(); //returned result. sdEndorserState.SDEndorsers = retMap.Values.ToList(); sdEndorserState.PickedLayout = pickedLayout; return(sdEndorserState); }
/** * Endorsement selection by layout group that has least required and block height is the highest (most up to date). */ public static SDEndorserState ENDORSEMENT_SELECTION_LEAST_REQUIRED_BLOCKHEIGHT(SDChaindcode sdChaindcode) { List <SDLayout> layouts = sdChaindcode.Layouts; SDLayout pickedLayout = null; Dictionary <SDLayout, HashSet <SDEndorser> > layoutEndorsers = new Dictionary <SDLayout, HashSet <SDEndorser> >(); // if (layouts.size() > 1) { // pick layout by least number of endorsers .. least number of peers hit and smaller block! foreach (SDLayout sdLayout in layouts) { HashSet <LGroup> remainingGroups = new HashSet <LGroup>(); foreach (SDGroup sdGroup in sdLayout.Groups) { remainingGroups.Add(new LGroup(sdGroup)); } // These are required as there is no choice. HashSet <SDEndorser> required = new HashSet <SDEndorser>(); foreach (LGroup lgroup in remainingGroups) { if (lgroup.StillRequired == lgroup.Endorsers.Count) { required.AddRange(lgroup.Endorsers); } } //add those that there are no choice. if (required.Count > 0) { List <LGroup> remove = new List <LGroup>(); foreach (LGroup lGroup in remainingGroups) { if (!lGroup.Endorsed(required)) { remove.Add(lGroup); } } remove.ForEach(a => remainingGroups.Remove(a)); if (!layoutEndorsers.ContainsKey(sdLayout)) { layoutEndorsers[sdLayout] = new HashSet <SDEndorser>(); } layoutEndorsers[sdLayout].AddRange(required); } if (remainingGroups.Count == 0) { // no more groups here done for this layout. continue; // done with this layout there really were no choices. } //Now go through groups finding which endorsers can satisfy the most groups. do { Dictionary <SDEndorser, int> matchCount = new Dictionary <SDEndorser, int>(); foreach (LGroup group in remainingGroups) { foreach (SDEndorser sdEndorser in group.Endorsers) { if (matchCount.ContainsKey(sdEndorser)) { matchCount[sdEndorser] = matchCount[sdEndorser] + 1; } else { matchCount[sdEndorser] = 1; } } } List <SDEndorser> theMost = new List <SDEndorser>(); int maxMatch = 0; foreach (SDEndorser sdEndorser in matchCount.Keys) { int count = matchCount[sdEndorser]; if (count > maxMatch) { theMost.Clear(); theMost.Add(sdEndorser); maxMatch = count; } else if (count == maxMatch) { theMost.Add(sdEndorser); } } HashSet <SDEndorser> theVeryMost = new HashSet <SDEndorser>(); long max = 0L; // Tie breaker: Pick one with greatest ledger height. foreach (SDEndorser sd in theMost) { if (sd.LedgerHeight > max) { max = sd.LedgerHeight; theVeryMost.Clear(); theVeryMost.Add(sd); } } List <LGroup> remove2 = new List <LGroup>(remainingGroups.Count); foreach (LGroup lGroup in remainingGroups) { if (!lGroup.Endorsed(theVeryMost)) { remove2.Add(lGroup); } } if (!layoutEndorsers.ContainsKey(sdLayout)) { layoutEndorsers[sdLayout] = new HashSet <SDEndorser>(); } layoutEndorsers[sdLayout].AddRange(theVeryMost); remove2.ForEach(a => remainingGroups.Remove(a)); } while (remainingGroups.Count > 0); // Now pick the layout with least endorsers } //Pick layout which needs least endorsements. int min = int.MaxValue; HashSet <SDLayout> theLeast = new HashSet <SDLayout>(); foreach (SDLayout sdLayoutK in layoutEndorsers.Keys) { int count = layoutEndorsers[sdLayoutK].Count; if (count < min) { theLeast.Clear(); theLeast.Add(sdLayoutK); min = count; } else if (count == min) { theLeast.Add(sdLayoutK); } } if (theLeast.Count == 1) { pickedLayout = theLeast.First(); } else { long max = 0L; // Tie breaker: Pick one with greatest ledger height. foreach (SDLayout sdLayout in theLeast) { long height = 0; foreach (SDEndorser sdEndorser in layoutEndorsers[sdLayout]) { height += sdEndorser.LedgerHeight; } if (height > max) { max = height; pickedLayout = sdLayout; } } } SDEndorserState sdEndorserState = new SDEndorserState(); sdEndorserState.SDEndorsers = pickedLayout != null ? layoutEndorsers[pickedLayout].ToList() : new List <SDEndorser>(); sdEndorserState.PickedLayout = pickedLayout; return(sdEndorserState); }