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_verify_key(key_pair.private)
    assert derived_public == key_pair.public
    assert derived_public is not key_pair.public
def pick_recipient(candidates, exclude=(), pick_existing_probability=0.5):
    recipient = None
    private_key = None
    if random.random() < pick_existing_probability:
        recipient = random.choice(candidates)
        if recipient in exclude:
            recipient = None

    if recipient is None:
        recipient_key_pair = generate_key_pair()
        logger.info('New recipient account: %s', recipient_key_pair)
        recipient = recipient_key_pair.public
        private_key = recipient_key_pair.private

    return recipient, private_key
Example #3
0
def test_can_get_nodes_from_genesis_state_and_blocks(
    blockchain_directory, blockchain_genesis_state, user_account_key_pair
):
    blockchain = FileBlockchain(base_directory=blockchain_directory)

    key_pair = generate_key_pair()
    blockchain_state_node = baker.make(Node, identifier=key_pair.public)
    blockchain_genesis_state.account_states[key_pair.public] = AccountState(node=blockchain_state_node)

    blockchain.add_blockchain_state(blockchain_genesis_state)
    blockchain.validate()

    request = NodeDeclarationSignedChangeRequest.create(
        network_addresses=['https://127.0.0.1:8555/'], fee_amount=3, signing_key=user_account_key_pair.private
    )
    blocks_node = request.message.node
    assert blocks_node.identifier

    block = Block.create_from_signed_change_request(blockchain, request, get_node_signing_key())
    blockchain.add_block(block)

    assert list(blockchain.yield_nodes()) == [blocks_node, blockchain_state_node]
Example #4
0
def test_can_get_nodes_from_complex_blockchain(blockchain_directory, blockchain_genesis_state):
    key_pair1 = generate_key_pair()
    key_pair2 = generate_key_pair()
    key_pair3 = generate_key_pair()
    key_pair4 = generate_key_pair()
    key_pair5 = generate_key_pair()
    key_pair6 = generate_key_pair()
    assert len({
        key_pair1.public, key_pair2.public, key_pair3.public, key_pair4.public, key_pair5.public, key_pair6.public
    }) == 6

    blockchain = FileBlockchain(base_directory=blockchain_directory)
    node1 = baker.make(Node, network_addresses=['https://192.168.0.29:8555/'], identifier=key_pair1.public)
    blockchain_genesis_state.account_states[node1.identifier] = AccountState(node=node1)
    blockchain.add_blockchain_state(blockchain_genesis_state)
    blockchain.validate()

    # Block 0
    request = NodeDeclarationSignedChangeRequest.create(
        network_addresses=['https://192.168.0.30:8555/'], fee_amount=3, signing_key=key_pair2.private
    )
    node2 = request.message.node
    blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key()))

    # Block 1
    request = NodeDeclarationSignedChangeRequest.create(
        network_addresses=['https://192.168.0.31:8555/'], fee_amount=3, signing_key=key_pair3.private
    )
    node3_old = request.message.node
    blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key()))

    # Block 2
    request = NodeDeclarationSignedChangeRequest.create(
        network_addresses=['https://192.168.0.32:8555/'], fee_amount=3, signing_key=key_pair4.private
    )
    node4 = request.message.node
    blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key()))

    def sort_key(value):
        return value.network_addresses

    def sort_me(list_):
        return sorted(list_, key=sort_key)

    assert sort_me(blockchain.yield_nodes(block_number=2)) == sort_me([node4, node3_old, node2, node1])

    blockchain.snapshot_blockchain_state()

    # Block 3
    request = NodeDeclarationSignedChangeRequest.create(
        network_addresses=['https://192.168.0.33:8555/'], fee_amount=3, signing_key=key_pair3.private
    )
    node3 = request.message.node
    blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key()))

    # Block 4
    request = NodeDeclarationSignedChangeRequest.create(
        network_addresses=['https://192.168.0.34:8555/'], fee_amount=3, signing_key=key_pair5.private
    )
    node5 = request.message.node
    blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key()))

    # Block 5
    request = NodeDeclarationSignedChangeRequest.create(
        network_addresses=['https://192.168.0.35:8555/'], fee_amount=3, signing_key=key_pair6.private
    )
    node6 = request.message.node
    blockchain.add_block(Block.create_from_signed_change_request(blockchain, request, get_node_signing_key()))

    assert sort_me(blockchain.yield_nodes()) == sort_me([node6, node5, node3, node4, node2, node1])
    assert sort_me(blockchain.yield_nodes(block_number=5)) == sort_me([node6, node5, node3, node4, node2, node1])
    assert sort_me(blockchain.yield_nodes(block_number=4)) == sort_me([node5, node3, node4, node2, node1])
    assert sort_me(blockchain.yield_nodes(block_number=3)) == sort_me([node3, node4, node2, node1])
    assert sort_me(blockchain.yield_nodes(block_number=2)) == sort_me([node4, node3_old, node2, node1])
    assert sort_me(blockchain.yield_nodes(block_number=1)) == sort_me([node3_old, node2, node1])
    assert sort_me(blockchain.yield_nodes(block_number=0)) == sort_me([node2, node1])
    assert sort_me(blockchain.yield_nodes(block_number=-1)) == sort_me([node1])
Example #5
0
 def handle(self, *args, **options):
     self.stdout.write(generate_key_pair().private)
def generate_blockchain(blockchain: BlockchainBase,
                        size,
                        add_blockchain_genesis_state=True,
                        validate=True,
                        treasury_account_key_pair=None):
    treasury_account_key_pair = treasury_account_key_pair or generate_key_pair(
    )
    treasury_account = treasury_account_key_pair.public
    logger.info('Using treasury account: %s', treasury_account_key_pair)

    if add_blockchain_genesis_state and blockchain.get_blockchain_states_count(
    ) == 0:
        blockchain_genesis_state = BlockchainState(
            account_states={
                treasury_account:
                AccountState(balance=281474976710656,
                             balance_lock=treasury_account)
            })
        blockchain.add_blockchain_state(blockchain_genesis_state)

    primary_validator = PrimaryValidator(identifier=get_node_identifier(),
                                         fee_amount=4,
                                         network_addresses=[])
    pv_fee = primary_validator.fee_amount

    preferred_node = RegularNode(identifier=generate_key_pair().public,
                                 fee_amount=1,
                                 network_addresses=[])
    node_fee = preferred_node.fee_amount

    balances = get_initial_balances(blockchain)
    accounts = list(balances)

    assert len(balances) == 1
    assert treasury_account in balances
    assert balances[treasury_account] >= MAX_AMOUNT

    account_private_keys = {
        treasury_account: treasury_account_key_pair.private
    }
    sender_candidates = {treasury_account}
    min_sender_amount = MAX_AMOUNT + pv_fee + node_fee

    for _ in tqdm(range(size)):
        amount = random.randint(1, MAX_AMOUNT)
        # TODO(dmu) MEDIUM: Improve performance at tuple(sender_candidates)
        sender = random.choice(tuple(sender_candidates))
        sender_private_key = account_private_keys[sender]

        recipient, recipient_private_key = pick_recipient(accounts,
                                                          exclude=(sender, ))
        if recipient_private_key:
            # We got new recipient
            accounts.append(recipient)
            account_private_keys[recipient] = recipient_private_key

        signed_change_request = CoinTransferSignedChangeRequest.from_main_transaction(
            blockchain=blockchain,
            recipient=recipient,
            amount=amount,
            signing_key=sender_private_key,
            primary_validator=primary_validator,
            node=preferred_node)

        sender_new_balance = balances[sender] - (amount + pv_fee + node_fee)
        balances[sender] = sender_new_balance
        if sender_new_balance < min_sender_amount:
            sender_candidates.discard(sender)

        recipient_new_balance = balances.get(recipient, 0) + amount
        balances[recipient] = recipient_new_balance
        if recipient_new_balance >= min_sender_amount:
            sender_candidates.add(recipient)

        blockchain.add_block_from_signed_change_request(signed_change_request,
                                                        validate=validate)
Example #7
0
def test_partial_blockchain(primary_validator, preferred_node):
    account1_key_pair = generate_key_pair()
    account2_key_pair = generate_key_pair()
    account3_key_pair = generate_key_pair()
    new_account_key_pair = generate_key_pair()

    fake_lock1, _ = generate_key_pair()
    fake_lock2, _ = generate_key_pair()
    fake_lock3, _ = generate_key_pair()

    base_account_root_file = BlockchainState(
        account_states={
            account1_key_pair.public: AccountState(balance=1000, balance_lock=fake_lock1),
            account2_key_pair.public: AccountState(balance=2000, balance_lock=fake_lock2),
            account3_key_pair.public: AccountState(balance=3000, balance_lock=fake_lock3),
        },
        last_block_number=1234,
        last_block_identifier='23203d245b5e128465669223b5220b3061af1e2e72b0429ef26b07ce3a2282e7',
        last_block_timestamp=datetime.utcnow(),
        next_block_identifier='626dea61c1a6480d6a4c9cd657c7d7be52ddc38e5f2ec590b609ac01edde62fd',
    )

    blockchain = MemoryBlockchain(account_root_files=[base_account_root_file])
    assert blockchain.get_block_count() == 0
    assert blockchain.get_account_current_balance(account1_key_pair.public) == 1000
    assert blockchain.get_account_current_balance(account2_key_pair.public) == 2000
    assert blockchain.get_account_current_balance(account3_key_pair.public) == 3000
    assert blockchain.get_account_current_balance(new_account_key_pair.public) == 0
    blockchain.validate()

    signed_change_request1 = CoinTransferSignedChangeRequest.from_main_transaction(
        blockchain=blockchain,
        recipient=account2_key_pair.public,
        amount=10,
        signing_key=account1_key_pair.private,
        primary_validator=primary_validator,
        node=preferred_node
    )
    signed_change_request1.validate(blockchain, blockchain.get_next_block_number())
    blockchain.add_block_from_signed_change_request(signed_change_request1, get_node_signing_key())
    blockchain.validate()

    assert blockchain.get_block_count() == 1
    assert blockchain.get_account_current_balance(account1_key_pair.public) == 1000 - 10 - 4 - 1
    assert blockchain.get_account_current_balance(account2_key_pair.public) == 2000 + 10
    assert blockchain.get_account_current_balance(account3_key_pair.public) == 3000
    assert blockchain.get_account_current_balance(new_account_key_pair.public) == 0

    signed_change_request2 = CoinTransferSignedChangeRequest.from_main_transaction(
        blockchain=blockchain,
        recipient=new_account_key_pair.public,
        amount=20,
        signing_key=account2_key_pair.private,
        primary_validator=primary_validator,
        node=preferred_node
    )
    signed_change_request2.validate(blockchain, blockchain.get_next_block_number())
    blockchain.add_block_from_signed_change_request(signed_change_request2, get_node_signing_key())
    blockchain.validate()

    assert blockchain.get_block_count() == 2
    assert blockchain.get_account_current_balance(account1_key_pair.public) == 1000 - 10 - 4 - 1
    assert blockchain.get_account_current_balance(account2_key_pair.public) == 2000 + 10 - 20 - 4 - 1
    assert blockchain.get_account_current_balance(account3_key_pair.public) == 3000
    assert blockchain.get_account_current_balance(new_account_key_pair.public) == 20

    blockchain.snapshot_blockchain_state()
    blockchain.validate()

    assert blockchain.get_account_current_balance(account1_key_pair.public) == 1000 - 10 - 4 - 1
    assert blockchain.get_account_current_balance(account2_key_pair.public) == 2000 + 10 - 20 - 4 - 1
    assert blockchain.get_account_current_balance(account3_key_pair.public) == 3000
    assert blockchain.get_account_current_balance(new_account_key_pair.public) == 20

    signed_change_request3 = CoinTransferSignedChangeRequest.from_main_transaction(
        blockchain=blockchain,
        recipient=account2_key_pair.public,
        amount=30,
        signing_key=account3_key_pair.private,
        primary_validator=primary_validator,
        node=preferred_node
    )
    signed_change_request3.validate(blockchain, blockchain.get_next_block_number())
    blockchain.add_block_from_signed_change_request(signed_change_request3, get_node_signing_key())
    blockchain.validate()

    assert blockchain.get_account_current_balance(account1_key_pair.public) == 1000 - 10 - 4 - 1
    assert blockchain.get_account_current_balance(account2_key_pair.public) == 2000 + 10 - 20 - 4 - 1 + 30
    assert blockchain.get_account_current_balance(account3_key_pair.public) == 3000 - 30 - 4 - 1
    assert blockchain.get_account_current_balance(new_account_key_pair.public) == 20