def test_public_key_handler_revoke_with_empty_proto(): """ Case: send transaction request to revoke another ownder certificate public key with empty proto Expect: invalid transaction error """ revoke_public_key_payload = RevokePubKeyPayload() transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.REVOKE transaction_payload.data = revoke_public_key_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header(serialized_transaction_payload, INPUTS, OUTPUTS) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer(private_key=SENDER_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={}) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert proto_error_msg( RevokePubKeyPayload, {'address': ['Missed address']} ) == str(error.value)
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)
def test_store_public_key_for_other_invalid_transfer_method(): """ Case: send transaction request, to store certificate public key for other, with invalid transfer method value. Expect: invalid transaction error is raised with invalid account method value error message. """ account_method_impossible_value = 5347 new_public_key_payload = generate_rsa_payload() transaction_payload = TransactionPayload() transaction_payload.method = account_method_impossible_value transaction_payload.data = new_public_key_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header(serialized_transaction_payload, INPUTS, OUTPUTS) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer(private_key=PAYER_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={}) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert f'Invalid account method value ({account_method_impossible_value}) has been set.' == str(error.value)
def test_public_key_handler_store_decode_error(): """ Case: send transaction request, to store certificate public key, with invalid transaction payload. Expect: invalid transaction error is raised with cannot decode transaction payload error message. """ serialized_not_valid_transaction_payload = b'F1120071db7c02f5731d06df194dc95465e9b27' transaction_header = generate_header( serialized_not_valid_transaction_payload, INPUTS, OUTPUTS) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_not_valid_transaction_payload, signature=create_signer( private_key=SENDER_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={}) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert 'Cannot decode transaction payload.' == str(error.value)
def test_close_atomic_swap_before_approve(): """ Case: close swap before it is approved. Expect: invalid transaction error is raised with transaction cannot be closed before it is approved error message. """ atomic_swap_close_payload = AtomicSwapClosePayload( swap_id=SWAP_ID, secret_key=SECRET_KEY, ) transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.CLOSE transaction_payload.data = atomic_swap_close_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) existing_swap_info_to_close = AtomicSwapInfo() existing_swap_info_to_close.swap_id = SWAP_ID existing_swap_info_to_close.state = AtomicSwapInfo.OPENED existing_swap_info_to_close.secret_lock = SECRET_LOCK existing_swap_info_to_close.is_initiator = True serialized_existing_swap_info_to_lock = existing_swap_info_to_close.SerializeToString( ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ ADDRESS_TO_STORE_SWAP_INFO_BY: serialized_existing_swap_info_to_lock, }) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert 'Transaction cannot be closed before it\'s approved.' == str( error.value)
def test_public_key_handler_revoke_non_existent_public_key(): """ Case: send transaction request to revoke non-existent certificate public key. Expect: invalid transaction error is raised with no certificate public key is presented in chain error message. """ revoke_public_key_payload = RevokePubKeyPayload( address=ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY, ) transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.REVOKE transaction_payload.data = revoke_public_key_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header(serialized_transaction_payload, INPUTS, OUTPUTS) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer(private_key=SENDER_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={}) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert 'No public key is presented in chain.' == str(error.value)
def test_approve_atomic_swap_without_secret_lock_state(): """ Case: approve atomic swap without secret lock state. Expect: invalid transaction error is raised with swap identifier is already closed error message. """ atomic_swap_approve_payload = AtomicSwapApprovePayload(swap_id=SWAP_ID, ) transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.APPROVE transaction_payload.data = atomic_swap_approve_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) swap_info = AtomicSwapInfo() swap_info.swap_id = SWAP_ID swap_info.state = AtomicSwapInfo.OPENED swap_info.amount = TOKENS_AMOUNT_TO_SWAP swap_info.created_at = CURRENT_TIMESTAMP swap_info.sender_address = BOT_ADDRESS swap_info.secret_lock = SECRET_LOCK swap_info.receiver_address = ALICE_ADDRESS swap_info.is_initiator = True serialized_swap_info = swap_info.SerializeToString() mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ ADDRESS_TO_STORE_SWAP_INFO_BY: serialized_swap_info, }) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert f'Swap identifier {SWAP_ID} is already closed.' == str(error.value)
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
def test_close_already_closed_atomic_swap(): """ Case: close already closed atomic swap. Expect: invalid transaction error is raised with already operation with closed or expired swap error message. """ atomic_swap_close_payload = AtomicSwapClosePayload( swap_id=SWAP_ID, secret_key=SECRET_KEY, ) transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.CLOSE transaction_payload.data = atomic_swap_close_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) already_closed_swap_info = AtomicSwapInfo() already_closed_swap_info.swap_id = SWAP_ID already_closed_swap_info.state = AtomicSwapInfo.CLOSED serialized_already_closed_swap_info = already_closed_swap_info.SerializeToString( ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ ADDRESS_TO_STORE_SWAP_INFO_BY: serialized_already_closed_swap_info, }) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert f'No operations can be done upon the swap: {SWAP_ID} as it is already closed or expired.' == str( error.value)
def test_atomic_swap_init_with_empty_proto(): """ Case: send empty proto for init Expect: invalid transaction error """ inputs = outputs = [ ADDRESS_TO_GET_SWAP_COMMISSION_AMOUNT_BY, BLOCK_INFO_CONFIG_ADDRESS, BLOCK_INFO_ADDRESS, BOT_ADDRESS, ZERO_ADDRESS, ADDRESS_TO_STORE_SWAP_INFO_BY, ADDRESS_TO_GET_GENESIS_MEMBERS_AS_STRING_BY, ] atomic_swap_init_payload = AtomicSwapInitPayload() transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.INIT transaction_payload.data = atomic_swap_init_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=inputs, outputs=outputs, initial_state={}) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert proto_error_msg( AtomicSwapInitPayload, { 'receiver_address': ['Missed address'], 'sender_address_non_local': ['This field is required.'], 'amount': ['This field is required.'], 'swap_id': ['Missed swap_id'], 'created_at': ['This field is required.'], } ) == str(error.value)
def test_atomic_swap_init_swap_no_account_in_state(): """ Case: initialize swap of bot's Remme node tokens to Alice's ERC20 Remme tokens from non-existent bot address. Expect: invalid transaction error is raised with not enough balance error message. """ atomic_swap_init_payload = AtomicSwapInitPayload( receiver_address=ALICE_ADDRESS, sender_address_non_local=BOT_ETHEREUM_ADDRESS, amount=TOKENS_AMOUNT_TO_SWAP, swap_id=SWAP_ID, secret_lock_by_solicitor=BOT_IT_IS_INITIATOR_MARK, email_address_encrypted_by_initiator=ALICE_EMAIL_ADDRESS_ENCRYPTED_BY_INITIATOR, created_at=CURRENT_TIMESTAMP, ) transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.INIT transaction_payload.data = atomic_swap_init_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) swap_commission_setting = Setting() swap_commission_setting.entries.add(key=SETTINGS_SWAP_COMMISSION, value=str(SWAP_COMMISSION_AMOUNT)) serialized_swap_commission_setting = swap_commission_setting.SerializeToString() mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ BLOCK_INFO_CONFIG_ADDRESS: SERIALIZED_BLOCK_INFO_CONFIG, BLOCK_INFO_ADDRESS: SERIALIZED_BLOCK_INFO, ADDRESS_TO_GET_SWAP_COMMISSION_AMOUNT_BY: serialized_swap_commission_setting, }) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) total_amount = TOKENS_AMOUNT_TO_SWAP + SWAP_COMMISSION_AMOUNT assert f'Not enough balance to perform the transaction in the amount (with a commission) {total_amount}.' \ == str(error.value)
def test_set_lock_to_atomic_swap_with_set_lock(): """ Case: set secret lock to atomic swap with already set secret lock. Expect: invalid transaction error is raised with secret lock is already added error message. """ atomic_swap_init_payload = AtomicSwapSetSecretLockPayload( swap_id=SWAP_ID, secret_lock=SECRET_LOCK, ) transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.SET_SECRET_LOCK transaction_payload.data = atomic_swap_init_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) already_set_lock_swap_info = AtomicSwapInfo() already_set_lock_swap_info.swap_id = SWAP_ID already_set_lock_swap_info.state = AtomicSwapInfo.OPENED already_set_lock_swap_info.secret_lock = SECRET_LOCK serialized_already_set_lock_swap_info = already_set_lock_swap_info.SerializeToString( ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ ADDRESS_TO_STORE_SWAP_INFO_BY: serialized_already_set_lock_swap_info, }) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert f'Secret lock is already added for {SWAP_ID}.' == str(error.value)
def test_atomic_swap_init_swap_receiver_address_invalid_type(): """ Case: initialize swap of bot's Remme node tokens to Alice's ERC20 Remme tokens with invalid Alice node address. Expect: invalid transaction error is raised with atomic swap id has already been taken error message. """ invalid_receiver_address = '112934y*(J#QJ3UH*PD(:9B&TYDB*I0b0a8edc4104ef28093ee30' atomic_swap_init_payload = AtomicSwapInitPayload( receiver_address=invalid_receiver_address, sender_address_non_local=BOT_ETHEREUM_ADDRESS, amount=TOKENS_AMOUNT_TO_SWAP, swap_id=SWAP_ID, secret_lock_by_solicitor=BOT_IT_IS_INITIATOR_MARK, email_address_encrypted_by_initiator=ALICE_EMAIL_ADDRESS_ENCRYPTED_BY_INITIATOR, created_at=CURRENT_TIMESTAMP, ) transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.INIT transaction_payload.data = atomic_swap_init_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ BLOCK_INFO_CONFIG_ADDRESS: SERIALIZED_BLOCK_INFO_CONFIG, BLOCK_INFO_ADDRESS: SERIALIZED_BLOCK_INFO, }) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert proto_error_msg( AtomicSwapInitPayload, {'receiver_address': ['Address is not of a blockchain token type.']} ) == str(error.value)
def test_expire_atomic_swap_by_not_swap_owner(): """ Case: to expire atomic swap by signer address isn't specified in atomic swap sender address. Expect: invalid transaction error is raised with signer is not the one who opened the swap. error message. """ atomic_swap_close_payload = AtomicSwapExpirePayload(swap_id=SWAP_ID, ) transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.EXPIRE transaction_payload.data = atomic_swap_close_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) existing_swap_info_to_expire = AtomicSwapInfo() existing_swap_info_to_expire.swap_id = SWAP_ID existing_swap_info_to_expire.state = AtomicSwapInfo.OPENED existing_swap_info_to_expire.sender_address = RANDOM_ADDRESS serialized_existing_swap_info_to_expire = existing_swap_info_to_expire.SerializeToString( ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ ADDRESS_TO_STORE_SWAP_INFO_BY: serialized_existing_swap_info_to_expire, }) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert f'Signer is not the one who opened the swap.' == str(error.value)
def test_public_key_handler_revoke(): """ Case: send transaction request to revoke certificate public key. Expect: public key storage blockchain record is changed to True. """ revoke_public_key_payload = RevokePubKeyPayload( address=ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY, ) transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.REVOKE transaction_payload.data = revoke_public_key_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header(serialized_transaction_payload, INPUTS, OUTPUTS) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer(private_key=SENDER_PRIVATE_KEY).sign(serialized_header), ) existing_public_key_payload = generate_rsa_payload() existing_public_key_storage = PubKeyStorage() existing_public_key_storage.owner = SENDER_PUBLIC_KEY existing_public_key_storage.payload.CopyFrom(existing_public_key_payload) existing_public_key_storage.is_revoked = False serialized_existing_public_key_storage = existing_public_key_storage.SerializeToString() mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY: serialized_existing_public_key_storage, }) expected_public_key_payload = generate_rsa_payload() expected_public_key_storage = PubKeyStorage() expected_public_key_storage.owner = SENDER_PUBLIC_KEY expected_public_key_storage.payload.CopyFrom(expected_public_key_payload) expected_public_key_storage.is_revoked = True serialized_expected_public_key_storage = expected_public_key_storage.SerializeToString() expected_state = { ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY: serialized_expected_public_key_storage, } PubKeyHandler().apply(transaction=transaction_request, context=mock_context) state_as_list = mock_context.get_state(addresses=[ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY]) state_as_dict = {entry.address: entry.data for entry in state_as_list} assert expected_state == state_as_dict
def test_store_public_key_for_other_no_payer_account(): """ Case: send transaction request, to store certificate public key for other, when payer account does not exist. Expect: invalid transaction error is raised with not enough transferable balance error message. """ new_public_key_payload = generate_rsa_payload(key=CERTIFICATE_PUBLIC_KEY) serialized_new_public_key_payload = new_public_key_payload.SerializeToString() private_key = Secp256k1PrivateKey.from_hex(OWNER_PRIVATE_KEY) signature_by_owner = Secp256k1Context().sign(serialized_new_public_key_payload, private_key) new_public_key_store_and_pay_payload = NewPubKeyStoreAndPayPayload( pub_key_payload=new_public_key_payload, owner_public_key=bytes.fromhex(OWNER_PUBLIC_KEY), signature_by_owner=bytes.fromhex(signature_by_owner), ) transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.STORE_AND_PAY transaction_payload.data = new_public_key_store_and_pay_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header( serialized_transaction_payload, INPUTS, OUTPUTS, signer_public_key=PAYER_PUBLIC_KEY, ) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer(private_key=PAYER_PRIVATE_KEY).sign(serialized_header), ) owner_account = Account() owner_account.pub_keys.append(RANDOM_ALREADY_STORED_OWNER_PUBLIC_KEY_ADDRESS) serialized_owner_account = owner_account.SerializeToString() zero_account = Account() zero_account.balance = 0 serialized_zero_account = zero_account.SerializeToString() mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ OWNER_ADDRESS: serialized_owner_account, ZERO_ADDRESS: serialized_zero_account, }) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert 'Not enough transferable balance. Sender\'s current balance: 0.' == str(error.value)
def test_store_public_key_for_other_not_der_public_key_format(): """ Case: send transaction request to store certificate public key not in DER format for other. Expect: invalid transaction error is raised with public key is already registered error message. """ not_der_format_public_key_to_store = b'h8ybuhtvrofpckejfhgubicojslmkghvbiuokl' address_from_public_key_to_store = generate_address('pub_key', not_der_format_public_key_to_store) inputs = outputs = [ address_from_public_key_to_store, OWNER_ADDRESS, ZERO_ADDRESS, IS_NODE_ECONOMY_ENABLED_ADDRESS, ] new_public_key_payload = generate_rsa_payload(key=not_der_format_public_key_to_store) serialized_new_public_key_payload = new_public_key_payload.SerializeToString() private_key = Secp256k1PrivateKey.from_hex(OWNER_PRIVATE_KEY) signature_by_owner = Secp256k1Context().sign(serialized_new_public_key_payload, private_key) new_public_key_store_and_pay_payload = NewPubKeyStoreAndPayPayload( pub_key_payload=new_public_key_payload, owner_public_key=bytes.fromhex(OWNER_PUBLIC_KEY), signature_by_owner=bytes.fromhex(signature_by_owner), ) transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.STORE_AND_PAY transaction_payload.data = new_public_key_store_and_pay_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header( serialized_transaction_payload, inputs, outputs, signer_public_key=PAYER_PUBLIC_KEY, ) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer(private_key=PAYER_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=inputs, outputs=outputs, initial_state={}) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert 'Cannot deserialize the provided public key. Check if it is in DER format.' == str(error.value)
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)
def test_atomic_swap_init_swap_no_block_info(): """ Case: initialize swap of bot's Remme node tokens to Alice's ERC20 Remme tokens when no needed block information. Expect: invalid transaction error is raised with nlock config not found error message. """ atomic_swap_init_payload = AtomicSwapInitPayload( receiver_address=ALICE_ADDRESS, sender_address_non_local=BOT_ETHEREUM_ADDRESS, amount=TOKENS_AMOUNT_TO_SWAP, swap_id=SWAP_ID, secret_lock_by_solicitor=BOT_IT_IS_INITIATOR_MARK, email_address_encrypted_by_initiator=ALICE_EMAIL_ADDRESS_ENCRYPTED_BY_INITIATOR, created_at=CURRENT_TIMESTAMP, ) transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.INIT transaction_payload.data = atomic_swap_init_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ BLOCK_INFO_CONFIG_ADDRESS: SERIALIZED_BLOCK_INFO_CONFIG, }) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert f'Block {block_info_config.latest_block + 1} not found.' == str(error.value)
def test_store_public_key_for_other_already_registered_public_key(): """ Case: send transaction request to store already registered certificate public key for other. Expect: invalid transaction error is raised with public key is already registered error message. """ new_public_key_payload = generate_rsa_payload(key=CERTIFICATE_PUBLIC_KEY) serialized_new_public_key_payload = new_public_key_payload.SerializeToString() private_key = Secp256k1PrivateKey.from_hex(OWNER_PRIVATE_KEY) signature_by_owner = Secp256k1Context().sign(serialized_new_public_key_payload, private_key) new_public_key_store_and_pay_payload = NewPubKeyStoreAndPayPayload( pub_key_payload=new_public_key_payload, owner_public_key=bytes.fromhex(OWNER_PUBLIC_KEY), signature_by_owner=bytes.fromhex(signature_by_owner), ) transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.STORE_AND_PAY transaction_payload.data = new_public_key_store_and_pay_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header( serialized_transaction_payload, INPUTS, OUTPUTS, signer_public_key=PAYER_PUBLIC_KEY, ) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer(private_key=PAYER_PRIVATE_KEY).sign(serialized_header), ) already_registered_public_key = PubKeyStorage() already_registered_public_key.owner = OWNER_PUBLIC_KEY already_registered_public_key.payload.CopyFrom(new_public_key_payload) already_registered_public_key.is_revoked = False serialized_already_registered_public_key = already_registered_public_key.SerializeToString() mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY: serialized_already_registered_public_key, }) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert 'This public key is already registered.' == str(error.value)
def test_close_not_initialized_atomic_swap(): """ Case: close not initialized atomic swap. Expect: invalid transaction error is raised with atomic swap was not initiated error message. """ atomic_swap_close_payload = AtomicSwapClosePayload( swap_id=SWAP_ID, secret_key=SECRET_KEY, ) transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.CLOSE transaction_payload.data = atomic_swap_close_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={}) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert f'Atomic swap was not initiated for identifier {SWAP_ID}!' == str( error.value)
def test_set_lock_with_empty_proto(): """ Case: send empty proto for set lock Expect: invalid transaction error """ atomic_swap_init_payload = AtomicSwapSetSecretLockPayload() transaction_payload = TransactionPayload() transaction_payload.method = AtomicSwapMethod.SET_SECRET_LOCK transaction_payload.data = atomic_swap_init_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = TransactionHeader( signer_public_key=BOT_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=BOT_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={}) with pytest.raises(InvalidTransaction) as error: AtomicSwapHandler().apply(transaction=transaction_request, context=mock_context) assert proto_error_msg( AtomicSwapSetSecretLockPayload, { 'swap_id': ['Missed swap_id'], 'secret_lock': ['This field is required.'], }) == str(error.value)
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)
def test_store_rsa_public_key_for_other_with_empty_proto(): """ Case: send transaction request to store certificate public key with empty protobuf. Expect: invalid transaction error with detailed description about missed protobuf parameters. """ new_public_key_store_and_pay_payload = NewPubKeyStoreAndPayPayload() transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.STORE_AND_PAY transaction_payload.data = new_public_key_store_and_pay_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header( serialized_transaction_payload, INPUTS, OUTPUTS, signer_public_key=PAYER_PUBLIC_KEY, ) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer(private_key=PAYER_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={}) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert proto_error_msg( NewPubKeyStoreAndPayPayload, { 'pub_key_payload': { 'hashing_algorithm': ['Not a valid choice'], 'entity_hash': ['This field is required.'], 'entity_hash_signature': ['This field is required.'], 'valid_from': ['This field is required.'], 'valid_to': ['This field is required.'], 'configuration': [ 'At least one of RSAConfiguration, ECDSAConfiguration or Ed25519Configuration must be set', ], }, 'owner_public_key': ['This field is required.'], 'signature_by_owner': ['This field is required.'], } ) == str(error.value)
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)
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)
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)
def test_store_public_key_for_other_invalid_certificate_signature(): """ Case: send transaction request, to store certificate public for other, when certificate signature_by_owner is invalid. Expect: invalid transaction error is raised with public key is already registered error message. """ not_user_certificate_private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend(), ) entity_hash_signature = generate_rsa_signature(b'w', not_user_certificate_private_key) new_public_key_payload = generate_rsa_payload( key=CERTIFICATE_PUBLIC_KEY, entity_hash_signature=entity_hash_signature, ) serialized_new_public_key_payload = new_public_key_payload.SerializeToString() private_key = Secp256k1PrivateKey.from_hex(OWNER_PRIVATE_KEY) signature_by_owner = Secp256k1Context().sign(serialized_new_public_key_payload, private_key) new_public_key_store_and_pay_payload = NewPubKeyStoreAndPayPayload( pub_key_payload=new_public_key_payload, owner_public_key=bytes.fromhex(OWNER_PUBLIC_KEY), signature_by_owner=bytes.fromhex(signature_by_owner), ) transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.STORE_AND_PAY transaction_payload.data = new_public_key_store_and_pay_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header(serialized_transaction_payload, INPUTS, OUTPUTS) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer(private_key=PAYER_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={}) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert 'Payed public key has invalid signature.' == str(error.value)
def test_public_key_handler_store_invalid_signature(): """ Case: send transaction request, to store certificate public, when signature is invalid. Expect: invalid transaction error is raised with public key is already registered error message. """ not_user_certificte_private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend(), ) entity_hash_signature = generate_rsa_signature( b'w', not_user_certificte_private_key) new_public_key_payload = generate_rsa_payload( entity_hash_signature=entity_hash_signature) transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.STORE transaction_payload.data = new_public_key_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header(serialized_transaction_payload, INPUTS, OUTPUTS) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer( private_key=SENDER_PRIVATE_KEY).sign(serialized_header), ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={}) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert 'Invalid signature' == str(error.value)
def test_public_key_handler_store_already_registered_public_key(): """ Case: send transaction request to store already registered certificate public key. Expect: invalid transaction error is raised with public key is already registered error message. """ new_public_key_payload = generate_rsa_payload() transaction_payload = TransactionPayload() transaction_payload.method = PubKeyMethod.STORE transaction_payload.data = new_public_key_payload.SerializeToString() serialized_transaction_payload = transaction_payload.SerializeToString() transaction_header = generate_header(serialized_transaction_payload, INPUTS, OUTPUTS) serialized_header = transaction_header.SerializeToString() transaction_request = TpProcessRequest( header=transaction_header, payload=serialized_transaction_payload, signature=create_signer( private_key=SENDER_PRIVATE_KEY).sign(serialized_header), ) already_registered_public_key = PubKeyStorage() already_registered_public_key.owner = SENDER_PUBLIC_KEY already_registered_public_key.payload.CopyFrom(new_public_key_payload) already_registered_public_key.is_revoked = False serialized_already_registered_public_key = already_registered_public_key.SerializeToString( ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY: serialized_already_registered_public_key, }) with pytest.raises(InvalidTransaction) as error: PubKeyHandler().apply(transaction=transaction_request, context=mock_context) assert 'This public key is already registered.' == str(error.value)