def react_to_received_subchain(subchain): if subchain is None: return if not core.compare(subchain[0].transmission_hash, storage.get_block(storage.get_head()).unsigned_transmission_hash()): return for j in range(1, len(subchain)): if not core.compare(subchain[j].previous_hash, subchain[j - 1].unsigned_transmission_hash()): return if not core.verify_transmission(subchain[j]): return for sub in subchain[1:]: storage.put_block(sub)
def check_self(self): prev = bytearray(self.previous_hash, "utf-8") time = bytearray(self.timestamp, "utf-8") pubs = bytearray("".join(self.pub_keys), "utf-8") hash = bytearray(self.hash, "utf-8") sign = bytearray(self.signed_hash, "utf-8") comb = prev + time + pubs + hash + sign own_hash = cryptoHashes.CryptoHashes.sha3_512(comb) return core.compare(own_hash, self.transmission_hash)
def react_to_receive_messsage(self, transmission): if transmission is None: return if not core.compare(transmission.transmission_hash, storage.get_block(storage.get_head()).unsigned_transmission_hash()): print("REMOTE SYNC REJECTED") core.network_log("REMOTE TRANSMISSION REJECTED") return if not core.verify_transmission(transmission): print("REMOTE SYNC REJECTED") core.network_log("REMOTE TRANSMISSION REJECTED") return storage.put_block(transmission) print("REMOTE SYNC ACCEPTED") core.network_log("REMOTE TRANSMISSION ACCEPTED")
def synchronize(self): # Synchronizing: # Step 1: send request message and get list of transmission hashes (clear and signed) message_list = self.client.send_synchronize_request() # message_list: [{public_key, transmission_hash, transmission_hash_signed}] # Step 2: group received hashes by majority majority = [] for msg in message_list: # TODO add again #r = requests.get('https://api.zipixx.com/cryptocontracts/', header="Content-Type: application/json", data="{key: " + msg["public_key"] + "}") #if not r.status_code == 200: # continue unsigned_hash = signing.unsign(msg["transmission_hash_signed"], {msg["public_key"]}) if not core.compare(unsigned_hash, msg["transmission_hash"]): continue close = False for i in range(len(majority)): if core.compare(majority[i]["hash"], msg["transmission_hash"]): majority[i]["count"] += 1 majority[i]["list"].append(msg) close = True break if not close: majority.append({ "hash": msg["transmission_hash"], "count": 1, "list": [msg] }) majority = sorted(majority, key=lambda k: k["count"], reverse=True) # Step 3: request subchain result = None already_synced = 0 for maj in majority: if core.compare( maj["hash"], storage.get_block( storage.get_head()).unsigned_transmission_hash()): already_synced += 1 continue elif storage.block_exists(maj["hash"]): subchain = storage.get_subchain(maj["hash"]) subchain.reverse() self.client.send_n1_subchain(subchain) print("SYNCRONIZATION SUCCESSFUL") core.network_log("SYNC SUCCESS") return SUCCESS succeeded = False for i in range(5): rnd = random.randint(0, len(maj["list"]) - 1) subchain = self.client.request_subchain( maj["list"][rnd], storage.get_block( storage.get_head()).unsigned_transmission_hash()) # subchain: list of transmissions [old -> new] if subchain is None: continue if not core.compare( subchain[0].transmission_hash, storage.get_block( storage.get_head()).unsigned_transmission_hash()): continue failed = False for j in range(1, len(subchain)): if not core.compare( subchain[j].previous_hash, subchain[j - 1].unsigned_transmission_hash()): failed = True break if not core.verify_transmission(subchain[j]): failed = True break if failed: continue succeeded = True result = subchain break if succeeded: break if already_synced == len(majority): print("ALREADY SYNCHRONIZED") core.network_log("ALREADY SYNCHRONIZED") return SUCCESS # Step 4: Add if result is None: print("SYNCHRONIZATION FAILED") core.network_log("SYNC FAIL") return FAIL for sub in result[1:]: storage.put_block(sub) print("SYNCHRONIZATION SUCCESSFUL") core.network_log("SYNC SUCCESS") return SUCCESS