kostaleonard / leocoin

Leo's cryptocurrency
MIT License
4 stars 1 forks source link

Add functions to verify blockchain #26

Closed kostaleonard closed 9 months ago

kostaleonard commented 9 months ago

As a miner, I want to be able to verify a blockchain I receive from my peers so that I know the block I'm mining will be valid and I will be able to make LeoCoin off it.

Function prototype:

/**
 * @brief Verifies that the blockchain is valid.
 * 
 * A blockchain is valid if it meets the following conditions.
 * 
 * 1. Every block has a valid proof of work. For every block other than the
 * genesis block, the block must hash to a value that contains the number of
 * leading zero bytes in the blockchain data structure. The genesis block must
 * have the magic number proof of work GENESIS_BLOCK_PROOF_OF_WORK and be the
 * first block.
 * 2. Every block must have a correct previous block hash. For the genesis
 * block, the previous block hash must be zero.
 * 3. Every transaction in every block must have a valid digital signature.
 * 
 * @param blockchain The blockchain.
 * @param is_valid_blockchain A pointer to fill with the result.
 * @param first_invalid_block If the blockchain is invalid and this argument is
 * not NULL, the function fills this pointer with the first invalid block.
 * @return return_code_t A return code indicating success or failure.
 */
return_code_t blockchain_verify(
    blockchain_t *blockchain,
    bool *is_valid_blockchain,
    block_t **first_invalid_block
);

Test function prototypes:

void test_blockchain_verify_succeeds_on_valid_blockchain() {
    // TODO need to serialize blockchain and save as fixture
}

void test_blockchain_verify_fails_on_invalid_genesis_block() {
    // TODO
}

void test_blockchain_verify_fails_on_invalid_proof_of_work() {
    // TODO
}

void test_blockchain_verify_fails_on_invalid_previous_block_hash() {
    // TODO
}

void test_blockchain_verify_fails_on_invalid_transaction_signature() {
    // TODO
}

void test_blockchain_verify_fails_on_invalid_input() {
    // TODO
}

Here's how we plan to place the feature in main.c.

return_code_t mine_blocks(
    blockchain_t *blockchain,
    ssh_key_t *miner_public_key,
    ssh_key_t *miner_private_key,
    char *outfile) {
    return_code_t return_code = SUCCESS;
    if (NULL == blockchain ||
        NULL == miner_public_key ||
        NULL == miner_private_key) {
        return_code = FAILURE_INVALID_INPUT;
        goto end;
    }
    while (true) {
        // TODO verify blockchain here just before mining a new block