public async Task InsertSpentOutputs(Guid transactionId, IEnumerable <IOutput> outputs)
        {
            Action <MongoServerException> throwIfBackend = (exception) =>
            {
                if (exception != null && exception.IsDuplicateError())
                {
                    throw new BackendException("entity already exists " +
                                               ((exception as MongoBulkWriteException <OutputEntity>)?.UnprocessedRequests.FirstOrDefault() as InsertOneModel <OutputEntity>)
                                               ?.Document.BsonId, ErrorCode.TransactionConcurrentInputsProblem);
                }
            };

            try
            {
                var forInsert = outputs.Select(o => OutputEntity.Create(transactionId, o)).ToList();

                while (forInsert.Count > 0)
                {
                    var part = forInsert.Take(100);
                    forInsert = forInsert.Skip(100).ToList();
                    await _storage.InsertAsync(part);
                }
            }
            catch (MongoServerException e)
            {
                throwIfBackend(e);
                throw;
            }
        }
        public async Task <IEnumerable <IOutput> > GetUnspentOutputs(IEnumerable <IOutput> outputs)
        {
            var enumerable = outputs.ToArray();
            var ids        = enumerable.Select(x => OutputEntity.GenerateId(x.TransactionHash, x.N)).ToArray();

            var hs = new HashSet <string>();

            while (ids.Any())
            {
                var part = ids.Take(200).ToArray();

                var dbOutputs = await _storage.GetDataAsync(o => part.Contains(o.BsonId));

                hs.UnionWith(dbOutputs.Select(x => x.BsonId));

                ids = ids.Skip(200).ToArray();
            }

            return(enumerable.Where(x => !hs.Contains(OutputEntity.GenerateId(x.TransactionHash, x.N))));
        }
 public async Task RemoveSpentOutputs(IEnumerable <IOutput> outputs)
 {
     var ids = outputs.Select(x => OutputEntity.GenerateId(x.TransactionHash, x.N)).ToArray();
     await _storage.DeleteAsync(o => ids.Contains(o.BsonId));
 }