Ejemplo n.º 1
0
def mine_block():
    """ Mines a new block for the block chain.
    """
    if request.method == 'POST':
        data = request.form
        blockchain = Blockchain()
        blockchain.new_transaction(data['transaction_sender_id'],
                                   data['transaction_recipient_id'],
                                   data['amount'])
        last_proof = Block().get_last().proof

        proof = blockchain.proof_of_work(last_proof)
        prev_hash = Block().get_last().previous_hash

        blockchain.new_block(data['transaction_sender_id'],
                             data['transaction_recipient_id'], data['amount'],
                             proof, prev_hash)

        # register the transation
        UtilityItemUser().register(data['transaction_id'])
        # Add virtual value to the miner
        miner_id = flask_session.get('miner_id')
        UserWallet().successful_mine(miner_id)

    return "Block successfully mined."
def send_block(height_or_hash):
    """
    获得指定高度的区块数据并发送到 kafka
    :param height_or_hash:
    :return:
    """
    # 获取指定的区块,并加入缓存列表
    block1 = w3.eth.getBlock(height_or_hash, True)
    if block1.number in block_cache:
        logger_err.error(f'获得重复区块高度 {block1.number}')
        block_cache[block1.number] = block1
        return
    block_cache[block1.number] = block1

    # 从缓存列表里获得待处理的区块,如果为 None,则代表缓存的数据量不够,不进行任何处理
    block2 = block_cache.pop()
    if block2 is None:
        logger.info(
            f'获取到高度为 {block1.number} 的区块,加入缓存,当前缓存区块数 {len(block_cache)}')
        return
    else:
        logger.info(
            f'获取到高度为 {block1.number} 的区块,加入缓存,开始处理高度为 {block2.number} 的区块')

    Block(data=block2).save()
    for tx in block2.transactions:
        Transaction(data=tx).save()
Ejemplo n.º 3
0
    def new_block(self,
                  transaction_sender_id,
                  transaction_recipient_id,
                  amount,
                  proof,
                  prev_hash=None):
        """ Adds a new block to the blockchain.

        :param transaction_sender_id: Id of the user who initiated the transaction.
        :param type: int
        :param transaction_recipient_id: Id of the user who recieved the transaction.
        :param type: int
        :param amount: Amount of money used in transaction
        :param type: int
        :param prev_hash: Hash of the previous transaction
        :param type: String
        :param proof: Proof of work for the transaction.
        :param type: String
        """

        block = Block(timestamp=datetime.now(),
                      transaction_sender_id=transaction_sender_id,
                      transaction_recipient_id=transaction_recipient_id,
                      transaction_amount=amount,
                      proof=proof,
                      previous_hash=prev_hash)
        self.current_transactions = []
        block.create()
Ejemplo n.º 4
0
    def post(self):
        block_args = add_block_parser.parse_args()

        if 'id' not in block_args:
            highest = Block.query.order_by(Block.id).last()
            block_id = highest + 1
        else:
            block_id = block_args['id']

        block = Block(id=block_id,
                      number=block_args['number'],
                      line=block_args['line'],
                      grade=block_args['grade'],
                      elevation=block_args['elevation'],
                      cumulative_elevation=block_args['cumulative_elevation'],
                      occupancy=block_args['occupancy'])

        if 'switch_id' in block_args:
            block.switch_id = block_args['switch_id']

        if 'station_id' in block_args:
            block.station_id = block_args['station_id']

        if 'crossing_id' in block_args:
            block.crossing_id = block_args['crossing_id']

        db.session.add(block)
        db.session.commit()

        return block, 201
Ejemplo n.º 5
0
 def handle_new_pad(self):
     pad = Pad(name='Untitled Pad')
     block = Block(type='text', position=0, content='')
     pad.blocks.append(block)
     db.session.add(pad)
     db.session.add(block)
     db.session.commit()
     return redirect('pad/%i' % (pad.id))
Ejemplo n.º 6
0
 def _initiate_blocks():
     colors = [color.value for color in BlockColors]
     blocks = [
         Block(position=index, number=item[0], color=item[1])
         for index, item in enumerate(
             itertools.product([i for i in range(12)], colors))
     ]
     random.shuffle(blocks)
     return blocks
Ejemplo n.º 7
0
def main():
    global no_of_tabs, block_buffer, condition_stack, for_else, isOnElse, if_pos
    print("opening: {0}".format(sample))
    with open(sample) as file:
        lines = file.readlines()
        for eachline in lines:
            matched = re.match(identation_expression, eachline).groups()
            if matched[0] is not None:
                tabs = len(matched[0])
            else:
                tabs = 0
            if tabs > no_of_tabs:
                block_buffer = [eachline]
            elif tabs < no_of_tabs:
                try:
                    condition_stack.pop()
                except:
                    pass
                conditional_block = ConditionalBlock(condition_stack,
                                                     Block(block_buffer))
                graph.connect(conditional_block)

            else:
                block_buffer.append(eachline)

            eachline = eachline.strip()
            is_conditional_statement = re.match(conditional_expression,
                                                eachline.strip())
            is_else_conditional_statement = re.match(else_expression,
                                                     eachline.strip())
            if is_conditional_statement is not None:
                if eachline.startswith('elif'):
                    condition_stack.pop()
                condition_stack.append(
                    Condition(is_conditional_statement.groups()[1]))
                for_else.append(
                    Condition(is_conditional_statement.groups()[1]).negate())
                no_of_tabs -= 4

            elif is_else_conditional_statement is not None:
                condition_stack.extend(for_else[if_pos * -1:-1])
                no_of_tabs -= 4
                for_else = []
                try:
                    condition_stack.pop()
                except:
                    pass

            no_of_tabs = tabs
            print(
                "inside :", " AND ".join(
                    map(
                        lambda x: "'{0}'".format(x), condition_stack
                        if len(condition_stack) > 0 else ["global"])),
                " ------------->  ", eachline.strip())
Ejemplo n.º 8
0
def main():
    global no_of_tabs, block_buffer, condition_stack
    print("opening: {0}".format(sample))
    with open(sample) as file:
        lines = file.readlines()
        for eachline in lines:
            eachline = eachline.strip()
            matched = re.match(identation_expression, eachline).groups()
            if matched[0] is not None:
                tabs = len(matched[0])
            else:
                tabs = 0
            if tabs > no_of_tabs:
                block_buffer = [eachline]
            elif tabs < no_of_tabs:
                conditional_block = ConditionalBlock(condition_stack,
                                                     Block(block_buffer))
                graph.connect(conditional_block)
                condition_stack.pop()
                # if(isOnElse):
                #     condition_stack.pop()
            else:
                block_buffer.append(eachline)
            no_of_tabs = tabs
            print("inside :",
                  " AND ".join(
                      map(
                          lambda x: "'{0}'".format(x), condition_stack
                          if len(condition_stack) > 0 else ["global"])),
                  end=" ")
            print("   ------------->  ", eachline.strip())
            is_conditional_statement = re.match(conditional_expression,
                                                eachline.strip())
            is_else_conditional_statement = re.match(else_expression,
                                                     eachline.strip())
            if is_conditional_statement is not None:
                if eachline.startswith('elif'):
                    condition_stack.pop()
                condition_stack.append(
                    Condition(is_conditional_statement.groups()[0],
                              is_conditional_statement.groups()[1]))
                for_else.append(
                    Condition(is_conditional_statement.groups()[0],
                              is_conditional_statement.groups()[1]))
                no_of_tabs -= 1
                isOnElse = False

            elif is_else_conditional_statement is not None:
                condition_stack.append(condition_stack.pop().negate())
                no_of_tabs -= 1
                isOnElse = True
                condition_stack.pop()
            else:
                isOnElse = False
Ejemplo n.º 9
0
def block_create():
    list = get_files()
    if not list:
        create_genesice()
        block = Block(name='Evgeny', amount=5, to_whom='Next user')
        db.session.add(block)
        db.session.commit()
        return redirect(url_for('posts.blockchain'))
    if request.method=='POST':
        lender=request.form['Lender']
        amount=request.form['Amount']
        borrower=request.form['Borrower']
        if lender and amount and borrower:
            try:
                write_block(name=lender,amount=amount,to_whom=borrower)
                block = Block(name = lender,amount = amount,to_whom = borrower)
                db.session.add(block)
                db.session.commit()
            except:
                print('something is wrong')
        return redirect(url_for('posts.blockchain'))
    return render_template('posts/block_create.html')
Ejemplo n.º 10
0
def validate_and_add_block():
    """Endpoint to add a block mine by someone else to the node chain"""
    block_data = request.get_json()
    block = Block(block_data["index"], block_data["transactions"],
                  block_data["timestamp", block_data["previous_hash"]])

    proof = block_data['hash']
    added = blockchain.add_block(block, proof)

    if not added:
        return "The block was discarded by the node", 400

    return "Block added to the chain", 201
Ejemplo n.º 11
0
    def mine(self, miner, transactions, previous_block=None):
        print "Start mining block: ", transactions, previous_block
        id = str(uuid.uuid4())
        previous_block_id = previous_block.id if previous_block is not None else '-1'

        for length in [1, 10]:
            for proof_chars in product(printable, repeat=length):
                proof = ''.join(proof_chars)
                hash = hashlib.sha256(
                    Block.generate_payload(id, miner, proof, transactions,
                                           previous_block_id)).hexdigest()
                if hash[:DIFFICULTY] == '0' * DIFFICULTY:
                    block = Block(id, miner, proof, transactions,
                                  previous_block_id)
                    print "Block successfully mined: ", block
                    return block
Ejemplo n.º 12
0
    def __init__(self, size=None):
        self.screen = pygame.display.set_mode(size)
        self.tile_width = TILE_WIDTH
        self.tile_height = TILE_HEIGHT
        self.blocks = []
        self.whites = []
        self.browns = []
        self.shots = []
        self.already_shot = []

        for row in BLOCK_ROWS:
            for _ in range(0, MAX_BLOCKS):
                cell = random.choice(range(0, MAP_WIDTH))
                x = row * self.tile_width
                y = cell * self.tile_height
                b = Block(x, y, self.tile_width, self.tile_height,
                          len(self.blocks) + 1)
                self.blocks.append(b)

        for _ in range(0, MAX_WHITE):
            cell = random.choice(range(0, MAP_WIDTH))
            x = 0
            y = cell * self.tile_height
            w = WhiteManWithLaser(x, y, self.tile_width, self.tile_height,
                                  len(self.whites) + 1)
            w.set_blocks(self.blocks)
            w.set_shots(self.shots)
            w.check_boundaries()
            self.whites.append(w)

        for _ in range(0, MAX_BROWN):
            cell = random.choice(range(0, MAP_WIDTH))
            x = 9 * self.tile_width
            y = cell * self.tile_width
            b = BrownRebelScumbagWithLaser(x, y, self.tile_width,
                                           self.tile_height,
                                           len(self.browns) + 1)
            b.set_blocks(self.blocks)
            b.set_shots(self.shots)
            b.check_boundaries()
            self.browns.append(b)
Ejemplo n.º 13
0
def drivers(request):
    if request.method == 'GET':
        data = serializers.serialize("json", Driver.objects.all())

        return HttpResponse(data, content_type='application/json')

    if request.method == 'POST':
        req = json.loads(request.body)

        for item in req:

            name = item['driverName'].split(" ")
            firstName = name[0]
            lastName = name[1]

            id = item['driverId']
            startTime = item['driverStartTime']
            endTime = item['driverEndTime']
            time = item['driverBlockTime']

            try:
                Block.objects.get(startTime=startTime)
            except:
                block = Block(startTime=startTime, endTime=endTime, shiftLength=time)
                block.save()
            try:
                Driver.objects.get(DPID=id)
            except ObjectDoesNotExist:
                block = Block.objects.get(startTime=startTime)
                driver = Driver(DPID=id,
                                firstName = firstName,
                                lastName = lastName,
                                shiftLength = time,
                                startTime = startTime,
                                endTime = endTime,
                                block = block
                                )
                driver.save()

        return HttpResponse("Kevin is the greatest of all time --drivers")
Ejemplo n.º 14
0
def testdb_command():
    db.drop_all()
    db.create_all()

    block1 = Block(id=1,
                   number=1,
                   line="green",
                   length=100.0,
                   grade=0.5,
                   speedLimit=55,
                   elevation=0.5,
                   cumulative_elevation=0.5,
                   occupancy=False)
    db.session.add(block1)

    tcBlock1 = TrackControllerBlock(id=1,
                                    occupancy=False,
                                    maintenance=False,
                                    broken=False)
    db.session.add(tcBlock1)

    block2 = Block(id=2,
                   number=2,
                   line="green",
                   length=100.0,
                   grade=1.0,
                   speedLimit=55,
                   elevation=1.0,
                   cumulative_elevation=1.5,
                   occupancy=False)
    db.session.add(block2)

    tcBlock2 = TrackControllerBlock(id=2,
                                    occupancy=False,
                                    maintenance=False,
                                    broken=False)
    db.session.add(tcBlock2)

    block3 = Block(id=3,
                   number=3,
                   line="green",
                   length=100.0,
                   grade=1.5,
                   speedLimit=55,
                   elevation=1.5,
                   cumulative_elevation=3.0,
                   occupancy=False)
    db.session.add(block3)

    tcBlock3 = TrackControllerBlock(id=3,
                                    occupancy=False,
                                    maintenance=False,
                                    broken=False)
    db.session.add(tcBlock3)

    switch1 = Switch(id=1, state=False)
    db.session.add(switch1)
    block1.switch = switch1

    crossing1 = Crossing(id=1, state=False)
    db.session.add(crossing1)
    block3.crossing = crossing1

    station1 = Station(id=1, name="Station 1")
    db.session.add(station1)
    block2.station = station1

    light1 = Light(id=1, state=False)
    db.session.add(light1)
    light2 = Light(id=2, state=False)
    db.session.add(light1)

    switch1.lights.append(light1)
    switch1.lights.append(light2)

    # block1.message = "hello"

    train1 = Train(id=1,
                   name="train1",
                   length=1000.0,
                   width=100.0,
                   height=100.0,
                   mass=1000.0,
                   crewCount=0,
                   passengerCount=0)
    db.session.add(train1)
    train1.front_block = block1
    # block1.train_id = block1.front_train.id

    msg1 = Message(id=1, text="50,GO")
    db.session.add(msg1)
    msg1.block = block1
    msg1.train = train1

    msg2 = Message(id=2, text="100,GO")
    db.session.add(msg2)
    msg2.block = block2

    msg3 = Message(id=3, text="0,STOP")
    db.session.add(msg3)
    msg3.block = block3

    request = CTCRequest(id=0, type=0, input="")
    db.session.add(request)

    db.session.commit()

    # user1 = User(username='******', password='******')
    # db.session.add(user1)
    #
    # chatroom1 = ChatRoom(name='Super Awesome Chat Room')
    # db.session.add(chatroom1)
    #
    # user1.created_rooms.append(chatroom1)
    #
    # message1 = Message(creator=user1.username,text="Hello, there!", chatroom=chatroom1.name)
    # db.session.add(message1)
    # db.session.commit()

    print('Initialized the testing database.')
Ejemplo n.º 15
0
 def __init__(self):
     self.current_transactions = []
     self.chain = []
     if Block().get_last() is None:
         self.create_genesis_block()
Ejemplo n.º 16
0
with Renderer(root = "Reality", goal= "Attacker gets data from bucket") as graph:

    apiCache = Action(
        label="Search API Caches",
        chain="recon",
        cost=0,
        time=3,
        objective="Discover bucket paths",
        pSuccess=1.0
    )

    siteMapsDisabled = Block(
        label="Sitemaps disabled",
        cost=0,
        description="Ensure sitemaps are disabled",
        complexity=1,
        implemented=False,
        pSuccess=1.0
    )

    awsPublicBucketSearch = Action(
        label="AWS Public Bucket Search",
        chain="recon",
        cost=200,
        time=1,
        objective="Discover bucket paths",
        pSuccess=1.0
    )

    s3urls = Discovery(
        label="S3 Urls",
Ejemplo n.º 17
0
    def block_check(self):
        # set current scanned block
        last_block = Block.last_block(db_session)
        if last_block:
            current_scanned_block = last_block.num
        else:
            current_scanned_block = cfg.startblock
            # check if no accounts created so we can skip to the most recent block
            with self.account_lock:
                acct_count = Account.count(db_session)
                if acct_count == 0:
                    current_scanned_block = get_current_block_number() - 1

        # check for reorgs and invalidate any blocks (and associated txs)
        block_num = current_scanned_block
        block = Block.from_number(db_session, current_scanned_block)
        if block:
            any_reorgs = False
            block_hash = get_block_hash(block_num)
            if not block_hash:
                self.logger.error("unable to get hash for block %d" %
                                  block_num)
                return
            while block_hash != block.hash:
                self.logger.info(
                    "block %d hash does not match current blockchain, must have been reorged"
                    % block_num)
                block.set_reorged(db_session)
                any_reorgs = True
                # decrement block_num, set new current_scanned_block
                block_num -= 1
                current_scanned_block = block_num
                # now do the previous block
                block = Block.from_number(db_session, block_num)
                if not block:
                    break
                block_hash = get_block_hash(block_num)
            if any_reorgs:
                db_session.commit()

        # get address list from db
        with self.account_lock:
            addresses = Account.all_active_addresses(db_session)

        # scan for new blocks
        current_block = get_current_block_number()
        while current_scanned_block < current_block and self.keep_running:
            block_num = current_scanned_block + 1
            start = time.time()
            block_hash, txs, tx_count = get_block_hash_and_txs(
                block_num, addresses)
            # check for reorged blocks now reorged *back* into the main chain
            block = Block.from_hash(db_session, block_hash)
            if block:
                self.logger.info("block %s (was #%d) now un-reorged" %
                                 (block_hash.hex(), block.num))
                block.num = block_num
                block.reorged = False
            else:
                block = Block(block_num, block_hash)
                db_session.add(block)
                db_session.flush()
            for key in txs.keys():
                self.logger.info("adding txs for " + key)
                for tx in txs[key]:
                    self.logger.info(" - %s, %s" %
                                     (tx["hash"].hex(), tx["value"]))
                Account.add_txs(db_session, key, block.id, txs[key])
            db_session.commit()
            current_scanned_block = block_num
            self.logger.info(
                "#block# %d scan took %f seconds (%d addresses, %d txs)" %
                (block_num, time.time() - start, len(addresses), tx_count))

        # scan for pending transactions
        start = time.time()
        txs, tx_count = scan_pending_txs(addresses)
        for key in txs.keys():
            self.logger.info("adding txs for " + key)
            for tx in txs[key]:
                self.logger.info(" - %s, %s" % (tx["hash"].hex(), tx["value"]))
            Account.add_txs(db_session, key, None, txs[key])
        db_session.commit()
        self.logger.info(
            "!pending! tx scan took %f seconds (%d addresses, %d txs)" %
            (time.time() - start, len(addresses), tx_count))
Ejemplo n.º 18
0
        def blockloop():
            logger.info("ZapWeb blockloop started")

            # get last block from the db
            last_block = Block.last_block(db.session)
            if last_block:
                scanned_block_num = last_block.num
            else:
                scanned_block_num = cfg.start_block

            while 1:
                gevent.sleep(5)

                # check for reorgs and invalidate any blocks (and associated txs)
                block = Block.from_number(db.session, scanned_block_num)
                if block:
                    any_reorgs = False
                    blk_hash = block_hash(scanned_block_num)
                    if not blk_hash:
                        msg = f"unable to get hash (from node) for block {scanned_block_num}"
                        logger.error(msg)
                        utils.email_death(logger, msg)
                        sys.exit(1)
                    while blk_hash != block.hash:
                        logger.info("block %d hash does not match current blockchain, must have been reorged" % scanned_block_num)
                        block.set_reorged(db.session)
                        any_reorgs = True
                        # decrement scanned_block_num
                        scanned_block_num -= 1
                        # now do the previous block
                        block = Block.from_number(db.session, scanned_block_num)
                        if not block:
                            msg = f"unable to get hash (from db) for block {scanned_block_num}"
                            logger.error(msg)
                            utils.email_death(logger, msg)
                            sys.exit(1)
                        blk_hash = block_hash(scanned_block_num)
                    if any_reorgs:
                        db.session.commit()
            
                # scan for new blocks
                # use "block_height() - 1" because with the WavesNG protocol the block can have new transactions
                # added until the next block is found
                while block_height() - 1 > scanned_block_num:
                    block = block_at(scanned_block_num + 1)
                    res, reason = block_chk(block)
                    if not res:
                        logger.error(f"failed to get block at {scanned_block_num + 1} ({reason})")
                        break
                    blk_hash = block_hash(block)
                    # check for reorged blocks now reorged *back* into the main chain
                    dbblk = Block.from_hash(db.session, blk_hash)
                    if dbblk:
                        logger.info("block %s (was #%d) now un-reorged" % (blk_hash, dbblk.num))
                        dbblk.num = scanned_block_num + 1
                        dbblk.reorged = False
                    else:
                        dbblk = Block(block["timestamp"], block["height"], blk_hash)
                        db.session.add(dbblk)
                        db.session.flush()
                    # add transactions to db
                    if "transactions" in block:
                        for tx in block["transactions"]:
                            if tx["type"] == 4:
                                recipient = tx["recipient"]
                                asset_id = tx["assetId"]
                                if recipient == cfg.address and asset_id == cfg.asset_id:
                                    txid = tx["id"]
                                    logger.info(f"new tx {txid}")
                                    attachment = tx["attachment"]
                                    if attachment:
                                        attachment = base58.b58decode(attachment)
                                        logger.info(f"    {attachment}")
                                    invoice_id = utils.extract_invoice_id(logger, attachment)
                                    if invoice_id:
                                        logger.info(f"    {invoice_id}")
                                    dbtx = Transaction(txid, tx["sender"], recipient, tx["amount"], attachment, invoice_id, dbblk.id)
                                    db.session.add(dbtx)
                    scanned_block_num = block["height"]
                    logger.debug(f"scanned block {scanned_block_num}")
                    if scanned_block_num % 100 == 0:
                        db.session.commit()
                    gevent.sleep(0)
                db.session.commit()
Ejemplo n.º 19
0
        'interkey_time': INTERKEY_TIME
    }

    if day == 0:
        """ Initial instructions """
        if SHOW_QUIZ:
            finishedQuiz = False
            while not finishedQuiz:
                instructions.run()
                finishedQuiz = quiz.run(1)
        elif SHOW_INSTRUCTIONS:
            instructions.run()
        """ Trial Block """
        instructions.ready_practice()
        block = Block(experiment=experiment,
                      block_number=0,
                      subject=subject,
                      feedback=True)
        block.run()
        block.save()

        for i in range(1, 7):
            instructions.ready_n(i - 1)
            block = Block(experiment=experiment,
                          block_number=i,
                          subject=subject,
                          feedback=False)
            accuracyRecord.append(block.run())
            block.save()
    else:
        instructions.day2()
        for i in range(6):
def get_participant_for_file(path, metadata_by_pid):
    with open(path, "r") as data_file:
        reader = DictReader(data_file)
        blocks = []
        prolific_pid = None
        slowdown = None
        keyset = None
        compensation = None
        user_agent = None
        current_block_responses = []
        current_block_center = None
        compensation_descriptor = None
        version = None
        model_name = None
        for row in reader:
            prolific_pid = row.get("prolificPid")
            if prolific_pid in invalid_prolific_pids:
                raise ParticipantException(prolific_pid, "marked-invalid")
            if row.get("version") is None:
                raise ParticipantException(prolific_pid, "no-version")
            if row["trial_type"] == "keyset-select":
                keyset = row.get("chosenKeyset")
            if row["trial_type"] == "block-bookend" and len(
                    current_block_responses) == 20:
                next_block = Block(center_azimuth=current_block_center,
                                   responses=current_block_responses)
                blocks.append(next_block)
                current_block_responses = []
            if row["trial_type"] == "echo-presentation":
                compensation_str = row.get("compensation")
                if compensation_str == "NaN":
                    compensation = 0
                else:
                    compensation = int(compensation_str)
                choices = list(map(int, row.get("choices").split(",")))
                current_block_center = choices[2]
                slowdown = int(row.get("slowdown"))
                compensation_descriptor = row.get("compensationDescriptor")
                true_azimuth = row.get("azimuth")
                user_agent = row.get("userAgent")
                version = row.get("version")
                model_name = row.get("modelName")
                response_azimuth = row.get("responseAzimuth")
                response_delay = row.get("responseDelay")
                filename = row.get("filename")
                if true_azimuth and response_azimuth:
                    response = Response(
                        true_azimuth=int(true_azimuth),
                        response_azimuth=int(response_azimuth),
                        azimuth_choices=choices,
                        response_delay_ms=int(response_delay),
                        filename=filename,
                    )
                    current_block_responses.append(response)
        metadata = metadata_by_pid.get(prolific_pid)
        if (len(blocks) == 6 and slowdown and compensation is not None
                and compensation_descriptor and version and prolific_pid):
            return Participant(
                version=version,
                user_agent=user_agent,
                compensation=compensation,
                compensation_descriptor=compensation_descriptor,
                slowdown=slowdown,
                blocks=blocks,
                keyset=keyset,
                prolific_pid=prolific_pid,
                model_name=model_name,
                sex=metadata["sex"],
                age=(int(metadata["age"]) if metadata["age"] else None),
            )
    raise ParticipantException(prolific_pid, "missing-data")