コード例 #1
0
ファイル: storage.py プロジェクト: baby636/lamden
def get_latest_block_height(driver: ContractDriver):
    h = driver.get(BLOCK_NUM_HEIGHT, mark=False)
    if h is None:
        return 0
    return h
コード例 #2
0
ファイル: test_delegate.py プロジェクト: Lamden/lamden
    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)
コード例 #3
0
ファイル: storage.py プロジェクト: baby636/lamden
def get_latest_block_hash(driver: ContractDriver):
    latest_hash = driver.get(BLOCK_HASH_KEY, mark=False)
    if latest_hash is None:
        return '0' * 64
    return latest_hash
コード例 #4
0
ファイル: test_delegate.py プロジェクト: Lamden/lamden
class TestDelegate(TestCase):
    def setUp(self):
        self.ctx = zmq.asyncio.Context()
        self.loop = asyncio.new_event_loop()
        self.driver = ContractDriver(driver=InMemDriver())
        self.client = ContractingClient(driver=self.driver)
        self.client.flush()
        asyncio.set_event_loop(self.loop)

        self.authenticator = authentication.SocketAuthenticator(
            client=self.client, ctx=self.ctx)

    def tearDown(self):
        self.client.flush()
        self.driver.flush()
        self.authenticator.authenticator.stop()
        self.ctx.destroy()
        self.loop.close()

    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)

    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)

    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)

    def test_generate_environment_creates_datetime_wrapped_object(self):
        timestamp = int(time.time())

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

        e = exe.generate_environment(self.client.raw_driver, timestamp,
                                     'A' * 64)

        t = datetime.utcfromtimestamp(timestamp)

        #self.assertEqual(type(e['now']), Datetime)
        self.assertEqual(e['now'].year, t.year)
        self.assertEqual(e['now'].month, t.month)
        self.assertEqual(e['now'].day, t.day)
        self.assertEqual(e['now'].hour, t.hour)
        self.assertEqual(e['now'].minute, t.minute)
        self.assertEqual(e['now'].second, t.second)

    def test_generate_environment_creates_input_hash(self):
        timestamp = time.time()

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

        e = exe.generate_environment(self.client.raw_driver, timestamp,
                                     'A' * 64)

        self.assertEqual(e['__input_hash'], 'A' * 64)

    def test_generate_environment_creates_block_hash(self):
        timestamp = time.time()

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

        e = exe.generate_environment(self.client.raw_driver, timestamp,
                                     'A' * 64)

        self.assertEqual(e['block_hash'],
                         storage.get_latest_block_hash(self.client.raw_driver))

    def test_generate_environment_creates_block_num(self):
        timestamp = time.time()

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

        e = exe.generate_environment(self.client.raw_driver, timestamp,
                                     'A' * 64)

        self.assertEqual(
            e['block_num'],
            storage.get_latest_block_height(self.client.raw_driver) + 1)

    def test_execute_tx_batch_returns_all_transactions(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)

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

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

    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)

    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)

    def test_no_txs_merklizes_and_signs_input_hash(self):
        tx_batch_1 = {
            'transactions': [],
            'timestamp': time.time(),
            'input_hash': 'A' * 64
        }

        work = [tx_batch_1]

        w = Wallet()

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

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

        self.assertTrue(
            verify(w.verifying_key, results[0]['input_hash'],
                   results[0]['merkle_tree']['signature']))

        h = hashlib.sha3_256()
        h.update(bytes.fromhex(results[0]['input_hash']))

        self.assertEqual(h.hexdigest(), results[0]['merkle_tree']['leaves'][0])

    def test_acquire_work_1_master_gathers_tx_batches(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()

        mn = masternode.Masternode(socket_base=ips[0],
                                   ctx=self.ctx,
                                   wallet=mw,
                                   constitution={
                                       'masternodes': [mw.verifying_key],
                                       'delegates': [dw.verifying_key]
                                   },
                                   driver=ContractDriver(driver=InMemDriver()))

        dl = delegate.Delegate(socket_base=ips[1],
                               ctx=self.ctx,
                               wallet=dw,
                               constitution={
                                   'masternodes': [mw.verifying_key],
                                   'delegates': [dw.verifying_key]
                               },
                               driver=ContractDriver(driver=InMemDriver()))

        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.send_work(),
            dl.acquire_work(),
            stop_server(mn.router, 1),
            stop_server(dl.router, 1),
        )

        _, _, _, w, _, _ = self.loop.run_until_complete(tasks)

        self.assertEqual(len(w), 1)
        self.assertEqual(w[0]['sender'], mw.verifying_key)

    def test_acquire_work_2_masters_gathers_tx_batches_pads_work_and_waits_if_missing(
            self):
        ips = ['tcp://127.0.0.1:18001', 'tcp://127.0.0.1:18002']

        dw = Wallet()
        mw = Wallet()
        mw2 = Wallet()

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

        mn = masternode.Masternode(socket_base=ips[0],
                                   ctx=self.ctx,
                                   wallet=mw,
                                   constitution={
                                       'masternodes':
                                       [mw.verifying_key, mw2.verifying_key],
                                       'delegates': [dw.verifying_key]
                                   },
                                   driver=ContractDriver(driver=InMemDriver()))

        dl = delegate.Delegate(socket_base=ips[1],
                               ctx=self.ctx,
                               wallet=dw,
                               constitution={
                                   'masternodes':
                                   [mw.verifying_key, mw2.verifying_key],
                                   'delegates': [dw.verifying_key]
                               },
                               driver=ContractDriver(driver=InMemDriver()))

        peers = {
            mw.verifying_key: ips[0],
            dw.verifying_key: ips[1],
            mw2.verifying_key: 'tpc://127.0.0.1:18003'
        }

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

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

        _, _, _, w, _, _ = self.loop.run_until_complete(tasks)

        self.assertEqual(len(w), 2)
        self.assertEqual(w[0]['sender'], mw.verifying_key)

        self.assertEqual(w[1]['sender'], mw2.verifying_key)
        self.assertEqual(w[1]['input_hash'], mw2.verifying_key)
        self.assertEqual(w[1]['signature'], '0' * 128)

    def test_process_new_work_processes_tx_batch(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()

        mn = masternode.Masternode(socket_base=ips[0],
                                   ctx=self.ctx,
                                   wallet=mw,
                                   constitution={
                                       'masternodes': [mw.verifying_key],
                                       'delegates': [dw.verifying_key]
                                   },
                                   driver=ContractDriver(driver=InMemDriver()))

        mnq = router.QueueProcessor()
        mn.router.add_service(base.CONTENDER_SERVICE, mnq)

        dl = delegate.Delegate(socket_base=ips[1],
                               ctx=self.ctx,
                               wallet=dw,
                               constitution={
                                   'masternodes': [mw.verifying_key],
                                   'delegates': [dw.verifying_key]
                               },
                               driver=ContractDriver(driver=InMemDriver()))

        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.send_work(),
            dl.process_new_work(),
            stop_server(mn.router, 1),
            stop_server(dl.router, 1),
        )

        self.loop.run_until_complete(tasks)

        sbc = mnq.q.pop(0)

        self.assertEqual(len(sbc), 1)
        self.assertEqual(sbc[0]['previous'], '0' * 64)
        self.assertEqual(sbc[0]['signer'], dw.verifying_key)

    def test_masternode_delegate_single_loop_works(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()

        mn = masternode.Masternode(socket_base=ips[0],
                                   ctx=self.ctx,
                                   wallet=mw,
                                   constitution={
                                       'masternodes': [mw.verifying_key],
                                       'delegates': [dw.verifying_key]
                                   },
                                   driver=ContractDriver(driver=InMemDriver()))

        dl = delegate.Delegate(socket_base=ips[1],
                               ctx=self.ctx,
                               wallet=dw,
                               constitution={
                                   'masternodes': [mw.verifying_key],
                                   'delegates': [dw.verifying_key]
                               },
                               driver=ContractDriver(driver=InMemDriver()))

        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)

        # sbc = mnq.q.pop(0)
        #
        # self.assertEqual(len(sbc), 1)
        # self.assertEqual(sbc[0]['previous'], '0' * 64)
        # self.assertEqual(sbc[0]['signer'], dw.verifying_key)

    # def test_masternode_delegate_single_loop_commits_state_changes(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)
    #
    #     dbal = dld.get_var(contract='currency', variable='balances', arguments=['jeff'])
    #     mbal = mnd.get_var(contract='currency', variable='balances', arguments=['jeff'])
    #
    #     self.assertEqual(dbal, 1338)
    #     self.assertEqual(mbal, 1338)

    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)
コード例 #5
0
def owner_of(m: ModuleType):
    _driver = rt.env.get('__Driver') or ContractDriver()
    owner = _driver.get_var(m.__name__, OWNER_KEY)
    return owner
コード例 #6
0
from unittest import TestCase

from lamden.nodes.masternode.webserver import WebServer
from lamden.crypto.wallet import Wallet
from contracting.client import ContractingClient
from contracting.db.driver import ContractDriver, decode, encode
from lamden.storage import BlockStorage
from lamden.crypto.transaction import build_transaction
from lamden import storage

n = ContractDriver()


class TestClassWebserver(TestCase):
    def setUp(self):
        self.w = Wallet()

        self.blocks = BlockStorage()
        self.driver = ContractDriver()

        self.ws = WebServer(wallet=self.w,
                            contracting_client=ContractingClient(),
                            blocks=self.blocks,
                            driver=n)
        self.ws.client.flush()
        self.ws.blocks.drop_collections()

    def tearDown(self):
        self.ws.client.flush()
        self.ws.blocks.drop_collections()
コード例 #7
0
ファイル: test_base_node.py プロジェクト: baby636/lamden
class TestNode(TestCase):
    def setUp(self):
        self.ctx = zmq.asyncio.Context()
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        self.blocks = storage.BlockStorage()

        self.driver = ContractDriver(driver=InMemDriver())
        self.b = masternode.BlockService(blocks=self.blocks,
                                         driver=self.driver)

        self.blocks.drop_collections()
        self.driver.flush()

        self.authenticator = authentication.SocketAuthenticator(
            client=ContractingClient(), ctx=self.ctx)

    def tearDown(self):
        self.authenticator.authenticator.stop()
        self.ctx.destroy()
        self.loop.close()
        self.b.blocks.drop_collections()
        self.b.driver.flush()

    def test_catchup(self):
        driver = ContractDriver(driver=InMemDriver())

        dl_vk = Wallet().verifying_key

        mn_bootnode = 'tcp://127.0.0.1:18001'
        mn_wallet = Wallet()
        mn_router = router.Router(socket_id=mn_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=mn_wallet)

        mn_router.add_service(base.BLOCK_SERVICE, self.b)

        nw = Wallet()
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=nw,
                         constitution={
                             'masternodes': [mn_wallet.verifying_key],
                             'delegates': [dl_vk]
                         },
                         driver=driver)

        self.authenticator.add_verifying_key(mn_wallet.verifying_key)
        self.authenticator.add_verifying_key(nw.verifying_key)
        self.authenticator.add_verifying_key(dl_vk)
        self.authenticator.configure()

        blocks = generate_blocks(3)

        self.blocks.store_block(blocks[0])
        self.blocks.store_block(blocks[1])
        self.blocks.store_block(blocks[2])
        storage.set_latest_block_height(3, self.driver)

        tasks = asyncio.gather(
            mn_router.serve(),
            node.catchup('tcp://127.0.0.1:18001', mn_wallet.verifying_key),
            stop_server(mn_router, 2))

        self.loop.run_until_complete(tasks)

        self.assertEqual(storage.get_latest_block_height(node.driver), 3)

    def test_catchup_with_nbn_added(self):
        driver = ContractDriver(driver=InMemDriver())

        mn_bootnode = 'tcp://127.0.0.1:18001'
        mn_wallet = Wallet()
        mn_router = router.Router(socket_id=mn_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=mn_wallet)

        mn_router.add_service(base.BLOCK_SERVICE, self.b)

        nw = Wallet()
        dlw = Wallet()
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=nw,
                         constitution={
                             'masternodes': [mn_wallet.verifying_key],
                             'delegates': [dlw.verifying_key]
                         },
                         driver=driver)

        self.authenticator.add_verifying_key(mn_wallet.verifying_key)
        self.authenticator.add_verifying_key(nw.verifying_key)
        self.authenticator.add_verifying_key(dlw.verifying_key)
        self.authenticator.configure()

        blocks = generate_blocks(4)

        self.blocks.store_block(blocks[0])
        self.blocks.store_block(blocks[1])
        self.blocks.store_block(blocks[2])

        storage.set_latest_block_height(3, self.driver)

        node.new_block_processor.q.append(blocks[3])

        tasks = asyncio.gather(
            mn_router.serve(),
            node.catchup('tcp://127.0.0.1:18001', mn_wallet.verifying_key),
            stop_server(mn_router, 1))

        self.loop.run_until_complete(tasks)
        self.assertEqual(storage.get_latest_block_height(node.driver), 4)

    def test_should_process_block_false_if_failed_block(self):
        block = {
            'hash': 'f' * 64,
            'number': 1,
            'previous': '0' * 64,
            'subblocks': []
        }

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertFalse(node.should_process(block))

    def test_should_process_block_false_if_current_height_not_increment(self):
        block = {
            'hash': 'a' * 64,
            'number': 2,
            'previous': '0' * 64,
            'subblocks': []
        }

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertFalse(node.should_process(block))

    def test_should_process_block_false_if_previous_if_not_current_hash(self):
        block = {
            'hash': 'a' * 64,
            'number': 1,
            'previous': 'b' * 64,
            'subblocks': []
        }

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertFalse(node.should_process(block))

    def test_should_process_block_false_if_expected_block_not_equal_to_provided_block(
            self):
        block = {
            'hash': 'a' * 64,
            'number': 1,
            'previous': '0' * 64,
            'subblocks': []
        }

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertFalse(node.should_process(block))

    def test_should_process_block_true_if_expected_block_equal_to_block(self):
        block = canonical.block_from_subblocks(subblocks=[],
                                               previous_hash='0' * 64,
                                               block_num=1)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertTrue(node.should_process(block))

    def test_process_new_block_updates_state(self):
        block = canonical.block_from_subblocks(subblocks=[],
                                               previous_hash='0' * 64,
                                               block_num=1)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        node.process_new_block(block)

        self.assertEqual(storage.get_latest_block_height(node.driver), 1)
        self.assertEqual(storage.get_latest_block_hash(node.driver),
                         block['hash'])

    def test_process_new_block_stores_block_if_should_store(self):
        block = canonical.block_from_subblocks(subblocks=[],
                                               previous_hash='0' * 64,
                                               block_num=1)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(
            socket_base='tcp://127.0.0.1:18002',
            ctx=self.ctx,
            wallet=Wallet(),
            constitution={
                'masternodes': [Wallet().verifying_key],
                'delegates': [Wallet().verifying_key]
            },
            driver=driver,
            store=True,
            blocks=self.blocks,
        )

        node.process_new_block(block)

        b = node.blocks.get_block(1)

        self.assertEqual(b, block)

    def test_process_new_block_clears_cache(self):
        block = canonical.block_from_subblocks(subblocks=[],
                                               previous_hash='0' * 64,
                                               block_num=1)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(
            socket_base='tcp://127.0.0.1:18002',
            ctx=self.ctx,
            wallet=Wallet(),
            constitution={
                'masternodes': [Wallet().verifying_key],
                'delegates': [Wallet().verifying_key]
            },
            driver=driver,
            store=True,
            blocks=self.blocks,
        )

        node.driver.cache['test'] = 123

        node.process_new_block(block)

        self.assertIsNone(node.driver.cache.get('test'))

    def test_process_new_block_cleans_nbn(self):
        blocks = generate_blocks(2)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(
            socket_base='tcp://127.0.0.1:18002',
            ctx=self.ctx,
            wallet=Wallet(),
            constitution={
                'masternodes': [Wallet().verifying_key],
                'delegates': [Wallet().verifying_key]
            },
            driver=driver,
            store=True,
            blocks=self.blocks,
        )

        # Add one old and one new block.
        # Function should only delete the old one
        node.new_block_processor.q.append(blocks[0])
        node.new_block_processor.q.append(blocks[1])

        node.process_new_block(blocks[0])

        block = node.new_block_processor.q[0]

        self.assertEqual(block, blocks[1])
        self.assertEqual(len(node.new_block_processor.q), 1)

    def test_start_boots_up_normally(self):
        # This MN will also provide 'catch up' services

        mn_bootnode = 'tcp://127.0.0.1:18001'
        mn_wallet = Wallet()
        mn_router = router.Router(socket_id=mn_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=mn_wallet)

        mn_network = network.Network(wallet=mn_wallet,
                                     ip_string=mn_bootnode,
                                     ctx=self.ctx,
                                     router=mn_router)

        blocks = generate_blocks(4)

        self.blocks.store_block(blocks[0])
        self.blocks.store_block(blocks[1])
        self.blocks.store_block(blocks[2])

        storage.set_latest_block_height(3, self.driver)

        mn_router.add_service(
            base.BLOCK_SERVICE,
            masternode.BlockService(self.blocks, self.driver))

        dl_bootnode = 'tcp://127.0.0.1:18002'
        dl_wallet = Wallet()
        dl_router = router.Router(socket_id=dl_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=dl_wallet)
        dl_network = network.Network(wallet=dl_wallet,
                                     ip_string=dl_bootnode,
                                     ctx=self.ctx,
                                     router=dl_router)

        constitution = {
            'masternodes': [mn_wallet.verifying_key],
            'delegates': [dl_wallet.verifying_key]
        }

        bootnodes = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node_w = Wallet()
        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18003',
                         ctx=self.ctx,
                         wallet=node_w,
                         constitution=constitution,
                         driver=driver,
                         store=False,
                         bootnodes=bootnodes)

        self.authenticator.add_verifying_key(mn_wallet.verifying_key)
        self.authenticator.add_verifying_key(dl_wallet.verifying_key)
        self.authenticator.add_verifying_key(node_w.verifying_key)

        self.authenticator.configure()

        vks = [mn_wallet.verifying_key, dl_wallet.verifying_key]

        tasks = asyncio.gather(
            mn_router.serve(),
            dl_router.serve(),
            mn_network.start(bootnodes, vks),
            dl_network.start(bootnodes, vks),
            stop_server(mn_router, 0.2),
            stop_server(dl_router, 0.2),
        )

        self.loop.run_until_complete(tasks)

        tasks = asyncio.gather(mn_router.serve(), dl_router.serve(),
                               node.start(), stop_server(mn_router, 1),
                               stop_server(dl_router, 1),
                               stop_server(node.router, 1))

        self.loop.run_until_complete(tasks)

        self.assertEqual(storage.get_latest_block_height(node.driver), 3)
        self.assertEqual(storage.get_latest_block_hash(node.driver),
                         blocks[2]['hash'])

    def test_new_block_service_appends_to_q_to_process_msg(self):
        nb = base.NewBlock(driver=ContractDriver())

        msg = 'test'

        self.loop.run_until_complete(nb.process_message(msg))

        self.assertEqual(nb.q, [msg])

    def test_wait_for_next_holds_until_q_len_greater_than_0(self):
        nb = base.NewBlock(driver=ContractDriver())

        msg = 'test'

        async def slow_add():
            await asyncio.sleep(0.5)
            await nb.process_message(msg)

        self.loop.run_until_complete(slow_add())

        self.assertEqual(nb.q, [msg])

    def test_wait_for_next_pops_first_in_q(self):
        nb = base.NewBlock(driver=ContractDriver())

        msg = 'test'

        nb.q.append('first')

        tasks = asyncio.gather(nb.process_message(msg), nb.wait_for_next_nbn())

        _, r = self.loop.run_until_complete(tasks)

        self.assertEqual(r, 'first')

    def test_wait_for_next_clears_q(self):
        nb = base.NewBlock(driver=ContractDriver())

        nb.q.append('first')
        nb.q.append('second')
        nb.q.append('third')

        tasks = asyncio.gather(nb.wait_for_next_nbn())

        self.loop.run_until_complete(tasks)

        self.assertEqual(nb.q, [])

    def test_get_member_peers_returns_vk_ip_pairs(self):
        mn_wallet = Wallet()
        dl_wallet = Wallet()

        mn_bootnode = 'tcp://127.0.0.1:18001'
        dl_bootnode = 'tcp://127.0.0.1:18002'

        constitution = {
            'masternodes': [mn_wallet.verifying_key],
            'delegates': [dl_wallet.verifying_key]
        }

        bootnodes = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node_w = Wallet()
        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18003',
                         ctx=self.ctx,
                         wallet=node_w,
                         constitution=constitution,
                         driver=driver,
                         store=False,
                         bootnodes=bootnodes)

        # Assume caught up state
        node.network.peers = bootnodes

        m = node._get_member_peers('masternodes')
        d = node._get_member_peers('delegates')

        self.assertEqual(m, {mn_wallet.verifying_key: mn_bootnode})
        self.assertEqual(d, {dl_wallet.verifying_key: dl_bootnode})

    def test_get_delegate_peers_returns_deletates(self):
        mn_wallet = Wallet()
        dl_wallet = Wallet()

        mn_bootnode = 'tcp://127.0.0.1:18001'
        dl_bootnode = 'tcp://127.0.0.1:18002'

        constitution = {
            'masternodes': [mn_wallet.verifying_key],
            'delegates': [dl_wallet.verifying_key]
        }

        bootnodes = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node_w = Wallet()
        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18003',
                         ctx=self.ctx,
                         wallet=node_w,
                         constitution=constitution,
                         driver=driver,
                         store=False,
                         bootnodes=bootnodes)

        # Assume caught up state
        node.network.peers = bootnodes

        d = node.get_delegate_peers()

        self.assertEqual(d, {dl_wallet.verifying_key: dl_bootnode})

    def test_get_masternode_peers_gets_masternodes(self):
        mn_wallet = Wallet()
        dl_wallet = Wallet()

        mn_bootnode = 'tcp://127.0.0.1:18001'
        dl_bootnode = 'tcp://127.0.0.1:18002'

        constitution = {
            'masternodes': [mn_wallet.verifying_key],
            'delegates': [dl_wallet.verifying_key]
        }

        bootnodes = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node_w = Wallet()
        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18003',
                         ctx=self.ctx,
                         wallet=node_w,
                         constitution=constitution,
                         driver=driver,
                         store=False,
                         bootnodes=bootnodes)

        # Assume caught up state
        node.network.peers = bootnodes

        m = node.get_masternode_peers()

        self.assertEqual(m, {mn_wallet.verifying_key: mn_bootnode})
コード例 #8
0
ファイル: test_base_node.py プロジェクト: baby636/lamden
    def test_start_boots_up_normally(self):
        # This MN will also provide 'catch up' services

        mn_bootnode = 'tcp://127.0.0.1:18001'
        mn_wallet = Wallet()
        mn_router = router.Router(socket_id=mn_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=mn_wallet)

        mn_network = network.Network(wallet=mn_wallet,
                                     ip_string=mn_bootnode,
                                     ctx=self.ctx,
                                     router=mn_router)

        blocks = generate_blocks(4)

        self.blocks.store_block(blocks[0])
        self.blocks.store_block(blocks[1])
        self.blocks.store_block(blocks[2])

        storage.set_latest_block_height(3, self.driver)

        mn_router.add_service(
            base.BLOCK_SERVICE,
            masternode.BlockService(self.blocks, self.driver))

        dl_bootnode = 'tcp://127.0.0.1:18002'
        dl_wallet = Wallet()
        dl_router = router.Router(socket_id=dl_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=dl_wallet)
        dl_network = network.Network(wallet=dl_wallet,
                                     ip_string=dl_bootnode,
                                     ctx=self.ctx,
                                     router=dl_router)

        constitution = {
            'masternodes': [mn_wallet.verifying_key],
            'delegates': [dl_wallet.verifying_key]
        }

        bootnodes = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node_w = Wallet()
        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18003',
                         ctx=self.ctx,
                         wallet=node_w,
                         constitution=constitution,
                         driver=driver,
                         store=False,
                         bootnodes=bootnodes)

        self.authenticator.add_verifying_key(mn_wallet.verifying_key)
        self.authenticator.add_verifying_key(dl_wallet.verifying_key)
        self.authenticator.add_verifying_key(node_w.verifying_key)

        self.authenticator.configure()

        vks = [mn_wallet.verifying_key, dl_wallet.verifying_key]

        tasks = asyncio.gather(
            mn_router.serve(),
            dl_router.serve(),
            mn_network.start(bootnodes, vks),
            dl_network.start(bootnodes, vks),
            stop_server(mn_router, 0.2),
            stop_server(dl_router, 0.2),
        )

        self.loop.run_until_complete(tasks)

        tasks = asyncio.gather(mn_router.serve(), dl_router.serve(),
                               node.start(), stop_server(mn_router, 1),
                               stop_server(dl_router, 1),
                               stop_server(node.router, 1))

        self.loop.run_until_complete(tasks)

        self.assertEqual(storage.get_latest_block_height(node.driver), 3)
        self.assertEqual(storage.get_latest_block_hash(node.driver),
                         blocks[2]['hash'])