def minner(self): member_index = 0 while True: # blockchain多个线程共享使用,需要加锁 if self.view == 0 and self.is_primary: time.sleep(30) # 用 run + simulation 运行时根据节点数量设置相应大的等待时间 print("-------START--------") self.sendrequest(0) # first = False if not (not self.startflag or self.receivealltx < len(self.committee_member) or int(time.time()) <= self.maxTime): print("-------collected enough tx: the start of commit-------") # with self.lock: print('current:', len(self.blockchain.current_transactions)) self.receivealltx_last = self.receivealltx self.txinblock = len(self.blockchain.current_transactions) # print "txinblock", self.txinblock new_block = self.blockchain.do_mine(self.view) self.blockcache = new_block self.sendblockhash(new_block.current_hash) self.startflag = False if self.replyflag and self.is_primary and (int(time.time()) > self.replytime + 30): print("++++++++++BFT FAILED++++++++++") self.sendrequest(-1) if self.failhash and self.receiveblock: self.receiveblock = False print("------send correct------") node = self.committee_member[member_index] msg_obj = packet.Message( "sendcorrect", { "hash": self.failhash[0], "address": (self.client.ip, self.client.port) }) msg_bytes = pickle.dumps(msg_obj) self.client.sendcorrect(self.server.socket, (node.ip, node.port), msg_bytes) member_index += 1 if self.replysend['view'] == self.view and int( time.time()) > self.replysend['time'] + 100: for node in self.committee_member: msg_obj = packet.Message("sendoff", self.view) msg_bytes = pickle.dumps(msg_obj) self.client.sendoff(self.server.socket, (node.ip, node.port), msg_bytes) time.sleep(.1)
def asklsp(self,address=[]):#address代表广播的源地址 #print "enter asklsp" if not address:#如果是广播发起节点 payload=packet.askinf(self.tablsp.basetable[0], self.tablsp.basetable[1]) msg_obj=packet.Message("lspr",payload) msg_bytes=pickle.dumps(msg_obj) if address:#如果是中转节点 payload=packet.askinf(address[0],address[1]) msg_obj=packet.Message("lspr",payload) msg_bytes=pickle.dumps(msg_obj) for x in range(0,self.tablsp.length()):#向LSP中的每个邻居发送请求命令 target_node_address=(self.tablsp.neighbourip[x], self.tablsp.neighbourport[x]) self.client.asklsp(self.server.socket,target_node_address,msg_bytes)
def found_neighbors(self, node_id, rpc_id, neighbors, sock, server_node_id, server_node_address): payload = packet.FoundNeighbors(node_id, self.node_id, server_node_id, rpc_id, neighbors) msg_obj = packet.Message("found_neighbors", payload) msg_bytes = pickle.dumps(msg_obj) self.client.found_neighbors(sock, server_node_address, msg_bytes)
def found_value(self, key, value, rpc_id, sock, server_node_id, target_node_address): payload = packet.FoundValue(key, value, self.node_id, server_node_id, rpc_id) msg_obj = packet.Message("found_value", payload) msg_bytes = pickle.dumps(msg_obj) self.client.found_value(sock, target_node_address, msg_bytes)
def sendrequestmessage(self, payload): print("change sent") node = self.committee_member[0] msg_obj = packet.Message("sendrequestmessage", payload) msg_bytes = pickle.dumps(msg_obj) self.client.sendrequestmessage(self.server.socket, (node.ip, node.port), msg_bytes)
def lspr(self, target_node_address): #发送自己的lsp给广播节点 ##发送自己的lsp给广播 payload = packet.lsp(self.tablsp) #打包lsp的信息 msg_obj = packet.Message("respoflspr", payload) #表示这是对lspr的回复 msg_bytes = pickle.dumps(msg_obj) sock = self.server.socket self.client.respoflspr(sock, target_node_address, msg_bytes)
def sendreply(self, blockhash): print "------send reply: the end of reply------" msg_obj = packet.Message("sendreply", blockhash) msg_bytes = pickle.dumps(msg_obj) print "primary_node_address:" print self.primary_node_address self.client.sendreply(self.server.socket, self.primary_node_address, msg_bytes)
def sendreply(self, blockhash): print("------send reply: the end of reply------") msg_obj = packet.Message("sendreply", { 'blockhash': blockhash, 'view': self.view }) msg_bytes = pickle.dumps(msg_obj) print("primary_node_address:") print(self.primary_node_address) self.client.sendreply(self.server.socket, self.primary_node_address, msg_bytes)
def pong(self, sock, server_node_id, target_node_address): """ 发送对ping请求的响应消息 :param sock: Server端监听返回的客户端连接 :param target_node_address: 目标节点的地址 :return: """ payload = packet.Pong(self.node_id, server_node_id) msg_obj = packet.Message("pong", payload) msg_bytes = pickle.dumps(msg_obj) self.client.pong(sock, target_node_address, msg_bytes)
def sendtx(self, tx): """ 广播一个交易 :param tx: :return: """ data_key = self.__hash_function(tx.txid) k_nearest_ndoes = self.iterative_find_nodes(data_key) if not k_nearest_ndoes: self.data[data_key] = tx for node in k_nearest_ndoes: tx.from_id = self.node_id msg_obj = packet.Message("sendtx", tx) msg_bytes = pickle.dumps(msg_obj) self.client.sendtx(self.server.socket, (node.ip, node.port), msg_bytes)
def sendalltx(self, alltx): print "------send alltx: the end of prepare------" # print "before sendalltx" # print "send tx:", len(self.blockchain.send_transactions) # print "received tx:", len(self.blockchain.received_transactions) # print "current tx:", len(self.blockchain.current_transactions) tm = int(time.time()) for node in self.committee_member: print "sendalltx to ", (node.ip, node.port) msg_obj = packet.Message("sendalltx", {"alltx": alltx, "time": tm}) msg_bytes = pickle.dumps(msg_obj) self.client.sendalltx(self.server.socket, (node.ip, node.port), msg_bytes) for new_tx in alltx: self.blockchain.current_transactions.append(new_tx)
def sendblock(self, block): """ 广播一个block :param block: :return: """ data_key = self.__hash_function(block.current_hash) k_nearest_ndoes = self.iterative_find_nodes(data_key) if not k_nearest_ndoes: self.data[data_key] = block for node in k_nearest_ndoes: block.from_id = self.node_id msg_obj = packet.Message("sendblock", block) msg_bytes = pickle.dumps(msg_obj) print '[Info] send block', node.ip, node.port, block.current_hash self.client.sendblock(self.server.socket, (node.ip, node.port), msg_bytes)
def minner(self): member_index = 0 while True: # blockchain多个线程共享使用,需要加锁 if self.view == 0 and self.is_primary: time.sleep(60) print "-------START--------" self.sendrequest(0) # first = False if self.startflag and (self.receivealltx >= len( self.committee_member)) and (int(time.time()) > self.maxTime): print "-------collected enough tx: the start of commit-------" # with self.lock: print len(self.blockchain.current_transactions) self.receivealltx_last = self.receivealltx self.txinblock = len(self.blockchain.current_transactions) # print "txinblock", self.txinblock new_block = self.blockchain.do_mine(self.view) self.blockcache = new_block self.sendblockhash(new_block.current_hash) self.startflag = False if self.replyflag and self.is_primary and (int(time.time()) > self.replytime + 30): print "++++++++++PBFT FAILED++++++++++" self.sendrequest(-1) if self.failhash and self.receiveblock: self.receiveblock = False print "------send correct------" node = self.committee_member[member_index] msg_obj = packet.Message( "sendcorrect", { "hash": self.failhash[0], "address": (self.client.ip, self.client.port) }) msg_bytes = pickle.dumps(msg_obj) self.client.sendcorrect(self.server.socket, (node.ip, node.port), msg_bytes) member_index += 1 time.sleep(1)
def sendblockhash(self, blockhash): """ 广播一个blockhash :param blockhash: :return: """ print "------send blockhash: the end of commit------" for node in self.committee_member: msg_obj = packet.Message("sendblockhash", blockhash) msg_bytes = pickle.dumps(msg_obj) self.client.sendblockhash(self.server.socket, (node.ip, node.port), msg_bytes) # error test # if self.view == 4: # break if self.is_primary: self.replyflag = True self.replytime = int(time.time())
def broadcast(self, context, tree, dictlsp): print "mark dictlsp" print dictlsp child = self.tablsp.findkids(dictlsp, tree) #先用这个数组测试功能 tree = self.tablsp.deletenode(tree, dictlsp) #删除该节点作为子节点的子节点的情况 print "mark 删除后的树" print tree payload = packet.broadcast(context, tree, dictlsp) msg_obj = packet.Message("broadcast", payload) msg_bytes = pickle.dumps(msg_obj) x = 0 #用于记录这个路由的位置 k = len(child) #根据Id找到对应的路由信息 #找到对应的ip,port for i in range(k): ip = child[i][0] port = child[i][1] target_node_address = (ip, port) #按路由发送广波 sock = self.server.socket self.client.broadcast(sock, target_node_address, msg_bytes)
def sendtx(self, tx): """ 广播一個交易 :param tx: :return: """ #向tablsp中的所有节点广播 data_key = self.__hash_function(tx.txid) k = self.tablsp.length() # k_nearest_ndoes = self.iterative_find_nodes(data_key) # if not k_nearest_ndoes: # self.data[data_key] = tx print "sa" print self.tablsp.neighbourip print self.tablsp.neighbourport print k for x in range(k): tx.from_id = self.node_id ip = self.tablsp.neighbourip[x] port = self.tablsp.neighbourport[x] msg_obj = packet.Message("sendtx", tx) msg_bytes = pickle.dumps(msg_obj) self.client.sendtx(self.server.socket, (ip, port), msg_bytes)
def sendverck(self, node, verack): msg_obj = packet.Message("verack", verack) msg_bytes = pickle.dumps(msg_obj) self.client.sendverack(self.server.socket, (node.ip, node.port), msg_bytes)
def store(self, key, value, sock, server_node_id, target_node_address): payload = packet.Store(key, value, self.node_id, server_node_id) msg_obj = packet.Message("store", payload) msg_bytes = pickle.dumps(msg_obj) self.client.store(sock, target_node_address, msg_bytes)
def sendblock(self, payload): print "----send block----" msg_obj = packet.Message("sendblock", payload["block"]) msg_bytes = pickle.dumps(msg_obj) self.client.sendblock(self.server.socket, payload["address"], msg_bytes)
def ping(self, sock, server_node_id, target_node_address): payload = packet.Ping(self.node_id, server_node_id) msg_obj = packet.Message("ping", payload) msg_bytes = pickle.dumps(msg_obj) self.client.ping(sock, target_node_address, msg_bytes)
def sendrequest(self, payload): """ 广播一個request消息 :param payload 上一轮commit的hash: :return: """ print "-------send request: the end of pre-prepare-------" if payload != -1: if payload != self.blockcache.current_hash: self.failhash.append(payload) else: # print "pre-prepared1" #自身确认入链 if self.view >= 1: db.write_to_db(self.blockchain.wallet.address, self.blockcache) print "write to db" if self.view >= 1: self.commitMessages = [] self.maxTime = 0 self.blockchain.received_transactions = self.blockchain.received_transactions[ len(self.blockchain.send_transactions):] self.blockchain.current_transactions = self.blockchain.current_transactions[ self.txinblock:] self.receivealltx -= self.receivealltx_last self.blockchain.send_transactions = deepcopy( self.blockchain.received_transactions) # print "transaction list reset" self.view += 1 print "view:", self.view for node in self.committee_member: msg_obj = packet.Message( "sendrequest", { "hash": payload, "address": (self.client.ip, self.client.port), "GST": self.GST }) msg_bytes = pickle.dumps(msg_obj) self.client.sendrequest(self.server.socket, (node.ip, node.port), msg_bytes) # print "++++++++++++++sendrequest&tx++++++++++++++++" self.sendalltx(self.blockchain.send_transactions) self.startflag = True # print "pre-prepared2" else: self.GST += 5 for node in self.committee_member: msg_obj = packet.Message( "sendrequest", { "hash": payload, "address": (self.client.ip, self.client.port), "GST": self.GST }) msg_bytes = pickle.dumps(msg_obj) self.client.sendrequest(self.server.socket, (node.ip, node.port), msg_bytes) self.commitMessages = [] self.replyMessage = 0 self.maxTime = 0 self.blockchain.current_transactions = self.blockchain.current_transactions[ self.txinblock:] self.blockchain.send_transactions = deepcopy( self.blockchain.received_transactions) self.receivealltx -= self.receivealltx_last # print "transaction list reset" self.view += 1 print "view:", self.view # print "++++++++++++++sendrequest&tx++++++++++++++++" self.sendalltx(self.blockchain.send_transactions) self.startflag = True # print "pre-prepared2" self.replyflag = False