Exemple #1
0
    def test_run_bad_contract_reverts_to_last_successful_contract_remove_partial(
            self):
        """
        Tests that running a failing contract reverts any database changes it made before the point of failure
        """
        sender = ALICE_VK
        receiver = BOB_VK

        self.interpreter = SenecaInterpreter()
        dummy_contract = get_contract_exports(self.interpreter.ex,
                                              self.interpreter.contracts_table,
                                              contract_id='dummy')

        sender_initial_balance = dummy_contract.get_balance(sender)
        self.assertEqual(dummy_contract.get_balance(sender),
                         sender_initial_balance)
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_dummy_tx(sender_sk=ALICE_SK,
                                                       receiver_vk=receiver,
                                                       fail=False))
        self.interpreter.interpret(contract_tx)
        self.assertEqual(dummy_contract.get_balance(sender),
                         sender_initial_balance + 500)
        # NOTE it attempts to update the balance to 123 and add the same user again
        #   Updating should work and adding already added user
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_dummy_tx(sender_sk=ALICE_SK,
                                                       receiver_vk=receiver,
                                                       fail=True))
        self.interpreter.interpret(contract_tx)
        self.assertEqual(dummy_contract.get_balance(sender),
                         sender_initial_balance + 500)
Exemple #2
0
    def test_rerun_fail(self):
        orig = SenecaInterpreter._run_contract

        def mocked_rerun(*args, **kwargs):
            if kwargs.get('rerun'):
                return None
            return orig(*args, **kwargs)

        sender = ALICE_VK
        receiver = BOB_VK

        self.interpreter = SenecaInterpreter()
        dummy_contract = get_contract_exports(self.interpreter.ex,
                                              self.interpreter.contracts_table,
                                              contract_id='dummy')

        sender_initial_balance = dummy_contract.get_balance(sender)
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_dummy_tx(sender_sk=ALICE_SK,
                                                       receiver_vk=receiver,
                                                       fail=False))
        self.interpreter.interpret(contract_tx)
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_dummy_tx(sender_sk=ALICE_SK,
                                                       receiver_vk=receiver,
                                                       fail=True))
        with mock.patch(
                'cilantro.protocol.interpreter.SenecaInterpreter._run_contract',
                side_effect=mocked_rerun,
                autospec=True) as mock_some_method:
            with self.assertRaises(Exception) as context:
                self.interpreter.interpret(contract_tx)
Exemple #3
0
    def test_flushes_with_update(self):
        """
        Tests that calling .flush on an self.interpreter with update_state=True after interpreting several transactions
        successfully commits the changes to the database
        """
        sender = ALICE_VK
        receiver = BOB_VK

        self.interpreter = SenecaInterpreter()
        dummy_contract = get_contract_exports(self.interpreter.ex,
                                              self.interpreter.contracts_table,
                                              contract_id='dummy')

        sender_initial_balance = dummy_contract.get_balance(sender)
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_dummy_tx(sender_sk=ALICE_SK,
                                                       receiver_vk=receiver,
                                                       fail=False))
        self.interpreter.interpret(contract_tx)
        self.assertEqual(dummy_contract.get_balance(sender),
                         sender_initial_balance + 500)
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_dummy_tx(sender_sk=ALICE_SK,
                                                       receiver_vk=receiver,
                                                       fail=False))
        self.interpreter.interpret(contract_tx)
        self.interpreter.flush(update_state=True)
        self.assertEqual(dummy_contract.get_balance(sender),
                         sender_initial_balance + 1000)
Exemple #4
0
    def test_interpret_currency(self):
        amount = 1260
        receiver = BOB_VK
        sender = ALICE_VK
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_currency_tx(sender_sk=ALICE_SK,
                                                          receiver_vk=receiver,
                                                          amount=amount))

        self.interpreter = SenecaInterpreter()
        currency_contract = get_contract_exports(
            self.interpreter.ex,
            self.interpreter.contracts_table,
            contract_id='currency')

        sender_initial_balance = currency_contract.get_balance(sender)
        receiver_initial_balance = currency_contract.get_balance(receiver)

        self.interpreter.interpret(contract_tx)

        # Assert the contract ran and updated the expected rows
        self.assertEqual(currency_contract.get_balance(sender),
                         sender_initial_balance - amount)
        self.assertEqual(currency_contract.get_balance(receiver),
                         receiver_initial_balance + amount)

        # Assert the contract was added to the queue
        self.assertEqual(self.interpreter.queue_size, 1)
        self.assertEqual(self.interpreter.queue[0], contract_tx.transaction)
Exemple #5
0
    def test_check_contract_async_shuffled_adhoc_checks(self):
        def assertCondition():
            self.assertEqual(contracts[0].transaction,
                             self.interpreter.queue[0])
            self.assertEqual(contracts[2].transaction,
                             self.interpreter.queue[1])
            self.assertEqual(contracts[1].transaction,
                             self.interpreter.queue[2])
            self.assertEqual(len(self.interpreter.queue), 3)
            self.interpreter.stop()

        sender = ALICE_VK
        receiver = BOB_VK
        now = int(time.time() * 1000)

        self.interpreter = SenecaInterpreter()
        contracts = [
            self.ordered_tx(ContractTransactionBuilder.create_dummy_tx(sender_sk=ALICE_SK, receiver_vk=receiver, fail=False)) \
            for i in range(5)
        ]
        contracts[0]._data.utcTimeMs = now - 2000
        contracts[1]._data.utcTimeMs = now
        contracts[2]._data.utcTimeMs = now - 1000
        contracts[3]._data.utcTimeMs = now + 5000
        contracts[4]._data.utcTimeMs = now + 6000

        for c in contracts:
            self.interpreter.interpret(c, async=True)

        t = Timer(2.8, assertCondition)
        t.start()
Exemple #6
0
def build_test_transaction() -> TransactionBase:
    """
    Utility method to build a random transaction (an instance of a subclass of TransactionBase). Used exclusively for
    unit/integration tests.
    :return: An instance of a subclass of TransactionBase
    """
    from cilantro.messages.transaction.contract import ContractTransactionBuilder
    return ContractTransactionBuilder.random_currency_tx()
Exemple #7
0
    def test_creation(self):
        sk, vk = wallet.new()
        code = 'while True: do_that_thing'

        contract_tx = ContractTransactionBuilder.create_contract_tx(
            sender_sk=sk, code_str=code)

        self.assertEquals(contract_tx.sender, vk)
        self.assertEquals(contract_tx.code, code)
Exemple #8
0
    def test_run_bad_contract_reverts_to_last_successful_contract(self):
        """
        Tests that running a failing contract reverts any database changes it made before the point of failure
        """
        receiver = BOB_VK
        sender = ALICE_VK

        self.interpreter = SenecaInterpreter()
        currency_contract = get_contract_exports(
            self.interpreter.ex,
            self.interpreter.contracts_table,
            contract_id='currency')

        sender_initial_balance = currency_contract.get_balance(sender)
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_currency_tx(sender_sk=ALICE_SK,
                                                          receiver_vk=receiver,
                                                          amount=1000))
        self.interpreter.interpret(contract_tx)
        self.assertEqual(currency_contract.get_balance(sender),
                         sender_initial_balance - 1000)
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_currency_tx(sender_sk=ALICE_SK,
                                                          receiver_vk=receiver,
                                                          amount=200))
        self.interpreter.interpret(contract_tx)
        self.assertEqual(currency_contract.get_balance(sender),
                         sender_initial_balance - 1200)
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_currency_tx(sender_sk=ALICE_SK,
                                                          receiver_vk=receiver,
                                                          amount=60))
        self.interpreter.interpret(contract_tx)
        self.assertEqual(currency_contract.get_balance(sender),
                         sender_initial_balance - 1260)

        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_currency_tx(sender_sk=ALICE_SK,
                                                          receiver_vk=receiver,
                                                          amount=3696947))
        self.interpreter.interpret(contract_tx)
        self.assertEqual(currency_contract.get_balance(sender),
                         sender_initial_balance - 1260)
 def test_creation(self):
     """
     Tests that a created block data reply has the expected properties
     """
     sk = wallet.new()[0]
     contracts = [
         ContractTransactionBuilder.create_contract_tx(sk, code_str) \
         for code_str in ['some random binary', 'some deterministic binary', 'While True: self.eatAss()']
     ]
     tx_binaries = [c.serialize() for c in contracts]
     bdr = TransactionReply.create(tx_binaries)
     self.assertEqual(contracts, bdr.transactions)
Exemple #10
0
    def test_create_currency_tx(self):
        sk, vk = wallet.new()
        sk2, vk2 = wallet.new()
        amount = 9000
        currency_code = ContractTemplate.interpolate_template('currency',
                                                              amount=amount,
                                                              receiver=vk2)

        contract_tx = ContractTransactionBuilder.create_currency_tx(
            sender_sk=sk, receiver_vk=vk2, amount=amount)

        self.assertEquals(contract_tx.sender, vk)
        self.assertEquals(contract_tx.code, currency_code)
Exemple #11
0
    def test_restore_to_beginning(self):
        orig = SenecaInterpreter._run_contract

        sender = ALICE_VK
        receiver = BOB_VK

        self.interpreter = SenecaInterpreter()
        dummy_contract = get_contract_exports(self.interpreter.ex,
                                              self.interpreter.contracts_table,
                                              contract_id='dummy')

        sender_initial_balance = dummy_contract.get_balance(sender)
        contract_tx = self.ordered_tx(
            ContractTransactionBuilder.create_dummy_tx(sender_sk=ALICE_SK,
                                                       receiver_vk=receiver,
                                                       fail=True))
        self.interpreter.interpret(contract_tx)
    def test_validate_matches_request_no_match(self):
        """
        Tests that a created block data reply has the expected properties
        """
        sk = wallet.new()[0]
        code_strs = ['some random binary', 'some deterministic binary', 'While True: self.eatAss()']
        contracts = [
            ContractTransactionBuilder.create_contract_tx(sk, code_str) \
            for code_str in code_strs
        ]
        tx_binaries = [c.serialize() for c in contracts]

        tx_hashes = [Hasher.hash(cs+b'bbb') for cs in tx_binaries]
        bdr_req = TransactionRequest.create(tx_hashes)

        bdr_rep = TransactionReply.create(tx_binaries)
        assert not bdr_rep.validate_matches_request(bdr_req)
    def test_serialization(self):
        """
        Tests that a message successfully serializes and deserializes. The deserialized object should have the same
        properties as the original one before it was serialized.
        """
        sk = wallet.new()[0]
        code_strs = ['some random binary', 'some deterministic binary', 'While True: self.eatAss()']
        contracts = [
            ContractTransactionBuilder.create_contract_tx(sk, code_str) \
            for code_str in code_strs
        ]
        tx_binaries = [c.serialize() for c in contracts]
        original = TransactionReply.create(tx_binaries)
        original_binary = original.serialize()
        clone = TransactionReply.from_bytes(original_binary)  # deserialize byte object

        self.assertEqual(original.transactions, clone.transactions)
Exemple #14
0
    def test_check_contract_correct_order(self):
        sender = ALICE_VK
        receiver = BOB_VK
        now = int(time.time() * 1000)

        self.interpreter = SenecaInterpreter()
        contracts = [
            self.ordered_tx(ContractTransactionBuilder.create_dummy_tx(sender_sk=ALICE_SK, receiver_vk=receiver, fail=False)) \
            for i in range(5)
        ]
        contracts[0]._data.utcTimeMs = now - 2000
        contracts[1]._data.utcTimeMs = now - 1000
        contracts[2]._data.utcTimeMs = now
        contracts[3]._data.utcTimeMs = now + 1000
        contracts[4]._data.utcTimeMs = now + 2000

        for c in contracts:
            self.interpreter.interpret(c, async=True)

        self.assertEqual(contracts,
                         [heappop(self.interpreter.heap)[1] for i in range(5)])
Exemple #15
0
    def test_queue_binary(self):
        """
        Tests that queue_binary returns a list of serialized ContractTransactions
        """
        sender = ALICE_VK
        receiver = BOB_VK

        self.interpreter = SenecaInterpreter()
        dummy_contract = get_contract_exports(self.interpreter.ex,
                                              self.interpreter.contracts_table,
                                              contract_id='dummy')

        contracts = []
        for i in range(5):
            contract_tx = self.ordered_tx(
                ContractTransactionBuilder.create_dummy_tx(
                    sender_sk=ALICE_SK, receiver_vk=receiver, fail=False))
            self.interpreter.interpret(contract_tx)
            contracts.append(contract_tx.transaction)

        for actual, expected in zip([c.serialize() for c in contracts],
                                    self.interpreter.queue_binary):
            self.assertEqual(actual, expected)
Exemple #16
0
def publisher():
    SLEEP_TIME = 0.05
    MAX_TIME = 10
    from cilantro.logger import get_logger, overwrite_logger_level
    from cilantro.utils.test import MPComposer
    from cilantro.messages.transaction.contract import ContractTransactionBuilder
    from cilantro.constants.testnet import TESTNET_DELEGATES
    import time, os

    log = get_logger("Publisher")
    sub_info = TESTNET_DELEGATES[1]
    sub_info['ip'] = os.getenv('HOST_IP')

    d_info = TESTNET_DELEGATES[0]
    d_info['ip'] = os.getenv('HOST_IP')

    pub = MPComposer(sk=d_info['sk'])

    # Publish on this node's own IP
    pub.add_pub(os.getenv('HOST_IP'))

    log.important(
        "Starting experiment, sending messages every {} seconds for a total of {} seconds"
        .format(SLEEP_TIME, MAX_TIME))
    elapsed_time = 0

    while elapsed_time < MAX_TIME:
        log.notice("Sending pub")
        msg = ContractTransactionBuilder.random_currency_tx()
        pub.send_pub_msg(filter='0', message=msg)

        time.sleep(SLEEP_TIME)
        elapsed_time += SLEEP_TIME

    pub.teardown()
    log.important("Done with experiment!")