예제 #1
0
        public void MarkOutput(string transaction, int index, string spendingTransactionId, long spendingBlockIndex)
        {
            FilterDefinition <MapTransactionAddress> filter = Builders <MapTransactionAddress> .Filter.Eq(addr => addr.Id, string.Format("{0}-{1}", transaction, index));

            UpdateDefinition <MapTransactionAddress> update = Builders <MapTransactionAddress> .Update
                                                              .Set(blockInfo => blockInfo.SpendingTransactionId, spendingTransactionId)
                                                              .Set(blockInfo => blockInfo.SpendingBlockIndex, spendingBlockIndex);

            MapTransactionAddress.UpdateOne(filter, update);
        }
예제 #2
0
        public void DeleteBlock(string blockHash)
        {
            SyncBlockInfo block = BlockGetByHash(blockHash);

            // delete the outputs
            FilterDefinition <MapTransactionAddress> addrFilter = Builders <MapTransactionAddress> .Filter.Eq(addr => addr.BlockIndex, block.BlockIndex);

            MapTransactionAddress.DeleteMany(addrFilter);

            // delete the transaction
            FilterDefinition <MapTransactionBlock> transactionFilter = Builders <MapTransactionBlock> .Filter.Eq(info => info.BlockIndex, block.BlockIndex);

            MapTransactionBlock.DeleteMany(transactionFilter);

            // delete the block itself.
            FilterDefinition <MapBlock> blockFilter = Builders <MapBlock> .Filter.Eq(info => info.BlockHash, blockHash);

            MapBlock.DeleteOne(blockFilter);
        }
예제 #3
0
        private IEnumerable <SyncTransactionAddressItem> SelectAddressWithPool(SyncBlockInfo current, string address, bool availableOnly)
        {
            FilterDefinitionBuilder <MapTransactionAddress> builder = Builders <MapTransactionAddress> .Filter;
            var addressFiler = new List <string> {
                address
            };
            FilterDefinition <MapTransactionAddress> filter = builder.AnyIn(transactionAddress => transactionAddress.Addresses, addressFiler);

            if (availableOnly)
            {
                // we only want spendable transactions
                filter = filter & builder.Eq(info => info.SpendingTransactionId, null);
            }

            watch.Restart();

            SortDefinition <MapTransactionAddress> sort = Builders <MapTransactionAddress> .Sort.Descending(info => info.BlockIndex);

            var addrs = MapTransactionAddress.Find(filter).Sort(sort).ToList();

            watch.Stop();

            log.LogInformation($"Select: Seconds = {watch.Elapsed.TotalSeconds} - UnspentOnly = {availableOnly} - Addr = {address} - Items = {addrs.Count()}");

            // this creates a copy of the collection (to avoid thread issues)
            ICollection <Transaction> pool = MemoryTransactions.Values;

            if (pool.Any())
            {
                // mark trx in output as spent if they exist in the pool
                List <MapTransactionAddress> addrsupdate = addrs;
                GetPoolOutputs(pool).ForEach(f =>
                {
                    MapTransactionAddress adr = addrsupdate.FirstOrDefault(a => a.TransactionId == f.Item1.PrevOut.Hash.ToString() && a.Index == f.Item1.PrevOut.N);
                    if (adr != null)
                    {
                        adr.SpendingTransactionId = f.Item2;
                    }
                });

                // if only spendable transactions are to be returned we need to remove
                // any that have been marked as spent by a transaction in the pool
                if (availableOnly)
                {
                    addrs = addrs.Where(d => d.SpendingTransactionId == null).ToList();
                }

                // add all pool transactions to main output
                var paddr = PoolToMapTransactionAddress(pool, address).ToList();
                addrs = addrs.OrderByDescending(s => s.BlockIndex).Concat(paddr).ToList();
            }

            // map to return type and calculate confirmations
            return(addrs.Select(s => new SyncTransactionAddressItem
            {
                Address = address,
                Index = s.Index,
                TransactionHash = s.TransactionId,
                BlockIndex = s.BlockIndex == -1 ? default(long?) : s.BlockIndex,
                Value = s.Value,
                Confirmations = s.BlockIndex == -1 ? 0 : current.BlockIndex - s.BlockIndex + 1,
                SpendingTransactionHash = s.SpendingTransactionId,
                SpendingBlockIndex = s.SpendingBlockIndex,
                CoinBase = s.CoinBase,
                CoinStake = s.CoinStake,
                ScriptHex = new Script(Encoders.Hex.DecodeData(s.ScriptHex)).ToString(),
                Type = StandardScripts.GetTemplateFromScriptPubKey(new Script(Encoders.Hex.DecodeData(s.ScriptHex)))?.Type.ToString(),
                Time = s.BlockIndex == -1 ? UnixUtils.DateToUnixTimestamp(DateTime.UtcNow) : current.BlockTime
            }));
        }
예제 #4
0
        public string GetSpendingTransaction(string transaction, int index)
        {
            FilterDefinition <MapTransactionAddress> filter = Builders <MapTransactionAddress> .Filter.Eq(addr => addr.Id, string.Format("{0}-{1}", transaction, index));

            return(MapTransactionAddress.Find(filter).ToList().Select(t => t.SpendingTransactionId).FirstOrDefault());
        }