Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions include/bitcoin/node/channels/channel_electrum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <bitcoin/node/configuration.hpp>
#include <bitcoin/node/define.hpp>
#include <bitcoin/node/interfaces/interfaces.hpp>
#include <bitcoin/node/parsers/parsers.hpp>

namespace libbitcoin {
namespace node {
Expand Down Expand Up @@ -51,6 +52,34 @@ class BCN_API channel_electrum
network::tracker<channel_electrum>(log)
{
}

/// Properties.
/// -----------------------------------------------------------------------

inline void set_client(const std::string& name) NOEXCEPT
{
name_ = name;
}

inline const std::string& client() const NOEXCEPT
{
return name_;
}

inline void set_version(electrum_version version) NOEXCEPT
{
version_ = version;
}

inline electrum_version version() const NOEXCEPT
{
return version_;
}

private:
// These are protected by strand.
electrum_version version_{ electrum_version::v0_0 };
std::string name_{};
};

} // namespace node
Expand Down
13 changes: 9 additions & 4 deletions include/bitcoin/node/protocols/protocol_electrum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class BCN_API protocol_electrum
const network::channel::ptr& channel,
const options_t& options) NOEXCEPT
: node::protocol_rpc<channel_electrum>(session, channel, options),
channel_(std::dynamic_pointer_cast<channel_t>(channel)),
network::tracker<protocol_electrum>(session->log)
{
}
Expand Down Expand Up @@ -116,10 +117,14 @@ class BCN_API protocol_electrum
rpc_interface::mempool_get_fee_histogram) NOEXCEPT;

protected:
////bool is_version(protocol_version version) const NOEXCEPT
////{
//// return version_ >= version;
////}
inline bool is_version(electrum_version version) const NOEXCEPT
{
return channel_->version() >= version;
}

private:
// This is mostly thread safe, and used in a thread safe manner.
const channel_t::ptr channel_;
};

} // namespace node
Expand Down
22 changes: 12 additions & 10 deletions include/bitcoin/node/protocols/protocol_electrum_version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class BCN_API protocol_electrum_version
const network::channel::ptr& channel,
const options_t& options) NOEXCEPT
: node::protocol_rpc<channel_electrum>(session, channel, options),
channel_(std::dynamic_pointer_cast<channel_t>(channel)),
network::tracker<protocol_electrum_version>(session->log)
{
}
Expand All @@ -50,22 +51,22 @@ class BCN_API protocol_electrum_version
virtual void complete(const code& ec, const code& shake) NOEXCEPT;

protected:
static constexpr electrum_version minimum = electrum_version::v1_4;
static constexpr electrum_version maximum = electrum_version::v1_4_2;
static constexpr size_t max_client_name_length = 1024;

void handle_server_version(const code& ec,
rpc_interface::server_version, const std::string& client_name,
const interface::value_t& protocol_version) NOEXCEPT;

protected:
static constexpr electrum_version minimum = electrum_version::v1_4;
static constexpr electrum_version maximum = electrum_version::v1_4_2;

electrum_version version() const NOEXCEPT;
std::string_view get_version() const NOEXCEPT;
std::string_view negotiated_version() const NOEXCEPT;
bool set_version(const interface::value_t& version) NOEXCEPT;
bool get_versions(electrum_version& min, electrum_version& max,
const interface::value_t& version) NOEXCEPT;

std::string_view get_server() const NOEXCEPT;
std::string_view get_client() const NOEXCEPT;
std::string_view server_name() const NOEXCEPT;
std::string_view client_name() const NOEXCEPT;
std::string escape_client(const std::string& in) NOEXCEPT;
bool set_client(const std::string& name) NOEXCEPT;

Expand All @@ -75,10 +76,11 @@ class BCN_API protocol_electrum_version
static electrum_version version_from_string(
const std::string_view& version) NOEXCEPT;

// These are protected by strand.
// This is mostly thread safe, and used in a thread safe manner.
const channel_t::ptr channel_;

// This is protected by strand.
std::shared_ptr<network::result_handler> handler_{};
electrum_version version_{ electrum_version::v0_0 };
std::string name_{};
};

} // namespace node
Expand Down
41 changes: 19 additions & 22 deletions src/protocols/protocol_electrum_version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ using namespace network;
using namespace interface;
using namespace std::placeholders;

constexpr auto max_client_name_length = 1024u;

BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
BC_PUSH_WARNING(SMART_PTR_NOT_NEEDED)
BC_PUSH_WARNING(NO_VALUE_OR_CONST_REF_SHARED_PTR)
Expand Down Expand Up @@ -72,7 +70,7 @@ void protocol_electrum_version::complete(const code& ec,
// Calls after handshake completion are allowed and will skip this.
if (handler_)
{
// shake error will result in stopped channel.
// Invoke handshake completion, error will result in stopped channel.
(*handler_)(shake);
handler_.reset();
}
Expand All @@ -84,14 +82,14 @@ void protocol_electrum_version::complete(const code& ec,
// Changed in version 1.6: server must tolerate and ignore extraneous args.
void protocol_electrum_version::handle_server_version(const code& ec,
rpc_interface::server_version, const std::string& client_name,
const value_t& electrum_version) NOEXCEPT
const value_t& protocol_version) NOEXCEPT
{
if (stopped(ec))
return;

// v0_0 implies version has not been set (first call).
if ((version() == electrum_version::v0_0) &&
(!set_client(client_name) || !set_version(electrum_version)))
if ((channel_->version() == electrum_version::v0_0) &&
(!set_client(client_name) || !set_version(protocol_version)))
{
const auto reason = error::invalid_argument;
send_code(reason, BIND(complete, _1, reason));
Expand All @@ -102,24 +100,27 @@ void protocol_electrum_version::handle_server_version(const code& ec,
{
array_t
{
{ string_t{ get_server() } },
{ string_t{ get_version() } }
{ string_t{ server_name() } },
{ string_t{ negotiated_version() } }
}
}, 70, BIND(complete, _1, error::success));
}

// Handshake must leave channel paused, before leaving stranded handler.
if (handler_) pause();
}

// Client/server names.
// ----------------------------------------------------------------------------

std::string_view protocol_electrum_version::get_server() const NOEXCEPT
std::string_view protocol_electrum_version::server_name() const NOEXCEPT
{
return settings().user_agent;
}

std::string_view protocol_electrum_version::get_client() const NOEXCEPT
std::string_view protocol_electrum_version::client_name() const NOEXCEPT
{
return name_;
return channel_->client();
}

bool protocol_electrum_version::set_client(const std::string& name) NOEXCEPT
Expand All @@ -129,11 +130,12 @@ bool protocol_electrum_version::set_client(const std::string& name) NOEXCEPT
return false;

// Do not put to log without escaping.
name_ = escape_client(name);
channel_->set_client(escape_client(name));
return true;
}

std::string protocol_electrum_version::escape_client(const std::string& in) NOEXCEPT
std::string protocol_electrum_version::escape_client(
const std::string& in) NOEXCEPT
{
std::string out(in.size(), '*');
std::transform(in.begin(), in.end(), out.begin(), [](char c) NOEXCEPT
Expand All @@ -148,14 +150,9 @@ std::string protocol_electrum_version::escape_client(const std::string& in) NOEX
// Negotiated version.
// ----------------------------------------------------------------------------

electrum_version protocol_electrum_version::version() const NOEXCEPT
{
return version_;
}

std::string_view protocol_electrum_version::get_version() const NOEXCEPT
std::string_view protocol_electrum_version::negotiated_version() const NOEXCEPT
{
return version_to_string(version_);
return version_to_string(channel_->version());
}

bool protocol_electrum_version::set_version(const value_t& version) NOEXCEPT
Expand All @@ -171,9 +168,9 @@ bool protocol_electrum_version::set_version(const value_t& version) NOEXCEPT
return false;

LOGA("Electrum [" << authority() << "] version ("
<< version_to_string(client_max) << ") " << get_client());
<< version_to_string(client_max) << ") " << client_name());

version_ = upper;
channel_->set_version(upper);
return true;
}

Expand Down
Loading