/ DAS / block.py
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