public void TestAddOutdated() { NodeAddressCollection addressCollection = new NodeAddressCollection(); NodeAddress address1 = new NodeAddress(IPAddress.Parse("192.168.0.1"), 8333); NodeAddress address2 = new NodeAddress(IPAddress.Parse("192.168.0.2"), 8333); DateTime baseDate = DateTime.UtcNow; addressCollection.Add(address1); addressCollection.Add(address2); addressCollection.Reject(address1); addressCollection.Reject(address2); Assert.That(addressCollection.GetNewestUntested(10), Is.EqualTo(new List<NodeAddress>())); Assert.That(addressCollection.GetOldestRejected(10), Is.EqualTo(new List<NodeAddress> {address1, address2})); SystemTime.Override(baseDate.AddMonths(1)); addressCollection.Add(address2); Assert.That(addressCollection.GetNewestUntested(10), Is.EqualTo(new List<NodeAddress> {address2})); Assert.That(addressCollection.GetOldestRejected(10), Is.EqualTo(new List<NodeAddress>())); }
public void TestBannedTransitions() { NodeAddressCollection addressCollection = new NodeAddressCollection(); NodeAddress address0 = new NodeAddress(IPAddress.Parse("192.168.0.9"), 8333); NodeAddress address1 = new NodeAddress(IPAddress.Parse("192.168.0.1"), 8333); NodeAddress address2 = new NodeAddress(IPAddress.Parse("192.168.0.2"), 8333); NodeAddress address3 = new NodeAddress(IPAddress.Parse("192.168.0.3"), 8333); NodeAddress address4 = new NodeAddress(IPAddress.Parse("192.168.0.4"), 8333); addressCollection.Add(address0); addressCollection.Add(address1); addressCollection.Add(address2); addressCollection.Add(address3); addressCollection.Add(address4); addressCollection.Ban(address0); addressCollection.Ban(address1); addressCollection.Ban(address2); addressCollection.Ban(address3); addressCollection.Ban(address4); Assert.That(addressCollection.GetNewestBanned(10), Is.EqualTo(new List<NodeAddress> {address4, address3, address2, address1, address0})); addressCollection.Add(address1); addressCollection.Reject(address2); addressCollection.Ban(address3); addressCollection.Confirm(address4); Assert.That(addressCollection.GetNewestUntested(10), Is.EqualTo(new List<NodeAddress>())); Assert.That(addressCollection.GetOldestRejected(10), Is.EqualTo(new List<NodeAddress>())); Assert.That(addressCollection.GetNewestBanned(10), Is.EqualTo(new List<NodeAddress> {address3, address4, address2, address1, address0})); Assert.That(addressCollection.GetNewestConfirmed(10), Is.EqualTo(new List<NodeAddress>())); Assert.That(addressCollection.GetOldestTemporaryRejected(10), Is.EqualTo(new List<NodeAddress>())); }
public void Add(NodeAddress address) { lock (lockObject) { if (!rejected.ContainsKey(address) && !banned.ContainsKey(address) && !confirmed.ContainsKey(address) && !temporaryRejected.ContainsKey(address)) { untested.Add(address); } } }
public void Ban(NodeAddress address) { lock (lockObject) { untested.Remove(address); rejected.Remove(address); confirmed.Remove(address); temporaryRejected.Remove(address); banned.Add(address); } }
public void Add(NodeAddress address) { DateTime now = SystemTime.UtcNow; addresses.Remove(address); FixFutureDates(now); addresses.Add(address, now); Truncate(now); }
public void Confirm(NodeAddress address) { lock (lockObject) { if (banned.ContainsKey(address)) { return; } untested.Remove(address); rejected.Remove(address); temporaryRejected.Remove(address); confirmed.Add(address); } }
public void Reject(NodeAddress address) { lock (lockObject) { if (confirmed.Remove(address) || temporaryRejected.Remove(address)) { temporaryRejected.Add(address); } else if (banned.ContainsKey(address)) { // do nothing } else { untested.Remove(address); rejected.Remove(address); rejected.Add(address); } } }
public bool Remove(NodeAddress address) { return addresses.Remove(address); }
public bool ContainsKey(NodeAddress address) { Truncate(SystemTime.UtcNow); return addresses.ContainsKey(address); }
public void ConnectTo(NodeAddress address) { if (cancellationTokenSource.IsCancellationRequested) { return; } //todo: The construction of BitcoinEndpoint and BitcoinConnection is confusing. Both can use host and port. BitcoinEndpoint endpoint = new BitcoinEndpoint(HandleMessage); try { endpoint.Connect(address.Address.ToString(), address.Port); } catch (BitcoinNetworkException) { addressCollection.Reject(address); //todo: log error? return; } //todo: check nonce to avoid connection to self //todo: check if peer is banned //todo: send ping messages to check if connection is alive if ((endpoint.PeerInfo.VersionMessage.Services & VersionMessage.ServiceNodeNetwork) == 0) { // outgoing connections ignore non-full nodes addressCollection.Reject(address); endpoint.Dispose(); return; } addressCollection.Confirm(address); if (!connectionCollection.Add(NodeConnectionDirection.Outgoing, endpoint)) { endpoint.Dispose(); return; } services.OnNodeConnected(endpoint); //todo: make sure that OnNodeConnected is always called before OnNodeDisconnected and before message processing endpoint.Disconnected += () => services.OnNodeDisconnected(endpoint); }
protected bool Equals(NodeAddress other) { return Equals(address, other.address) && port == other.port; }