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)
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')