def get_name_puzzle_conditions_rust(generator: BlockGenerator, max_cost: int, *, cost_per_byte: int, safe_mode: bool) -> NPCResult: block_program, block_program_args = setup_generator_args(generator) max_cost -= len(bytes(generator.program)) * cost_per_byte if max_cost < 0: return NPCResult(uint16(Err.INVALID_BLOCK_COST.value), [], uint64(0)) flags = STRICT_MODE if safe_mode else 0 err, result, clvm_cost = GENERATOR_MOD.run_as_generator( max_cost, flags, block_program, block_program_args) if err is not None: return NPCResult(uint16(err), [], uint64(0)) else: npc_list = [] for r in result: conditions = [] for c in r.conditions: cwa = [] for cond_list in c[1]: cwa.append( ConditionWithArgs( ConditionOpcode(bytes([cond_list.opcode])), cond_list.vars)) conditions.append((ConditionOpcode(bytes([c[0]])), cwa)) npc_list.append(NPC(r.coin_name, r.puzzle_hash, conditions)) return NPCResult(None, npc_list, uint64(clvm_cost))
def get_name_puzzle_conditions( generator: BlockGenerator, max_cost: int, *, cost_per_byte: int, mempool_mode: bool ) -> NPCResult: block_program, block_program_args = setup_generator_args(generator) max_cost -= len(bytes(generator.program)) * cost_per_byte if max_cost < 0: return NPCResult(uint16(Err.INVALID_BLOCK_COST.value), [], uint64(0)) flags = MEMPOOL_MODE if mempool_mode else 0 try: err, result, clvm_cost = GENERATOR_MOD.run_as_generator(max_cost, flags, block_program, block_program_args) if err is not None: return NPCResult(uint16(err), [], uint64(0)) else: npc_list = [] for r in result: conditions = [] for c in r.conditions: cwa = [] for cond_list in c[1]: cwa.append(ConditionWithArgs(ConditionOpcode(bytes([cond_list.opcode])), cond_list.vars)) conditions.append((ConditionOpcode(bytes([c[0]])), cwa)) npc_list.append(NPC(r.coin_name, r.puzzle_hash, conditions)) return NPCResult(None, npc_list, uint64(clvm_cost)) except BaseException as e: log.debug(f"get_name_puzzle_condition failed: {e}") return NPCResult(uint16(Err.GENERATOR_RUNTIME_ERROR.value), [], uint64(0))
def get_name_puzzle_conditions(generator: BlockGenerator, max_cost: int, safe_mode: bool) -> NPCResult: try: block_program, block_program_args = setup_generator_args(generator) if safe_mode: cost, result = GENERATOR_MOD.run_safe_with_cost( max_cost, block_program, block_program_args) else: cost, result = GENERATOR_MOD.run_with_cost(max_cost, block_program, block_program_args) npc_list: List[NPC] = [] opcodes: Set[bytes] = set(item.value for item in ConditionOpcode) for res in result.as_iter(): conditions_list: List[ConditionWithArgs] = [] spent_coin_parent_id: bytes32 = res.first().first().as_atom() spent_coin_puzzle_hash: bytes32 = res.first().rest().first( ).as_atom() spent_coin_amount: uint64 = uint64( res.first().rest().rest().first().as_int()) spent_coin: Coin = Coin(spent_coin_parent_id, spent_coin_puzzle_hash, spent_coin_amount) for cond in res.rest().first().as_iter(): if cond.first().as_atom() in opcodes: opcode: ConditionOpcode = ConditionOpcode( cond.first().as_atom()) elif not safe_mode: opcode = ConditionOpcode.UNKNOWN else: return NPCResult(uint16(Err.GENERATOR_RUNTIME_ERROR.value), [], uint64(0)) cvl = ConditionWithArgs(opcode, cond.rest().as_atom_list()) conditions_list.append(cvl) conditions_dict = conditions_by_opcode(conditions_list) if conditions_dict is None: conditions_dict = {} npc_list.append( NPC(spent_coin.name(), spent_coin.puzzle_hash, [(a, b) for a, b in conditions_dict.items()])) return NPCResult(None, npc_list, uint64(cost)) except Exception: return NPCResult(uint16(Err.GENERATOR_RUNTIME_ERROR.value), [], uint64(0))
def get_name_puzzle_conditions_python(generator: BlockGenerator, max_cost: int, *, cost_per_byte: int, safe_mode: bool) -> NPCResult: """ This executes the generator program and returns the coins and their conditions. If the cost of the program (size, CLVM execution and conditions) exceed max_cost, the function fails. In order to accurately take the size of the program into account when calculating cost, cost_per_byte must be specified. safe_mode determines whether the clvm program and conditions are executed in strict mode or not. When in safe/strict mode, unknow operations or conditions are considered failures. This is the mode when accepting transactions into the mempool. """ block_program, block_program_args = setup_generator_args(generator) max_cost -= len(bytes(generator.program)) * cost_per_byte if max_cost < 0: return NPCResult(uint16(Err.INVALID_BLOCK_COST.value), [], uint64(0)) if safe_mode: clvm_cost, result = GENERATOR_MOD.run_safe_with_cost( max_cost, block_program, block_program_args) else: clvm_cost, result = GENERATOR_MOD.run_with_cost( max_cost, block_program, block_program_args) max_cost -= clvm_cost if max_cost < 0: return NPCResult(uint16(Err.INVALID_BLOCK_COST.value), [], uint64(0)) npc_list: List[NPC] = [] for res in result.first().as_iter(): conditions_list: List[ConditionWithArgs] = [] if len(res.first().atom) != 32: raise ValidationError(Err.INVALID_CONDITION) spent_coin_parent_id: bytes32 = res.first().as_atom() res = res.rest() if len(res.first().atom) != 32: raise ValidationError(Err.INVALID_CONDITION) spent_coin_puzzle_hash: bytes32 = res.first().as_atom() res = res.rest() spent_coin_amount: uint64 = uint64(sanitize_int( res.first(), safe_mode)) res = res.rest() spent_coin: Coin = Coin(spent_coin_parent_id, spent_coin_puzzle_hash, spent_coin_amount) for cond in res.first().as_iter(): cost, cvl = parse_condition(cond, safe_mode) max_cost -= cost if max_cost < 0: return NPCResult(uint16(Err.INVALID_BLOCK_COST.value), [], uint64(0)) if cvl is not None: conditions_list.append(cvl) conditions_dict = conditions_by_opcode(conditions_list) if conditions_dict is None: conditions_dict = {} npc_list.append( NPC(spent_coin.name(), spent_coin.puzzle_hash, [(a, b) for a, b in conditions_dict.items()])) return NPCResult(None, npc_list, uint64(clvm_cost))
def get_name_puzzle_conditions(generator: BlockGenerator, max_cost: int, *, cost_per_byte: int, mempool_mode: bool, height: Optional[uint32] = None) -> NPCResult: block_program, block_program_args = setup_generator_args(generator) size_cost = len(bytes(generator.program)) * cost_per_byte max_cost -= size_cost if max_cost < 0: return NPCResult(uint16(Err.INVALID_BLOCK_COST.value), [], uint64(0)) # in mempool mode, the height doesn't matter, because it's always strict. # But otherwise, height must be specified to know which rules to apply assert mempool_mode or height is not None # mempool mode also has these rules apply assert (MEMPOOL_MODE & COND_CANON_INTS) != 0 assert (MEMPOOL_MODE & NO_NEG_DIV) != 0 if mempool_mode: flags = MEMPOOL_MODE elif unwrap(height) >= DEFAULT_CONSTANTS.SOFT_FORK_HEIGHT: # conditions must use integers in canonical encoding (i.e. no redundant # leading zeros) # the division operator may not be used with negative operands flags = COND_CANON_INTS | NO_NEG_DIV else: flags = 0 try: err, result = GENERATOR_MOD.run_as_generator(max_cost, flags, block_program, block_program_args) if err is not None: assert err != 0 return NPCResult(uint16(err), [], uint64(0)) first = True npc_list = [] for r in result.spends: conditions: Dict[ConditionOpcode, List[ConditionWithArgs]] = {} if r.height_relative is not None: add_int_cond(conditions, ConditionOpcode.ASSERT_HEIGHT_RELATIVE, r.height_relative) if r.seconds_relative > 0: add_int_cond(conditions, ConditionOpcode.ASSERT_SECONDS_RELATIVE, r.seconds_relative) for cc in r.create_coin: if cc[2] == b"": add_cond(conditions, ConditionOpcode.CREATE_COIN, [cc[0], int_to_bytes(cc[1])]) else: add_cond(conditions, ConditionOpcode.CREATE_COIN, [cc[0], int_to_bytes(cc[1]), cc[2]]) for sig in r.agg_sig_me: add_cond(conditions, ConditionOpcode.AGG_SIG_ME, [sig[0], sig[1]]) # all conditions that aren't tied to a specific spent coin, we roll into the first one if first: first = False if result.reserve_fee > 0: add_int_cond(conditions, ConditionOpcode.RESERVE_FEE, result.reserve_fee) if result.height_absolute > 0: add_int_cond(conditions, ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, result.height_absolute) if result.seconds_absolute > 0: add_int_cond(conditions, ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, result.seconds_absolute) for sig in result.agg_sig_unsafe: add_cond(conditions, ConditionOpcode.AGG_SIG_UNSAFE, [sig[0], sig[1]]) npc_list.append( NPC(r.coin_id, r.puzzle_hash, [(op, cond) for op, cond in conditions.items()])) return NPCResult(None, npc_list, uint64(result.cost + size_cost)) except BaseException as e: log.debug(f"get_name_puzzle_condition failed: {e}") return NPCResult(uint16(Err.GENERATOR_RUNTIME_ERROR.value), [], uint64(0))