protected override bool Execute(CodeActivityContext context) { try { var res = ARM_Service.BPS_GetPSBalanceExcelDocument2(BalanceId.Get(context), StartDateTime.Get(context), EndDateTime.Get(context), DiscreteType, DataSourceType, isPower, isOffsetFromMoscowEnbledForDrums, IsPowerEquipmentEnabled, 7, null, false); if (res != null) { var ms = new MemoryStream(); res.CopyTo(ms); ms.Position = 0; Document.Set(context, ms); } } catch (Exception ex) { Error.Set(context, ex.Message); if (!HideException.Get(context)) { throw ex; } } return(string.IsNullOrEmpty(Error.Get(context))); }
private ChainTable <Models.BalanceSummary> GetBalanceSummaryCacheTable(BalanceId balanceId, bool colored) { Scope scope = new Scope(new[] { balanceId.ToString() }); scope = scope.GetChild(colored ? "colsum" : "balsum"); var cacheTable = Configuration.GetChainCacheTable <BalanceSummary>(scope); return(cacheTable); }
public ChainTable <Models.BalanceSummary> GetBalanceSummaryCacheTable(BalanceId balanceId, bool colored) { Scope scope = new Scope(new[] { balanceId.ToString() }); scope = scope.GetChild(colored ? "colsum" : "balsum"); var cacheTable = GetBalancesCacheTable(scope); return(cacheTable); }
public BalanceSummary AddressBalanceSummary( [ModelBinder(typeof(BalanceIdModelBinder))] BalanceId balanceId, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature at = null, bool debug = false, bool colored = false) { colored = colored || IsColoredAddress(); return(BalanceSummary(balanceId, at, debug, colored)); }
public BalanceSummary AddressBalanceSummary( string walletName, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature at = null, bool debug = false, bool colored = false) { BalanceId id = new BalanceId(walletName); return(BalanceSummary(id, at, debug, colored)); }
public Task <BalanceSummary> AddressBalanceSummary( [ModelBinder(typeof(BalanceIdModelBinder))] BalanceId balanceId, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature at = null, bool debug = false, bool colored = false, int?unconfExpiration = null) { colored = colored || IsColoredAddress(); return(BalanceSummary(balanceId, at, debug, colored, unconfExpiration)); }
public Task <BalanceSummary> AddressBalanceSummary( string walletName, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature at = null, bool debug = false, bool colored = false, int?unconfExpiration = null ) { BalanceId id = new BalanceId(walletName); return(BalanceSummary(id, at, debug, colored, unconfExpiration)); }
public BalanceSummary AddressBalanceSummary( [ModelBinder(typeof(Base58ModelBinder))] IDestination address, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature at = null, bool debug = false, bool colored = false) { BalanceId id = new BalanceId(address); colored = address is BitcoinColoredAddress || colored; return(BalanceSummary(id, at, debug, colored)); }
protected override bool Execute(CodeActivityContext context) { try { var balanceFreeHierarchyUNs = new List <string> { BalanceId.Get(context) }; var balanceResult = ARM_Service.BL_GetFreeHierarchyBalanceResult(balanceFreeHierarchyUNs, StartDateTime.Get(context), EndDateTime.Get(context), null, TExportExcelAdapterType.toXLSx, true, DiscreteType, EnumUnitDigit.Kilo, false, EnumUnitDigit.Kilo, true, false, 3, 3, false, false, false); if (balanceResult != null) { if (balanceResult.CalculatedValues == null || balanceResult.CalculatedValues.Count == 0) { throw new Exception("Документ не сформирован. Неверный идентификатор или баланс удален."); } var calculatedResult = balanceResult.CalculatedValues.First().Value; if (calculatedResult.CompressedDoc == null) { throw new Exception("Документ пуст. Ошибка формирования"); } var ms = new MemoryStream(); CompressUtility.DecompressGZip(calculatedResult.CompressedDoc).CopyTo(ms); ms.Position = 0; Document.Set(context, ms); } } catch (Exception ex) { Error.Set(context, ex.Message); if (!HideException.Get(context)) { throw ex; } } return(string.IsNullOrEmpty(Error.Get(context))); }
public BalanceModel WalletBalance( string walletName, [ModelBinder(typeof(BalanceLocatorModelBinder))] BalanceLocator continuation = null, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature until = null, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature from = null, bool includeImmature = false, bool unspentOnly = false, bool colored = false) { var balanceId = new BalanceId(walletName); return(Balance(balanceId, continuation, until, from, includeImmature, unspentOnly, colored)); }
public BalanceModel AddressBalance( [ModelBinder(typeof(BalanceIdModelBinder))] BalanceId balanceId, [ModelBinder(typeof(BalanceLocatorModelBinder))] BalanceLocator continuation = null, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature until = null, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature from = null, bool includeImmature = false, bool unspentOnly = false, bool colored = false) { colored = colored || IsColoredAddress(); return(Balance(balanceId, continuation, until, from, includeImmature, unspentOnly, colored)); }
public BalanceModel AddressBalance( [ModelBinder(typeof(Base58ModelBinder))] IDestination address, [ModelBinder(typeof(BalanceLocatorModelBinder))] BalanceLocator continuation = null, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature until = null, [ModelBinder(typeof(BlockFeatureModelBinder))] BlockFeature from = null, bool includeImmature = false, bool unspentOnly = false, bool colored = false) { var balanceId = new BalanceId(address); colored = address is BitcoinColoredAddress || colored; return(Balance(balanceId, continuation, until, from, includeImmature, unspentOnly, colored)); }
protected override bool Execute(CodeActivityContext context) { try { var res = ARM_Service.BPS_GetBalansPSResultAndHtmlDocument2(BalanceId.Get(context), StartDateTime.Get(context), EndDateTime.Get(context), DiscreteType, //.Get(context), DataSourceType, //.Get(context), isPower, //.Get(context), isOffsetFromMoscowEnbledForDrums, //.Get(context), IsPowerEquipmentEnabled, 7, null, false); if (res.Errors != null) { Error.Set(context, res.Errors.ToString()); } var ms = CompressUtility.DecompressGZip(res.HTMLDocument); if (ms != null) { ms.Position = 0; Document.Set(context, ms); } IsHasUnbalanceValue.Set(context, !res.IsHasUnbalanceValue); } catch (Exception ex) { if (!HideException.Get(context)) { throw ex; } } return(true); }
public TableQuery CreateTableQuery(BalanceId balanceId) { return CreateTableQuery(balanceId.PartitionKey, balanceId.ToString()); }
public void NonStandardScriptPubKeyDoesNotReturnsWrongBalance() { using(var tester = CreateTester()) { var bob = new Key(); var alice = new Key(); BalanceId bobId = new BalanceId(bob); NonStandardScriptPubKeyDoesNotReturnsWrongBalanceCore(tester, bob, alice, bobId); bob = new Key(); alice = new Key(); bobId = new BalanceId("bob"); tester.Client.AddWalletRule("bob", new ScriptRule() { ScriptPubKey = bob.ScriptPubKey }); NonStandardScriptPubKeyDoesNotReturnsWrongBalanceCore(tester, bob, alice, bobId); bob = new Key(); alice = new Key(); bobId = new BalanceId("bob2"); tester.Client.AddWalletRule("bob2", new ScriptRule() { ScriptPubKey = bob.ScriptPubKey }); var chainBuilder = tester.CreateChainBuilder(); List<Coin> bobCoins = new List<Coin>(); bobCoins.AddRange(chainBuilder.EmitMoney(bob, "50.0").Outputs.AsCoins()); bobCoins.AddRange(chainBuilder.EmitMoney(bob, "5.0").Outputs.AsCoins()); bobCoins.AddRange(chainBuilder.EmitMoney(bob, "15.0").Outputs.AsCoins()); var prev = chainBuilder.Emit(new Transaction() { Outputs = { new TxOut(Money.Coins(1.0m), bob.ScriptPubKey + OpcodeType.OP_NOP), new TxOut(Money.Coins(1.5m), bob.ScriptPubKey + OpcodeType.OP_NOP), new TxOut(Money.Coins(2.0m), bob.ScriptPubKey + OpcodeType.OP_NOP), } }); bobCoins.AddRange(prev.Outputs.AsCoins()); Shuffle(bobCoins); chainBuilder.SubmitBlock(); chainBuilder.SyncIndexer(); var bobBalance = tester.Client.GetOrderedBalance(bobId).ToArray(); Assert.True(bobBalance.Length == 3); var tx = new Transaction(); foreach(var coin in bobCoins) { tx.Inputs.Add(new TxIn() { PrevOut = coin.Outpoint, ScriptSig = bob.ScriptPubKey }); } tx.Outputs.Add(new TxOut(Money.Coins(0.1m), alice)); tx.Sign(bob, false); chainBuilder.Emit(tx); chainBuilder.SubmitBlock(); chainBuilder.SyncIndexer(); for(int i = 0; i < 2; i++) { bobBalance = tester.Client.GetOrderedBalance(bobId).ToArray(); Assert.True(bobBalance.Length == 4); //OP_NOP spending should not appear Assert.True(bobBalance[0].SpentCoins.Count == 3); foreach(var coin in bobBalance[0].SpentCoins) { Assert.Equal(bob.ScriptPubKey, coin.TxOut.ScriptPubKey); } } } }
private bool MergeIntoWalletCore(string walletId, BalanceId balanceId, WalletRule rule, CancellationToken cancel) { var indexer = Configuration.CreateIndexer(); var query = new BalanceQuery() { From = new UnconfirmedBalanceLocator().Floor(), RawOrdering = true }; var sourcesByKey = GetOrderedBalanceCore(balanceId, query, cancel) .ToDictionary(i => GetKey(i)); if(sourcesByKey.Count == 0) return false; var destByKey = GetOrderedBalance(walletId, query, cancel) .ToDictionary(i => GetKey(i)); List<OrderedBalanceChange> entities = new List<OrderedBalanceChange>(); foreach(var kv in sourcesByKey) { var source = kv.Value; var existing = destByKey.TryGet(kv.Key); if(existing == null) { existing = new OrderedBalanceChange(walletId, source); } existing.Merge(kv.Value, rule); entities.Add(existing); if(entities.Count == 100) indexer.Index(entities); } if(entities.Count != 0) indexer.Index(entities); return true; }
private IEnumerable<OrderedBalanceChange> GetOrderedBalanceCore(BalanceId balanceId, BalanceQuery query, CancellationToken cancel) { foreach(var partition in GetOrderedBalanceCoreAsync(balanceId, query, cancel)) { foreach(var change in partition.Result) { yield return change; } } }
public IEnumerable<Task<List<OrderedBalanceChange>>> GetOrderedBalanceAsync(BalanceId balanceId, BalanceQuery query = null, CancellationToken cancel = default(CancellationToken)) { return GetOrderedBalanceCoreAsync(balanceId, query, cancel); }
private static void NonStandardScriptPubKeyDoesNotReturnsWrongBalanceCore(IndexerTester tester, Key bob, Key alice, BalanceId bobId) { var chainBuilder = tester.CreateChainBuilder(); chainBuilder.EmitMoney(bob, "50.0"); var prev = chainBuilder.Emit(new Transaction() { Outputs = { new TxOut(Money.Coins(1.0m), bob.ScriptPubKey + OpcodeType.OP_NOP) } }); chainBuilder.SubmitBlock(); chainBuilder.SyncIndexer(); var bobBalance = tester.Client.GetOrderedBalance(bobId).ToArray(); Assert.True(bobBalance.Length == 1); var tx = new Transaction(); tx.Inputs.Add(new TxIn() { PrevOut = prev.Outputs.AsCoins().First().Outpoint, ScriptSig = bob.ScriptPubKey }); tx.Outputs.Add(new TxOut(Money.Coins(0.1m), alice)); tx.Sign(bob, false); chainBuilder.Emit(tx); chainBuilder.SubmitBlock(); chainBuilder.SyncIndexer(); for(int i = 0; i < 2; i++) { bobBalance = tester.Client.GetOrderedBalance(bobId).ToArray(); Assert.True(bobBalance.Length < 2); //OP_NOP spending should not appear } }
public BalanceSummary BalanceSummary( BalanceId balanceId, BlockFeature at, bool debug, bool colored, int?unconfExpiration) { var expiration = GetExpiration(unconfExpiration); var repo = Configuration.CreateWalletRepository(); CancellationTokenSource cancel = new CancellationTokenSource(); cancel.CancelAfter(30000); var checkpoint = Configuration.Indexer.CreateIndexer() .GetCheckpoint(balanceId.Type == BalanceType.Address ? IndexerCheckpoints.Balances : IndexerCheckpoints.Wallets); var atBlock = AtBlock(at); var query = new BalanceQuery(); query.RawOrdering = true; query.From = null; if (at != null) { query.From = ToBalanceLocator(atBlock); } if (query.From == null) { query.From = new UnconfirmedBalanceLocator(DateTimeOffset.UtcNow - expiration); } query.PageSizes = new[] { 1, 10, 100 }; var cacheTable = repo.GetBalanceSummaryCacheTable(balanceId, colored); var cachedSummary = cacheTable.Query(Chain, query).FirstOrDefault(c => (((ConfirmedBalanceLocator)c.Locator).BlockHash == atBlock.HashBlock && at != null) || c.Immature.TransactionCount == 0 || ((c.Immature.TransactionCount != 0) && !IsMature(c.OlderImmature, atBlock))); var cachedLocator = cachedSummary == null ? null : (ConfirmedBalanceLocator)cachedSummary.Locator; if (cachedSummary != null && at != null && cachedLocator.Height == atBlock.Height) { cachedSummary.CacheHit = CacheHit.FullCache; cachedSummary.PrepareForSend(at, debug); return(cachedSummary); } cachedSummary = cachedSummary ?? new BalanceSummary() { Confirmed = new BalanceSummaryDetails(), UnConfirmed = new BalanceSummaryDetails(), OlderImmature = int.MaxValue }; int stopAtHeight = cachedSummary.Locator == null ? -1 : cachedLocator.Height; int lookback = (int)(expiration.Ticks / this.Network.Consensus.PowTargetSpacing.Ticks); if (at == null) { stopAtHeight = stopAtHeight - lookback; } var client = Configuration.Indexer.CreateIndexerClient(); client.ColoredBalance = colored; var diff = client .GetOrderedBalance(balanceId, query) .WhereNotExpired(expiration) .TakeWhile(_ => !cancel.IsCancellationRequested) //Some confirmation of the fetched unconfirmed may hide behind stopAtHeigh .TakeWhile(_ => _.BlockId == null || _.Height > stopAtHeight - lookback) .AsBalanceSheet(Chain); if (cancel.Token.IsCancellationRequested) { throw new HttpResponseException(new HttpResponseMessage() { StatusCode = HttpStatusCode.InternalServerError, ReasonPhrase = "The server can't fetch the balance summary because the balance is too big. Please, load it in several step with ?at={blockFeature} parameter. Once fully loaded after all the step, the summary will return in constant time." }); } RemoveBehind(diff, stopAtHeight); RemoveConflicts(diff); var unconfs = diff.Unconfirmed; var confs = cachedLocator == null ? diff.Confirmed : diff.Confirmed.Where(c => c.Height > cachedLocator.Height).ToList(); var immature = confs.Where(c => !IsMature(c, atBlock)).ToList(); var summary = new BalanceSummary() { Confirmed = BalanceSummaryDetails.CreateFrom(confs, Network, colored), Immature = BalanceSummaryDetails.CreateFrom(immature, Network, colored), UnConfirmed = BalanceSummaryDetails.CreateFrom(unconfs, Network, colored), }; summary.Confirmed += cachedSummary.Confirmed; summary.Immature += cachedSummary.Immature; summary.Locator = new ConfirmedBalanceLocator(atBlock.Height, atBlock.HashBlock); summary.CacheHit = cachedSummary.Locator == null ? CacheHit.NoCache : CacheHit.PartialCache; var newCachedLocator = (ConfirmedBalanceLocator)summary.Locator; if ( cachedSummary.Locator == null || newCachedLocator.BlockHash != cachedLocator.BlockHash) { var olderImmature = immature.Select(_ => _.Height).Concat(new[] { int.MaxValue }).Min(); var newCachedSummary = new Models.BalanceSummary() { Confirmed = summary.Confirmed, Immature = summary.Immature, Locator = summary.Locator, OlderImmature = Math.Min(cachedSummary.OlderImmature, olderImmature) }; var checkpointBlock = Chain.GetBlock(checkpoint.BlockLocator.Blocks[0]); if (checkpointBlock != null && checkpointBlock.Height >= atBlock.Height) { cacheTable.Create(newCachedLocator, newCachedSummary); } } summary.PrepareForSend(at, debug); return(summary); }
private void Init(uint256 txId, BalanceId balanceId, uint256 blockId, BlockHeader blockHeader, int height) { BlockId = blockId; SeenUtc = blockHeader == null ? DateTime.UtcNow : blockHeader.BlockTime.UtcDateTime; Height = blockId == null ? UnconfirmedBalanceLocator.UnconfHeight : height; TransactionId = txId; BalanceId = balanceId; }
internal OrderedBalanceChange(uint256 txId, Script scriptPubKey, uint256 blockId, BlockHeader blockHeader, int height) : this() { var balanceId = new BalanceId(scriptPubKey); Init(txId, balanceId, blockId, blockHeader, height); if(!balanceId.ContainsScript) { _ScriptPubKey = scriptPubKey; } }
BalanceModel Balance(BalanceId balanceId, BalanceLocator continuation, BlockFeature until, BlockFeature from, bool includeImmature, bool unspentOnly, bool colored) { CancellationTokenSource cancel = new CancellationTokenSource(); cancel.CancelAfter(30000); BalanceQuery query = new BalanceQuery(); query.From = null; if (from != null) { query.From = ToBalanceLocator(from); query.FromIncluded = true; } if (continuation != null) { query = new BalanceQuery { From = continuation, FromIncluded = false }; } if (query.From == null) { query.From = new UnconfirmedBalanceLocator(DateTimeOffset.UtcNow - TimeSpan.FromHours(24.0)); } if (until != null) { query.To = ToBalanceLocator(until); query.FromIncluded = true; } if (query.To.IsGreaterThan(query.From)) { throw InvalidParameters("Invalid agurment : from < until"); } var client = Configuration.Indexer.CreateIndexerClient(); client.ColoredBalance = colored; var balance = client .GetOrderedBalance(balanceId, query) .TakeWhile(_ => !cancel.IsCancellationRequested) .WhereNotExpired() .Where(o => includeImmature || IsMature(o, Chain.Tip)) .AsBalanceSheet(Chain); var balanceChanges = balance.All; if (until != null && balance.Confirmed.Count != 0) //Strip unconfirmed that can appear after the last until { for (int i = balanceChanges.Count - 1; i >= 0; i--) { var last = balanceChanges[i]; if (last.BlockId == null) { balanceChanges.RemoveAt(i); } else { break; } } } if (unspentOnly) { var changeByTxId = balanceChanges.ToDictionary(_ => _.TransactionId); var spentOutpoints = changeByTxId.Values.SelectMany(b => b.SpentCoins.Select(c => c.Outpoint)).ToDictionary(_ => _); foreach (var change in changeByTxId.Values.ToArray()) { change.SpentCoins.Clear(); change.ReceivedCoins.RemoveAll(c => spentOutpoints.ContainsKey(c.Outpoint)); } } var result = new BalanceModel(balanceChanges, Chain); if (cancel.IsCancellationRequested) { if (balanceChanges.Count > 0) { var lastop = balanceChanges[balanceChanges.Count - 1]; result.Continuation = lastop.CreateBalanceLocator(); } } return(result); }
private IEnumerable<Task<List<OrderedBalanceChange>>> GetOrderedBalanceCoreAsync(BalanceId balanceId, BalanceQuery query, CancellationToken cancel) { if(query == null) query = new BalanceQuery(); var table = Configuration.GetBalanceTable(); var tableQuery = ExecuteBalanceQuery(table, query.CreateTableQuery(balanceId), query.PageSizes); var partitions = tableQuery .Select(c => new OrderedBalanceChange(c)) .Select(c => new LoadingTransactionTask { Loaded = NeedLoading(c) ? EnsurePreviousLoadedAsync(c) : Task.FromResult(true), Change = c }) .Partition(BalancePartitionSize); if(!query.RawOrdering) { return GetOrderedBalanceCoreAsyncOrdered(partitions, cancel); } return GetOrderedBalanceCoreAsyncRaw(partitions, cancel); }
public ChainTable <Models.BalanceSummary> GetBalanceSummaryCacheTable(string walletName, bool colored) { var balanceId = new BalanceId(walletName); return(GetBalanceSummaryCacheTable(balanceId, colored)); }
BalanceModel Balance(BalanceId balanceId, BalanceLocator continuation, BlockFeature until, BlockFeature from, bool includeImmature, bool unspentOnly, bool colored, int?unconfExpiration) { var expiration = GetExpiration(unconfExpiration); CancellationTokenSource cancel = new CancellationTokenSource(); cancel.CancelAfter(30000); BalanceQuery query = new BalanceQuery(); query.RawOrdering = true; query.From = null; if (from != null) { query.From = ToBalanceLocator(from); query.FromIncluded = true; } if (continuation != null) { query = new BalanceQuery { From = continuation, FromIncluded = false }; query.RawOrdering = true; } if (query.From == null) { query.From = new UnconfirmedBalanceLocator(DateTimeOffset.UtcNow - expiration); } if (until != null) { query.To = ToBalanceLocator(until); query.FromIncluded = true; } if (query.To.IsGreaterThan(query.From)) { throw InvalidParameters("Invalid argument : from < until"); } var client = Configuration.Indexer.CreateIndexerClient(); client.ColoredBalance = colored; var balance = client .GetOrderedBalance(balanceId, query) .TakeWhile(_ => !cancel.IsCancellationRequested) .WhereNotExpired(expiration) .Where(o => includeImmature || IsMature(o, Chain.Tip)) .AsBalanceSheet(Chain); var balanceChanges = balance.All; if (until != null && balance.Confirmed.Count != 0) //Strip unconfirmed that can appear after the last until { List <OrderedBalanceChange> oldUnconfirmed = new List <OrderedBalanceChange>(); var older = balanceChanges.Last(); for (int i = 0; i < balanceChanges.Count; i++) { var last = balanceChanges[i]; if (last.BlockId == null) { if (last.SeenUtc < older.SeenUtc) { oldUnconfirmed.Add(last); } } else { break; } } foreach (var unconf in oldUnconfirmed) { balanceChanges.Remove(unconf); } } var conflicts = RemoveConflicts(balance); if (unspentOnly) { HashSet <OutPoint> spents = new HashSet <OutPoint>(); foreach (var change in balanceChanges.SelectMany(b => b.SpentCoins)) { spents.Add(change.Outpoint); } foreach (var change in balanceChanges) { change.SpentCoins.Clear(); change.ReceivedCoins.RemoveAll(c => spents.Contains(c.Outpoint)); } } var result = new BalanceModel(balanceChanges, Chain); result.ConflictedOperations = result.GetBalanceOperations(conflicts, Chain); if (cancel.IsCancellationRequested) { if (balanceChanges.Count > 0) { var lastop = balanceChanges[balanceChanges.Count - 1]; result.Continuation = lastop.CreateBalanceLocator(); } } return(result); }
public IEnumerable<OrderedBalanceChange> GetOrderedBalance(BalanceId balanceId, BalanceQuery query = null, CancellationToken cancel = default(CancellationToken)) { return GetOrderedBalanceCore(balanceId, query, cancel); }