Repository: bitcoin/bitcoin
File: src/rpc/output_script.cpp (C++)

Code before:
            if (!desc) {
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
            }

            if (!desc->IsRange() && request.params.size() > 1) {
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Range should not be specified for an un-ranged descriptor");
            }

            if (desc->IsRange() && request.params.size() == 1) {
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified for a ranged descriptor");
            }

            UniValue addresses(UniValue::VARR);

            for (int64_t i = range_begin; i <= range_end; ++i) {
                FlatSigningProvider provider;
                std::vector<CScript> scripts;
                if (!desc->Expand(i, key_provider, scripts, provider)) {
                    throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys");
                }

                for (const CScript& script : scripts) {
                    CTxDestination dest;
                    if (!ExtractDestination(script, dest)) {
                        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Descriptor does not have a corresponding address");
                    }

                    addresses.push_back(EncodeDestination(dest));
                }
            }

            // This should not be possible, but an assert seems overkill:
            if (addresses.empty()) {
                throw JSONRPCError(RPC_MISC_ERROR, "Unexpected empty result");
            }

            return addresses;
        },
    };
}

void RegisterOutputScriptRPCCommands(CRPCTable& t)
{
    static const CRPCCommand commands[]{
        {"util", &validateaddress},
        {"util", &createmultisig},
        {"util", &deriveaddresses},
        {"util", &getdescriptorinfo},
    };
    for (const auto& c : commands) {
        t.appendCommand(c.name, &c);

Review comment (suggestion):
in https://github.com/bitcoin/bitcoin/pull/28246/commits/6c87957a8e51cef93647858d61a5d38f3336eeaa:

Where are we saying this is no longer a valid destination? Per `IsStandard` and the `Solver` it seems to be fine, but perhaps I'm missing something.

Code after:
            if (!desc) {
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
            }

            if (!desc->IsRange() && request.params.size() > 1) {
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Range should not be specified for an un-ranged descriptor");
            }

            if (desc->IsRange() && request.params.size() == 1) {
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified for a ranged descriptor");
            }

            UniValue addresses(UniValue::VARR);

            for (int64_t i = range_begin; i <= range_end; ++i) {
                FlatSigningProvider provider;
                std::vector<CScript> scripts;
                if (!desc->Expand(i, key_provider, scripts, provider)) {
                    throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys");
                }

                for (const CScript& script : scripts) {
                    CTxDestination dest;
                    if (!ExtractDestination(script, dest)) {
                        // ExtractDestination no longer returns true for P2PK since it doesn't have a corresponding address
                        // However combo will output P2PK and should just ignore that script
                        if (scripts.size() > 1 && std::get_if<PubKeyDestination>(&dest)) {
                            continue;
                        }
                        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Descriptor does not have a corresponding address");
                    }

                    addresses.push_back(EncodeDestination(dest));
                }
            }

            // This should not be possible, but an assert seems overkill:
            if (addresses.empty()) {
                throw JSONRPCError(RPC_MISC_ERROR, "Unexpected empty result");
            }

            return addresses;
        },
    };
}

void RegisterOutputScriptRPCCommands(CRPCTable& t)
{
    static const CRPCCommand commands[]{
        {"util", &validateaddress},
        {"util", &createmultisig},