source: trunk/CrypPlugins/KeySearcher/P2P/DistributedBruteForceManager.cs @ 1727

Last change on this file since 1727 was 1727, checked in by Paul Lelgemann, 12 years ago

+ P2PEditor can display the status of jobs, if available; Participating displays overlay while loading workspace data
+ KeySearcher can upload status for P2PEditor display

File size: 8.2 KB
Line 
1using System;
2using System.Diagnostics;
3using System.Numerics;
4using System.Windows.Threading;
5using Cryptool.P2P;
6using Cryptool.PluginBase;
7using KeySearcher.Helper;
8using KeySearcher.KeyPattern;
9using KeySearcher.P2P.Exceptions;
10using KeySearcher.P2P.Helper;
11using KeySearcher.P2P.Presentation;
12using KeySearcher.P2P.Storage;
13using KeySearcher.P2P.Tree;
14using KeySearcherPresentation.Controls;
15
16namespace KeySearcher.P2P
17{
18    internal class DistributedBruteForceManager
19    {
20        private readonly StorageKeyGenerator keyGenerator;
21        private readonly KeySearcher keySearcher;
22        private readonly KeySearcherSettings settings;
23        private readonly KeyQualityHelper keyQualityHelper;
24        private readonly P2PQuickWatchPresentation quickWatch;
25        private readonly KeyPatternPool patternPool;
26        private readonly StatusContainer status;
27        internal readonly StatisticsGenerator StatisticsGenerator;
28        internal readonly Stopwatch StopWatch;
29
30        private KeyPoolTree keyPoolTree;
31
32        public DistributedBruteForceManager(KeySearcher keySearcher, KeyPattern.KeyPattern keyPattern, KeySearcherSettings settings,
33                                            KeyQualityHelper keyQualityHelper, P2PQuickWatchPresentation quickWatch)
34        {
35            this.keySearcher = keySearcher;
36            this.settings = settings;
37            this.keyQualityHelper = keyQualityHelper;
38            this.quickWatch = quickWatch;
39
40            // TODO when setting is still default (21), it is only displayed as 21 - but the settings-instance contains 0 for that key!
41            if (settings.ChunkSize == 0)
42            {
43                settings.ChunkSize = 21;
44            }
45
46            StopWatch = new Stopwatch();
47            status = new StatusContainer();
48            status.IsCurrentProgressIndeterminate = true;
49
50            keyGenerator = new StorageKeyGenerator(keySearcher, settings);
51            patternPool = new KeyPatternPool(keyPattern, new BigInteger(Math.Pow(2, settings.ChunkSize)));
52            StatisticsGenerator = new StatisticsGenerator(status, quickWatch, keySearcher, settings, this);
53            quickWatch.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(UpdateStatusContainerInQuickWatch));
54        }
55
56        public void Execute()
57        {
58            status.CurrentOperation = "Initializing connection to the peer-to-peer system";
59            new ConnectionHelper(keySearcher, settings).ValidateConnectionToPeerToPeerSystem();
60
61            if (!P2PManager.IsConnected)
62            {
63                keySearcher.GuiLogMessage("Unable to use peer-to-peer system.", NotificationLevel.Error);
64                status.CurrentOperation = "Unable to use peer-to-peer system";
65                return;
66            }
67
68            status.CurrentOperation = "Initializing distributed key pool tree";
69            keyPoolTree = new KeyPoolTree(patternPool, this.keySearcher, keyQualityHelper, keyGenerator, status, StatisticsGenerator);
70
71            keySearcher.GuiLogMessage(
72                "Total amount of patterns: " + patternPool.Length + ", each containing " + patternPool.PartSize +
73                " keys.", NotificationLevel.Info);
74            status.CurrentOperation = "Ready for calculation";
75
76            status.StartDate = keyPoolTree.StartDate();
77
78            Leaf currentLeaf;
79            while (!keySearcher.stop)
80            {
81                status.IsCurrentProgressIndeterminate = true;
82
83                BigInteger displayablePatternId;
84                try
85                {
86                    status.CurrentOperation = "Finding next leaf to calculate";
87                    currentLeaf = keyPoolTree.FindNextLeaf();
88                    if (currentLeaf == null)
89                    {
90                        break;
91                    }
92                    displayablePatternId = currentLeaf.PatternId() + 1;
93                }
94                catch (AlreadyCalculatedException)
95                {
96                    keySearcher.GuiLogMessage("Node was already calculated.", NotificationLevel.Info);
97                    keyPoolTree.Reset();
98                    continue;
99                }
100
101                if (!currentLeaf.ReserveLeaf())
102                {
103                    keySearcher.GuiLogMessage(
104                        "Pattern #" + displayablePatternId +
105                        " was reserved before it could be reserved for this CrypTool instance.",
106                        NotificationLevel.Info);
107                    keyPoolTree.Reset();
108                    continue;
109                }
110
111                keySearcher.GuiLogMessage(
112                    "Running pattern #" + displayablePatternId + " of " + patternPool.Length,
113                    NotificationLevel.Info);
114                status.CurrentChunk = displayablePatternId;
115                status.CurrentOperation = "Calculating pattern " + status.CurrentChunk;
116
117                try
118                {
119                    status.IsCurrentProgressIndeterminate = false;
120                    StopWatch.Start();
121                    var result = keySearcher.BruteForceWithLocalSystem(patternPool[currentLeaf.PatternId()], true);
122                    StopWatch.Stop();
123                    status.IsCurrentProgressIndeterminate = true;
124
125                    if (!keySearcher.stop)
126                    {
127                        status.CurrentOperation = "Processing results of calculation";
128                        KeyPoolTree.ProcessCurrentPatternCalculationResult(currentLeaf, result);
129                        StatisticsGenerator.ProcessPatternResults(result);
130
131                        status.CurrentOperation = "Calculating global statistics";
132                        StatisticsGenerator.CalculateGlobalStatistics(displayablePatternId);
133
134                        status.LocalFinishedChunks++;
135                        keySearcher.GuiLogMessage(
136                            string.Format("Best match: {0} with {1}", result.First.Value.key, result.First.Value.value),
137                            NotificationLevel.Info);
138
139                        status.CurrentOperation = "Updating status in DHT";
140                        keyPoolTree.UpdateStatus(currentLeaf);
141                    }
142                    else
143                    {
144                        keySearcher.GuiLogMessage("Brute force was stopped, not saving results...",
145                                                  NotificationLevel.Info);
146                        status.ProgressOfCurrentChunk = 0;
147                    }
148                }
149                catch (ReservationRemovedException)
150                {
151                    keySearcher.GuiLogMessage("Reservation removed by another node (while calculating). " +
152                                              "To avoid a state in limbo, proceeding to first available leaf...",
153                                              NotificationLevel.Info);
154                    keyPoolTree.Reset();
155                    continue;
156                }
157                catch (UpdateFailedException e)
158                {
159                    keySearcher.GuiLogMessage("Could not store results: " + e.Message, NotificationLevel.Info);
160                    keyPoolTree.Reset();
161                    continue;
162                }
163            }
164
165            // Set progress to 100%
166            if (!keySearcher.stop && keyPoolTree.IsCalculationFinished())
167            {
168                keySearcher.showProgress(keySearcher.costList, 1, 1, 1);
169                keySearcher.GuiLogMessage("Calculation complete.", NotificationLevel.Info);
170                keyPoolTree.UpdateStatusForFinishedCalculation();
171               
172            }
173
174            StatisticsGenerator.CalculationStopped();
175            status.ProgressOfCurrentChunk = 0;
176            status.IsSearchingForReservedNodes = false;
177            status.IsCurrentProgressIndeterminate = false;
178            status.CurrentOperation = "Idle";
179            status.RemainingTimeTotal = new TimeSpan(0);
180        }
181
182        private void UpdateStatusContainerInQuickWatch()
183        {
184            quickWatch.DataContext = status;
185            quickWatch.UpdateSettings(keySearcher, settings);
186        }
187    }
188}
Note: See TracBrowser for help on using the repository browser.