Example #1
0
        private async Task UpdateRepository(RPCClient client, DerivationSchemeTrackedSource trackedSource, Repository repo, ScanTxoutOutput[] outputs, ScannedItems scannedItems, ScanUTXOProgress progressObj)
        {
            var clientBatch      = client.PrepareBatch();
            var blockIdsByHeight = new ConcurrentDictionary <int, uint256>();
            await Task.WhenAll(outputs.Select(async o =>
            {
                blockIdsByHeight.TryAdd(o.Height, await clientBatch.GetBlockHashAsync(o.Height));
            }).Concat(new[] { clientBatch.SendBatchAsync() }).ToArray());

            var data = outputs
                       .GroupBy(o => o.Coin.Outpoint.Hash)
                       .Select(o => (Coins: o.Select(c => c.Coin).ToList(),
                                     BlockId: blockIdsByHeight.TryGet(o.First().Height),
                                     TxId: o.Select(c => c.Coin.Outpoint.Hash).FirstOrDefault(),
                                     KeyPathInformations: o.Select(c => scannedItems.KeyPathInformations[c.Coin.ScriptPubKey]).ToList()))
                       .Where(o => o.BlockId != null)
                       .Select(o =>
            {
                foreach (var keyInfo in o.KeyPathInformations)
                {
                    var index   = keyInfo.KeyPath.Indexes.Last();
                    var highest = progressObj.HighestKeyIndexFound[keyInfo.Feature];
                    if (highest == null || index > highest.Value)
                    {
                        progressObj.HighestKeyIndexFound[keyInfo.Feature] = (int)index;
                    }
                }
                return(o);
            }).ToList();

            var blockHeadersByBlockId = new ConcurrentDictionary <uint256, BlockHeader>();

            clientBatch = client.PrepareBatch();
            var gettingBlockHeaders = Task.WhenAll(data.Select(async o =>
            {
                blockHeadersByBlockId.TryAdd(o.BlockId, await clientBatch.GetBlockHeaderAsync(o.BlockId));
            }).Concat(new[] { clientBatch.SendBatchAsync() }).ToArray());
            await repo.SaveKeyInformations(scannedItems.
                                           KeyPathInformations.
                                           Select(p => p.Value).
                                           Where(p =>
            {
                var highest = progressObj.HighestKeyIndexFound[p.Feature];
                if (highest == null)
                {
                    return(false);
                }
                return(p.KeyPath.Indexes.Last() <= highest.Value);
            }).ToArray());

            await repo.UpdateAddressPool(trackedSource, progressObj.HighestKeyIndexFound);

            await          gettingBlockHeaders;
            DateTimeOffset now = DateTimeOffset.UtcNow;
            await repo.SaveMatches(data.Select(o => new TrackedTransaction(new TrackedTransactionKey(o.TxId, o.BlockId, true), trackedSource, o.Coins, o.KeyPathInformations)
            {
                Inserted = now,
                FirstSeen = blockHeadersByBlockId.TryGetValue(o.BlockId, out var header) && header != null ? header.BlockTime : NBitcoin.Utils.UnixTimeToDateTime(0)
            }).ToArray());
Example #2
0
 public ScanUTXOWorkItem(NBXplorerNetwork network,
                         DerivationStrategyBase derivationStrategy)
 {
     Network            = network;
     DerivationStrategy = new DerivationSchemeTrackedSource(derivationStrategy);
     Id        = DerivationStrategy.ToString();
     StartTime = DateTime.UtcNow;
 }
Example #3
0
        private static TrackedSource GetTrackedSource(DerivationStrategyBase derivationScheme, BitcoinAddress address)
        {
            TrackedSource trackedSource = null;

            if (address != null)
            {
                trackedSource = new AddressTrackedSource(address);
            }
            if (derivationScheme != null)
            {
                trackedSource = new DerivationSchemeTrackedSource(derivationScheme);
            }
            return(trackedSource);
        }
Example #4
0
        private async Task UpdateRepository(DerivationSchemeTrackedSource trackedSource, Repository repo, SlimChain chain, ScanTxoutOutput[] outputs, ScannedItems scannedItems, ScanUTXOProgress progressObj)
        {
            var data = outputs
                       .GroupBy(o => o.Coin.Outpoint.Hash)
                       .Select(o => (Coins: o.Select(c => c.Coin).ToList(),
                                     BlockId: chain.GetBlock(o.First().Height)?.Hash,
                                     TxId: o.Select(c => c.Coin.Outpoint.Hash).FirstOrDefault(),
                                     KeyPathInformations: o.Select(c => scannedItems.KeyPathInformations[c.Coin.ScriptPubKey]).ToList()))
                       .Where(o => o.BlockId != null)
                       .Select(o =>
            {
                foreach (var keyInfo in o.KeyPathInformations)
                {
                    var index   = keyInfo.KeyPath.Indexes.Last();
                    var highest = progressObj.HighestKeyIndexFound[keyInfo.Feature];
                    if (highest == null || index > highest.Value)
                    {
                        progressObj.HighestKeyIndexFound[keyInfo.Feature] = (int)index;
                    }
                }
                return(o);
            }).ToList();

            await repo.SaveKeyInformations(scannedItems.
                                           KeyPathInformations.
                                           Select(p => p.Value).
                                           Where(p =>
            {
                var highest = progressObj.HighestKeyIndexFound[p.Feature];
                if (highest == null)
                {
                    return(false);
                }
                return(p.KeyPath.Indexes.Last() <= highest.Value);
            }).ToArray());

            await repo.UpdateAddressPool(trackedSource, progressObj.HighestKeyIndexFound);

            DateTimeOffset now = DateTimeOffset.UtcNow;
            await repo.SaveMatches(data.Select(o => new TrackedTransaction(new TrackedTransactionKey(o.TxId, o.BlockId, true), trackedSource, o.Coins, o.KeyPathInformations)).ToArray());
        }