class TestIdentityObserver():
    def __init__(self):
        self._identity_view_factory = MockIdentityViewFactory()
        self._identity_cache = IdentityCache(
            self._identity_view_factory)
        self._identity_obsever = IdentityObserver(
            to_update=self._identity_cache.invalidate,
            forked=self._identity_cache.forked
        )

        # Make sure IdentityCache has populated roles and policy
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role(
            "network",
            "policy1")
        self._identity_cache.get_role("network", "state_root")
        self._identity_cache.get_policy("policy1", "state_root")

    def _current_root_func(self):
        return "0000000000000000000000"

    def create_block(self, previous_block_id="0000000000000000"):
        block_header = BlockHeader(
            block_num=85,
            state_root_hash="0987654321fedcba",
            previous_block_id=previous_block_id)
        block = BlockWrapper(
            Block(
                header_signature="abcdef1234567890",
                header=block_header.SerializeToString()))
        return block
Beispiel #2
0
 def setUp(self):
     self.private_key = signing.generate_private_key()
     self.public_key = signing.generate_public_key(self.private_key)
     self._identity_view_factory = MockIdentityViewFactory()
     self.permissions = {}
     self._identity_cache = IdentityCache(self._identity_view_factory,
                                          self._current_root_func)
     self.permission_verifier = \
         PermissionVerifier(
             permissions=self.permissions,
             current_root_func=self._current_root_func,
             identity_cache=self._identity_cache)
Beispiel #3
0
    def setUp(self):
        self._identity_view_factory = MockIdentityViewFactory()
        self._identity_cache = IdentityCache(self._identity_view_factory)
        self._identity_obsever = IdentityObserver(
            to_update=self._identity_cache.invalidate,
            forked=self._identity_cache.forked)

        # Make sure IdentityCache has populated roles and policy
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role("network", "policy1")
        self._identity_cache.get_role("network", lambda: "state_root")
        self._identity_cache.get_policy("policy1", lambda: "state_root")
Beispiel #4
0
 def setUp(self):
     context = create_context('secp256k1')
     crypto_factory = CryptoFactory(context)
     private_key = context.new_random_private_key()
     self.signer = crypto_factory.new_signer(private_key)
     self._identity_view_factory = MockIdentityViewFactory()
     self.permissions = {}
     self._identity_cache = IdentityCache(self._identity_view_factory)
     self.permission_verifier = \
         PermissionVerifier(
             permissions=self.permissions,
             current_root_func=self._current_root_func,
             identity_cache=self._identity_cache)
Beispiel #5
0
 def setUp(self):
     context = create_context('secp256k1')
     crypto_factory = CryptoFactory(context)
     private_key = context.new_random_private_key()
     self.signer = crypto_factory.new_signer(private_key)
     self._identity_view_factory = MockIdentityViewFactory()
     self.permissions = {}
     self._identity_cache = IdentityCache(
         self._identity_view_factory)
     self.permission_verifier = \
         PermissionVerifier(
             permissions=self.permissions,
             current_root_func=self._current_root_func,
             identity_cache=self._identity_cache)
Beispiel #6
0
    def setUp(self):
        self._identity_view_factory = MockIdentityViewFactory()
        self._identity_cache = IdentityCache(
            self._identity_view_factory)
        self._identity_obsever = IdentityObserver(
            to_update=self._identity_cache.invalidate,
            forked=self._identity_cache.forked
        )

        # Make sure IdentityCache has populated roles and policy
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role(
            "network",
            "policy1")
        self._identity_cache.get_role("network", "state_root")
        self._identity_cache.get_policy("policy1", "state_root")
Beispiel #7
0
class TestIdentityCache(unittest.TestCase):
    def setUp(self):
        self._identity_view_factory = MockIdentityViewFactory()
        self._identity_cache = IdentityCache(self._identity_view_factory,
                                             self._current_root_func)

    def _current_root_func(self):
        return "0000000000000000000000"

    def test_get_role(self):
        """
        Test that a role can be fetched from the state.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role("network", "policy1")
        self.assertIsNone(self._identity_cache["network"])

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")
        self.assertEquals(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))

    def test_get_policy(self):
        """
        Test that a policy can be fetched from the state.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role("network", "policy1")
        self.assertIsNone(self._identity_cache["policy1"])

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")
        self.assertEquals(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))

    def test_role_invalidate(self):
        """
        Test that a role can be invalidated.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role("network", "policy1")
        self._identity_cache.invalidate("network")
        self.assertEquals(self._identity_cache["network"], None)

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")
        self.assertEquals(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))

    def test_policy_invalidate(self):
        """
        Test that a policy can be invalidated.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role("network", "policy1")
        self._identity_cache.invalidate("policy1")
        self.assertEqual(self._identity_cache["policy1"], None)

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")
        self.assertEquals(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))

    def test_forked(self):
        """
        Test that forked() invalidates all items in the cache, and they can
        be fetched from state.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role("network", "policy1")

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")

        self._identity_cache.get_policy("policy1", "state_root")
        self._identity_cache.get_role("network", "state_root")

        self.assertEquals(len(self._identity_cache), 2)
        self._identity_cache.forked()

        self.assertEquals(self._identity_cache["network"], None)
        self.assertEquals(self._identity_cache["policy1"], None)

        self.assertEquals(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))

        self.assertEquals(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))
Beispiel #8
0
class TestIdentityObserver(unittest.TestCase):
    def setUp(self):
        self._identity_view_factory = MockIdentityViewFactory()
        self._identity_cache = IdentityCache(self._identity_view_factory,
                                             self._current_root_func)
        self._identity_obsever = IdentityObserver(
            to_update=self._identity_cache.invalidate,
            forked=self._identity_cache.forked)

        # Make sure IdentityCache has populated roles and policy
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role("network", "policy1")
        self._identity_cache.get_role("network", "state_root")
        self._identity_cache.get_policy("policy1", "state_root")

    def _current_root_func(self):
        return "0000000000000000000000"

    def create_block(self, previous_block_id="0000000000000000"):
        block_header = BlockHeader(block_num=85,
                                   state_root_hash="0987654321fedcba",
                                   previous_block_id=previous_block_id)
        block = BlockWrapper(
            Block(header_signature="abcdef1234567890",
                  header=block_header.SerializeToString()))
        return block

    def test_chain_update(self):
        """
        Test that if there is no fork and only one value is udpated, only
        that value is in validated in the catch.
        """
        # Set up cache so it does not fork
        block1 = self.create_block()
        self._identity_obsever.chain_update(block1, [])
        self._identity_cache.get_role("network", "state_root")
        self._identity_cache.get_policy("policy1", "state_root")
        self.assertNotEqual(self._identity_cache["network"], None)
        self.assertNotEqual(self._identity_cache["policy1"], None)

        # Add next block and event that says network was updated.
        block2 = self.create_block("abcdef1234567890")
        event = Event(
            event_type="identity_update",
            attributes=[Event.Attribute(key="updated", value="network")])
        receipts = TransactionReceipt(events=[event])
        self._identity_obsever.chain_update(block2, [receipts])
        # Check that only "network" was invalidated
        self.assertEquals(self._identity_cache["network"], None)
        self.assertNotEqual(self._identity_cache["policy1"], None)

        # check that the correct values can be fetched from state.
        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")

        self.assertEquals(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))

        self.assertEquals(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))

    def test_fork(self):
        """
        Test that if there is a fork, all values in the cache will be
        invalidated and fetched from state.
        """
        block = self.create_block()
        self._identity_obsever.chain_update(block, [])
        # Check that all items are invalid
        for key in self._identity_cache:
            self.assertEquals(self._identity_cache[key], None)

        # Check that the items can be fetched from state.
        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")

        self.assertEquals(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))

        self.assertEquals(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))
Beispiel #9
0
class TestPermissionVerifier(unittest.TestCase):
    def setUp(self):
        self.private_key = signing.generate_private_key()
        self.public_key = signing.generate_public_key(self.private_key)
        self._identity_view_factory = MockIdentityViewFactory()
        self.permissions = {}
        self._identity_cache = IdentityCache(self._identity_view_factory,
                                             self._current_root_func)
        self.permission_verifier = \
            PermissionVerifier(
                permissions=self.permissions,
                current_root_func=self._current_root_func,
                identity_cache=self._identity_cache)

    def _current_root_func(self):
        return "0000000000000000000000"

    def _create_transactions(self, count):
        txn_list = []
        for i in range(count):
            payload = {'Verb': 'set', 'Name': 'name', 'Value': 1}
            intkey_prefix = \
                hashlib.sha512('intkey'.encode('utf-8')).hexdigest()[0:6]

            addr = intkey_prefix + \
                hashlib.sha512(payload["Name"].encode('utf-8')).hexdigest()

            payload_encode = hashlib.sha512(cbor.dumps(payload)).hexdigest()

            header = TransactionHeader(signer_public_key=self.public_key,
                                       family_name='intkey',
                                       family_version='1.0',
                                       inputs=[addr],
                                       outputs=[addr],
                                       dependencies=[],
                                       payload_sha512=payload_encode)

            header.batcher_public_key = self.public_key

            header_bytes = header.SerializeToString()

            signature = signing.sign(header_bytes, self.private_key)

            transaction = Transaction(header=header_bytes,
                                      payload=cbor.dumps(payload),
                                      header_signature=signature)

            txn_list.append(transaction)

        return txn_list

    def _create_batches(self, batch_count, txn_count):

        batch_list = []

        for i in range(batch_count):
            txn_list = self._create_transactions(txn_count)
            txn_sig_list = [txn.header_signature for txn in txn_list]

            batch_header = BatchHeader(signer_public_key=self.public_key)
            batch_header.transaction_ids.extend(txn_sig_list)

            header_bytes = batch_header.SerializeToString()

            signature = signing.sign(header_bytes, self.private_key)

            batch = Batch(header=header_bytes,
                          transactions=txn_list,
                          header_signature=signature)

            batch_list.append(batch)

        return batch_list

    def test_permission(self):
        """
        Test that if no roles are set and no default policy is set,
        permit all is used.
        """
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

    def test_default_policy_permission(self):
        """
        Test that if no roles are set, the default policy is used.
            1. Set default policy to permit all. Batch should be allowed.
            2. Set default policy to deny all. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("default", ["PERMIT_KEY *"])
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("default", ["DENY_KEY *"])
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_transactor_role(self):
        """
        Test that role:"transactor" is checked properly.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY " +  \
                                               self.public_key])
        self._identity_view_factory.add_role("transactor", "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role("transactor", "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_transactor_batch_signer(self):
        """
        Test that role: "transactor.batch_signer" is checked properly.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY " +  \
                                               self.public_key])
        self._identity_view_factory.add_role("transactor.batch_signer",
                                             "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role("transactor.batch_signer",
                                             "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_transactor_transaction_signer(self):
        """
        Test that role: "transactor.transaction_signer" is checked properly.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY " +  \
                                               self.public_key])
        self._identity_view_factory.add_role("transactor.transaction_signer",
                                             "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role("transactor.transaction_signer",
                                             "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_transactor_transaction_siger_transaction_family(self):
        """
        Test that role: "transactor.transaction_signer.intkey" is checked
        properly.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY " +  \
                                               self.public_key])
        self._identity_view_factory.add_role(
            "transactor.transaction_signer.intkey", "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role(
            "transactor.transaction_signer.intkey", "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_off_chain_permissions(self):
        """
        Test that if permissions are empty all signers are permitted.
        """
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

    def test_off_chain_transactor(self):
        """
        Test that role:"transactor" is checked properly if in permissions.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        policy = make_policy("policy1", ["PERMIT_KEY " + self.public_key])
        self.permissions["transactor"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

        policy = make_policy("policy1", ["PERMIT_KEY other"])
        self.permissions["transactor"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertFalse(allowed)

    def test_off_chain_transactor_batch_signer(self):
        """
        Test that role:"transactor.batch_signer" is checked properly if in
        permissions.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        policy = make_policy("policy1", ["PERMIT_KEY " + self.public_key])
        self.permissions["transactor.batch_signer"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

        policy = make_policy("policy1", ["PERMIT_KEY other"])
        self.permissions["transactor.batch_signer"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertFalse(allowed)

    def test_off_chain_transactor_transaction_signer(self):
        """
        Test that role:"transactor.transaction_signer" is checked properly if in
        permissions.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        policy = make_policy("policy1", ["PERMIT_KEY " + self.public_key])
        self.permissions["transactor.transaction_signer"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

        policy = make_policy("policy1", ["PERMIT_KEY other"])
        self.permissions["transactor.transaction_signer"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertFalse(allowed)

    def test_off_chain_transactor_transaction_signer_family(self):
        """
        Test that role:"transactor.transaction_signer.intkey" is checked
        properly if in permissions.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        policy = make_policy("policy1", ["PERMIT_KEY " + self.public_key])
        self.permissions["transactor.transaction_signer.intkey"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

        policy = make_policy("policy1", ["PERMIT_KEY other"])
        self.permissions["transactor.transaction_signer.intkey"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertFalse(allowed)

    def test_network(self):
        """
        Test that if no roles are set and no default policy is set,
        permit all is used.
        """
        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertTrue(allowed)

    def test_network_default(self):
        """
        Test that if no roles are set, the default policy is used.
            1. Set default policy to permit all. Public key should be allowed.
            2. Set default policy to deny all. Public key should be rejected.
        """
        self._identity_view_factory.add_policy("default", ["PERMIT_KEY *"])
        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("default", ["DENY_KEY *"])
        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertFalse(allowed)

    def test_network_role(self):
        """
        Test that role:"network" is checked properly.
            1. Set policy to permit signing key. Public key should be allowed.
            2. Set policy to permit some other key. Public key should be
                rejected.
        """
        self._identity_view_factory.add_policy(
            "policy1", ["PERMIT_KEY " + self.public_key])

        self._identity_view_factory.add_role("network", "policy1")

        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy2", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role("network", "policy2")
        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertFalse(allowed)

    def test_network_consensus(self):
        """
        Test that if no roles are set and no default policy is set,
        permit all is used.
        """
        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertTrue(allowed)

    def test_network_consensus_default(self):
        """
        Test that if no roles are set, the default policy is used.
            1. Set default policy to permit all. Public key should be allowed.
            2. Set default policy to deny all. Public key should be rejected.
        """
        self._identity_view_factory.add_policy("default", ["PERMIT_KEY *"])
        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("default", ["DENY_KEY *"])
        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertFalse(allowed)

    def test_network_consensus_role(self):
        """
        Test that role:"network.consensus" is checked properly.
            1. Set policy to permit signing key. Public key should be allowed.
            2. Set policy to permit some other key. Public key should be
                rejected.
        """
        self._identity_view_factory.add_policy(
            "policy1", ["PERMIT_KEY " + self.public_key])

        self._identity_view_factory.add_role("network.consensus", "policy1")

        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy2", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role("network.consensus", "policy2")
        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertFalse(allowed)
 def __init__(self):
     self._identity_view_factory = MockIdentityViewFactory()
     self._identity_cache = IdentityCache(
         self._identity_view_factory)
Beispiel #11
0
class TestIdentityCache(unittest.TestCase):
    def setUp(self):
        self._identity_view_factory = MockIdentityViewFactory()
        self._identity_cache = IdentityCache(
            self._identity_view_factory)

    def test_get_role(self):
        """
        Test that a role can be fetched from the state.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role(
            "network",
            "policy1")
        self.assertIsNone(self._identity_cache["network"])

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")
        self.assertEqual(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))

    def test_get_policy(self):
        """
        Test that a policy can be fetched from the state.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role(
            "network",
            "policy1")
        self.assertIsNone(self._identity_cache["policy1"])

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")
        self.assertEqual(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))

    def test_role_invalidate(self):
        """
        Test that a role can be invalidated.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role(
            "network",
            "policy1")
        self._identity_cache.invalidate("network")
        self.assertEqual(self._identity_cache["network"], None)

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")
        self.assertEqual(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))

    def test_policy_invalidate(self):
        """
        Test that a policy can be invalidated.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role(
            "network",
            "policy1")
        self._identity_cache.invalidate("policy1")
        self.assertEqual(self._identity_cache["policy1"], None)

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")
        self.assertEqual(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))

    def test_forked(self):
        """
        Test that forked() invalidates all items in the cache, and they can
        be fetched from state.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role(
            "network",
            "policy1")

        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")

        self._identity_cache.get_policy("policy1", "state_root")
        self._identity_cache.get_role("network", "state_root")

        self.assertEqual(len(self._identity_cache), 2)
        self._identity_cache.forked()

        self.assertEqual(self._identity_cache["network"], None)
        self.assertEqual(self._identity_cache["policy1"], None)

        self.assertEqual(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))

        self.assertEqual(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))
Beispiel #12
0
class TestIdentityObserver(unittest.TestCase):
    def setUp(self):
        self._identity_view_factory = MockIdentityViewFactory()
        self._identity_cache = IdentityCache(
            self._identity_view_factory)
        self._identity_obsever = IdentityObserver(
            to_update=self._identity_cache.invalidate,
            forked=self._identity_cache.forked
        )

        # Make sure IdentityCache has populated roles and policy
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY key"])
        self._identity_view_factory.add_role(
            "network",
            "policy1")
        self._identity_cache.get_role("network", "state_root")
        self._identity_cache.get_policy("policy1", "state_root")

    def _current_root_func(self):
        return "0000000000000000000000"

    def create_block(self, previous_block_id="0000000000000000"):
        block_header = BlockHeader(
            block_num=85,
            state_root_hash="0987654321fedcba",
            previous_block_id=previous_block_id)
        block = BlockWrapper(
            Block(
                header_signature="abcdef1234567890",
                header=block_header.SerializeToString()))
        return block

    def test_chain_update(self):
        """
        Test that if there is no fork and only one value is udpated, only
        that value is in validated in the catch.
        """
        # Set up cache so it does not fork
        block1 = self.create_block()
        self._identity_obsever.chain_update(block1, [])
        self._identity_cache.get_role("network", "state_root")
        self._identity_cache.get_policy("policy1", "state_root")
        self.assertNotEqual(self._identity_cache["network"], None)
        self.assertNotEqual(self._identity_cache["policy1"], None)

        # Add next block and event that says network was updated.
        block2 = self.create_block("abcdef1234567890")
        event = Event(
            event_type="identity/update",
            attributes=[Event.Attribute(key="updated", value="network")])
        receipts = TransactionReceipt(events=[event])
        self._identity_obsever.chain_update(block2, [receipts])
        # Check that only "network" was invalidated
        self.assertEqual(self._identity_cache["network"], None)
        self.assertNotEqual(self._identity_cache["policy1"], None)

        # check that the correct values can be fetched from state.
        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")

        self.assertEqual(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))

        self.assertEqual(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))

    def test_fork(self):
        """
        Test that if there is a fork, all values in the cache will be
        invalidated and fetched from state.
        """
        block = self.create_block()
        self._identity_obsever.chain_update(block, [])
        # Check that all items are invalid
        for key in self._identity_cache:
            self.assertEqual(self._identity_cache[key], None)

        # Check that the items can be fetched from state.
        identity_view = \
            self._identity_view_factory.create_identity_view("state_root")

        self.assertEqual(
            self._identity_cache.get_role("network", "state_root"),
            identity_view.get_role("network"))

        self.assertEqual(
            self._identity_cache.get_policy("policy1", "state_root"),
            identity_view.get_policy("policy1"))
Beispiel #13
0
class TestPermissionVerifier(unittest.TestCase):
    def setUp(self):
        context = create_context('secp256k1')
        crypto_factory = CryptoFactory(context)
        private_key = context.new_random_private_key()
        self.signer = crypto_factory.new_signer(private_key)
        self._identity_view_factory = MockIdentityViewFactory()
        self.permissions = {}
        self._identity_cache = IdentityCache(
            self._identity_view_factory)
        self.permission_verifier = \
            PermissionVerifier(
                permissions=self.permissions,
                current_root_func=self._current_root_func,
                identity_cache=self._identity_cache)

    @property
    def public_key(self):
        return self.signer.get_public_key().as_hex()

    def _current_root_func(self):
        return "0000000000000000000000"

    def _create_transactions(self, count):
        txn_list = []

        for _ in range(count):
            payload = {
                'Verb': 'set',
                'Name': 'name',
                'Value': 1,
            }

            intkey_prefix = \
                hashlib.sha512('intkey'.encode('utf-8')).hexdigest()[0:6]

            addr = intkey_prefix + \
                hashlib.sha512(payload["Name"].encode('utf-8')).hexdigest()

            payload_encode = hashlib.sha512(cbor.dumps(payload)).hexdigest()

            header = TransactionHeader(
                signer_public_key=self.public_key,
                family_name='intkey',
                family_version='1.0',
                inputs=[addr],
                outputs=[addr],
                dependencies=[],
                payload_sha512=payload_encode)

            header.batcher_public_key = self.public_key

            header_bytes = header.SerializeToString()

            signature = self.signer.sign(header_bytes)

            transaction = Transaction(
                header=header_bytes,
                payload=cbor.dumps(payload),
                header_signature=signature)

            txn_list.append(transaction)

        return txn_list

    def _create_batches(self, batch_count, txn_count):

        batch_list = []

        for _ in range(batch_count):
            txn_list = self._create_transactions(txn_count)
            txn_sig_list = [txn.header_signature for txn in txn_list]

            batch_header = BatchHeader(
                signer_public_key=self.signer.get_public_key().as_hex())
            batch_header.transaction_ids.extend(txn_sig_list)

            header_bytes = batch_header.SerializeToString()

            signature = self.signer.sign(header_bytes)

            batch = Batch(
                header=header_bytes,
                transactions=txn_list,
                header_signature=signature)

            batch_list.append(batch)

        return batch_list

    def test_permission(self):
        """
        Test that if no roles are set and no default policy is set,
        permit all is used.
        """
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

    def test_default_policy_permission(self):
        """
        Test that if no roles are set, the default policy is used.
            1. Set default policy to permit all. Batch should be allowed.
            2. Set default policy to deny all. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("default", ["PERMIT_KEY *"])
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("default", ["DENY_KEY *"])
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_transactor_role(self):
        """
        Test that role:"transactor" is checked properly.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY " +
                                                           self.public_key])
        self._identity_view_factory.add_role("transactor", "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role("transactor", "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_transactor_batch_signer(self):
        """
        Test that role: "transactor.batch_signer" is checked properly.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY " +
                                                           self.public_key])
        self._identity_view_factory.add_role("transactor.batch_signer",
                                             "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role("transactor.batch_signer",
                                             "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_transactor_transaction_signer(self):
        """
        Test that role: "transactor.transaction_signer" is checked properly.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY " +
                                                           self.public_key])
        self._identity_view_factory.add_role("transactor.transaction_signer",
                                             "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role("transactor.transaction_signer",
                                             "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_transactor_transaction_siger_transaction_family(self):
        """
        Test that role: "transactor.transaction_signer.intkey" is checked
        properly.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY " +
                                                           self.public_key])
        self._identity_view_factory.add_role(
            "transactor.transaction_signer.intkey",
            "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy1", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role(
            "transactor.transaction_signer.intkey",
            "policy1")
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.is_batch_signer_authorized(batch)
        self.assertFalse(allowed)

    def test_off_chain_permissions(self):
        """
        Test that if permissions are empty all signers are permitted.
        """
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

    def test_off_chain_transactor(self):
        """
        Test that role:"transactor" is checked properly if in permissions.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        policy = make_policy("policy1", ["PERMIT_KEY " + self.public_key])
        self.permissions["transactor"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

        policy = make_policy("policy1", ["PERMIT_KEY other"])
        self.permissions["transactor"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertFalse(allowed)

    def test_off_chain_transactor_batch_signer(self):
        """
        Test that role:"transactor.batch_signer" is checked properly if in
        permissions.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        policy = make_policy("policy1", ["PERMIT_KEY " + self.public_key])
        self.permissions["transactor.batch_signer"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

        policy = make_policy("policy1", ["PERMIT_KEY other"])
        self.permissions["transactor.batch_signer"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertFalse(allowed)

    def test_off_chain_transactor_transaction_signer(self):
        """
        Test that role:"transactor.transaction_signer" is checked
        properly if in permissions.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.

        """
        policy = make_policy("policy1", ["PERMIT_KEY " + self.public_key])
        self.permissions["transactor.transaction_signer"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

        policy = make_policy("policy1", ["PERMIT_KEY other"])
        self.permissions["transactor.transaction_signer"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertFalse(allowed)

    def test_off_chain_transactor_transaction_signer_family(self):
        """
        Test that role:"transactor.transaction_signer.intkey" is checked
        properly if in permissions.
            1. Set policy to permit signing key. Batch should be allowed.
            2. Set policy to permit some other key. Batch should be rejected.
        """
        policy = make_policy("policy1", ["PERMIT_KEY " + self.public_key])
        self.permissions["transactor.transaction_signer.intkey"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertTrue(allowed)

        policy = make_policy("policy1", ["PERMIT_KEY other"])
        self.permissions["transactor.transaction_signer.intkey"] = policy
        batch = self._create_batches(1, 1)[0]
        allowed = self.permission_verifier.check_off_chain_batch_roles(batch)
        self.assertFalse(allowed)

    def test_network(self):
        """
        Test that if no roles are set and no default policy is set,
        permit all is used.
        """
        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertTrue(allowed)

    def test_network_default(self):
        """
        Test that if no roles are set, the default policy is used.
            1. Set default policy to permit all. Public key should be allowed.
            2. Set default policy to deny all. Public key should be rejected.
        """
        self._identity_view_factory.add_policy("default", ["PERMIT_KEY *"])
        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("default", ["DENY_KEY *"])
        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertFalse(allowed)

    def test_network_role(self):
        """
        Test that role:"network" is checked properly.
            1. Set policy to permit signing key. Public key should be allowed.
            2. Set policy to permit some other key. Public key should be
                rejected.
        """
        self._identity_view_factory.add_policy(
            "policy1", ["PERMIT_KEY " + self.public_key])

        self._identity_view_factory.add_role(
            "network",
            "policy1")

        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy2", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role(
            "network",
            "policy2")
        allowed = self.permission_verifier.check_network_role(self.public_key)
        self.assertFalse(allowed)

    def test_network_consensus(self):
        """
        Test that if no roles are set and no default policy is set,
        permit all is used.
        """
        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertTrue(allowed)

    def test_network_consensus_default(self):
        """
        Test that if no roles are set, the default policy is used.
            1. Set default policy to permit all. Public key should be allowed.
            2. Set default policy to deny all. Public key should be rejected.
        """
        self._identity_view_factory.add_policy("default", ["PERMIT_KEY *"])
        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("default", ["DENY_KEY *"])
        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertFalse(allowed)

    def test_network_consensus_role(self):
        """
        Test that role:"network.consensus" is checked properly.
            1. Set policy to permit signing key. Public key should be allowed.
            2. Set policy to permit some other key. Public key should be
                rejected.
        """
        self._identity_view_factory.add_policy(
            "policy1", ["PERMIT_KEY " + self.public_key])

        self._identity_view_factory.add_role(
            "network.consensus",
            "policy1")

        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertTrue(allowed)

        self._identity_cache.forked()
        self._identity_view_factory.add_policy("policy2", ["PERMIT_KEY other"])
        self._identity_view_factory.add_role(
            "network.consensus",
            "policy2")
        allowed = self.permission_verifier.check_network_consensus_role(
            self.public_key)
        self.assertFalse(allowed)
Beispiel #14
0
    def __init__(self,
                 bind_network,
                 bind_component,
                 endpoint,
                 peering,
                 seeds_list,
                 peer_list,
                 data_dir,
                 config_dir,
                 identity_signing_key,
                 scheduler_type,
                 permissions,
                 network_public_key=None,
                 network_private_key=None,
                 roles=None,
                 metrics_registry=None):
        """Constructs a validator instance.

        Args:
            bind_network (str): the network endpoint
            bind_component (str): the component endpoint
            endpoint (str): the zmq-style URI of this validator's
                publically reachable endpoint
            peering (str): The type of peering approach. Either 'static'
                or 'dynamic'. In 'static' mode, no attempted topology
                buildout occurs -- the validator only attempts to initiate
                peering connections with endpoints specified in the
                peer_list. In 'dynamic' mode, the validator will first
                attempt to initiate peering connections with endpoints
                specified in the peer_list and then attempt to do a
                topology buildout starting with peer lists obtained from
                endpoints in the seeds_list. In either mode, the validator
                will accept incoming peer requests up to max_peers.
            seeds_list (list of str): a list of addresses to connect
                to in order to perform the initial topology buildout
            peer_list (list of str): a list of peer addresses
            data_dir (str): path to the data directory
            config_dir (str): path to the config directory
            identity_signing_key (str): key validator uses for signing
        """
        db_filename = os.path.join(data_dir,
                                   'merkle-{}.lmdb'.format(bind_network[-2:]))
        LOGGER.debug('database file is %s', db_filename)

        merkle_db = LMDBNoLockDatabase(db_filename, 'c')

        delta_db_filename = os.path.join(
            data_dir, 'state-deltas-{}.lmdb'.format(bind_network[-2:]))
        LOGGER.debug('state delta store file is %s', delta_db_filename)
        state_delta_db = LMDBNoLockDatabase(delta_db_filename, 'c')

        receipt_db_filename = os.path.join(
            data_dir, 'txn_receipts-{}.lmdb'.format(bind_network[-2:]))
        LOGGER.debug('txn receipt store file is %s', receipt_db_filename)
        receipt_db = LMDBNoLockDatabase(receipt_db_filename, 'c')

        state_delta_store = StateDeltaStore(state_delta_db)
        receipt_store = TransactionReceiptStore(receipt_db)

        context_manager = ContextManager(merkle_db, state_delta_store)
        self._context_manager = context_manager

        state_view_factory = StateViewFactory(merkle_db)

        block_db_filename = os.path.join(
            data_dir, 'block-{}.lmdb'.format(bind_network[-2:]))
        LOGGER.debug('block store file is %s', block_db_filename)

        block_db = LMDBNoLockDatabase(block_db_filename, 'c')
        block_store = BlockStore(block_db)

        batch_tracker = BatchTracker(block_store)

        # setup network
        self._dispatcher = Dispatcher(metrics_registry=metrics_registry)

        thread_pool = ThreadPoolExecutor(max_workers=10)
        sig_pool = ThreadPoolExecutor(max_workers=3)

        self._thread_pool = thread_pool
        self._sig_pool = sig_pool

        self._service = Interconnect(bind_component,
                                     self._dispatcher,
                                     secured=False,
                                     heartbeat=False,
                                     max_incoming_connections=20,
                                     monitor=True,
                                     max_future_callback_workers=10,
                                     metrics_registry=metrics_registry)

        executor = TransactionExecutor(
            service=self._service,
            context_manager=context_manager,
            settings_view_factory=SettingsViewFactory(
                StateViewFactory(merkle_db)),
            scheduler_type=scheduler_type,
            invalid_observers=[batch_tracker],
            metrics_registry=metrics_registry)

        self._executor = executor
        self._service.set_check_connections(executor.check_connections)

        state_delta_processor = StateDeltaProcessor(self._service,
                                                    state_delta_store,
                                                    block_store)
        event_broadcaster = EventBroadcaster(self._service, block_store,
                                             receipt_store)

        zmq_identity = hashlib.sha512(
            time.time().hex().encode()).hexdigest()[:23]

        network_thread_pool = ThreadPoolExecutor(max_workers=10)
        self._network_thread_pool = network_thread_pool

        self._network_dispatcher = Dispatcher(
            metrics_registry=metrics_registry)

        secure = False
        if network_public_key is not None and network_private_key is not None:
            secure = True

        self._network = Interconnect(
            bind_network,
            dispatcher=self._network_dispatcher,
            zmq_identity=zmq_identity,
            secured=secure,
            server_public_key=network_public_key,
            server_private_key=network_private_key,
            heartbeat=True,
            public_endpoint=endpoint,
            connection_timeout=30,
            max_incoming_connections=100,
            max_future_callback_workers=10,
            authorize=True,
            public_key=signing.generate_pubkey(identity_signing_key),
            priv_key=identity_signing_key,
            roles=roles,
            metrics_registry=metrics_registry)

        self._gossip = Gossip(self._network,
                              endpoint=endpoint,
                              peering_mode=peering,
                              initial_seed_endpoints=seeds_list,
                              initial_peer_endpoints=peer_list,
                              minimum_peer_connectivity=3,
                              maximum_peer_connectivity=10,
                              topology_check_frequency=1)

        completer = Completer(block_store, self._gossip)

        block_sender = BroadcastBlockSender(completer, self._gossip)
        batch_sender = BroadcastBatchSender(completer, self._gossip)
        chain_id_manager = ChainIdManager(data_dir)

        identity_view_factory = IdentityViewFactory(
            StateViewFactory(merkle_db))

        id_cache = IdentityCache(identity_view_factory,
                                 block_store.chain_head_state_root)

        permission_verifier = PermissionVerifier(
            permissions, block_store.chain_head_state_root, id_cache)

        identity_observer = IdentityObserver(to_update=id_cache.invalidate,
                                             forked=id_cache.forked)

        # Create and configure journal
        self._journal = Journal(
            block_store=block_store,
            state_view_factory=StateViewFactory(merkle_db),
            block_sender=block_sender,
            batch_sender=batch_sender,
            transaction_executor=executor,
            squash_handler=context_manager.get_squash_handler(),
            identity_signing_key=identity_signing_key,
            chain_id_manager=chain_id_manager,
            data_dir=data_dir,
            config_dir=config_dir,
            permission_verifier=permission_verifier,
            check_publish_block_frequency=0.1,
            block_cache_purge_frequency=30,
            block_cache_keep_time=300,
            batch_observers=[batch_tracker],
            chain_observers=[
                state_delta_processor, event_broadcaster, receipt_store,
                batch_tracker, identity_observer
            ],
            metrics_registry=metrics_registry)

        self._genesis_controller = GenesisController(
            context_manager=context_manager,
            transaction_executor=executor,
            completer=completer,
            block_store=block_store,
            state_view_factory=state_view_factory,
            identity_key=identity_signing_key,
            data_dir=data_dir,
            config_dir=config_dir,
            chain_id_manager=chain_id_manager,
            batch_sender=batch_sender)

        responder = Responder(completer)

        completer.set_on_batch_received(self._journal.on_batch_received)
        completer.set_on_block_received(self._journal.on_block_received)

        self._dispatcher.add_handler(
            validator_pb2.Message.TP_ADD_RECEIPT_DATA_REQUEST,
            tp_state_handlers.TpAddReceiptDataHandler(context_manager),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.TP_ADD_EVENT_REQUEST,
            tp_state_handlers.TpAddEventHandler(context_manager), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.TP_STATE_DEL_REQUEST,
            tp_state_handlers.TpStateDeleteHandler(context_manager),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.TP_STATE_GET_REQUEST,
            tp_state_handlers.TpStateGetHandler(context_manager), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.TP_STATE_SET_REQUEST,
            tp_state_handlers.TpStateSetHandler(context_manager), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.TP_REGISTER_REQUEST,
            processor_handlers.ProcessorRegisterHandler(executor.processors),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.TP_UNREGISTER_REQUEST,
            processor_handlers.ProcessorUnRegisterHandler(executor.processors),
            thread_pool)

        # Set up base network handlers
        self._network_dispatcher.add_handler(
            validator_pb2.Message.NETWORK_PING,
            PingHandler(network=self._network), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.NETWORK_CONNECT,
            ConnectHandler(network=self._network), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.NETWORK_DISCONNECT,
            DisconnectHandler(network=self._network), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.AUTHORIZATION_VIOLATION,
            AuthorizationViolationHandler(network=self._network,
                                          gossip=self._gossip),
            network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.AUTHORIZATION_TRUST_REQUEST,
            AuthorizationTrustRequestHandler(
                network=self._network,
                permission_verifier=permission_verifier,
                gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.AUTHORIZATION_CHALLENGE_REQUEST,
            AuthorizationChallengeRequestHandler(network=self._network),
            network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.AUTHORIZATION_CHALLENGE_SUBMIT,
            AuthorizationChallengeSubmitHandler(
                network=self._network,
                permission_verifier=permission_verifier,
                gossip=self._gossip), network_thread_pool)

        # Set up gossip handlers
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_GET_PEERS_REQUEST,
            NetworkPermissionHandler(network=self._network,
                                     permission_verifier=permission_verifier,
                                     gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_GET_PEERS_REQUEST,
            GetPeersRequestHandler(gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_GET_PEERS_RESPONSE,
            NetworkPermissionHandler(network=self._network,
                                     permission_verifier=permission_verifier,
                                     gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_GET_PEERS_RESPONSE,
            GetPeersResponseHandler(gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_REGISTER,
            NetworkPermissionHandler(network=self._network,
                                     permission_verifier=permission_verifier,
                                     gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_REGISTER,
            PeerRegisterHandler(gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_UNREGISTER,
            PeerUnregisterHandler(gossip=self._gossip), network_thread_pool)

        # GOSSIP_MESSAGE 1) Sends acknowledgement to the sender
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_MESSAGE, GossipMessageHandler(),
            network_thread_pool)

        # GOSSIP_MESSAGE 2) Verify Network Permissions
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_MESSAGE,
            NetworkPermissionHandler(network=self._network,
                                     permission_verifier=permission_verifier,
                                     gossip=self._gossip), network_thread_pool)

        # GOSSIP_MESSAGE 3) Verifies signature
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_MESSAGE,
            signature_verifier.GossipMessageSignatureVerifier(), sig_pool)

        # GOSSIP_MESSAGE 4) Verifies batch structure
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_MESSAGE,
            structure_verifier.GossipHandlerStructureVerifier(),
            network_thread_pool)

        # GOSSIP_MESSAGE 4) Verifies that the node is allowed to publish a
        # block
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_MESSAGE,
            NetworkConsensusPermissionHandler(
                network=self._network,
                permission_verifier=permission_verifier,
                gossip=self._gossip), network_thread_pool)

        # GOSSIP_MESSAGE 5) Determines if we should broadcast the
        # message to our peers. It is important that this occur prior
        # to the sending of the message to the completer, as this step
        # relies on whether the  gossip message has previously been
        # seen by the validator to determine whether or not forwarding
        # should occur
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_MESSAGE,
            GossipBroadcastHandler(gossip=self._gossip, completer=completer),
            network_thread_pool)

        # GOSSIP_MESSAGE 6) Send message to completer
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_MESSAGE,
            CompleterGossipHandler(completer), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BLOCK_REQUEST,
            NetworkPermissionHandler(network=self._network,
                                     permission_verifier=permission_verifier,
                                     gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BLOCK_REQUEST,
            BlockResponderHandler(responder, self._gossip),
            network_thread_pool)

        # GOSSIP_BLOCK_RESPONSE 1) Sends ack to the sender
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
            GossipBlockResponseHandler(), network_thread_pool)

        # GOSSIP_MESSAGE 2) Verify Network Permissions
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
            NetworkPermissionHandler(network=self._network,
                                     permission_verifier=permission_verifier,
                                     gossip=self._gossip), network_thread_pool)

        # GOSSIP_BLOCK_RESPONSE 3) Verifies signature
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
            signature_verifier.GossipBlockResponseSignatureVerifier(),
            sig_pool)

        # GOSSIP_BLOCK_RESPONSE 4) Check batch structure
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
            structure_verifier.GossipBlockResponseStructureVerifier(),
            network_thread_pool)

        # GOSSIP_BLOCK_RESPONSE 5) Send message to completer
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
            CompleterGossipBlockResponseHandler(completer),
            network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
            ResponderBlockResponseHandler(responder, self._gossip),
            network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST,
            NetworkPermissionHandler(network=self._network,
                                     permission_verifier=permission_verifier,
                                     gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST,
            BatchByBatchIdResponderHandler(responder, self._gossip),
            network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_BY_TRANSACTION_ID_REQUEST,
            NetworkPermissionHandler(network=self._network,
                                     permission_verifier=permission_verifier,
                                     gossip=self._gossip), network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_BY_TRANSACTION_ID_REQUEST,
            BatchByTransactionIdResponderHandler(responder, self._gossip),
            network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
            NetworkPermissionHandler(network=self._network,
                                     permission_verifier=permission_verifier,
                                     gossip=self._gossip), network_thread_pool)

        # GOSSIP_BATCH_RESPONSE 1) Sends ack to the sender
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
            GossipBatchResponseHandler(), network_thread_pool)

        # GOSSIP_BATCH_RESPONSE 2) Verifies signature
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
            signature_verifier.GossipBatchResponseSignatureVerifier(),
            sig_pool)

        # GOSSIP_BATCH_RESPONSE 3) Check batch structure
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
            structure_verifier.GossipBatchResponseStructureVerifier(),
            network_thread_pool)

        # GOSSIP_BATCH_RESPONSE 4) Send message to completer
        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
            CompleterGossipBatchResponseHandler(completer),
            network_thread_pool)

        self._network_dispatcher.add_handler(
            validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
            ResponderBatchResponseHandler(responder, self._gossip),
            network_thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST,
            BatchListPermissionVerifier(
                permission_verifier=permission_verifier), sig_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST,
            signature_verifier.BatchListSignatureVerifier(), sig_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST,
            structure_verifier.BatchListStructureVerifier(),
            network_thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST,
            CompleterBatchListBroadcastHandler(completer, self._gossip),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST,
            client_handlers.BatchSubmitFinisher(batch_tracker), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BATCH_STATUS_REQUEST,
            client_handlers.BatchStatusRequest(batch_tracker), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_STATE_LIST_REQUEST,
            client_handlers.StateListRequest(merkle_db,
                                             self._journal.get_block_store()),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_STATE_GET_REQUEST,
            client_handlers.StateGetRequest(merkle_db,
                                            self._journal.get_block_store()),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BLOCK_LIST_REQUEST,
            client_handlers.BlockListRequest(self._journal.get_block_store()),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BLOCK_GET_REQUEST,
            client_handlers.BlockGetRequest(self._journal.get_block_store()),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BATCH_LIST_REQUEST,
            client_handlers.BatchListRequest(self._journal.get_block_store()),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_BATCH_GET_REQUEST,
            client_handlers.BatchGetRequest(self._journal.get_block_store()),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_TRANSACTION_LIST_REQUEST,
            client_handlers.TransactionListRequest(
                self._journal.get_block_store()), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_TRANSACTION_GET_REQUEST,
            client_handlers.TransactionGetRequest(
                self._journal.get_block_store()), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_STATE_CURRENT_REQUEST,
            client_handlers.StateCurrentRequest(
                self._journal.get_current_root), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_RECEIPT_GET_REQUEST,
            ClientReceiptGetRequestHandler(receipt_store), thread_pool)

        # State Delta Subscription Handlers
        self._dispatcher.add_handler(
            validator_pb2.Message.STATE_DELTA_SUBSCRIBE_REQUEST,
            StateDeltaSubscriberValidationHandler(state_delta_processor),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.STATE_DELTA_SUBSCRIBE_REQUEST,
            StateDeltaAddSubscriberHandler(state_delta_processor), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.STATE_DELTA_UNSUBSCRIBE_REQUEST,
            StateDeltaUnsubscriberHandler(state_delta_processor), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.STATE_DELTA_GET_EVENTS_REQUEST,
            StateDeltaGetEventsHandler(block_store, state_delta_store),
            thread_pool)

        # Client Events Handlers
        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_EVENTS_SUBSCRIBE_REQUEST,
            ClientEventsSubscribeValidationHandler(event_broadcaster),
            thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_EVENTS_SUBSCRIBE_REQUEST,
            ClientEventsSubscribeHandler(event_broadcaster), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_EVENTS_UNSUBSCRIBE_REQUEST,
            ClientEventsUnsubscribeHandler(event_broadcaster), thread_pool)

        self._dispatcher.add_handler(
            validator_pb2.Message.CLIENT_EVENTS_GET_REQUEST,
            ClientEventsGetRequestHandler(event_broadcaster), thread_pool)
Beispiel #15
0
 def setUp(self):
     self._identity_view_factory = MockIdentityViewFactory()
     self._identity_cache = IdentityCache(self._identity_view_factory)
Beispiel #16
0
 def setUp(self):
     self._identity_view_factory = MockIdentityViewFactory()
     self._identity_cache = IdentityCache(self._identity_view_factory,
                                          self._current_root_func)
Beispiel #17
0
    def __init__(self,
                 bind_network,
                 bind_component,
                 bind_consensus,
                 endpoint,
                 peering,
                 seeds_list,
                 peer_list,
                 data_dir,
                 config_dir,
                 identity_signer,
                 scheduler_type,
                 permissions,
                 minimum_peer_connectivity,
                 maximum_peer_connectivity,
                 state_pruning_block_depth,
                 network_public_key=None,
                 network_private_key=None,
                 roles=None):
        """Constructs a validator instance.

        Args:
            bind_network (str): the network endpoint
            bind_component (str): the component endpoint
            endpoint (str): the zmq-style URI of this validator's
                publically reachable endpoint
            peering (str): The type of peering approach. Either 'static'
                or 'dynamic'. In 'static' mode, no attempted topology
                buildout occurs -- the validator only attempts to initiate
                peering connections with endpoints specified in the
                peer_list. In 'dynamic' mode, the validator will first
                attempt to initiate peering connections with endpoints
                specified in the peer_list and then attempt to do a
                topology buildout starting with peer lists obtained from
                endpoints in the seeds_list. In either mode, the validator
                will accept incoming peer requests up to max_peers.
            seeds_list (list of str): a list of addresses to connect
                to in order to perform the initial topology buildout
            peer_list (list of str): a list of peer addresses
            data_dir (str): path to the data directory
            config_dir (str): path to the config directory
            identity_signer (str): cryptographic signer the validator uses for
                signing
        """
        # -- Setup Global State Database and Factory -- #
        global_state_db_filename = os.path.join(
            data_dir, 'merkle-{}.lmdb'.format(bind_network[-2:]))
        LOGGER.debug('global state database file is %s',
                     global_state_db_filename)
        global_state_db = NativeLmdbDatabase(
            global_state_db_filename,
            indexes=MerkleDatabase.create_index_configuration())
        state_view_factory = StateViewFactory(global_state_db)

        # -- Setup Receipt Store -- #
        receipt_db_filename = os.path.join(
            data_dir, 'txn_receipts-{}.lmdb'.format(bind_network[-2:]))
        LOGGER.debug('txn receipt store file is %s', receipt_db_filename)
        receipt_db = LMDBNoLockDatabase(receipt_db_filename, 'c')
        receipt_store = TransactionReceiptStore(receipt_db)

        # -- Setup Block Store -- #
        block_db_filename = os.path.join(
            data_dir, 'block-{}.lmdb'.format(bind_network[-2:]))
        LOGGER.debug('block store file is %s', block_db_filename)
        block_db = IndexedDatabase(
            block_db_filename,
            BlockStore.serialize_block,
            BlockStore.deserialize_block,
            flag='c',
            indexes=BlockStore.create_index_configuration())
        block_store = BlockStore(block_db)
        # The cache keep time for the journal's block cache must be greater
        # than the cache keep time used by the completer.
        base_keep_time = 1200
        block_cache = BlockCache(block_store,
                                 keep_time=int(base_keep_time * 9 / 8),
                                 purge_frequency=30)

        # -- Setup Thread Pools -- #
        component_thread_pool = InstrumentedThreadPoolExecutor(
            max_workers=10, name='Component')
        network_thread_pool = InstrumentedThreadPoolExecutor(max_workers=10,
                                                             name='Network')
        client_thread_pool = InstrumentedThreadPoolExecutor(max_workers=5,
                                                            name='Client')
        sig_pool = InstrumentedThreadPoolExecutor(max_workers=3,
                                                  name='Signature')

        # -- Setup Dispatchers -- #
        component_dispatcher = Dispatcher()
        network_dispatcher = Dispatcher()

        # -- Setup Services -- #
        component_service = Interconnect(bind_component,
                                         component_dispatcher,
                                         secured=False,
                                         heartbeat=False,
                                         max_incoming_connections=20,
                                         monitor=True,
                                         max_future_callback_workers=10)

        zmq_identity = hashlib.sha512(
            time.time().hex().encode()).hexdigest()[:23]

        secure = False
        if network_public_key is not None and network_private_key is not None:
            secure = True

        network_service = Interconnect(bind_network,
                                       dispatcher=network_dispatcher,
                                       zmq_identity=zmq_identity,
                                       secured=secure,
                                       server_public_key=network_public_key,
                                       server_private_key=network_private_key,
                                       heartbeat=True,
                                       public_endpoint=endpoint,
                                       connection_timeout=120,
                                       max_incoming_connections=100,
                                       max_future_callback_workers=10,
                                       authorize=True,
                                       signer=identity_signer,
                                       roles=roles)

        # -- Setup Transaction Execution Platform -- #
        context_manager = ContextManager(global_state_db)

        batch_tracker = BatchTracker(block_store)

        settings_cache = SettingsCache(
            SettingsViewFactory(state_view_factory), )

        transaction_executor = TransactionExecutor(
            service=component_service,
            context_manager=context_manager,
            settings_view_factory=SettingsViewFactory(state_view_factory),
            scheduler_type=scheduler_type,
            invalid_observers=[batch_tracker])

        component_service.set_check_connections(
            transaction_executor.check_connections)

        event_broadcaster = EventBroadcaster(component_service, block_store,
                                             receipt_store)

        # -- Setup P2P Networking -- #
        gossip = Gossip(network_service,
                        settings_cache,
                        lambda: block_store.chain_head,
                        block_store.chain_head_state_root,
                        endpoint=endpoint,
                        peering_mode=peering,
                        initial_seed_endpoints=seeds_list,
                        initial_peer_endpoints=peer_list,
                        minimum_peer_connectivity=minimum_peer_connectivity,
                        maximum_peer_connectivity=maximum_peer_connectivity,
                        topology_check_frequency=1)

        completer = Completer(block_store,
                              gossip,
                              cache_keep_time=base_keep_time,
                              cache_purge_frequency=30,
                              requested_keep_time=300)

        block_sender = BroadcastBlockSender(completer, gossip)
        batch_sender = BroadcastBatchSender(completer, gossip)
        chain_id_manager = ChainIdManager(data_dir)

        identity_view_factory = IdentityViewFactory(
            StateViewFactory(global_state_db))

        id_cache = IdentityCache(identity_view_factory)

        # -- Setup Permissioning -- #
        permission_verifier = PermissionVerifier(
            permissions, block_store.chain_head_state_root, id_cache)

        identity_observer = IdentityObserver(to_update=id_cache.invalidate,
                                             forked=id_cache.forked)

        settings_observer = SettingsObserver(
            to_update=settings_cache.invalidate, forked=settings_cache.forked)

        # -- Consensus Engine -- #
        consensus_thread_pool = InstrumentedThreadPoolExecutor(
            max_workers=3, name='Consensus')
        consensus_dispatcher = Dispatcher()
        consensus_service = Interconnect(bind_consensus,
                                         consensus_dispatcher,
                                         secured=False,
                                         heartbeat=False,
                                         max_incoming_connections=20,
                                         monitor=True,
                                         max_future_callback_workers=10)

        consensus_notifier = ConsensusNotifier(consensus_service)

        # -- Setup Journal -- #
        batch_injector_factory = DefaultBatchInjectorFactory(
            block_cache=block_cache,
            state_view_factory=state_view_factory,
            signer=identity_signer)

        block_publisher = BlockPublisher(
            transaction_executor=transaction_executor,
            block_cache=block_cache,
            state_view_factory=state_view_factory,
            settings_cache=settings_cache,
            block_sender=block_sender,
            batch_sender=batch_sender,
            chain_head=block_store.chain_head,
            identity_signer=identity_signer,
            data_dir=data_dir,
            config_dir=config_dir,
            permission_verifier=permission_verifier,
            check_publish_block_frequency=0.1,
            batch_observers=[batch_tracker],
            batch_injector_factory=batch_injector_factory)

        block_publisher_batch_sender = block_publisher.batch_sender()

        block_validator = BlockValidator(
            block_cache=block_cache,
            state_view_factory=state_view_factory,
            transaction_executor=transaction_executor,
            identity_signer=identity_signer,
            data_dir=data_dir,
            config_dir=config_dir,
            permission_verifier=permission_verifier)

        chain_controller = ChainController(
            block_store=block_store,
            block_cache=block_cache,
            block_validator=block_validator,
            state_database=global_state_db,
            chain_head_lock=block_publisher.chain_head_lock,
            state_pruning_block_depth=state_pruning_block_depth,
            data_dir=data_dir,
            observers=[
                event_broadcaster, receipt_store, batch_tracker,
                identity_observer, settings_observer
            ])

        genesis_controller = GenesisController(
            context_manager=context_manager,
            transaction_executor=transaction_executor,
            completer=completer,
            block_store=block_store,
            state_view_factory=state_view_factory,
            identity_signer=identity_signer,
            data_dir=data_dir,
            config_dir=config_dir,
            chain_id_manager=chain_id_manager,
            batch_sender=batch_sender)

        responder = Responder(completer)

        completer.set_on_batch_received(block_publisher_batch_sender.send)
        completer.set_on_block_received(chain_controller.queue_block)
        completer.set_chain_has_block(chain_controller.has_block)

        # -- Register Message Handler -- #
        network_handlers.add(network_dispatcher, network_service, gossip,
                             completer, responder, network_thread_pool,
                             sig_pool, chain_controller.has_block,
                             block_publisher.has_batch, permission_verifier,
                             block_publisher, consensus_notifier)

        component_handlers.add(component_dispatcher, gossip, context_manager,
                               transaction_executor, completer, block_store,
                               batch_tracker, global_state_db,
                               self.get_chain_head_state_root_hash,
                               receipt_store, event_broadcaster,
                               permission_verifier, component_thread_pool,
                               client_thread_pool, sig_pool, block_publisher)

        # -- Store Object References -- #
        self._component_dispatcher = component_dispatcher
        self._component_service = component_service
        self._component_thread_pool = component_thread_pool

        self._network_dispatcher = network_dispatcher
        self._network_service = network_service
        self._network_thread_pool = network_thread_pool

        consensus_proxy = ConsensusProxy(
            block_cache=block_cache,
            chain_controller=chain_controller,
            block_publisher=block_publisher,
            gossip=gossip,
            identity_signer=identity_signer,
            settings_view_factory=SettingsViewFactory(state_view_factory),
            state_view_factory=state_view_factory)

        consensus_handlers.add(consensus_dispatcher, consensus_thread_pool,
                               consensus_proxy)

        self._consensus_dispatcher = consensus_dispatcher
        self._consensus_service = consensus_service
        self._consensus_thread_pool = consensus_thread_pool

        self._client_thread_pool = client_thread_pool
        self._sig_pool = sig_pool

        self._context_manager = context_manager
        self._transaction_executor = transaction_executor
        self._genesis_controller = genesis_controller
        self._gossip = gossip

        self._block_publisher = block_publisher
        self._chain_controller = chain_controller
        self._block_validator = block_validator
Beispiel #18
0
 def setUp(self):
     self._identity_view_factory = MockIdentityViewFactory()
     self._identity_cache = IdentityCache(
         self._identity_view_factory)