Esempio n. 1
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)
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
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()
Esempio n. 5
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)
Esempio n. 6
0
def run_contracts_in_interpreter(num_contracts=100):
    interpreter = SenecaInterpreter()

    # Generate the contracts
    log.notice("Generating {} contracts...".format(num_contracts))
    contracts = [God.random_contract_tx() for _ in range(num_contracts)]
    log.notice("Done generating contracts.")

    # Interpret them
    count = 0
    start = time.time()
    log.info("Running contracts...")
    for contract in contracts:
        interpreter._run_contract(contract)
        count += 1
        if count % checkpoint_freq == 0:
            log.notice("{} contracts run so far.".format(count))

    total_time = time.time() - start
    cps = num_contracts / total_time
    log.important("Ran {} contracts in {} seconds".format(
        num_contracts, round(total_time, 4)))
    log.important("{} contracts per second.".format(round(cps, 2)))

    assert interpreter.queue_size == num_contracts, "Interpreter queue size {} does not match num contracts {}..y tho"\
                                                    .format(interpreter.queue_size, num_contracts)
Esempio n. 7
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)
Esempio n. 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)
Esempio n. 9
0
    def __init__(self, signing_key, witness_list, url, sbb_index):
        self.log = get_logger("SubBlockBuilder_{}".format(sb_index))
        # Comment out below for more granularity in debugging
        # self.log.setLevel(logging.INFO)

        #self.log.important("SubBlockBuilder started with url {}".format(url))

        # Register signal handler to teardown
        signal.signal(signal.SIGTERM, self._signal_teardown)

        # need to revisit this when threading strategy is clear
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        self.signing_key = signing_key
        # witness_list should be comma separated list of ip:vk  
        self.witness_table = self._parse_witness_list(witness_list)
        self.url = url
        self.sbb_index = sbb_index
        self.block_num = (int) sbb_index / 16       # hard code this for now
        self.sub_block_num = (int) sb_index % 16
        self.num_txs = 0
        self.num_sub_blocks = 0
        self.tasks = []

        #SenecaInterpreter connect with BlockManager (parent process that spawned this one)
        self.context = zmq.asyncio.Context()
        self.socket = self.context.socket(zmq.PAIR)  # For communication with main process
        self.socket.connect(self.url)

        # do we need this still? or do we move it to a util methods
        self.verifying_key = wallet.get_vk(self.signing_key)
        skg = SigningKey(seed=bytes.fromhex(sk))
        self.vk = skg.verify_key.encode().hex()
        self.public_key = self.vk2pk(self.vk)
        self.private_key = crypto_sign_ed25519_sk_to_curve25519(skg._signing_key).hex()
        priv = PrivateKey(bytes.fromhex(self.private_key))
        publ = priv.public_key
        self.public_key = public_key = encode(publ._public_key)
        self.secret = secret_key = encode(priv._private_key)

        self.pending_txs = LinkedHashTable()
        self.interpreter = SenecaInterpreter()
        self._recently_seen = CappedSet(max_size=DUPE_TABLE_SIZE)

        try:
            self._subscribe_to_witnesses()
            # start event loop and start listening witness sockets as well as mgr
            self.run_loop_second_time()
        except Exception as e:
            err_msg = '\n' + '!' * 64 + '\nSBB terminating with exception:\n' + str(traceback.format_exc())
            err_msg += '\n' + '!' * 64 + '\n'
            self.log.error(err_msg)
        finally:
            self._teardown()
Esempio n. 10
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)])
Esempio n. 11
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)
Esempio n. 12
0
    def test_interpret_invalid_type(self):
        self.interpreter = SenecaInterpreter()
        not_a_contract = 'sup bro im a string'

        self.assertRaises(AssertionError, self.interpreter.interpret,
                          not_a_contract)
Esempio n. 13
0
 def test_init(self):
     self.interpreter = SenecaInterpreter()  # this should not blow up
     self.assertTrue(self.interpreter.ex is not None)
     self.assertTrue(self.interpreter.contracts_table is not None)
Esempio n. 14
0
class TestSenecaInterpreter(TestCase):
    def setUp(self):
        reset_db()

    def tearDown(self):
        self.interpreter.ex.cur.close()
        self.interpreter.ex.conn.close()

    def ordered_tx(self, contract):
        return OrderingContainer.create(contract, MN_VK)

    def test_init(self):
        self.interpreter = SenecaInterpreter()  # this should not blow up
        self.assertTrue(self.interpreter.ex is not None)
        self.assertTrue(self.interpreter.contracts_table is not None)

    def test_interpret_invalid_type(self):
        self.interpreter = SenecaInterpreter()
        not_a_contract = 'sup bro im a string'

        self.assertRaises(AssertionError, self.interpreter.interpret,
                          not_a_contract)

    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)

    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_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)

    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)

    def test_flushes_without_update(self):
        """
        Tests that calling .flush on an self.interpreter with update_state=False after interpreting several transactions
        successfully rolls back
        """
        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=False))
        self.interpreter.interpret(contract_tx)
        self.interpreter.flush(update_state=True)
        self.assertEqual(dummy_contract.get_balance(sender),
                         sender_initial_balance + 1000)

        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 + 1500)
        self.interpreter.flush(update_state=False)
        self.assertEqual(dummy_contract.get_balance(sender),
                         sender_initial_balance + 1000)

    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)

    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)])

    def test_check_contract_correct_order_shuffled(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 + 1000
        contracts[3]._data.utcTimeMs = now
        contracts[4]._data.utcTimeMs = now - 3000

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

        self.assertEqual(contracts[4], heappop(self.interpreter.heap)[1])
        self.assertEqual(contracts[0], heappop(self.interpreter.heap)[1])
        self.assertEqual(contracts[1], heappop(self.interpreter.heap)[1])
        self.assertEqual(contracts[3], heappop(self.interpreter.heap)[1])
        self.assertEqual(contracts[2], heappop(self.interpreter.heap)[1])

    @async_run_for(3)
    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()

    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)

    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)
Esempio n. 15
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     # Properties shared among all states (ie via self.parent.some_prop)
     self.pending_sigs, self.pending_txs = deque(), deque()
     self.interpreter = SenecaInterpreter()
     self.current_hash = BlockStorageDriver.get_latest_block_hash()