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

Code before:

        m_private_key = DecodeI2PBase64(reply.Get("DESTINATION"));
    } else {
        // Read our persistent destination (private key) from disk or generate
        // one and save it to disk. Then use it when creating the session.
        const auto& [read_ok, data] = ReadBinaryFile(m_private_key_file);
        if (read_ok) {
            m_private_key.assign(data.begin(), data.end());
        } else {
            GenerateAndSavePrivateKey(*sock);
        }

        const std::string& private_key_b64 = SwapBase64(EncodeBase64(m_private_key));

        SendRequestAndGetReply(*sock,
                               strprintf("SESSION CREATE STYLE=STREAM ID=%s DESTINATION=%s "
                                         "i2cp.leaseSetEncType=4,0 inbound.quantity=3 outbound.quantity=3",
                                         session_id,
                                         private_key_b64));
    }

    m_my_addr = CService(DestBinToAddr(MyDestination()), I2P_SAM31_PORT);
    m_session_id = session_id;
    m_control_sock = std::move(sock);

    LogPrintLevel(BCLog::I2P, BCLog::Level::Info, "%s SAM session %s created, my address=%s\n",
        Capitalize(session_type),
        m_session_id,
        m_my_addr.ToStringAddrPort());
}

std::unique_ptr<Sock> Session::StreamAccept()
{
    auto sock = Hello();

    const Reply& reply = SendRequestAndGetReply(
        *sock, strprintf("STREAM ACCEPT ID=%s SILENT=false", m_session_id), false);

    const std::string& result = reply.Get("RESULT");

    if (result == "OK") {
        return sock;
    }

    if (result == "INVALID_ID") {
        // If our session id is invalid, then force session re-creation on next usage.
        Disconnect();
    }

    throw std::runtime_error(strprintf("\"%s\"", reply.full));
}

Review comment (suggestion):
Should these log messages include "I2P" somewhere? Otherwise figuring out what SAM relates to may be confusing. The help text for `-i2psam` describes it as an "I2P SAM proxy".

Code after:

        m_private_key = DecodeI2PBase64(reply.Get("DESTINATION"));
    } else {
        // Read our persistent destination (private key) from disk or generate
        // one and save it to disk. Then use it when creating the session.
        const auto& [read_ok, data] = ReadBinaryFile(m_private_key_file);
        if (read_ok) {
            m_private_key.assign(data.begin(), data.end());
        } else {
            GenerateAndSavePrivateKey(*sock);
        }

        const std::string& private_key_b64 = SwapBase64(EncodeBase64(m_private_key));

        SendRequestAndGetReply(*sock,
                               strprintf("SESSION CREATE STYLE=STREAM ID=%s DESTINATION=%s "
                                         "i2cp.leaseSetEncType=4,0 inbound.quantity=3 outbound.quantity=3",
                                         session_id,
                                         private_key_b64));
    }

    m_my_addr = CService(DestBinToAddr(MyDestination()), I2P_SAM31_PORT);
    m_session_id = session_id;
    m_control_sock = std::move(sock);

    LogInfo("%s I2P SAM session %s created, my address=%s",
        Capitalize(session_type),
        m_session_id,
        m_my_addr.ToStringAddrPort());
}

std::unique_ptr<Sock> Session::StreamAccept()
{
    auto sock = Hello();

    const Reply& reply = SendRequestAndGetReply(
        *sock, strprintf("STREAM ACCEPT ID=%s SILENT=false", m_session_id), false);

    const std::string& result = reply.Get("RESULT");

    if (result == "OK") {
        return sock;
    }

    if (result == "INVALID_ID") {
        // If our session id is invalid, then force session re-creation on next usage.
        Disconnect();
    }

    throw std::runtime_error(strprintf("\"%s\"", reply.full));
}