The wallet code uses `Optional::emplace()`, which was only added in boost 1.56, see https://github.com/boostorg/optional/commit/2e583aaf30964afd66c1284aa71d0d8b42fa440d

So for 0.21.0 there are two options:
* Work around `emplace` and keep the minimum boost version below 1.56
* Require boost 1.56


```
wallet/rpcwallet.cpp: In function ‘UniValue listsinceblock(const JSONRPCRequest&)’:
wallet/rpcwallet.cpp:1560:16: error: ‘Optional<int>’ has no member named ‘emplace’
         height.emplace();
                ^
wallet/rpcwallet.cpp:1561:19: error: ‘Optional<int>’ has no member named ‘emplace’
         altheight.emplace();
                   ^
fIncludeEmpty = params[1].get_bool();
    isminefilter filter = ISMINE_SPENDABLE;
    if (ParseIncludeWatchonly(params[2], *pwallet)) {
        filter |= ISMINE_WATCH_ONLY;
    }
    bool has_filtered_address = false;
    CTxDestination filtered_address = CNoDestination();
    if (!by_label && params.size() > 3) {
        if (!IsValidDestinationString(params[3].get_str())) {
            throw JSONRPCError(RPC_WALLET_ERROR, "address_filter parameter was invalid");
        }
        filtered_address = DecodeDestination(params[3].get_str());
        has_filtered_address = true;
    }
    
    std::map<CTxDestination, tallyitem> mapTally;
    for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
        const CWalletTx& wtx = pairWtx.second;
        if (wtx.IsCoinBase() || !pwallet->chain().checkFinalTx(*wtx.tx)) {
            continue;
        }
        int nDepth = wtx.GetDepthInMainChain();
        if (nDepth < nMinDepth)
            continue;
        for (const CTxOut& txout : wtx.tx->vout)
        {
            CTxDestination address;
            if (!ExtractDestination(txout.scriptPubKey, address))
                continue;
            if (has_filtered_address && !(filtered_address == address)) {