Пример #1
0
        private async Task <AccountAddress> GetPoolAccountAddressAsync(CancellationToken cancellationToken)
        {
            var poolAddress = Configuration.GetSection("Pool").GetValue <string>("Address");

            if (string.IsNullOrWhiteSpace(poolAddress))
            {
                return(null);
            }
            var cachedAddress = _address;

            if (cachedAddress != null && cachedAddress.Item1 == poolAddress)
            {
                return(cachedAddress.Item2);
            }

            cachedAddress = Tuple.Create(poolAddress, await BurstApi.GetAccountAddressAsync(poolAddress, cancellationToken).ConfigureAwait(false));
            _address      = cachedAddress;
            return(cachedAddress.Item2);
        }
Пример #2
0
        private async Task ProcessBlockStateAsync(long blockHeight, CancellationToken stopCancellationToken)
        {
            AccountAddress poolAddress = null;
            bool           first       = true;

            while (poolAddress == null)
            {
                if (!first)
                {
                    await Task.Delay(TimeSpan.FromSeconds(30), stopCancellationToken);
                }
                else
                {
                    first = false;
                }
                poolAddress = await GetPoolAccountAddressAsync(stopCancellationToken);
            }
            var blockResult = await BurstApi.GetBlockAsync(blockHeight, stopCancellationToken).ConfigureAwait(false);

            if (blockResult == null)
            {
                return;
            }
            var rewardReceipient = await BurstApi.GetRewardReceipientAsync(blockResult.Generator.ToString(), stopCancellationToken);

            var rewardReceipientAccount = await BurstApi.GetAccountAddressAsync(rewardReceipient);

            bool poolWins = rewardReceipientAccount.Account == poolAddress.Account;

            using (var scope = ServiceScopeFactory.CreateScope())
            {
                var db = scope.ServiceProvider.GetRequiredService <PoolContext>();
                using (var transaction = await db.Database.BeginTransactionAsync(stopCancellationToken))
                {
                    if (await db.BlockStates.AnyAsync(i => i.Height == blockHeight))
                    {
                        return;
                    }
                    var blockState = new BlockState()
                    {
                        Height       = blockHeight,
                        IsPoolMember = poolWins,
                    };
                    if (poolWins)
                    {
                        var previousTransaction = await db.PoolTransactions.OrderByDescending(i => i.Height).ThenByDescending(i => i.Created).FirstOrDefaultAsync(stopCancellationToken);

                        var poolTransaction = db.PoolTransactions.Add(new PoolTransaction()
                        {
                            Adjustment  = blockResult.TotalBlockReward,
                            Height      = blockHeight,
                            PoolBalance = (previousTransaction?.PoolBalance ?? 0m) + blockResult.TotalBlockReward
                        });
                        await db.SaveChangesAsync(stopCancellationToken);

                        blockState.PoolTransactionId = poolTransaction.Entity.Id;
                    }
                    db.BlockStates.Add(blockState);
                    await db.SaveChangesAsync(stopCancellationToken);

                    transaction.Commit();
                    if (blockState.IsPoolMember)
                    {
                        Logger.LogInformation("Block {height}: Pool wins, Block reward: {reward}. Winner: {winner}", blockHeight, blockResult.TotalBlockReward, blockResult.GeneratorReedSolomon);
                    }
                    else
                    {
                        Logger.LogInformation("Block {height}: Pool didn't win.", blockHeight);
                    }
                }
            }
        }