diff --git a/DAS/requirements.txt b/DAS/requirements.txt index 76b14c7..43f8b1c 100644 --- a/DAS/requirements.txt +++ b/DAS/requirements.txt @@ -4,5 +4,5 @@ matplotlib==3.6.2 mplfinance==0.12.9b7 networkx==3.0 numpy==1.23.5 -seaborn==0.12.2 +seaborn==0.13.0 joblib==1.2.0 diff --git a/DAS/simulator.py b/DAS/simulator.py index 4f8fe98..a4b5cf1 100644 --- a/DAS/simulator.py +++ b/DAS/simulator.py @@ -274,6 +274,7 @@ class Simulator: stepCustodyCountsRow, stepCustodyCountsCol = [], [] # Count of custody in each step malicious_nodes_not_added_count = 0 steps = 0 + while(True): missingVector.append(missingSamples) self.logger.debug("Expected Samples: %d" % expected, extra=self.format) @@ -375,6 +376,7 @@ class Simulator: self.result.addMetric("rowCustody", stepCustodyCountsRow) self.result.addMetric("colCustody", stepCustodyCountsCol) + for i in range(0,self.shape.numberNodes): if not self.validators[i].amIaddedToQueue : malicious_nodes_not_added_count += 1 diff --git a/DAS/visualizer.py b/DAS/visualizer.py index 34da38c..00459d1 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -182,6 +182,7 @@ class Visualizer: """Average the runs if needed""" if(len(self.config.runs) > 1): data = self.averageRuns(data, len(self.config.runs)) + else: return filteredKeys = self.similarKeys(data) vmin, vmax = 0, self.maxTTA+1000 print("Plotting heatmaps...") diff --git a/DAS/visualizor.py b/DAS/visualizor.py index 4d56260..008afa3 100644 --- a/DAS/visualizor.py +++ b/DAS/visualizor.py @@ -122,7 +122,7 @@ class Visualizor: for result in self.results: plotPath = "results/"+self.execID+"/plots/"+str(result.shape) os.makedirs(plotPath, exist_ok=True) - self.plotMissingSamples(result, plotPath) + self.plotMissingSegments(result, plotPath) self.plotProgress(result, plotPath) self.plotSentData(result, plotPath) self.plotRecvData(result, plotPath) @@ -264,8 +264,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Box Plot of Restore Row Count by Nodes" conf["xlabel"] = "Node Type" conf["ylabel"] = "Restore Row Count" @@ -290,8 +291,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Box Plot of Restore Column Count by Nodes" conf["xlabel"] = "Node Type" conf["ylabel"] = "Restore Column Count" @@ -316,8 +318,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Boxen Plot of Restore Row Count by Nodes" conf["xlabel"] = "Restore Row Count" conf["ylabel"] = "Nodes" @@ -340,8 +343,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Boxen Plot of Restore Column Count by Nodes" conf["xlabel"] = "Restore Column Count" conf["ylabel"] = "Nodes" @@ -364,8 +368,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "ECDF of Restore Row Count by Nodes" conf["xlabel"] = "Restore Row Count" conf["ylabel"] = "ECDF" @@ -392,8 +397,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "ECDF of Restore Column Count by Nodes" conf["xlabel"] = "Restore Column Count" conf["ylabel"] = "ECDF" @@ -420,8 +426,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "ECDF of Messages Sent by Nodes" conf["xlabel"] = "Number of Messages Sent" conf["ylabel"] = "ECDF" @@ -447,8 +454,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "ECDF of Messages Received by Nodes" conf["xlabel"] = "Number of Messages Received" conf["ylabel"] = "ECDF" @@ -474,8 +482,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "ECDF of Samples Received by Nodes" conf["xlabel"] = "Number of Samples Received" conf["ylabel"] = "ECDF" @@ -501,8 +510,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "ECDF of Row-Col Distribution by Nodes" conf["xlabel"] = "Row-Col Distribution" conf["ylabel"] = "ECDF" @@ -528,8 +538,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "ECDF of Samples Repaired by Nodes" conf["xlabel"] = "Number of Samples Repaired" conf["ylabel"] = "ECDF" @@ -555,8 +566,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Samples Received by Nodes" conf["xlabel"] = "Node Type" conf["ylabel"] = "Number of Samples Received" @@ -581,8 +593,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Samples Repaired by Nodes" conf["xlabel"] = "Node Type" conf["ylabel"] = "Number of Samples Repaired" @@ -607,8 +620,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Row/Column Distribution" conf["xlabel"] = "Row/Column Type" conf["ylabel"] = "Validators Subscribed" @@ -638,8 +652,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Messages Sent by Nodes" conf["xlabel"] = "Node Type" conf["ylabel"] = "Number of Messages Sent" @@ -662,8 +677,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Messages Received by Nodes" conf["xlabel"] = "Node Type" conf["ylabel"] = "Number of Messages Received" @@ -686,8 +702,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Samples Repaired by Nodes" conf["type"] = "individual_bar" conf["legLoc"] = 1 @@ -707,8 +724,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Row/Column Distribution" conf["xlabel"] = "" conf["ylabel"] = "Validators Subscribed" @@ -730,8 +748,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Restore Row Count for Each Node" conf["type"] = "individual_bar" conf["legLoc"] = 1 @@ -752,8 +771,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Restore Column Count for Each Node" conf["type"] = "individual_bar" conf["legLoc"] = 1 @@ -774,8 +794,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Percentage of Samples Received by Nodes" conf["type"] = "individual_bar_with_2line" conf["legLoc"] = 1 @@ -809,8 +830,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Samples Received by Nodes" conf["type"] = "individual_bar_with_2line" conf["legLoc"] = 1 @@ -824,25 +846,27 @@ class Visualizor: plotBoxData(conf) print("Plot %s created." % conf["path"]) - def plotMissingSamples(self, result, plotPath): - """Plots the missing samples in the network""" + def plotMissingSegments(self, result, plotPath): + """Plots the missing segments in the network""" conf = {} attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] - conf["title"] = "Missing Samples" + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize)+"\nMissing Segment: "+str(round(min(result.missingVector) * 100 / max(result.missingVector), 3))+"%"\ + +"\nMissing Segments: "+str(result.missingVector[-1]) + conf["title"] = "Missing Segments" conf["type"] = "plot_with_1line" conf["legLoc"] = 1 conf["desLoc"] = 1 conf["colors"] = ["m-"] - conf["labels"] = ["Missing Samples"] + conf["labels"] = ["Missing Segments"] conf["xlabel"] = "Time (ms)" - conf["ylabel"] = "Number of Missing Samples" + conf["ylabel"] = "Number of Missing Segments" conf["data"] = [result.missingVector] conf["xdots"] = [x*self.config.stepDuration for x in range(len(result.missingVector))] - conf["path"] = plotPath+"/missingSamples.png" + conf["path"] = plotPath+"/missingSegments.png" maxi = 0 for v in conf["data"]: if max(v) > maxi: @@ -850,7 +874,7 @@ class Visualizor: conf["yaxismax"] = maxi x = result.shape.nbCols * result.shape.custodyRows + result.shape.nbRows * result.shape.custodyCols conf["expected_value"] = (result.shape.numberNodes - 1) * (result.shape.class1ratio * result.shape.vpn1 * x + (1 - result.shape.class1ratio) * result.shape.vpn2 * x) - conf["line_label"] = "Total samples to deliver" + conf["line_label"] = "Total segments to deliver" plotData(conf) print("Plot %s created." % conf["path"]) @@ -863,8 +887,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Nodes/validators ready" conf["type"] = "plot" conf["legLoc"] = 2 @@ -876,11 +901,7 @@ class Visualizor: conf["data"] = [vector1, vector2, vector3] conf["xdots"] = [x*self.config.stepDuration for x in range(len(vector1))] conf["path"] = plotPath+"/nodesReady.png" - maxi = 0 - for v in conf["data"]: - if max(v) > maxi: - maxi = max(v) - conf["yaxismax"] = maxi + conf["yaxismax"] = 1 plotData(conf) print("Plot %s created." % conf["path"]) @@ -897,8 +918,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Sent data" conf["type"] = "plot" conf["legLoc"] = 2 @@ -929,8 +951,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Received data" conf["type"] = "plot" conf["legLoc"] = 2 @@ -961,8 +984,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Duplicated data" conf["type"] = "plot" conf["legLoc"] = 2 @@ -994,8 +1018,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Row/Column distribution" conf["type"] = "grouped_bar" conf["legLoc"] = 2 @@ -1021,8 +1046,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Messages Sent by Nodes" conf["type"] = "individual_bar" conf["legLoc"] = 1 @@ -1043,8 +1069,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Messages Sent by Nodes" conf["xlabel"] = "Node Type" conf["ylabel"] = "Number of Messages Sent" @@ -1060,8 +1087,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Messages Received by Nodes" conf["type"] = "individual_bar" conf["legLoc"] = 1 @@ -1082,8 +1110,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Messages Received by Nodes" conf["type"] = "individual_bar" conf["legLoc"] = 1 @@ -1105,8 +1134,9 @@ class Visualizor: attrbs = self.__get_attrbs__(result) conf["textBox"] = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ - +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"\nMalicious Node: "+attrbs['mn']+"\nNetwork degree: "+attrbs['nd']\ - +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"+"\nNetwork degree: "+attrbs['nd']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']+"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2']\ + +"\nSegment Size: "+str(self.config.segmentSize) conf["title"] = "Number of Samples Repaired by Nodes" conf["type"] = "individual_bar" conf["legLoc"] = 1 @@ -1120,3 +1150,225 @@ class Visualizor: conf["yaxismax"] = maxi plotData(conf) print("Plot %s created." % conf["path"]) + + def plotHeatMapData(self, conf): + data = {'x': conf['x'], 'y': conf['y'], 'weights': conf['weights']} + df = pd.DataFrame(data) + pivot_df = df.pivot_table(index='y', columns='x', values='weights', aggfunc="sum") + + # Create subplots + fig, (ax_heatmap, ax_textbox) = plt.subplots(1, 2, figsize=(18, 6)) + + # Plot heatmap + sns.heatmap(pivot_df, annot=True, cmap='viridis', fmt='.0f', ax=ax_heatmap) + ax_heatmap.set_xlabel(conf['xlabel']) + ax_heatmap.set_ylabel(conf['ylabel']) + ax_heatmap.set_title(conf['title']) + + # Plot textbox + props = dict(boxstyle='round', facecolor='wheat', alpha=0.5) + ax_textbox.text(0.5, 0.5, conf["textBox"], fontsize=14, verticalalignment='center', transform=ax_textbox.transAxes, bbox=props) + ax_textbox.axis('off') # Turn off axis for the textbox subplot + + folder = f"results/{self.execID}/heatmaps/{conf['folder']}" + os.makedirs(folder, exist_ok=True) + plt.savefig(f"{folder}/{conf['path']}") + plt.clf() + plt.close() + + # Number of simulation runs with the same parameters for statistical relevance + def totalRuns(self): + rs = [] + for result in self.results: + attrbs = self.__get_attrbs__(result) + rs.append(int(attrbs['r'])) + + return max(rs) - min(rs) + 1 + + # x -> network degree, y -> number of nodes, weights -> simulation duration + def plotNWDegVsNodeOnRuntime(self): + xyS = dict() + for result in self.results: + attrbs = self.__get_attrbs__(result) + textBox = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ + +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ + +"\nFailure rate: "+attrbs['fr']+"%"+"\nMalicious Node: "+attrbs['mn']+"%"\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']\ + +"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + filename = "bsrn_" + attrbs['bsrn'] +\ + "_bsrk_" + attrbs['bsrk'] +\ + "_bscn_" + attrbs['bscn' ] +\ + "_bsck_" + attrbs['bsck'] +\ + "_fr_" + attrbs['fr'] +\ + "_mn_" + attrbs['mn'] +\ + "_cusr_" + attrbs['cusr'] +\ + "_cusc_" + attrbs['cusc'] +\ + "_vpn1_" + attrbs['vpn1'] +\ + "_vpn2_" + attrbs['vpn2'] + identifier = ( + attrbs['bsrn'], attrbs['bsrk'], attrbs['bscn'], + attrbs['bsck'], attrbs['fr'], attrbs['mn'], + attrbs['cusr'], attrbs['cusc'], attrbs['vpn1'], + attrbs['vpn2'] + ) + if identifier in xyS.keys(): + xyS[identifier]['x'].append(result.shape.netDegree) + xyS[identifier]['y'].append(result.shape.numberNodes) + xyS[identifier]['w'].append(self.config.stepDuration * (len(result.missingVector) - 1)) + else: + xyS[identifier] = { + 'x': [result.shape.netDegree], + 'y': [result.shape.numberNodes], + 'w': [self.config.stepDuration * (len(result.missingVector) - 1)], + 'textBox': textBox, + 'filename': filename + } + + runs = self.totalRuns() + for v in xyS.values(): + x = v['x'] + y = v['y'] + weights = [(w / runs) for w in v['w']] + + if len(set(x)) * len(set(y)) < 2: return # Not enough unique params for heatmap + + conf = { + 'x': x, + 'y': y, + 'weights': weights, + 'xlabel': 'Net Degree', + 'ylabel': 'Number of Nodes', + 'title': 'Net Degree vs. Number of Nodes on Simulation Runtime (ms)', + 'folder': 'NWDegVsNodeOnRuntime', + 'textBox': v['textBox'], + 'path': f"{v['filename']}.png" + } + + self.plotHeatMapData(conf) + + # x -> network degree, y -> % of malicious nodes, weights -> no of missing samples + def plotNWDegVsMalNodeOnMissingSamples(self): + xyS = dict() + for result in self.results: + attrbs = self.__get_attrbs__(result) + textBox = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ + +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ + +"\nFailure rate: "+attrbs['fr']+"%"+"\nNodes: "+attrbs['nn']\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']\ + +"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + filename = "bsrn_" + attrbs['bsrn'] +\ + "_bsrk_" + attrbs['bsrk'] +\ + "_bscn_" + attrbs['bscn' ] +\ + "_bsck_" + attrbs['bsck'] +\ + "-nn-" + attrbs['nn'] +\ + "_fr_" + attrbs['fr'] +\ + "_cusr_" + attrbs['cusr'] +\ + "_cusc_" + attrbs['cusc'] +\ + "_vpn1_" + attrbs['vpn1'] +\ + "_vpn2_" + attrbs['vpn2'] + identifier = ( + attrbs['bsrn'], attrbs['bsrk'], attrbs['bscn'], + attrbs['bsck'], attrbs['fr'], attrbs['nn'], + attrbs['cusr'], attrbs['cusc'], attrbs['vpn1'], + attrbs['vpn2'] + ) + if identifier in xyS.keys(): + xyS[identifier]['x'].append(result.shape.netDegree) + xyS[identifier]['y'].append(result.shape.maliciousNodes) + xyS[identifier]['w'].append(result.missingVector[-1]) + else: + xyS[identifier] = { + 'x': [result.shape.netDegree], + 'y': [result.shape.maliciousNodes], + 'w': [result.missingVector[-1]], + 'textBox': textBox, + 'filename': filename + } + + runs = self.totalRuns() + for v in xyS.values(): + x = v['x'] + y = v['y'] + weights = [(w / runs) for w in v['w']] + + if len(set(x)) * len(set(y)) < 2: return # Not enough unique params for heatmap + + conf = { + 'x': x, + 'y': y, + 'weights': weights, + 'xlabel': 'Net Degree', + 'ylabel': 'Malicious Nodes (%)', + 'title': 'Net Degree vs Malicious Nodes (%) on Missing Samples', + 'folder': 'NWDegVsMalNodeOnMissingSamples', + 'textBox': v['textBox'], + 'path': f"{v['filename']}.png" + } + + self.plotHeatMapData(conf) + + # x -> network degree, y -> failure rate, weights -> no of missing samples + def plotNWDegVsFailureRateOnMissingSamples(self): + xyS = dict() + for result in self.results: + attrbs = self.__get_attrbs__(result) + textBox = "Row Size (N, K): "+attrbs['bsrn']+ ", "+attrbs['bsrk']\ + +"\nColumn Size: (N, K): "+attrbs['bscn']+ ", "+attrbs['bsck']\ + +"\nNodes: "+attrbs['nn']+"\nMalicious Node: "+attrbs['mn']+"%"\ + +"\nCustody Rows: "+attrbs['cusr']+"\nCustody Cols: "+attrbs['cusc']\ + +"\nCustody 1: "+attrbs['vpn1']+"\nCustody 2: "+attrbs['vpn2'] + filename = "bsrn_" + attrbs['bsrn'] +\ + "_bsrk_" + attrbs['bsrk'] +\ + "_bscn_" + attrbs['bscn' ] +\ + "_bsck_" + attrbs['bsck'] +\ + "-nn-" + attrbs['nn'] +\ + "_mn_" + attrbs['mn'] +\ + "_cusr_" + attrbs['cusr'] +\ + "_cusc_" + attrbs['cusc'] +\ + "_vpn1_" + attrbs['vpn1'] +\ + "_vpn2_" + attrbs['vpn2'] + identifier = ( + attrbs['bsrn'], attrbs['bsrk'], attrbs['bscn'], + attrbs['bsck'], attrbs['mn'], attrbs['nn'], + attrbs['cusr'], attrbs['cusc'], attrbs['vpn1'], + attrbs['vpn2'] + ) + if identifier in xyS.keys(): + xyS[identifier]['x'].append(result.shape.netDegree) + xyS[identifier]['y'].append(result.shape.failureRate) + xyS[identifier]['w'].append(result.missingVector[-1]) + else: + xyS[identifier] = { + 'x': [result.shape.netDegree], + 'y': [result.shape.failureRate], + 'w': [result.missingVector[-1]], + 'textBox': textBox, + 'filename': filename + } + + runs = self.totalRuns() + for v in xyS.values(): + x = v['x'] + y = v['y'] + weights = [(w / runs) for w in v['w']] + + if len(set(x)) * len(set(y)) < 2: return # Not enough unique params for heatmap + + conf = { + 'x': x, + 'y': y, + 'weights': weights, + 'xlabel': 'Net Degree', + 'ylabel': 'Failure Rate (%)', + 'title': 'Net Degree vs Failure Rate (%) on Missing Samples', + 'folder': 'NWDegVsFailureRateOnMissingSamples', + 'textBox': v['textBox'], + 'path': f"{v['filename']}.png" + } + + self.plotHeatMapData(conf) + + def plotAllHeatMaps(self): + self.plotNWDegVsNodeOnRuntime() + self.plotNWDegVsMalNodeOnMissingSamples() + self.plotNWDegVsFailureRateOnMissingSamples() \ No newline at end of file diff --git a/study.py b/study.py index 380cf30..a824e66 100644 --- a/study.py +++ b/study.py @@ -5,6 +5,9 @@ import importlib import subprocess from joblib import Parallel, delayed from DAS import * +import os +import pickle +import uuid # Parallel execution: # The code currently uses 'joblib' to execute on multiple cores. For other options such as 'ray', see @@ -29,6 +32,13 @@ def runOnce(config, shape, execID): shape.setSeed(config.randomSeed+"-"+str(shape)) random.seed(shape.randomSeed) + backup_folder = f"results/{execID}/backup" + if not os.path.exists(backup_folder): + os.makedirs(backup_folder) + backup_file = os.path.join(backup_folder, f"simulation_data_{shape}.pkl") + with open(backup_file, 'ab') as f: + pickle.dump(shape.__dict__, f) + sim = Simulator(shape, config, execID) sim.initLogger() sim.initValidators() @@ -43,9 +53,124 @@ def runOnce(config, shape, execID): visual = Visualizor(execID, config, [result]) visual.plotAll() + with open(backup_file, 'ab') as f: + pickle.dump("completed", f) + return result + +def check_simulation_completion(state_file): + backup_dir = os.path.join(os.path.dirname(state_file), "backup") + if not os.path.exists(backup_dir): + return False + + all_completed = True + incomplete_files = [] + completed_files = [] + completed_shapes = [] + for filename in sorted(os.listdir(backup_dir), reverse=True): + if not filename.endswith(".pkl"): + continue + full_path = os.path.join(backup_dir, filename) + try: + with open(full_path, 'rb') as f: + items = [] + while True: + try: + item = pickle.load(f) + items.append(item) + except EOFError: + break + last_item = items[-1] + if last_item != "completed": + all_completed = False + incomplete_files.append(full_path) + else: + completed_files.append(full_path) + completed_shapes.append(items[0]) + except (OSError, pickle.UnpicklingError) as e: + print(f"Error loading state from {full_path}: {e}") + all_completed = False + break + return all_completed, incomplete_files, completed_files, completed_shapes + + +def start_simulation(execID, completed_files, completed_shapes, incomplete_files): + config = importlib.import_module("smallConf") + logger = initLogger(config) + format = {"entity": "Study"} + + results = [] + if not os.path.exists("results"): + os.makedirs("results") + dir = "results/"+execID + if not os.path.exists(dir): + os.makedirs(dir) + if config.saveGit: + with open(dir+"/git.diff", 'w') as f: + subprocess.run(["git", "diff"], stdout=f) + with open(dir+"/git.describe", 'w') as f: + subprocess.run(["git", "describe", "--always"], stdout=f) + + logger.info("Starting simulations:", extra=format) + start = time.time() + for shape in config.nextShape(): + comparison_dict = shape.__dict__.copy() + ignore_keys = ['randomSeed'] + for key in ignore_keys: + del comparison_dict[key] + + if any(all(comparison_dict[key] == completed_shape[key] for key in comparison_dict.keys() if key not in ignore_keys) for completed_shape in completed_shapes): + logger.info("Skipping simulation for shape (already completed): %s" % (str(shape.__dict__)), extra=format) + else: + results.append(delayed(runOnce)(config, shape, execID)) + + results = Parallel(config.numJobs)(results) + end = time.time() + logger.info("A total of %d simulations ran in %d seconds" % (len(results), end-start), extra=format) + + if config.visualization: + vis = Visualizer(execID, config) + vis.plotHeatmaps() + + visual = Visualizor(execID, config, results) + visual.plotHeatmaps("nn", "fr") + + def study(): + restart_path = None + for arg in sys.argv[1:]: + if arg.startswith("--restart="): + restart_path = arg[len("--restart="):] + + if restart_path: + execID = restart_path.split("/")[1] + state_file = f"results/{execID}/backup" + all_completed, incomplete_files, completed_files, completed_shapes = check_simulation_completion(state_file) + + current_shapes = [] + config = importlib.import_module("smallConf") + + completed_shapes_without_seed = completed_shapes + for shape in config.nextShape(): + shape_dict = copy.deepcopy(shape.__dict__) + del shape_dict['randomSeed'] + current_shapes.append(shape_dict) + for shape in completed_shapes_without_seed: + if 'randomSeed' in shape: + del shape['randomSeed'] + + completed_set = {frozenset(shape.items()) for shape in completed_shapes_without_seed} + current_set = {frozenset(shape.items()) for shape in current_shapes} + + if all_completed and completed_set == current_set: + print("Simulation is already completed.") + sys.exit(0) + else: + print("Restarting simulations.") + start_simulation(execID, completed_files, completed_shapes, incomplete_files) + sys.exit(0) + if len(sys.argv) < 2: print("You need to pass a configuration file in parameter") exit(1) @@ -93,6 +218,7 @@ def study(): visual = Visualizor(execID, config, results) visual.plotHeatmaps("nn", "fr") + visual.plotAllHeatMaps() if __name__ == "__main__": study()