コード例 #1
0
    def test_transaction_v2_invalid_signature(self):
        # noinspection PyDictCreation
        tx_dumped = {
            'from':
            'hx48cd6eb32339d5c719dcc0af21e9bc3b67d733e6',
            'to':
            'hx22f72e44141bedd50d1e536455682863d3d8a484',
            'value':
            '0x186a0',
            'fee':
            '0xf4240',
            'timestamp':
            '1558679280067963',
            'nonce':
            '1',
            'tx_hash':
            '34477b3bc76fa73aad0258ba9fd36f28a3c4b26956c1e5eb92ddda7d98df4e32',  # valid hash
            'signature':
            'W/hW/PAo+ExeSsreD//yJVgNqmnkWKs+m0VUqE11O7Ek82yEINuczLRXtj1k515q8Ep4OLsRPPiPNjDM9vuhsgE='
        }
        tx_dumped['signature'] = Signature(os.urandom(
            Signature.size)).to_base64str()  # invalid signature

        tx_version, tx_type = self.tx_versioner.get_version(tx_dumped)
        ts = TransactionSerializer.new(tx_version, tx_type, self.tx_versioner)
        tx = ts.from_(tx_dumped)

        tv = TransactionVerifier.new(tx_version, tx_type, self.tx_versioner)
        self.assertRaises(TransactionInvalidSignatureError,
                          lambda: tv.verify(tx))
        self.assertRaises(TransactionInvalidSignatureError,
                          lambda: tv.pre_verify(tx))
コード例 #2
0
    def test_block_invalid_vote(self):
        ratio = 0.67
        block_hash = Hash32(os.urandom(Hash32.size))
        block_votes = BlockVotes(self.reps, ratio, 0, 0, block_hash)

        invalid_block_vote = BlockVote.new(self.signers[0], 0, 0, 1,
                                           block_hash)
        self.assertRaises(RuntimeError, block_votes.add_vote,
                          invalid_block_vote)

        invalid_block_vote = BlockVote.new(self.signers[0], 0, 1, 0,
                                           block_hash)
        self.assertRaises(RuntimeError, block_votes.add_vote,
                          invalid_block_vote)

        invalid_block_vote = BlockVote.new(self.signers[0], 0, 0, 0,
                                           Hash32(os.urandom(32)))
        self.assertRaises(RuntimeError, block_votes.add_vote,
                          invalid_block_vote)

        invalid_block_vote = BlockVote(rep=self.reps[0],
                                       timestamp=0,
                                       signature=Signature(os.urandom(65)),
                                       block_height=0,
                                       round_=0,
                                       block_hash=block_hash)
        self.assertRaises(RuntimeError, block_votes.add_vote,
                          invalid_block_vote)

        block_vote = BlockVote.new(self.signers[0], 0, 0, 0, block_hash)
        block_votes.add_vote(block_vote)
        duplicate_block_vote = BlockVote.new(self.signers[0], 0, 0, 0,
                                             Hash32.empty())
        self.assertRaises(votes.VoteDuplicateError, block_votes.add_vote,
                          duplicate_block_vote)
コード例 #3
0
ファイル: block_serializer.py プロジェクト: yakkle/loopchain
    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"])
        }
コード例 #4
0
    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,
        )
コード例 #5
0
ファイル: block_builder.py プロジェクト: JINWOO-J/loopchain
    def sign(self):
        if self.signature is not None:
            return self.signature

        if self.hash is None:
            raise RuntimeError

        self.signature = Signature(self.signer.sign_hash(self.hash))
        return self.signature
コード例 #6
0
    def sign_transaction(self, tx: 'Transaction'):
        if self.signer.address != tx.signer_address.hex_hx():
            raise RuntimeError(
                f"Signer not match. {self.signer.address} != {tx.signer_address.hex_hx()}"
            )

        signature = Signature(self.signer.sign_hash(tx.hash))

        raw_data = dict(tx.raw_data)
        raw_data["signature"] = signature.to_base64str()

        return Transaction(raw_data=raw_data,
                           hash=tx.hash,
                           signature=signature,
                           timestamp=tx.timestamp,
                           from_address=tx.from_address,
                           to_address=tx.to_address,
                           value=tx.value,
                           fee=tx.fee,
                           nonce=tx.nonce)
コード例 #7
0
        def _header(hash_: Hash32 = Hash32.new(),
                    prev_hash: Hash32 = Hash32.new(),
                    height: int = 0,
                    timestamp: int = 0,
                    peer_id: ExternalAddress = ExternalAddress.new(),
                    signature: Signature = Signature.new(),
                    next_leader: Address = Address.new(),
                    merkle_tree_root_hash: Hash32 = Hash32.new(),
                    commit_state: dict = dict()) -> BlockHeader_v0_1a:

            return BlockHeader_v0_1a(hash_, prev_hash, height, timestamp, peer_id,
                                     signature, next_leader, merkle_tree_root_hash, commit_state)
コード例 #8
0
        def _header(hash_: Hash32 = Hash32.new(),
                    prev_hash: Hash32 = Hash32.new(),
                    height: int = 0,
                    timestamp: int = 0,
                    peer_id: ExternalAddress = ExternalAddress.new(),
                    signature: Signature = Signature.new(),
                    next_leader: ExternalAddress = ExternalAddress.new(),
                    logs_bloom: BloomFilter = BloomFilter.new(),
                    transactions_hash: Hash32 = Hash32.new(),
                    state_hash: Hash32 = Hash32.new(),
                    receipts_hash: Hash32 = Hash32.new(),
                    reps_hash: Hash32 = Hash32.new(),
                    next_reps_hash: Hash32 = Hash32.new(),
                    leader_votes_hash: Hash32 = Hash32.new(),
                    prev_votes_hash: Hash32 = Hash32.new()) -> BlockHeader_v0_4:

            return BlockHeader_v0_4(hash_, prev_hash, height, timestamp, peer_id, signature,
                                    next_leader, logs_bloom, transactions_hash,
                                    state_hash, receipts_hash, reps_hash,
                                    next_reps_hash, leader_votes_hash, prev_votes_hash)
コード例 #9
0
    def test_leader_invalid_vote(self):
        ratio = 0.67

        old_leader = self.reps[0]
        new_leader = self.reps[1]
        leader_votes = LeaderVotes(self.reps, ratio, 0, 0, old_leader)

        invalid_leader_vote = LeaderVote.new(self.signers[0], 0, 1, 0,
                                             old_leader, new_leader)
        self.assertRaises(RuntimeError, leader_votes.add_vote,
                          invalid_leader_vote)

        invalid_leader_vote = LeaderVote.new(self.signers[0], 0, 0, 1,
                                             old_leader, new_leader)
        self.assertRaises(RuntimeError, leader_votes.add_vote,
                          invalid_leader_vote)

        invalid_leader_vote = LeaderVote.new(self.signers[0], 0, 0, 0,
                                             new_leader, new_leader)
        self.assertRaises(RuntimeError, leader_votes.add_vote,
                          invalid_leader_vote)

        invalid_leader_vote = LeaderVote(rep=self.reps[0],
                                         timestamp=0,
                                         signature=Signature(os.urandom(65)),
                                         block_height=0,
                                         round_=0,
                                         new_leader=new_leader,
                                         old_leader=old_leader)
        self.assertRaises(RuntimeError, leader_votes.add_vote,
                          invalid_leader_vote)

        leader_vote = LeaderVote.new(self.signers[0], 0, 0, 0, old_leader,
                                     new_leader)
        leader_votes.add_vote(leader_vote)
        duplicate_leader_vote = LeaderVote.new(self.signers[0], 0, 0, 0,
                                               old_leader, self.reps[2])
        self.assertRaises(votes.VoteDuplicateError, leader_votes.add_vote,
                          duplicate_leader_vote)
コード例 #10
0
    def test_transaction_v3_invalid_signature(self):
        # noinspection PyDictCreation
        tx_dumped = {
            'version':
            '0x3',
            'from':
            'hx48cd6eb32339d5c719dcc0af21e9bc3b67d733e6',
            'to':
            'hxe0a231fa5c80e45f51d7df5f7d127954320df829',
            'stepLimit':
            '0xf4240',
            'timestamp':
            '0x5899c717f92f8',
            'nid':
            '0x3',
            'value':
            '0x186a0',
            'nonce':
            '0x64',
            'data':
            'test',
            'dataType':
            'message',
            'signature':
            'J84KdBtQR4w1bcBdBGF8g6aNoCXjsY/5T6vGV4RXeMwEvafj9xVRDVjzF+vN1JVYvXrAzjlYPCiiBXBQe6+tRAE='
        }
        tx_dumped['signature'] = Signature(os.urandom(
            Signature.size)).to_base64str()  # invalid signature

        tx_version, tx_type = self.tx_versioner.get_version(tx_dumped)
        ts = TransactionSerializer.new(tx_version, tx_type, self.tx_versioner)
        tx = ts.from_(tx_dumped)

        tv = TransactionVerifier.new(tx_version, tx_type, self.tx_versioner)
        self.assertRaises(TransactionInvalidSignatureError,
                          lambda: tv.verify(tx))
        self.assertRaises(TransactionInvalidSignatureError,
                          lambda: tv.pre_verify(tx, nid=3))
コード例 #11
0
ファイル: block_serializer.py プロジェクト: yakkle/loopchain
    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"]
        }
コード例 #12
0
ファイル: vote.py プロジェクト: yakkle/loopchain
 def empty(cls, rep: ExternalAddress, block_height: int, round_: int,
           old_leader: ExternalAddress):
     return cls(rep, 0, Signature.empty(), block_height, round_, old_leader,
                ExternalAddress.empty())
コード例 #13
0
 def _deserialize(cls, data: dict):
     return {
         "rep": ExternalAddress.fromhex_address(data["rep"]),
         "timestamp": int(data["timestamp"], 16),
         "signature": Signature.from_base64str(data["signature"])
     }
コード例 #14
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)
コード例 #15
0
ファイル: vote.py プロジェクト: yakkle/loopchain
 def empty(cls, rep: ExternalAddress, block_height: int):
     return cls(rep, 0, Signature.empty(), block_height, Hash32.empty())
コード例 #16
0
class TestTxCache:
    target_attrs = ["hash", "signature"]

    @pytest.mark.parametrize("target_attr", target_attrs)
    def test_no_cache_attr_in_tx_if_not_verified(self, tx_version,
                                                 tx_factory: 'TxFactory',
                                                 target_attr):
        """Check that Transaction has no attribute until the verification func has been invoked"""
        tx = tx_factory(tx_version)
        if any("cache" in attr for attr in dir(tx)):
            raise AttributeError(
                "Something wrong. Transaction has cached value when initialized."
            )

        with pytest.raises(AttributeError):
            getattr(tx, f"_cache_verify_{target_attr}")

    @pytest.mark.parametrize("raise_exception", [True, False])
    @pytest.mark.parametrize("target_attr", ["hash", "signature"])
    def test_has_cache_attr_when_verified_successfully(self, tx_version,
                                                       tx_factory: 'TxFactory',
                                                       raise_exception,
                                                       target_attr):
        """Check that the verification result has been cached successfully"""
        tx = tx_factory(tx_version)
        tv = TransactionVerifier.new(tx.version,
                                     tx.type(),
                                     tx_versioner,
                                     raise_exceptions=raise_exception)

        verify_func_name = f"verify_{target_attr}"
        verify_func = getattr(tv, verify_func_name)
        verify_func(tx)

        assert getattr(tx, f"_cache_{verify_func_name}")

    @pytest.mark.parametrize("raise_exception", [True, False])
    @pytest.mark.parametrize("expected_exc, target_attr, fake_value", [
        (TransactionInvalidHashError, "hash", Hash32.new()),
        (TransactionInvalidSignatureError, "signature", Signature.new()),
    ])
    def test_exception_cached_when_raised_exception_while_verification(
            self, tx_version, tx_factory: 'TxFactory', raise_exception,
            expected_exc, target_attr, fake_value, monkeypatch):
        """Check that the exception successfully cached when raised any exception while verification step"""
        tx = tx_factory(tx_version)
        tv = TransactionVerifier.new(tx.version,
                                     tx.type(),
                                     tx_versioner,
                                     raise_exceptions=raise_exception)
        verify_func = getattr(tv, f"verify_{target_attr}")

        orig_value = getattr(tx, target_attr)
        test_values = (fake_value, orig_value)

        for test_value in test_values:
            # Monkeypatch
            object.__setattr__(tx, target_attr, test_value)
            assert getattr(tx, target_attr) == test_value

            # Verification test
            if raise_exception:
                with pytest.raises(expected_exc):
                    verify_func(tx)
            else:
                tv.exceptions.clear()
                assert not tv.exceptions
                verify_func(tx)
                assert isinstance(tv.exceptions[0], expected_exc)

    @pytest.mark.parametrize("raise_exception", [True, False])
    @pytest.mark.parametrize("expected_exc, target_attr, fake_value", [
        (TransactionInvalidHashError, "hash", Hash32.new()),
        (TransactionInvalidSignatureError, "signature", Signature.new()),
    ])
    def test_verify_success_and_no_exc_with_fake_value_at_second(
            self, tx_version, tx_factory: 'TxFactory', raise_exception,
            expected_exc, target_attr, fake_value, monkeypatch):
        """Check that the result is successfully cached and bypasses further verifications which could raise exceptions.

        Do not apply this usecase in code!
        This test aims the reliablity of cache logic, not for the usefulness of this case.
        """
        tx = tx_factory(tx_version)
        tv = TransactionVerifier.new(tx.version,
                                     tx.type(),
                                     tx_versioner,
                                     raise_exceptions=raise_exception)
        verify_func = getattr(tv, f"verify_{target_attr}")

        # First verification
        verify_func(tx)

        # Monkeypatch with fake value
        object.__setattr__(tx, target_attr, fake_value)
        assert getattr(tx, target_attr) == fake_value

        # Verify again with fake value and ensure no exceptions raised
        if raise_exception:
            verify_func(tx)
        else:
            tv.exceptions.clear()
            assert not tv.exceptions
            verify_func(tx)
            assert not tv.exceptions

    @pytest.mark.parametrize("tag", ["before_cache", "after_cache"])
    @pytest.mark.parametrize("target_attr", ["hash", "signature"])
    def test_benchmark_verify(self, benchmark, tx_version,
                              tx_factory: 'TxFactory', target_attr, tag):
        """Benchmark the elapsed time of verification func in various cases."""
        tx = tx_factory(tx_version)
        tv = TransactionVerifier.new(tx.version, tx.type(), tx_versioner)
        verify_func = getattr(tv, f"verify_{target_attr}")

        if tag == "first":
            benchmark(verify_func, tx)
        else:
            verify_func(tx)
            benchmark(verify_func, tx)
コード例 #17
0
    def sign(self):
        if self.hash is None:
            self.build_hash()

        self.signature = Signature(self.signer.sign_hash(self.hash))
        return self.signature