Beispiel #1
0
        /**
         * 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);
        }
Beispiel #2
0
        /**
         * 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);
        }