Example #1
0
    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,
        )
Example #3
0
    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()
Example #4
0
        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
Example #5
0
    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'])
Example #6
0
    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"]
        }
Example #7
0
    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
Example #8
0
    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)
Example #9
0
    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)