def post(self): user_id = self.get_argument("user_id") folder_hash = self.get_argument("folder_hash") block_size = int(self.get_argument("block_size")) folder_size = int(self.get_argument("folder_size")) groupid = self.get_argument("groupid") capsule = self.get_argument("capsule") timestamp = self.get_argument("timestamp") signature = self.get_argument("signature") vk = keys.UmbralPublicKey.from_bytes(bytes.fromhex(str(user_id))) sig = signing.Signature.from_bytes(bytes.fromhex(str(signature))) assert sig.verify(timestamp.encode("utf8"), vk) print(tree.current_port, len(self.request.body)) if not os.path.exists("data/%s" % user_id): os.mkdir("data/%s" % user_id) open("data/%s/%s" % (user_id, folder_hash), "wb").write(self.request.body) open("data/%s/%s_capsule" % (user_id, folder_hash), "wb").write(bytes.fromhex(capsule)) data = { "folder_hash": folder_hash, "block_size": block_size, "folder_size": folder_size, "groupid": groupid, "user_id": user_id, "by": tree.current_port } tree.forward( ["UPDATE_HOME", user_id, data, time.time(), uuid.uuid4().hex]) self.finish()
def on_message(self, msg): if msg is None: if not self.remove_node: print(tree.current_port, "reconnect leader on message...") # self.ws_uri = "ws://%s:%s/leader?host=%s&port=%s" % (self.host, self.port, tree.current_host, tree.current_port) tornado.ioloop.IOLoop.instance().call_later(1.0, self.connect) return seq = tornado.escape.json_decode(msg) # print(tree.current_port, "on message from leader", seq) if seq[0] == "NEW_CHAIN_BLOCK": miner.new_block(seq) elif seq[0] == "PBFT_O": # print(tree.current_port, "PBFT_O get message", seq[1]) view = seq[1] view_no = seq[2] # view's no should be continuous block = seq[3] msgid = block["transaction"]["txid"] if "transaction" in block else block["message"]["msgid"] # gen block block_hash = block["block_hash"] k = "%s_%s"%(int(view), int(view_no)) view_transactions[k] = block forward(["PBFT_P", view, view_no, msgid, block_hash]) return elif seq[0] == "PBFT_P": view = seq[1] view_no = seq[2] msgid = seq[3] block_hash = seq[4] # verify blockhash with own blockhash for msgid forward(["PBFT_C", view, view_no, msgid, current_view]) return elif seq[0] == "PBFT_C": view = seq[1] view_no = seq[2] msgid = seq[3] confirm_view = seq[4] k = "%s_%s"%(int(view), int(view_no)) block = view_transactions.get(k) view_confirms.setdefault(k, set()) confirms = view_confirms[k] if confirm_view not in confirms: confirms.add(confirm_view) # print(tree.current_port, current_view, confirms, block) if block and len(confirms)==2: print(tree.current_port, "NEW BLOCK", msgid) if "transaction" in block: message = ["NEW_TX_BLOCK", block, time.time(), uuid.uuid4().hex] else: message = ["NEW_MSG_BLOCK", block, time.time(), uuid.uuid4().hex] tree.forward(message) return forward(seq)
def mining(): global nonce longest = miner.longest_chain() # print(longest) if longest: longest_hash = longest[-1].hash difficulty = longest[-1].difficulty data = longest[-1].data identity = longest[-1].identity recent = longest[-3:] # print(recent) if len(recent) * setting.BLOCK_INTERVAL_SECONDS > recent[ -1].timestamp - recent[0].timestamp: new_difficulty = min(255, difficulty + 1) else: new_difficulty = max(1, difficulty - 1) # if tree.current_port in [i.identity for i in longest[-6:]]: # return else: longest_hash, difficulty, new_difficulty, data, identity = "0" * 64, 1, 1, "", "" if not transactions: return print(transactions) transaction = transactions[0] msg_header, user_id, data, timestamp, msg_id = transaction if msg_id in [i["identity"] for i in longest or []]: transactions.pop(0) return for i in range(100): block_hash = hashlib.sha256( (identity + json.dumps(data) + longest_hash + str(difficulty) + str(nonce)).encode('utf8')).hexdigest() if int(block_hash, 16) < int("1" * (256 - difficulty), 2): if longest: print(len(longest), longest[-1].timestamp, longest[0].timestamp, longest[-1].timestamp - longest[0].timestamp) # db.execute("UPDATE chain SET hash = %s, prev_hash = %s, nonce = %s, wallet_address = %s WHERE id = %s", block_hash, longest_hash, nonce, wallet_address, last.id) # database.connection.execute("INSERT INTO chain"+tree.current_port+" (hash, prev_hash, nonce, difficulty, identity, timestamp, data) VALUES (%s, %s, %s, %s, '')", block_hash, longest_hash, nonce, difficulty, str(tree.current_port)) message = [ "NEW_BLOCK", block_hash, longest_hash, nonce, new_difficulty, msg_id, int(time.time()), data, uuid.uuid4().hex ] tree.forward(message) # print(tree.current_port, "mining", nonce, block_hash) nonce = 0 transactions.pop(0) break nonce += 1
def on_message(self, msg): global current_view_no seq = tornado.escape.json_decode(msg) # print(tree.current_port, "on message from leader connector", seq) if seq[0] == "NEW_CHAIN_BLOCK": miner.new_block(seq) elif seq[0] == "PBFT_O": # print(tree.current_port, "PBFT_O get message", seq[1]) view = seq[1] view_no = seq[2] # view's no should be continuous block = seq[3] msgid = block["transaction"]["txid"] if "transaction" in block else block["message"]["msgid"] # gen block block_hash = block["block_hash"] k = "%s_%s"%(int(view), int(view_no)) view_transactions[k] = block forward(["PBFT_P", view, view_no, msgid, block_hash]) return elif seq[0] == "PBFT_P": view = seq[1] view_no = seq[2] msgid = seq[3] block_hash = seq[4] # verify blockhash with own blockhash for msgid forward(["PBFT_C", view, view_no, msgid, current_view]) return elif seq[0] == "PBFT_C": view = seq[1] view_no = seq[2] msgid = seq[3] confirm_view = seq[4] k = "%s_%s"%(int(view), int(view_no)) block = view_transactions.get(k) view_confirms.setdefault(k, set()) confirms = view_confirms[k] if confirm_view not in confirms: confirms.add(confirm_view) # print(tree.current_port, current_view, confirms, block) if block and len(confirms)==2: print(tree.current_port, "NEW BLOCK", msgid) if "transaction" in block: message = ["NEW_TX_BLOCK", block, time.time(), uuid.uuid4().hex] else: message = ["NEW_MSG_BLOCK", block, time.time(), uuid.uuid4().hex] tree.forward(message) return elif seq[0] == "PBFT_V": pass forward(seq)
def mining(): global nonce longest = longest_chain() # print(longest) if longest: longest_hash = longest[-1].hash difficulty = longest[-1].difficulty identity = longest[-1].identity data = longest[-1].data recent = longest[-3:] # print(recent) if len(recent) * setting.BLOCK_INTERVAL_SECONDS > recent[ -1].timestamp - recent[0].timestamp: new_difficulty = min(255, difficulty + 1) else: new_difficulty = max(1, difficulty - 1) if tree.current_port in [i.identity for i in longest[-6:]]: # this is a good place to wake up leader by timestamp return else: longest_hash, difficulty, new_difficulty, data, identity = "0" * 64, 1, 1, "", "" new_identity = str(tree.current_port) new_timestamp = str(time.time()) for i in range(100): block_hash = hashlib.sha256( (new_identity + new_timestamp + identity + data + longest_hash + str(difficulty) + str(nonce)).encode('utf8')).hexdigest() if int(block_hash, 16) < int("1" * (256 - difficulty), 2): if longest: print(tree.current_port, 'height', len(longest), longest[-1].timestamp, longest[0].timestamp, 'timecost', longest[-1].timestamp - longest[0].timestamp) # db.execute("UPDATE chain SET hash = %s, prev_hash = %s, nonce = %s, wallet_address = %s WHERE id = %s", block_hash, longest_hash, nonce, wallet_address, last.id) # database.connection.execute("INSERT INTO chain"+tree.current_port+" (hash, prev_hash, nonce, difficulty, identity, timestamp, data) VALUES (%s, %s, %s, %s, '')", block_hash, longest_hash, nonce, difficulty, str(tree.current_port)) message = [ "NEW_BLOCK", block_hash, longest_hash, len(longest) + 1, nonce, new_difficulty, new_identity, new_timestamp, {}, uuid.uuid4().hex ] tree.forward(message) # print(tree.current_port, "mining", nonce, block_hash) nonce = 0 break nonce += 1
def reg(self, domain): nodepk = base64.b32encode( tree.node_sk.get_verifying_key().to_string()).decode("utf8") msg = { "message": { "msgid": uuid.uuid4().hex, "sender": nodepk, "receiver": base64.b32encode(domain.encode("utf8")), "timestamp": time.time() }, "signature": base64.b32decode("4".encode("utf8")).decode("utf8") } tree.forward(["NEW_MSG", msg, time.time(), uuid.uuid4().hex]) self.finish({"msgid": msg["message"]["msgid"], "msg": msg})
def post(self): tx = tornado.escape.json_decode(self.request.body) tree.forward(["NEW_TX", tx, time.time(), uuid.uuid4().hex]) self.finish({"txid": tx["transaction"]["txid"]})
def get(self): test_msg = ["TEST_MSG", tree.current_groupid, time.time(), uuid.uuid4().hex] tree.forward(test_msg) self.finish({"test_msg": test_msg})
def mining(): # global working # global transactions # global locked_blocks # print(tree.current_port, "leader transactions", transactions) if transactions: seq = transactions.pop(0) transaction = seq[1] txid = transaction["transaction"]["txid"] sender = transaction["transaction"]["sender"] receiver = transaction["transaction"]["receiver"] amount = transaction["transaction"]["amount"] timestamp = transaction["transaction"]["timestamp"] signature = transaction["signature"] sender_blocks = lastest_block(sender) receiver_blocks = lastest_block(receiver) from_block = sender_blocks[-1] if sender_blocks else sender to_block = receiver_blocks[-1] if receiver_blocks else receiver # if from_block in locked_blocks or to_block in locked_blocks: # transactions.append(seq) # tornado.ioloop.IOLoop.instance().call_later(1, mining) # return nonce = 0 data = txid + sender + receiver + str(amount) + str( timestamp) + signature + from_block + to_block + str( tree.current_port) while True: block_hash = hashlib.sha256( (data + str(nonce)).encode('utf8')).hexdigest() if block_hash < certain_value: locked_blocks.add(from_block) locked_blocks.add(to_block) transaction["block_hash"] = block_hash transaction["nonce"] = nonce transaction["from_block"] = from_block transaction["to_block"] = to_block block_to_confirm[txid] = transaction reply = block_to_reply.setdefault(txid, set()) for leader_node in LeaderHandler.leader_nodes: reply.add(leader_node) for leader_connector in LeaderConnector.leader_nodes: reply.add(leader_connector) # print(tree.current_port, "reply", reply) message = [ "NEW_TX_BLOCK", transaction, time.time(), uuid.uuid4().hex ] print(tree.current_port, message) tree.forward(message) message = ["TX", transaction] # forward(message) break nonce += 1 print(tree.current_port, txid, from_block, to_block) if working: tornado.ioloop.IOLoop.instance().call_later(1, mining)