Beispiel #1
0
    def RPC_PM_find_work(self):
        pm_id = -1
        tmpblock = None

        nodes = self.RPC_nodes()
        for i in range(len(nodes)):
            work, tmpblock = nodes[i].PM_get_work(self.id)
            if (work != None and tmpblock != None and putil.valid_block(
                    tmpblock, self.blockchain, self.cur_coins_from_issuer)):
                pm_id = i
                break
            else:
                pm_id = -1

        return pm_id, work, tmpblock
Beispiel #2
0
 def PM_send_share(self, id, block):
     self.lock.acquire()
     if (self.PM_verify_block(block)):
         self.pm_miner_share[id] += 1
     #lock
     if (putil.valid_block(block, self.blockchain,
                           self.cur_coins_from_issuer)):
         self.blockchain.append(block)
         putil.update_metadata(block, self.blockchain,
                               self.cur_coins_from_issuer,
                               self.cur_coins_from_voter)
         self.lock.release()
         self.RPC_add_block(block)
         #new thread call stop, update state
         for id in self.pm_miner_share.keys():
             t1 = threading.Thread(self.nodes[id].PM_stop, (self.id))
             t1.start()
         #pay money
         return
     else:
         self.lock.release()
         return
Beispiel #3
0
    def PM_verify_block(self, tmpblock):
        # if(tmpblock.prev_block_hash!=self.blockchain[len(self.blockchain)-1].block.to_hash()):
        #         return False

        # coins_from_issuer=self.coins_from_issuer.copy()
        # coins_from_voter=self.coins_from_voter.copy()

        # #check transactions
        # for transaction in tmpblock.transactions:
        #     if(not self.verify_transaction(transaction, coins_from_issuer, coins_from_voter)):
        #         return False
        # #check block.roothash
        # tmp_MerkleTree = MerkleTree(tmpblock.transactions)
        # if(tmp_MerkleTree.get_hash!=tmpblock.block.root_hash):
        #     return False

        if (not putil.valid_block(tmpblock, self.blockchain,
                                  self.cur_coins_from_issuer)):
            return False

        if (not self.PM_check_hash(tmpblock.block.to_hash())):
            return False

        return True
Beispiel #4
0
    def headers_first_DL(self, group, len_bc):

        nodes = []
        for i in range(len(self.node_addresses)):
            if i == self.id:
                continue
            rpc_obj = xmlrpc.client.ServerProxy(self.node_addresses[i],
                                                allow_none=True)
            nodes.append(rpc_obj)

        self.blockheaders = []

        flag = 0
        for id in group:
            try:
                blockheaders = nodes[id].get_block_headers()
                blockheaders = pickle.loads(blockheaders.data)
            except:
                group.remove(id)
                continue
            if (self.verfity_blockheaders(blockheaders)):
                flag = 1
            else:
                group.remove(id)

        if (flag == 0):
            return False

        self.blockchain = [None for i in range(len_bc)]
        # print(self.blockchain)
        coins_from_issuer = {}
        coins_from_voter = {}
        len_gp = len(group)

        #cur = 1

        t = [None for i in range(len_gp)]
        # print("gp:",group)
        for i in range(0, len_bc, len_gp):
            for j in range(len_gp):
                if (i + j >= len_bc):
                    break

                # print(i+j," : ", nodes[group[j]])
                t[j] = threading.Thread(target=self.RPC_get_block,
                                        args=(i + j, nodes[group[j]]))
                t[j].start()

            for j in range(len_gp):
                t[j].join()

            end = min(i + len_gp, len_bc)
            #check pointers
            for k in range(i, end):
                if (k == 0):
                    if not isinstance(self.blockchain[0].block, GenesisBlock):
                        group.remove(group[k - i])
                        return False
                if (k != 0 and self.blockchain[k].prev_block_hash !=
                        self.blockchain[k - 1].block.to_hash()):
                    group.remove(group[k - i])
                    return False

            for k in range(i, end):
                logic_block = self.blockchain[k]
                #check blocks
                if not putil.valid_block(logic_block, self.blockchain[:k],
                                         coins_from_issuer):
                    group.remove(k - i)
                    return False
                else:
                    if (k != 0):
                        putil.update_metadata(logic_block, self.blockchain[:k],
                                              coins_from_issuer,
                                              coins_from_voter)
                #check block.roothash
                # tmp_MerkleTree = MerkleTree(logic_block.transactions)
                # if tmp_MerkleTree.get_hash() != logic_block.block.root_hash:
                #     group.remove(k-i)
                #     return False

        # self.coins_from_issuer = coins_from_issuer
        # self.coins_from_voter = coins_from_voter

        self.cur_coins_from_issuer = coins_from_issuer
        self.cur_coins_from_voter = coins_from_voter
        self.pending_transactions = []

        return True
Beispiel #5
0
    def add_block(self, newblock, id):
        #lock here
        self.lock.acquire()
        if id != self.id:
            newblock = pickle.loads(newblock.data)
        if not putil.valid_block(newblock, self.blockchain,
                                 self.cur_coins_from_issuer):
            if id == self.id:
                self.lock.release()
                return False

            # get their blockchain
            # if theirs is longer then verify and set to ours
            # else i don't care if theyre behind
            # self.nodes_lock.acquire()
            try:
                rpc_obj = xmlrpc.client.ServerProxy(self.node_addresses[id],
                                                    allow_none=True)
                other_bc = pickle.loads(rpc_obj.get_blockchain().data)
            except:
                # The other guy didn't respond so ignore
                return False
            # self.nodes_lock.release()
            if len(other_bc) > len(
                    self.blockchain) and other_bc[0].block.to_hash(
                    ) == self.blockchain[0].block.to_hash():
                coins_from_issuer, coins_from_voter = putil.valid_blockchain(
                    other_bc)
                if coins_from_issuer is None:
                    self.lock.release()
                    return False
                else:
                    self.cur_coins_from_issuer = coins_from_issuer
                    self.cur_coins_from_voter = coins_from_voter
                    self.blockchain = other_bc
                    self.lock.release()
                    return True
            # t1 = threading.Thread(target=self.nodes[id].update_blockchain,args=(self.blockchain))
            # t1.start()
            self.lock.release()
            return False
        else:
            # print("The block is valid")
            # update pending transactions
            # else:
            # we called add_block on ourselves
            # probabl;y do nothing else
            # readd mining_transactions to pending maybe
            # if id == self.id:
            #     print('Valid block received from ourselves')
            # else:
            #     print('Valid block recieved from someone else')
            if self.is_mining and id is not self.id:
                self.recieved_new_block = True
                # self.mining_thread.terminate()
                if len(self.mining_transactions) > 0:
                    self.pending_transactions = self.mining_transactions[
                        1:] + self.pending_transactions
                    self.mining_transactions = []

            #     # if receive block from someone else
            #     self.mining_thread.stop()
            #     temp store pending and mining transactions
            #     set those to []

            #     for transaction in self.mining_transactions:
            #         self.add_transaction(transaction) if valid
            #     for transaciton in pending:
            #         self.add_transactin(transation) if valid
            self.blockchain.append(newblock)
            # update the metadata
            putil.update_metadata(newblock, self.blockchain,
                                  self.cur_coins_from_issuer,
                                  self.cur_coins_from_voter)
            self.lock.release()
            return True