Пример #1
0
        void BeginTestMessage2(MessagesTest test, DrpTesterPeerApp peer1, DrpTesterPeerApp peer2)
        {
            var text = $"test{_insecureRandom.Next()}-{_insecureRandom.Next()}_from_{peer1}_to_{peer2}";
            var sw   = Stopwatch.StartNew();

            BeginTestMessage3(test, peer1, peer2, sw, text);
        }
Пример #2
0
        void BeginTestMessage3(MessagesTest test, DrpTesterPeerApp peer1, DrpTesterPeerApp peer2, Stopwatch sw, string text)
        {
            var userCertificate1 = UserCertificate.GenerateKeyPairsAndSignAtSingleDevice(peer1.DrpPeerEngine.CryptoLibrary, peer1.UserId, peer1.UserRootPrivateKeys, DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1));

            peer1.LocalDrpPeer.BeginSendShortSingleMessage(userCertificate1, peer2.LocalDrpPeer.Configuration.LocalPeerRegistrationId, peer2.UserId, text, TimeSpan.FromSeconds(60), (exc) =>
            {
                BeginVerifyReceivedMessage(test, peer1, peer2, text, sw, Stopwatch.StartNew());
            });
        }
Пример #3
0
        void BeginCreateUserAppOrContinue(int userIndex)
        {
            if (userIndex >= NumberOfUserApps)
            {
                if (NumberOfUserApps != 0)
                {
                    BeginTestMessages();
                }
                BeginTestTemporaryPeers();
                return;
            }

            var userEngine = new DrpPeerEngine(new DrpPeerEngineConfiguration
            {
                InsecureRandomSeed    = _insecureRandom.Next(),
                VisionChannel         = _visionChannel,
                VisionChannelSourceId = $"{VisionChannelSourceIdPrefix}U{userIndex}",
                SandboxModeOnly_NumberOfDimensions = NumberOfDimensions
            });
            var localDrpPeerConfiguration = LocalDrpPeerConfiguration.Create(userEngine.CryptoLibrary, NumberOfDimensions);

            var epEndpoints = new List <IPEndPoint>();

            if (RemoteEpEndPoints != null)
            {
                epEndpoints.AddRange(RemoteEpEndPoints);
            }
            epEndpoints.AddRange(_localEpApps.Select(x => new IPEndPoint(x.LocalDrpPeer.PublicIpApiProviderResponse, x.DrpPeerEngine.Configuration.LocalPort.Value)));
            localDrpPeerConfiguration.EntryPeerEndpoints = epEndpoints.ToArray();

            var userApp = new DrpTesterPeerApp(userEngine, localDrpPeerConfiguration);

            _userApps.Add(userApp);
            if (epEndpoints.Count == 0)
            {
                throw new Exception("no endpoints for users to register");
            }

            var sw = Stopwatch.StartNew();

            _visionChannel.Emit(userEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName, AttentionLevel.guiActivity, $"registering (adding first neighbor)... via {epEndpoints.Count} EPs");
            userEngine.BeginRegister(localDrpPeerConfiguration, userApp, (localDrpPeer) =>
            {
                userApp.LocalDrpPeer = localDrpPeer;
                _visionChannel.Emit(userEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName, AttentionLevel.guiActivity, $"registration completed in {(int)sw.Elapsed.TotalMilliseconds}ms");
                var waitForNeighborsSw = Stopwatch.StartNew();

                // wait until number of neighbors reaches minimum
                userEngine.EngineThreadQueue.EnqueueDelayed(TimeSpan.FromMilliseconds(300), () =>
                {
                    userEngine_AfterEpRegistration_ContinueIfConnectedToEnoughNeighbors(userApp, userIndex, waitForNeighborsSw);
                }, "waiting for connection with neighbors 324155");
            });
        }
Пример #4
0
        void xList_BeginCreate(int index, int?copyRegIdFromIndexNullable)
        {
            string visionChannelSourceId = $"X{index}";

            if (copyRegIdFromIndexNullable != null)
            {
                visionChannelSourceId += $"_copyFrom{copyRegIdFromIndexNullable}";
            }

            var x = new DrpPeerEngine(new DrpPeerEngineConfiguration
            {
                InsecureRandomSeed = _insecureRandom.Next(),
                VisionChannel      = _visionChannel,
                ForcedPublicIpApiProviderResponse  = IPAddress.Loopback,
                VisionChannelSourceId              = visionChannelSourceId,
                SandboxModeOnly_DisablePoW         = true,
                SandboxModeOnly_EnableInsecureLogs = true,
                SandboxModeOnly_NumberOfDimensions = NumberOfDimensions,
                NeighborhoodExtensionMinIntervalS  = NeighborhoodExtensionMinIntervalS
            });

            EmitAllPeers(AttentionLevel.guiActivity, $"creating peer index {index} (copyRegIdFromIndex={copyRegIdFromIndexNullable})...");

            byte[] ed25519privateKey = null; RegistrationId registrationId = null;
            if (copyRegIdFromIndexNullable.HasValue)
            {
                var copyFromUser = _xList[copyRegIdFromIndexNullable.Value];
                ed25519privateKey = copyFromUser.DrpPeerRegistrationConfiguration.LocalPeerRegistrationPrivateKey.ed25519privateKey;
                registrationId    = copyFromUser.DrpPeerRegistrationConfiguration.LocalPeerRegistrationId;
            }
            var xLocalDrpPeerConfig = LocalDrpPeerConfiguration.Create(x.CryptoLibrary, NumberOfDimensions, ed25519privateKey, registrationId);

            xLocalDrpPeerConfig.EntryPeerEndpoints           = new[] { new IPEndPoint(IPAddress.Loopback, EpLocalPort) };
            xLocalDrpPeerConfig.MinDesiredNumberOfNeighbors  = copyRegIdFromIndexNullable.HasValue ? 1 : MinDesiredNumberOfNeighbors;
            xLocalDrpPeerConfig.SoftMaxNumberOfNeighbors     = copyRegIdFromIndexNullable.HasValue ? 1 : SoftMaxDesiredNumberOfNeighbors;
            xLocalDrpPeerConfig.AbsoluteMaxNumberOfNeighbors = copyRegIdFromIndexNullable.HasValue ? 1 : AbsoluteMaxDesiredNumberOfNeighbors;
            xLocalDrpPeerConfig.MinDesiredNumberOfNeighborsSatisfied_WorstNeighborDestroyIntervalS = MinDesiredNumberOfNeighborsSatisfied_WorstNeighborDestroyIntervalS;
            var xDrpTesterPeerApp = new DrpTesterPeerApp(x, xLocalDrpPeerConfig);

            _xList.Add(xDrpTesterPeerApp);
            x.BeginRegister(xLocalDrpPeerConfig, xDrpTesterPeerApp, (localDrpPeer) =>
            {
                xDrpTesterPeerApp.LocalDrpPeer = localDrpPeer;
                _visionChannel.Emit(x.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                    AttentionLevel.guiActivity, $"registration with EP is complete. waiting for connection with neighbors...");
                x.EngineThreadQueue.EnqueueDelayed(TimeSpan.FromSeconds(1), () =>
                {
                    xList_AfterEpRegistration_ContinueIfConnectedToNeighbors(xDrpTesterPeerApp, index);
                }, "waiting for connection with neighbors 234580");
            });
        }
Пример #5
0
        void BeginTestTemporaryPeers()
        {
            if (_tempApps.Count < NumberOfTempPeers)
            {
                var tempPeerEngine = new DrpPeerEngine(new DrpPeerEngineConfiguration
                {
                    InsecureRandomSeed    = _insecureRandom.Next(),
                    VisionChannel         = _visionChannel,
                    VisionChannelSourceId = $"{VisionChannelSourceIdPrefix}T{_createdTempPeersCount++}",
                    SandboxModeOnly_NumberOfDimensions = NumberOfDimensions,
                });
                var localDrpPeerConfiguration = LocalDrpPeerConfiguration.Create(tempPeerEngine.CryptoLibrary, NumberOfDimensions);

                var epEndpoints = RemoteEpEndPoints.ToList();
                epEndpoints.AddRange(_localEpApps.Select(x => new IPEndPoint(x.LocalDrpPeer.PublicIpApiProviderResponse, x.DrpPeerEngine.Configuration.LocalPort.Value)));
                localDrpPeerConfiguration.EntryPeerEndpoints = epEndpoints.ToArray();

                var tempPeerApp = new DrpTesterPeerApp(tempPeerEngine, localDrpPeerConfiguration);
                _tempApps.Add(tempPeerApp);
                if (epEndpoints.Count == 0)
                {
                    throw new Exception("no endpoints for users to register");
                }

                var sw = Stopwatch.StartNew();
                _visionChannel.Emit(tempPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName, AttentionLevel.guiActivity,
                                    $"registering (adding first neighbor)... via {epEndpoints.Count} EPs");
                tempPeerEngine.BeginRegister(localDrpPeerConfiguration, tempPeerApp, (localDrpPeer) =>
                {
                    tempPeerApp.LocalDrpPeer = localDrpPeer;
                    _visionChannel.Emit(tempPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName, AttentionLevel.guiActivity,
                                        $"registration completed in {(int)sw.Elapsed.TotalMilliseconds}ms");
                    TestTemporaryPeers_WaitUntilEnoughNeighbors(tempPeerApp, Stopwatch.StartNew());
                    TestTemporaryPeers_Wait();
                });
            }
            else if (_tempApps.Count > 0)
            {
                // destroy a random temp peer
                var removeAtIndex = _insecureRandom.Next(_tempApps.Count);
                var tempPeerApp   = _tempApps[removeAtIndex];
                _tempApps.RemoveAt(removeAtIndex);

                _visionChannel.Emit(tempPeerApp.DrpPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName, AttentionLevel.guiActivity,
                                    $"destroying a random temp peer");
                tempPeerApp.DrpPeerEngine.Dispose();

                TestTemporaryPeers_Wait();
            }
        }
Пример #6
0
        void BeginConnectEP(DrpTesterPeerApp ep, int epIndex, Action cb)
        {
            var endpoints = new List <IPEndPoint>();

            for (int i = epIndex + 1; i < _epList.Count; i++)
            {
                endpoints.Add(
                    new IPEndPoint(IPAddress.Loopback, _epList[i].DrpPeerEngine.Configuration.LocalPort.Value)
                    );
            }

            EmitAllPeers(AttentionLevel.guiActivity, $"connecting {ep} to other EPs...");


            ep.LocalDrpPeer.BeginConnectToEPs(endpoints.ToArray(), cb);
        }
Пример #7
0
        void userEngine_AfterEpRegistration_ContinueIfConnectedToEnoughNeighbors(DrpTesterPeerApp userApp, int userIndex, Stopwatch waitForNeighborsSw)
        {
            if (userApp.LocalDrpPeer.ConnectedNeighbors.Count >= userApp.LocalDrpPeer.Configuration.MinDesiredNumberOfNeighbors)
            {
                waitForNeighborsSw.Stop();

                var level = waitForNeighborsSw.Elapsed.TotalMilliseconds < 10000 ? AttentionLevel.guiActivity : AttentionLevel.lightPain;
                _visionChannel.EmitListOfPeers(userApp.DrpPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName, AttentionLevel.guiActivity,
                                               $"{userApp} is connected with {userApp.LocalDrpPeer.ConnectedNeighbors.Count} neighbors (in {waitForNeighborsSw.Elapsed.TotalMilliseconds}ms), enough to continue to create more users");

                BeginCreateUserAppOrContinue(userIndex + 1);
            }
            else
            {
                _visionChannel.Emit(userApp.DrpPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName, AttentionLevel.higherLevelDetail,
                                    $"{userApp} is connected with {userApp.LocalDrpPeer.ConnectedNeighbors.Count} neighbors, not enough to continue with more users");
                userApp.DrpPeerEngine.EngineThreadQueue.EnqueueDelayed(TimeSpan.FromSeconds(1), () =>
                {
                    userEngine_AfterEpRegistration_ContinueIfConnectedToEnoughNeighbors(userApp, userIndex, waitForNeighborsSw);
                }, "userEngine_AfterEpRegistration_ContinueIfConnectedToEnoughNeighbors4644");
            }
        }
Пример #8
0
        void TestTemporaryPeers_WaitUntilEnoughNeighbors(DrpTesterPeerApp app, Stopwatch sw)
        {
            if (app.DrpPeerEngine.IsDisposed)
            {
                return;
            }

            app.DrpPeerEngine.EngineThreadQueue.EnqueueDelayed(TimeSpan.FromSeconds(1), () =>
            {
                var neighborsCount = app.LocalDrpPeer.ConnectedNeighbors.Count;
                var elapsedMs      = sw.Elapsed.TotalMilliseconds;
                var level          = AttentionLevel.guiActivity;
                if (elapsedMs > 30000)
                {
                    level = AttentionLevel.needsAttention;
                }
                else if (elapsedMs > 40000)
                {
                    level = AttentionLevel.mediumPain;
                }
                if (neighborsCount >= app.LocalDrpPeer.Configuration.MinDesiredNumberOfNeighbors)
                {
                    _visionChannel.Emit(app.DrpPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                        level,
                                        $"temp. peer got {neighborsCount} neighbors in {elapsedMs}ms");
                }
                else
                {
                    _visionChannel.Emit(app.DrpPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                        level,
                                        $"temp. peer got {neighborsCount} neighbors in {elapsedMs}ms");
                    if (level != AttentionLevel.mediumPain)
                    {
                        TestTemporaryPeers_WaitUntilEnoughNeighbors(app, sw);
                    }
                }
            }, "TestTemporaryPeers_WaitUntilEnoughNeighbors 237");
        }
Пример #9
0
        void BeginVerifyReceivedMessage(MessagesTest test, DrpTesterPeerApp peer1, DrpTesterPeerApp peer2, string sentText, Stopwatch sw, Stopwatch afterCompletionSw)
        {
            if (peer2.LatestReceivedTextMessage == sentText)
            {
                sw.Stop();
                test.OnSuccessfullyDelivered(sw.Elapsed.TotalMilliseconds, _visionChannel.TimeNow, peer2.LatestReceivedTextMessage_req);
                _visionChannel.EmitListOfPeers(peer1.DrpPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                               AttentionLevel.guiActivity, $"successfully tested message from {peer1} to {peer2} in {sw.Elapsed.TotalMilliseconds}ms. {test.Report}");
            }
            else
            { // try to wait for 1 sec   in case when sender-side callback is invoked BEFORE receiver-side callback
                if (afterCompletionSw.Elapsed.TotalMilliseconds < 1000)
                {
                    peer2.DrpPeerEngine.EngineThreadQueue.EnqueueDelayed(TimeSpan.FromMilliseconds(10), () =>
                    {
                        BeginVerifyReceivedMessage(test, peer1, peer2, sentText, sw, afterCompletionSw);
                    }, "verifyMsg 247");
                    return;
                }

                _visionChannel.EmitListOfPeers(peer1.DrpPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                               AttentionLevel.mediumPain,
                                               $"test message failed from {peer1} to {peer2}: received '{peer2.LatestReceivedTextMessage}', expected '{sentText}. {test.Report}");

                var failedCount = test.OnFailed(_visionChannel.TimeNow);
                if (failedCount >= 100)
                {
                    _visionChannel.EmitListOfPeers(peer1.DrpPeerEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                                   AttentionLevel.strongPain,
                                                   $"disposing the test: {failedCount} messages failed");

                    BeginDisposeOnFailure();
                    return;
                }
            }

            BeginTestMessage(test); // continue with next test message, =between another pair of users
        }
Пример #10
0
 void xList_AfterEpRegistration_ContinueIfConnectedToNeighbors(DrpTesterPeerApp x, int index)
 {
     if (x.LocalDrpPeer.ConnectedNeighbors.Count >= x.LocalDrpPeer.Configuration.MinDesiredNumberOfNeighbors)
     {
         EmitAllPeers(AttentionLevel.guiActivity, $"{x} is connected with {x.LocalDrpPeer.ConnectedNeighbors.Count} neighbors, enough to continue with other peers");
         if (index < NumberOfPeers)
         {
             xList_BeginCreate(index + 1);
         }
         if (index > NumberOfPeersToStartMessagesTest)
         {
             BeginTestInvitesIfNotStartedAlready();
         }
     }
     else
     {
         EmitAllPeers(AttentionLevel.guiActivity, $"{x} is connected with {x.LocalDrpPeer.ConnectedNeighbors.Count} neighbors, not enough to continue with other peers");
         x.DrpPeerEngine.EngineThreadQueue.EnqueueDelayed(TimeSpan.FromSeconds(1), () =>
         {
             xList_AfterEpRegistration_ContinueIfConnectedToNeighbors(x, index);
         }, "xList_AfterEpRegistration_ContinueIfConnectedToNeighbors2345");
     }
 }
Пример #11
0
        void xList_BeginCreate(int index)
        {
            var x = new DrpPeerEngine(new DrpPeerEngineConfiguration
            {
                InsecureRandomSeed = _insecureRandom.Next(),
                VisionChannel      = _visionChannel,
                ForcedPublicIpApiProviderResponse  = IPAddress.Loopback,
                VisionChannelSourceId              = $"X{index}",
                SandboxModeOnly_DisablePoW         = true,
                SandboxModeOnly_EnableInsecureLogs = true,
                SandboxModeOnly_NumberOfDimensions = NumberOfDimensions,
                NeighborhoodExtensionMinIntervalS  = NeighborhoodExtensionMinIntervalS
            });

            EmitAllPeers(AttentionLevel.guiActivity, $"creating peer index {index}...");

            var xLocalDrpPeerConfig = LocalDrpPeerConfiguration.Create(x.CryptoLibrary, NumberOfDimensions);

            xLocalDrpPeerConfig.EntryPeerEndpoints           = new[] { new IPEndPoint(IPAddress.Loopback, EpLocalPort) };
            xLocalDrpPeerConfig.MinDesiredNumberOfNeighbors  = MinDesiredNumberOfNeighbors;
            xLocalDrpPeerConfig.SoftMaxNumberOfNeighbors     = SoftMaxDesiredNumberOfNeighbors;
            xLocalDrpPeerConfig.AbsoluteMaxNumberOfNeighbors = AbsoluteMaxDesiredNumberOfNeighbors;
            xLocalDrpPeerConfig.MinDesiredNumberOfNeighborsSatisfied_WorstNeighborDestroyIntervalS = MinDesiredNumberOfNeighborsSatisfied_WorstNeighborDestroyIntervalS;
            var xDrpTesterPeerApp = new DrpTesterPeerApp(x, xLocalDrpPeerConfig);

            _xList.Add(xDrpTesterPeerApp);
            x.BeginRegister(xLocalDrpPeerConfig, xDrpTesterPeerApp, (localDrpPeer) =>
            {
                xDrpTesterPeerApp.LocalDrpPeer = localDrpPeer;
                _visionChannel.Emit(x.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                    AttentionLevel.guiActivity, $"registration with EP is complete. waiting for connection with neighbors...");
                x.EngineThreadQueue.EnqueueDelayed(TimeSpan.FromSeconds(1), () =>
                {
                    xList_AfterEpRegistration_ContinueIfConnectedToNeighbors(xDrpTesterPeerApp, index);
                }, "waiting for connection with neighbors 234580");
            });
        }
Пример #12
0
        void BeginCreateLocalEpOrContinue(int localEpIndex)
        {
            if (localEpIndex >= NumberOfLocalInterconnectedEpEngines)
            { // continue
                _visionChannel.EmitListOfPeers("", DrpTesterVisionChannelModuleName,
                                               AttentionLevel.guiActivity, $"connected all EPs");

                foreach (var ep2 in _localEpApps)
                {
                    ep2.DrpPeerRegistrationConfiguration.MinDesiredNumberOfNeighborsSatisfied_WorstNeighborDestroyIntervalS = null;
                    ep2.DrpPeerRegistrationConfiguration.AbsoluteMaxNumberOfNeighbors = EpAbsoluteMaxDesiredNumberOfNeighbors;
                    ep2.DrpPeerRegistrationConfiguration.SoftMaxNumberOfNeighbors     = EpSoftMaxDesiredNumberOfNeighbors;
                    ep2.DrpPeerRegistrationConfiguration.MinDesiredNumberOfNeighbors  = EpMinDesiredNumberOfNeighbors;
                }

                BeginCreateUserAppOrContinue(0);
                return;
            }


            var epEngine = new DrpPeerEngine(new DrpPeerEngineConfiguration
            {
                InsecureRandomSeed    = _insecureRandom.Next(),
                LocalPort             = (ushort)(LocalInterconnectedEpEnginesBasePort + localEpIndex),
                VisionChannel         = _visionChannel,
                VisionChannelSourceId = $"{VisionChannelSourceIdPrefix}EP{localEpIndex}",
                SandboxModeOnly_NumberOfDimensions = NumberOfDimensions
            });;
            var epLocalDrpPeerConfig = LocalDrpPeerConfiguration.Create(epEngine.CryptoLibrary, NumberOfDimensions);

            epLocalDrpPeerConfig.MinDesiredNumberOfNeighbors  = null;
            epLocalDrpPeerConfig.AbsoluteMaxNumberOfNeighbors = null;
            epLocalDrpPeerConfig.SoftMaxNumberOfNeighbors     = null;
            epLocalDrpPeerConfig.MinDesiredNumberOfNeighborsSatisfied_WorstNeighborDestroyIntervalS = null;
            var epApp = new DrpTesterPeerApp(epEngine, epLocalDrpPeerConfig);

            epEngine.BeginCreateLocalPeer(epLocalDrpPeerConfig, epApp, (localDrpPeer) =>
            {
                var connectToEpsList = _localEpApps.Select(x => x.LocalDrpPeerEndpoint).ToList(); // make a list of EPs   WITHOUT this new EP
                epApp.LocalDrpPeer   = localDrpPeer;
                _localEpApps.Add(epApp);
                _visionChannel.Emit(epEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                    AttentionLevel.guiActivity, $"created local EP #{localEpIndex}/{NumberOfLocalInterconnectedEpEngines}");

                if (RemoteEpEndPoints != null)
                {
                    connectToEpsList.AddRange(RemoteEpEndPoints.Where(x => !connectToEpsList.Contains(x) && !x.Equals(epApp.LocalDrpPeerEndpoint)));
                }
                if (connectToEpsList.Count != 0)
                {
                    _visionChannel.Emit(epEngine.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                        AttentionLevel.guiActivity, $"connecting with {connectToEpsList.Count} other EPs...");
                    epApp.LocalDrpPeer.BeginConnectToEPs(connectToEpsList.ToArray(), () =>
                    {
                        BeginCreateLocalEpOrContinue(localEpIndex + 1);
                    });
                }
                else
                {
                    BeginCreateLocalEpOrContinue(localEpIndex + 1);
                }
            });
        }
Пример #13
0
        public DrpTester1(VisionChannel visionChannel, Action cb = null)
        {
            _visionChannel = visionChannel;
            _ep            = new DrpPeerEngine(new DrpPeerEngineConfiguration
            {
                InsecureRandomSeed                 = _insecureRandom.Next(),
                LocalPort                          = EpLocalPort,
                VisionChannel                      = visionChannel,
                VisionChannelSourceId              = "EP",
                ForcedPublicIpApiProviderResponse  = IPAddress.Loopback,
                SandboxModeOnly_NumberOfDimensions = NumberOfDimensions
            });
            var epLocalDrpPeerConfig = LocalDrpPeerConfiguration.Create(_ep.CryptoLibrary, NumberOfDimensions);

            _ep.BeginCreateLocalPeer(epLocalDrpPeerConfig, new DrpTesterPeerApp(_ep, epLocalDrpPeerConfig), (rpLocalPeer) =>
            {
                _a = new DrpPeerEngine(new DrpPeerEngineConfiguration
                {
                    InsecureRandomSeed = _insecureRandom.Next(),
                    VisionChannel      = visionChannel,
                    ForcedPublicIpApiProviderResponse  = IPAddress.Loopback,
                    VisionChannelSourceId              = "A",
                    SandboxModeOnly_NumberOfDimensions = NumberOfDimensions
                });
                var aLocalDrpPeerConfig = LocalDrpPeerConfiguration.Create(_a.CryptoLibrary, NumberOfDimensions);
                aLocalDrpPeerConfig.EntryPeerEndpoints = new[] { new IPEndPoint(IPAddress.Loopback, EpLocalPort) };

                _x = new DrpPeerEngine(new DrpPeerEngineConfiguration
                {
                    InsecureRandomSeed = _insecureRandom.Next(),
                    VisionChannel      = visionChannel,
                    ForcedPublicIpApiProviderResponse  = IPAddress.Loopback,
                    VisionChannelSourceId              = "X",
                    SandboxModeOnly_NumberOfDimensions = NumberOfDimensions
                });

                _retryx:
                var xLocalDrpPeerConfig = LocalDrpPeerConfiguration.Create(_x.CryptoLibrary, NumberOfDimensions);
                var distance_eptoa      = epLocalDrpPeerConfig.LocalPeerRegistrationId.GetDistanceTo(_x.CryptoLibrary, aLocalDrpPeerConfig.LocalPeerRegistrationId, NumberOfDimensions);
                var distance_xtoa       = xLocalDrpPeerConfig.LocalPeerRegistrationId.GetDistanceTo(_x.CryptoLibrary, aLocalDrpPeerConfig.LocalPeerRegistrationId, NumberOfDimensions);
                if (distance_xtoa.IsGreaterThan(distance_eptoa))
                {
                    goto _retryx;
                }
                xLocalDrpPeerConfig.EntryPeerEndpoints = new[] { new IPEndPoint(IPAddress.Loopback, EpLocalPort) };

                _n = new DrpPeerEngine(new DrpPeerEngineConfiguration
                {
                    InsecureRandomSeed = _insecureRandom.Next(),
                    VisionChannel      = visionChannel,
                    ForcedPublicIpApiProviderResponse  = IPAddress.Loopback,
                    VisionChannelSourceId              = "N",
                    SandboxModeOnly_NumberOfDimensions = NumberOfDimensions
                });


                _retryn:
                var nLocalDrpPeerConfig = LocalDrpPeerConfiguration.Create(_n.CryptoLibrary, NumberOfDimensions);
                var distance_ntoa       = nLocalDrpPeerConfig.LocalPeerRegistrationId.GetDistanceTo(_n.CryptoLibrary, aLocalDrpPeerConfig.LocalPeerRegistrationId, NumberOfDimensions);
                if (distance_ntoa.IsGreaterThan(distance_xtoa))
                {
                    goto _retryn;
                }
                nLocalDrpPeerConfig.EntryPeerEndpoints = new[] { new IPEndPoint(IPAddress.Loopback, EpLocalPort) };

                var distance_xton  = xLocalDrpPeerConfig.LocalPeerRegistrationId.GetDistanceTo(_n.CryptoLibrary, nLocalDrpPeerConfig.LocalPeerRegistrationId, NumberOfDimensions);
                var distance_epton = epLocalDrpPeerConfig.LocalPeerRegistrationId.GetDistanceTo(_n.CryptoLibrary, nLocalDrpPeerConfig.LocalPeerRegistrationId, NumberOfDimensions);
                if (distance_xton.IsGreaterThan(distance_epton))
                {
                    goto _retryn;
                }

                _xUser  = new DrpTesterPeerApp(_x, xLocalDrpPeerConfig);
                var swX = Stopwatch.StartNew();
                _x.BeginRegister(xLocalDrpPeerConfig, _xUser, (xLocalPeer) =>
                {
                    _visionChannel.Emit(_x.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                        AttentionLevel.guiActivity, $"registration complete in {(int)swX.Elapsed.TotalMilliseconds}ms");

                    _xLocalDrpPeer = xLocalPeer;
                    var swN        = Stopwatch.StartNew();
                    _n.BeginRegister(nLocalDrpPeerConfig, new DrpTesterPeerApp(_n, nLocalDrpPeerConfig), (nLocalPeer) =>
                    {
                        _visionChannel.Emit(_n.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                            AttentionLevel.guiActivity, $"registration complete in {(int)swN.Elapsed.TotalMilliseconds}ms");
                        _nLocalDrpPeer = nLocalPeer;
                        _aUser         = new DrpTesterPeerApp(_a, aLocalDrpPeerConfig);
                        var swA        = Stopwatch.StartNew();
                        _a.BeginRegister(aLocalDrpPeerConfig, _aUser, (aLocalPeer) =>
                        {
                            _visionChannel.Emit(_a.Configuration.VisionChannelSourceId, DrpTesterVisionChannelModuleName,
                                                AttentionLevel.guiActivity, $"registration complete in {(int)swA.Elapsed.TotalMilliseconds}ms");
                            _aLocalDrpPeer = aLocalPeer;
                            if (cb != null)
                            {
                                cb();
                            }
                        });
                    });
                });
            });
        }