private async Task ProcessBlockAsync(long height, PoolContext db, CancellationToken cancellationToken)
        {
            var period       = Period;
            var oldestHeight = height - period - 1;
            var accounts     = await db.Accounts.Where(i => i.Shares.Any(x => x.BlockId <= height && x.BlockId > oldestHeight) && !i.AverageShareHistory.Any(x => x.Height == height)).Select(i => i.Id).ToListAsync(cancellationToken);

            int counter = 0;

            foreach (var account in accounts)
            {
                if (await db.AccountAverageShareHistory.AnyAsync(x => x.AccountId == account && x.Height == height, cancellationToken))
                {
                    continue;
                }
                var shares = await db.Shares.Where(i => i.AccountId == account && i.BlockId <= height && i.BlockId > oldestHeight).Select(i => new { i.BlockId, i.ShareValue }).ToListAsync(cancellationToken);

                var average = shares.GroupBy(i => i.BlockId).Select(x => x.Max(t => t.ShareValue)).Sum() / period;
                Logger.LogInformation("Account {accountId}, computed average shares {average} for block {blockHeight}", account, average, height);
                db.AccountAverageShareHistory.Add(new AccountAverageShareHistory()
                {
                    AccountId     = account,
                    Height        = height,
                    AverageShares = average
                });
                counter += 1;
                // Save every 1000 inserts, to avoid performance hit.
                if (counter % 1000 == 0)
                {
                    await db.SaveChangesAsync(cancellationToken);
                }
            }
            await db.SaveChangesAsync(cancellationToken);
        }
Пример #2
0
        public async Task RecordSharesAsync(ulong accountId, long block, decimal shares, ulong nonce, ulong deadline)
        {
            using (var transaction = await _context.Database.BeginTransactionAsync())
            {
                if (await _context.Shares.AnyAsync(i => i.AccountId == accountId && i.BlockId == block && i.ShareValue >= shares))
                {
                    return;
                }
                if (!await _context.Accounts.AnyAsync(i => i.Id == accountId))
                {
                    _context.Accounts.Add(new Account()
                    {
                        Id = accountId
                    });
                    await _context.SaveChangesAsync().ConfigureAwait(false);
                }

                _context.Shares.Add(new Share()
                {
                    AccountId  = accountId,
                    BlockId    = block,
                    ShareValue = shares,
                    Nonce      = nonce,
                    Deadline   = deadline
                });
                await _context.SaveChangesAsync().ConfigureAwait(false);

                transaction.Commit();
            }
            var message = new DeadlineMessage(accountId, nonce, (long)deadline, shares);
            await _messenger.PublishAsync($"Public.Share.Block.Accepted.{block}", data : message);

            await _messenger.PublishAsync($"Public.Share.Account.Accepted.{accountId}", data : message);
        }