block.py
1 #!/bin/python3 2 3 import random 4 from bitarray import bitarray 5 from bitarray.util import zeros 6 7 class Block: 8 """This class represents a block in the Ethereum blockchain.""" 9 10 def __init__(self, blockSizeR, blockSizeRK=0, blockSizeC=0, blockSizeCK=0): 11 """Initialize the block with a data array of blocksize^2 zeros. 12 13 BlockSizeR: row size 14 BlockSizeRK: original row size, before erasure coding to BlocksSizeR 15 BlockSizeC: column size (i.e. number of rows) 16 BlockSizeCK: original column size, before erasure coding to BlocksSizeR 17 """ 18 self.blockSizeR = blockSizeR 19 self.blockSizeRK = blockSizeRK if blockSizeRK else blockSizeR/2 20 self.blockSizeC = blockSizeC if blockSizeC else blockSizeR 21 self.blockSizeCK = blockSizeCK if blockSizeCK else blockSizeRK 22 self.data = zeros(self.blockSizeR*self.blockSizeC) 23 24 def fill(self): 25 """It fills the block data with ones.""" 26 self.data.setall(1) 27 28 def merge(self, merged): 29 """It merges (OR) the existing block with the received one.""" 30 self.data |= merged.data 31 32 def getSegment(self, rowID, columnID): 33 """Check whether a segment is included""" 34 return self.data[rowID*self.blockSizeR + columnID] 35 36 def setSegment(self, rowID, columnID, value = 1): 37 """Set value for a segment (default 1)""" 38 self.data[rowID*self.blockSizeR + columnID] = value 39 40 def getColumn(self, columnID): 41 """It returns the block column corresponding to columnID.""" 42 return self.data[columnID::self.blockSizeR] 43 44 def mergeColumn(self, columnID, column): 45 """It merges (OR) the existing column with the received one.""" 46 self.data[columnID::self.blockSizeR] |= column 47 48 def repairColumn(self, id): 49 """It repairs the entire column if it has at least blockSizeCK ones. 50 Returns: list of repaired segments 51 """ 52 line = self.data[id::self.blockSizeR] 53 success = line.count(1) 54 if success >= self.blockSizeCK: 55 ret = ~line 56 self.data[id::self.blockSizeR] = 1 57 else: 58 ret = zeros(self.blockSizeC) 59 return ret 60 61 def getRow(self, rowID): 62 """It returns the block row corresponding to rowID.""" 63 return self.data[rowID*self.blockSizeR:(rowID+1)*self.blockSizeR] 64 65 def mergeRow(self, rowID, row): 66 """It merges (OR) the existing row with the received one.""" 67 self.data[rowID*self.blockSizeR:(rowID+1)*self.blockSizeR] |= row 68 69 def repairRow(self, id): 70 """It repairs the entire row if it has at least blockSizeRK ones. 71 Returns: list of repaired segments. 72 """ 73 line = self.data[id*self.blockSizeR:(id+1)*self.blockSizeR] 74 success = line.count(1) 75 if success >= self.blockSizeRK: 76 ret = ~line 77 self.data[id*self.blockSizeR:(id+1)*self.blockSizeR] = 1 78 else: 79 ret = zeros(self.blockSizeR) 80 return ret 81 82 def print(self): 83 """It prints the block in the terminal (outside of the logger rules)).""" 84 dash = "-" * (self.blockSizeR+2) 85 print(dash) 86 for i in range(self.blockSizeC): 87 line = "|" 88 for j in range(self.blockSizeR): 89 line += "%i" % self.data[(i*self.blockSizeR)+j] 90 print(line+"|") 91 print(dash) 92