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_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_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_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_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_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_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 _pre_parse_payload_and_exec(self, context, cert, key, type='store'): 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) transaction_payload = context.client.get_new_pub_key_payload(pub_key, rem_sig, crt_sig, valid_from, valid_to) cert_address = PubKeyHandler.make_address_from_data(pub_key) if type == 'store': context.client.store_pub_key(pub_key, rem_sig, crt_sig, valid_from, valid_to) elif type == 'revoke': context.client.revoke_pub_key(cert_address) else: raise AssertionError('Type for pre parse not found') return cert_address, transaction_payload
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_store_fail_invalid_validity_date(self): context = self.get_context() cert, key, _ = create_certificate(context.pub_key_payload, signer=context.client.get_signer()) 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) cert_address = PubKeyHandler.make_address_from_data(pub_key) valid_from = int(valid_from - PUB_KEY_MAX_VALIDITY.total_seconds()) valid_to = int(valid_to + PUB_KEY_MAX_VALIDITY.total_seconds()) context.client.store_pub_key(pub_key, rem_sig, crt_sig, valid_from, valid_to) self.expect_get({cert_address: None}) self.expect_invalid_transaction()
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)
def test_public_key_handler_store_with_empty_proto(): """ Case: send transaction request to store certificate public key with empty proto Expect: invalid transaction error """ new_public_key_payload = NewPubKeyPayload() 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 proto_error_msg( NewPubKeyPayload, { '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' ], }) == str(error.value)
def test_store_public_key_for_other_public_key_exceeded_validity(): """ Case: send transaction request to store certificate public key with exceeded validity for other. Expect: invalid transaction error is raised with validity exceeds the maximum value error message. """ new_public_key_payload = generate_rsa_payload( key=CERTIFICATE_PUBLIC_KEY, valid_to=int(EXCEEDED_PUBLIC_KEY_VALIDITY_TIMESTAMP), ) 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 'The public key validity exceeds the maximum value.' == str(error.value)
def test_public_key_handler_non_existing_sender_account(): """ Case: send transaction request, to store certificate public key, from non-existing account. Expect: invalid transaction error is raised with not enough transferable balance 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), ) zero_account = Account() zero_account.balance = 0 serialized_zero_account = zero_account.SerializeToString() mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ 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_public_key_handler_store_public_key_exceeded_validity(): """ Case: send transaction request to store certificate public key with exceeded validity. Expect: invalid transaction error is raised with validity exceeds the maximum value error message. """ new_public_key_payload = generate_rsa_payload( valid_to=int(EXCEEDED_PUBLIC_KEY_VALIDITY_TIMESTAMP)) 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 'The public key validity exceeds the maximum value.' == str( error.value)
def test_public_key_handler_rsa_store(): """ Case: send transaction request to store certificate public key. Expect: public key information is stored to blockchain linked to owner address. Owner paid tokens for storing. """ 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), ) sender_account = Account() sender_account.balance = SENDER_INITIAL_BALANCE sender_account.pub_keys.append(RANDOM_ALREADY_STORED_SENDER_PUBLIC_KEY) serialized_sender_account = sender_account.SerializeToString() zero_account = Account() zero_account.balance = 0 serialized_zero_account = zero_account.SerializeToString() mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ SENDER_ADDRESS: serialized_sender_account, ZERO_ADDRESS: serialized_zero_account, }) expected_public_key_storage = PubKeyStorage() expected_public_key_storage.owner = SENDER_PUBLIC_KEY expected_public_key_storage.payload.CopyFrom(new_public_key_payload) expected_public_key_storage.is_revoked = False expected_serialized_public_key_storage = expected_public_key_storage.SerializeToString( ) expected_sender_account = Account() expected_sender_account.balance = SENDER_INITIAL_BALANCE - PUB_KEY_STORE_PRICE expected_sender_account.pub_keys.append( RANDOM_ALREADY_STORED_SENDER_PUBLIC_KEY) expected_sender_account.pub_keys.append( ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY) expected_serialized_sender_account = expected_sender_account.SerializeToString( ) expected_zero_account = Account() expected_zero_account.balance = 0 + PUB_KEY_STORE_PRICE expected_serialized_zero_account = expected_zero_account.SerializeToString( ) expected_state = { SENDER_ADDRESS: expected_serialized_sender_account, ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY: expected_serialized_public_key_storage, ZERO_ADDRESS: expected_serialized_zero_account, } PubKeyHandler().apply(transaction=transaction_request, context=mock_context) state_as_list = mock_context.get_state(addresses=[ SENDER_ADDRESS, ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY, ZERO_ADDRESS, ]) 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_economy_is_not_enabled(): """ Case: send transaction request, to store certificate public key for other, when economy isn't enabled. Expect: public key information is stored to blockchain linked to owner address. Owner hasn't paid for storing. """ 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), ) payer_account = Account() payer_account.balance = PAYER_INITIAL_BALANCE serialized_payer_account = payer_account.SerializeToString() 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() is_economy_enabled_setting = Setting() is_economy_enabled_setting.entries.add(key='remme.economy_enabled', value='false') serialized_is_economy_enabled_setting = is_economy_enabled_setting.SerializeToString() mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ OWNER_ADDRESS: serialized_owner_account, PAYER_ADDRESS: serialized_payer_account, ZERO_ADDRESS: serialized_zero_account, IS_NODE_ECONOMY_ENABLED_ADDRESS: serialized_is_economy_enabled_setting, }) expected_public_key_storage = PubKeyStorage() expected_public_key_storage.owner = OWNER_PUBLIC_KEY expected_public_key_storage.payload.CopyFrom(new_public_key_payload) expected_public_key_storage.is_revoked = False expected_serialized_public_key_storage = expected_public_key_storage.SerializeToString() expected_payer_account = Account() expected_payer_account.balance = PAYER_INITIAL_BALANCE serialized_expected_payer_account = expected_payer_account.SerializeToString() expected_owner_account = Account() expected_owner_account.pub_keys.append(RANDOM_ALREADY_STORED_OWNER_PUBLIC_KEY_ADDRESS) expected_owner_account.pub_keys.append(ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY) serialized_expected_owner_account = expected_owner_account.SerializeToString() expected_zero_account = Account() expected_zero_account.balance = 0 expected_serialized_zero_account = expected_zero_account.SerializeToString() expected_state = { OWNER_ADDRESS: serialized_expected_owner_account, PAYER_ADDRESS: serialized_expected_payer_account, ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY: expected_serialized_public_key_storage, ZERO_ADDRESS: expected_serialized_zero_account, } PubKeyHandler().apply(transaction=transaction_request, context=mock_context) state_as_list = mock_context.get_state(addresses=[ OWNER_ADDRESS, PAYER_ADDRESS, ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY, ZERO_ADDRESS, ]) state_as_dict = {entry.address: entry.data for entry in state_as_list} assert expected_state == state_as_dict
# 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)
IS_NODE_ECONOMY_ENABLED_ADDRESS = generate_settings_address('remme.economy_enabled') RANDOM_ALREADY_STORED_SENDER_PUBLIC_KEY = 'a23be17ca9c3bd150627ac6469f11ccf25c0c96d8bb8ac333879d3ea06a90413cd4536' RANDOM_NODE_PUBLIC_KEY = '039d6881f0a71d05659e1f40b443684b93c7b7c504ea23ea8949ef5216a2236940' MESSAGE = generate_message('some-data-to-sign') CURRENT_TIMESTAMP = datetime.datetime.now().timestamp() CURRENT_TIMESTAMP_PLUS_YEAR = CURRENT_TIMESTAMP + PUB_KEY_MAX_VALIDITY.total_seconds() EXCEEDED_PUBLIC_KEY_VALIDITY_TIMESTAMP = CURRENT_TIMESTAMP_PLUS_YEAR + 1 RSA_PUBLIC_KEY_TO_STORE_TYPE_VALUE = PERSONAL_PUBLIC_KEY_TYPE_VALUE = 0 TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS = { 'family_name': PubKeyHandler().family_name, 'family_version': PubKeyHandler()._family_versions[0], } def generate_rsa_payload(key=None, entity_hash=None, entity_hash_signature=None, valid_to=int(CURRENT_TIMESTAMP_PLUS_YEAR)): if key is None: key = CERTIFICATE_PUBLIC_KEY if entity_hash is None: entity_hash = generate_entity_hash(MESSAGE) if entity_hash_signature is None: entity_hash_signature = generate_rsa_signature(entity_hash, CERTIFICATE_PRIVATE_KEY) return NewPubKeyPayload( entity_hash=entity_hash, entity_hash_signature=entity_hash_signature, valid_from=int(CURRENT_TIMESTAMP),
# 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"] }')
def test_public_key_handler_store_sender_is_node(): """ Case: send transaction request, to store certificate public key, when sender is node (same addresses). Expect: public key information is stored to blockchain linked to owner address. Owner hasn't paid for storing. """ 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), ) sender_account = Account() sender_account.pub_keys.append(RANDOM_ALREADY_STORED_SENDER_PUBLIC_KEY) serialized_sender_account = sender_account.SerializeToString() zero_account = Account() serialized_zero_account = zero_account.SerializeToString() is_economy_enabled_setting = Setting() is_economy_enabled_setting.entries.add(key='remme.economy_enabled', value='false') serialized_is_economy_enabled_setting = is_economy_enabled_setting.SerializeToString( ) mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ SENDER_ADDRESS: serialized_sender_account, IS_NODE_ECONOMY_ENABLED_ADDRESS: serialized_is_economy_enabled_setting, ZERO_ADDRESS: serialized_zero_account, }) expected_public_key_storage = PubKeyStorage() expected_public_key_storage.owner = SENDER_PUBLIC_KEY expected_public_key_storage.payload.CopyFrom(new_public_key_payload) expected_public_key_storage.is_revoked = False expected_serialized_public_key_storage = expected_public_key_storage.SerializeToString( ) expected_sender_account = Account() expected_sender_account.pub_keys.append( RANDOM_ALREADY_STORED_SENDER_PUBLIC_KEY) expected_sender_account.pub_keys.append( ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY) expected_serialized_sender_account = expected_sender_account.SerializeToString( ) expected_zero_account = Account() expected_serialized_zero_account = expected_zero_account.SerializeToString( ) expected_state = { SENDER_ADDRESS: expected_serialized_sender_account, ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY: expected_serialized_public_key_storage, ZERO_ADDRESS: expected_serialized_zero_account, } PubKeyHandler().apply(transaction=transaction_request, context=mock_context) state_as_list = mock_context.get_state(addresses=[ SENDER_ADDRESS, ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY, ZERO_ADDRESS, ]) state_as_dict = {entry.address: entry.data for entry in state_as_list} assert expected_state == state_as_dict
def test_store_rsa_public_key_no_owner_account(): """ Case: send transaction request, to store certificate public key (RSA) for other, when owner account does not exist. Expect: public key information is stored to blockchain linked to the newly created owner account's address. """ 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), ) payer_account = Account() payer_account.balance = PAYER_INITIAL_BALANCE serialized_payer_account = payer_account.SerializeToString() zero_account = Account() zero_account.balance = 0 serialized_zero_account = zero_account.SerializeToString() mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={ PAYER_ADDRESS: serialized_payer_account, ZERO_ADDRESS: serialized_zero_account, }) expected_public_key_storage = PubKeyStorage() expected_public_key_storage.owner = OWNER_PUBLIC_KEY expected_public_key_storage.payload.CopyFrom(new_public_key_payload) expected_public_key_storage.is_revoked = False expected_serialized_public_key_storage = expected_public_key_storage.SerializeToString() expected_payer_account = Account() expected_payer_account.balance = PAYER_INITIAL_BALANCE - PUB_KEY_STORE_PRICE serialized_expected_payer_account = expected_payer_account.SerializeToString() expected_owner_account = Account() expected_owner_account.pub_keys.append(ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY) serialized_expected_owner_account = expected_owner_account.SerializeToString() expected_zero_account = Account() expected_zero_account.balance = 0 + PUB_KEY_STORE_PRICE expected_serialized_zero_account = expected_zero_account.SerializeToString() expected_state = { OWNER_ADDRESS: serialized_expected_owner_account, PAYER_ADDRESS: serialized_expected_payer_account, ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY: expected_serialized_public_key_storage, ZERO_ADDRESS: expected_serialized_zero_account, } PubKeyHandler().apply(transaction=transaction_request, context=mock_context) state_as_list = mock_context.get_state(addresses=[ OWNER_ADDRESS, PAYER_ADDRESS, ADDRESS_FROM_CERTIFICATE_PUBLIC_KEY, ZERO_ADDRESS, ]) state_as_dict = {entry.address: entry.data for entry in state_as_list} assert expected_state == state_as_dict
# 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:
def test_store_ecdsa_public_key(): """ Case: send transaction request to store certificate public key (ECDSA) for other. Expect: public key information is stored to blockchain linked to owner address. Transaction sender paid for storing. """ inputs = outputs = [ ADDRESS_FROM_ECDSA_PUBLIC_KEY, OWNER_ADDRESS, PAYER_ADDRESS, ZERO_ADDRESS, IS_NODE_ECONOMY_ENABLED_ADDRESS, ] new_public_key_payload = generate_ecdsa_payload(key=ECDSA_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), ) payer_account = Account() payer_account.balance = PAYER_INITIAL_BALANCE serialized_payer_account = payer_account.SerializeToString() 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, PAYER_ADDRESS: serialized_payer_account, ZERO_ADDRESS: serialized_zero_account, }) expected_public_key_storage = PubKeyStorage() expected_public_key_storage.owner = OWNER_PUBLIC_KEY expected_public_key_storage.payload.CopyFrom(new_public_key_payload) expected_public_key_storage.is_revoked = False expected_serialized_public_key_storage = expected_public_key_storage.SerializeToString() expected_payer_account = Account() expected_payer_account.balance = PAYER_INITIAL_BALANCE - PUB_KEY_STORE_PRICE serialized_expected_payer_account = expected_payer_account.SerializeToString() expected_owner_account = Account() expected_owner_account.pub_keys.append(RANDOM_ALREADY_STORED_OWNER_PUBLIC_KEY_ADDRESS) expected_owner_account.pub_keys.append(ADDRESS_FROM_ECDSA_PUBLIC_KEY) serialized_expected_owner_account = expected_owner_account.SerializeToString() expected_zero_account = Account() expected_zero_account.balance = 0 + PUB_KEY_STORE_PRICE expected_serialized_zero_account = expected_zero_account.SerializeToString() expected_state = { OWNER_ADDRESS: serialized_expected_owner_account, PAYER_ADDRESS: serialized_expected_payer_account, ADDRESS_FROM_ECDSA_PUBLIC_KEY: expected_serialized_public_key_storage, ZERO_ADDRESS: expected_serialized_zero_account, } PubKeyHandler().apply(transaction=transaction_request, context=mock_context) state_as_list = mock_context.get_state(addresses=[ OWNER_ADDRESS, PAYER_ADDRESS, ADDRESS_FROM_ECDSA_PUBLIC_KEY, ZERO_ADDRESS, ]) state_as_dict = {entry.address: entry.data for entry in state_as_list} assert expected_state == state_as_dict