Exemplo n.º 1
0
    def mine(self, cons):
        """ Create and send block in PUB socket based on consensus """
        name = threading.current_thread().getName()

        while True and not self.k.is_set():
            # move e flag inside generate?
            self.start.wait()
            self.f.wait()

            lastblock = self.bchain.getLastBlock()
            node = hashlib.sha256(self.ipaddr).hexdigest()
            self.stake = self.balance

            # find new block
            b = self.generateNewblock(lastblock, node, self.stake, cons)

            if b and not self.e.is_set():
                logging.info("Mined block %s" % b.hash)
                sqldb.writeBlock(b)
                sqldb.writeChain(b)
                self.bchain.addBlocktoBlockchain(b)
                self.psocket.send_multipart(
                    [consensus.MSG_BLOCK, self.ipaddr,
                     pickle.dumps(b, 2)])
                time.sleep(parameter.timeout)
            else:
                if (self.synced == True):
                    self.e.clear()
Exemplo n.º 2
0
 def recursiveValidate(self, blockerror, address=None):
     index = blockerror.index - 1
     pblock = sqldb.dbtoBlock(sqldb.blockQuery(['',
                                                index]))  # previous block
     trials = 3
     while index and trials:
         logging.debug('validating index %s' % index)
         chainnew = self.reqBlocks(index + 1, index + 1, address)
         new = chainnew[0]
         new = sqldb.dbtoBlock(new)
         print('NEW ID ON RECURSIVE', new.index)
         print('NEW ON RECURSIVE', new.hash)
         #print("NEW", new.index)
         if new and validations.validateBlockHeader(new):
             sqldb.writeBlock(new)
             if validations.validateBlock(
                     new, pblock) and validations.validateChallenge(
                         new, self.stake):
                 logging.debug('returning')
                 #print('FORK', new.index)
                 return new
             else:
                 index -= 1
                 pblock = sqldb.dbtoBlock(sqldb.blockQuery(['', index]))
                 #print("PBLOCK", pblock.index)
         else:
             trials -= 1
     return new
Exemplo n.º 3
0
def validateChain(bc, l):
    lastBlock = bc.getLastBlock()
    print lastBlock.blockInfo()
    for b in l:
        b = sqldb.dbtoBlock(b)
        if not validateBlockHeader(b):  # invalid
            return b, True
        if validateBlock(b, lastBlock):
            lastBlock = b
            bc.addBlocktoBlockchain(b)
            sqldb.writeBlock(b)
            sqldb.writeChain(b)
        else:  # fork
            return b, False
    return None, False
Exemplo n.º 4
0
 def mine(self, cons):
     # target = 2 ** (20) - 1
     name = threading.current_thread().getName()
     while True and not self.k.is_set():
         # move e flag inside generate?
         self.start.wait()
         self.f.wait()
         lastblock = self.bchain.getLastBlock()
         b = cons.generateNewblock(lastblock, self.e)
         if b and not self.e.is_set():
             logging.info("Mined block %s" % b.hash)
             sqldb.writeBlock(b)
             self.bchain.addBlocktoBlockchain(b)
             self.psocket.send_multipart([consensus.MSG_BLOCK, self.ipaddr, pickle.dumps(b, 2)])
         else:
             self.e.clear()
Exemplo n.º 5
0
def validateChain(bc, l):
    lastBlock = bc.getLastBlock()
    #print lastBlock.blockInfo()
    for b in l:
        #print b
        b = sqldb.dbtoBlock(b)  # maybe avoid converting
        # validade block header ?
        #validateBlockHeader(b)
        if validateBlock(b, lastBlock):
            lastBlock = b
            bc.addBlocktoBlockchain(b)
            sqldb.writeBlock(b)
        else:  # fork
            #sqldb.writeFork(b)
            return b
    return None
Exemplo n.º 6
0
 def listen(self):
     """ Listen to block messages in a SUB socket
         Message frames: [ 'block', ip, block data ]
     """
     self.bind(self.psocket)
     while True and not self.k.is_set():
         try:
             msg, ip, block_recv = self.subsocket.recv_multipart()
             self.f.clear()
             # serialize
             b = pickle.loads(block_recv)
             logging.info("Got block %s miner %s" % (b.hash, ip))
             # Verify block
             if consensus.validateBlockHeader(b):
                 logging.debug('valid block header')
                 lb = self.bchain.getLastBlock()
                 if (b.index - lb.index == 1) and consensus.validateBlock(
                         b, lb):
                     self.e.set()
                     sqldb.writeBlock(b)
                     sqldb.writeChain(b)
                     self.bchain.addBlocktoBlockchain(b)
                     # rebroadcast
                     #logging.debug('rebroadcast')
                     self.psocket.send_multipart(
                         [consensus.MSG_BLOCK, ip,
                          pickle.dumps(b, 2)])
                 elif b.index - lb.index > 1:
                     self.synced = False
                     self.sync(b, ip)
                 elif b.index == lb.index:
                     if b.hash == lb.hash:
                         logging.debug('retransmission')
                     else:
                         logging.debug('fork')
                         # double entry
                         sqldb.writeBlock(b)
                 else:
                     # ignore old block
                     logging.debug('old')
             #
             self.f.set()
         except (zmq.ContextTerminated):
             break
Exemplo n.º 7
0
 def recursiveValidate(self, blockerror):
     index = blockerror.index - 1
     pblock = sqldb.dbtoBlock(sqldb.blockQuery(['',
                                                index]))  # previous block
     tries = 3
     while index and tries:
         logging.debug('validating index %s' % index)
         new = self.reqBlock(index)
         if new and consensus.validateBlockHeader(new):
             sqldb.writeBlock(new)
             if consensus.validateBlock(new, pblock):
                 logging.debug('returning')
                 return new
             else:
                 index -= 1
                 pblock = sqldb.dbtoBlock(sqldb.blockQuery(['', index]))
         else:
             tries -= 1
     return new
Exemplo n.º 8
0
 def listen(self):
     self.bind(self.psocket)
     while True and not self.k.is_set():
         try:
             msg, ip, block_recv = self.subsocket.recv_multipart()
             self.f.clear()
             b = pickle.loads(block_recv)
             logging.info("Got block %s miner %s" % (b.hash, ip))
             # Verify block
             if consensus.validateBlockHeader(b):
                 logging.debug('valid block')
                 lb = self.bchain.getLastBlock()
                 if (b.index - lb.index == 1) and consensus.validateBlock(
                         b, lb):
                     self.e.set()
                     sqldb.writeBlock(b)
                     self.bchain.addBlocktoBlockchain(b)
                     # rebroadcast
                     #logging.debug('rebroadcast')
                     self.psocket.send_multipart(
                         [consensus.MSG_BLOCK, ip,
                          pickle.dumps(b, 2)])
                 elif b.index - lb.index > 1:
                     self.synced = False
                     self.sync(b, ip)
                 elif b.index == lb.index:
                     if b.hash == lb.hash:
                         logging.debug('retransmission')
                         pass
                     else:
                         #fork
                         logging.debug('strong fork')
                         pass
                 else:
                     #fork
                     logging.debug('weak fork')
                     pass
             #
             self.f.set()
         except (zmq.ContextTerminated):
             break
Exemplo n.º 9
0
def validateChain(bc, chain, stake):
    lastBlock = bc.getLastBlock()
    for b in chain:
        b = sqldb.dbtoBlock(b)
        if not validateBlockHeader(b):  # invalid
            #print("HEADER NOT OK")
            return b, True
        #print("lastblock index",lastBlock.index)
        #print("current block index", b.index)
        if validateBlock(b, lastBlock):
            #print("BLOCK OK")
            if validateChallenge(b, stake) and validateRound(
                    b, bc) and validateExpectedRound(b, lastBlock):
                print("BLOCO VALIDO SINCRONIZADO")
                lastBlock = b
                bc.addBlocktoBlockchain(b)
                sqldb.writeBlock(b)
                sqldb.writeChain(b)
        else:  # fork
            return b, False
    return None, False
Exemplo n.º 10
0
 def sync(self, rBlock=None, address=None):
     # TODO change variables names and test again
     self.synced = True
     logging.debug('syncing...')
     # limit number of peers?
     if not rBlock:
         rBlock = self.bchain.getLastBlock()
         for i in range(0, min(len(self.peers), 3)):
             i += 1
             logging.debug('request #%d' % i)
             b, ip = self.reqLastBlock()
             if b:
                 logging.debug('Block index %s' % b.index)
             if (b and (b.index > rBlock.index)):
                 rBlock = b
                 address = ip
                 logging.debug('Best index %s with ip %s' % (b.index, ip))
     last = self.bchain.getLastBlock()
     #
     if (rBlock.index > last.index):
         self.e.set()
         if (rBlock.index - last.index == 1) and consensus.validateBlock(
                 rBlock, last):
             logging.debug('valid block')
             sqldb.writeBlock(rBlock)
             self.bchain.addBlocktoBlockchain(rBlock)
         else:
             l = self.reqBlocks(address, last.index + 1, rBlock.index)
             if l:
                 # validate here
                 error = consensus.validateChain(self.bchain, l)
                 if error:
                     # maybe fork, request previous
                     logging.debug('fork')
                     # sync again?
                 #sqldb.writeBlock(l)
     logging.debug('synced')
Exemplo n.º 11
0
 def sync(self, rBlock=None, address=None):
     """ Syncronize with peers and validate chain
     rBlock -- can be passed as argument to sync based on that block index instead of requesting
     address -- try to force requests to use this ip address
     """
     self.synced = True
     logging.debug('syncing...')
     # Request before sync
     if not rBlock:
         rBlock = self.bchain.getLastBlock()
         # limit number of peers request
         for i in range(0, min(len(self.peers), 3)):
             i += 1
             logging.debug('request #%d' % i)
             b, ip = self.reqLastBlock()
             if b:
                 logging.debug('Block index %s' % b.index)
             if (b and (b.index > rBlock.index)):
                 rBlock = b
                 address = ip
                 logging.debug('Best index %s with ip %s' % (b.index, ip))
     last = self.bchain.getLastBlock()
     # Sync based on rBlock
     if (rBlock.index > last.index):
         self.e.set()
         if (rBlock.index - last.index == 1) and consensus.validateBlock(
                 rBlock, last):
             logging.debug('valid block')
             sqldb.writeBlock(rBlock)
             sqldb.writeChain(rBlock)
             self.bchain.addBlocktoBlockchain(rBlock)
         else:
             l = self.reqBlocks(last.index + 1, rBlock.index, address)
             if l:
                 # validate and write
                 b_error, h_error = consensus.validateChain(self.bchain, l)
                 if b_error:
                     if not h_error and b_error.index == last.index + 1:
                         logging.debug('fork')
                         sqldb.writeBlock(b_error)
                         # trying to solve and pick a fork
                         n = self.recursiveValidate(b_error)
                         if n:
                             self.bchain.chain.clear(
                             )  # TODO change this and refactor
                             for i in xrange(n.index, last.index + 1):
                                 logging.debug('updating chain')
                                 if i == 1:
                                     sqldb.replaceChain(n)
                                     self.bchain.addBlocktoBlockchain(n)
                                 else:
                                     n = sqldb.forkUpdate(i)
                                     sqldb.replaceChain(n)
                                     self.bchain.addBlocktoBlockchain(
                                         sqldb.dbtoBlock(n))
                             consensus.validateChain(self.bchain, l)
                     else:
                         logging.debug('invalid')  # request again
                         new = self.reqBlock(b_error.index)
                         self.sync(new)
     logging.debug('synced')
Exemplo n.º 12
0
    def rpcServer(self, ip='127.0.0.1', port=9999):
        """ RPC-like server to interact with rpcclient.py """
        self.bind(self.rpcsocket, ip, port)
        time.sleep(1)
        while True:
            try:
                messages = self.rpcsocket.recv_multipart()
            except zmq.ContextTerminated:
                break
            time.sleep(1)
            cmd = messages[0].lower()
            if cmd == rpc.MSG_LASTBLOCK:
                b = self.bchain.getLastBlock()
                self.rpcsocket.send(b.blockInfo())
            elif cmd == rpc.MSG_BLOCKCHAIN:
                b = self.bchain.Info()
                self.rpcsocket.send(b)
            elif cmd == rpc.MSG_BLOCK:
                b = sqldb.dbtoBlock(sqldb.blockQuery(messages))
                self.rpcsocket.send(b.blockInfo() if b else 'error')
            elif cmd == rpc.MSG_BLOCKS:
                l = sqldb.blocksListQuery(messages)
                blocks = []
                for b in l:
                    blocks.append(sqldb.dbtoBlock(b).blockInfo())
                self.rpcsocket.send_pyobj(blocks)
            elif cmd == rpc.MSG_ADD:
                m = self.addPeer(messages[1])
                self.rpcsocket.send_string(m)
            elif cmd == rpc.MSG_REMOVE:
                m = self.removePeer(messages[1])
                self.rpcsocket.send_string(m)
            elif cmd == rpc.MSG_PEERS:
                self.rpcsocket.send_pyobj(self.getPeers())
            elif cmd == rpc.MSG_START:
                self.rpcsocket.send_string('Starting mining...')
                self.start.set()
                self.f.set()
            elif cmd == rpc.MSG_STOP:
                self.start.clear()
                self.f.clear()
                self.e.set()
                self.rpcsocket.send_string('Stopping mining...')
            elif cmd == rpc.MSG_EXIT:
                self.rpcsocket.send_string('Exiting...')
                raise StopException
            elif cmd == rpc.MSG_BALANCE:
                self.addBalance(int(messages[1]))
                self.rpcsocket.send_string('Node Balance is ' +
                                           str(self.balance))
            elif cmd == rpc.MSG_ADDBLOCK:
                l = []
                for i in messages[1:]:
                    l.append(i)
                last_hash = sqldb.dbtoBlock(
                    sqldb.blockQuery(['', str(int(l[0]) - 1)])).hash
                hash_node = hashlib.sha256(self.ipaddr).hexdigest()
                time_create = int(
                    time.mktime(datetime.datetime.now().timetuple()))
                c_header = str(last_hash) + str(l[1]) + str(hash_node)
                hash = hashlib.sha256(c_header).hexdigest()
                b = block.Block(int(l[0]), last_hash, int(l[1]), hash_node,
                                time_create, hash)
                sqldb.writeBlock(b)
                #sqldb.writeChain(b)
                self.bchain.addBlocktoBlockchain(b)
                self.rpcsocket.send_string('Block created ' +
                                           str(b.blockInfo()))

                self.psocket.send_multipart(
                    [consensus.MSG_BLOCK, self.ipaddr,
                     pickle.dumps(b, 2)])
            else:
                self.rpcsocket.send_string('Command unknown')
                logging.warning('Command unknown')
Exemplo n.º 13
0
    def sync(self, rBlock=None, address=None):
        """ Syncronize with peers and validate chain
        rBlock -- can be passed as argument to sync based on that block index instead of requesting
        address -- try to force requests to use this ip address
        """
        logging.debug('syncing...')
        # Request before sync
        if not rBlock:
            rBlock = self.bchain.getLastBlock()
            # limit number of peers request
            for i in xrange(0, min(len(self.peers), 3)):
                i += 1
                logging.debug('request #%d' % i)
                b, ip = self.reqLastBlock()
                if b:
                    logging.debug('Block index %s' % b.index)
                if (b and (b.index > rBlock.index)):
                    rBlock = b
                    address = ip
                    logging.debug('Best index %s with ip %s' % (b.index, ip))
        last = self.bchain.getLastBlock()
        #print('INDEX BLOCK', last.index)
        #print('LAST BLOCK ON SYNC FUNCTION', last.hash)
        #print('rBLOCK', rBlock.index)
        # Sync based on rBlock
        if (rBlock.index > last.index):
            #print("RBLOCK", rBlock.index)
            if (rBlock.index - last.index == 1):

                if (validations.validateBlockHeader(rBlock)
                        and validations.validateChallenge(rBlock, self.stake)
                        and validations.validateExpectedRound(rBlock, last)):
                    if (validations.validateBlock(rBlock, last)):
                        #print('SYNC-BLOCO CADEIA ATUAL')
                        logging.debug('valid block')
                        sqldb.writeBlock(rBlock)
                        sqldb.writeChain(rBlock)
                        self.bchain.addBlocktoBlockchain(rBlock)
                    else:
                        #print('SYNC-BLOCO OUTRA CADEIA')
                        sqldb.writeBlock(rBlock)
                        # trying to solve and pick a fork
                        n = self.recursiveValidate(rBlock, address)
                        #print('B_ERROR', b_error.index)
                        #print("PONTO DO FORK:", n.index)
                        if n:
                            fork = n
                            #print('BLOCO EM FORK', fork.index)
                            #print('BLOCO EM FORK - HASH', fork.index)
                            #self.bchain.chain.clear() # TODO change this and refactor
                            #remove all blocks after fork point
                            for i in xrange(n.index, last.index + 1):
                                self.bchain.chain.popleft()

                            teste = self.bchain.getLastBlock()
                            #print('ULTIMO BLOCO DEPOIS DE REMOVER BLOCO DO FORK', teste.index)
                            #print('ULTIMO BLOCO DEPOIS DE REMOVER BLOCO DO FORK - HASH', teste.hash)

                            #insert new blocks starting on n block
                            for i in xrange(last.index + 1, n.index - 1, -1):
                                logging.debug('updating chain')
                                if i == 1:
                                    sqldb.replaceChain(n)
                                    self.bchain.addBlocktoBlockchain(n)
                                else:
                                    if (i == rBlock.index):
                                        #print('INSERIR rBLock', rBlock.index)
                                        sqldb.writeChain(rBlock)
                                    else:
                                        lastBlock = sqldb.dbtoBlock(
                                            sqldb.blockQuery(['', i + 1]))
                                        actualBlock = sqldb.dbtoBlock(
                                            sqldb.blockQuery(['', i]))
                                        #print('LAST BLOCK INDEX', lastBlock.index)
                                        #print('LAST BLOCK PREV_HASH', lastBlock.prev_hash)
                                        #print('ACTUAL BLOCK INDEX', actualBlock.index)
                                        #print('ACTUAL BLOCK CHAIN', actualBlock.hash)
                                        if (lastBlock.prev_hash !=
                                                actualBlock.hash):
                                            search = sqldb.blockQueryFork(
                                                ['', i])
                                            for j in search:
                                                value = sqldb.dbtoBlock(j)
                                                if (value.hash ==
                                                        lastBlock.prev_hash):
                                                    sqldb.replaceChain(j)
                            for i in xrange(n.index, last.index + 2):
                                block = sqldb.dbtoBlock(
                                    sqldb.blockQuery(['', i]))
                                self.bchain.addBlocktoBlockchain(block)

                                #n = sqldb.forkUpdate(i)
                                #if(i == rBlock.index-1):
                                #   fork = sqldb.dbtoBlock(sqldb.blockQuery(['',i]))
                                #   print('SUBSTITUINDO O FORK')
                                #   print('FORK HASH', fork.hash)
                                #   print('rBlock PREV HASH', rBlock.prev_hash)
                                #   if(fork.hash != rBlock.prev_hash):
                                #       print('SUBSTITUIR')
                                #       n = sqldb.blockQueryFork(['',i])
                                #       for j in n:
                                #           value = sqldb.dbtoBlock(j)
                                #           if (value.hash == rBlock.prev_hash):
                                #               sqldb.replaceChain(j)
                                #               self.bchain.addBlocktoBlockchain(sqldb.dbtoBlock(j))
                                #   else:
                                #       print('NAO SUBSTITUIR')
                                #       self.bchain.addBlocktoBlockchain(fork)
                                #else:
                                #    sqldb.replaceChain(n)
                                #   self.bchain.addBlocktoBlockchain(sqldb.dbtoBlock(n))

                    teste = self.bchain.getLastBlock()
                    #print('ULTIMO BLOCO DEPOIS DE INSERIR OS BLOCOS DA NOVA CADEIA', teste.index)
                    self.synced = True

            else:
                if (validations.validateBlockHeader(rBlock)
                        and validations.validateChallenge(rBlock, self.stake)):
                    print('BLOCO RECEBIDO > 1 ON SYNC FUNCTION')
                    chain = self.reqBlocks(last.index + 1, rBlock.index,
                                           address)
                    if chain:
                        # validate and write
                        b_error, h_error = validations.validateChain(
                            self.bchain, chain, self.stake)
                        # update last block
                        last = self.bchain.getLastBlock()
                        print('LAST BLOCK ON LOCAL CHAIN', last.index)
                        # if b_error is diffent to None
                        if b_error:
                            print('b_error', b_error.index)
                            # TODO review from next line, because it is strange
                            # if h_error is false and block index equal last block index plus one
                            if not h_error and b_error.index == last.index + 1:
                                print('FORK')
                                sqldb.writeBlock(b_error)
                                # trying to solve and pick a fork
                                n = self.recursiveValidate(b_error, address)
                                print('B_ERROR', b_error.index)
                                print("PONTO DO FORK:", n.index)
                                if n:
                                    #self.bchain.chain.clear() # TODO change this and refactor
                                    #remove all blocks after fork point
                                    teste = self.bchain.getLastBlock()
                                    print('BCHAIN BEFORE POPLEFT', teste.index)
                                    for i in xrange(n.index, last.index + 1):
                                        self.bchain.chain.popleft()

                                    teste = self.bchain.getLastBlock()
                                    print('BCHAIN AFTER POPLEFT', teste.index)
                                    #insert new blocks starting on n block
                                    for i in xrange(last.index + 1,
                                                    n.index - 1, -1):
                                        logging.debug('updating chain')
                                        if i == 1:
                                            sqldb.replaceChain(n)
                                            self.bchain.addBlocktoBlockchain(n)
                                        else:
                                            if (i == b_error.index):
                                                print('INSERIR b_error',
                                                      b_error.index)
                                                sqldb.writeChain(b_error)
                                            else:
                                                lastBlock = sqldb.dbtoBlock(
                                                    sqldb.blockQuery(
                                                        ['', i + 1]))
                                                actualBlock = sqldb.dbtoBlock(
                                                    sqldb.blockQuery(['', i]))
                                                if (lastBlock.prev_hash !=
                                                        actualBlock.hash):
                                                    search = sqldb.blockQueryFork(
                                                        ['', i])
                                                    for j in search:
                                                        value = sqldb.dbtoBlock(
                                                            j)
                                                        if (value.hash ==
                                                                lastBlock.
                                                                prev_hash):
                                                            sqldb.replaceChain(
                                                                j)
                                    for i in xrange(n.index, last.index + 2):
                                        block = sqldb.dbtoBlock(
                                            sqldb.blockQuery(['', i]))
                                        self.bchain.addBlocktoBlockchain(block)

                                    #for i in xrange(n.index,last.index+1):
                                    #      logging.debug('updating chain')
                                    #      if i == 1:
                                    #          sqldb.replaceChain(n)
                                    #          self.bchain.addBlocktoBlockchain(n)
                                    #      else:
                                    #          n = sqldb.forkUpdate(i)
                                    #          sqldb.replaceChain(n)
                                    #          self.bchain.addBlocktoBlockchain(sqldb.dbtoBlock(n))
                                    #validations.validateChain(self.bchain, chain, self.stake)
                                self.synced = True
                            else:
                                logging.debug('invalid')  # request again
                                chainnew = self.reqBlocks(
                                    b_error.index, b_error.index, address)
                                new = chainnew[0]
                                new = sqldb.dbtoBlock(new)
                                #print('NEW RETURN SYNC', new.index)
                                self.sync(new)
                        else:
                            self.synced = True
        else:
            self.synced = True
        logging.debug('synced')
Exemplo n.º 14
0
    def listen(self):
        """ Listen to block messages in a SUB socket
            Message frames: [ 'block', ip, block data ]
        """
        self.bind(self.psocket)
        while True and not self.k.is_set():
            try:
                msg, ip, block_recv = self.subsocket.recv_multipart()
                self.f.clear()
                newChain = False
                # serialize
                b = pickle.loads(block_recv)
                logging.info("Got block %s miner %s" % (b.hash, ip))
                b.arrive_time = int(
                    time.mktime(datetime.datetime.now().timetuple()))
                # Verify block
                if validations.validateBlockHeader(b):
                    logging.debug('valid block header')
                    lb = self.bchain.getLastBlock()

                    if (b.index - lb.index == 1):
                        print('BLOCK', b.index)
                        print('VALIDATEBLOCK',
                              validations.validateBlock(b, lb))
                        print('VALIDATEROUND',
                              validations.validateRound(b, self.bchain))
                        print('VALIDATECHALLENGE',
                              validations.validateChallenge(b, self.stake))
                        self.e.set()
                        if (validations.validateBlock(b, lb)):
                            if (validations.validateRound(b, self.bchain)
                                    and validations.validateChallenge(
                                        b, self.stake)
                                    and validations.validateExpectedRound(
                                        b, lb)):
                                #print('NOVO BLOCO RECEBIDO---ACEITO SEM PROBLEMAS')
                                self.bchain.addBlocktoBlockchain(b)
                                sqldb.writeBlock(b)
                                sqldb.writeChain(b)
                        else:
                            if (validations.validateRound(b, self.bchain)
                                    and validations.validateChallenge(
                                        b, self.stake)
                                    and validations.validateExpectedRound(
                                        b, lb)):
                                print('BLOCO RECEBIDO APOS O FORK-', b.index)
                                self.synced = False
                                self.sync(b, ip)

                    # rebroadcast
                        logging.debug('rebroadcast')
                        self.psocket.send_multipart(
                            [consensus.MSG_BLOCK, ip,
                             pickle.dumps(b, 2)])
                        #self.e.clear()

                    elif b.index - lb.index > 1:
                        print('BLOCO RECEBIDO INDEX MAIOR QUE 1', b.index)
                        self.e.set()
                        self.synced = False
                        self.sync(b, ip)
                        self.e.clear()

                    elif b.index == lb.index:
                        if b.hash == lb.hash:
                            logging.debug('retransmission')
                        else:
                            if (b.round == lb.round):
                                logging.debug('possible fork')
                                pre_block = sqldb.dbtoBlock(
                                    sqldb.blockQuery([
                                        '', lb.index - 1
                                    ]))  #get the block that b and lb point.

                                if (validations.validateBlock(b, pre_block)
                                        and validations.validateChallenge(
                                            b, self.stake)
                                        and validations.validateExpectedRound(
                                            b, pre_block)):
                                    # double entry
                                    sqldb.writeBlock(b)
                    else:
                        # ignore old block
                        logging.debug('old')
                else:
                    logging.debug('invalid block')
                #
                self.f.set()
            except (zmq.ContextTerminated):
                break