def get_balance(request): player = request.user.player cooldown_error = check_cooldown_error(player) if cooldown_error is not None: return cooldown_error cooldown_seconds = get_cooldown(player, 0.0) player.cooldown = timezone.now() + timedelta(0, cooldown_seconds) player.save() body_unicode = request.body.decode('utf-8') # Check that the required fields are in the POST'ed data player_id = player.id balance = Blockchain.get_user_balance(player_id) response = { 'cooldown': cooldown_seconds, 'messages': [f'You have a balance of {balance} Lambda Coins'], 'errors': [] } return JsonResponse(response)
def last_proof(request): player = request.user.player cooldown_error = check_cooldown_error(player) if cooldown_error is not None: return cooldown_error cooldown_seconds = get_cooldown(player, 0.0) player.cooldown = timezone.now() + timedelta(0, cooldown_seconds) player.save() # Get the blockchain from the database # For now, assume there is only one and get that blockchain = Block.objects.all() last_proof_value = blockchain.last().proof response = { 'proof': last_proof_value, 'difficulty': ChainDifficulty.objects.all().last().difficulty, 'cooldown': cooldown_seconds, 'messages': [], 'errors': [] } return JsonResponse(response)
def mine(request): player = request.user.player cooldown_error = check_cooldown_error(player) if cooldown_error is not None: return cooldown_error cooldown_seconds = get_cooldown(player, 1.0) if not player.has_rename: cooldown_seconds += PENALTY_BLASPHEMY errors.append( f"One with no name is unworthy to mine: +{PENALTY_BLASPHEMY}s") player.cooldown = timezone.now() + timedelta(0, cooldown_seconds) player.save() return api_response(player, cooldown_seconds, errors=errors, messages=messages) # Get the blockchain from the database # For now, assume there is only one and get that blockchain = Block.objects.all() # Determine if proof is valid last_block = blockchain.last() last_proof = last_block.proof body_unicode = request.body.decode('utf-8') values = json.loads(body_unicode) submitted_proof = values.get('proof') player_id = player.id errors = [] messages = [] if Blockchain.valid_proof(last_proof, submitted_proof): # We must receive a reward for finding the proof. # The sender is "0" to signify that this node has mine a new coin Blockchain.new_transaction( sender="0", recipient=player_id, amount=REWARD_PER_BLOCK, ) # Forge the new Block by adding it to the chain previous_hash = Blockchain.hash(last_block) block = Blockchain.new_block(submitted_proof, previous_hash) messages.append("New Block Forged") player.cooldown = timezone.now() + timedelta(0, cooldown_seconds) player.has_mined = True player.save() response = { 'index': block.index, 'transactions': str(block.transactions), 'proof': block.proof, 'previous_hash': block.previous_hash, 'cooldown': cooldown_seconds, 'messages': messages, 'errors': errors } return JsonResponse(response) else: # Check if solution would have worked on a previous block. for block in blockchain[::-1]: if Blockchain.valid_proof(block.proof, submitted_proof): # Flag successful attempt that was too late player.has_mined = True cooldown_seconds += PENALTY_DUPLICATE_PROOF_VIOLATION player.cooldown = timezone.now() + timedelta( 0, cooldown_seconds) player.save() errors.append("Proof already submitted: ") return JsonResponse( { "cooldown": cooldown_seconds, 'errors': [ f"Proof already submitted: +{PENALTY_DUPLICATE_PROOF_VIOLATION}s CD" ] }, safe=True, status=400) cooldown_seconds += PENALTY_INVALID_PROOF_VIOLATION player.cooldown = timezone.now() + timedelta(0, cooldown_seconds) player.save() return JsonResponse( { "cooldown": cooldown_seconds, 'errors': [f"Invalid proof: +{PENALTY_INVALID_PROOF_VIOLATION}s CD"] }, safe=True, status=400)