Esempio n. 1
0
        internal void Append(
            Block <T> block,
            DateTimeOffset currentTime,
            bool render
            )
        {
            _rwlock.EnterUpgradeableReadLock();
            ActionEvaluation <T>[] evaluations;
            try
            {
                HashDigest <SHA256>?tip =
                    Store.IndexBlockHash(Id.ToString(), -1);

                block.Validate(
                    currentTime,
                    a => GetStates(new[] { a }, tip).GetValueOrDefault(a));
                InvalidBlockException e =
                    Policy.ValidateNextBlock(this, block);

                if (!(e is null))
                {
                    throw e;
                }

                evaluations = EvaluateActions(block);
                _rwlock.EnterWriteLock();
                try
                {
                    Blocks[block.Hash] = block;
                    SetStates(block, evaluations);

                    Store.AppendIndex(Id.ToString(), block.Hash);
                    ISet <TxId> txIds = block.Transactions
                                        .Select(t => t.Id)
                                        .ToImmutableHashSet();

                    Store.UnstageTransactionIds(txIds);
                }
                finally
                {
                    _rwlock.ExitWriteLock();
                }
            }
            finally
            {
                _rwlock.ExitUpgradeableReadLock();
            }

            if (render)
            {
                foreach (var evaluation in evaluations)
                {
                    evaluation.Action.Render(
                        evaluation.InputContext,
                        evaluation.OutputStates
                        );
                }
            }
        }
Esempio n. 2
0
        public void Validate(
            IReadOnlyList <Block <T> > blocks,
            DateTimeOffset currentTime
            )
        {
            InvalidBlockException e =
                Policy.ValidateBlocks(blocks, currentTime);

            if (e != null)
            {
                throw e;
            }
        }
Esempio n. 3
0
        public void Validate(
            IEnumerable <Block <T> > blocks, DateTimeOffset currentTime)
        {
            foreach (Block <T> block in blocks)
            {
                block.Validate(currentTime);
            }

            InvalidBlockException e =
                Policy.ValidateBlocks(blocks, currentTime);

            if (e != null)
            {
                throw e;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Checks if <paramref name="blocks"/> are invalid, and if that
        /// returns the reason.
        /// <para>Note that it returns <c>null</c> when blocks are
        /// <em>valid</em>.</para>
        /// </summary>
        /// <param name="policy"><see cref="IBlockPolicy{T}"/> to used for
        /// validation <paramref name="blocks"/>.</param>
        /// <param name="blocks">Consecutive <see cref="Block{T}"/>s to
        /// validate.</param>
        /// <param name="currentTime">The current time to be used to validate
        /// of <see cref="Block{T}.Timestamp"/>s.
        /// Usually <see cref="DateTimeOffset.UtcNow"/> is used.</param>
        /// <returns>The reason why the given <paramref name="blocks"/> are
        /// <em>invalid</em>, or <c>null</c> if <paramref name="blocks"/> are
        /// <em>valid</em>.</returns>
        /// <typeparam name="T">An <see cref="IAction"/> type.  It should match
        /// to <see cref="Block{T}"/>'s type parameter.</typeparam>
        /// <seealso cref="IBlockPolicy{T}"/>
        /// <seealso cref="IBlockPolicy{T}.ValidateNextBlock"/>
        public static InvalidBlockException ValidateBlocks <T>(
            this IBlockPolicy <T> policy,
            IReadOnlyList <Block <T> > blocks,
            DateTimeOffset currentTime)
            where T : IAction, new()
        {
            var tempBlocks = new List <Block <T> >();

            foreach (Block <T> block in blocks)
            {
                InvalidBlockException exception =
                    policy.ValidateNextBlock(tempBlocks, block);
                if (!(exception is null))
                {
                    return(exception);
                }

                tempBlocks.Add(block);
            }

            return(null);
        }
Esempio n. 5
0
        internal void Append(
            Block <T> block,
            DateTimeOffset currentTime,
            bool evaluateActions,
            bool renderActions
            )
        {
            if (!evaluateActions && renderActions)
            {
                throw new ArgumentException(
                          $"{nameof(renderActions)} option requires {nameof(evaluateActions)} " +
                          "to be turned on.",
                          nameof(renderActions)
                          );
            }

            _rwlock.EnterUpgradeableReadLock();
            try
            {
                InvalidBlockException e =
                    Policy.ValidateNextBlock(this, block);

                if (!(e is null))
                {
                    throw e;
                }

                HashDigest <SHA256>?tip = Store.IndexBlockHash(Id, -1);

                var nonceDeltas = new Dictionary <Address, long>();

                // block.Transactions have already been sorted by
                // the tx nounce order when the block was created
                foreach (Transaction <T> tx1 in block.Transactions)
                {
                    Address txSigner = tx1.Signer;
                    nonceDeltas.TryGetValue(txSigner, out var nonceDelta);

                    long expectedNonce = nonceDelta + Store.GetTxNonce(Id, txSigner);

                    if (!expectedNonce.Equals(tx1.Nonce))
                    {
                        throw new InvalidTxNonceException(
                                  tx1.Id,
                                  expectedNonce,
                                  tx1.Nonce,
                                  "Transaction nonce is invalid."
                                  );
                    }

                    nonceDeltas[txSigner] = nonceDelta + 1;
                }

                _rwlock.EnterWriteLock();
                try
                {
                    Block <T> prevTip = Tip;
                    Blocks[block.Hash] = block;
                    foreach (KeyValuePair <Address, long> pair in nonceDeltas)
                    {
                        Store.IncreaseTxNonce(Id, pair.Key, pair.Value);
                    }

                    Store.AppendIndex(Id, block.Hash);
                    var tipChangedEventArgs = new TipChangedEventArgs
                    {
                        PreviousIndex = prevTip?.Index,
                        PreviousHash  = prevTip?.Hash,
                        Index         = block.Index,
                        Hash          = block.Hash,
                    };
                    TipChanged?.Invoke(this, tipChangedEventArgs);
                    ISet <TxId> txIds = block.Transactions
                                        .Select(t => t.Id)
                                        .ToImmutableHashSet();

                    Store.UnstageTransactionIds(txIds);
                }
                finally
                {
                    _rwlock.ExitWriteLock();
                }
            }
            finally
            {
                _rwlock.ExitUpgradeableReadLock();
            }

            if (evaluateActions)
            {
                ExecuteActions(block, renderActions);
            }
        }
Esempio n. 6
0
 public NullPolicy(InvalidBlockException exceptionToThrow = null, long difficulty = 1)
 {
     _exceptionToThrow = exceptionToThrow;
     _difficulty       = difficulty;
 }
 public NullPolicy(InvalidBlockException exceptionToThrow = null)
 {
     _exceptionToThrow = exceptionToThrow;
 }
Esempio n. 8
0
        internal void Append(
            Block <T> block,
            DateTimeOffset currentTime,
            bool evaluateActions,
            bool renderActions
            )
        {
            if (!evaluateActions && renderActions)
            {
                throw new ArgumentException(
                          $"{nameof(renderActions)} option requires {nameof(evaluateActions)} " +
                          "to be turned on.",
                          nameof(renderActions)
                          );
            }

            _rwlock.EnterUpgradeableReadLock();
            try
            {
                InvalidBlockException e =
                    Policy.ValidateNextBlock(this, block);

                if (!(e is null))
                {
                    throw e;
                }

                string ns = Id.ToString();
                HashDigest <SHA256>?tip = Store.IndexBlockHash(ns, -1);

                var nonceDeltas = new Dictionary <Address, long>();
                foreach (Transaction <T> tx1 in block.Transactions)
                {
                    Address txSigner = tx1.Signer;
                    nonceDeltas.TryGetValue(txSigner, out var nonceDelta);

                    long expectedNonce = nonceDelta + Store.GetTxNonce(Id.ToString(), txSigner);

                    if (!expectedNonce.Equals(tx1.Nonce))
                    {
                        throw new InvalidTxNonceException(
                                  tx1.Id,
                                  expectedNonce,
                                  tx1.Nonce,
                                  "Transaction nonce is invalid."
                                  );
                    }

                    nonceDeltas[txSigner] = nonceDelta + 1;
                }

                _rwlock.EnterWriteLock();
                try
                {
                    Blocks[block.Hash] = block;
                    foreach (KeyValuePair <Address, long> pair in nonceDeltas)
                    {
                        Store.IncreaseTxNonce(ns, pair.Key, pair.Value);
                    }

                    Store.AppendIndex(ns, block.Hash);
                    ISet <TxId> txIds = block.Transactions
                                        .Select(t => t.Id)
                                        .ToImmutableHashSet();

                    Store.UnstageTransactionIds(txIds);
                }
                finally
                {
                    _rwlock.ExitWriteLock();
                }
            }
            finally
            {
                _rwlock.ExitUpgradeableReadLock();
            }

            if (evaluateActions)
            {
                ExecuteActions(block, renderActions);
            }
        }
Esempio n. 9
0
        internal static Exception TransformSqlException(Exception e)
        {
            Exception containerNotFoundException;

            if (e is ArgumentOutOfRangeException)
            {
                return(new XStoreArgumentOutOfRangeException(e.Message, e));
            }
            if (e is ArgumentException)
            {
                return(new XStoreArgumentException(e.Message, e));
            }
            if (e is InvalidOperationException)
            {
                if (e.Message.Contains("Null values are not supported in key members"))
                {
                    return(new TableServiceGeneralException(TableServiceError.PropertiesNeedValue, e));
                }
                if (!e.Message.Contains("Resource not found for the segment"))
                {
                    goto Label1;
                }
                string message  = e.Message;
                char[] chrArray = new char[] { '\'' };
                string str      = message.Split(chrArray)[1];
                using (DevelopmentStorageDbDataContext dbContext = DevelopmentStorageDbDataContext.GetDbContext())
                {
                    if ((
                            from t in dbContext.TableContainers
                            where t.TableName == str
                            select t).FirstOrDefault <Microsoft.WindowsAzure.DevelopmentStorage.Store.TableContainer>() != null)
                    {
                        containerNotFoundException = e;
                        return(containerNotFoundException);
                    }
                    else
                    {
                        containerNotFoundException = e;
                        return(containerNotFoundException);
                    }
                }
            }
Label1:
            if (!(e is SqlException))
            {
                return(e);
            }
            IEnumerator enumerator = ((SqlException)e).Errors.GetEnumerator();

            try
            {
                while (enumerator.MoveNext())
                {
                    SqlError current = (SqlError)enumerator.Current;
                    if (current.Number == 547)
                    {
                        if (!current.Message.Contains("TableContainer_TableRow"))
                        {
                            continue;
                        }
                        containerNotFoundException = new ContainerNotFoundException();
                        return(containerNotFoundException);
                    }
                    else if (current.Number != 2627)
                    {
                        if (current.Number != 8152)
                        {
                            if (current.Number != 50000)
                            {
                                continue;
                            }
                            if (current.Message == "BlockIdMismatch")
                            {
                                containerNotFoundException = new InvalidBlockException();
                                return(containerNotFoundException);
                            }
                            else if (current.Message == "InvalidBlockList")
                            {
                                containerNotFoundException = new InvalidBlockListException();
                                return(containerNotFoundException);
                            }
                            else if (current.Message == "BlobHasSnapshots")
                            {
                                containerNotFoundException = new SnapshotsPresentException();
                                return(containerNotFoundException);
                            }
                            else if (current.Message != "BlobHasNoSnapshots")
                            {
                                if (current.Message != "EntityTooLarge")
                                {
                                    continue;
                                }
                                containerNotFoundException = new TableServiceGeneralException(TableServiceError.EntityTooLarge, e);
                                return(containerNotFoundException);
                            }
                            else
                            {
                                containerNotFoundException = new BlobNotFoundException();
                                return(containerNotFoundException);
                            }
                        }
                        else
                        {
                            containerNotFoundException = new TableServiceGeneralException(TableServiceError.PropertyValueTooLarge, e);
                            return(containerNotFoundException);
                        }
                    }
                    else if (current.Message.Contains(string.Concat("'dbo.", typeof(Microsoft.WindowsAzure.DevelopmentStorage.Store.BlobContainer).Name, "'")))
                    {
                        containerNotFoundException = new ContainerAlreadyExistsException();
                        return(containerNotFoundException);
                    }
                    else if (current.Message.Contains(string.Concat("'dbo.", typeof(Blob).Name, "'")))
                    {
                        containerNotFoundException = new BlobAlreadyExistsException();
                        return(containerNotFoundException);
                    }
                    else if (current.Message.Contains(string.Concat("'dbo.", typeof(Microsoft.WindowsAzure.DevelopmentStorage.Store.QueueContainer).Name, "'")))
                    {
                        containerNotFoundException = new ContainerAlreadyExistsException();
                        return(containerNotFoundException);
                    }
                    else if (!current.Message.Contains(string.Concat("'dbo.", typeof(Microsoft.WindowsAzure.DevelopmentStorage.Store.TableContainer).Name, "'")))
                    {
                        if (!current.Message.Contains(string.Concat("'dbo.", typeof(TableRow).Name, "'")))
                        {
                            continue;
                        }
                        containerNotFoundException = new TableServiceGeneralException(TableServiceError.EntityAlreadyExists, e);
                        return(containerNotFoundException);
                    }
                    else
                    {
                        containerNotFoundException = new ContainerAlreadyExistsException();
                        return(containerNotFoundException);
                    }
                }
                return(e);
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
            return(containerNotFoundException);
        }
Esempio n. 10
0
        internal void Append(
            Block <T> block,
            DateTimeOffset currentTime,
            bool render
            )
        {
            _rwlock.EnterUpgradeableReadLock();
            ActionEvaluation <T>[] evaluations;
            try
            {
                InvalidBlockException e =
                    Policy.ValidateNextBlock(this, block);

                if (!(e is null))
                {
                    throw e;
                }

                HashDigest <SHA256>?tip =
                    Store.IndexBlockHash(Id.ToString(), -1);

                foreach (Transaction <T> tx in block.Transactions)
                {
                    Address signer = tx.Signer;
                    long    nonce  = Store.GetTxNonce(Id.ToString(), signer);

                    if (!nonce.Equals(tx.Nonce))
                    {
                        throw new InvalidTxNonceException(
                                  tx.Id,
                                  nonce,
                                  tx.Nonce,
                                  "Transaction nonce is invalid.");
                    }
                }

                evaluations = block.Evaluate(
                    currentTime,
                    a => GetStates(new[] { a }, tip).GetValueOrDefault(a)
                    ).ToArray();

                _rwlock.EnterWriteLock();
                try
                {
                    Blocks[block.Hash] = block;
                    SetStates(block, evaluations);

                    Store.AppendIndex(Id.ToString(), block.Hash);
                    ISet <TxId> txIds = block.Transactions
                                        .Select(t => t.Id)
                                        .ToImmutableHashSet();

                    Store.UnstageTransactionIds(txIds);
                }
                finally
                {
                    _rwlock.ExitWriteLock();
                }
            }
            finally
            {
                _rwlock.ExitUpgradeableReadLock();
            }

            if (render)
            {
                foreach (var evaluation in evaluations)
                {
                    evaluation.Action.Render(
                        evaluation.InputContext,
                        evaluation.OutputStates
                        );
                }
            }
        }