internal NodeConnectionParameters CreateNodeConnectionParameters() { IPEndPoint myExternal = Utils.EnsureIPv6(this.ExternalEndpoint); NodeConnectionParameters param2 = this.InboundNodeConnectionParameters.Clone(); param2.Nonce = this.Nonce; param2.Version = this.Version; param2.AddressFrom = myExternal; return(param2); }
public static Node Connect(NetworkInfo network, IPEndPoint endpoint, NodeConnectionParameters parameters) { var peer = new NetworkAddress() { Time = DateTimeOffset.UtcNow, Endpoint = endpoint }; return(new Node(peer, network, parameters)); }
private void InitDefaultBehaviors(NodeConnectionParameters parameters) { IsTrusted = parameters.IsTrusted != null ? parameters.IsTrusted.Value : Peer.Endpoint.Address.IsLocal(); // Advertize = parameters.Advertize; // PreferredTransactionOptions = parameters.PreferredTransactionOptions; _ReuseBuffer = parameters.ReuseBuffer; _Behaviors.DelayAttach = true; foreach (var behavior in parameters.TemplateBehaviors) { _Behaviors.Add(behavior.Clone()); } _Behaviors.DelayAttach = false; }
public NodesGroup( Network network, NodeConnectionParameters connectionParameters = null, NodeRequirement requirements = null) { AllowSameGroup = false; MaximumNodeConnection = 8; _Network = network; cs = new object(); _ConnectedNodes = new NodesCollection(); _ConnectionParameters = connectionParameters ?? new NodeConnectionParameters(); _ConnectionParameters = _ConnectionParameters.Clone(); _Requirements = requirements ?? new NodeRequirement(); _Disconnect = new CancellationTokenSource(); }
public NodeConnectionParameters(NodeConnectionParameters other) { Version = other.Version; IsRelay = other.IsRelay; Services = other.Services; ConnectCancellation = other.ConnectCancellation; UserAgent = other.UserAgent; AddressFrom = other.AddressFrom; Nonce = other.Nonce; Advertize = other.Advertize; PreferredTransactionOptions = other.PreferredTransactionOptions; EndpointConnector = other.EndpointConnector.Clone(); SocketSettings = other.SocketSettings.Clone(); foreach (var behavior in other.TemplateBehaviors) { TemplateBehaviors.Add(behavior.Clone()); } }
public NodeConnectionParameters(NodeConnectionParameters other) { Version = other.Version; IsRelay = other.IsRelay; Services = other.Services; ReceiveBufferSize = other.ReceiveBufferSize; SendBufferSize = other.SendBufferSize; ConnectCancellation = other.ConnectCancellation; UserAgent = other.UserAgent; AddressFrom = other.AddressFrom; Nonce = other.Nonce; Advertize = other.Advertize; PreferredTransactionOptions = other.PreferredTransactionOptions; foreach (var behavior in other.TemplateBehaviors) { TemplateBehaviors.Add(behavior.Clone()); } }
public NodeServer(Network network, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION, int internalPort = -1) { AllowLocalPeers = true; InboundNodeConnectionParameters = new NodeConnectionParameters(); internalPort = internalPort == -1 ? network.DefaultPort : internalPort; _LocalEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6Ex(), internalPort); _Network = network; _ExternalEndpoint = new IPEndPoint(_LocalEndpoint.Address, Network.DefaultPort); _Version = version; var listener = new EventLoopMessageListener<IncomingMessage>(ProcessMessage); _MessageProducer.AddMessageListener(listener); OwnResource(listener); _ConnectedNodes = new NodesCollection(); _ConnectedNodes.Added += _Nodes_NodeAdded; _ConnectedNodes.Removed += _Nodes_NodeRemoved; _ConnectedNodes.MessageProducer.AddMessageListener(listener); _Trace = new TraceCorrelation(NodeServerTrace.Trace, "Node server listening on " + LocalEndpoint); }
public NodeServer(NetworkInfo network, ProtocolVersion version = ProtocolVersion.PROTOCOL_VERSION, int internalPort = -1) { AllowLocalPeers = true; InboundNodeConnectionParameters = new NodeConnectionParameters(); internalPort = internalPort == -1 ? network.DefaultPort : internalPort; _LocalEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6Ex(), internalPort); _Network = network; //_ExternalEndpoint = new IPEndPoint(_LocalEndpoint.Address, Network.DefaultPort); //TODO _Version = version; var listener = new EventLoopMessageListener <IncomingMessage>(ProcessMessage); _MessageProducer.AddMessageListener(listener); OwnResource(listener); _ConnectedNodes = new NodesCollection(); _ConnectedNodes.Added += _Nodes_NodeAdded; _ConnectedNodes.Removed += _Nodes_NodeRemoved; _ConnectedNodes.MessageProducer.AddMessageListener(listener); _Trace = new TraceCorrelation(NodeServerTrace.Trace, "Node server listening on " + LocalEndpoint); }
public NodeConnectionParameters(NodeConnectionParameters other) { Version = other.Version; IsRelay = other.IsRelay; Services = other.Services; ReceiveBufferSize = other.ReceiveBufferSize; SendBufferSize = other.SendBufferSize; ConnectCancellation = other.ConnectCancellation; UserAgent = other.UserAgent; AddressFrom = other.AddressFrom; IsTrusted = other.IsTrusted; Nonce = other.Nonce; Advertize = other.Advertize; ReuseBuffer = other.ReuseBuffer; foreach (var behavior in other.TemplateBehaviors) { TemplateBehaviors.Add((NodeBehavior)((ICloneable)behavior).Clone()); } }
public NodeServer(Network network, uint?version = null, int internalPort = -1) { AllowLocalPeers = true; InboundNodeConnectionParameters = new NodeConnectionParameters(); internalPort = internalPort == -1 ? network.DefaultPort : internalPort; _LocalEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0").MapToIPv6Ex(), internalPort); MaxConnections = 125; _Network = network; _ExternalEndpoint = new IPEndPoint(_LocalEndpoint.Address, Network.DefaultPort); _Version = version == null ? network.MaxP2PVersion : version.Value; var listener = new EventLoopMessageListener <IncomingMessage>(ProcessMessage); _MessageProducer.AddMessageListener(listener); OwnResource(listener); _ConnectedNodes = new NodesCollection(); _ConnectedNodes.Added += _Nodes_NodeAdded; _ConnectedNodes.Removed += _Nodes_NodeRemoved; _ConnectedNodes.MessageProducer.AddMessageListener(listener); }
public NodeConnectionParameters(NodeConnectionParameters other) { Version = other.Version; IsRelay = other.IsRelay; Services = other.Services; ReceiveBufferSize = other.ReceiveBufferSize; SendBufferSize = other.SendBufferSize; ConnectCancellation = other.ConnectCancellation; UserAgent = other.UserAgent; AddressFrom = other.AddressFrom; IsTrusted = other.IsTrusted; Nonce = other.Nonce; Advertize = other.Advertize; ReuseBuffer = other.ReuseBuffer; foreach(var behavior in other.TemplateBehaviors) { TemplateBehaviors.Add((NodeBehavior)((ICloneable)behavior).Clone()); } }
public NodeConnectionParameters(NodeConnectionParameters other) { this.Version = other.Version; this.IsRelay = other.IsRelay; this.Services = other.Services; this.ReceiveBufferSize = other.ReceiveBufferSize; this.SendBufferSize = other.SendBufferSize; this.ConnectCancellation = other.ConnectCancellation; this.UserAgent = other.UserAgent; this.AddressFrom = other.AddressFrom; this.Nonce = other.Nonce; this.Advertize = other.Advertize; this.ReuseBuffer = other.ReuseBuffer; this.PreferredTransactionOptions = other.PreferredTransactionOptions; foreach (INodeBehavior behavior in other.TemplateBehaviors) { this.TemplateBehaviors.Add(behavior.Clone()); } }
internal Node(NetworkAddress peer, NetworkInfo network, NodeConnectionParameters parameters, Socket socket, VersionPayload peerVersion) { _RemoteSocketAddress = ((IPEndPoint)socket.RemoteEndPoint).Address; _RemoteSocketPort = ((IPEndPoint)socket.RemoteEndPoint).Port; Inbound = true; _Behaviors = new NodeBehaviorsCollection(this); _MyVersion = parameters.CreateVersion(peer.Endpoint, network); Network = network; _Peer = peer; _Connection = new NodeConnection(this, socket); _PeerVersion = peerVersion; LastSeen = peer.Time; ConnectedAt = DateTimeOffset.UtcNow; TraceCorrelation.LogInside(() => { NodeServerTrace.Information("Connected to advertised node " + _Peer.Endpoint); State = NodeState.Connected; }); InitDefaultBehaviors(parameters); _Connection.BeginListen(); }
/// <summary> /// Connect to a random node on the network /// </summary> /// <param name="network">The network to connect to</param> /// <param name="addrman">The addrman used for finding peers</param> /// <param name="parameters">The parameters used by the found node</param> /// <param name="connectedAddresses">The already connected addresses, the new address will be select outside of existing groups</param> /// <returns></returns> public static Node Connect(NetworkInfo network, AddressManager addrman, NodeConnectionParameters parameters = null, IPAddress[] connectedAddresses = null) { parameters = parameters ?? new NodeConnectionParameters(); AddressManagerBehavior.SetAddrman(parameters, addrman); return(Connect(network, parameters, connectedAddresses)); }
public static NodesGroup GetNodeGroup(NodeConnectionParameters parameters) { return(GetNodeGroup(parameters.TemplateBehaviors)); }
/// <summary> /// Connect to the node of this machine /// </summary> /// <param name="network"></param> /// <param name="parameters"></param> /// <returns></returns> public static Node ConnectToLocal(NetworkInfo network, NodeConnectionParameters parameters) { return(Connect(network, Utils.ParseIpEndpoint("localhost", network.DefaultPort), parameters)); }
internal Node(NetworkAddress peer, NetworkInfo network, NodeConnectionParameters parameters) { parameters = parameters ?? new NodeConnectionParameters(); var addrman = AddressManagerBehavior.GetAddrman(parameters); Inbound = false; _Behaviors = new NodeBehaviorsCollection(this); _MyVersion = parameters.CreateVersion(peer.Endpoint, network); Network = network; _Peer = peer; LastSeen = peer.Time; var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); _Connection = new NodeConnection(this, socket); socket.ReceiveBufferSize = parameters.ReceiveBufferSize; socket.SendBufferSize = parameters.SendBufferSize; using (TraceCorrelation.Open()) { try { var completed = new ManualResetEvent(false); var args = new SocketAsyncEventArgs(); args.RemoteEndPoint = peer.Endpoint; args.Completed += (s, a) => { Utils.SafeSet(completed); }; if (!socket.ConnectAsync(args)) { completed.Set(); } WaitHandle.WaitAny(new WaitHandle[] { completed, parameters.ConnectCancellation.WaitHandle }); parameters.ConnectCancellation.ThrowIfCancellationRequested(); if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } var remoteEndpoint = (IPEndPoint)(socket.RemoteEndPoint ?? args.RemoteEndPoint); _RemoteSocketAddress = remoteEndpoint.Address; _RemoteSocketPort = remoteEndpoint.Port; State = NodeState.Connected; ConnectedAt = DateTimeOffset.UtcNow; NodeServerTrace.Information("Outbound connection successfull"); if (addrman != null) { addrman.Attempt(Peer); } } catch (OperationCanceledException) { Utils.SafeCloseSocket(socket); NodeServerTrace.Information("Connection to node cancelled"); State = NodeState.Offline; if (addrman != null) { addrman.Attempt(Peer); } throw; } catch (Exception ex) { Utils.SafeCloseSocket(socket); NodeServerTrace.Error("Error connecting to the remote endpoint ", ex); DisconnectReason = new NodeDisconnectReason() { Reason = "Unexpected exception while connecting to socket", Exception = ex }; State = NodeState.Failed; if (addrman != null) { addrman.Attempt(Peer); } throw; } InitDefaultBehaviors(parameters); _Connection.BeginListen(); } }
private static NodesGroup CreateGroup(NodeServerTester servers, int connections) { AddressManagerBehavior behavior = new AddressManagerBehavior(new AddressManager()); if(connections == 1) { behavior.AddressManager.Add(new NetworkAddress(servers.Server1.ExternalEndpoint), IPAddress.Parse("127.0.0.1")); } if(connections > 1) { behavior.AddressManager.Add(new NetworkAddress(servers.Server2.ExternalEndpoint), IPAddress.Parse("127.0.0.1")); } NodeConnectionParameters parameters = new NodeConnectionParameters(); parameters.TemplateBehaviors.Add(behavior); Wallet.ConfigureDefaultNodeConnectionParameters(parameters); parameters.IsTrusted = true; NodesGroup connected = new NodesGroup(Network.TestNet, parameters); connected.AllowSameGroup = true; connected.MaximumNodeConnection = connections; return connected; }
public void CanMaintainConnectionToNodes() { using(NodeServerTester servers = new NodeServerTester(Network.TestNet)) { servers.Server1.InboundNodeConnectionParameters.Services = NodeServices.Network; AddressManagerBehavior behavior = new AddressManagerBehavior(new AddressManager()); behavior.AddressManager.Add(new NetworkAddress(servers.Server1.ExternalEndpoint), IPAddress.Parse("127.0.0.1")); NodeConnectionParameters parameters = new NodeConnectionParameters(); parameters.TemplateBehaviors.Add(behavior); NodesGroup connected = new NodesGroup(Network.TestNet, parameters, new NodeRequirement() { RequiredServices = NodeServices.Network }); connected.AllowSameGroup = true; connected.MaximumNodeConnection = 2; connected.Connect(); TestUtils.Eventually(() => connected.ConnectedNodes.Count == 2); //Server crash abruptly servers.Server1.ConnectedNodes.First().Disconnect(); TestUtils.Eventually(() => connected.ConnectedNodes.Count == 1); //Reconnect ? TestUtils.Eventually(() => connected.ConnectedNodes.Count == 2); //Client crash abruptly connected.ConnectedNodes.First().Disconnect(); TestUtils.Eventually(() => connected.ConnectedNodes.Count == 1); //Reconnect ? TestUtils.Eventually(() => connected.ConnectedNodes.Count == 2); } }
public static Node Connect(NetworkInfo network, NetworkAddress endpoint, NodeConnectionParameters parameters) { return(new Node(endpoint, network, parameters)); }
internal void DiscoverPeers(Network network, NodeConnectionParameters parameters, int peerToFind) { TimeSpan backoff = TimeSpan.Zero; Logs.NodeServer.LogTrace("Discovering nodes"); int found = 0; { while (found < peerToFind) { Thread.Sleep(backoff); backoff = backoff == TimeSpan.Zero ? TimeSpan.FromSeconds(1.0) : TimeSpan.FromSeconds(backoff.TotalSeconds * 2); if (backoff > TimeSpan.FromSeconds(10.0)) { backoff = TimeSpan.FromSeconds(10.0); } parameters.ConnectCancellation.ThrowIfCancellationRequested(); Logs.NodeServer.LogTrace("Remaining peer to get {remainingPeerCount}", (-found + peerToFind)); List <NetworkAddress> peers = new List <NetworkAddress>(); peers.AddRange(this.GetAddr()); if (peers.Count == 0) { PopulateTableWithDNSNodes(network, peers).GetAwaiter().GetResult(); PopulateTableWithHardNodes(network, peers); peers = new List <NetworkAddress>(peers.OrderBy(a => RandomUtils.GetInt32())); if (peers.Count == 0) { return; } } CancellationTokenSource peerTableFull = new CancellationTokenSource(); CancellationToken loopCancel = CancellationTokenSource.CreateLinkedTokenSource(peerTableFull.Token, parameters.ConnectCancellation).Token; try { Parallel.ForEach(peers, new ParallelOptions() { MaxDegreeOfParallelism = 5, CancellationToken = loopCancel, }, p => { using (CancellationTokenSource timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5))) using (var cancelConnection = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, loopCancel)) { Node n = null; try { var param2 = parameters.Clone(); param2.ConnectCancellation = cancelConnection.Token; var addrman = param2.TemplateBehaviors.Find <AddressManagerBehavior>(); param2.TemplateBehaviors.Clear(); param2.TemplateBehaviors.Add(addrman); n = Node.Connect(network, p.Endpoint, param2); n.VersionHandshake(cancelConnection.Token); n.MessageReceived += (s, a) => { var addr = (a.Message.Payload as AddrPayload); if (addr != null) { Interlocked.Add(ref found, addr.Addresses.Length); backoff = TimeSpan.FromSeconds(0); if (found >= peerToFind) { peerTableFull.Cancel(); } } }; n.SendMessageAsync(new GetAddrPayload()); loopCancel.WaitHandle.WaitOne(2000); } catch { } finally { if (n != null) { n.DisconnectAsync(); } } } if (found >= peerToFind) { peerTableFull.Cancel(); } else { Logs.NodeServer.LogInformation("Need {neededPeerCount} more peers", (-found + peerToFind)); } }); } catch (OperationCanceledException) { if (parameters.ConnectCancellation.IsCancellationRequested) { throw; } } } } }
public static void ConfigureDefaultNodeConnectionParameters(NodeConnectionParameters parameters) { parameters = parameters ?? new NodeConnectionParameters(); parameters.IsTrusted = false; //Connecting to the wild //Optimize for small device parameters.ReuseBuffer = false; parameters.SendBufferSize = 1024 * 100; parameters.ReceiveBufferSize = 1024 * 100; parameters.IsRelay = false; parameters.TemplateBehaviors.FindOrCreate<PingPongBehavior>(); //Ping Pong }
/// <summary> /// Configure the components of the wallet /// </summary> /// <param name="parameters">The parameters to the connection</param> public void Configure(NodeConnectionParameters parameters) { if(parameters == null) throw new ArgumentNullException("parameters"); Configure(new NodesGroup(_Parameters.Network, parameters)); }
/// <summary> /// Configure the components of the wallet /// </summary> /// <param name="chain">The chain to keep in sync, if not provided the whole chain will be downloaded on the network (more than 30MB)</param> /// <param name="addrman">The Address Manager for speeding up peer discovery</param> /// <param name="tracker">The tracker responsible for providing bloom filters</param> public void Configure(ConcurrentChain chain = null, AddressManager addrman = null, Tracker tracker = null) { if(State != WalletState.Created) throw new InvalidOperationException("The wallet is already connecting or connected"); var parameters = new NodeConnectionParameters(); ConfigureDefaultNodeConnectionParameters(parameters); //Pick the behaviors if(addrman != null) parameters.TemplateBehaviors.Add(new AddressManagerBehavior(addrman)); //Listen addr, help for node discovery if(chain != null) parameters.TemplateBehaviors.Add(new ChainBehavior(chain)); //Keep chain in sync if(tracker != null) parameters.TemplateBehaviors.Add(new TrackerBehavior(tracker, chain)); //Set bloom filters and scan the blockchain Configure(parameters); }
/// <summary> /// Connect the wallet with the given connection parameters /// </summary> /// <param name="parameters"></param> public void Connect(NodeConnectionParameters parameters) { if(State != WalletState.Created) throw new InvalidOperationException("The wallet is already connecting or connected"); var group = NodesGroup.GetNodeGroup(parameters); if(group == null) { group = new NodesGroup(_Parameters.Network, parameters); } parameters = group.NodeConnectionParameters; group.Requirements.MinVersion = ProtocolVersion.PROTOCOL_VERSION; group.Requirements.RequiredServices = NodeServices.Network; var chain = parameters.TemplateBehaviors.Find<ChainBehavior>(); if(chain == null) { chain = new ChainBehavior(new ConcurrentChain(_Parameters.Network)); parameters.TemplateBehaviors.Add(chain); } if(chain.Chain.Genesis.HashBlock != _Parameters.Network.GetGenesis().GetHash()) throw new InvalidOperationException("ChainBehavior with invalid network chain detected"); var addrman = parameters.TemplateBehaviors.Find<AddressManagerBehavior>(); if(addrman == null) { addrman = new AddressManagerBehavior(new AddressManager()); parameters.TemplateBehaviors.Add(addrman); } var tracker = parameters.TemplateBehaviors.Find<TrackerBehavior>(); if(tracker == null) { tracker = new TrackerBehavior(new Tracker(), chain.Chain); parameters.TemplateBehaviors.Add(tracker); } _Chain = chain.Chain; _AddressManager = addrman.AddressManager; _Tracker = tracker.Tracker; _TrackerBehavior = tracker; _Group = group; if(AddKnownScriptToTracker()) _Group.Purge("Bloom filter renew"); _State = WalletState.Disconnected; _Group.Connect(); _Group.ConnectedNodes.Added += ConnectedNodes_Added; _Group.ConnectedNodes.Removed += ConnectedNodes_Added; foreach(var node in _Group.ConnectedNodes) { node.Behaviors.Find<TrackerBehavior>().Scan(_ScanLocation, Created); } }
public void CanSyncWalletCore(WalletCreation creation) { using(NodeServerTester servers = new NodeServerTester(Network.TestNet)) { var chainBuilder = new BlockchainBuilder(); //Simulate SPV compatible server servers.Server1.InboundNodeConnectionParameters.Services = NodeServices.Network; servers.Server1.InboundNodeConnectionParameters.TemplateBehaviors.Add(new ChainBehavior(chainBuilder.Chain) { AutoSync = false }); servers.Server1.InboundNodeConnectionParameters.TemplateBehaviors.Add(new SPVBehavior(chainBuilder)); ///////////// //The SPV client does not verify the chain and keep one connection alive with Server1 NodeConnectionParameters parameters = new NodeConnectionParameters(); Wallet.ConfigureDefaultNodeConnectionParameters(parameters); parameters.IsTrusted = true; AddressManagerBehavior addrman = new AddressManagerBehavior(new AddressManager()); addrman.AddressManager.Add(new NetworkAddress(servers.Server1.ExternalEndpoint), IPAddress.Parse("127.0.0.1")); parameters.TemplateBehaviors.Add(addrman); NodesGroup connected = new NodesGroup(Network.TestNet, parameters); connected.AllowSameGroup = true; connected.MaximumNodeConnection = 1; ///////////// Wallet wallet = new Wallet(creation, keyPoolSize: 11); Assert.True(wallet.State == WalletState.Created); wallet.Connect(connected); Assert.True(wallet.State == WalletState.Disconnected); TestUtils.Eventually(() => connected.ConnectedNodes.Count == 1); Assert.True(wallet.State == WalletState.Connected); chainBuilder.FindBlock(); TestUtils.Eventually(() => wallet.Chain.Height == 1); for(int i = 0 ; i < 9 ; i++) { wallet.GetNextScriptPubKey(); } wallet.GetNextScriptPubKey(); //Should provoke purge TestUtils.Eventually(() => wallet.State == WalletState.Disconnected && wallet.ConnectedNodes == 0); TestUtils.Eventually(() => wallet.ConnectedNodes == 1); TestUtils.Eventually(() => servers.Server1.ConnectedNodes.Count == 1); var spv = servers.Server1.ConnectedNodes.First().Behaviors.Find<SPVBehavior>(); TestUtils.Eventually(() => spv._Filter != null); var k = wallet.GetNextScriptPubKey(); Assert.Equal(creation.UseP2SH, k.GetDestinationAddress(Network.TestNet) is BitcoinScriptAddress); chainBuilder.GiveMoney(k, Money.Coins(1.0m)); TestUtils.Eventually(() => wallet.GetTransactions().Count == 1); chainBuilder.FindBlock(); TestUtils.Eventually(() => wallet.GetTransactions().Where(t => t.BlockInformation != null).Count() == 1); chainBuilder.Broadcast = false; chainBuilder.GiveMoney(k, Money.Coins(1.5m)); chainBuilder.Broadcast = true; chainBuilder.FindBlock(); TestUtils.Eventually(() => wallet.GetTransactions().Summary.Confirmed.TransactionCount == 2); chainBuilder.Broadcast = false; for(int i = 0 ; i < 30 ; i++) { chainBuilder.FindBlock(); } chainBuilder.GiveMoney(k, Money.Coins(0.001m)); chainBuilder.FindBlock(); chainBuilder.Broadcast = true; chainBuilder.FindBlock(); //Sync automatically TestUtils.Eventually(() => wallet.GetTransactions().Summary.Confirmed.TransactionCount == 3); MemoryStream ms = new MemoryStream(); wallet.Save(ms); ms.Position = 0; var wallet2 = Wallet.Load(ms); wallet2.Connect(connected); Assert.Equal(wallet.Created, wallet2.Created); Assert.Equal(wallet.GetNextScriptPubKey(), wallet2.GetNextScriptPubKey()); Assert.True(wallet.GetKnownScripts().Length == wallet2.GetKnownScripts().Length); var fork = wallet.Chain.FindFork(wallet2._ScanLocation); Assert.True(fork.Height == chainBuilder.Chain.Height - 5); } }
public static Node Connect(NetworkInfo network, string endpoint, NodeConnectionParameters parameters) { return(Connect(network, Utils.ParseIpEndpoint(endpoint, network.DefaultPort), parameters)); }
internal void DiscoverPeers(Network network, NodeConnectionParameters parameters) { int peerToFind = 1000; TraceCorrelation traceCorrelation = new TraceCorrelation(NodeServerTrace.Trace, "Discovering nodes"); int found = 0; using(traceCorrelation.Open()) { while(found < peerToFind) { parameters.ConnectCancellation.ThrowIfCancellationRequested(); NodeServerTrace.PeerTableRemainingPeerToGet(-found + peerToFind); List<NetworkAddress> peers = new List<NetworkAddress>(); peers.AddRange(this.GetAddr()); if(peers.Count == 0) { PopulateTableWithDNSNodes(network, peers); PopulateTableWithHardNodes(network, peers); peers = new List<NetworkAddress>(peers.OrderBy(a => RandomUtils.GetInt32())); } CancellationTokenSource peerTableFull = new CancellationTokenSource(); CancellationToken loopCancel = CancellationTokenSource.CreateLinkedTokenSource(peerTableFull.Token, parameters.ConnectCancellation).Token; try { Parallel.ForEach(peers, new ParallelOptions() { MaxDegreeOfParallelism = 5, CancellationToken = loopCancel, }, p => { CancellationTokenSource timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5)); var cancelConnection = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, loopCancel); Node n = null; try { var param2 = parameters.Clone(); param2.ConnectCancellation = cancelConnection.Token; var addrman = param2.TemplateBehaviors.Find<AddressManagerBehavior>(); param2.TemplateBehaviors.Clear(); param2.TemplateBehaviors.Add(addrman); n = Node.Connect(network, p.Endpoint, param2); n.VersionHandshake(cancelConnection.Token); n.MessageReceived += (s, a) => { var addr = (a.Message.Payload as AddrPayload); if(addr != null) { Interlocked.Add(ref found, addr.Addresses.Length); if(found >= peerToFind) peerTableFull.Cancel(); } }; n.SendMessageAsync(new GetAddrPayload()); loopCancel.WaitHandle.WaitOne(2000); } catch { } finally { if(n != null) n.DisconnectAsync(); } if(found >= peerToFind) peerTableFull.Cancel(); else NodeServerTrace.Information("Need " + (-found + peerToFind) + " more peers"); }); } catch(OperationCanceledException) { if(parameters.ConnectCancellation.IsCancellationRequested) throw; } } } }
public void DiscoverPeers(Network network, NodeConnectionParameters parameters, int peerToFind) { TraceCorrelation traceCorrelation = new TraceCorrelation(NodeServerTrace.Trace, "Discovering nodes"); int found = 0; using (traceCorrelation.Open()) { while (found < peerToFind) { parameters.ConnectCancellation.ThrowIfCancellationRequested(); NodeServerTrace.PeerTableRemainingPeerToGet(-found + peerToFind); List <NetworkAddress> peers = new List <NetworkAddress>(); peers.AddRange(this.GetAddr()); if (peers.Count == 0) { PopulateTableWithDNSNodes(network, peers); PopulateTableWithHardNodes(network, peers); peers = new List <NetworkAddress>(peers.OrderBy(a => RandomUtils.GetInt32())); if (peers.Count == 0) { return; } } CancellationTokenSource peerTableFull = new CancellationTokenSource(); CancellationToken loopCancel = CancellationTokenSource.CreateLinkedTokenSource(peerTableFull.Token, parameters.ConnectCancellation).Token; try { Parallel.ForEach(peers, new ParallelOptions() { MaxDegreeOfParallelism = 5, CancellationToken = loopCancel, }, p => { CancellationTokenSource timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5)); var cancelConnection = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, loopCancel); Node n = null; try { var param2 = parameters.Clone(); param2.ConnectCancellation = cancelConnection.Token; var addrman = param2.TemplateBehaviors.Find <AddressManagerBehavior>(); param2.TemplateBehaviors.Clear(); param2.TemplateBehaviors.Add(addrman); n = Node.Connect(network, p.Endpoint, param2); n.VersionHandshake(cancelConnection.Token); n.MessageReceived += (s, a) => { var addr = (a.Message.Payload as AddrPayload); if (addr != null) { Interlocked.Add(ref found, addr.Addresses.Length); if (found >= peerToFind) { peerTableFull.Cancel(); } } }; n.SendMessageAsync(new GetAddrPayload()); loopCancel.WaitHandle.WaitOne(2000); } catch { } finally { if (n != null) { n.DisconnectAsync(); } } if (found >= peerToFind) { peerTableFull.Cancel(); } else { NodeServerTrace.Information("Need " + (-found + peerToFind) + " more peers"); } }); } catch (OperationCanceledException) { if (parameters.ConnectCancellation.IsCancellationRequested) { throw; } } } } }
public static NodesGroup GetNodeGroup(NodeConnectionParameters parameters) { return GetNodeGroup(parameters.TemplateBehaviors); }
public void CanConnectToRandomNode() { Stopwatch watch = new Stopwatch(); NodeConnectionParameters parameters = new NodeConnectionParameters(); var addrman = GetCachedAddrMan("addrmancache.dat"); parameters.TemplateBehaviors.Add(new AddressManagerBehavior(addrman)); watch.Start(); using(var node = Node.Connect(Network.Main, parameters)) { var timeToFind = watch.Elapsed; node.VersionHandshake(); node.Dispose(); watch.Restart(); using(var node2 = Node.Connect(Network.Main, parameters)) { var timeToFind2 = watch.Elapsed; } } addrman.SavePeerFile("addrmancache.dat", Network.Main); }