Home Reference Source Repository

src/lib/ccp-block.js

import { getDifficulty } from '../utils';
import {isValid} from './../schemas';
import {trymore} from 'crypto-io-utils';
import {read} from 'crypto-io-fs';
import events from './bus';
import {validateTransactions, createRewardTransaction} from './transaction';
import {calculateBlockHash} from './hash';
import {BlockError, TransactionError} from './errors.js';


/**
 * validate block
 *
 * @param {object} previousBlock
 * @param {object} block
 * @param {number} difficulty
 * @param {number} unspent
 */
export const validateBlock = (previousBlock, block, difficulty, unspent) => {
	if (!isValid('block', block)) throw BlockError('data');
	if (previousBlock.index + 1 !== block.index) throw BlockError('index');
	if (previousBlock.hash !== block.prevHash) throw BlockError('prevhash');
	if (calculateBlockHash(block) !== block.hash) throw BlockError('hash');
	if (blockDifficulty(block) > difficulty) throw BlockError('difficulty');
	return validateTransactions(block.transactions, unspent);
};

/**
 * Create genesis block
 *
 * @return {object} {index, prevHash, time, transactions, nonce}
 */
export const genesisBlock = () => {
	const block = {
		index: 0,
		prevHash: '0',
		time: Math.floor(new Date().getTime() / 1000),
		transactions: [],
		nonce: 0
	};
	block.hash = calculateBlockHash(block);
	return block;
};

/**
 * Get hash difficulty
 *
 * @param {*} hash
 * @return {number}
 */
export const difficulty = (hash) => {
	return parseInt(hash.substring(0, 8), 16);
};

/**
 * Get hash difficulty from block
 *
 * @param {*} hash
 * @return {number}
 */
export const blockDifficulty = ({hash}) => {
	return difficulty(hash);
};

/**
 * Create new block
 *
 * @param transactions {array}
 * @param lastBlock {object}
 * @param address {string}
 * @return {index, prevHash, time, transactions, nonce}
 */
export const block = (transactions, lastBlock, address) => {
	transactions = transactions.slice();
	transactions.push(createRewardTransaction(address, lastBlock.index + 1));
	const block = {
		index: lastBlock.index + 1,
		prevHash: lastBlock.hash,
		time: Math.floor(new Date().getTime() / 1000),
		transactions,
		nonce: 0,
	};
	block.hash = calculateBlockHash(block);

	return block;
};
export default block;