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
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
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
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
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