Example #1
0
 def create_from_signed_change_request_message(
         cls: Type[T], message: SignedChangeRequestMessage,
         signing_key: hexstr) -> T:
     request = cls(signer=derive_public_key(signing_key),
                   message=copy.deepcopy(message))
     request.sign(signing_key)
     return request
Example #2
0
def test_generate_key_pair():
    key_pair = generate_key_pair()
    assert isinstance(key_pair.private, str)
    assert len(key_pair.private) == 64
    assert isinstance(key_pair.public, str)
    assert len(key_pair.public) == 64

    derived_public = derive_public_key(key_pair.private)
    assert derived_public == key_pair.public
    assert derived_public is not key_pair.public
def test_can_create_block_from_signed_change_request(
    forced_mock_blockchain, sample_signed_change_request: CoinTransferSignedChangeRequest
):

    sender = sample_signed_change_request.signer
    assert sender

    def get_account_balance(self, account, on_block_number):
        return 450 if account == sender else 0

    with patch.object(MockBlockchain, 'get_account_balance', new=get_account_balance):
        block = Block.create_from_signed_change_request(
            forced_mock_blockchain, sample_signed_change_request, get_node_signing_key()
        )

    assert block.message
    assert block.hash
    assert block.signature
    block.validate_signature()
    assert block.signer
    assert block.signer == derive_public_key(get_node_signing_key())

    block_message = block.message

    signed_change_request = block_message.signed_change_request
    assert signed_change_request == sample_signed_change_request
    assert signed_change_request is not sample_signed_change_request  # test that a copy of it was made

    assert isinstance(block_message.timestamp, datetime)
    assert block_message.timestamp.tzinfo is None
    assert block_message.timestamp - datetime.utcnow() < timedelta(seconds=1)

    assert block_message.block_number == 0
    assert block_message.block_identifier == 'next-block-identifier'
    updated_account_states = block_message.updated_account_states

    assert isinstance(updated_account_states, dict)
    assert len(updated_account_states) == 4

    assert updated_account_states[sender].balance == 450 - 425 - 4 - 1
    assert updated_account_states[sender].balance_lock

    assert updated_account_states['484b3176c63d5f37d808404af1a12c4b9649cd6f6769f35bdf5a816133623fbc'].balance == 425
    assert updated_account_states['484b3176c63d5f37d808404af1a12c4b9649cd6f6769f35bdf5a816133623fbc'
                                  ].balance_lock is None

    assert updated_account_states['ad1f8845c6a1abb6011a2a434a079a087c460657aad54329a84b406dce8bf314'].balance == 4
    assert updated_account_states['ad1f8845c6a1abb6011a2a434a079a087c460657aad54329a84b406dce8bf314'
                                  ].balance_lock is None

    assert updated_account_states['5e12967707909e62b2bb2036c209085a784fabbc3deccefee70052b6181c8ed8'].balance == 1
    assert updated_account_states['5e12967707909e62b2bb2036c209085a784fabbc3deccefee70052b6181c8ed8'
                                  ].balance_lock is None
Example #4
0
def add_blocks_to_blockchain(blockchain, block_count, treasury_account_private_key):
    treasury_account_key_pair = KeyPair(
        public=derive_public_key(treasury_account_private_key), private=treasury_account_private_key
    )
    generate_blockchain(
        blockchain,
        block_count,
        get_node_signing_key(),
        add_blockchain_genesis_state=False,
        validate=False,
        treasury_account_key_pair=treasury_account_key_pair
    )
Example #5
0
 def create_from_signed_change_request(
     cls: Type[T],
     blockchain,
     signed_change_request: SignedChangeRequest,
     pv_signing_key,
 ) -> T:
     block = cls(
         signer=derive_public_key(pv_signing_key),
         message=BlockMessage.from_signed_change_request(blockchain, signed_change_request)
     )
     block.sign(pv_signing_key)
     block.hash_message()
     return block
Example #6
0
 def create(cls: Type[T],
            *,
            network_addresses: list[str],
            fee_amount: int,
            signing_key: hexstr,
            fee_account: Optional[hexstr] = None) -> T:
     message = NodeDeclarationSignedChangeRequestMessage.create(
         identifier=derive_public_key(signing_key),
         network_addresses=network_addresses,
         fee_amount=fee_amount,
         fee_account=fee_account,
     )
     return cls.create_from_signed_change_request_message(
         message, signing_key)
Example #7
0
    def sign(self, signing_key):
        verify_key = derive_public_key(signing_key)
        stored_verify_key = self.signer
        if not stored_verify_key:
            logger.warning('Signing message with an empty signer')
        elif stored_verify_key != verify_key:
            logger.warning('Signer does not match with signing key')

        message_signature = self.message.generate_signature(signing_key)
        stored_message_signature = self.signature
        if stored_message_signature and stored_message_signature != message_signature:
            logger.warning('Overwriting existing message signature')

        self.signature = message_signature
Example #8
0
 def from_main_transaction(cls: Type[T],
                           *,
                           blockchain,
                           recipient: hexstr,
                           amount: int,
                           signing_key: hexstr,
                           primary_validator: PrimaryValidator,
                           node: RegularNode,
                           memo: str = None) -> T:
     message = CoinTransferSignedChangeRequestMessage.from_main_transaction(
         blockchain=blockchain,
         coin_sender=derive_public_key(signing_key),
         recipient=recipient,
         amount=amount,
         primary_validator=primary_validator,
         node=node,
         memo=memo,
     )
     return cls.create_from_signed_change_request_message(
         message, signing_key)
def test_can_get_self_node(forced_memory_blockchain, api_client):
    blockchain = forced_memory_blockchain
    signing_key = get_node_signing_key()
    node_id = derive_public_key(signing_key)
    node_declaration_request = NodeDeclarationSignedChangeRequest.create(
        network_addresses=['http://my.domain.com/'],
        fee_amount=3,
        signing_key=signing_key,
    )
    block = Block.create_from_signed_change_request(
        blockchain,
        signed_change_request=node_declaration_request,
        pv_signing_key=signing_key,
    )
    blockchain.add_block(block)

    response = api_client.get(f'{API_V1_NODES_PREFIX}/self/')

    assert response.status_code == 200
    data = response.json()
    assert data['identifier'] == node_id
    assert data['fee_amount'] == 3
Example #10
0
def get_node_identifier() -> hexstr:
    return derive_public_key(get_node_signing_key())
def test_can_create_block_from_main_transaction(
    forced_mock_blockchain, treasury_account_key_pair: KeyPair, user_account_key_pair: KeyPair,
    primary_validator_key_pair: KeyPair, node_key_pair: KeyPair
):

    def get_account_balance(self, account, on_block_number):
        return 430 if account == treasury_account_key_pair.public else 0

    with patch.object(MockBlockchain, 'get_account_balance', new=get_account_balance):
        block = Block.create_from_main_transaction(
            blockchain=forced_mock_blockchain,
            recipient=user_account_key_pair.public,
            amount=20,
            request_signing_key=treasury_account_key_pair.private,
            pv_signing_key=get_node_signing_key(),
        )

    # Assert block
    assert block.message
    assert block.hash
    assert block.signature

    block.validate_signature()
    assert block.signer
    assert block.signer == derive_public_key(get_node_signing_key())

    # Assert block.message
    block_message = block.message
    assert block_message
    assert isinstance(block_message.timestamp, datetime)
    assert block_message.timestamp.tzinfo is None
    assert block_message.timestamp - datetime.utcnow() < timedelta(seconds=1)

    assert block_message.block_number == 0
    assert block_message.block_identifier == 'next-block-identifier'
    updated_account_states = block_message.updated_account_states

    assert isinstance(updated_account_states, dict)
    assert len(updated_account_states) == 4

    assert updated_account_states[treasury_account_key_pair.public].balance == 430 - 25
    assert updated_account_states[treasury_account_key_pair.public].balance_lock

    assert updated_account_states[user_account_key_pair.public].balance == 20
    assert updated_account_states[user_account_key_pair.public].balance_lock is None

    assert updated_account_states[primary_validator_key_pair.public].balance == 4
    assert updated_account_states[primary_validator_key_pair.public].balance_lock is None

    assert updated_account_states[node_key_pair.public].balance == 1
    assert updated_account_states[node_key_pair.public].balance_lock is None

    # Assert block_message.signed_change_request
    signed_change_request = block_message.signed_change_request
    assert signed_change_request.signer == treasury_account_key_pair.public
    assert signed_change_request.signature

    # Assert block_message.signed_change_request.message
    coin_transfer_signed_request_message = signed_change_request.message
    assert isinstance(coin_transfer_signed_request_message, CoinTransferSignedChangeRequestMessage)
    assert coin_transfer_signed_request_message.balance_lock
    assert len(coin_transfer_signed_request_message.txs) == 3
    txs_dict = {tx.recipient: tx for tx in coin_transfer_signed_request_message.txs}
    assert len(txs_dict) == 3

    assert txs_dict[user_account_key_pair.public].amount == 20
    assert txs_dict[user_account_key_pair.public].is_fee is False

    assert txs_dict[primary_validator_key_pair.public].amount == 4
    assert txs_dict[primary_validator_key_pair.public].is_fee

    assert txs_dict[node_key_pair.public].amount == 1
    assert txs_dict[node_key_pair.public].is_fee

    assert coin_transfer_signed_request_message.get_total_amount() == 25