Merge pull request #45 from status-im/failureMode

Failure mode
This commit is contained in:
Csaba Kiraly 2023-05-02 15:07:02 +02:00 committed by GitHub
commit e8cf5a4730
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 8 deletions

View File

@ -3,11 +3,12 @@
class Shape:
"""This class represents a set of parameters for a specific simulation."""
def __init__(self, blockSize, numberNodes, failureRate, class1ratio, chi, vpn1, vpn2, netDegree, bwUplinkProd, bwUplink1, bwUplink2, run):
def __init__(self, blockSize, numberNodes, failureModel, failureRate, class1ratio, chi, vpn1, vpn2, netDegree, bwUplinkProd, bwUplink1, bwUplink2, run):
"""Initializes the shape with the parameters passed in argument."""
self.run = run
self.numberNodes = numberNodes
self.blockSize = blockSize
self.failureModel = failureModel
self.failureRate = failureRate
self.netDegree = netDegree
self.class1ratio = class1ratio
@ -24,6 +25,7 @@ class Shape:
shastr = ""
shastr += "bs-"+str(self.blockSize)
shastr += "-nn-"+str(self.numberNodes)
shastr += "-fm-"+str(self.failureModel)
shastr += "-fr-"+str(self.failureRate)
shastr += "-c1r-"+str(self.class1ratio)
shastr += "-chi-"+str(self.chi)

View File

@ -219,6 +219,11 @@ class Simulator:
def run(self):
"""It runs the main simulation until the block is available or it gets stucked."""
self.glob.checkRowsColumns(self.validators)
for i in range(0,self.shape.numberNodes):
if i == self.proposerID:
self.validators[i].initBlock()
else:
self.validators[i].logIDs()
arrived, expected, ready, validatedall, validated = self.glob.checkStatus(self.validators)
missingSamples = expected - arrived
missingVector = []

View File

@ -123,10 +123,55 @@ class Validator:
self.logger.warning("I am not a block proposer", extra=self.format)
else:
self.logger.debug("Creating block...", extra=self.format)
order = [i for i in range(self.shape.blockSize * self.shape.blockSize)]
order = random.sample(order, int((1 - self.shape.failureRate/100) * len(order)))
for i in order:
self.block.data[i] = 1
if self.shape.failureModel == "random":
order = [i for i in range(self.shape.blockSize * self.shape.blockSize)]
order = random.sample(order, int((1 - self.shape.failureRate/100) * len(order)))
for i in order:
self.block.data[i] = 1
elif self.shape.failureModel == "sequential":
order = [i for i in range(self.shape.blockSize * self.shape.blockSize)]
order = order[:int((1 - self.shape.failureRate/100) * len(order))]
for i in order:
self.block.data[i] = 1
elif self.shape.failureModel == "MEP": # Minimal size non-recoverable Erasure Pattern
for r in range(self.shape.blockSize):
for c in range(self.shape.blockSize):
k = self.shape.blockSize/2
if r > k or c > k:
self.block.setSegment(r,c)
elif self.shape.failureModel == "MEP+1": # MEP +1 segment to make it recoverable
for r in range(self.shape.blockSize):
for c in range(self.shape.blockSize):
k = self.shape.blockSize/2
if r > k or c > k:
self.block.setSegment(r,c)
self.block.setSegment(0, 0)
elif self.shape.failureModel == "DEP":
for r in range(self.shape.blockSize):
for c in range(self.shape.blockSize):
k = self.shape.blockSize/2
if (r+c) % self.shape.blockSize > k:
self.block.setSegment(r,c)
elif self.shape.failureModel == "DEP+1":
for r in range(self.shape.blockSize):
for c in range(self.shape.blockSize):
k = self.shape.blockSize/2
if (r+c) % self.shape.blockSize > k:
self.block.setSegment(r,c)
self.block.setSegment(0, 0)
elif self.shape.failureModel == "MREP": # Minimum size Recoverable Erasure Pattern
for r in range(self.shape.blockSize):
for c in range(self.shape.blockSize):
k = self.shape.blockSize/2
if r < k and c < k:
self.block.setSegment(r,c)
elif self.shape.failureModel == "MREP-1": # make MREP non-recoverable
for r in range(self.shape.blockSize):
for c in range(self.shape.blockSize):
k = self.shape.blockSize/2
if r < k and c < k:
self.block.setSegment(r,c)
self.block.setSegment(0, 0, 0)
nbFailures = self.block.data.count(0)
measuredFailureRate = nbFailures * 100 / (self.shape.blockSize * self.shape.blockSize)

View File

@ -50,6 +50,9 @@ runs = range(3)
# Number of validators
numberNodes = range(128, 513, 128)
# select failure model between: "random, sequential, MEP, MEP+1, DEP, DEP+1, MREP, MREP-1"
failureModels = ["random"]
# Percentage of block not released by producer
failureRates = range(40, 81, 20)
@ -99,9 +102,9 @@ diagnostics = False
saveGit = False
def nextShape():
for run, fr, class1ratio, chi, vpn1, vpn2, blockSize, nn, netDegree, bwUplinkProd, bwUplink1, bwUplink2 in itertools.product(
runs, failureRates, class1ratios, chis, validatorsPerNode1, validatorsPerNode2, blockSizes, numberNodes, netDegrees, bwUplinksProd, bwUplinks1, bwUplinks2):
for run, fm, fr, class1ratio, chi, vpn1, vpn2, blockSize, nn, netDegree, bwUplinkProd, bwUplink1, bwUplink2 in itertools.product(
runs, failureModels, failureRates, class1ratios, chis, validatorsPerNode1, validatorsPerNode2, blockSizes, numberNodes, netDegrees, bwUplinksProd, bwUplinks1, bwUplinks2):
# Network Degree has to be an even number
if netDegree % 2 == 0:
shape = Shape(blockSize, nn, fr, class1ratio, chi, vpn1, vpn2, netDegree, bwUplinkProd, bwUplink1, bwUplink2, run)
shape = Shape(blockSize, nn, fm, fr, class1ratio, chi, vpn1, vpn2, netDegree, bwUplinkProd, bwUplink1, bwUplink2, run)
yield shape