Пример #1
0
    def setUpClass(cls, handler, client_class=None):
        url = os.getenv('TEST_BIND', 'tcp://127.0.0.1:4004')

        cls.validator = RemmeMockValidator()

        cls.validator.listen(url)

        for item in TP_HANDLERS:
            if not cls.validator.register_processor():
                raise Exception('Failed to register processor')

        cls.factory = None

        cls._zmq_patcher = mock.patch('remme.clients.basic.Stream',
                                      return_value=cls.validator)
        cls._zmq_patcher_obj = cls._zmq_patcher.start()

        cls.handler = handler
        cls.client_class = client_class

        cls._pk_patcher = mock.patch(
            'remme.clients.basic.BasicClient.get_signer_priv_key_from_file',
            return_value=BasicClient.generate_signer())
        cls._pk_patcher_obj = cls._pk_patcher.start()

        # generate token account addresses
        cls.account_signer1 = cls.get_new_signer()
        cls.account_address1 = AccountHandler.make_address_from_data(
            cls.account_signer1.get_public_key().as_hex())
        cls.account_signer2 = cls.get_new_signer()
        cls.account_address2 = AccountHandler.make_address_from_data(
            cls.account_signer2.get_public_key().as_hex())

        cls._factory = cls.handler.get_message_factory(cls.account_signer1)
Пример #2
0
    def _swap_expire(self, context, signer_pubkey, swap_expire_payload):
        """
        Transaction initiator (Alice) decides to withdraw deposit in 24 hours, or Bob in 48 hours

        """

        swap_info = self.get_swap_info_from_swap_id(
            context, swap_expire_payload.swap_id)

        if AccountHandler().make_address_from_data(
                signer_pubkey) != swap_info.sender_address:
            raise InvalidTransaction(
                'Signer is not the one who opened the swap.')

        now = datetime.datetime.utcnow()
        created_at = self.get_datetime_from_timestamp(swap_info.created_at)
        time_delta = INITIATOR_TIME_DELTA_LOCK if swap_info.is_initiator else NON_INITIATOR_TIME_DELTA_LOCK
        if (created_at + time_delta) > now:
            intiator_name = "initiator" if swap_info.is_initiator else "non initiator"
            raise InvalidTransaction(
                'Swap {} needs to wait {} hours since timestamp: {} to withdraw.'
                .format(intiator_name, INTIATOR_TIME_LOCK,
                        swap_info.created_at))

        swap_info.state = AtomicSwapInfo.EXPIRED

        transfer_payload = AccountClient.get_transfer_payload(
            swap_info.sender_address, swap_info.amount)
        token_updated_state = AccountHandler()._transfer_from_address(
            context, ZERO_ADDRESS, transfer_payload)

        return {**self.get_state_update(swap_info), **token_updated_state}
Пример #3
0
def test_account_handler_apply_decode_error():
    """
    Case: send transaction request, to send tokens to address, to account handler with invalid transaction payload.
    Expect: invalid transaction error is raised cannot decode transaction payload error message.
    """
    serialized_not_valid_transaction_payload = b'F1120071db7c02f5731d06df194dc95465e9b27'

    transaction_header = TransactionHeader(
        signer_public_key=RANDOM_NODE_PUBLIC_KEY,
        family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_name'),
        family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_version'),
        inputs=INPUTS,
        outputs=OUTPUTS,
        dependencies=[],
        payload_sha512=hash512(data=serialized_not_valid_transaction_payload),
        batcher_public_key=RANDOM_NODE_PUBLIC_KEY,
        nonce=time.time().hex().encode(),
    )

    serialized_header = transaction_header.SerializeToString()

    transaction_request = TpProcessRequest(
        header=transaction_header,
        payload=serialized_not_valid_transaction_payload,
        signature=create_signer(private_key=ACCOUNT_FROM_PRIVATE_KEY).sign(serialized_header),
    )
    mock_context = create_context(account_from_balance=ACCOUNT_FROM_BALANCE, account_to_balance=ACCOUNT_TO_BALANCE)

    with pytest.raises(InvalidTransaction) as error:
        AccountHandler().apply(transaction=transaction_request, context=mock_context)

    assert 'Cannot decode transaction payload.' == str(error.value)
Пример #4
0
    def _swap_approve(self, context, signer_pubkey, swap_approve_payload):
        """

        Only called by Alice to approve REMchain => other transaction for Bob to close it.

        """
        LOGGER.info('swap id: {}'.format(swap_approve_payload.swap_id))
        swap_info = self.get_swap_info_from_swap_id(
            context, swap_approve_payload.swap_id)

        if not swap_info.is_initiator or swap_info.sender_address != AccountHandler(
        ).make_address_from_data(signer_pubkey):
            raise InvalidTransaction(
                'Only transaction initiator (Alice) may approve the swap, '
                'once Bob provided a secret lock.')
        if not swap_info.secret_lock:
            raise InvalidTransaction(
                'Secret Lock is needed for Bob to provide a secret key.')

        if swap_info.state != AtomicSwapInfo.SECRET_LOCK_PROVIDED:
            raise InvalidTransaction('Swap id {} is already closed.'.format(
                swap_info.swap_id))

        swap_info.state = AtomicSwapInfo.APPROVED

        return self.get_state_update(swap_info)
Пример #5
0
    def _swap_close(self, context, signer_pubkey, swap_close_payload):
        """
        Bob or Alice closes the swap by providing the secret key which matches secret lock.
        Requires "is_approved = True"
        Requires hash of secret key to match secret lock

        """
        swap_info = self.get_swap_info_from_swap_id(context,
                                                    swap_close_payload.swap_id)

        if not swap_info.secret_lock:
            raise InvalidTransaction(
                'Secret lock is required to close the swap!')

        if web3_hash(swap_close_payload.secret_key) != swap_info.secret_lock:
            raise InvalidTransaction(
                'Secret key doesn\'t match specified secret lock!')

        if swap_info.is_initiator and swap_info.state != AtomicSwapInfo.APPROVED:
            raise InvalidTransaction(
                'Transaction cannot be closed before it\'s approved.')

        transfer_payload = AccountClient.get_transfer_payload(
            swap_info.receiver_address, swap_info.amount)
        token_updated_state = AccountHandler()._transfer_from_address(
            context, ZERO_ADDRESS, transfer_payload)
        swap_info.state = AtomicSwapInfo.CLOSED

        return {**self.get_state_update(swap_info), **token_updated_state}
Пример #6
0
def test_account_handler_apply():
    """
    Case: send transaction request, to send tokens to address, to the account handler.
    Expect: addresses data, stored in state, are changed according to transfer amount.
    """
    expected_account_from_balance = ACCOUNT_FROM_BALANCE - TOKENS_AMOUNT_TO_SEND
    expected_account_to_balance = ACCOUNT_TO_BALANCE + TOKENS_AMOUNT_TO_SEND

    account_protobuf = Account()

    account_protobuf.balance = expected_account_from_balance
    expected_serialized_account_from_balance = account_protobuf.SerializeToString()

    account_protobuf.balance = expected_account_to_balance
    expected_serialized_account_to_balance = account_protobuf.SerializeToString()

    expected_state = {
        ACCOUNT_ADDRESS_FROM: expected_serialized_account_from_balance,
        ACCOUNT_ADDRESS_TO: expected_serialized_account_to_balance,
    }

    transfer_payload = TransferPayload()
    transfer_payload.address_to = ACCOUNT_ADDRESS_TO
    transfer_payload.value = TOKENS_AMOUNT_TO_SEND

    transaction_payload = TransactionPayload()
    transaction_payload.method = AccountMethod.TRANSFER
    transaction_payload.data = transfer_payload.SerializeToString()

    serialized_transaction_payload = transaction_payload.SerializeToString()

    transaction_header = TransactionHeader(
        signer_public_key=RANDOM_NODE_PUBLIC_KEY,
        family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_name'),
        family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_version'),
        inputs=INPUTS,
        outputs=OUTPUTS,
        dependencies=[],
        payload_sha512=hash512(data=serialized_transaction_payload),
        batcher_public_key=RANDOM_NODE_PUBLIC_KEY,
        nonce=time.time().hex().encode(),
    )

    serialized_header = transaction_header.SerializeToString()

    transaction_request = TpProcessRequest(
        header=transaction_header,
        payload=serialized_transaction_payload,
        signature=create_signer(private_key=ACCOUNT_FROM_PRIVATE_KEY).sign(serialized_header),
    )

    mock_context = create_context(account_from_balance=ACCOUNT_FROM_BALANCE, account_to_balance=ACCOUNT_TO_BALANCE)

    AccountHandler().apply(transaction=transaction_request, context=mock_context)

    state_as_list = mock_context.get_state(addresses=[ACCOUNT_ADDRESS_TO, ACCOUNT_ADDRESS_FROM])
    state_as_dict = {entry.address: entry.data for entry in state_as_list}

    assert expected_state == state_as_dict
Пример #7
0
    def _store_pub_key(self, context, signer_pubkey, transaction_payload):
        address = self.make_address_from_data(transaction_payload.public_key)
        LOGGER.info('Pub key address {}'.format(address))

        account_address = AccountHandler().make_address_from_data(signer_pubkey)
        LOGGER.info('Account address {}'.format(address))
        data, account = get_multiple_data(context, [(address, PubKeyStorage), (account_address, Account)])
        if data:
            raise InvalidTransaction('This pub key is already registered.')

        cert_signer_pubkey = load_pem_public_key(transaction_payload.public_key.encode('utf-8'),
                                                 backend=default_backend())
        try:
            ehs_bytes = binascii.unhexlify(transaction_payload.entity_hash_signature)
            eh_bytes = binascii.unhexlify(transaction_payload.entity_hash)
        except binascii.Error:
            LOGGER.debug(f'entity_hash_signature {transaction_payload.entity_hash_signature}')
            LOGGER.debug(f'entity_hash {transaction_payload.entity_hash}')
            raise InvalidTransaction('Entity hash or signature not a hex format')

        # FIXME: For support PKCS1v15 and PSS
        LOGGER.warn('HAZARD: Detecting padding for verification')
        sigerr = 0
        pkcs = padding.PKCS1v15()
        pss = padding.PSS(mgf=padding.MGF1(hashes.SHA512()), salt_length=padding.PSS.MAX_LENGTH)
        for _padding in (pkcs, pss):
            try:
                cert_signer_pubkey.verify(ehs_bytes, eh_bytes, _padding, hashes.SHA512())
                LOGGER.warn('HAZARD: Padding found: %s', _padding.name)
            except InvalidSignature:
                sigerr += 1

        if sigerr == 2:
            raise InvalidTransaction('Invalid signature')

        valid_from = datetime.fromtimestamp(transaction_payload.valid_from)
        valid_to = datetime.fromtimestamp(transaction_payload.valid_to)

        if valid_to - valid_from > PUB_KEY_MAX_VALIDITY:
            raise InvalidTransaction('The public key validity exceeds the maximum value.')

        data = PubKeyStorage()
        data.owner = signer_pubkey
        data.payload.CopyFrom(transaction_payload)
        data.revoked = False

        if not account:
            account = Account()
        if _get_setting_value(context, 'remme.economy_enabled', 'true').lower() == 'true':
            if account.balance < PUB_KEY_STORE_PRICE:
                raise InvalidTransaction('Not enough tokens to register a new pub key. Current balance: {}'
                                         .format(account.balance))
            account.balance -= PUB_KEY_STORE_PRICE

        if address not in account.pub_keys:
            account.pub_keys.append(address)

        return {address: data,
                account_address: account}
Пример #8
0
    def store_pub_key(self, public_key, entity_hash, entity_hash_signature,
                      valid_from, valid_to):
        payload = self.get_new_pub_key_payload(public_key, entity_hash,
                                               entity_hash_signature,
                                               valid_from, valid_to)

        crt_address = self.make_address_from_data(public_key)

        account_address = AccountHandler.make_address_from_data(
            self._signer.get_public_key().as_hex())
        return self._send_transaction(
            PubKeyMethod.STORE, payload,
            [crt_address, account_address]), crt_address
Пример #9
0
    def store_pub_key(self, public_key, entity_hash, entity_hash_signature, valid_from, valid_to):
        payload = self.get_new_pub_key_payload(public_key,
                                               entity_hash,
                                               entity_hash_signature,
                                               valid_from,
                                               valid_to)

        crt_address = self.make_address_from_data(public_key)
        account_address = AccountHandler.make_address_from_data(self._signer.get_public_key().as_hex())
        settings_address = _make_settings_key('remme.economy_enabled')
        addresses_input = [crt_address, account_address, settings_address, self.get_user_address()]
        addresses_output = [crt_address, self.get_user_address()]
        return self._send_transaction(PubKeyMethod.STORE, payload, addresses_input, addresses_output), crt_address
Пример #10
0
    def test_store_success(self):
        context = self.get_context()

        cert, key, _ = PubKeyClient.create_certificate(
            context.pub_key_payload, signer=context.client.get_signer())

        transaction_signature, cert_address, transaction_payload = self._pre_parse_payload_and_exec(
            context, cert, key)
        crt_export, crt_bin, crt_sig, rem_sig, pub_key, \
            valid_from, valid_to = PubKeyClient.get_crt_export_bin_sig_rem_sig(cert, key, context.client)

        account = AccountClient.get_account_model(PUB_KEY_STORE_PRICE)

        storage_account = AccountClient.get_account_model(0)
        storage_signer = self.get_new_signer()
        storage_pub_key = storage_signer.get_public_key().as_hex()
        storage_address = AccountHandler().make_address_from_data(
            storage_pub_key)

        data = PubKeyStorage()
        data.owner = self.account_signer1.get_public_key().as_hex()
        data.payload.CopyFrom(transaction_payload)
        data.revoked = False

        self.expect_get({cert_address: None, self.account_address1: account})
        self.expect_get({_make_settings_key('remme.economy_enabled'): None})
        self.expect_get({
            _make_settings_key(SETTINGS_STORAGE_PUB_KEY):
            get_setting_from_key_value(SETTINGS_STORAGE_PUB_KEY,
                                       storage_pub_key)
        })
        self.expect_get({
            self.account_address1: account,
            storage_address: storage_account
        })

        context.client.store_pub_key(pub_key, rem_sig, crt_sig, valid_from,
                                     valid_to)

        account.balance -= PUB_KEY_STORE_PRICE
        account.pub_keys.append(cert_address)
        storage_account.balance += PUB_KEY_STORE_PRICE

        self.expect_set(
            transaction_signature, PubKeyMethod.STORE, {
                self.account_address1: account,
                cert_address: data,
                storage_address: storage_account
            })

        self.expect_ok()
Пример #11
0
def test_account_handler_genesis_already_initialized():
    """
    Case: send transaction request, to send tokens from genesis address,
        to the account handler when genesis was already initialized.
    Expect: invalid transaction error is raised with genesis is already initialized error message.
    """
    genesis_payload = GenesisPayload()
    genesis_payload.total_supply = TOKENS_AMOUNT_TO_SUPPLY

    transaction_payload = TransactionPayload()
    transaction_payload.method = AccountMethod.GENESIS
    transaction_payload.data = genesis_payload.SerializeToString()

    serialized_transaction_payload = transaction_payload.SerializeToString()

    transaction_header = TransactionHeader(
        signer_public_key=NODE_PUBLIC_KEY,
        family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get(
            'family_name'),
        family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get(
            'family_version'),
        inputs=INPUTS,
        outputs=OUTPUTS,
        dependencies=[],
        payload_sha512=hash512(data=serialized_transaction_payload),
        batcher_public_key=NODE_PUBLIC_KEY,
        nonce=time.time().hex().encode(),
    )

    serialized_header = transaction_header.SerializeToString()

    transaction_request = TpProcessRequest(
        header=transaction_header,
        payload=serialized_transaction_payload,
        signature=create_signer(
            private_key=NODE_PRIVATE_KEY).sign(serialized_header),
    )

    genesis_status = GenesisStatus()
    genesis_status.status = True

    mock_context = StubContext(
        inputs=INPUTS,
        outputs=OUTPUTS,
        initial_state={GENESIS_ADDRESS: genesis_status.SerializeToString()})

    with pytest.raises(InvalidTransaction) as error:
        AccountHandler().apply(transaction=transaction_request,
                               context=mock_context)

    assert f'Genesis is already initialized.' == str(error.value)
Пример #12
0
    def _swap_expire(self, context, signer_pubkey, swap_expire_payload):
        """
        Transaction initiator (Alice) decides to withdraw deposit in 24 hours, or Bob in 48 hours

        """

        swap_info = self.get_swap_info_from_swap_id(
            context, swap_expire_payload.swap_id)

        if AccountHandler() \
           .make_address_from_data(signer_pubkey) != swap_info.sender_address:
            raise InvalidTransaction('Signer is not the one who opened '
                                     'the swap.')

        block = self._get_latest_block_info(context)
        block_time = self.get_datetime_from_timestamp(block.timestamp)

        created_at = self.get_datetime_from_timestamp(swap_info.created_at)
        time_delta = INITIATOR_TIME_DELTA_LOCK \
            if swap_info.is_initiator else NON_INITIATOR_TIME_DELTA_LOCK
        if (created_at + time_delta) > block_time:
            intiator_name = "initiator" \
                if swap_info.is_initiator else "non initiator"
            raise InvalidTransaction(f'Swap {intiator_name} needs to wait '
                                     f'{INTIATOR_TIME_LOCK} hours since '
                                     f'timestamp: {swap_info.created_at} '
                                     f'to withdraw.')

        swap_info.state = AtomicSwapInfo.EXPIRED

        transfer_payload = AccountClient \
            .get_transfer_payload(swap_info.sender_address, swap_info.amount)
        token_updated_state = AccountHandler() \
            ._transfer_from_address(context, ZERO_ADDRESS, transfer_payload)

        return {**self.get_state_update(swap_info), **token_updated_state}
Пример #13
0
def test_account_handler_genesis_apply_with_empty_proto():
    """
    Case: send transaction request of genesis with empty proto
    Expect: invalid transaction error
    """
    genesis_payload = GenesisPayload()

    transaction_payload = TransactionPayload()
    transaction_payload.method = AccountMethod.GENESIS
    transaction_payload.data = genesis_payload.SerializeToString()

    serialized_transaction_payload = transaction_payload.SerializeToString()

    transaction_header = TransactionHeader(
        signer_public_key=NODE_PUBLIC_KEY,
        family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get(
            'family_name'),
        family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get(
            'family_version'),
        inputs=INPUTS,
        outputs=OUTPUTS,
        dependencies=[],
        payload_sha512=hash512(data=serialized_transaction_payload),
        batcher_public_key=NODE_PUBLIC_KEY,
        nonce=time.time().hex().encode(),
    )

    serialized_header = transaction_header.SerializeToString()

    transaction_request = TpProcessRequest(
        header=transaction_header,
        payload=serialized_transaction_payload,
        signature=create_signer(
            private_key=NODE_PRIVATE_KEY).sign(serialized_header),
    )

    mock_context = StubContext(inputs=INPUTS,
                               outputs=OUTPUTS,
                               initial_state={})

    with pytest.raises(InvalidTransaction) as error:
        AccountHandler().apply(transaction=transaction_request,
                               context=mock_context)

    assert proto_error_msg(
        GenesisPayload,
        {'total_supply': ['This field is required.']}) == str(error.value)
Пример #14
0
def test_account_transfer_from_address_to_address_not_account_type():
    """
    Case: transfer tokens from address to address that is not account type.
    Expect: invalid transaction error is raised with receiver address is not account type error message.
    """
    mock_context = create_context(account_from_balance=ACCOUNT_FROM_BALANCE, account_to_balance=ACCOUNT_TO_BALANCE)

    transfer_payload = TransferPayload()
    transfer_payload.address_to = ADDRESS_NOT_ACCOUNT_TYPE
    transfer_payload.value = TOKENS_AMOUNT_TO_SEND

    transaction_payload = TransactionPayload()
    transaction_payload.method = AccountMethod.TRANSFER
    transaction_payload.data = transfer_payload.SerializeToString()

    serialized_transaction_payload = transaction_payload.SerializeToString()

    transaction_header = TransactionHeader(
        signer_public_key=RANDOM_NODE_PUBLIC_KEY,
        family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_name'),
        family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_version'),
        inputs=INPUTS,
        outputs=OUTPUTS,
        dependencies=[],
        payload_sha512=hash512(data=serialized_transaction_payload),
        batcher_public_key=RANDOM_NODE_PUBLIC_KEY,
        nonce=time.time().hex().encode(),
    )

    serialized_header = transaction_header.SerializeToString()

    transaction_request = TpProcessRequest(
        header=transaction_header,
        payload=serialized_transaction_payload,
        signature=create_signer(private_key=ACCOUNT_FROM_PRIVATE_KEY).sign(serialized_header),
    )

    with pytest.raises(InvalidTransaction) as error:
        AccountHandler().apply(transaction=transaction_request, context=mock_context)

    assert proto_error_msg(
        TransferPayload,
        {
            'address_to': ['Address is not of a blockchain token type.'],
        }
    ) == str(error.value)
Пример #15
0
def test_account_transfer_from_address_without_previous_usage():
    """
    Case: transfer tokens from address to address when them have never been used before.
    Expect: invalid transaction error is raised with not enough transferable balance error message.
    """
    initial_state = {
        ACCOUNT_ADDRESS_FROM: None,
        ACCOUNT_ADDRESS_TO: None,
    }

    mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state=initial_state)

    transfer_payload = TransferPayload()
    transfer_payload.address_to = ACCOUNT_ADDRESS_TO
    transfer_payload.value = TOKENS_AMOUNT_TO_SEND

    transaction_payload = TransactionPayload()
    transaction_payload.method = AccountMethod.TRANSFER
    transaction_payload.data = transfer_payload.SerializeToString()

    serialized_transaction_payload = transaction_payload.SerializeToString()

    transaction_header = TransactionHeader(
        signer_public_key=RANDOM_NODE_PUBLIC_KEY,
        family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_name'),
        family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_version'),
        inputs=INPUTS,
        outputs=OUTPUTS,
        dependencies=[],
        payload_sha512=hash512(data=serialized_transaction_payload),
        batcher_public_key=RANDOM_NODE_PUBLIC_KEY,
        nonce=time.time().hex().encode(),
    )

    serialized_header = transaction_header.SerializeToString()

    transaction_request = TpProcessRequest(
        header=transaction_header,
        payload=serialized_transaction_payload,
        signature=create_signer(private_key=ACCOUNT_FROM_PRIVATE_KEY).sign(serialized_header),
    )

    with pytest.raises(InvalidTransaction) as error:
        AccountHandler().apply(transaction=transaction_request, context=mock_context)

    assert f'Not enough transferable balance. Sender\'s current balance: 0.' == str(error.value)
Пример #16
0
def test_account_handler_with_empty_proto():
    """
    Case: send transaction request with empty proto
    Expect: invalid transaction error
    """
    transfer_payload = TransferPayload()

    transaction_payload = TransactionPayload()
    transaction_payload.method = AccountMethod.TRANSFER
    transaction_payload.data = transfer_payload.SerializeToString()

    serialized_transaction_payload = transaction_payload.SerializeToString()

    transaction_header = TransactionHeader(
        signer_public_key=RANDOM_NODE_PUBLIC_KEY,
        family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_name'),
        family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_version'),
        inputs=INPUTS,
        outputs=OUTPUTS,
        dependencies=[],
        payload_sha512=hash512(data=serialized_transaction_payload),
        batcher_public_key=RANDOM_NODE_PUBLIC_KEY,
        nonce=time.time().hex().encode(),
    )

    serialized_header = transaction_header.SerializeToString()

    transaction_request = TpProcessRequest(
        header=transaction_header,
        payload=serialized_transaction_payload,
        signature=create_signer(private_key=ACCOUNT_FROM_PRIVATE_KEY).sign(serialized_header),
    )

    mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={})

    with pytest.raises(InvalidTransaction) as error:
        AccountHandler().apply(transaction=transaction_request, context=mock_context)

    assert proto_error_msg(
        TransferPayload,
        {
            'address_to': ['Missed address'],
            'value': ['Could not transfer with zero amount.'],
        }
    ) == str(error.value)
Пример #17
0
def test_account_handler_apply_invalid_transfer_method():
    """
    Case: send transaction request, to send tokens to address, to account handler with invalid transfer method value.
    Expect: invalid transaction error is raised with invalid account method value error message.
    """
    account_method_impossible_value = 5347

    transfer_payload = TransferPayload()
    transfer_payload.address_to = ACCOUNT_ADDRESS_TO
    transfer_payload.value = TOKENS_AMOUNT_TO_SEND

    transaction_payload = TransactionPayload()
    transaction_payload.method = account_method_impossible_value
    transaction_payload.data = transfer_payload.SerializeToString()

    serialized_transaction_payload = transaction_payload.SerializeToString()

    transaction_header = TransactionHeader(
        signer_public_key=RANDOM_NODE_PUBLIC_KEY,
        family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_name'),
        family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_version'),
        inputs=INPUTS,
        outputs=OUTPUTS,
        dependencies=[],
        payload_sha512=hash512(data=serialized_transaction_payload),
        batcher_public_key=RANDOM_NODE_PUBLIC_KEY,
        nonce=time.time().hex().encode(),
    )

    serialized_header = transaction_header.SerializeToString()

    transaction_request = TpProcessRequest(
        header=transaction_header,
        payload=serialized_transaction_payload,
        signature=create_signer(private_key=ACCOUNT_FROM_PRIVATE_KEY).sign(serialized_header),
    )
    mock_context = create_context(account_from_balance=ACCOUNT_FROM_BALANCE, account_to_balance=ACCOUNT_TO_BALANCE)

    with pytest.raises(InvalidTransaction) as error:
        AccountHandler().apply(transaction=transaction_request, context=mock_context)

    assert f'Invalid account method value ({account_method_impossible_value}) has been set.' == str(error.value)
Пример #18
0
    AccountMethod,
    GenesisPayload,
    GenesisStatus,
    TransferPayload,
)
from remme.protos.transaction_pb2 import TransactionPayload
from remme.shared.utils import hash512
from remme.tp.account import AccountHandler
from testing.conftest import create_signer
from testing.mocks.stub import StubContext
from testing.utils.client import proto_error_msg

TOKENS_AMOUNT_TO_SUPPLY = 1_000_000

TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS = {
    'family_name': AccountHandler().family_name,
    'family_version': AccountHandler()._family_versions[0],
}

GENESIS_ADDRESS = '0000000000000000000000000000000000000000000000000000000000000000000001'
ACCOUNT_ADDRESS_TO = '112007d71fa7e120c60fb392a64fd69de891a60c667d9ea9e5d9d9d617263be6c20202'

INPUTS = OUTPUTS = [
    GENESIS_ADDRESS,
    ACCOUNT_ADDRESS_TO,
]

NODE_PUBLIC_KEY = '039d6881f0a71d05659e1f40b443684b93c7b7c504ea23ea8949ef5216a2236940'
NODE_PRIVATE_KEY = '1cb15ecfe1b3dc02df0003ac396037f85b98cf9f99b0beae000dc5e9e8b6dab4'

Пример #19
0
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------------------------------------------------

import argparse

from sawtooth_sdk.processor.core import TransactionProcessor

from remme.tp.atomic_swap import AtomicSwapHandler
from remme.tp.pub_key import PubKeyHandler
from remme.tp.account import AccountHandler
from remme.shared.logging import setup_logging
from remme.settings.default import load_toml_with_defaults

TP_HANDLERS = [AccountHandler(), PubKeyHandler(), AtomicSwapHandler()]

if __name__ == '__main__':
    config = load_toml_with_defaults(
        '/config/remme-client-config.toml')['remme']['client']
    parser = argparse.ArgumentParser(description='Transaction processor.')
    parser.add_argument('-v', '--verbosity', type=int, default=2)
    parser.add_argument('--account', action='store_true')
    parser.add_argument('--atomic-swap', action='store_true')
    parser.add_argument('--pubkey', action='store_true')
    args = parser.parse_args()
    setup_logging('remme', args.verbosity)

    processor = TransactionProcessor(
        url=f'tcp://{ config["validator_ip"] }:{ config["validator_port"] }')
Пример #20
0
# limitations under the License.
# ------------------------------------------------------------------------

# pylint: disable=invalid-name

import argparse

from sawtooth_sdk.processor.core import TransactionProcessor

from remme.tp.atomic_swap import AtomicSwapHandler
from remme.tp.pub_key import PubKeyHandler
from remme.tp.account import AccountHandler
from remme.shared.logging_setup import setup_logging
from remme.settings.default import load_toml_with_defaults

TP_HANDLERS = [AccountHandler(), PubKeyHandler(), AtomicSwapHandler()]

if __name__ == '__main__':
    config = load_toml_with_defaults(
        '/config/remme-client-config.toml')['remme']['client']
    parser = argparse.ArgumentParser(description='Transaction processor.')
    parser.add_argument('-v', '--verbosity', type=int, default=2)
    args = parser.parse_args()
    setup_logging('remme-tp', args.verbosity)

    processor = TransactionProcessor(
        url=f'tcp://{ config["validator_ip"] }:{ config["validator_port"] }')

    for handler in TP_HANDLERS:
        processor.add_handler(handler)
    try:
Пример #21
0
OUTPUT_BATCH = '/genesis/batch/token-proposal.batch'

if __name__ == '__main__':
    parameters = load_toml_with_defaults(
        '/config/remme-genesis-config.toml')['remme']['genesis']

    parser = argparse.ArgumentParser(
        description='File with a public key to assign initial supply.')
    parser.add_argument('--token-supply', default=parameters['token_supply'])
    args = parser.parse_args()

    account_client = AccountClient()

    if parameters['economy_enabled']:
        zero_address = AccountHandler().make_address('0' * 64)
        target_address = AccountHandler().make_address_from_data(
            account_client.get_signer().get_public_key().as_hex())

        print('Issuing {} tokens to address {}'.format(args.token_supply,
                                                       target_address))

        addresses_input = [GENESIS_ADDRESS]
        addresses_output = [GENESIS_ADDRESS, target_address]

        payload = TransactionPayload()
        payload.method = AccountMethod.GENESIS
        payload.data = account_client.get_genesis_payload(
            args.token_supply).SerializeToString()

        batch_list = AccountClient().make_batch_list(payload, addresses_input,
def is_valid_token_balance():
    account_client = AccountClient()
    signer_pub_key = account_client.get_signer().get_public_key().as_hex()
    signer_balance = account_client.get_balance(
        AccountHandler().make_address_from_data(signer_pub_key))
    return signer_balance >= PUB_KEY_STORE_PRICE
Пример #23
0
 def get_user_address(self):
     return AccountHandler.make_address_from_data(
         self._signer.get_public_key().as_hex())
Пример #24
0
    def get_user_address(self):
        from remme.tp.account import AccountHandler

        return AccountHandler().make_address_from_data(self._signer.get_public_key().as_hex())
Пример #25
0
def test_account_handler_genesis_apply():
    """
    Case: send transaction request, to send tokens from genesis address, to the account handler.
    Expect:
    """
    account = Account()
    account.balance = TOKENS_AMOUNT_TO_SUPPLY
    expected_serialized_account_to_balance = account.SerializeToString()

    genesis_payload = GenesisPayload()
    genesis_payload.total_supply = TOKENS_AMOUNT_TO_SUPPLY

    transaction_payload = TransactionPayload()
    transaction_payload.method = AccountMethod.GENESIS
    transaction_payload.data = genesis_payload.SerializeToString()

    serialized_transaction_payload = transaction_payload.SerializeToString()

    transaction_header = TransactionHeader(
        signer_public_key=NODE_PUBLIC_KEY,
        family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get(
            'family_name'),
        family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get(
            'family_version'),
        inputs=INPUTS,
        outputs=OUTPUTS,
        dependencies=[],
        payload_sha512=hash512(data=serialized_transaction_payload),
        batcher_public_key=NODE_PUBLIC_KEY,
        nonce=time.time().hex().encode(),
    )

    serialized_header = transaction_header.SerializeToString()

    transaction_request = TpProcessRequest(
        header=transaction_header,
        payload=serialized_transaction_payload,
        signature=create_signer(
            private_key=NODE_PRIVATE_KEY).sign(serialized_header),
    )

    genesis_status = GenesisStatus()
    genesis_status.status = True

    expected_state = {
        GENESIS_ADDRESS: genesis_status.SerializeToString(),
        ACCOUNT_ADDRESS_TO: expected_serialized_account_to_balance,
    }

    mock_context = StubContext(inputs=INPUTS,
                               outputs=OUTPUTS,
                               initial_state={})

    AccountHandler().apply(transaction=transaction_request,
                           context=mock_context)

    state_as_list = mock_context.get_state(
        addresses=[GENESIS_ADDRESS, ACCOUNT_ADDRESS_TO])
    state_as_dict = {entry.address: entry.data for entry in state_as_list}

    assert expected_state == state_as_dict
Пример #26
0
    def _swap_init(self, context, signer_pubkey, swap_init_payload):
        """
        if SecretLockOptionalBob is provided, Bob uses _swap_init to respond to requested swap
        Otherwise, Alice uses _swap_init to request a swap and thus, Bob can't receive funds until Alice "approves".
        """
        LOGGER.info("0. Check if swap ID already exists")
        # 0. Check if swap ID already exists
        if self.get_swap_info_from_swap_id(context,
                                           swap_init_payload.swap_id,
                                           to_raise_exception=False):
            raise InvalidTransaction(
                'Atomic swap ID has already been taken, please use a different one!'
            )
        # END

        swap_info = AtomicSwapInfo()
        swap_info.swap_id = swap_init_payload.swap_id
        swap_info.state = AtomicSwapInfo.OPENED
        swap_info.amount = swap_init_payload.amount
        swap_info.created_at = swap_init_payload.created_at
        swap_info.email_address_encrypted_optional = swap_init_payload.email_address_encrypted_by_initiator
        swap_info.sender_address = AccountHandler().make_address_from_data(
            signer_pubkey)
        swap_info.sender_address_non_local = swap_init_payload.sender_address_non_local
        swap_info.receiver_address = swap_init_payload.receiver_address

        if not AccountHandler().is_handler_address(swap_info.receiver_address):
            raise InvalidTransaction(
                'Receiver address is not of a Token type.')

        LOGGER.info("1. Ensure transaction initiated within an hour")
        # 1. Ensure transaction initiated within an hour
        swap_info.secret_lock = swap_init_payload.secret_lock_by_solicitor
        created_at = self.get_datetime_from_timestamp(swap_info.created_at)
        now = datetime.datetime.utcnow()

        if not (now - datetime.timedelta(hours=1) < created_at < now):
            raise InvalidTransaction(
                'Transaction is created a long time ago or timestamp is assigned set.'
            )
        # END

        LOGGER.info("2. Check weather the sender is Alice")
        # 2. Check weather the sender is Alice:
        swap_info.is_initiator = not swap_init_payload.secret_lock_by_solicitor
        # END

        # 3. Transfer funds to zero address.
        LOGGER.info("3. Transfer funds to zero address")
        commission = int(_get_setting_value(context, SETTINGS_SWAP_COMMISSION))
        if commission < 0:
            raise InvalidTransaction('Wrong commission address.')
        LOGGER.info("4. Get sender's account {}".format(
            swap_info.sender_address))
        account = get_account_by_address(context, swap_info.sender_address)
        total_amount = swap_info.amount + commission
        if account.balance < total_amount:
            raise InvalidTransaction(
                'Not enough balance to perform the transaction in '
                'the amount (with a commission) {}.'.format(total_amount))

        transfer_payload = AccountClient.get_transfer_payload(
            ZERO_ADDRESS, total_amount)
        token_updated_state = AccountHandler()._transfer_from_address(
            context, swap_info.sender_address, transfer_payload)
        LOGGER.info("Save state")

        return {**self.get_state_update(swap_info), **token_updated_state}
Пример #27
0
# pylint: disable=invalid-name

import argparse

from sawtooth_sdk.processor.core import TransactionProcessor

from remme.tp.atomic_swap import AtomicSwapHandler
from remme.tp.pub_key import PubKeyHandler
from remme.tp.account import AccountHandler
from remme.shared.logging_setup import setup_logging
from remme.settings.default import load_toml_with_defaults

TP_HANDLERS = {
    handler._family_name: handler
    for handler in (AccountHandler(), PubKeyHandler(), AtomicSwapHandler())
}

if __name__ == '__main__':
    config = load_toml_with_defaults(
        '/config/remme-client-config.toml')['remme']['client']
    parser = argparse.ArgumentParser(description='Transaction processor.')
    parser.add_argument('-v', '--verbosity', type=int, default=2)
    args = parser.parse_args()
    setup_logging('remme-tp', args.verbosity)

    processor = TransactionProcessor(
        url=f'tcp://{ config["validator_ip"] }:{ config["validator_port"] }')

    for handler in TP_HANDLERS.values():
        processor.add_handler(handler)