Пример #1
0
    def test_bad_tx_returns_properly(self):
        class BadTX:
            def __init__(self, tx, err):
                self.tx = tx
                self.err = err

        stu = Wallet()
        tx = transaction.build_transaction(wallet=stu,
                                           contract='testing',
                                           function='eat_stamps',
                                           kwargs={},
                                           stamps=10000,
                                           processor='0' * 64,
                                           nonce=0)

        exe = execution.SerialExecutor(executor=self.client.executor)

        result = exe.execute_tx_batch(
            batch={'transactions': [BadTX(decode(tx), Exception)]},
            stamp_cost=200,
            timestamp=int(time.time()),
            input_hash='A' * 32,
            driver=self.client.raw_driver)

        self.assertEqual(result[0]['status'], 1)
        self.assertEqual(result[0]['result'], safe_repr(str(Exception)))
        self.assertEqual(result[0]['stamps_used'], 0)
Пример #2
0
    def test_push_two_transaction_pop_gets_oldest_first(self):
        tx = build_transaction(wallet=Wallet(),
                               processor='b' * 64,
                               stamps=123,
                               nonce=0,
                               contract='currency',
                               function='transfer',
                               kwargs={
                                   'amount': 123,
                                   'to': 'jeff'
                               })

        self.q.append(tx)

        tx2 = build_transaction(wallet=Wallet(),
                                processor='b' * 64,
                                stamps=123,
                                nonce=0,
                                contract='currency',
                                function='transfer',
                                kwargs={
                                    'amount': 123,
                                    'to': 'jeff2'
                                })

        self.q.append(tx2)

        tx_2 = self.q.pop(0)
        self.assertEqual(decode(tx), tx_2)
Пример #3
0
    def test_push_transaction_can_be_retrieved_with_pop(self):
        tx = build_transaction(wallet=Wallet(),
                               processor='b' * 64,
                               stamps=123,
                               nonce=0,
                               contract='currency',
                               function='transfer',
                               kwargs={
                                   'amount': 123,
                                   'to': 'jeff'
                               })

        self.q.append(tx)

        tx_2 = self.q.pop(0)
        self.assertEqual(decode(tx), tx_2)
Пример #4
0
    def test_execute_tx_returns_successful_output(self):
        test_contract = '''
v = Variable()

@construct
def seed():
    v.set('hello')

@export
def set(var: str):
    v.set(var)

@export
def get():
    return v.get()
                '''

        self.client.submit(test_contract, name='testing')

        self.client.raw_driver.commit()
        self.client.raw_driver.clear_pending_state()

        stu = Wallet()

        tx = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'jeff'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        e = execution.SerialExecutor(executor=self.client.executor)

        result = e.execute_tx(decode(tx), stamp_cost=20_000)

        self.assertEqual(result['status'], 0)
        self.assertEqual(result['state'][0]['key'], 'testing.v')
        self.assertEqual(result['state'][0]['value'],  'jeff')
        self.assertEqual(result['stamps_used'], 1)
Пример #5
0
    def test_tx_with_error_returns_exception(self):
        tx = build_transaction(wallet=Wallet(),
                               processor=self.ws.wallet.verifying_key,
                               stamps=123,
                               nonce=0,
                               contract='currency',
                               function='transfer',
                               kwargs={
                                   'amount': 123,
                                   'to': 'jeff'
                               })

        tx = decode(tx)
        tx['payload']['stamps_supplied'] = -123
        tx = encode(tx)

        _, response = self.ws.app.test_client.post('/', data=tx)

        self.assertDictEqual(
            response.json, {'error': 'Transaction is not formatted properly.'})
Пример #6
0
    def test_stamp_deduction_on_fail(self):
        test_contract = '''
@export
def eat_stamps():
    while True:
        pass
        '''

        self.client.submit(test_contract, name='testing')

        self.client.raw_driver.commit()
        self.client.raw_driver.clear_pending_state()

        stu = Wallet()

        self.client.raw_driver.set(f'currency.balances:{stu.verifying_key}', 100000)

        tx = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='eat_stamps',
            kwargs={},
            stamps=10000,
            processor='0' * 64,
            nonce=0
        )

        e = execution.SerialExecutor(executor=self.client.executor)

        self.client.executor.metering = True

        result = e.execute_tx(decode(tx), stamp_cost=200)

        self.assertEqual(result['status'], 1)
        self.assertEqual(result['state'][0]['key'], f'currency.balances:{stu.verifying_key}')
        self.assertEqual(result['state'][0]['value'], Decimal('99950.0'))
        self.assertEqual(result['stamps_used'], 10000)
Пример #7
0
    def test_masternode_delegate_single_loop_updates_block_num(self):
        ips = [
            'tcp://127.0.0.1:18001',
            'tcp://127.0.0.1:18002'
        ]

        dw = Wallet()
        mw = Wallet()

        self.authenticator.add_verifying_key(mw.verifying_key)
        self.authenticator.add_verifying_key(dw.verifying_key)
        self.authenticator.configure()

        mnd = ContractDriver(driver=InMemDriver())
        mn = masternode.Masternode(
            socket_base=ips[0],
            ctx=self.ctx,
            wallet=mw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=mnd
        )
        sender = Wallet()
        mnd.set_var(contract='currency', variable='balances', arguments=[sender.verifying_key], value=1_000_000)

        dld = ContractDriver(driver=InMemDriver())
        dld.set_var(contract='currency', variable='balances', arguments=[sender.verifying_key], value=1_000_000)
        dl = delegate.Delegate(
            socket_base=ips[1],
            ctx=self.ctx,
            wallet=dw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=dld
        )

        tx = transaction.build_transaction(
            wallet=sender,
            contract='currency',
            function='transfer',
            kwargs={
                'amount': 1338,
                'to': 'jeff'
            },
            stamps=5000,
            nonce=0,
            processor=mw.verifying_key
        )

        tx_decoded = decode(tx)
        mn.tx_batcher.queue.append(tx_decoded)

        peers = {
            mw.verifying_key: ips[0],
            dw.verifying_key: ips[1]
        }

        mn.network.peers = peers
        dl.network.peers = peers

        tasks = asyncio.gather(
            mn.router.serve(),
            dl.router.serve(),
            mn.loop(),
            dl.loop(),
            stop_server(mn.router, 1),
            stop_server(dl.router, 1),
        )

        self.loop.run_until_complete(tasks)

        dh = storage.get_latest_block_height(dld)
        mh = storage.get_latest_block_height(mnd)

        self.assertEqual(dh, 1)
        self.assertEqual(mh, 1)
Пример #8
0
    def test_execute_work_multiple_transaction_batches_works(self):
        test_contract = '''
v = Variable()

@construct
def seed():
    v.set('hello')

@export
def set(var: str):
    v.set(var)

@export
def get():
    return v.get()
        '''

        self.client.submit(test_contract, name='testing')

        self.client.raw_driver.commit()
        self.client.raw_driver.clear_pending_state()

        stu = Wallet()

        tx1_1 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'howdy'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx1_1 = decode(tx1_1)

        tx1_2 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='get',
            kwargs={},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx1_2 = decode(tx1_2)

        tx_batch_1 = {
            'transactions': [tx1_1, tx1_2],
            'timestamp': time.time(),
            'input_hash': 'C' * 64
        }

        tx2_1 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': '123'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx2_1 = decode(tx2_1)

        jeff = Wallet()
        tx2_2 = transaction.build_transaction(
            wallet=jeff,
            contract='testing',
            function='set',
            kwargs={'var': 'poo'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx2_2 = decode(tx2_2)

        tx_batch_2 = {
            'transactions': [tx2_1, tx2_2],
            'timestamp': time.time(),
            'input_hash': 'A' * 64
        }

        work = [tx_batch_1, tx_batch_2]

        exe = execution.SerialExecutor(executor=self.client.executor)

        results = exe.execute_work(
            driver=self.client.raw_driver,
            work=work,
            previous_block_hash='B' * 64,
            wallet=Wallet(),
            stamp_cost=20_000
        )

        sb1, sb2 = results

        td1, td2 = sb1['transactions']
        self.assertEqual(td1['status'], 0)
        self.assertEqual(td1['state'][0]['key'], 'testing.v')
        self.assertEqual(td1['state'][0]['value'], 'howdy')
        self.assertEqual(td1['stamps_used'], 1)

        self.assertEqual(td2['status'], 0)
        self.assertEqual(len(td2['state']), 0)
        self.assertEqual(td2['stamps_used'], 1)

        self.assertEqual(sb1['input_hash'], tx_batch_1['input_hash'])
        self.assertEqual(sb1['subblock'], 0)
        self.assertEqual(sb1['previous'], 'B' * 64)

        td1, td2 = sb2['transactions']
        self.assertEqual(td1['status'], 0)
        self.assertEqual(td1['state'][0]['key'], 'testing.v')
        self.assertEqual(td1['state'][0]['value'], '123')
        self.assertEqual(td1['stamps_used'], 1)

        self.assertEqual(td2['status'], 0)
        self.assertEqual(td2['state'][0]['key'], 'testing.v')
        self.assertEqual(td2['state'][0]['value'], 'poo')
        self.assertEqual(td2['stamps_used'], 1)

        self.assertEqual(sb2['input_hash'], tx_batch_2['input_hash'])
        self.assertEqual(sb2['subblock'], 1)
        self.assertEqual(sb2['previous'], 'B' * 64)
Пример #9
0
    def test_execute_tx_batch_returns_all_transactions_4_in_order(self):
        test_contract = '''
v = Variable()

@construct
def seed():
    v.set('hello')

@export
def set(var: str):
    v.set(var)

@export
def get():
    return v.get()
        '''

        self.client.submit(test_contract, name='testing')

        self.client.raw_driver.commit()
        self.client.raw_driver.clear_pending_state()

        stu = Wallet()

        tx = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'howdy'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx = decode(tx)

        tx2 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='get',
            kwargs={},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx2 = decode(tx2)

        tx3 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'something'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx3 = decode(tx3)

        tx4 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'something2'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx4 = decode(tx4)

        tx_batch = {
            'transactions': [tx, tx2, tx3, tx4]
        }

        e = execution.SerialExecutor(executor=self.client.executor)

        results = e.execute_tx_batch(
            driver=self.client.raw_driver,
            batch=tx_batch,
            timestamp=time.time(),
            input_hash='A' * 64,
            stamp_cost=20_000
        )

        td1, td2, td3, td4 = results

        self.assertEqual(td1['status'], 0)
        self.assertEqual(td1['state'][0]['key'], 'testing.v')
        self.assertEqual(td1['state'][0]['value'], 'howdy')
        self.assertEqual(td1['stamps_used'], 1)

        self.assertEqual(td2['status'], 0)
        self.assertEqual(len(td2['state']), 0)
        self.assertEqual(td2['stamps_used'], 1)

        self.assertEqual(td3['status'], 0)
        self.assertEqual(td3['state'][0]['key'], 'testing.v')
        self.assertEqual(td3['state'][0]['value'], 'something')
        self.assertEqual(td3['stamps_used'], 1)

        self.assertEqual(td4['status'], 0)
        self.assertEqual(td4['state'][0]['key'], 'testing.v')
        self.assertEqual(td4['state'][0]['value'], 'something2')
        self.assertEqual(td4['stamps_used'], 1)