Skip to content

Commit b48333e

Browse files
committed
Port Libre Relay to v29.0
All changes from v28.1..libre-relay-v28.1-2, minus the docker/github CI stuff.
1 parent f490f55 commit b48333e

30 files changed

Lines changed: 252 additions & 90 deletions

src/bitcoin-cli.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
395395
private:
396396
std::array<std::array<uint16_t, NETWORKS.size() + 1>, 3> m_counts{{{}}}; //!< Peer counts by (in/out/total, networks/total)
397397
uint8_t m_block_relay_peers_count{0};
398+
uint8_t m_libre_peers_count{0};
398399
uint8_t m_manual_peers_count{0};
399400
int8_t NetworkStringToId(const std::string& str) const
400401
{
@@ -470,6 +471,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
470471
if (conn_type == "block-relay-only") return "block";
471472
if (conn_type == "manual" || conn_type == "feeler") return conn_type;
472473
if (conn_type == "addr-fetch") return "addr";
474+
if (conn_type == "libre") return "libre";
473475
return "";
474476
}
475477
std::string FormatServices(const UniValue& services)
@@ -536,6 +538,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
536538
++m_counts.at(2).at(network_id); // total by network
537539
++m_counts.at(2).at(NETWORKS.size()); // total overall
538540
if (conn_type == "block-relay-only") ++m_block_relay_peers_count;
541+
if (conn_type == "libre") ++m_libre_peers_count;
539542
if (conn_type == "manual") ++m_manual_peers_count;
540543
if (m_outbound_only_selected && !is_outbound) continue;
541544
if (DetailsRequested()) {
@@ -577,7 +580,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
577580
// Report detailed peer connections list sorted by direction and minimum ping time.
578581
if (DetailsRequested() && !m_peers.empty()) {
579582
std::sort(m_peers.begin(), m_peers.end());
580-
result += strprintf("<-> type net %*s v mping ping send recv txn blk hb %*s%*s%*s ",
583+
result += strprintf("<-> type net %*s v mping ping send recv txn blk hb %*s%*s%*s ",
581584
m_max_services_length, "serv",
582585
m_max_addr_processed_length, "addrp",
583586
m_max_addr_rate_limited_length, "addrl",
@@ -587,7 +590,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
587590
for (const Peer& peer : m_peers) {
588591
std::string version{ToString(peer.version) + peer.sub_version};
589592
result += strprintf(
590-
"%3s %6s %5s %*s %2s%7s%7s%5s%5s%5s%5s %2s %*s%*s%*s%*i %*s %-*s%s\n",
593+
"%3s %8s %5s %*s %2s%7s%7s%5s%5s%5s%5s %2s %*s%*s%*s%*i %*s %-*s%s\n",
591594
peer.is_outbound ? "out" : "in",
592595
ConnectionTypeForNetinfo(peer.conn_type),
593596
peer.network,
@@ -615,7 +618,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
615618
IsAddressSelected() ? peer.addr : "",
616619
IsVersionSelected() && version != "0" ? version : "");
617620
}
618-
result += strprintf(" %*s ms ms sec sec min min %*s\n\n", m_max_services_length, "", m_max_age_length, "min");
621+
result += strprintf(" %*s ms ms sec sec min min %*s\n\n", m_max_services_length, "", m_max_age_length, "min");
619622
}
620623

621624
// Report peer connection totals by type.
@@ -638,6 +641,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
638641
}
639642

640643
result += " total block";
644+
if (m_libre_peers_count) result += " libre";
641645
if (m_manual_peers_count) result += " manual";
642646

643647
const std::array rows{"in", "out", "total"};
@@ -649,6 +653,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
649653
result += strprintf(" %5i", m_counts.at(i).at(NETWORKS.size())); // total peers count
650654
if (i == 1) { // the outbound row has two extra columns for block relay and manual peer counts
651655
result += strprintf(" %5i", m_block_relay_peers_count);
656+
if (m_libre_peers_count) result += strprintf(" %5i", m_libre_peers_count);
652657
if (m_manual_peers_count) result += strprintf(" %5i", m_manual_peers_count);
653658
}
654659
}
@@ -705,6 +710,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
705710
" \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n"
706711
" \"feeler\" - short-lived connection for testing addresses\n"
707712
" \"addr\" - address fetch; short-lived connection for requesting addresses\n"
713+
" \"libre\" - libre relay; long-lived connection for libre transaction-relay\n"
708714
" net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", \"cjdns\", or \"npr\" (not publicly routable))\n"
709715
" serv Services offered by the peer\n"
710716
" \"n\" - NETWORK: peer can serve the full block chain\n"

src/init.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ namespace { // Variables internal to initialization process only
837837

838838
int nMaxConnections;
839839
int available_fds;
840-
ServiceFlags g_local_services = ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
840+
ServiceFlags g_local_services = ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_LIBRE_RELAY);
841841
int64_t peer_connect_timeout;
842842
std::set<BlockFilterType> g_enabled_filter_types;
843843

@@ -1905,6 +1905,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
19051905
CConnman::Options connOptions;
19061906
connOptions.m_local_services = g_local_services;
19071907
connOptions.m_max_automatic_connections = nMaxConnections;
1908+
connOptions.m_max_outbound_libre_relay = MAX_LIBRE_RELAY_CONNECTIONS;
19081909
connOptions.uiInterface = &uiInterface;
19091910
connOptions.m_banman = node.banman.get();
19101911
connOptions.m_msgproc = node.peerman.get();

src/net.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,6 +1875,9 @@ bool CConnman::AddConnection(const std::string& address, ConnectionType conn_typ
18751875
case ConnectionType::BLOCK_RELAY:
18761876
max_connections = m_max_outbound_block_relay;
18771877
break;
1878+
case ConnectionType::LIBRE_RELAY:
1879+
max_connections = m_max_outbound_libre_relay;
1880+
break;
18781881
// no limit for ADDR_FETCH because -seednode has no limit either
18791882
case ConnectionType::ADDR_FETCH:
18801883
break;
@@ -2633,6 +2636,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, Spa
26332636
// Only connect out to one peer per ipv4/ipv6 network group (/16 for IPv4).
26342637
int nOutboundFullRelay = 0;
26352638
int nOutboundBlockRelay = 0;
2639+
int nOutboundLibreRelay = 0;
26362640
int outbound_privacy_network_peers = 0;
26372641
std::set<std::vector<unsigned char>> outbound_ipv46_peer_netgroups;
26382642

@@ -2641,6 +2645,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, Spa
26412645
for (const CNode* pnode : m_nodes) {
26422646
if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
26432647
if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
2648+
if (pnode->IsLibreRelay()) nOutboundLibreRelay++;
26442649

26452650
// Make sure our persistent outbound slots to ipv4/ipv6 peers belong to different netgroups.
26462651
switch (pnode->m_conn_type) {
@@ -2656,6 +2661,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, Spa
26562661
case ConnectionType::MANUAL:
26572662
case ConnectionType::OUTBOUND_FULL_RELAY:
26582663
case ConnectionType::BLOCK_RELAY:
2664+
case ConnectionType::LIBRE_RELAY:
26592665
const CAddress address{pnode->addr};
26602666
if (address.IsTor() || address.IsI2P() || address.IsCJDNS()) {
26612667
// Since our addrman-groups for these networks are
@@ -2684,6 +2690,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, Spa
26842690
auto now = GetTime<std::chrono::microseconds>();
26852691
bool anchor = false;
26862692
bool fFeeler = false;
2693+
bool libre = false;
26872694
std::optional<Network> preferred_net;
26882695

26892696
// Determine what type of connection to open. Opening
@@ -2730,6 +2737,9 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, Spa
27302737
// (similar to how we deal with extra outbound peers).
27312738
next_extra_block_relay = now + rng.rand_exp_duration(EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
27322739
conn_type = ConnectionType::BLOCK_RELAY;
2740+
} else if (nOutboundLibreRelay < m_max_outbound_libre_relay) {
2741+
conn_type = ConnectionType::LIBRE_RELAY;
2742+
libre = true;
27332743
} else if (now > next_feeler) {
27342744
next_feeler = now + rng.rand_exp_duration(FEELER_INTERVAL);
27352745
conn_type = ConnectionType::FEELER;
@@ -2827,6 +2837,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, Spa
28272837
continue;
28282838
}
28292839

2840+
// if we would like to open a libre connection, requires
2841+
// the libre service flag to be set
2842+
if (libre && !HasLibreRelayServiceFlag(addr.nServices))
2843+
continue;
2844+
28302845
// for non-feelers, require all the services we'll want,
28312846
// for feelers, only require they be a full node (only because most
28322847
// SPV clients don't have a good address DB available)

src/net.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 4 * 1000 * 1000;
6565
static const unsigned int MAX_SUBVERSION_LENGTH = 256;
6666
/** Maximum number of automatic outgoing nodes over which we'll relay everything (blocks, tx, addrs, etc) */
6767
static const int MAX_OUTBOUND_FULL_RELAY_CONNECTIONS = 8;
68+
/** Maximum number of automatic libre-relay peers */
69+
static const int MAX_LIBRE_RELAY_CONNECTIONS = 4;
6870
/** Maximum number of addnode outgoing nodes */
6971
static const int MAX_ADDNODE_CONNECTIONS = 8;
7072
/** Maximum number of block-relay-only outgoing connections */
@@ -761,6 +763,7 @@ class CNode
761763
switch (m_conn_type) {
762764
case ConnectionType::OUTBOUND_FULL_RELAY:
763765
case ConnectionType::BLOCK_RELAY:
766+
case ConnectionType::LIBRE_RELAY:
764767
return true;
765768
case ConnectionType::INBOUND:
766769
case ConnectionType::MANUAL:
@@ -789,6 +792,7 @@ class CNode
789792
case ConnectionType::ADDR_FETCH:
790793
return false;
791794
case ConnectionType::OUTBOUND_FULL_RELAY:
795+
case ConnectionType::LIBRE_RELAY:
792796
case ConnectionType::MANUAL:
793797
return true;
794798
} // no default case, so the compiler can warn about missing cases
@@ -812,6 +816,10 @@ class CNode
812816
return m_conn_type == ConnectionType::INBOUND;
813817
}
814818

819+
bool IsLibreRelay() const {
820+
return m_conn_type == ConnectionType::LIBRE_RELAY;
821+
}
822+
815823
bool ExpectServicesFromConn() const {
816824
switch (m_conn_type) {
817825
case ConnectionType::INBOUND:
@@ -821,6 +829,7 @@ class CNode
821829
case ConnectionType::OUTBOUND_FULL_RELAY:
822830
case ConnectionType::BLOCK_RELAY:
823831
case ConnectionType::ADDR_FETCH:
832+
case ConnectionType::LIBRE_RELAY:
824833
return true;
825834
} // no default case, so the compiler can warn about missing cases
826835

@@ -1078,6 +1087,7 @@ class CConnman
10781087
bool m_i2p_accept_incoming;
10791088
bool whitelist_forcerelay = DEFAULT_WHITELISTFORCERELAY;
10801089
bool whitelist_relay = DEFAULT_WHITELISTRELAY;
1090+
int m_max_outbound_libre_relay = 0;
10811091
};
10821092

10831093
void Init(const Options& connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex, !m_total_bytes_sent_mutex)
@@ -1088,7 +1098,8 @@ class CConnman
10881098
m_max_automatic_connections = connOptions.m_max_automatic_connections;
10891099
m_max_outbound_full_relay = std::min(MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, m_max_automatic_connections);
10901100
m_max_outbound_block_relay = std::min(MAX_BLOCK_RELAY_ONLY_CONNECTIONS, m_max_automatic_connections - m_max_outbound_full_relay);
1091-
m_max_automatic_outbound = m_max_outbound_full_relay + m_max_outbound_block_relay + m_max_feeler;
1101+
m_max_outbound_libre_relay = connOptions.m_max_outbound_libre_relay;
1102+
m_max_automatic_outbound = m_max_outbound_full_relay + m_max_outbound_block_relay + m_max_feeler + m_max_outbound_libre_relay;
10921103
m_max_inbound = std::max(0, m_max_automatic_connections - m_max_automatic_outbound);
10931104
m_use_addrman_outgoing = connOptions.m_use_addrman_outgoing;
10941105
m_client_interface = connOptions.uiInterface;
@@ -1524,6 +1535,8 @@ class CConnman
15241535
/** Pointer to this node's banman. May be nullptr - check existence before dereferencing. */
15251536
BanMan* m_banman;
15261537

1538+
int m_max_outbound_libre_relay;
1539+
15271540
/**
15281541
* Addresses that were saved during the previous clean shutdown. We'll
15291542
* attempt to make block-relay-only connections to them.

src/net_processing.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3420,6 +3420,13 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
34203420
return;
34213421
}
34223422

3423+
if (pfrom.IsLibreRelay() && !HasLibreRelayServiceFlag(nServices))
3424+
{
3425+
LogDebug(BCLog::NET, "peer=%d does not offer libre relay as expected; disconnecting\n", pfrom.GetId());
3426+
pfrom.fDisconnect = true;
3427+
return;
3428+
}
3429+
34233430
if (nVersion < MIN_PEER_PROTO_VERSION) {
34243431
// disconnect from peers older than this proto version
34253432
LogDebug(BCLog::NET, "peer using obsolete version %i, %s\n", nVersion, pfrom.DisconnectMsg(fLogIPs));

src/node/connection_types.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ std::string ConnectionTypeAsString(ConnectionType conn_type)
2020
return "block-relay-only";
2121
case ConnectionType::ADDR_FETCH:
2222
return "addr-fetch";
23+
case ConnectionType::LIBRE_RELAY:
24+
return "libre";
2325
} // no default case, so the compiler can warn about missing cases
2426

2527
assert(false);

src/node/connection_types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ enum class ConnectionType {
7575
* AddrMan is empty.
7676
*/
7777
ADDR_FETCH,
78+
79+
/**
80+
* Libre-relay connections are long-lived connections used to relay transactions
81+
* with peers accepting the libre standardness policies.
82+
*/
83+
LIBRE_RELAY,
7884
};
7985

8086
/** Convert ConnectionType enum to a string value */

src/node/mempool_args.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,12 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& argsman, const CChainP
8181

8282
mempool_opts.permit_bare_multisig = argsman.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
8383

84-
if (argsman.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER)) {
85-
mempool_opts.max_datacarrier_bytes = argsman.GetIntArg("-datacarriersize", MAX_OP_RETURN_RELAY);
86-
} else {
87-
mempool_opts.max_datacarrier_bytes = std::nullopt;
88-
}
84+
// if (argsman.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER)) {
85+
// mempool_opts.max_datacarrier_bytes = argsman.GetIntArg("-datacarriersize", MAX_OP_RETURN_RELAY);
86+
// } else {
87+
// mempool_opts.max_datacarrier_bytes = std::nullopt;
88+
// }
89+
mempool_opts.max_datacarrier_bytes = MAX_OP_RETURN_RELAY;
8990

9091
mempool_opts.require_standard = !argsman.GetBoolArg("-acceptnonstdtxn", DEFAULT_ACCEPT_NON_STD_TXN);
9192
if (!chainparams.IsTestChain() && !mempool_opts.require_standard) {

src/policy/feerate.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ class CFeeRate
7272
friend CFeeRate operator*(const CFeeRate& f, int a) { return CFeeRate(a * f.nSatoshisPerK); }
7373
friend CFeeRate operator*(int a, const CFeeRate& f) { return CFeeRate(a * f.nSatoshisPerK); }
7474

75+
// For RBFR. A bit of a hack to have this. But does the job.
76+
friend CFeeRate operator*(const CFeeRate& f, double a) { return CFeeRate(int(a * f.nSatoshisPerK)); }
77+
friend CFeeRate operator*(double a, const CFeeRate& f) { return CFeeRate(int(a * f.nSatoshisPerK)); }
78+
7579
SERIALIZE_METHODS(CFeeRate, obj) { READWRITE(obj.nSatoshisPerK); }
7680
};
7781

src/policy/policy.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,17 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
137137
}
138138
}
139139

140-
unsigned int nDataOut = 0;
140+
//unsigned int nDataOut = 0;
141141
TxoutType whichType;
142142
for (const CTxOut& txout : tx.vout) {
143143
if (!::IsStandard(txout.scriptPubKey, max_datacarrier_bytes, whichType)) {
144144
reason = "scriptpubkey";
145145
return false;
146146
}
147147

148-
if (whichType == TxoutType::NULL_DATA)
149-
nDataOut++;
150-
else if ((whichType == TxoutType::MULTISIG) && (!permit_bare_multisig)) {
148+
if (whichType == TxoutType::NULL_DATA) {
149+
// nDataOut++;
150+
} else if ((whichType == TxoutType::MULTISIG) && (!permit_bare_multisig)) {
151151
reason = "bare-multisig";
152152
return false;
153153
}
@@ -160,10 +160,10 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
160160
}
161161

162162
// only one OP_RETURN txout is permitted
163-
if (nDataOut > 1) {
164-
reason = "multi-op-return";
165-
return false;
166-
}
163+
//if (nDataOut > 1) {
164+
// reason = "multi-op-return";
165+
// return false;
166+
//}
167167

168168
return true;
169169
}

0 commit comments

Comments
 (0)