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

    account_protobuf = Account()

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

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

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

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

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

    serialized_transaction_payload = transaction_payload.SerializeToString()

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

    serialized_header = transaction_header.SerializeToString()

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

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

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

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

    assert expected_state == state_as_dict
Пример #2
0
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)
Пример #3
0
 def _genesis(self, context, pub_key, genesis_payload):
     signer_key = self.make_address_from_data(pub_key)
     genesis_status = get_data(context, GenesisStatus, GENESIS_ADDRESS)
     if not genesis_status:
         genesis_status = GenesisStatus()
     elif genesis_status.status:
         raise InvalidTransaction('Genesis is already initialized.')
     genesis_status.status = True
     account = Account()
     account.balance = genesis_payload.total_supply
     LOGGER.info(
         'Generated genesis transaction. Issued {} tokens to address {}'.
         format(genesis_payload.total_supply, signer_key))
     return {signer_key: account, GENESIS_ADDRESS: genesis_status}
Пример #4
0
def create_context(account_from_balance, account_to_balance):
    """
    Create stub context with initial data.

    Stub context is an interface around Sawtooth state, consider as database.
    State is key-value storage that contains address with its data (i.e. account balance).

    References:
        - https://github.com/Remmeauth/remme-core/blob/dev/testing/mocks/stub.py
    """
    account_protobuf = Account()

    account_protobuf.balance = account_from_balance
    serialized_account_from_balance = account_protobuf.SerializeToString()

    account_protobuf.balance = account_to_balance
    serialized_account_to_balance = account_protobuf.SerializeToString()

    initial_state = {
        ACCOUNT_ADDRESS_FROM: serialized_account_from_balance,
        ACCOUNT_ADDRESS_TO: serialized_account_to_balance,
    }

    return StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state=initial_state)
Пример #5
0
    def test_genesis_success(self):
        TOTAL_SUPPLY = 10000

        self.send_transaction(AccountMethod.GENESIS, AccountClient.get_genesis_payload(TOTAL_SUPPLY),
                              [GENESIS_ADDRESS, self.account_address1])

        self.expect_get({GENESIS_ADDRESS: None})

        genesis_status = GenesisStatus()
        genesis_status.status = True
        account = Account()
        account.balance = TOTAL_SUPPLY

        self.expect_set({
            self.account_address1: account,
            GENESIS_ADDRESS: genesis_status
        })

        self.expect_ok()
Пример #6
0
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)
Пример #7
0
def test_expire_atomic_swap():
    """
    Case: to expire atomic swap.
    Expect: increase bot address balance by swap amount. Leave commission on zero address.
    """
    atomic_swap_expire_payload = AtomicSwapExpirePayload(swap_id=SWAP_ID, )

    transaction_payload = TransactionPayload()
    transaction_payload.method = AtomicSwapMethod.EXPIRE
    transaction_payload.data = atomic_swap_expire_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),
    )

    bot_account = Account()
    bot_account.balance = 4700
    serialized_bot_account = bot_account.SerializeToString()

    genesis_members_setting = Setting()
    genesis_members_setting.entries.add(key=SETTINGS_KEY_ZERO_ADDRESS_OWNERS,
                                        value=f'{BOT_PUBLIC_KEY},')
    serialized_genesis_members_setting = genesis_members_setting.SerializeToString(
    )

    existing_swap_info = AtomicSwapInfo()
    existing_swap_info.swap_id = SWAP_ID
    existing_swap_info.state = AtomicSwapInfo.OPENED
    existing_swap_info.amount = TOKENS_AMOUNT_TO_SWAP
    existing_swap_info.created_at = CURRENT_TIMESTAMP // 2
    existing_swap_info.sender_address = BOT_ADDRESS
    existing_swap_info.receiver_address = ALICE_ADDRESS
    existing_swap_info.is_initiator = True
    serialized_existing_swap_info = existing_swap_info.SerializeToString()

    mock_context = StubContext(inputs=INPUTS,
                               outputs=OUTPUTS,
                               initial_state={
                                   BLOCK_INFO_CONFIG_ADDRESS:
                                   SERIALIZED_BLOCK_INFO_CONFIG,
                                   BLOCK_INFO_ADDRESS:
                                   SERIALIZED_BLOCK_INFO,
                                   BOT_ADDRESS:
                                   serialized_bot_account,
                                   ADDRESS_TO_STORE_SWAP_INFO_BY:
                                   serialized_existing_swap_info,
                                   ADDRESS_TO_GET_GENESIS_MEMBERS_AS_STRING_BY:
                                   serialized_genesis_members_setting,
                               })

    expected_bot_account = Account()
    expected_bot_account.balance = 4700 + TOKENS_AMOUNT_TO_SWAP
    serialized_expected_bot_account = expected_bot_account.SerializeToString()

    expected_swap_info = AtomicSwapInfo()
    expected_swap_info.swap_id = SWAP_ID
    expected_swap_info.state = AtomicSwapInfo.EXPIRED
    expected_swap_info.amount = TOKENS_AMOUNT_TO_SWAP
    expected_swap_info.created_at = CURRENT_TIMESTAMP // 2
    expected_swap_info.sender_address = BOT_ADDRESS
    expected_swap_info.receiver_address = ALICE_ADDRESS
    expected_swap_info.is_initiator = True
    serialized_expected_swap_info = expected_swap_info.SerializeToString()

    expected_state = {
        BOT_ADDRESS: serialized_expected_bot_account,
        ADDRESS_TO_STORE_SWAP_INFO_BY: serialized_expected_swap_info,
    }

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

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

    assert expected_state == state_as_dict
Пример #8
0
    def get_account_model(self, balance):
        account = Account()
        account.balance = int(balance)

        return account
Пример #9
0
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
Пример #10
0
def test_account_handler_genesis_apply():
    """
    Case: send transaction request, to send tokens from genesis address, to the account handler.
    Expect:
    """
    account = Account()
    account.balance = TOKENS_AMOUNT_TO_SUPPLY
    expected_serialized_account_to_balance = account.SerializeToString()

    genesis_payload = GenesisPayload()
    genesis_payload.total_supply = TOKENS_AMOUNT_TO_SUPPLY

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

    serialized_transaction_payload = transaction_payload.SerializeToString()

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

    serialized_header = transaction_header.SerializeToString()

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

    genesis_status = GenesisStatus()
    genesis_status.status = True

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

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

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

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

    assert expected_state == state_as_dict
Пример #11
0
def test_close_atomic_swap():
    """
    Case: close atomic swap.
    Expect: increase Alice account address by swap amount.
    """
    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),
    )

    alice_account = Account()
    alice_account.balance = 0
    serialized_alice_account = alice_account.SerializeToString()

    existing_swap_info_to_close = AtomicSwapInfo()
    existing_swap_info_to_close.swap_id = SWAP_ID
    existing_swap_info_to_close.amount = 200
    existing_swap_info_to_close.state = AtomicSwapInfo.APPROVED
    existing_swap_info_to_close.secret_lock = SECRET_LOCK
    existing_swap_info_to_close.is_initiator = True
    existing_swap_info_to_close.sender_address = BOT_ADDRESS
    existing_swap_info_to_close.receiver_address = ALICE_ADDRESS
    serialized_existing_swap_info_to_lock = existing_swap_info_to_close.SerializeToString(
    )

    genesis_members_setting = Setting()
    genesis_members_setting.entries.add(key=SETTINGS_KEY_ZERO_ADDRESS_OWNERS,
                                        value=f'{BOT_PUBLIC_KEY},')
    serialized_genesis_members_setting = genesis_members_setting.SerializeToString(
    )

    mock_context = StubContext(inputs=INPUTS,
                               outputs=OUTPUTS,
                               initial_state={
                                   ADDRESS_TO_GET_GENESIS_MEMBERS_AS_STRING_BY:
                                   serialized_genesis_members_setting,
                                   ADDRESS_TO_STORE_SWAP_INFO_BY:
                                   serialized_existing_swap_info_to_lock,
                                   ALICE_ADDRESS: serialized_alice_account,
                               })

    expected_alice_account = Account()
    expected_alice_account.balance = TOKENS_AMOUNT_TO_SWAP
    serialized_expected_alice_account = expected_alice_account.SerializeToString(
    )

    expected_closed_swap_info = AtomicSwapInfo()
    expected_closed_swap_info.swap_id = SWAP_ID
    expected_closed_swap_info.amount = 200
    expected_closed_swap_info.state = AtomicSwapInfo.CLOSED
    expected_closed_swap_info.secret_lock = SECRET_LOCK
    expected_closed_swap_info.secret_key = SECRET_KEY
    expected_closed_swap_info.is_initiator = True
    expected_closed_swap_info.sender_address = BOT_ADDRESS
    expected_closed_swap_info.receiver_address = ALICE_ADDRESS
    serialized_expected_closed_swap_info = expected_closed_swap_info.SerializeToString(
    )

    expected_state = {
        ADDRESS_TO_STORE_SWAP_INFO_BY: serialized_expected_closed_swap_info,
        ALICE_ADDRESS: serialized_expected_alice_account,
    }

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

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

    assert expected_state == state_as_dict
Пример #12
0
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
Пример #13
0
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
Пример #14
0
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
Пример #15
0
def test_atomic_swap_init_swap_not_enough_balance():
    """
    Case: initialize swap of bot's Remme node tokens to Alice's ERC20 Remme tokens with not enough bot address balance.
    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),
    )

    bot_account = Account()
    bot_account.balance = 0
    serialized_bot_account_balance = bot_account.SerializeToString()

    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,
        BOT_ADDRESS: serialized_bot_account_balance,
        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)
Пример #16
0
def test_atomic_swap_init():
    """
    Case: initialize swap of bot's Remme node tokens to Alice's ERC20 Remme tokens.
    Expect: bot sends commission to the zero account address, swap amount is decreased from bot account.
    """

    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),
    )

    bot_account = Account()
    bot_account.balance = 5000
    serialized_bot_account = bot_account.SerializeToString()

    zero_account = Account()
    zero_account.balance = 0
    serialized_zero_account = zero_account.SerializeToString()

    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()

    genesis_members_setting = Setting()
    genesis_members_setting.entries.add(key=SETTINGS_KEY_ZERO_ADDRESS_OWNERS, value=f'{BOT_PUBLIC_KEY},')
    serialized_genesis_members_setting = genesis_members_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,
        BOT_ADDRESS: serialized_bot_account,
        ZERO_ADDRESS: serialized_zero_account,
        ADDRESS_TO_GET_SWAP_COMMISSION_AMOUNT_BY: serialized_swap_commission_setting,
        ADDRESS_TO_GET_GENESIS_MEMBERS_AS_STRING_BY: serialized_genesis_members_setting,
    })

    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.email_address_encrypted_optional = ALICE_EMAIL_ADDRESS_ENCRYPTED_BY_INITIATOR
    swap_info.sender_address = BOT_ADDRESS
    swap_info.sender_address_non_local = BOT_ETHEREUM_ADDRESS
    swap_info.receiver_address = ALICE_ADDRESS
    swap_info.is_initiator = True
    serialized_swap_info = swap_info.SerializeToString()

    expected_bot_account = Account()
    expected_bot_account.balance = 5000 - TOKENS_AMOUNT_TO_SWAP - SWAP_COMMISSION_AMOUNT
    serialized_expected_bot_account = expected_bot_account.SerializeToString()

    expected_zero_account = Account()
    expected_zero_account.balance = SWAP_COMMISSION_AMOUNT
    serialized_expected_zero_account = expected_zero_account.SerializeToString()

    expected_state = {
        BOT_ADDRESS: serialized_expected_bot_account,
        ZERO_ADDRESS: serialized_expected_zero_account,
        ADDRESS_TO_STORE_SWAP_INFO_BY: serialized_swap_info,
    }

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

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

    assert expected_state == state_as_dict