예제 #1
0
 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;
 }
예제 #2
0
 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);
         }
     }
 }
예제 #3
0
        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;
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
 public TableQuery CreateTableQuery(BalanceId balanceId)
 {
     return(CreateTableQuery(balanceId.PartitionKey, balanceId.ToString()));
 }
예제 #6
0
        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));
        }
예제 #7
0
 public IEnumerable <Task <List <OrderedBalanceChange> > > GetOrderedBalanceAsync(BalanceId balanceId,
                                                                                  BalanceQuery query       = null,
                                                                                  CancellationToken cancel = default(CancellationToken))
 {
     return(GetOrderedBalanceCoreAsync(balanceId, query, cancel));
 }
예제 #8
0
        internal OrderedBalanceChange(DynamicTableEntity entity)
        {
            var splitted = entity.RowKey.Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries);

            Height    = Helper.StringToHeight(splitted[1]);
            BalanceId = BalanceId.Parse(splitted[0]);

            var locator     = BalanceLocator.Parse(string.Join("-", splitted.Skip(1).ToArray()), true);
            var confLocator = locator as ConfirmedBalanceLocator;

            if (confLocator != null)
            {
                Height        = confLocator.Height;
                TransactionId = confLocator.TransactionId;
                BlockId       = confLocator.BlockHash;
            }

            var unconfLocator = locator as UnconfirmedBalanceLocator;

            if (unconfLocator != null)
            {
                TransactionId = unconfLocator.TransactionId;
            }

            SeenUtc = entity.Properties["s"].DateTime.Value;

            _SpentOutpoints = Helper.DeserializeList <OutPoint>(Helper.GetEntityProperty(entity, "a"));

            if (entity.Properties.ContainsKey("b0"))
            {
                _SpentCoins = new CoinCollection(Helper.DeserializeList <Spendable>(Helper.GetEntityProperty(entity, "b")).Select(s => new Coin()
                {
                    Outpoint = s.OutPoint,
                    TxOut    = s.TxOut
                }).ToList());
            }
            else if (_SpentOutpoints.Count == 0)
            {
                _SpentCoins = new CoinCollection();
            }

            _SpentIndices = Helper.DeserializeList <IntCompactVarInt>(Helper.GetEntityProperty(entity, "ss")).Select(i => (uint)i.ToLong()).ToList();

            var receivedIndices = Helper.DeserializeList <IntCompactVarInt>(Helper.GetEntityProperty(entity, "c")).Select(i => (uint)i.ToLong()).ToList();
            var receivedTxOuts  = Helper.DeserializeList <TxOut>(Helper.GetEntityProperty(entity, "d"));

            _ReceivedCoins = new CoinCollection();
            for (int i = 0; i < receivedIndices.Count; i++)
            {
                _ReceivedCoins.Add(new Coin()
                {
                    Outpoint = new OutPoint(TransactionId, receivedIndices[i]),
                    TxOut    = receivedTxOuts[i]
                });
            }

            var flags = entity.Properties["e"].StringValue;

            HasOpReturn = flags[0] == 'o';
            IsCoinbase  = flags[1] == 'o';

            _MatchedRules = Helper.DeserializeObject <List <MatchedRule> >(entity.Properties["f"].StringValue).ToList();

            if (entity.Properties.ContainsKey("g"))
            {
                var ctx = new ColoredTransaction();
                ctx.FromBytes(entity.Properties["g"].BinaryValue);
                ColoredTransaction = ctx;
            }

            if (entity.Properties.ContainsKey("h"))
            {
                _ScriptPubKey = new Script(entity.Properties["h"].BinaryValue);
            }

            var data = Helper.GetEntityProperty(entity, "cu");

            if (data != null)
            {
                CustomData = Encoding.UTF8.GetString(data);
            }
        }