public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
 {
     try
     {
         return(reader.TokenType == JsonToken.Null ? null : BalanceLocator.Parse(reader.Value.ToString()));
     }
     catch (FormatException)
     {
         throw new JsonObjectException("Invalid BalanceLocator", reader);
     }
 }
示例#2
0
        internal void PrepareForSend(BlockFeature at, bool debug)
        {
            if (at != null)
            {
                UnConfirmed = null;
            }
            CalculateSpendable();
#if !CLIENT
            Locator = null;
#endif
            if (!debug)
            {
                CacheHit = null;
            }
            OlderImmature = 0;
        }
示例#3
0
        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));
        }
示例#4
0
 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));
 }
示例#5
0
        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));
        }
        public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            if (!typeof(BalanceLocator).IsAssignableFrom(bindingContext.ModelType))
            {
                return(false);
            }

            ValueProviderResult val = bindingContext.ValueProvider.GetValue(
                bindingContext.ModelName);

            if (val == null)
            {
                return(true);
            }
            string key = val.RawValue as string;

            bindingContext.Model = BalanceLocator.Parse(key);
            return(true);
        }
示例#7
0
 private static BalanceLocator UnEscapeLocator(string str)
 {
     return(BalanceLocator.Parse(str.Substring(1), true));
 }
示例#8
0
        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);
        }
示例#9
0
        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);
        }