Пример #1
0
def test_1():
    puzzle_program_1 = puzzle_program_for_index(uint32(1))
    puzzle_program_2 = puzzle_program_for_index(uint32(2))

    conditions = Program.to([
        make_create_coin_condition(std_hash(bytes(pp)), amount)
        for pp, amount in [(puzzle_program_1, 1000), (puzzle_program_2, 2000)]
    ])

    assert conditions is not None
    puzzle_reveal = p2_delegated_puzzle.puzzle_reveal_for_conditions(
        conditions)
    solution = p2_delegated_puzzle.solution_for_conditions(conditions)

    error, output_conditions, cost = conditions_for_solution(
        puzzle_reveal, solution)
    assert error is None
    from pprint import pprint

    assert output_conditions is not None
    output_conditions_dict = conditions_by_opcode(output_conditions)
    pprint(output_conditions_dict)
    input_coin_info_hash = bytes([0] * 32)
    created_outputs_for_conditions_dict(output_conditions_dict,
                                        input_coin_info_hash)
    aggsigs = aggsig_in_conditions_dict(output_conditions_dict)
    pprint(aggsigs)
Пример #2
0
    def sign_transaction(self, spends: List[Tuple[Program, CoinSolution]]):
        sigs = []
        solution: Program
        puzzle: Program
        for puzzle, solution in spends:  # type: ignore # noqa
            pubkey, secretkey = self.get_keys(solution.coin.puzzle_hash)
            code_ = [puzzle, solution.solution]
            sexp = Program.to(code_)
            err, con, cost = conditions_for_solution(sexp)
            if not con:
                return
            conditions_dict = conditions_by_opcode(con)

            for _, msg in pkm_pairs_for_conditions_dict(
                    conditions_dict, bytes(solution.coin)):
                signature = AugSchemeMPL.sign(secretkey, msg)
                sigs.append(signature)
        aggsig = AugSchemeMPL.aggregate(sigs)
        solution_list: List[CoinSolution] = [
            CoinSolution(coin_solution.coin,
                         Program.to([puzzle, coin_solution.solution]))
            for (puzzle, coin_solution) in spends
        ]
        spend_bundle = SpendBundle(solution_list, aggsig)
        return spend_bundle
Пример #3
0
    def sign_transaction(self, spends: List[Tuple[Program, CoinSolution]]):
        sigs = []
        solution: Program
        puzzle: Program
        for puzzle, solution in spends:  # type: ignore # noqa
            pubkey, secretkey = self.get_keys(solution.coin.puzzle_hash)
            secretkey = BLSPrivateKey(secretkey)
            code_ = [puzzle, solution.solution]
            sexp = Program.to(code_)
            err, con, cost = conditions_for_solution(sexp)
            if not con:
                return
            conditions_dict = conditions_by_opcode(con)

            for _ in hash_key_pairs_for_conditions_dict(
                    conditions_dict, bytes(solution.coin)):
                signature = secretkey.sign(_.message_hash)
                sigs.append(signature)
        aggsig = BLSSignature.aggregate(sigs)
        solution_list: List[CoinSolution] = [
            CoinSolution(coin_solution.coin,
                         clvm.to_sexp_f([puzzle, coin_solution.solution]))
            for (puzzle, coin_solution) in spends
        ]
        spend_bundle = SpendBundle(solution_list, aggsig)
        return spend_bundle
Пример #4
0
 def signature_for_solution(self, coin_solution: CoinSolution) -> AugSchemeMPL:
     signatures = []
     err, conditions, cost = conditions_for_solution(coin_solution.puzzle_reveal, coin_solution.solution)
     assert conditions is not None
     conditions_dict = conditions_by_opcode(conditions)
     for public_key, message_hash in pkm_pairs_for_conditions_dict(conditions_dict, coin_solution.coin.name()):
         signature = self.sign(bytes(public_key), message_hash)
         signatures.append(signature)
     return AugSchemeMPL.aggregate(signatures)
Пример #5
0
 def signature_for_solution(self, solution, coin_name):
     signatures = []
     conditions = conditions_for_solution(solution)
     assert conditions[1] is not None
     conditions_dict = conditions_by_opcode(conditions[1])
     for _ in hash_key_pairs_for_conditions_dict(conditions_dict, coin_name):
         signature = self.sign(_)
         signatures.append(signature)
     return BLSSignature.aggregate(signatures)
Пример #6
0
 def signature_for_solution(self, solution, coin_name):
     signatures = []
     conditions = conditions_for_solution(solution)
     assert conditions[1] is not None
     conditions_dict = conditions_by_opcode(conditions[1])
     for pk, msg in pkm_pairs_for_conditions_dict(conditions_dict,
                                                  coin_name):
         signature = self.sign(pk, msg)
         signatures.append(signature)
     return AugSchemeMPL.aggregate(signatures)
Пример #7
0
    async def test_agg_sig_condition(self, two_nodes):
        num_blocks = 2
        wallet_a = WalletTool()
        coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
        wallet_receiver = WalletTool()
        receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()

        blocks = bt.get_consecutive_blocks(
            test_constants, num_blocks, [], 10, b"", coinbase_puzzlehash
        )
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]
        async for _ in full_node_1.respond_block(
            full_node_protocol.RespondBlock(block)
        ):
            pass

        unsigned: List[
            Tuple[Program, CoinSolution]
        ] = wallet_a.generate_unsigned_transaction(
            1000, receiver_puzzlehash, block.header.data.coinbase, {}, 0
        )
        assert len(unsigned) == 1

        puzzle, solution = unsigned[0]
        code_ = [puzzle, solution.solution]
        sexp = Program.to(code_)

        err, con, cost = conditions_for_solution(sexp)
        assert con is not None

        conditions_dict = conditions_by_opcode(con)
        hash_key_pairs = hash_key_pairs_for_conditions_dict(
            conditions_dict, solution.coin.name()
        )
        assert len(hash_key_pairs) == 1

        pk_pair: BLSSignature.PkMessagePair = hash_key_pairs[0]
        assert pk_pair.message_hash == solution.solution.first().get_tree_hash()

        spend_bundle = wallet_a.sign_transaction(unsigned)
        assert spend_bundle is not None

        tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
            spend_bundle
        )
        async for _ in full_node_1.respond_transaction(tx):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
        assert sb is spend_bundle
Пример #8
0
    async def test_agg_sig_condition(self, two_nodes):
        num_blocks = 2

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10, b"")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]
        async for _ in full_node_1.respond_block(
            full_node_protocol.RespondBlock(block)
        ):
            pass

        # this code has been changed to use generate_test_spend_bundle
        # not quite sure why all the gymnastics are being performed
        spend_bundle_0 = generate_test_spend_bundle(
            block.get_coinbase(),
        )
        unsigned: List[CoinSolution] = spend_bundle_0.coin_solutions

        assert len(unsigned) == 1
        coin_solution = unsigned[0]

        err, con, cost = conditions_for_solution(coin_solution.solution)
        assert con is not None

        puzzle, solution = list(coin_solution.solution.as_iter())
        conditions_dict = conditions_by_opcode(con)
        pkm_pairs = pkm_pairs_for_conditions_dict(
            conditions_dict, coin_solution.coin.name()
        )
        assert len(pkm_pairs) == 1

        assert pkm_pairs[0][1] == solution.first().get_tree_hash()

        spend_bundle = WALLET_A.sign_transaction(unsigned)
        assert spend_bundle is not None

        tx: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(spend_bundle)
        )
        async for _ in full_node_1.respond_transaction(tx):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
        assert sb is spend_bundle
def get_name_puzzle_conditions(block_program: SerializedProgram, safe_mode: bool):
    # TODO: allow generator mod to take something (future)
    # TODO: write more tests
    block_program_args = SerializedProgram.from_bytes(b"\x80")

    try:
        if safe_mode:
            cost, result = GENERATOR_MOD.run_safe_with_cost(block_program, block_program_args)
        else:
            cost, result = GENERATOR_MOD.run_with_cost(block_program, block_program_args)
        npc_list = []
        opcodes = set(item.value for item in ConditionOpcode)
        for res in result.as_iter():
            conditions_list = []
            name = std_hash(
                bytes(
                    res.first().first().as_atom()
                    + res.first().rest().first().as_atom()
                    + res.first().rest().rest().first().as_atom()
                )
            )
            puzzle_hash = bytes32(res.first().rest().first().as_atom())
            for cond in res.rest().first().as_iter():
                if cond.first().as_atom() in opcodes:
                    opcode = ConditionOpcode(cond.first().as_atom())
                elif not safe_mode:
                    opcode = ConditionOpcode.UNKNOWN
                else:
                    return "Unknown operator in safe mode.", None, None
                if len(list(cond.as_iter())) > 1:
                    cond_var_list = []
                    for cond_1 in cond.rest().as_iter():
                        cond_var_list.append(cond_1.as_atom())
                    cvl = ConditionVarPair(opcode, cond_var_list)
                else:
                    cvl = ConditionVarPair(opcode, [])
                conditions_list.append(cvl)
            conditions_dict = conditions_by_opcode(conditions_list)
            if conditions_dict is None:
                conditions_dict = {}
            npc_list.append(NPC(name, puzzle_hash, [(a, b) for a, b in conditions_dict.items()]))
        return None, npc_list, uint64(cost)
    except Exception:
        tb = traceback.format_exc()
        return tb, None, None
    def sign_transaction(self, coin_solutions: List[CoinSolution]) -> SpendBundle:
        signatures = []
        solution: Program
        puzzle: Program
        for coin_solution in coin_solutions:  # type: ignore # noqa
            secret_key = self.get_private_key_for_puzzle_hash(coin_solution.coin.puzzle_hash)
            synthetic_secret_key = calculate_synthetic_secret_key(secret_key, DEFAULT_HIDDEN_PUZZLE_HASH)
            err, con, cost = conditions_for_solution(coin_solution.solution)
            if not con:
                raise ValueError(err)
            conditions_dict = conditions_by_opcode(con)

            for _, msg in pkm_pairs_for_conditions_dict(conditions_dict, bytes(coin_solution.coin.name())):
                signature = AugSchemeMPL.sign(synthetic_secret_key, msg)
                signatures.append(signature)
        aggsig = AugSchemeMPL.aggregate(signatures)
        spend_bundle = SpendBundle(coin_solutions, aggsig)
        return spend_bundle
Пример #11
0
    async def sign_transaction(
        self, spends: List[Tuple[Program, CoinSolution]]
    ) -> Optional[SpendBundle]:
        signatures = []
        for puzzle, solution in spends:
            # Get keys
            keys = await self.wallet_state_manager.get_keys(solution.coin.puzzle_hash)
            if not keys:
                self.log.error(
                    f"Sign transaction failed, No Keys for puzzlehash {solution.coin.puzzle_hash}"
                )
                return None

            pubkey, secretkey = keys
            secretkey = BLSPrivateKey(secretkey)
            code_ = [puzzle, solution.solution]
            sexp = clvm.to_sexp_f(code_)

            # Get AGGSIG conditions
            err, con, cost = conditions_for_solution(sexp)
            if err or not con:
                self.log.error(f"Sign transcation failed, con:{con}, error: {err}")
                return None

            conditions_dict = conditions_by_opcode(con)

            # Create signature
            for pk_message in hash_key_pairs_for_conditions_dict(
                conditions_dict, bytes(solution.coin)
            ):
                signature = secretkey.sign(pk_message.message_hash)
                signatures.append(signature)

        # Aggregate signatures
        aggsig = BLSSignature.aggregate(signatures)
        solution_list: List[CoinSolution] = [
            CoinSolution(
                coin_solution.coin, clvm.to_sexp_f([puzzle, coin_solution.solution])
            )
            for (puzzle, coin_solution) in spends
        ]
        spend_bundle = SpendBundle(solution_list, aggsig)

        return spend_bundle
Пример #12
0
    async def test_agg_sig_condition(self, two_nodes):
        num_blocks = 2
        wallet_a = bt.get_pool_wallet_tool()
        wallet_receiver = WalletTool()
        receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()

        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10,
                                           b"")
        full_node_1, full_node_2, server_1, server_2 = two_nodes

        block = blocks[1]
        async for _ in full_node_1.respond_block(
                full_node_protocol.RespondBlock(block)):
            pass

        unsigned: List[CoinSolution] = wallet_a.generate_unsigned_transaction(
            1000, receiver_puzzlehash, block.get_coinbase(), {}, 0)
        assert len(unsigned) == 1
        coin_solution = unsigned[0]

        err, con, cost = conditions_for_solution(coin_solution.solution)
        assert con is not None

        puzzle, solution = list(coin_solution.solution.as_iter())
        conditions_dict = conditions_by_opcode(con)
        pkm_pairs = pkm_pairs_for_conditions_dict(conditions_dict,
                                                  coin_solution.coin.name())
        assert len(pkm_pairs) == 1

        assert pkm_pairs[0][1] == solution.first().get_tree_hash()

        spend_bundle = wallet_a.sign_transaction(unsigned)
        assert spend_bundle is not None

        tx: full_node_protocol.RespondTransaction = (
            full_node_protocol.RespondTransaction(spend_bundle))
        async for _ in full_node_1.respond_transaction(tx):
            outbound: OutboundMessage = _
            # Maybe transaction means that it's accepted in mempool
            assert outbound.message.function == "new_transaction"

        sb = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
        assert sb is spend_bundle