示例#1
0
        private async Task RenewAssets()
        {
            var assets = (await _assetRepository.GetBitcoinAssets()).Where(o => !string.IsNullOrEmpty(o.AssetAddress) &&
                                                                           !o.IsDisabled &&
                                                                           o.IssueAllowed).ToList();

            foreach (var asset in assets)
            {
                try
                {
                    var queue = _queueFactory.Create(asset.BlockChainAssetId);
                    var count = await queue.Count();

                    for (int i = 0; i < count; i++)
                    {
                        var coin = await queue.DequeueCoin();

                        if (coin == null)
                        {
                            return;
                        }
                        await queue.EnqueueOutputs(coin);
                    }
                }
                catch (BackendException)
                {
                    //ignore
                }
                catch (Exception e)
                {
                    await _logger.WriteErrorAsync("PregeneratedOutputsRenewFunction", "RenewAssets", $"Asset {asset.Id}", e);
                }
            }
        }
        private async Task GenerateAssetOutputs()
        {
            await _logger.WriteInfoAsync("GenerateOutputsFunction", "GenerateAssetOutputs", null, "Start process");

            var hotWallet = new BitcoinPubKeyAddress(_baseSettings.HotWalletForPregeneratedOutputs, _connectionParams.Network);
            var assets    = (await _assetRepository.GetBitcoinAssets()).Where(o => !string.IsNullOrEmpty(o.AssetAddress) &&
                                                                              !o.IsDisabled &&
                                                                              o.IssueAllowed).ToList();

            foreach (var asset in assets)
            {
                try
                {
                    if (asset.DefinitionUrl == null)
                    {
                        await _logger.WriteWarningAsync("GenerateOutputsFunction", "GenerateAssetOutputs", $"Asset: {asset.Id} has no DefinitionUrl", "");

                        continue;
                    }
                    var queue = _pregeneratedOutputsQueueFactory.Create(asset.BlockChainAssetId);
                    while (await queue.Count() < _baseSettings.MinPregeneratedAssetOutputsCount)
                    {
                        var coins = await _bitcoinOutputsService.GetUncoloredUnspentOutputs(hotWallet.ToString());

                        TransactionBuilder builder = new TransactionBuilder();

                        builder.AddCoins(coins);
                        for (var i = 0; i < _baseSettings.GenerateAssetOutputsBatchSize; i++)
                        {
                            builder.Send(new BitcoinPubKeyAddress(asset.AssetAddress, _connectionParams.Network), _dustSize);
                        }
                        builder.SetChange(hotWallet);

                        builder.SendFees(await _feeProvider.CalcFeeForTransaction(builder));
                        var signedHex = await _signatureApiProvider.SignTransaction(builder.BuildTransaction(true).ToHex());

                        var signedTr      = new Transaction(signedHex);
                        var transactionId = Guid.NewGuid();
                        await _bitcoinClient.BroadcastTransaction(signedTr, transactionId);

                        await queue.EnqueueOutputs(signedTr.Outputs.AsCoins()
                                                   .Where(o => o.ScriptPubKey.GetDestinationAddress(_connectionParams.Network).ToString() == asset.AssetAddress &&
                                                          o.TxOut.Value == _dustSize).ToArray());

                        await FinishOutputs(transactionId, signedTr, hotWallet);
                    }
                }
                catch (Exception e)
                {
                    await _logger.WriteWarningAsync("GenerateOutputsFunction", "GenerateAssetOutputs", $"Asset {asset.Id}", e);
                }
            }
            await _logger.WriteInfoAsync("GenerateOutputsFunction", "GenerateAssetOutputs", null, "End process");
        }
示例#3
0
        public Task <CreateTransactionResponse> GetIssueTransaction(BitcoinAddress bitcoinAddres, decimal amount, IAsset asset, Guid transactionId)
        {
            return(Retry.Try(async() =>
            {
                var context = _transactionBuildContextFactory.Create(_connectionParams.Network);

                return await context.Build(async() =>
                {
                    var builder = new TransactionBuilder();
                    var queue = _pregeneratedOutputsQueueFactory.Create(asset.BlockChainAssetId);

                    var coin = await queue.DequeueCoin();

                    try
                    {
                        var issueCoin = new IssuanceCoin(coin)
                        {
                            DefinitionUrl = new Uri(asset.DefinitionUrl)
                        };

                        var assetId = new BitcoinAssetId(asset.BlockChainAssetId, _connectionParams.Network).AssetId;

                        builder.AddCoins(issueCoin)
                        .IssueAsset(bitcoinAddres, new AssetMoney(assetId, amount, asset.MultiplierPower));
                        context.IssueAsset(assetId);

                        await _transactionBuildHelper.AddFee(builder, context);

                        var buildedTransaction = builder.BuildTransaction(true);

                        await _spentOutputService.SaveSpentOutputs(transactionId, buildedTransaction);

                        await SaveNewOutputs(transactionId, buildedTransaction, context);

                        return new CreateTransactionResponse(buildedTransaction.ToHex(), transactionId);
                    }
                    catch (Exception)
                    {
                        await queue.EnqueueOutputs(coin);
                        throw;
                    }
                });
            }, exception => (exception as BackendException)?.Code == ErrorCode.TransactionConcurrentInputsProblem, 3, _log));
        }
示例#4
0
        private async Task GenerateIssueAllowedCoins()
        {
            foreach (var asset in await _assetRepostory.Values())
            {
                if (OpenAssetsHelper.IsBitcoin(asset.Id) || OpenAssetsHelper.IsLkk(asset.Id) || !asset.IssueAllowed)
                {
                    continue;
                }

                try
                {
                    var setting = await GetAssetSetting(asset.Id);

                    if (setting.HotWallet != setting.ChangeWallet)
                    {
                        continue;
                    }

                    var hotWallet = OpenAssetsHelper.ParseAddress(setting.HotWallet);
                    var assetId   = new BitcoinAssetId(asset.BlockChainAssetId).AssetId;

                    var coins = await _bitcoinOutputsService.GetColoredUnspentOutputs(setting.HotWallet, assetId);

                    var outputSize = new AssetMoney(assetId, setting.OutputSize, asset.MultiplierPower);

                    await _logger.WriteInfoAsync("GenerateOffchainOutputsFunction", "GenerateIssueAllowedCoins", "AssetId " + asset.Id, "Start process");

                    var existingCoinsCount = coins.Count(o => o.Amount <= outputSize && o.Amount * 2 > outputSize);

                    if (existingCoinsCount > setting.MinOutputsCount)
                    {
                        continue;
                    }

                    var generateCnt = setting.MaxOutputsCount - existingCoinsCount;
                    var generated   = 0;
                    while (generated < generateCnt)
                    {
                        var outputsCount = Math.Min(setting.MaxOutputsCountInTx, generateCnt - generated);

                        var context = _transactionBuildContextFactory.Create(_connectionParams.Network);

                        await context.Build(async() =>
                        {
                            var builder = new TransactionBuilder();
                            var queue   = _pregeneratedOutputsQueueFactory.Create(asset.BlockChainAssetId);
                            var coin    = await queue.DequeueCoin();

                            try
                            {
                                var issueCoin = new IssuanceCoin(coin)
                                {
                                    DefinitionUrl = new Uri(asset.DefinitionUrl)
                                };

                                builder.AddCoins(issueCoin);

                                for (var i = 0; i < outputsCount; i++)
                                {
                                    builder.IssueAsset(hotWallet, outputSize);
                                }
                                context.IssueAsset(assetId);
                                await _transactionBuildHelper.AddFee(builder, context);

                                var tr = builder.BuildTransaction(true);

                                await SignAndBroadcastTransaction(tr, context);

                                return("");
                            }
                            catch (Exception)
                            {
                                await queue.EnqueueOutputs(coin);

                                throw;
                            }
                        });

                        generated += outputsCount;
                    }
                }
                catch (Exception ex)
                {
                    await _logger.WriteWarningAsync("GenerateOffchainOutputsFunction", "GenerateIssueAllowedCoins", "AssetId " + asset.Id, ex);
                }
                finally
                {
                    await _logger.WriteInfoAsync("GenerateOffchainOutputsFunction", "GenerateIssueAllowedCoins", "AssetId " + asset.Id, "End process");
                }
            }
        }
示例#5
0
        private async Task RefreshOutputs(string type, string assetId)
        {
            Console.WriteLine($"Start process: type={type}" + (assetId != null ? $", asset={assetId}" : null));

            IPregeneratedOutputsQueue queue;
            string address;

            if (type == "fee")
            {
                queue   = _pregeneratedOutputsQueueFactory.CreateFeeQueue();
                address = _feeAddress;
            }
            else
            {
                var asset = await _assetRepository.GetAssetById(assetId);

                queue   = _pregeneratedOutputsQueueFactory.Create(asset.BlockChainAssetId);
                address = asset.AssetAddress;
                Console.WriteLine("BlockchainAssetId : " + asset.BlockChainAssetId);
            }

            var count = await queue.Count();

            Console.WriteLine($"Start collect {count} outputs from queue");

            var set = new HashSet <OutPoint>();

            while (count-- > 0)
            {
                Coin coin = null;
                try
                {
                    coin = await queue.DequeueCoin();
                }
                catch (Exception)
                {
                }
                finally
                {
                    if (coin != null && !set.Contains(coin.Outpoint))
                    {
                        set.Add(coin.Outpoint);
                        await queue.EnqueueOutputs(coin);
                    }
                }
            }

            Console.WriteLine($"Coins collected");

            var coins = (await _bitcoinOutputsService.GetOnlyNinjaOutputs(address, 1, int.MaxValue)).OfType <Coin>().ToArray();

            Console.WriteLine($"Received {coins.Length} outputs from qbitninja");

            coins = coins.Where(x => !set.Contains(x.Outpoint)).ToArray();

            Console.WriteLine($"Got {coins.Length} missing outputs");

            await queue.EnqueueOutputs(coins);

            //Console.WriteLine("Start remove outputs from queue");
            //int i = 0;
            //while (true)
            //    try
            //    {
            //        await queue.DequeueCoin();
            //        i++;
            //    }
            //    catch (BackendException)
            //    {
            //        break;
            //    }
            //Console.WriteLine($"Removed {i} coins from queue");
            //var coins = (await _bitcoinOutputsService.GetUncoloredUnspentOutputs(address)).OfType<Coin>().ToArray();

            //Console.WriteLine($"Received {coins.Length} outputs from qbitninja");
            //Console.WriteLine("Start add coins to queue");

            //await queue.EnqueueOutputs(coins);

            Console.WriteLine("All coins successfuly added to queue");
            Console.WriteLine(Environment.NewLine);
        }