예제 #1
0
    async def get_puzzle_and_solution(self, request: Dict) -> Optional[Dict]:
        coin_name: bytes32 = hexstr_to_bytes(request["coin_id"])
        height = request["height"]
        coin_record = await self.service.coin_store.get_coin_record(coin_name)
        if coin_record is None or not coin_record.spent or coin_record.spent_block_index != height:
            raise ValueError(
                f"Invalid height {height}. coin record {coin_record}")

        header_hash = self.service.blockchain.height_to_hash(height)
        block: Optional[
            FullBlock] = await self.service.block_store.get_full_block(
                header_hash)

        if block is None or block.transactions_generator is None:
            raise ValueError("Invalid block or block generator")

        block_generator: Optional[
            BlockGenerator] = await self.service.blockchain.get_block_generator(
                block)
        assert block_generator is not None
        error, puzzle, solution = get_puzzle_and_solution_for_coin(
            block_generator, coin_name,
            self.service.constants.MAX_BLOCK_COST_CLVM)
        if error is not None:
            raise ValueError(f"Error: {error}")

        puzzle_ser: SerializedProgram = SerializedProgram.from_program(
            Program.to(puzzle))
        solution_ser: SerializedProgram = SerializedProgram.from_program(
            Program.to(solution))
        return {
            "coin_solution": CoinSpend(coin_record.coin, puzzle_ser,
                                       solution_ser)
        }
예제 #2
0
    async def test_strict_mode(self, rust_checker: bool):
        wallet_tool = bt.get_pool_wallet_tool()
        ph = wallet_tool.get_new_puzzlehash()

        num_blocks = 3
        blocks = bt.get_consecutive_blocks(num_blocks, [],
                                           guarantee_transaction_block=True,
                                           pool_reward_puzzle_hash=ph,
                                           farmer_reward_puzzle_hash=ph)

        coinbase = None
        for coin in blocks[2].get_included_reward_coins():
            if coin.puzzle_hash == ph:
                coinbase = coin
                break
        assert coinbase is not None
        spend_bundle = wallet_tool.generate_signed_transaction(
            coinbase.amount,
            BURN_PUZZLE_HASH,
            coinbase,
        )
        assert spend_bundle is not None

        pk = bytes.fromhex(
            "88bc9360319e7c54ab42e19e974288a2d7a817976f7633f4b43f36ce72074e59c4ab8ddac362202f3e366f0aebbb6280"
        )
        puzzle = p2_delegated_puzzle_or_hidden_puzzle.puzzle_for_pk(pk)
        disassembly = binutils.disassemble(puzzle)
        program = SerializedProgram.from_bytes(
            binutils.assemble(
                f"(q ((0x3d2331635a58c0d49912bc1427d7db51afe3f20a7b4bcaffa17ee250dcbcbfaa {disassembly} 300"
                f"  (() (q . ((65 '00000000000000000000000000000000' 0x0cbba106e000))) ()))))"
            ).as_bin())
        generator = BlockGenerator(program, [])
        npc_result: NPCResult = get_name_puzzle_conditions(
            generator,
            test_constants.MAX_BLOCK_COST_CLVM,
            cost_per_byte=test_constants.COST_PER_BYTE,
            safe_mode=True,
            rust_checker=rust_checker,
        )
        assert npc_result.error is not None
        npc_result = get_name_puzzle_conditions(
            generator,
            test_constants.MAX_BLOCK_COST_CLVM,
            cost_per_byte=test_constants.COST_PER_BYTE,
            safe_mode=False,
            rust_checker=rust_checker,
        )
        assert npc_result.error is None

        coin_name = npc_result.npc_list[0].coin_name
        error, puzzle, solution = get_puzzle_and_solution_for_coin(
            generator, coin_name, test_constants.MAX_BLOCK_COST_CLVM)
        assert error is None
예제 #3
0
 def test_get_removals_for_single_coin(self):
     sb: SpendBundle = make_spend_bundle(1)
     start, end = match_standard_transaction_at_any_index(
         original_generator)
     ca = CompressorArg(uint32(0),
                        SerializedProgram.from_bytes(original_generator),
                        start, end)
     c = compressed_spend_bundle_solution(ca, sb)
     removal = sb.coin_spends[0].coin.name()
     error, puzzle, solution = get_puzzle_and_solution_for_coin(
         c, removal, INFINITE_COST)
     assert error is None
     assert bytes(puzzle) == bytes(sb.coin_spends[0].puzzle_reveal)
     assert bytes(solution) == bytes(sb.coin_spends[0].solution)
     # Test non compressed generator as well
     s = simple_solution_generator(sb)
     error, puzzle, solution = get_puzzle_and_solution_for_coin(
         s, removal, INFINITE_COST)
     assert error is None
     assert bytes(puzzle) == bytes(sb.coin_spends[0].puzzle_reveal)
     assert bytes(solution) == bytes(sb.coin_spends[0].solution)
예제 #4
0
 async def get_puzzle_and_solution(self, coin_id: bytes32, height: uint32) -> Optional[CoinSpend]:
     generator = list(filter(lambda block: block.height == height, self.service.blocks))[0].transactions_generator
     coin_record = await self.service.mempool_manager.coin_store.get_coin_record(coin_id)
     error, puzzle, solution = get_puzzle_and_solution_for_coin(
         generator,
         coin_id,
         self.service.defaults.MAX_BLOCK_COST_CLVM,
     )
     if error:
         return None
     else:
         puzzle_ser: SerializedProgram = SerializedProgram.from_program(Program.to(puzzle))
         solution_ser: SerializedProgram = SerializedProgram.from_program(Program.to(solution))
         return CoinSpend(coin_record.coin, puzzle_ser, solution_ser)
    async def test_basics(self, rust_checker: bool):
        wallet_tool = bt.get_pool_wallet_tool()
        ph = wallet_tool.get_new_puzzlehash()
        num_blocks = 3
        blocks = bt.get_consecutive_blocks(num_blocks, [],
                                           guarantee_transaction_block=True,
                                           pool_reward_puzzle_hash=ph,
                                           farmer_reward_puzzle_hash=ph)
        coinbase = None
        for coin in blocks[2].get_included_reward_coins():
            if coin.puzzle_hash == ph and coin.amount == 250000000000:
                coinbase = coin
                break
        assert coinbase is not None
        spend_bundle = wallet_tool.generate_signed_transaction(
            coinbase.amount,
            BURN_PUZZLE_HASH,
            coinbase,
        )
        assert spend_bundle is not None
        program: BlockGenerator = simple_solution_generator(spend_bundle)

        npc_result: NPCResult = get_name_puzzle_conditions(
            program,
            test_constants.MAX_BLOCK_COST_CLVM,
            cost_per_byte=test_constants.COST_PER_BYTE,
            safe_mode=False,
            rust_checker=rust_checker,
        )

        cost = calculate_cost_of_program(program.program, npc_result,
                                         test_constants.COST_PER_BYTE)

        assert npc_result.error is None
        assert len(bytes(program.program)) == 433

        coin_name = npc_result.npc_list[0].coin_name
        error, puzzle, solution = get_puzzle_and_solution_for_coin(
            program, coin_name, test_constants.MAX_BLOCK_COST_CLVM)
        assert error is None

        assert npc_result.clvm_cost == 404560

        # Create condition + agg_sig_condition + length + cpu_cost
        assert (cost == ConditionCost.CREATE_COIN.value +
                ConditionCost.AGG_SIG.value +
                len(bytes(program.program)) * test_constants.COST_PER_BYTE +
                404560  # clvm_cost
                )
예제 #6
0
    async def get_puzzle_and_solution(self, request: Dict) -> Optional[Dict]:
        coin_name: bytes32 = bytes32.from_hexstr(request["coin_id"])
        height = request["height"]
        coin_record = await self.service.coin_store.get_coin_record(coin_name)
        if coin_record is None or not coin_record.spent or coin_record.spent_block_index != height:
            raise ValueError(
                f"Invalid height {height}. coin record {coin_record}")

        header_hash = self.service.blockchain.height_to_hash(height)
        # TODO: address hint error and remove ignore
        #       error: Argument 1 to "get_full_block" of "BlockStore" has incompatible type "Optional[bytes32]";
        #       expected "bytes32"  [arg-type]
        block: Optional[
            FullBlock] = await self.service.block_store.get_full_block(
                header_hash)  # type: ignore[arg-type]  # noqa: E501

        if block is None or block.transactions_generator is None:
            raise ValueError("Invalid block or block generator")

        block_generator: Optional[
            BlockGenerator] = await self.service.blockchain.get_block_generator(
                block)
        assert block_generator is not None
        error, puzzle, solution = get_puzzle_and_solution_for_coin(
            block_generator, coin_name,
            self.service.constants.MAX_BLOCK_COST_CLVM)
        if error is not None:
            raise ValueError(f"Error: {error}")

        puzzle_ser: SerializedProgram = SerializedProgram.from_program(
            Program.to(puzzle))
        solution_ser: SerializedProgram = SerializedProgram.from_program(
            Program.to(solution))
        return {
            "coin_solution": CoinSpend(coin_record.coin, puzzle_ser,
                                       solution_ser)
        }
예제 #7
0
    async def test_basics(self):
        wallet_tool = bt.get_pool_wallet_tool()
        ph = wallet_tool.get_new_puzzlehash()
        num_blocks = 3
        blocks = bt.get_consecutive_blocks(num_blocks, [],
                                           guarantee_transaction_block=True,
                                           pool_reward_puzzle_hash=ph,
                                           farmer_reward_puzzle_hash=ph)
        coinbase = None
        for coin in blocks[2].get_included_reward_coins():
            if coin.puzzle_hash == ph:
                coinbase = coin
                break
        assert coinbase is not None
        spend_bundle = wallet_tool.generate_signed_transaction(
            coinbase.amount,
            BURN_PUZZLE_HASH,
            coinbase,
        )
        assert spend_bundle is not None
        program = best_solution_program(spend_bundle)

        result: CostResult = calculate_cost_of_program(
            program, test_constants.COST_PER_BYTE)
        clvm_cost = result.cost

        error, npc_list, cost = get_name_puzzle_conditions(program, False)
        assert error is None
        coin_name = npc_list[0].coin_name
        error, puzzle, solution = get_puzzle_and_solution_for_coin(
            program, coin_name)
        assert error is None

        # Create condition + agg_sig_condition + length + cpu_cost
        assert (clvm_cost == ConditionCost.CREATE_COIN.value +
                ConditionCost.AGG_SIG.value +
                len(bytes(program)) * test_constants.COST_PER_BYTE + cost)