def fix_next_block(block, chain): logger.info('fixing next block for {}'.format(block)) # it's likely that this block is an orphan so we should remove it and rescan this_height = block.height this_hash = get_block_hash(this_height, schema_name=chain) if not this_hash: logger.warning( 'could not get hash for block at height {}'.format(this_height)) return if this_hash != block.hash: block = Block.objects.create(hash=this_hash, height=this_height) next_hash = get_block_hash(this_height + 1, schema_name=chain) if not next_hash: logger.warning( 'could not get next hash for height {}'.format(this_height + 1)) return try: next_block = Block.objects.get(hash=next_hash) except Block.DoesNotExist: next_block = Block(hash=next_hash) block.next_block = next_block block.save() next_block.height = this_height + 1 next_block.previous_block = block next_block.save(validate=False)
def fix_previous_block(block, chain): logger.info('fixing previous block for {}'.format(block)) prev_hash = get_block_hash(block.height - 1, schema_name=chain) if not prev_hash: return try: prev_block = Block.objects.get(hash=prev_hash) except Block.DoesNotExist: prev_block = Block(hash=prev_hash) try: prev_height_block = Block.objects.get(height=block.height - 1) except Block.DoesNotExist: prev_height_block = prev_block if prev_block != prev_height_block: # the block with the previous height doesn't match the hash from this block # likely to be an orphan so remove it prev_height_block.delete() block.previous_block = prev_block block.save() prev_block.height = block.height - 1 prev_block.next_block = block prev_block.save()
def handle(self, *args, **options): """ Parse the block chain """ chain = connection.tenant rpc = send_rpc( { 'method': 'getinfo', 'params': [] }, schema_name=chain.schema_name ) if not rpc: logger.error('no RPC connection') return max_height = rpc['blocks'] for height in range(max_height): try: block = Block.objects.get(height=height) logger.info('existing block {}'.format(block)) continue except Block.DoesNotExist: block_hash = get_block_hash(height=height, schema_name=chain.schema_name) if not block_hash: continue block = Block(hash=block_hash) try: block.save(validate=False) except IntegrityError: pre_block = Block.objects.get(hash=block_hash) if pre_block.height: logger.error( 'block with hash {} already exists: {}'.format( block_hash[:8], pre_block ) ) continue pre_block.height = height pre_block.save(validate=False) logger.info('updated block {}'.format(pre_block)) continue logger.info('created block {}'.format(block)) for block in Block.objects.all().order_by('height'): block.save() logger.info('saved block {}'.format(block))
def create_blocks(inCode): ''' Generates a block with the specified code ''' block = Block(voteCount=0, winCount=0, code=inCode, winRate=0) block.save()
def get(self, request, *args, **kwargs): block_hash = kwargs['hash'] block_info = w3_client.eth.getBlock(block_hash) block_data = web3_to_dict(block_info) miner = self.get_address(block_data['miner']) existing_block = Block.objects.filter(hash=block_data['hash']) if existing_block.exists(): block = existing_block.first() block.difficulty = block_data['difficulty'] block.gas_limit = block_data['gasLimit'] block.gas_used = block_data['gasUsed'] block.hash = block_data['hash'] block.miner = miner block.nonce = block_data['nonce'] block.number = block_data['number'] block.parent_hash = Block.objects.filter( hash=block_data['parentHash']).first() block.size = block_data['size'] block.timestamp = block_data['timestamp'] block.total_difficulty = block_data['totalDifficulty'] block.save() else: # Create Block Instance block = Block() block.difficulty = block_data['difficulty'] block.gas_limit = block_data['gasLimit'] block.gas_used = block_data['gasUsed'] block.hash = block_data['hash'] block.miner = miner block.nonce = block_data['nonce'] block.number = block_data['number'] block.parent_hash = Block.objects.filter( hash=block_data['parentHash']).first() block.size = block_data['size'] block.timestamp = block_data['timestamp'] block.total_difficulty = block_data['totalDifficulty'] block.save() # Create transactions for block for transaction in block_data['transactions']: transaction_info = w3_client.eth.getTransaction(transaction) transaction_data = web3_to_dict(transaction_info) existing_transaction = Transaction.objects.filter( hash=transaction_data['hash']) if existing_transaction.exists(): transaction = existing_transaction.first() transaction.block_hash = block transaction.block_number = block.number # transaction.cumulative_gas_used = '' transaction.created_contract_address_hash = None transaction.error = '' transaction.from_address_hash = self.get_address( transaction_data['from']) transaction.gas = transaction_data['gas'] transaction.gas_price = transaction_data['gasPrice'] transaction.gas_used = (transaction_data['gas'] * transaction_data['gasPrice']) transaction.hash = transaction_data['hash'] transaction.index = transaction_data['transactionIndex'] transaction.input = transaction_data['input'] transaction.internal_transactions_indexed_at = None transaction.nonce = transaction_data['nonce'] transaction.r = transaction_data['r'] transaction.s = transaction_data['s'] # transaction.status = '' transaction.to_address_hash = self.get_address( transaction_data['to']) transaction.v = transaction_data['v'] transaction.value = transaction_data['value'] transaction.save() else: transaction = Transaction() transaction.block_hash = block transaction.block_number = block.number # transaction.cumulative_gas_used = '' transaction.created_contract_address_hash = None transaction.error = '' transaction.from_address_hash = self.get_address( transaction_data['from']) transaction.gas = transaction_data['gas'] transaction.gas_price = transaction_data['gasPrice'] transaction.gas_used = (transaction_data['gas'] * transaction_data['gasPrice']) transaction.hash = transaction_data['hash'] transaction.index = transaction_data['transactionIndex'] transaction.input = transaction_data['input'] transaction.internal_transactions_indexed_at = None transaction.nonce = transaction_data['nonce'] transaction.r = transaction_data['r'] transaction.s = transaction_data['s'] # transaction.status = '' transaction.to_address_hash = self.get_address( transaction_data['to']) transaction.v = transaction_data['v'] transaction.value = transaction_data['value'] transaction.save() # Create uncle block if exists for uncle in block_data['uncles']: uncle_info = w3_client.eth.getBlock(uncle) uncle_data = web3_to_dict(uncle_info) miner = self.get_address(uncle_data['miner']) existing_uncle_block = Block.objects.filter( hash=uncle_data['hash']) if existing_uncle_block.exists(): uncle_block = existing_uncle_block.first() uncle_block.consensus = False uncle_block.difficulty = uncle_data['difficulty'] uncle_block.gas_limit = uncle_data['gasLimit'] uncle_block.gas_used = uncle_data['gasUsed'] uncle_block.hash = uncle_data['hash'] uncle_block.miner = miner uncle_block.nonce = uncle_data['nonce'] uncle_block.number = uncle_data['number'] uncle_block.parent_hash = Block.objects.filter( hash=uncle_data['parentHash']).first() uncle_block.size = uncle_data['size'] uncle_block.timestamp = uncle_data['timestamp'] uncle_block.total_difficulty = uncle_data['totalDifficulty'] uncle_block.save() else: uncle_block = Block() uncle_block.consensus = False uncle_block.difficulty = uncle_data['difficulty'] uncle_block.gas_limit = uncle_data['gasLimit'] uncle_block.gas_used = uncle_data['gasUsed'] uncle_block.hash = uncle_data['hash'] uncle_block.miner = miner uncle_block.nonce = uncle_data['nonce'] uncle_block.number = uncle_data['number'] uncle_block.parent_hash = Block.objects.filter( hash=uncle_data['parentHash']).first() uncle_block.size = uncle_data['size'] uncle_block.timestamp = uncle_data['timestamp'] uncle_block.total_difficulty = uncle_data['totalDifficulty'] uncle_block.save() # Save relation between nephew and uncle SecondDegreeRelation.objects.get_or_create( nephew_hash=block, uncle_hash=uncle_block, defaults={'uncle_fetched_at': block.timestamp}) # Save transaction relation for uncle block transaction_index = 0 for transaction in uncle_data['transactions']: transaction = Transaction.objects.filter(hash=transaction) if not transaction.exists(): continue Fork.objects.create(hash=transaction.first(), index=transaction_index, uncle_hash=uncle_block) transaction_index += 1 return JsonResponse(status=200, data=block_data, safe=False)