Skip to content
This repository was archived by the owner on Oct 28, 2021. It is now read-only.

Commit 88e6896

Browse files
authored
Outputs ENR text representation in admin.nodeInfo RPC (#5701)
Outputs ENR text representation in admin.nodeInfo RPC
2 parents 7eb211d + ce7201f commit 88e6896

File tree

8 files changed

+152
-112
lines changed

8 files changed

+152
-112
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- Added: [#5634](https://github.com/ethereum/aleth/pull/5634) Bootnodes for Rinkeby and Goerli.
1616
- Added: [#5640](https://github.com/ethereum/aleth/pull/5640) Support EIP-1702 Generalized Account Versioning Scheme (active only in Experimental fork.)
1717
- Added: [#5690](https://github.com/ethereum/aleth/issues/5690) Istanbul support: EIP-2028 transaction data gas cost reduction.
18+
- Added: [#5701](https://github.com/ethereum/aleth/issues/5701) Outputs ENR text representation in admin.nodeInfo RPC.
1819
- Changed: [#5532](https://github.com/ethereum/aleth/pull/5532) The leveldb is upgraded to 1.22. This is breaking change on Windows and the old databases are not compatible.
1920
- Changed: [#5559](https://github.com/ethereum/aleth/pull/5559) Update peer validation error messages.
2021
- Changed: [#5568](https://github.com/ethereum/aleth/pull/5568) Improve rlpx handshake log messages and create new rlpx log channel.

libdevcore/Base64.cpp

Lines changed: 117 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
freely, subject to the following restrictions:
1313
1414
1. The origin of this source code must not be misrepresented; you must not
15-
claim that you wrote the original source code. If you use this source code
16-
in a product, an acknowledgment in the product documentation would be
17-
appreciated but is not required.
15+
claim that you wrote the original source code. If you use this source code
16+
in a product, an acknowledgment in the product documentation would be
17+
appreciated but is not required.
1818
1919
2. Altered source versions must be plainly marked as such, and must not be
20-
misrepresented as being the original source code.
20+
misrepresented as being the original source code.
2121
2222
3. This notice may not be removed or altered from any source distribution.
2323
@@ -33,114 +33,129 @@ using namespace dev;
3333

3434
static inline bool is_base64(byte c)
3535
{
36-
return (isalnum(c) || (c == '+') || (c == '/'));
36+
return (isalnum(c) || (c == '+') || (c == '/'));
3737
}
3838

3939
static inline byte find_base64_char_index(byte c)
4040
{
41-
if ('A' <= c && c <= 'Z') return c - 'A';
42-
else if ('a' <= c && c <= 'z') return c - 'a' + 1 + find_base64_char_index('Z');
43-
else if ('0' <= c && c <= '9') return c - '0' + 1 + find_base64_char_index('z');
44-
else if (c == '+') return 1 + find_base64_char_index('9');
45-
else if (c == '/') return 1 + find_base64_char_index('+');
46-
else return 1 + find_base64_char_index('/');
41+
if ('A' <= c && c <= 'Z') return c - 'A';
42+
else if ('a' <= c && c <= 'z') return c - 'a' + 1 + find_base64_char_index('Z');
43+
else if ('0' <= c && c <= '9') return c - '0' + 1 + find_base64_char_index('z');
44+
else if (c == '+') return 1 + find_base64_char_index('9');
45+
else if (c == '/') return 1 + find_base64_char_index('+');
46+
else return 1 + find_base64_char_index('/');
47+
}
48+
49+
string toBase64Encoding(bytesConstRef _in, char const* _base64_chars, bool _pad)
50+
{
51+
string ret;
52+
int i = 0;
53+
int j = 0;
54+
byte char_array_3[3];
55+
byte char_array_4[4];
56+
57+
auto buf = _in.data();
58+
auto bufLen = _in.size();
59+
60+
while (bufLen--)
61+
{
62+
char_array_3[i++] = *(buf++);
63+
if (i == 3)
64+
{
65+
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
66+
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
67+
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
68+
char_array_4[3] = char_array_3[2] & 0x3f;
69+
70+
for (i = 0; i < 4; i++)
71+
ret += _base64_chars[char_array_4[i]];
72+
i = 0;
73+
}
74+
}
75+
76+
if (i)
77+
{
78+
for (j = i; j < 3; j++)
79+
char_array_3[j] = '\0';
80+
81+
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
82+
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
83+
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
84+
char_array_4[3] = char_array_3[2] & 0x3f;
85+
86+
for (j = 0; j < i + 1; j++)
87+
ret += _base64_chars[char_array_4[j]];
88+
89+
while (i++ < 3 && _pad)
90+
ret += '=';
91+
}
92+
93+
return ret;
4794
}
4895

4996
string dev::toBase64(bytesConstRef _in)
5097
{
51-
static const char base64_chars[] =
52-
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
53-
"abcdefghijklmnopqrstuvwxyz"
54-
"0123456789+/";
55-
56-
string ret;
57-
int i = 0;
58-
int j = 0;
59-
byte char_array_3[3];
60-
byte char_array_4[4];
61-
62-
auto buf = _in.data();
63-
auto bufLen = _in.size();
64-
65-
while (bufLen--)
66-
{
67-
char_array_3[i++] = *(buf++);
68-
if (i == 3)
69-
{
70-
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
71-
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
72-
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
73-
char_array_4[3] = char_array_3[2] & 0x3f;
74-
75-
for (i = 0; i < 4; i++)
76-
ret += base64_chars[char_array_4[i]];
77-
i = 0;
78-
}
79-
}
80-
81-
if (i)
82-
{
83-
for (j = i; j < 3; j++)
84-
char_array_3[j] = '\0';
85-
86-
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
87-
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
88-
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
89-
char_array_4[3] = char_array_3[2] & 0x3f;
90-
91-
for (j = 0; j < i + 1; j++)
92-
ret += base64_chars[char_array_4[j]];
93-
94-
while (i++ < 3)
95-
ret += '=';
96-
}
97-
98-
return ret;
98+
static char const c_base64_chars[] =
99+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
100+
"abcdefghijklmnopqrstuvwxyz"
101+
"0123456789+/";
102+
bool const pad = true;
103+
return toBase64Encoding(_in, c_base64_chars, pad);
104+
}
105+
106+
string dev::toBase64URLSafe(bytesConstRef _in)
107+
{
108+
static char const c_base64_chars[] =
109+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
110+
"abcdefghijklmnopqrstuvwxyz"
111+
"0123456789-_";
112+
bool const pad = false;
113+
return toBase64Encoding(_in, c_base64_chars, pad);
99114
}
100115

101116
bytes dev::fromBase64(string const& encoded_string)
102117
{
103-
auto in_len = encoded_string.size();
104-
int i = 0;
105-
int j = 0;
106-
int in_ = 0;
107-
byte char_array_3[3];
108-
byte char_array_4[4];
109-
bytes ret;
110-
111-
while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_]))
112-
{
113-
char_array_4[i++] = encoded_string[in_]; in_++;
114-
if (i == 4)
115-
{
116-
for (i = 0; i < 4; i++)
117-
char_array_4[i] = find_base64_char_index(char_array_4[i]);
118-
119-
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
120-
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
121-
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
122-
123-
for (i = 0; (i < 3); i++)
124-
ret.push_back(char_array_3[i]);
125-
i = 0;
126-
}
127-
}
128-
129-
if (i)
130-
{
131-
for (j = i; j < 4; j++)
132-
char_array_4[j] = 0;
133-
134-
for (j = 0; j < 4; j++)
135-
char_array_4[j] = find_base64_char_index(char_array_4[j]);
136-
137-
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
138-
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
139-
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
140-
141-
for (j = 0; j < i - 1; j++)
142-
ret.push_back(char_array_3[j]);
143-
}
144-
145-
return ret;
118+
auto in_len = encoded_string.size();
119+
int i = 0;
120+
int j = 0;
121+
int in_ = 0;
122+
byte char_array_3[3];
123+
byte char_array_4[4];
124+
bytes ret;
125+
126+
while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_]))
127+
{
128+
char_array_4[i++] = encoded_string[in_]; in_++;
129+
if (i == 4)
130+
{
131+
for (i = 0; i < 4; i++)
132+
char_array_4[i] = find_base64_char_index(char_array_4[i]);
133+
134+
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
135+
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
136+
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
137+
138+
for (i = 0; (i < 3); i++)
139+
ret.push_back(char_array_3[i]);
140+
i = 0;
141+
}
142+
}
143+
144+
if (i)
145+
{
146+
for (j = i; j < 4; j++)
147+
char_array_4[j] = 0;
148+
149+
for (j = 0; j < 4; j++)
150+
char_array_4[j] = find_base64_char_index(char_array_4[j]);
151+
152+
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
153+
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
154+
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
155+
156+
for (j = 0; j < i - 1; j++)
157+
ret.push_back(char_array_3[j]);
158+
}
159+
160+
return ret;
146161
}

libdevcore/Base64.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
freely, subject to the following restrictions:
1313
1414
1. The origin of this source code must not be misrepresented; you must not
15-
claim that you wrote the original source code. If you use this source code
16-
in a product, an acknowledgment in the product documentation would be
17-
appreciated but is not required.
15+
claim that you wrote the original source code. If you use this source code
16+
in a product, an acknowledgment in the product documentation would be
17+
appreciated but is not required.
1818
1919
2. Altered source versions must be plainly marked as such, and must not be
20-
misrepresented as being the original source code.
20+
misrepresented as being the original source code.
2121
2222
3. This notice may not be removed or altered from any source distribution.
2323
@@ -28,13 +28,13 @@
2828
/// DEVified by Gav Wood.
2929
#pragma once
3030

31-
#include <string>
3231
#include "FixedHash.h"
32+
#include <string>
3333

3434
namespace dev
3535
{
36-
3736
std::string toBase64(bytesConstRef _in);
37+
std::string toBase64URLSafe(bytesConstRef _in);
3838
bytes fromBase64(std::string const& _in);
3939

40-
}
40+
} // namespace dev

libp2p/ENR.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Licensed under the GNU General Public License, Version 3.
44

55
#include "ENR.h"
6+
#include <libdevcore/Base64.h>
67
#include <libdevcore/SHA3.h>
78

89
namespace dev
@@ -279,5 +280,12 @@ std::ostream& operator<<(std::ostream& _out, ENR const& _enr)
279280
return _out;
280281
}
281282

283+
std::string ENR::textEncoding() const
284+
{
285+
RLPStream s;
286+
streamRLP(s);
287+
return ("enr:" + toBase64URLSafe(ref(s.out())));
288+
}
289+
282290
} // namespace p2p
283291
} // namespace dev

libp2p/ENR.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class ENR
5656
ENR update(
5757
std::map<std::string, bytes> const& _keyValuePair, SignFunction const& _signFunction) const;
5858

59+
std::string textEncoding() const;
60+
5961
private:
6062
uint64_t m_seq = 0;
6163
std::map<std::string, bytes> m_keyValuePairs;

libp2p/Host.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,16 @@ class ReputationManager
8989
struct NodeInfo
9090
{
9191
NodeInfo() = default;
92-
NodeInfo(NodeID const& _id, std::string const& _address, unsigned _port, std::string const& _version):
93-
id(_id), address(_address), port(_port), version(_version) {}
92+
NodeInfo(NodeID const& _id, std::string const& _address, unsigned _port, std::string const& _version, std::string const& _enr):
93+
id(_id), address(_address), port(_port), version(_version), enr(_enr) {}
9494

9595
std::string enode() const { return "enode://" + id.hex() + "@" + address + ":" + toString(port); }
9696

9797
NodeID id;
9898
std::string address;
9999
unsigned port;
100100
std::string version;
101+
std::string enr;
101102
};
102103

103104
/**
@@ -240,7 +241,14 @@ class Host: public Worker
240241
}
241242

242243
/// Get the node information.
243-
p2p::NodeInfo nodeInfo() const { return NodeInfo(id(), (networkConfig().publicIPAddress.empty() ? m_tcpPublic.address().to_string() : networkConfig().publicIPAddress), m_tcpPublic.port(), m_clientVersion); }
244+
p2p::NodeInfo nodeInfo() const
245+
{
246+
auto const e = enr();
247+
return NodeInfo(id(),
248+
(networkConfig().publicIPAddress.empty() ? m_tcpPublic.address().to_string() :
249+
networkConfig().publicIPAddress),
250+
m_tcpPublic.port(), m_clientVersion, e.textEncoding());
251+
}
244252

245253
/// Get Ethereum Node Record of the host
246254
ENR enr() const

libweb3jsonrpc/AdminNet.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Json::Value AdminNet::admin_net_nodeInfo(std::string const& _session)
3535
ret["listenAddr"] = i.address + ":" + toString(i.port);
3636
ret["id"] = i.id.hex();
3737
ret["enode"] = i.enode();
38+
ret["enr"] = i.enr;
3839
return ret;
3940
}
4041

@@ -51,6 +52,7 @@ Json::Value AdminNet::admin_nodeInfo()
5152
ret["listenAddr"] = i.address + ":" + toString(i.port);
5253
ret["id"] = i.id.hex();
5354
ret["enode"] = i.enode();
55+
ret["enr"] = i.enr;
5456
ret["protocols"] = Json::objectValue;
5557
ret["protocols"]["eth"] = Json::objectValue; //@todo fill with information
5658
return ret;

test/unittests/libp2p/ENRTest.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ TEST(enr, parse)
3030
"/oxVtw0RW/QAdpzBQA8yWM0xOIN1ZHCCdl8=");
3131
ENR enr = IdentitySchemeV4::parseENR(RLP{rlp});
3232

33+
EXPECT_EQ(enr.textEncoding(),
34+
"enr:-"
35+
"IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5w"
36+
"BgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8");
3337
EXPECT_EQ(enr.signature(),
3438
fromHex("7098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f3"
3539
"0813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c"));

0 commit comments

Comments
 (0)