示例#1
0
        public void UpdateDatabase()
        {
            try
            {
                //look for subsidies before we add new blocks because we depend on lastKnowBlockHeight to know where to start looking
                var subsidies = GetNewSubsidies();

                if (subsidies.Count > 0)
                {
                    Retry.ExecuteAction(() =>
                    {
                        using (P2PoolDb db = new P2PoolDb())
                        {
                            foreach (var subsidy in subsidies)
                            {
                                var existingSubsidy = db.Subsidies.Find(subsidy.TxHash);
                                if (existingSubsidy == null)
                                {
                                    Log(string.Format("Adding subsidy of {0} BTC, {1}", subsidy.Amount, subsidy.TxHash));
                                    db.Subsidies.Add(subsidy);
                                }
                                else if (existingSubsidy.BlockHeight != subsidy.BlockHeight || existingSubsidy.BlockHash != subsidy.BlockHash)
                                {
                                    Log(string.Format("Updating subsidy of {0} BTC, {1}", subsidy.Amount, subsidy.TxHash));
                                    existingSubsidy.BlockHash = subsidy.BlockHash;
                                    existingSubsidy.BlockHeight = subsidy.BlockHeight;
                                }
                                db.SaveChanges();
                            }
                        }
                    });
                }

                var blocks = GetNewBlocks();
                if (blocks.Count > 0)
                {
                    Retry.ExecuteAction(() =>
                    {
                        using (P2PoolDb db = new P2PoolDb())
                        {
                            foreach (var block in blocks)
                            {
                                var existingBlock = db.Blocks.Find(block.Id);
                                if (existingBlock == null)
                                {
                                    Log(string.Format("Adding block {0}, {1}{2}", block.BlockHeight, block.Id, block.IsP2Pool ? " (p2pool)" : ""));
                                    db.Blocks.Add(block);
                                }
                                else
                                {
                                    Log(string.Format("Updating block {0}, {1}{2}", block.BlockHeight, block.Id, block.IsP2Pool ? " (p2pool)" : ""));
                                    existingBlock.BlockHeight = block.BlockHeight;
                                    existingBlock.Difficulty = block.Difficulty;
                                    existingBlock.GenerationTxHash = block.GenerationTxHash;
                                    existingBlock.IsOrphaned = block.IsOrphaned;
                                    existingBlock.IsP2Pool = block.IsP2Pool;
                                    existingBlock.PrevBlock = block.PrevBlock;
                                    existingBlock.Timestamp = block.Timestamp;
                                }
                                db.SaveChanges();
                            }

                            //the following logic is too simplistic and only finds orphaned blocks if they are immediatly orphaned (vs a race between to candidate chains that lasts more than 1 block)

                            // this clears the orphaned flag from any blocks that now have a later block pointing at them
                            //db.Database.ExecuteSqlCommand("update p2pool_Blocks set isorphaned=0 where isorphaned=1 and exists (select * from p2pool_Blocks as b2 where b2.PrevBlock = p2pool_Blocks.Id)");

                            // this sets the orphaned flag for any blocks that aren't pointed at by some later block
                            db.Database.ExecuteSqlCommand("update p2pool_Blocks set isorphaned=1 where blockheight < (select max(blockheight) from p2pool_Blocks) and not exists (select * from p2pool_Blocks as b2 where b2.PrevBlock = p2pool_Blocks.Id)");
                        }
                    });
                }

            }
            catch (Exception ex)
            {
                Log("UpdateDatabase: " + ex.Message);
            }
        }
示例#2
0
        public void UpdateStats()
        {
            try
            {
                int timestamp = DateTime.UtcNow.ToUnixTime();

                int remainder = timestamp % 300;
                timestamp -= remainder;

                Log(string.Format("Updating stats for timestamp {0}", timestamp));

                IEnumerable<string> servers = null;

                bool updatedData = false;
                P2PWebClient client = new P2PWebClient();
                client.RequestTimeout = 3000;

                Retry.ExecuteAction(() =>
                {
                    using (P2PoolDb db = new P2PoolDb())
                    {
                        var existingUsersCount = (from u in db.Users where u.Timestamp == timestamp select u.Address).Count();

                        if (existingUsersCount == 0)
                        {
                            JObject users = null;

                            if (servers == null)
                            {
                                servers = GetServers();
                            }
                            foreach (var server in servers)
                            {
                                if (string.IsNullOrWhiteSpace(server))
                                {
                                    continue;
                                }
                                try
                                {
                                    var baseUrl = new Uri(server.Trim());
                                    users = JObject.Parse(client.DownloadString(new Uri(baseUrl, "/users")));
                                    Log(string.Format(" Stats: Retrived users from {0}", server));
                                    break;
                                }
                                catch (Exception ex)
                                {
                                    Log(" Stats: " + ex.Message);
                                }
                            }

                            if (users == null)
                            {
                                return;
                            }

                            Dictionary<string, decimal> addresses = new Dictionary<string, decimal>();
                            foreach (var userEntry in users.Properties())
                            {
                                string address = P2PHelper.ExtractAddress(userEntry.Name) ?? "Unknown";
                                if (address != null)
                                {
                                    decimal portion = 0;
                                    if (addresses.ContainsKey(address))
                                    {
                                        portion += addresses[address];
                                    }
                                    portion += (decimal)userEntry.Value;
                                    addresses[address] = portion;
                                }
                            }
                            foreach (var item in addresses)
                            {
                                User user = new User()
                                {
                                    Timestamp = timestamp,
                                    Address = item.Key,
                                    Portion = item.Value
                                };
                                db.Users.Add(user);

                            }
                            db.SaveChanges();
                            updatedData = true;
                            Log(string.Format(" Stats: Added {0} users", addresses.Count));
                        }


                    }
                });

                Retry.ExecuteAction(() =>
                {
                    using (P2PoolDb db = new P2PoolDb())
                    {


                        Stat entry = db.Stats.Find(timestamp);
                        if (entry == null)
                        {
                            decimal rate = -1;
                            if (servers == null)
                            {
                                servers = GetServers();
                            }
                            foreach (var server in servers)
                            {
                                if (string.IsNullOrWhiteSpace(server))
                                {
                                    continue;
                                }
                                try
                                {
                                    var baseUrl = new Uri(server.Trim());
                                    rate = decimal.Parse(client.DownloadString(new Uri(baseUrl, "/rate"))) / 1000000000m;
                                    Log(string.Format(" Stats: Retrived rate from {0}", server));
                                    break;
                                }
                                catch (Exception ex)
                                {
                                    Log(" Stats: " + ex.Message);
                                }
                            }

                            if (rate == -1)
                            {
                                return;
                            }

                            int userCount;

                            userCount = db.Database.SqlQuery<int>("select count (distinct address) from p2pool_Users where timestamp >= @start and timestamp <= @end", new SqlParameter("start", timestamp - 86400), new SqlParameter("end", timestamp)).First();

                            entry = new Stat
                            {
                                Timestamp = timestamp,
                                Rate = rate,
                                Users = userCount
                            };
                            db.Stats.Add(entry);
                            db.SaveChanges();
                            updatedData = true;
                            Log(string.Format(" Stats: Saved new rate: {0}", rate));

                        }
                    }
                });

                if (updatedData)
                {

                    Retry.ExecuteAction(() =>
                    {
                        using (P2PoolDb db = new P2PoolDb())
                        {
                            CurrentPayouts entry = db.CurrentPayouts.Find(1);
                            if (entry != null)
                            {
                                JObject payouts = null;
                                if (servers == null)
                                {
                                    servers = GetServers();
                                }
                                foreach (var server in servers)
                                {
                                    if (string.IsNullOrWhiteSpace(server))
                                    {
                                        continue;
                                    }
                                    try
                                    {
                                        var baseUrl = new Uri(server.Trim());
                                        payouts = JObject.Parse(client.DownloadString(new Uri(baseUrl, "/current_payouts")));
                                        Log(string.Format(" Stats: Retrived payouts from {0}", server));
                                        break;
                                    }
                                    catch (Exception ex)
                                    {
                                        Log(" Stats: " + ex.Message);
                                    }
                                }
                                if (payouts == null)
                                {
                                    return;
                                }
                                entry.Payouts = payouts.ToString();
                                entry.Updated = timestamp;
                                db.SaveChanges();
                                Log(" Stats: Saved updated payouts");
                            }
                        }
                    });

                    //cleanup old user stats
                    Retry.ExecuteAction(() =>
                    {
                        using (P2PoolDb db = new P2PoolDb())
                        {
                            // delete all the specific user stats older than 3 days
                            var result = db.Database.ExecuteSqlCommand("delete from p2pool_Users where [Timestamp] < @cutoff", new SqlParameter("cutoff", timestamp - 259200));
                            Log(string.Format(" Stats: Deleted old user rows", result));
                        }
                    });

                }

            }
            catch (Exception ex)
            {
                Log(" Stats: UpdateStats Exception: " + ex.Message);
            }
        }