def _deserialize_header_data(self, json_data: dict): hash_ = Hash32.fromhex(json_data["hash"]) prev_hash = json_data.get('prevHash') prev_hash = Hash32.fromhex(prev_hash) if prev_hash else None peer_id = json_data.get('leader') peer_id = ExternalAddress.fromhex(peer_id) if peer_id else None signature = json_data.get('signature') signature = Signature.from_base64str(signature) if signature else None next_leader = json_data.get("nextLeader") next_leader = ExternalAddress.fromhex( next_leader) if next_leader else None transactions_hash = json_data["transactionsHash"] transactions_hash = Hash32.fromhex(transactions_hash) receipts_hash = json_data["receiptsHash"] receipts_hash = Hash32.fromhex(receipts_hash) state_hash = json_data["stateHash"] state_hash = Hash32.fromhex(state_hash) reps_hash = json_data["repsHash"] reps_hash = Hash32.fromhex(reps_hash) next_reps_hash = json_data["nextRepsHash"] next_reps_hash = Hash32.fromhex(next_reps_hash) leader_votes_hash = json_data["leaderVotesHash"] leader_votes_hash = Hash32.fromhex(leader_votes_hash) prev_votes_hash = json_data["prevVotesHash"] prev_votes_hash = Hash32.fromhex(prev_votes_hash) height = json_data["height"] height = int(height, 16) timestamp = json_data["timestamp"] timestamp = int(timestamp, 16) return { "hash": hash_, "prev_hash": prev_hash, "height": height, "timestamp": timestamp, "peer_id": peer_id, "signature": signature, "next_leader": next_leader, "transactions_hash": transactions_hash, "receipts_hash": receipts_hash, "state_hash": state_hash, "reps_hash": reps_hash, "next_reps_hash": next_reps_hash, "leader_votes_hash": leader_votes_hash, "prev_votes_hash": prev_votes_hash, "logs_bloom": BloomFilter.fromhex(json_data["logsBloom"]) }
def from_(self, tx_data: dict) -> 'Transaction': tx_data_copied = dict(tx_data) tx_data_copied.pop('method', None) hash = tx_data_copied.pop('tx_hash', None) signature = tx_data_copied.pop('signature', None) timestamp = tx_data_copied.pop('timestamp', None) from_address = tx_data_copied.pop('from', None) to_address = tx_data_copied.pop('to', None) value = tx_data_copied.pop('value', None) fee = tx_data_copied.pop('fee', None) nonce = tx_data_copied.pop('nonce', None) extra = tx_data_copied value = int_fromhex(value) fee = int_fromhex(fee) if nonce is not None: nonce = int_fromstr(nonce) return Transaction( raw_data=tx_data, hash=Hash32.fromhex(hash, ignore_prefix=True, allow_malformed=False), signature=Signature.from_base64str(signature), timestamp=int(timestamp) if timestamp is not None else None, from_address=ExternalAddress.fromhex(from_address, ignore_prefix=False, allow_malformed=True), to_address=ExternalAddress.fromhex(to_address, ignore_prefix=False, allow_malformed=True), value=value, fee=fee, nonce=nonce, extra=extra, )
def add_complain(self, vote: LeaderVote): util.logger.spam(f"add_complain vote({vote})") if not self.epoch: util.logger.debug(f"Epoch is not initialized.") return if self.epoch.height == vote.block_height: if self.epoch.round == vote.round_: self.epoch.add_complain(vote) elif self.epoch.round > vote.round_: if vote.new_leader != ExternalAddress.empty(): self.__send_fail_leader_vote(vote) else: return else: # TODO: do round sync return elected_leader = self.epoch.complain_result() if elected_leader: if elected_leader == ExternalAddress.empty().hex_xx( ) and vote.round_ == self.epoch.round: util.logger.warning( f"Fail to elect the next leader on {self.epoch.round} round." ) elected_leader = self.blockchain.get_next_rep_in_reps( ExternalAddress.fromhex(self.epoch.leader_id), self.epoch.reps).hex_hx() if self.epoch.round == vote.round_: self.__channel_service.reset_leader(elected_leader, complained=True) elif self.epoch.height < vote.block_height: self.__channel_service.state_machine.block_sync()
def block_maker(timestamp: int, height: int = 0, prev_hash=None): """Make dummy block""" tx_versioner = TransactionVersioner() dummy_receipts = {} block_builder = BlockBuilder.new("0.1a", tx_versioner) for i in range(1000): tx_builder = TransactionBuilder.new("0x3", None, tx_versioner) tx_builder.signer = test_signer tx_builder.to_address = ExternalAddress.new() tx_builder.step_limit = random.randint(0, 10000) tx_builder.value = random.randint(0, 10000) tx_builder.nid = 2 tx = tx_builder.build() tx_serializer = TransactionSerializer.new( tx.version, tx.type(), tx_versioner) block_builder.transactions[tx.hash] = tx dummy_receipts[tx.hash.hex()] = { "dummy_receipt": "dummy", "tx_dumped": tx_serializer.to_full_data(tx) } block_builder.signer = test_signer block_builder.prev_hash = prev_hash block_builder.height = height block_builder.state_hash = Hash32(bytes(Hash32.size)) block_builder.receipts = dummy_receipts block_builder.reps = [ ExternalAddress.fromhex_address(test_signer.address) ] block_builder.peer_id = ExternalAddress.fromhex( test_signer.address) block_builder.next_leader = ExternalAddress.fromhex( test_signer.address) block_builder.fixed_timestamp = timestamp b = block_builder.build() assert b.header.timestamp == timestamp return b
def verify_accounts(self, tx: 'Transaction'): for account in tx.accounts: if "address" not in account: raise RuntimeError( f'Genesis Tx({tx.hash.hex()}), ' f'"address" does not exist in an account of genesis tx.') if "balance" not in account: raise RuntimeError( f'Genesis Tx({tx.hash.hex()}), ' f'"balance" does not exist in an account of genesis tx.') if "name" not in account: raise RuntimeError( f'Genesis Tx({tx.hash.hex()}), ' f'"name" does not exist in an account of genesis tx.') if account["balance"] is None: raise RuntimeError( f'Genesis Tx({tx.hash.hex()}), ' '"balance" value is None in an account of genesis tx.') # An exception will be raised if 'address' is invalid. ExternalAddress.fromhex(account['address'])
def _deserialize_header_data(self, json_data: dict): prev_hash = json_data.get('prev_block_hash') prev_hash = Hash32.fromhex(prev_hash, ignore_prefix=True) if prev_hash else None peer_id = json_data.get('peer_id') peer_id = ExternalAddress.fromhex(peer_id) if peer_id else None signature = json_data.get('signature') signature = Signature.from_base64str(signature) if signature else None next_leader = json_data.get("next_leader") next_leader = ExternalAddress.fromhex(next_leader) if next_leader else None return { "hash": Hash32.fromhex(json_data["block_hash"], ignore_prefix=True), "prev_hash": prev_hash, "height": json_data["height"], "timestamp": json_data["time_stamp"], "peer_id": peer_id, "signature": signature, "next_leader": next_leader, "merkle_tree_root_hash": Hash32.fromhex(json_data["merkle_tree_root_hash"], ignore_prefix=True), "commit_state": json_data["commit_state"] }
def get_leader_ids_for_complaint(self) -> Tuple[str, str]: """ :return: Return complained_leader_id and new_leader_id for the Leader Complaint. """ complained_leader_id = self.epoch.leader_id new_leader = self.blockchain.get_next_rep_in_reps( ExternalAddress.fromhex(complained_leader_id), self.epoch.reps) new_leader_id = new_leader.hex_hx() if new_leader else None if not isinstance(new_leader_id, str): new_leader_id = "" if not isinstance(complained_leader_id, str): complained_leader_id = "" return complained_leader_id, new_leader_id
def test_block_v0_4(self): block_version = "0.4" test_signer = Signer.from_prikey(os.urandom(32)) tx_versioner = TransactionVersioner() dummy_receipts = {} block_builder = BlockBuilder.new(block_version, tx_versioner) for i in range(5): tx_builder = TransactionBuilder.new("0x3", None, tx_versioner) tx_builder.signer = test_signer tx_builder.to_address = ExternalAddress.new() tx_builder.step_limit = random.randint(0, 10000) tx_builder.value = random.randint(0, 10000) tx_builder.nid = 2 tx = tx_builder.build() tx_serializer = TransactionSerializer.new(tx.version, tx.type(), tx_versioner) block_builder.transactions[tx.hash] = tx dummy_receipts[tx.hash.hex()] = { "dummy_receipt": "dummy", "tx_dumped": tx_serializer.to_full_data(tx) } next_leader = ExternalAddress.fromhex( "hx00112233445566778899aabbccddeeff00112233") block_builder.signer = test_signer block_builder.height = 0 block_builder.prev_hash = Hash32(bytes(Hash32.size)) block_builder.state_hash = Hash32(bytes(Hash32.size)) block_builder.receipts = dummy_receipts block_builder.reps = [ ExternalAddress.fromhex_address(test_signer.address) ] block_builder.next_leader = next_leader block_builder.next_reps = [] vote = BlockVote.new(test_signer, utils.get_time_stamp(), block_builder.height - 1, 0, block_builder.prev_hash) votes = BlockVotes(block_builder.reps, conf.VOTING_RATIO, block_builder.height - 1, 0, block_builder.prev_hash) votes.add_vote(vote) block_builder.prev_votes = votes.votes block = block_builder.build() block_verifier = BlockVerifier.new(block_version, tx_versioner) block_verifier.invoke_func = lambda b, prev_b: (block, dummy_receipts) reps_getter = lambda _: block_builder.reps generator = ExternalAddress.fromhex_address(test_signer.address) block_verifier.verify(block, None, None, generator=generator, reps_getter=reps_getter) block_serializer = BlockSerializer.new(block_version, tx_versioner) block_serialized = block_serializer.serialize(block) logging.info(json.dumps(block_serialized, indent=4)) block_deserialized = block_serializer.deserialize(block_serialized) logging.info( json.dumps(block_serializer.serialize(block_deserialized), indent=4)) assert block.header == block_deserialized.header assert block.body == block_deserialized.body tx_hashes = list(block.body.transactions) tx_index = random.randrange(0, len(tx_hashes)) block_prover = BlockProver.new(block.header.version, tx_hashes, BlockProverType.Transaction) tx_proof = block_prover.get_proof(tx_index) assert block_prover.prove(tx_hashes[tx_index], block.header.transactions_hash, tx_proof) block_prover = BlockProver.new(block.header.version, block_builder.receipts, BlockProverType.Receipt) receipt_proof = block_prover.get_proof(tx_index) receipts_hash = block_prover.to_hash32( block_builder.receipts[tx_index]) assert block_prover.prove(receipts_hash, block.header.receipts_hash, receipt_proof)
def new(cls, signer: Signer, timestamp: int, **kwargs): rep_id: ExternalAddress = ExternalAddress.fromhex(signer.address) hash_ = cls.to_hash(rep_id, timestamp, **kwargs) signature = Signature(signer.sign_hash(hash_)) return cls(rep_id, timestamp, signature, **kwargs)