def estimated_time_range(context: CandidateContext) -> None: """ allowable range from fastest time block is 1.2s. >>> [1.0, 1.5, 2.0, 2.7] fastest time: 1.0 consensus time range: 2.2s (1.0 + 1.2) result: 2.7s block is exclude this round >>> [1.0, 1.5, 2.0] """ candidate = context.get_data_list() if len(candidate) < 1: raise ValidationError("candidate context block: {}".format(len(candidate))) block_times = context.time if len(block_times) < 1: raise ValidationError("candidate context time: {}".format(len(block_times))) block_times.sort() estimated = estimated_time_point(block_times) # (time, time range) for blk in candidate: if blk.header.timestamp >= estimated[0]: if blk.header.timestamp <= estimated[1]: continue context.remove((blk.height, blk.creator))
async def execute(self, state: BaseState, context: BaseExecuteContext): state.state_db.increase_nonce(context.txbase) if context.is_create: nonce = state.state_db.get_nonce(context.create_address) if nonce != 0: ''' receipt error = "Already contract address: {}".format( self.execute_context.create_address) ''' raise ValidationError("Already contract address: {}".format( context.create_address)) else: # TODO: contract set code. build to account for contract precompile, error = context.is_precompile() if precompile and error is None: pass else: raise ValidationError("contract code build failed") context.use('create') # fee computation for "create" command. else: # TODO: wagon: call code, transfer value if context.code: context.use('call') # fee computation for "call" command. # computation class -> byte-code execution else: state.state_db.compute_balance(context.txbase, -1 * context.value) state.state_db.compute_balance(context.to, context.value) state.state_db.compute_balance(context.txbase, context.fee_remainder)
async def post(self): async with self.request.app['db'].acquire() as conn: data = await get_json_data(self.request) serializer = self.serializer_class(data=data) await serializer.create_validate() queryset = (User.c.username == serializer.validated_data['username']) &\ (User.c.password == serializer.validated_data['password']) query = self.build_query('select', queryset=queryset) users = await conn.execute(query) if users.rowcount == 0: raise ValidationError( dict(detail='Invalid username or password')) serializer = UserSerializer() user_data = await serializer.to_json(users) if user_data['blocked']: raise ValidationError(dict(detail='User is blocked')) query = Token.select().where(Token.c.user == user_data['id']) result = await conn.execute(query) if result.rowcount == 0: key = generate_token() query = Token.insert().values(key=key, user=user_data['id']) await conn.execute(query) else: token = await result.fetchone() key = token.key resp = dict(token=key) resp.update(user_data) return web.json_response(resp)
def _get_page(self): page = self.request.query.get('page', 1) try: page = int(page) except ValueError: raise ValidationError(dict(query_params='Page number is not int')) if page < 1: raise ValidationError(dict(query_params='Page less that 1 ')) return page
def validate_address(node_base) -> None: if not isinstance(node_base, bytes): raise ValidationError("address is not bytes, {}".format( type(node_base))) if not node_base.startswith((O_COIN_TYPE, CONTRACT_TYPE)): raise ValidationError("address not allowed {}".format(node_base)) if len(node_base) != ADDRESS_SIZE: raise ValidationError( "address specific length: {}, current length: {}, current address: {}" .format(ADDRESS_SIZE, len(node_base), node_base))
def validate_contract(node_base) -> None: if not isinstance(node_base, bytes): raise ValidationError("address is not bytes, {}".format( type(node_base))) if not node_base.startswith(b'gBc'): raise ValidationError("address not allowed {}".format(node_base)) if len(node_base) != ADDRESS_SIZE: raise ValidationError( "address specific length: {}, current length: {}, current address: {}" .format(ADDRESS_SIZE, len(node_base), node_base))
async def validate_vote(self, header: BaseHeader, vt_list): for vote in vt_list: await verify(vote.hash_vote, vote.byte_signature, vote.address_creator) if vote.hash_vote != vote.hash: raise ValidationError("saved vote hash: {} " "digest vote hash: {}".format( vote.hash_vote, vote.hash)) if header.num_height != vote.num_block_height: raise ValidationError("current header height: {} " "vote height: {}".format( header.num_height, vote.num_block_height))
async def validate_candidate(block: BaseBlock) -> None: if block.pre_hash != block.header.hash_candidate_block: raise ValidationError("candidate hash: {} " "current candidate hash: {}".format( block.pre_hash, block.header.hash_candidate_block)) await verify(block.pre_hash, block.header.byte_signature, block.header.address_creator) trie = make_hash_root(block.list_transactions) if block.header.hash_transaction_root != trie.root: raise ValidationError("block tx root: {}" "current block tx root: {}".format( trie.root, block.header.hash_transaction_root))
async def validate_finalize(block: BaseBlock) -> None: if block.hash != block.header.hash_block: raise ValidationError("finalize hash: {} " "current finalize hash: {}".format( block.hash, block.header.hash_block)) await verify(block.hash, block.header.byte_signature, block.header.address_creator)
async def execute_transactions(self, version, block: BaseBlock) -> BaseBlock: """ execute transactions :param int version: chain version. :param Block block: next height block. :return: Block class """ if block.height != self.header.num_height + 1: raise ValidationError( "wagon is execute on height={}, " "currently doesn't execute on height={}".format( self.header.num_height, block.height)) for index, transaction in enumerate(block.list_transactions): # self._tasks.add( # asyncio.ensure_future( # self.execute_transaction(version, index, block.header, transaction)) # ) await self.execute_transaction(version, index, block.header, transaction) # await self.event() self._receipts.sort(key=lambda obj: obj[0]) self._trie = make_hash_root([receipt for _, receipt in self._receipts]) self._pre_finalize(block) return block.copy(header=block.header.copy( hash_receipt_root=self._trie.root, hash_state_root=self.state.cache_trie_root))
async def is_valid(self, method, partial=False): errors = {} for field_name, field in self.fields.items(): if field.read_only: continue initial_value = self.initial_data.get(field_name, Empty) if method == 'update': if isinstance(field, PasswordField): continue if initial_value is Empty: if partial: continue else: if not field.required: continue value = await field.validate(initial_value) if field.validation_error is not None: errors[field_name] = field.validation_error else: self.validated_data[field_name] = value if errors: raise ValidationError(errors)
def _from_genesis(self, block): if block.height != 0: raise ValidationError("genesis block height {}" "current block height {}".format( 0, block.height)) if block.hash != Constant.block_hash: raise ValidationError("genesis hash {}" "current hash {}".format( Constant.block_hash, block.hash)) if block.header.hash_state_root != Constant.state_root: raise ValidationError("genesis state root: {} " "current state root: {}".format( Constant.state_root, block.header.hash_state_root)) self._db_context.chain.commit(block)
def validate_label_config_on_derived_input_schema( self, config_string_or_parsed_config): """ Validate label config on input schemas (tasks types and data keys) derived from imported tasks :param config_string_or_parsed_config: label config string or parsed config object :return: True if config match already imported tasks """ # check if schema exists, i.e. at least one task has been uploaded if not self.derived_input_schema: return config = config_string_or_parsed_config if isinstance(config, str): config = parse_config(config) input_types, input_values = set(), set() for input_items in map(itemgetter('inputs'), config.values()): for input_item in input_items: input_types.add(input_item['type']) input_values.add(input_item['value']) # check input data values: they must be in schema for item in input_values: if item not in self.derived_input_schema: raise ValidationError( 'You have already imported tasks and they are incompatible with a new config. ' 'You\'ve specified value=${item}, but imported tasks contain only keys: {input_schema_values}' .format(item=item, input_schema_values=list( self.derived_input_schema)))
async def make_finalize_from_confirm(self, confirm_block: BaseBlock, vt_list) -> BaseBlock: tx_trie = make_hash_root(confirm_block.list_transactions) permit_header = self.get_header_from_hash(confirm_block.previous) wagon = self.prepare_wagon(permit_header) if confirm_block.header.hash_transaction_root != tx_trie.root: raise ValidationError("tx root not matched") confirm_block.list_vote.extend(vt_list) vt_trie = make_hash_root(vt_list) confirm_block.header.hash_vote_root = vt_trie.root block = await wagon.execute_transactions(self.version, confirm_block) block.header.hash_vote_root = vt_trie.root block.header.timestamp_finalize = time.time() signature = self.make_signature(block.hash) wagon.clear() return block.copy(header=block.header.copy(hash_block=block.hash, byte_signature=signature), list_vote=vt_list)
async def post(self): async with self.request.app['db'].acquire() as conn: model = self.get_model() request_data = await get_json_data(self.request) serializer = UserCreateSerializer(data=request_data) await serializer.create_validate() registration = serializer.validated_data['registration'] if registration.is_completed: raise ValidationError( dict(detail='Registration is already completed')) data = { 'username': registration.username, 'password': registration.password, 'email': registration.email, 'first_name': registration.first_name, 'last_name': registration.last_name, 'role': serializer.validated_data['role'] } query = self.build_query('create', values=data) insert = await conn.execute(query) query = Registration.update().where( Registration.c.id == registration.id).values(is_completed=True) await conn.execute(query) queryset = model.c.id == insert.lastrowid query = self.build_query('select', queryset=queryset) result = await conn.execute(query) serializer = UserSerializer() data = await serializer.to_json(result) return web.json_response(data, status=201)
def validate_validator_set(validator_set, chain) -> None: for validator in validator_set: if not chain.has_validator(validator): raise ValidationError("validator set: {}, " "{} not in validator set." "".format(chain.get_validator_id_set(), validator))
async def validate_transaction(tx: BaseTransaction) -> None: # if not isinstance(tx.hash_transaction, bytes): # raise ValueError('tx hash is not bytes') if tx.hash_transaction != tx.hash: raise ValidationError("transaction hash: {} " "current transaction hash: {}".format( tx.hash, tx.hash_transaction)) await verify(tx.hash, tx.byte_signature, tx.address_sender)
def validate_has_transactions(transactions, chain): auth = [] for tx in transactions: if not chain.has_transaction(tx.hash): auth.append(tx.copy()) if len(auth) < 1: raise ValidationError("execute set is empty.") return auth
def set_message(self, message): try: if message != '' and isinstance(message, str): message = json.loads(message) self._message = dict(message) except Exception as e: raise ValidationError("message unexpected type, {}".format( type(message)))
def aggregate_vote_from_context(header: BaseHeader, context: VoteContext, logger): for v in context: if v.num_block_height != header.num_height: raise ValidationError( "event context height: {} " "current vote height: {}".format( context.height, v.num_block_height ) ) vt_data = [] for vt in context: vt_data.append((vt.num_block_height, vt.hash_candidate_block)) select_blocks = set(vt_data) diff_vote = select_blocks.difference( [(header.num_height, header.pre_hash)] ) if len(diff_vote) == 0: # 선택한 블록과 다른 투표 모두 동일한 투표일 때. return header.pre_hash # 선택한 블록과 다른 투표일 때 if len(diff_vote) >= 1: logger.debug("node-select: {}, " "diff-select: {}".format(header.pre_hash[:8], diff_vote)) aggregate = {} for h, agree_blk in diff_vote: aggregate[agree_blk] = 0 # { 'candidate-hash-key': 0, 'candidate-hash-key': 0 } for vt in context: if header.pre_hash != vt.hash_candidate_block: aggregate[vt.hash_candidate_block] += 1 # my select = 1 , 3 # other select = 3 , 1 for k, v in aggregate.items(): f = 3 # TODO: F computation # 1 <= f pass # 1 > f vote pow, penalty if v >= f: return k elif v <= f: return header.pre_hash else: raise RoundError( "aggregate vote error: " "{}".format(aggregate) )
def validate_payable(transaction, balance): amount_paid = transaction.amount_value + transaction.amount_fee balance_left = balance - amount_paid if balance_left < 0: raise ValidationError( 'payment refused, amount total paid: {}, account balance: {}'. format(amount_paid, balance)) else: return True
def extract(self): metadata = {} try: with zipfile.ZipFile(self.module_file, 'r') as zipped_module: try: build_file_content = zipped_module.read(BUILD_FILE_NAME) except KeyError: raise ValidationError('Provided file is not a valid module') metadata['_id'] = module_hash = str(uuid.uuid5( uuid.NAMESPACE_DNS, build_file_content.decode('utf-8'))) temporary_module_path = module_path = os.path.join( settings.MODULES_DIR, module_hash) while os.path.exists(temporary_module_path): temporary_module_path += '_' os.makedirs(temporary_module_path) for item in zipped_module.infolist(): output_filename = os.path.join( temporary_module_path, item.filename) output_dirname = os.path.dirname(output_filename) if not os.path.exists(output_dirname): os.makedirs(output_dirname) try: input_content = zipped_module.read(item.filename) with open(output_filename, 'wb') as output_file: output_file.write(input_content) except IsADirectoryError: pass if item.filename == MODULE_DATA_FILE_NAME: parser = ModuleDataFileParser(input_content) metadata.update(parser.parse()) if temporary_module_path != module_path: shutil.rmtree(module_path) shutil.move(temporary_module_path, module_path) except zipfile.BadZipFile: raise ValidationError('Provided file is not a valid module') return metadata
def validate_context(self, state, context, transaction): if context.limited != transaction.amount_fee: raise ValidationError("execute context limited: {}, " "current limited: {}".format( context.limited, transaction.amount_fee)) if context.value != transaction.amount_value: raise ValidationError("execute context value: {}" "current value: {}".format( context.value, transaction.amount_value)) if context.txbase != transaction.address_sender: raise ValidationError("execute context base: {}, " "current sender: {}".format( context.nodebase, transaction.address_sender)) nonce = state.state_db.get_nonce(context.txbase) if context.nonce != nonce: raise ValidationError("execute context nonce: {}" "current nonce: {}".format( context.nonce, nonce))
def validate_payable(transaction, abi): """Raise ValidationError if non-zero ether is sent to a non payable function. """ if 'value' in transaction: if transaction['value'] != 0: if "payable" in abi and not abi["payable"]: raise ValidationError( "Sending non-zero ether to a contract function " "with payable=False. Please ensure that " "transaction's value is 0.")
async def verify(msg_hash, sig, sender): signature = binascii.unhexlify(sig) msg_hash = binascii.unhexlify(msg_hash) public_key = await recover(msg_hash, signature) if isinstance(sender, str): sender = sender.encode() if sender != create_nodebase(public_key): raise ValidationError("object base on {} " "but signature signer is {}".format( sender, create_nodebase(public_key)))
def find_matching_fn_abi(abi, fn_identifier=None, args=None, kwargs=None): args = args or tuple() kwargs = kwargs or dict() num_arguments = len(args) + len(kwargs) if fn_identifier is FallbackFn: return get_fallback_func_abi(abi) if not is_text(fn_identifier): raise TypeError("Unsupported function identifier") name_filter = functools.partial(filter_by_name, fn_identifier) arg_count_filter = functools.partial(filter_by_argument_count, num_arguments) encoding_filter = functools.partial(filter_by_encodability, args, kwargs) function_candidates = pipe(abi, name_filter, arg_count_filter, encoding_filter) if len(function_candidates) == 1: return function_candidates[0] else: matching_identifiers = name_filter(abi) matching_function_signatures = [ abi_to_signature(func) for func in matching_identifiers ] arg_count_matches = len(arg_count_filter(matching_identifiers)) encoding_matches = len(encoding_filter(matching_identifiers)) if arg_count_matches == 0: diagnosis = "\nFunction invocation failed due to improper number of arguments." elif encoding_matches == 0: diagnosis = "\nFunction invocation failed due to no matching argument types." elif encoding_matches > 1: diagnosis = ( "\nAmbiguous argument encoding. " "Provided arguments can be encoded to multiple functions matching this call." ) message = ( "\nCould not identify the intended function with name `{name}`, " "positional argument(s) of type `{arg_types}` and " "keyword argument(s) of type `{kwarg_types}`." "\nFound {num_candidates} function(s) with the name `{name}`: {candidates}" "{diagnosis}").format( name=fn_identifier, arg_types=tuple(map(type, args)), kwarg_types=valmap(type, kwargs), num_candidates=len(matching_identifiers), candidates=matching_function_signatures, diagnosis=diagnosis, ) raise ValidationError(message)
async def finalize(self, block: BaseBlock) -> None: await self.validate_block(block) wagon = self.get_wagon() start_at = time.time() block = await wagon.execute_transactions(self.version, block) if block.header.hash_block != block.hash: raise ValidationError("final-block hash error " "block-hash: {}, current-hash: {}".format( block.header.hash_block, block.hash)) # fully executed transaction. self._link_block(block, wagon, start_at)
def validate_serializer(serializer): errors = [] try: serializer.is_valid(raise_exception=True) except exceptions.ValidationError as e: for key, list_error in e.detail.items(): for error in list_error: errors.append( f" {key}: {error.encode('utf-8').decode().lower()}") if errors: raise ValidationError(''.join(errors))
async def search_categories(request): async with request.app['db'].acquire() as conn: text = request.query.get('text') if text is None: raise ValidationError(dict(text='This query parameters is required')) query = Category.select().where(Category.c.name.like('%{}%'.format(text))) result = await conn.execute(query) serializer = CategorySerializer(many=True) data = await serializer.to_json(result) return web.json_response(data)
def validate_label_config_on_derived_output_schema( self, config_string_or_parsed_config): """ Validate label config on output schema (from_names, to_names and labeling types) derived from completions :param config_string_or_parsed_config: label config string or parsed config object :return: True if config match already created completions """ output_schema = self.derived_output_schema # check if schema exists, i.e. at least one completion has been created if not output_schema['from_name_to_name_type']: return config = config_string_or_parsed_config if isinstance(config, str): config = parse_config(config) completion_tuples = set() for from_name, to in config.items(): completion_tuples.add( (from_name, to['to_name'][0], to['type'].lower())) for from_name, to_name, type in output_schema[ 'from_name_to_name_type']: if (from_name, to_name, type) not in completion_tuples: raise ValidationError( 'You\'ve already completed some tasks, but some of them couldn\'t be loaded with this config: ' 'name={from_name}, toName={to_name}, type={type} are expected' .format(from_name=from_name, to_name=to_name, type=type)) for from_name, expected_label_set in output_schema['labels'].items(): if from_name not in config: raise ValidationError( 'You\'ve already completed some tasks, but some of them couldn\'t be loaded with this config: ' 'name=' + from_name + ' is expected') found_labels = set(config[from_name]['labels']) extra_labels = list(expected_label_set - found_labels) if extra_labels: raise ValidationError( 'You\'ve already completed some tasks, but some of them couldn\'t be loaded with this config: ' 'there are labels already created for "{from_name}":\n{extra_labels}' .format(from_name=from_name, extra_labels=extra_labels))