Skip to content

Commit 64051ef

Browse files
committed
Improve ENR equality logic
1 parent 61333bb commit 64051ef

139 files changed

Lines changed: 192 additions & 157 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Lantern.Discv5.Enr/Base64Url.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ public static byte[] ToBytes(string input)
2727
}
2828
return Convert.FromBase64String(sb.ToString());
2929
}
30-
}
30+
}

src/Lantern.Discv5.Enr/Enr.cs

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Lantern.Discv5.Enr.Entries;
1+
using Lantern.Discv5.Enr.Entries;
22
using Lantern.Discv5.Enr.Identity;
33
using Lantern.Discv5.Rlp;
44
using Multiformats.Base;
@@ -8,13 +8,14 @@ namespace Lantern.Discv5.Enr;
88

99
public class Enr : IEnr, IEquatable<IEnr>
1010
{
11-
private readonly IDictionary<string, IEntry> _entries;
11+
private readonly Dictionary<string, IEntry> _entries;
1212
private readonly IIdentitySigner? _signer;
1313
private readonly IIdentityVerifier? _verifier;
1414
private byte[]? _cachedNodeId;
15+
private int? _cachedHashCode;
1516

1617
public Enr(
17-
IDictionary<string, IEntry> initialEntries,
18+
Dictionary<string, IEntry> initialEntries,
1819
IIdentityVerifier verifier,
1920
IIdentitySigner? signer = null,
2021
byte[]? signature = null,
@@ -51,20 +52,12 @@ public byte[] NodeId
5152
}
5253

5354
public T GetEntry<T>(string key, T defaultValue = default!) where T : IEntry
54-
{
55-
var entry = _entries.Values.FirstOrDefault(e => e.Key == key);
56-
57-
return entry is T result ? result : defaultValue;
58-
}
55+
=> _entries.TryGetValue(key, out var entry) && entry is T result ? result : defaultValue;
5956

6057
public void UpdateEntry<T>(T value) where T : class, IEntry
6158
{
62-
foreach (var existingKey in _entries.Where(entry => entry.Value.Key.Equals(value.Key)).ToList())
63-
{
64-
_entries.Remove(existingKey.Key);
65-
}
66-
67-
_entries[value.Key] = value;
59+
string key = value.Key;
60+
_entries[key] = value;
6861
IncrementSequenceNumber();
6962
}
7063

@@ -104,20 +97,45 @@ public bool Equals(IEnr? other)
10497
return other != null && NodeId.AsSpan().SequenceEqual(other.NodeId.AsSpan());
10598
}
10699

100+
public override bool Equals(object? obj)
101+
{
102+
return obj is IEnr other && Equals(other);
103+
}
104+
105+
public override int GetHashCode()
106+
{
107+
if (_cachedHashCode.HasValue)
108+
return _cachedHashCode.Value;
109+
110+
var nodeId = NodeId;
111+
var hash = new HashCode();
112+
113+
foreach (var b in nodeId)
114+
{
115+
hash.Add(b);
116+
}
117+
118+
_cachedHashCode = hash.ToHashCode();
119+
return _cachedHashCode.Value;
120+
}
121+
107122
public override string ToString()
108123
{
109124
return $"enr:{Base64Url.ToString(EncodeRecord())}";
110125
}
111126

112127
public string ToEnode()
113128
{
114-
if (Signature == null)
115-
throw new InvalidOperationException("Signature must be set before encoding.");
129+
var publicKey = GetEntry<EntrySecp256K1>(EnrEntryKey.Secp256K1).Value;
130+
if (publicKey == null)
131+
throw new InvalidOperationException("Public key must be present in ENR for enode format.");
132+
133+
var publicKeyHex = Convert.ToHexString(publicKey).ToLower();
116134

117135
if (!HasKey(EnrEntryKey.Tcp))
118-
return $"enode://{Convert.ToHexString(Signature).ToLower()}@{GetEntry<EntryIp>(EnrEntryKey.Ip).Value}?discport={GetEntry<EntryUdp>(EnrEntryKey.Udp).Value}";
136+
return $"enode://{publicKeyHex}@{GetEntry<EntryIp>(EnrEntryKey.Ip).Value}?discport={GetEntry<EntryUdp>(EnrEntryKey.Udp).Value}";
119137

120-
return $"enode://{Convert.ToHexString(Signature).ToLower()}@{GetEntry<EntryIp>(EnrEntryKey.Ip).Value}:{GetEntry<EntryTcp>(EnrEntryKey.Tcp).Value}?discport={GetEntry<EntryUdp>(EnrEntryKey.Udp).Value}";
138+
return $"enode://{publicKeyHex}@{GetEntry<EntryIp>(EnrEntryKey.Ip).Value}:{GetEntry<EntryTcp>(EnrEntryKey.Tcp).Value}?discport={GetEntry<EntryUdp>(EnrEntryKey.Udp).Value}";
121139
}
122140

123141
public string ToPeerId()
@@ -143,4 +161,4 @@ private byte[] EncodeEnrContent()
143161
.SelectMany(e => e.Value.EncodeEntry())
144162
.ToArray();
145163
}
146-
}
164+
}

src/Lantern.Discv5.Enr/EnrConstants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ public static class EnrConstants
55
public const int EnrPrefixLength = 4;
66

77
public static readonly byte[] ProtoBufferPrefix = { 0x08, 0x02, 0x12, 0x21 };
8-
}
8+
}

src/Lantern.Discv5.Enr/EnrEntryKey.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ public record EnrEntryKey(string Value)
1616

1717
public static implicit operator string(EnrEntryKey key) => key.Value;
1818
public static implicit operator EnrEntryKey(string key) => new(key);
19-
}
19+
}

src/Lantern.Discv5.Enr/EnrEntryRegistry.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,4 @@ private void RegisterDefaultEntries()
5959
RegisterEntry(entry.Item1, entry.Item2);
6060
}
6161
}
62-
}
62+
}

src/Lantern.Discv5.Enr/Entries/EntryAttnets.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ public IEnumerable<byte> EncodeEntry()
1414
return ByteArrayUtils.JoinByteArrays(RlpEncoder.EncodeString(Key, Encoding.ASCII),
1515
RlpEncoder.EncodeBytes(Value));
1616
}
17-
}
17+
}

src/Lantern.Discv5.Enr/Entries/EntryEth2.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ public IEnumerable<byte> EncodeEntry()
1414
return ByteArrayUtils.JoinByteArrays(RlpEncoder.EncodeString(Key, Encoding.ASCII),
1515
RlpEncoder.EncodeBytes(Value));
1616
}
17-
}
17+
}

src/Lantern.Discv5.Enr/Entries/EntryId.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ public IEnumerable<byte> EncodeEntry()
1414
return ByteArrayUtils.JoinByteArrays(RlpEncoder.EncodeString(Key, Encoding.ASCII),
1515
RlpEncoder.EncodeString(Value, Encoding.ASCII));
1616
}
17-
}
17+
}

src/Lantern.Discv5.Enr/Entries/EntryIp.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ public IEnumerable<byte> EncodeEntry()
1515
return ByteArrayUtils.JoinByteArrays(RlpEncoder.EncodeString(Key, Encoding.ASCII),
1616
RlpEncoder.EncodeBytes(Value.GetAddressBytes()));
1717
}
18-
}
18+
}

src/Lantern.Discv5.Enr/Entries/EntryIp6.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ public IEnumerable<byte> EncodeEntry()
1515
return ByteArrayUtils.JoinByteArrays(RlpEncoder.EncodeString(Key, Encoding.ASCII),
1616
RlpEncoder.EncodeBytes(Value.GetAddressBytes()));
1717
}
18-
}
18+
}

0 commit comments

Comments
 (0)