From 1e4aefe2612575e89fe42c167e6884ea0ca537f2 Mon Sep 17 00:00:00 2001 From: Sudipta Basak Date: Thu, 30 May 2024 14:49:40 +0000 Subject: [PATCH] things are good before the plotting part --- DAS/node.py | 8 +++----- DAS/results.py | 1 - DAS/shape.py | 14 +++----------- DAS/simulator.py | 19 ++++++++++++++++--- smallConf.py | 24 ++++++++++++------------ 5 files changed, 34 insertions(+), 32 deletions(-) diff --git a/DAS/node.py b/DAS/node.py index 85aaf8a..1787af3 100644 --- a/DAS/node.py +++ b/DAS/node.py @@ -48,7 +48,7 @@ class Node: """It returns the node ID.""" return str(self.ID) - def __init__(self, ID, amIproposer, amImalicious, logger, shape, config, + def __init__(self, ID, amIproposer, nodeClass, amImalicious, logger, shape, config, validators, rows = set(), columns = set()): """It initializes the node, and eventual validators, following the simulation configuration in shape and config. @@ -82,7 +82,7 @@ class Node: self.rowIDs = range(shape.nbRows) self.columnIDs = range(shape.nbCols) else: - self.nodeClass = 1 if (self.ID <= shape.numberNodes * shape.class1ratio) else 2 + self.nodeClass = nodeClass self.vpn = len(validators) #TODO: needed by old code, change to fn self.rowIDs = set(rows) @@ -120,10 +120,8 @@ class Node: # 1 Mbps ~= 1e6 mbps * 0.050 s / (560*8) bits ~= 11 segments/timestep if self.amIproposer: self.bwUplink = shape.bwUplinkProd - elif self.nodeClass == 1: - self.bwUplink = shape.bwUplink1 else: - self.bwUplink = shape.bwUplink2 + self.bwUplink = shape.nodeTypes[self.nodeClass]['bwUplinks'] self.bwUplink *= 1e3 / 8 * config.stepDuration / config.segmentSize self.repairOnTheFly = config.evalConf(self, config.repairOnTheFly, shape) diff --git a/DAS/results.py b/DAS/results.py index f679702..2dc8db4 100644 --- a/DAS/results.py +++ b/DAS/results.py @@ -24,7 +24,6 @@ class Result: self.restoreColumnCount = [0] * shape.numberNodes self.repairedSampleCount = [0] * shape.numberNodes self.numberNodes = shape.numberNodes - self.class1ratio = shape.class1ratio def copyValidators(self, validators): """Copy information from simulator.validators to result.""" diff --git a/DAS/shape.py b/DAS/shape.py index ab17c4a..bb8ede2 100644 --- a/DAS/shape.py +++ b/DAS/shape.py @@ -3,7 +3,7 @@ class Shape: """This class represents a set of parameters for a specific simulation.""" def __init__(self, nbCols, nbColsK, nbRows, nbRowsK, - numberNodes, failureModel, failureRate, maliciousNodes, class1ratio, custodyRows, custodyCols, vpn1, vpn2, netDegree, bwUplinkProd, bwUplink1, bwUplink2, run): + numberNodes, failureModel, failureRate, maliciousNodes, custodyRows, custodyCols, netDegree, bwUplinkProd, run, nodeTypes): """Initializes the shape with the parameters passed in argument.""" self.run = run self.numberNodes = numberNodes @@ -15,14 +15,10 @@ class Shape: self.failureRate = failureRate self.maliciousNodes = maliciousNodes self.netDegree = netDegree - self.class1ratio = class1ratio self.custodyRows = custodyRows self.custodyCols = custodyCols - self.vpn1 = vpn1 - self.vpn2 = vpn2 self.bwUplinkProd = bwUplinkProd - self.bwUplink1 = bwUplink1 - self.bwUplink2 = bwUplink2 + self.nodeTypes = nodeTypes self.randomSeed = "" def __repr__(self): @@ -35,17 +31,13 @@ class Shape: shastr += "-nn-"+str(self.numberNodes) shastr += "-fm-"+str(self.failureModel) shastr += "-fr-"+str(self.failureRate) - shastr += "-c1r-"+str(self.class1ratio) shastr += "-cusr-"+str(self.custodyRows) shastr += "-cusc-"+str(self.custodyCols) - shastr += "-vpn1-"+str(self.vpn1) - shastr += "-vpn2-"+str(self.vpn2) shastr += "-bwupprod-"+str(self.bwUplinkProd) - shastr += "-bwup1-"+str(self.bwUplink1) - shastr += "-bwup2-"+str(self.bwUplink2) shastr += "-nd-"+str(self.netDegree) shastr += "-r-"+str(self.run) shastr += "-mn-"+str(self.maliciousNodes) + shastr += "-ntypes-"+str(self.nodeTypes['group']) return shastr def setSeed(self, seed): diff --git a/DAS/simulator.py b/DAS/simulator.py index 3657b03..a62ddfc 100644 --- a/DAS/simulator.py +++ b/DAS/simulator.py @@ -44,6 +44,19 @@ class Simulator: self.proposerPublishToR = config.evalConf(self, config.proposerPublishToR, shape) self.proposerPublishToC = config.evalConf(self, config.proposerPublishToR, shape) + def getNodeClass(self, nodeIdx): + nodeRatios = [] + for _k, _v in self.shape.nodeTypes.items(): + if _k != "group": nodeRatios.append(_v['ratio']) + nodeCounts = [int(self.shape.numberNodes * ratio / sum(nodeRatios)) for ratio in nodeRatios] + commulativeSum = [nodeCounts[0]] + for count in nodeCounts[1: ]: + commulativeSum.append(commulativeSum[-1] + count) + commulativeSum[-1] = self.shape.numberNodes + for i, idx in enumerate(commulativeSum): + if nodeIdx < idx: + return i + 1 + def initValidators(self): """It initializes all the validators in the network.""" self.glob = Observer(self.logger, self.shape) @@ -125,11 +138,11 @@ class Simulator: self.logger.error("custodyRows has to be smaller than %d" % self.shape.nbRows) vs = [] - nodeClass = 1 if (i <= self.shape.numberNodes * self.shape.class1ratio) else 2 - vpn = self.shape.vpn1 if (nodeClass == 1) else self.shape.vpn2 + nodeClass = self.getNodeClass(i) + vpn = self.shape.nodeTypes[nodeClass]['validatorsPerNode'] for v in range(vpn): vs.append(initValidator(self.shape.nbRows, self.shape.custodyRows, self.shape.nbCols, self.shape.custodyCols)) - val = Node(i, int(not i!=0), amImalicious_value, self.logger, self.shape, self.config, vs) + val = Node(i, int(not i!=0), nodeClass, amImalicious_value, self.logger, self.shape, self.config, vs) if i == self.proposerID: val.initBlock() else: diff --git a/smallConf.py b/smallConf.py index 18a9c17..87334dd 100644 --- a/smallConf.py +++ b/smallConf.py @@ -77,17 +77,17 @@ validatorBasedCustody = False custodyRows = range(2, 3, 2) custodyCols = range(2, 3, 2) -# ratio of class1 nodes (see below for parameters per class) -class1ratios = [0.8] - -# Number of validators per beacon node -validatorsPerNode1 = [1] -validatorsPerNode2 = [5] - # Set uplink bandwidth in megabits/second bwUplinksProd = [200] -bwUplinks1 = [10] -bwUplinks2 = [200] + +nodeTypesGroup = [ + { + "group": "g1", + # nodeClass: node config + 1: {'validatorsPerNode': 1, 'bwUplinks': 10, 'ratio': 8}, + 2: {'validatorsPerNode': 5, 'bwUplinks': 200, 'ratio': 2} + } +] # Step duration in miliseconds (Classic RTT is about 100ms) stepDuration = 50 @@ -135,11 +135,11 @@ colsK = range(32, 65, 128) rowsK = range(32, 65, 128) def nextShape(): - for nbCols, nbColsK, nbRows, nbRowsK, run, fm, fr, mn, class1ratio, chR, chC, vpn1, vpn2, nn, netDegree, bwUplinkProd, bwUplink1, bwUplink2 in itertools.product( - cols, colsK, rows, rowsK, runs, failureModels, failureRates, maliciousNodes, class1ratios, custodyRows, custodyCols, validatorsPerNode1, validatorsPerNode2, numberNodes, netDegrees, bwUplinksProd, bwUplinks1, bwUplinks2): + for nbCols, nbColsK, nbRows, nbRowsK, run, fm, fr, mn, chR, chC, nn, netDegree, bwUplinkProd, nodeTypes in itertools.product( + cols, colsK, rows, rowsK, runs, failureModels, failureRates, maliciousNodes, custodyRows, custodyCols, numberNodes, netDegrees, bwUplinksProd, nodeTypesGroup): # Network Degree has to be an even number if netDegree % 2 == 0: - shape = Shape(nbCols, nbColsK, nbRows, nbRowsK, nn, fm, fr, mn, class1ratio, chR, chC, vpn1, vpn2, netDegree, bwUplinkProd, bwUplink1, bwUplink2, run) + shape = Shape(nbCols, nbColsK, nbRows, nbRowsK, nn, fm, fr, mn, chR, chC, netDegree, bwUplinkProd, run, nodeTypes) yield shape def evalConf(self, param, shape = None):