예제 #1
0
        private void HandleNewAddress(RPCPeer address, StateOfNeoContext db)
        {
            var    newNode    = default(Node);
            string successUrl = null;
            var    ports      = this.netSettings.GetPorts();

            foreach (var portWithType in ports)
            {
                var url = portWithType.GetFullUrl(address.Address.ToMatchedIp());

                try
                {
                    var rpcResult = RpcCaller.MakeRPCCall <RPCResponseBody <int> >(url, "getblockcount")
                                    .GetAwaiter()
                                    .GetResult();


                    if (rpcResult?.Result > 0)
                    {
                        successUrl = url;
                        newNode    = this.CreateNodeOfAddress(address.Address,
                                                              portWithType.Type,
                                                              successUrl,
                                                              NodeAddressType.RPC);
                        break;
                    }
                }
                catch (Exception e)
                {
                    Log.Error($"Get blockcount parse error {e.Message}", e);
                    break;
                }
            }

            if (newNode == default(Node))
            {
                var httpTypes = new string[] { "https", "http" };
                foreach (var httpType in httpTypes)
                {
                    var url            = $"{httpType}://{address.Address.ToMatchedIp()}";
                    var heightResponse = HttpRequester.MakeRestCall <HeightResponseObject>($@"{url}/api/main_net/v1/get_height", HttpMethod.Get)
                                         .GetAwaiter()
                                         .GetResult();

                    if (heightResponse != null)
                    {
                        successUrl = url;
                        newNode    = this.CreateNodeOfAddress(address.Address,
                                                              httpType,
                                                              successUrl,
                                                              NodeAddressType.REST,
                                                              NodeCallsConstants.NeoScan);
                        break;
                    }

                    var versionResponse = HttpRequester.MakeRestCall <NeoNotificationVersionResponse>($@"{url}/v1/version", HttpMethod.Get)
                                          .GetAwaiter()
                                          .GetResult();

                    if (versionResponse != null)
                    {
                        successUrl = url;
                        newNode    = this.CreateNodeOfAddress(address.Address,
                                                              httpType,
                                                              successUrl,
                                                              NodeAddressType.REST,
                                                              NodeCallsConstants.NeoNotification);
                        break;
                    }
                }
            }

            if (newNode != null)
            {
                var newNodeAddress = new NodeAddress
                {
                    Ip   = address.Address.ToMatchedIp(),
                    Node = newNode
                };

                var peer = db.Peers.FirstOrDefault(x => x.Ip == address.Address.ToMatchedIp());

                var result = LocationCaller.UpdateNode(newNode, newNodeAddress.Ip).GetAwaiter().GetResult();

                newNode.NodeAddresses.Add(newNodeAddress);

                db.NodeAddresses.Add(newNodeAddress);
                db.Nodes.Add(newNode);
                peer.Node = newNode;
                db.SaveChanges();
            }
        }
예제 #2
0
        protected override void OnReceive(object message)
        {
            if (message is PersistCompleted m)
            {
                if (this.lastUpdateStamp == null ||
                    this.lastUpdateStamp.Value.ToUnixDate().AddMinutes(MinutesPerAudit) <= m.Block.Timestamp.ToUnixDate())
                {
                    if (this.lastUpdateStamp == null)
                    {
                        this.lastUpdateStamp = m.Block.Timestamp;
                    }

                    var optionsBuilder = new DbContextOptionsBuilder <StateOfNeoContext>();
                    optionsBuilder.UseSqlServer(this.connectionString, opts => opts.CommandTimeout((int)TimeSpan.FromMinutes(10).TotalSeconds));
                    var db = new StateOfNeoContext(optionsBuilder.Options);

                    var previousBlock     = Blockchain.Singleton.GetBlock(m.Block.PrevHash);
                    var previousBlockTime = previousBlock.Timestamp.ToUnixDate();

                    var nodes = db.Nodes
                                .Include(x => x.NodeAddresses)
                                .Include(x => x.Audits)
                                .Where(x => x.Net == this.net)
                                .ToList();

                    foreach (var node in nodes)
                    {
                        var successUrl = node.SuccessUrl;
                        var audit      = this.NodeAudit(node, m.Block);

                        if (audit != null)
                        {
                            db.NodeAudits.Add(audit);
                            node.LastAudit = m.Block.Timestamp;
                        }

                        if (string.IsNullOrEmpty(successUrl) || (!node.Longitude.HasValue && !node.Latitude.HasValue))
                        {
                            foreach (var address in node.NodeAddresses)
                            {
                                var result = LocationCaller.UpdateNode(node, address.Ip).GetAwaiter().GetResult();

                                var peerById = db.Peers.FirstOrDefault(x => x.NodeId == node.Id);
                                if (result && peerById == null)
                                {
                                    var peer = db.Peers.FirstOrDefault(x => x.Ip == address.Ip);

                                    if (peer != null)
                                    {
                                        peer.NodeId = node.Id;
                                    }
                                    else
                                    {
                                        var newPeer = CreatePeerFromNode(node, address.Ip);

                                        db.Peers.Add(newPeer);
                                    }

                                    break;
                                }
                                else if (peerById != null)
                                {
                                    if (!peerById.Longitude.HasValue && !peerById.Latitude.HasValue)
                                    {
                                        peerById.FlagUrl   = node.FlagUrl;
                                        peerById.Locale    = node.Locale;
                                        peerById.Latitude  = node.Latitude;
                                        peerById.Longitude = node.Longitude;
                                        peerById.Location  = node.Location;
                                    }
                                }
                            }
                        }

                        db.Nodes.Update(node);
                        db.SaveChanges();
                    }

                    this.lastUpdateStamp     = m.Block.Timestamp;
                    this.totalSecondsElapsed = null;
                }
            }
        }