Пример #1
0
def mine_block():
    logger.debug('Checking for sync locks...')
    if SyncLock.objects.count():
        logger.debug("Looks like we're syncing, canceling mine_block call.")
        return

    logger.debug('Mining new block...')
    broadcast = None
    with transaction.atomic():
        # Get the active block
        active_block = Block.get_active_block()
        logger.debug(f'{active_block.id} is the active block.')

        # Collect the unconfirmed transactions
        unconfirmed = UnconfirmedTransaction.objects.all()
        logger.debug(f'{len(unconfirmed)} unconfirmed transactions found.')

        # Prune invalid transactions
        transactions = prune_invalid_transactions(active_block, unconfirmed)
        logger.debug(f'{len(transactions)} transactions after pruning.')

        # Convert the unconfirmed transactions and add the block reward
        transactions = [u.to_transaction() for u in transactions]
        transactions.insert(0, Transaction.create_block_reward())

        # Set up the block
        block = Block(
            previous_block=active_block,
            depth=active_block.depth + 1,
            miner=settings.MINER_PUBLIC_KEY,
            extra_data=settings.BLOCK_EXTRA_DATA,
            time=now(),
        )
        block.set_merkle_root(transactions)
        block.set_balances(
            apply_transactions_to_balances(
                transactions,
                active_block.get_balances(),
            ))
        block.set_hash()
        block.sign()

        # Validate the block and transactions
        if validate_block(block, transactions):
            # Save the block
            block.save(transactions)
            UnconfirmedTransaction.objects.all().delete()
            broadcast = block
            logger.info(f'Block {block.id} successfully mined.')
        else:
            logger.info('Failed to mine block - validation error!')

    if broadcast:
        from boocoin.p2p import broadcast_block
        broadcast_block(broadcast)
Пример #2
0
    def handle(self, *args, **options):
        miners = options['miner_public_keys']

        # Verify the user doesn't already have a genesis block
        if Block.objects.count() > 0:
            sys.stderr.write("You already have a genesis block!\n")
            sys.exit(1)

        # This block will be signed by the miner, so its key must be included
        if settings.MINER_PUBLIC_KEY not in miners:
            sys.stderr.write("Your public key must be included.\n")
            sys.exit(1)

        # Set up the first transaction
        transaction = Transaction.create_block_reward()
        transactions = [transaction]

        # Set up the genesis block
        block = Block(
            depth=0,
            miner=settings.MINER_PUBLIC_KEY,
            extra_data=json.dumps(miners).encode('utf-8'),
            time=now(),
        )
        block.set_merkle_root(transactions)
        block.set_balances(apply_transaction_to_balances(transaction, {}))
        block.set_hash()
        block.sign()
        block.save(transactions)

        # Store the genesis block information in a file
        call_command('dumpdata',
                     'boocoin.Block',
                     'boocoin.Transaction',
                     indent=4,
                     output='genesis.json')
        self.stdout.write('Genesis block saved to db and genesis.json\n')