예제 #1
0
파일: server.py 프로젝트: Lamden/contractdb
    async def handle_msg(self, _id, msg):
        # Try to deserialize the message and run it through the rpc service
        try:
            json_command = decode(msg.decode())

            self.log.info('Received command: {}'.format(json_command))

            result = self.interface.process_json_rpc_command(json_command)

        # If this fails, just set the result to None
        except Exception as e:
            self.log.info('EXCEPTION!! -> ', str(e))
            result = None

        # Try to send the message now. This persists if the socket fails.
        sent = False
        while not sent:
            try:
                msg = encode(result).encode()

                self.log.info('result sent: {}, {}'.format(msg, result))
                await self.socket.send_multipart([_id, msg])
                sent = True

            except zmq.error.ZMQError:
                self.log.info('zmq error: {}'.format(zmq.error.ZMQError))
                self.socket.close()
                self.setup_socket()
예제 #2
0
    def test_merkle_leaf_complex_objects_works(self):
        tx_1_raw = b'{"hash": "503fa157e4d990f78f2b032731dffb398f6ff642b6bbc305817e24dd42b33402", "result": "None", "stamps_used": 198, "state": [{"key": "rewards.S:current_votes:masternodes", "value": 20}, {"key": "rewards.S:current_votes:delegates", "value": 20}, {"key": "rewards.S:current_votes:blackhole", "value": 5}, {"key": "rewards.S:current_votes:foundation", "value": 5}, {"key": "rewards.S:current_votes:developer", "value": 450}, {"key": "rewards.S:has_voted:b0fc27299da14bc08834df9c70d73074f3e511a5a91321d4fa413f3401144918", "value": true}, {"key": "rewards.S:vote_count", "value": 5}, {"key": "rewards.S:value", "value": [{"__fixed__": "0.04"}, {"__fixed__": "0.04"}, {"__fixed__": "0.01"}, {"__fixed__": "0.01"}, {"__fixed__": "0.9"}]}, {"key": "rewards.S:election_start", "value": null}, {"key": "currency.balances:b0fc27299da14bc08834df9c70d73074f3e511a5a91321d4fa413f3401144918", "value": {"__fixed__": "535.30200000"}}], "status": 0, "transaction": {"metadata": {"signature": "ceb4630c8be71f2c0c1e059790609fafa6ed948b7fceb4bb44c36dca46848fac8d55fe27f539036fee5bda6d772fff852b622393eab593aa6dce67f93f7d8f08", "timestamp": 1601411941}, "payload": {"contract": "election_house", "function": "vote", "kwargs": {"policy": "rewards", "value": [4, 4, 1, 1, 90]}, "nonce": 3, "processor": "5b09493df6c18d17cc883ebce54fcb1f5afbd507533417fe32c006009a9c3c4a", "sender": "b0fc27299da14bc08834df9c70d73074f3e511a5a91321d4fa413f3401144918", "stamps_supplied": 999}}}'

        tx_1 = decode(tx_1_raw)

        txs = [encode(tx).encode() for tx in [tx_1]]
        expected_tree = merklize(txs)

        w = Wallet()

        input_hash = 'something'
        signature = w.sign(expected_tree[0])

        sbc = {
            'subblock': 1,
            'transactions': [tx_1],
            'input_hash': input_hash,
            'signer': w.verifying_key,
            'merkle_tree': {
                'signature': signature,
                'leaves': expected_tree
            }
        }

        s = contender.SBCInbox()

        self.assertTrue(s.sbc_is_valid(sbc, 1))
예제 #3
0
    def test_sign_works_properly(self):
        w = Wallet()

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

        decoded = decode(tx)

        res = verify(
            w.verifying_key,
            encode(decoded['payload']),
            decoded['metadata']['signature']
        )

        self.assertTrue(res)
예제 #4
0
    def test_serialize_works_properly(self):
        w = Wallet()

        expected = {
            'sender': w.verifying_key,
            'processor': 'b' * 64,
            'stamps_supplied': 123,
            'nonce': 0,
            'contract': 'currency',
            'function': 'transfer',
            'kwargs': {
                'amount': 123,
                'to': 'jeff'
            }
        }

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

        decoded = decode(tx)

        self.assertDictEqual(decoded['payload'], expected)
예제 #5
0
    def get(self, item: str):
        v = self.db.find_one({'_id': item})

        if v is None:
            return None

        return decode(v['v'])
예제 #6
0
    def test_transaction_is_valid_complete_test_passes(self):
        w = Wallet()

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

        decoded = decode(tx)

        client = ContractingClient()
        client.flush()

        client.set_var(contract='currency',
                       variable='balances',
                       arguments=[w.verifying_key],
                       value=1_000_000)

        client.set_var(contract='stamp_cost',
                       variable='S',
                       arguments=['value'],
                       value=20_000)

        transaction.transaction_is_valid(transaction=decoded,
                                         expected_processor='b' * 64,
                                         client=client,
                                         nonces=self.driver)
예제 #7
0
파일: chain.py 프로젝트: Lamden/contractdb
    def get_transaction_by_hash(self, h: str):
        self.cursor.execute('select * from transaction_inputs where hash=?', (h,))
        tx_input = self.cursor.fetchone()

        self.cursor.execute('select * from transaction_outputs where hash=?', (h,))
        tx_output = self.cursor.fetchone()

        tx_hash, _, idx, sender, sig, contract, func, args = tx_input
        args_unpacked = json.loads(args)

        _, _, _, status, updates, result = tx_output
        updates_unpacked = json.loads(updates)

        # Build the dict
        tx = {
            'hash': tx_hash,
            'input': {
                'index': idx,
                'sender': sender,
                'signature': sig,
                'payload': {
                    'contract': contract,
                    'function': func,
                    'arguments': args_unpacked
                }
            },
            'output': {
                'status': status,
                'updates': updates_unpacked,
                'result': decode(result)
            }
        }

        return tx
예제 #8
0
def build_transaction(wallet, contract: str, function: str, kwargs: dict,
                      nonce: int, processor: str, stamps: int):
    payload = {
        'contract': contract,
        'function': function,
        'kwargs': kwargs,
        'nonce': nonce,
        'processor': processor,
        'sender': wallet.verifying_key,
        'stamps_supplied': stamps,
    }

    payload = format_dictionary(
        payload)  # Sort payload in case kwargs unsorted

    assert check_format(
        payload, rules.TRANSACTION_PAYLOAD_RULES), 'Invalid payload provided!'

    true_payload = encode(decode(encode(payload)))

    signature = wallet.sign(true_payload)

    metadata = {'signature': signature, 'timestamp': int(time.time())}

    tx = {'payload': payload, 'metadata': metadata}

    return encode(format_dictionary(tx))
예제 #9
0
    async def submit_transaction(self, request):
        log.debug(f'New request: {request}')
        # Reject TX if the queue is too large
        if len(self.queue) >= self.max_queue_len:
            return response.json({'error': "Queue full. Resubmit shortly."},
                                 status=503,
                                 headers={'Access-Control-Allow-Origin': '*'})

        tx_raw = _json.loads(request.body)
        log.error(tx_raw)
        # Check that the payload is valid JSON
        tx = decode(request.body)
        if tx is None:
            return response.json({'error': 'Malformed request body.'},
                                 headers={'Access-Control-Allow-Origin': '*'})

        # Check that the TX is correctly formatted
        try:
            transaction.check_tx_formatting(tx, self.wallet.verifying_key)

            transaction.transaction_is_valid(
                transaction=tx,
                expected_processor=self.wallet.verifying_key,
                client=self.client,
                nonces=self.nonces)

            nonce, pending_nonce = transaction.get_nonces(
                sender=tx['payload']['sender'],
                processor=tx['payload']['processor'],
                driver=self.nonces)

            pending_nonce = transaction.get_new_pending_nonce(
                tx_nonce=tx['payload']['nonce'],
                nonce=nonce,
                pending_nonce=pending_nonce)

            self.nonces.set_pending_nonce(sender=tx['payload']['sender'],
                                          processor=tx['payload']['processor'],
                                          value=pending_nonce)
        except TransactionException as e:
            log.error(f'Tx has error: {type(e)}')
            log.error(tx)
            return response.json(transaction.EXCEPTION_MAP[type(e)],
                                 headers={'Access-Control-Allow-Origin': '*'})

        # Add TX to the processing queue
        self.queue.append(request.body)
        log.error('Added to q')

        # Return the TX hash to the user so they can track it
        tx_hash = tx_hash_from_tx(tx)

        return response.json(
            {
                'success':
                'Transaction successfully submitted to the network.',
                'hash': tx_hash
            },
            headers={'Access-Control-Allow-Origin': '*'})
예제 #10
0
    def get(self, item: str):
        with self.db_reader.begin() as tx:
            v = tx.get(item.encode())

        if v is None:
            return None

        return decode(v)
예제 #11
0
파일: base.py 프로젝트: Lamden/lamden
    def pop(self, idx):
        items = sorted(self.root.iterdir(), key=os.path.getmtime)
        item = items.pop(idx)

        with open(item) as f:
            i = decode(f.read())

        os.remove(item)

        return i
예제 #12
0
    def get(self, item: str):
        try:
            filename = self._key_to_file(item)
            with open(filename, 'r') as f:
                v = f.read()

        except FileNotFoundError:
            return None

        return decode(v)
예제 #13
0
    def get(self, item: str):
        # supports item strings like contract.variable:key1:key2

        contract, args = item.split('.')
        args = args.split(':')
        variable = args.pop(0)

        keys = ','.join(args)

        r = requests.get(f'{self.masternode}/contracts/{contract}/{variable}?key={keys}')
        return decode(r.json()['value'])
예제 #14
0
        async def request(msg):
            msg = encode(msg).encode()

            socket = self.ctx.socket(zmq.DEALER)
            socket.connect('ipc:///tmp/router')

            await socket.send(msg)

            resp = await socket.recv()

            resp = decode(resp)

            return resp
예제 #15
0
    def test_transaction_is_not_expired_true_if_within_timeout(self):
        w = Wallet()

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

        decoded = decode(tx)
        transaction.transaction_is_not_expired(decoded)
예제 #16
0
    def test_future_transactions_fine_if_in_expiry(self):
        w = Wallet()

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

        decoded = decode(tx)
        decoded['metadata']['timestamp'] += 4

        transaction.transaction_is_not_expired(decoded)
예제 #17
0
    def test_check_tx_formatting_incorrect_processor_fails(self):
        w = Wallet()

        tx = build_transaction(wallet=w,
                               processor='b' * 64,
                               stamps=123,
                               nonce=0,
                               contract='currency',
                               function='transfer',
                               kwargs={
                                   'amount': 123.0,
                                   'to': 'jeff'
                               })

        decoded = decode(tx)

        with self.assertRaises(transaction.TransactionProcessorInvalid):
            transaction.check_tx_formatting(decoded, 'c' * 64)
예제 #18
0
파일: router.py 프로젝트: baby636/lamden
async def secure_request(msg: dict, service: str, wallet: Wallet, vk: str, ip: str, ctx: zmq.asyncio.Context,
                         linger=500, timeout=1000, cert_dir=DEFAULT_DIR):
    #if wallet.verifying_key == vk:
    #    return

    socket = ctx.socket(zmq.DEALER)
    socket.setsockopt(zmq.LINGER, linger)
    socket.setsockopt(zmq.TCP_KEEPALIVE, 1)

    socket.curve_secretkey = wallet.curve_sk
    socket.curve_publickey = wallet.curve_vk

    filename = str(cert_dir / f'{vk}.key')
    if not os.path.exists(filename):
        return None

    server_pub, _ = load_certificate(filename)

    socket.curve_serverkey = server_pub

    try:
        socket.connect(ip)
    except ZMQBaseError:
        logger.debug(f'Could not connect to {ip}')
        socket.close()
        return None

    message = build_message(service=service, message=msg)

    payload = encode(message).encode()

    await socket.send(payload)

    event = await socket.poll(timeout=timeout, flags=zmq.POLLIN)
    msg = None
    if event:
        #logger.debug(f'Message received on {ip}')
        response = await socket.recv()

        msg = decode(response)

    socket.close()

    return msg
예제 #19
0
파일: chain.py 프로젝트: Lamden/contractdb
    def _build_block(block, tx_inputs, tx_outputs):
        block_dict = {
            'hash': block[0],
            'index': block[1],
            'transactions': []
        }

        # Iterate through all transactions fetched
        for i in range(len(tx_inputs)):
            # Unpack the arguments in a concise way
            tx_hash, _, idx, sender, sig, contract, func, args = tx_inputs[i]
            args_unpacked = json.loads(args)

            _, _, _, status, updates, result = tx_outputs[i]
            updates_unpacked = json.loads(updates)

            # Build the dict
            tx = {
                'hash': tx_hash,
                'input': {
                    'index': idx,
                    'sender': sender,
                    'signature': sig,
                    'payload': {
                        'contract': contract,
                        'function': func,
                        'arguments': args_unpacked
                    }
                },
                'output': {
                    'status': status,
                    'updates': updates_unpacked,
                    'result': decode(result)
                }
            }

            # Add the dict to the transactions list
            block_dict['transactions'].append(tx)

        # Sort transactions by index
        sorted(block_dict['transactions'], key=lambda t: t['input']['index'])

        return block_dict
예제 #20
0
    def test_check_tx_formatting_signature_fails(self):
        w = Wallet()

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

        decoded = decode(tx)
        decoded['payload']['sender'] = 'a' * 64

        with self.assertRaises(transaction.TransactionSignatureInvalid):
            transaction.check_tx_formatting(decoded, 'b' * 64)
예제 #21
0
    def test_transaction_is_expired_false_if_outside_timeout(self):
        w = Wallet()

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

        decoded = decode(tx)
        decoded['metadata']['timestamp'] -= 1000

        with self.assertRaises(transaction.TransactionStaleError):
            transaction.transaction_is_not_expired(decoded)
예제 #22
0
    def test_future_transactions_raise_error_if_beyond_expiry(self):
        w = Wallet()

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

        decoded = decode(tx)
        decoded['metadata']['timestamp'] += 6

        with self.assertRaises(transaction.TransactionInvalidTimestampError):
            transaction.transaction_is_not_expired(decoded)
예제 #23
0
    def test_check_tx_formatting_succeeds(self):
        w = Wallet()

        tx = build_transaction(
            wallet=w,
            processor='b' * 64,
            stamps=123,
            nonce=0,
            contract='currency',
            function='transfer',
            kwargs={
                'amount': decimal.Decimal('123.872345873452873459873459870'),
                'to': 'jeff'
            })

        decoded = decode(tx)

        error = transaction.check_tx_formatting(decoded, 'b' * 64)
        self.assertIsNone(error)
예제 #24
0
    def test_check_tx_formatting_not_formatted_fails(self):
        w = Wallet()

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

        decoded = decode(tx)
        decoded['payload']['nonce'] = -123

        with self.assertRaises(transaction.TransactionFormattingError):
            transaction.check_tx_formatting(decoded, 'b' * 64)
def execute_tx(executor: Executor,
               transaction,
               stamp_cost,
               environment: dict = {},
               debug=True):
    # Deserialize Kwargs. Kwargs should be serialized JSON moving into the future for DX.
    kwargs = decode(transaction.payload.kwargs)

    output = executor.execute(sender=transaction.payload.sender.hex(),
                              contract_name=transaction.payload.contractName,
                              function_name=transaction.payload.functionName,
                              stamps=transaction.payload.stampsSupplied,
                              stamp_cost=stamp_cost,
                              kwargs=kwargs,
                              environment=environment,
                              auto_commit=False)

    if debug:
        log.error(output)

    deltas = []
    for k, v in output['writes'].items():
        key, value = encode_kv(k, v)
        d = transaction_capnp.Delta.new_message(key=key, value=value)
        deltas.append(d)

    tx_hash = tx_hash_from_tx(transaction)

    # Encode deltas into a Capnp struct
    tx_output = transaction_capnp.TransactionData.new_message(
        hash=tx_hash,
        transaction=transaction,
        status=output['status_code'],
        state=deltas,
        stampsUsed=output['stamps_used'])

    executor.driver.pending_writes.clear()  # add

    return tx_output
예제 #26
0
    def test_bigint_decode(self):
        _bi = '{"__big_int__":' + str(MONGO_MAX_INT + 1) + '}'

        self.assertEqual(decode(_bi), MONGO_MAX_INT + 1)
예제 #27
0
    def test_int_decode(self):
        i = '10'

        self.assertEqual(10, decode(i))
예제 #28
0
    def test_timedelta_decode(self):
        _t = '{"__delta__": [8, 0]}'

        t = decode(_t)

        self.assertEqual(t, Timedelta(weeks=1, days=1))
예제 #29
0
    def test_date_decode(self):
        _d = '{"__time__": [2019, 1, 1, 0, 0, 0, 0]}'

        d = decode(_d)

        self.assertEqual(Datetime(2019, 1, 1), d)
예제 #30
0
    def test_decode_failure(self):
        b = b'xwow'

        self.assertIsNone(decode(b))