예제 #1
0
        public override void SaveChanges(ChainedBlock newTip, IEnumerable <uint256> txIds, IEnumerable <Coins> coins)
        {
            int insertedEntities = 0;

            using (new StopWatch().Start(o => PerformanceCounter.AddInsertTime(o)))
            {
                using (var tx = _Engine.GetTransaction())
                {
                    var fork       = FindFork(newTip, Tip);
                    var currentTip = newTip;
                    var blocks     = new ChainedBlock[currentTip.Height - fork.Height];
                    int i          = 0;
                    while (currentTip.Height != fork.Height)
                    {
                        blocks[i++] = currentTip;
                        currentTip  = currentTip.Previous;
                    }
                    Array.Reverse(blocks);
                    insertedEntities += blocks.Length;
                    foreach (var block in blocks)
                    {
                        tx.Insert("Chain", block.Height, block.Header);
                    }
                    var txIdsEnum = txIds.GetEnumerator();
                    var coinsEnum = coins.GetEnumerator();
                    List <Tuple <uint256, Coins> > all = new List <Tuple <uint256, Coins> >();
                    while (txIdsEnum.MoveNext())
                    {
                        coinsEnum.MoveNext();
                        all.Add(Tuple.Create(txIdsEnum.Current, coinsEnum.Current));
                    }
                    all.Sort(CoinPairComparer.Instance);
                    foreach (var coin in all)
                    {
                        if (coin.Item2.IsPruned)
                        {
                            tx.RemoveKey("Coins", coin.Item1.ToBytes(false));
                        }
                        else
                        {
                            tx.Insert("Coins", coin.Item1.ToBytes(false), coin.Item2);
                        }
                    }
                    insertedEntities += all.Count;
                    tx.Commit();
                }
                _Tip = newTip;
            }
            PerformanceCounter.AddInsertedEntities(insertedEntities);
        }
예제 #2
0
        public override void SaveChanges(ChainedBlock newTip, IEnumerable <UnspentOutputs> unspentOutputs)
        {
            int insertedEntities = 0;

            using (new StopWatch().Start(o => PerformanceCounter.AddInsertTime(o)))
            {
                using (var tx = _Engine.GetTransaction())
                {
                    var fork       = FindFork(newTip, Tip);
                    var currentTip = newTip;
                    var blocks     = new ChainedBlock[currentTip.Height - fork.Height];
                    int i          = 0;
                    while (currentTip.Height != fork.Height)
                    {
                        blocks[i++] = currentTip;
                        currentTip  = currentTip.Previous;
                    }
                    Array.Reverse(blocks);
                    insertedEntities += blocks.Length;
                    foreach (var block in blocks)
                    {
                        tx.Insert("Chain", block.Height, block.Header);
                    }
                    var all = unspentOutputs.ToList();
                    all.Sort(UnspentOutputsComparer.Instance);
                    foreach (var coin in all)
                    {
                        if (coin.IsPrunable)
                        {
                            tx.RemoveKey("Coins", coin.TransactionId.ToBytes(false));
                        }
                        else
                        {
                            tx.Insert("Coins", coin.TransactionId.ToBytes(false), coin.ToCoins());
                        }
                    }
                    insertedEntities += all.Count;
                    tx.Commit();
                }
                _Tip = newTip;
            }
            PerformanceCounter.AddInsertedEntities(insertedEntities);
        }
예제 #3
0
 public override Task SaveChangesAsync(IEnumerable <UnspentOutputs> unspentOutputs, IEnumerable <TxOut[]> originalOutputs, uint256 oldBlockHash, uint256 nextBlockHash)
 {
     return(_Session.Do(() =>
     {
         RewindData rewindData = originalOutputs == null ? null : new RewindData(oldBlockHash);
         int insertedEntities = 0;
         using (new StopWatch().Start(o => PerformanceCounter.AddInsertTime(o)))
         {
             var current = GetCurrentHash();
             if (current != oldBlockHash)
             {
                 throw new InvalidOperationException("Invalid oldBlockHash");
             }
             SetBlockHash(nextBlockHash);
             var all = unspentOutputs.ToList();
             Dictionary <uint256, TxOut[]> unspentToOriginal = new Dictionary <uint256, TxOut[]>(all.Count);
             if (originalOutputs != null)
             {
                 var originalEnumerator = originalOutputs.GetEnumerator();
                 foreach (var u in all)
                 {
                     originalEnumerator.MoveNext();
                     unspentToOriginal.Add(u.TransactionId, originalEnumerator.Current);
                 }
             }
             all.Sort(UnspentOutputsComparer.Instance);
             foreach (var coin in all)
             {
                 if (coin.IsPrunable)
                 {
                     _Session.Transaction.RemoveKey("Coins", coin.TransactionId.ToBytes(false));
                 }
                 else
                 {
                     _Session.Transaction.Insert("Coins", coin.TransactionId.ToBytes(false), coin.ToCoins());
                 }
                 if (originalOutputs != null)
                 {
                     TxOut[] original = null;
                     unspentToOriginal.TryGetValue(coin.TransactionId, out original);
                     if (original == null)
                     {
                         //This one did not existed before, if we rewind, delete it
                         rewindData.TransactionsToRemove.Add(coin.TransactionId);
                     }
                     else
                     {
                         //We'll need to restore the original outputs
                         var clone = coin.Clone();
                         var before = clone.UnspentCount;
                         clone._Outputs = original.ToArray();
                         rewindData.OutputsToRestore.Add(clone);
                     }
                 }
             }
             if (rewindData != null)
             {
                 int nextRewindIndex = GetRewindIndex() + 1;
                 _Session.Transaction.Insert <int, RewindData>("Rewind", nextRewindIndex, rewindData);
             }
             insertedEntities += all.Count;
             _Session.Transaction.Commit();
         }
         PerformanceCounter.AddInsertedEntities(insertedEntities);
     }));
 }