def test_transfer_success_no_state_address2(self): ACCOUNT_AMOUNT1 = 500 TRANSFER_VALUE = 200 signature = self.send_transaction( AccountMethod.TRANSFER, AccountClient.get_transfer_payload(self.account_address2, TRANSFER_VALUE), [self.account_address1, self.account_address2]) self.expect_get({ self.account_address1: AccountClient.get_account_model(ACCOUNT_AMOUNT1), self.account_address2: None }) self.expect_set( signature, AccountMethod.TRANSFER, { self.account_address1: AccountClient.get_account_model(ACCOUNT_AMOUNT1 - TRANSFER_VALUE), self.account_address2: AccountClient.get_account_model(0 + TRANSFER_VALUE) }) self.expect_ok()
def get(pub_key_user): client = AccountClient() address = client.make_address_from_data(pub_key_user) print('Reading from address: {}'.format(address)) balance = client.get_balance(address) return {'balance': balance, 'address': address}
async def get_public_keys_list(request): client = AccountClient() try: address = request.params['public_key_address'] except KeyError: raise RpcInvalidParamsError(message='Missed public_key_address') return client.get_pub_keys(address)
def create_raw_transaction_send_token_payload(pub_key_to, amount=1): client = AccountClient() signer = client._signer address = client.make_address_from_data(pub_key_to) node_address = client.get_user_address() transfer = TransferPayload() transfer.address_to = address transfer.value = amount tr = TransactionPayload() tr.method = AccountMethod.TRANSFER tr.data = transfer.SerializeToString() payload = tr.SerializeToString() header = TransactionHeader( signer_public_key=signer.get_public_key().as_hex(), family_name=client._family_handler.family_name, family_version=client._family_handler.family_versions[-1], inputs=[node_address, address], outputs=[node_address, address], dependencies=[], payload_sha512=hash512(payload), batcher_public_key=signer.get_public_key().as_hex(), nonce=time.time().hex().encode()).SerializeToString() signature = signer.sign(header) transaction = Transaction(header=header, payload=payload, header_signature=signature) return transaction
def transfer(self, address1, amount1, address2, amount2, value): self.expect_get({address1: AccountClient.get_account_model(amount1)}) self.expect_get({address2: AccountClient.get_account_model(amount2)}) return { address1: AccountClient.get_account_model(amount1 - value), address2: AccountClient.get_account_model(amount2 + value) }
def test_transfer_fail_no_state_address1(self): ACCOUNT_AMOUNT2 = 500 TRANSFER_VALUE = 200 self.send_transaction(AccountMethod.TRANSFER, AccountClient.get_transfer_payload(self.account_address2, TRANSFER_VALUE), [self.account_address1, self.account_address2]) self.expect_get({self.account_address1: None, self.account_address2: AccountClient.get_account_model(0)}) self.expect_invalid_transaction()
def pub_key_already_exist(cert): account_client = AccountClient() address = account_client.make_address_from_data( cert.public_bytes(serialization.Encoding.DER).hex()) try: account_client.get_value(address) except KeyNotFound: return False return True
async def get_batch_status(request): try: id = request.params['id'] except KeyError: raise RpcInvalidParamsError(message='Missed id') client = AccountClient() return client.get_batch_status(id)
async def list_transactions(request): client = AccountClient() ids = request.params.get('ids') start = request.params.get('start') limit = request.params.get('limit') head = request.params.get('head') reverse = request.params.get('reverse') return client.list_transactions(ids, start, limit, head, reverse)
async def list_receipts(request): client = AccountClient() try: ids = request.params['ids'] except KeyError: raise RpcInvalidParamsError(message='Missed ids') try: return client.list_receipts(ids) except KeyNotFound: raise KeyNotFound(f'Transactions with ids "{ids}" not found')
def test_transfer_fail_no_balance(self): ACCOUNT_AMOUNT1 = 200 ACCOUNT_AMOUNT2 = 500 TRANSFER_VALUE = ACCOUNT_AMOUNT1 + 1 self.send_transaction(AccountMethod.TRANSFER, AccountClient.get_transfer_payload(self.account_address2, TRANSFER_VALUE), [self.account_address1, self.account_address2]) self.expect_get({self.account_address1: AccountClient.get_account_model(ACCOUNT_AMOUNT1), self.account_address2: AccountClient.get_account_model(ACCOUNT_AMOUNT2)}) self.expect_invalid_transaction()
async def fetch_transaction(request): try: id = request.params['id'] except KeyError: raise RpcInvalidParamsError(message='Missed id') client = AccountClient() try: return client.fetch_transaction(id) except KeyNotFound: raise KeyNotFound(f'Transaction with id "{id}" not found')
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()
def test_transfer_fail_to_zeroaddress(self): ACCOUNT_AMOUNT1 = 500 TRANSFER_VALUE = 200 self.send_transaction( AccountMethod.TRANSFER, AccountClient.get_transfer_payload(GENESIS_ADDRESS, TRANSFER_VALUE), [self.account_address1, self.account_address2]) self.expect_get({ self.account_address1: AccountClient.get_account_model(ACCOUNT_AMOUNT1) }) self.expect_invalid_transaction()
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}
def test_store_success(self): context = self.get_context() cert, key, _ = create_certificate(context.pub_key_payload, signer=context.client.get_signer()) 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 = get_crt_export_bin_sig_rem_sig(cert, key, context.client) account = AccountClient.get_account_model(PUB_KEY_STORE_PRICE) 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}) 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) self.expect_set({self.account_address1: account, cert_address: data}) self.expect_ok()
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}
async def fetch_transaction(request): id = request.params['id'] client = AccountClient() try: return await client.fetch_transaction(id) except KeyNotFound: raise KeyNotFound(f'Transaction with id "{id}" not found')
def test_swap_init_success(self): # Bob init context = self.get_context() init_data = { "receiver_address": self.account_address2, "sender_address_non_local": context.sender_address_non_local, "amount": context.AMOUNT, "swap_id": context.swap_id, "secret_lock_by_solicitor": context.secret_lock, "email_address_encrypted_by_initiator": context.email_address, "created_at": context.created_at, } context.client.swap_init(get_swap_init_payload(**init_data)) self.expect_get({context.swap_address: None}) self.expect_get({ _make_settings_key(SETTINGS_SWAP_COMMISSION): get_setting_from_key_value(SETTINGS_SWAP_COMMISSION, context.COMMISSION) }) TOTAL_TRANSFERED = context.AMOUNT+context.COMMISSION self.expect_get({self.account_address1: AccountClient.get_account_model(TOTAL_TRANSFERED)}) updated_state = self.transfer(self.account_address1, TOTAL_TRANSFERED, ZERO_ADDRESS, 0, TOTAL_TRANSFERED) context.swap_info.state = AtomicSwapInfo.OPENED self.expect_set({ **{context.swap_address: context.swap_info}, **updated_state }) self.expect_ok()
def test_transfer_fail_to_zeroaddress(self): TRANSFER_VALUE = 200 self.send_transaction( AccountMethod.TRANSFER, AccountClient.get_transfer_payload(GENESIS_ADDRESS, TRANSFER_VALUE), [self.account_address1, self.account_address2]) self.expect_invalid_transaction()
async def list_receipts(request): ids = request.params['ids'] client = AccountClient() try: return await client.list_receipts(ids) except KeyNotFound: raise KeyNotFound(f'Transactions with ids "{ids}" not found')
async def test_get_token_balance(self, root_mock, fetch_state_mock): address = AccountClient().make_address_from_data( '03823c7a9e285246985089824f3aaa51fb8675d08d84b151833ca5febce37ad61a' ) resp = await self.create_rpc_request('get_balance', {'public_key_address': address}) self.assertEqual(resp.status, 200) data = await resp.json() self.assertEqual(data['result'], 100)
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". """ address_swap_info_is_stored_by = self.make_address_from_data(swap_init_payload.swap_id) swap_information = get_data(context, AtomicSwapInfo, address_swap_info_is_stored_by) if swap_information: raise InvalidTransaction('Atomic swap ID has already been taken, please use a different one.') block_info = self._get_latest_block_info(context) block_time = block_info.timestamp swap_information = AtomicSwapInfo() swap_information.swap_id = swap_init_payload.swap_id swap_information.state = AtomicSwapInfo.OPENED swap_information.amount = swap_init_payload.amount swap_information.created_at = block_time swap_information.secret_lock = swap_init_payload.secret_lock_by_solicitor swap_information.email_address_encrypted_optional = swap_init_payload.email_address_encrypted_by_initiator swap_information.sender_address = AccountHandler().make_address_from_data(signer_pubkey) swap_information.sender_address_non_local = swap_init_payload.sender_address_non_local swap_information.receiver_address = swap_init_payload.receiver_address swap_information.is_initiator = not swap_init_payload.secret_lock_by_solicitor commission_amount = int(_get_setting_value(context, SETTINGS_SWAP_COMMISSION)) if commission_amount < 0: raise InvalidTransaction('Wrong commission address.') swap_total_amount = swap_information.amount + commission_amount account = get_data(context, Account, swap_information.sender_address) if account is None: account = Account() if account.balance < swap_total_amount: raise InvalidTransaction( f'Not enough balance to perform the transaction in the amount (with a commission) {swap_total_amount}.' ) transfer_payload = AccountClient.get_transfer_payload(ZERO_ADDRESS, commission_amount) transfer_state = AccountHandler()._transfer_from_address( context, swap_information.sender_address, transfer_payload, ) sender_account = transfer_state.get(swap_information.sender_address) sender_account.balance -= swap_information.amount return { address_swap_info_is_stored_by: swap_information, **transfer_state, }
def test_genesis_fail(self): TOTAL_SUPPLY = 10000 self.send_transaction(AccountMethod.GENESIS, AccountClient.get_genesis_payload(TOTAL_SUPPLY), [GENESIS_ADDRESS, self.account_address1]) genesis_status = GenesisStatus() genesis_status.status = True self.expect_get({GENESIS_ADDRESS: genesis_status}) self.expect_invalid_transaction()
def test_transfer_success(self): ACCOUNT_AMOUNT1 = 1000 ACCOUNT_AMOUNT2 = 500 TRANSFER_VALUE = ACCOUNT_AMOUNT1 self.send_transaction(AccountMethod.TRANSFER, AccountClient.get_transfer_payload(self.account_address2, TRANSFER_VALUE), [self.account_address1, self.account_address2]) self.expect_set(self.transfer(self.account_address1, ACCOUNT_AMOUNT1, self.account_address2, ACCOUNT_AMOUNT2, TRANSFER_VALUE)) self.expect_ok()
async def send_tokens(request): try: amount = request.params['amount'] except KeyError: raise RpcInvalidParamsError(message='Missed amount') try: public_key_to = request.params['public_key_to'] except KeyError: raise RpcInvalidParamsError(message='Missed public_key_to') client = AccountClient() signer_account = await client.get_account(client.get_signer_address()) if not amount: raise RpcGenericServerDefinedError( error_code=-32050, message='Could not transfer with zero amount' ) if signer_account.balance < amount: raise RpcGenericServerDefinedError( error_code=-32050, message='Not enough transferable balance of sender' ) address_to = client.make_address_from_data(public_key_to) result = await client.transfer(address_to, amount) return result['data']
def post(payload): client = AccountClient() signer_account = client.get_account(client.get_signer_address()) if not payload['amount']: return {'error': 'Could not transfer with zero amount'}, 400 if signer_account.balance < payload['amount']: return {'error': 'Not enough transferable balance of sender'}, 400 address_to = client.make_address_from_data(payload['pub_key_to']) result = client.transfer(address_to, payload['amount']) return {'batch_id': result['batch_id']}
def test_genesis_success(self): TOTAL_SUPPLY = 10000 self.send_transaction(AccountMethod.GENESIS, AccountClient.get_genesis_payload(TOTAL_SUPPLY), [GENESIS_ADDRESS, self.account_address1]) self.expect_get({GENESIS_ADDRESS: None}) genesis_status = GenesisStatus() genesis_status.status = True account = Account() account.balance = TOTAL_SUPPLY self.expect_set({ self.account_address1: account, GENESIS_ADDRESS: genesis_status }) self.expect_ok()
def test_transfer_success(self): ACCOUNT_AMOUNT1 = 1000 ACCOUNT_AMOUNT2 = 500 TRANSFER_VALUE = ACCOUNT_AMOUNT1 LOGGER.info(f'test_transfer_success signature ') signature = self.send_transaction( AccountMethod.TRANSFER, AccountClient.get_transfer_payload(self.account_address2, TRANSFER_VALUE), [self.account_address1, self.account_address2]) LOGGER.info(f'test_transfer_success signature {signature}') self.expect_set( signature, AccountMethod.TRANSFER, self.transfer(self.account_address1, ACCOUNT_AMOUNT1, self.account_address2, ACCOUNT_AMOUNT2, TRANSFER_VALUE)) self.expect_ok()
def test_store_success(self): context = self.get_context() cert, key, _ = create_certificate(context.pub_key_payload, signer=context.client.get_signer()) cert_address, transaction_payload = self._pre_parse_payload_and_exec(context, cert, key) self.expect_get({cert_address: None}) account = AccountClient.get_account_model(PUB_KEY_STORE_PRICE) self.expect_get({self.account_address1: account}) data = PubKeyStorage() data.owner = self.account_signer1.get_public_key().as_hex() data.payload.CopyFrom(transaction_payload) data.revoked = False account.balance -= PUB_KEY_STORE_PRICE account.pub_keys.append(cert_address) self.expect_set({ self.account_address1: account, cert_address: data }) self.expect_ok()