예제 #1
0
        IEnumerable <Tuple <Transaction <T>, ActionEvaluation> > EvaluateActionsPerTx(
            AccountStateGetter accountStateGetter     = null,
            AccountBalanceGetter accountBalanceGetter = null
            )
        {
            accountStateGetter ??= a => null;
            accountBalanceGetter ??= (a, c) => 0;

            IAccountStateDelta delta;

            foreach (Transaction <T> tx in Transactions)
            {
                delta = new AccountStateDeltaImpl(
                    accountStateGetter,
                    accountBalanceGetter,
                    tx.Signer
                    );
                IEnumerable <ActionEvaluation> evaluations =
                    tx.EvaluateActionsGradually(
                        Hash,
                        Index,
                        delta,
                        Miner.Value);
                foreach (var evaluation in evaluations)
                {
                    yield return(Tuple.Create(tx, evaluation));

                    delta = evaluation.OutputStates;
                }

                accountStateGetter   = delta.GetState;
                accountBalanceGetter = delta.GetBalance;
            }
        }
예제 #2
0
        IEnumerable <Tuple <Transaction <T>, ActionEvaluation> > EvaluateActionsPerTx(
            AccountStateGetter accountStateGetter     = null,
            AccountBalanceGetter accountBalanceGetter = null,
            ITrie previousBlockStatesTrie             = null
            )
        {
            accountStateGetter ??= a => null;
            accountBalanceGetter ??= (a, c) => new FungibleAssetValue(c);

            IAccountStateDelta delta;

            foreach (Transaction <T> tx in Transactions)
            {
                delta = ProtocolVersion > 0
                    ? new AccountStateDeltaImpl(accountStateGetter, accountBalanceGetter, tx.Signer)
                    : new AccountStateDeltaImplV0(
                    accountStateGetter, accountBalanceGetter, tx.Signer);
                IEnumerable <ActionEvaluation> evaluations =
                    tx.EvaluateActionsGradually(
                        PreEvaluationHash,
                        Index,
                        delta,
                        Miner.Value,
                        previousBlockStatesTrie: previousBlockStatesTrie);
                foreach (var evaluation in evaluations)
                {
                    yield return(Tuple.Create(tx, evaluation));

                    delta = evaluation.OutputStates;
                }

                accountStateGetter   = delta.GetState;
                accountBalanceGetter = delta.GetBalance;
            }
        }
예제 #3
0
 internal AccountStateDeltaImplV0(
     AccountStateGetter accountStateGetter,
     AccountBalanceGetter accountBalanceGetter,
     Address signer
     )
     : base(accountStateGetter, accountBalanceGetter, signer)
 {
 }
 /// <summary>
 /// Creates a null delta from the given <paramref name="accountStateGetter"/>.
 /// </summary>
 /// <param name="accountStateGetter">A view to the &#x201c;epoch&#x201d; states.</param>
 /// <param name="accountBalanceGetter">A view to the &#x201c;epoch&#x201d; asset balances.
 /// </param>
 /// <param name="signer">A signer address. Used for authenticating if a signer is allowed
 /// to mint a currency.</param>
 internal AccountStateDeltaImpl(
     AccountStateGetter accountStateGetter,
     AccountBalanceGetter accountBalanceGetter,
     Address signer
     )
 {
     StateGetter      = accountStateGetter;
     BalanceGetter    = accountBalanceGetter;
     UpdatedStates    = ImmutableDictionary <Address, IValue> .Empty;
     UpdatedFungibles = ImmutableDictionary <(Address, Currency), BigInteger> .Empty;
     Signer           = signer;
 }
예제 #5
0
        /// <summary>
        /// Executes every <see cref="IAction"/> in the
        /// <see cref="Transactions"/> and gets result states of each step of
        /// every <see cref="Transaction{T}"/>.
        /// <para>It throws an <see cref="InvalidBlockException"/> or
        /// an <see cref="InvalidTxException"/> if there is any
        /// integrity error.</para>
        /// <para>Otherwise it enumerates an <see cref="ActionEvaluation"/>
        /// for each <see cref="IAction"/>.</para>
        /// </summary>
        /// <param name="currentTime">The current time to validate
        /// time-wise conditions.</param>
        /// <param name="accountStateGetter">An <see cref="AccountStateGetter"/> delegate to get
        /// a previous state.  A <c>null</c> value, which is default, means a constant function
        /// that returns <c>null</c>.
        /// This affects the execution of <see cref="Transaction{T}.Actions"/>.
        /// </param>
        /// <param name="accountBalanceGetter">An <see cref="AccountBalanceGetter"/> delegate to
        /// get previous account balance.
        /// A <c>null</c> value, which is default, means a constant function that returns zero.
        /// This affects the execution of <see cref="Transaction{T}.Actions"/>.
        /// </param>
        /// <param name="previousBlockStatesTrie">The trie to contain states at previous block.
        /// </param>
        /// <returns>An <see cref="ActionEvaluation"/> for each
        /// <see cref="IAction"/>.</returns>
        /// <exception cref="InvalidBlockHashException">Thrown when
        /// the <see cref="Hash"/> is invalid.</exception>
        /// <exception cref="InvalidBlockTimestampException">Thrown when
        /// the <see cref="Timestamp"/> is invalid, for example, it is the far
        /// future than the given <paramref name="currentTime"/>.</exception>
        /// <exception cref="InvalidBlockIndexException">Thrown when
        /// the <see cref="Index"/>is invalid, for example, it is a negative
        /// integer.</exception>
        /// <exception cref="InvalidBlockDifficultyException">Thrown when
        /// the <see cref="Difficulty"/> is not properly configured,
        /// for example, it is too easy.</exception>
        /// <exception cref="InvalidBlockPreviousHashException">Thrown when
        /// <see cref="PreviousHash"/> is invalid so that
        /// the <see cref="Block{T}"/>s are not continuous.</exception>
        /// <exception cref="InvalidBlockNonceException">Thrown when
        /// the <see cref="Nonce"/> does not satisfy its
        /// <see cref="Difficulty"/> level.</exception>
        /// <exception cref="InvalidBlockTxHashException">Thrown when
        /// the <see cref="TxHash" /> does not match with its
        /// <see cref="Transactions"/>.</exception>
        /// <exception cref="InvalidTxUpdatedAddressesException">Thrown when
        /// any <see cref="IAction"/> of <see cref="Transactions"/> tries
        /// to update the states of <see cref="Address"/>es not included
        /// in <see cref="Transaction{T}.UpdatedAddresses"/>.</exception>
        /// <exception cref="InvalidTxSignatureException">Thrown when its
        /// <see cref="Transaction{T}.Signature"/> is invalid or not signed by
        /// the account who corresponds to its <see cref="PublicKey"/>.
        /// </exception>
        /// <exception cref="InvalidTxPublicKeyException">Thrown when its
        /// <see cref="Transaction{T}.Signer"/> is not derived from its
        /// <see cref="Transaction{T}.PublicKey"/>.</exception>
        public IEnumerable <ActionEvaluation> Evaluate(
            DateTimeOffset currentTime,
            AccountStateGetter accountStateGetter     = null,
            AccountBalanceGetter accountBalanceGetter = null,
            ITrie previousBlockStatesTrie             = null
            )
        {
            accountStateGetter ??= a => null;
            accountBalanceGetter ??= (a, c) => new FungibleAssetValue(c);

            Validate(currentTime);
            Tuple <Transaction <T>, ActionEvaluation>[] txEvaluations =
                EvaluateActionsPerTx(
                    accountStateGetter, accountBalanceGetter, previousBlockStatesTrie).ToArray();

            var txUpdatedAddressesPairs = txEvaluations
                                          .GroupBy(tuple => tuple.Item1)
                                          .Select(
                grp => (
                    grp.Key,
                    grp.Last().Item2.OutputStates.UpdatedAddresses
                    )
                );

            foreach (
                (Transaction <T> tx, IImmutableSet <Address> updatedAddresses)
                in txUpdatedAddressesPairs)
            {
                if (!tx.UpdatedAddresses.IsSupersetOf(updatedAddresses))
                {
                    const string msg =
                        "Actions in the transaction try to update " +
                        "the addresses not granted.";
                    throw new InvalidTxUpdatedAddressesException(
                              tx.Id,
                              tx.UpdatedAddresses,
                              updatedAddresses,
                              msg
                              );
                }
            }

            return(txEvaluations.Select(te => te.Item2));
        }
 public override IAccountStateDelta CreateInstance(
     AccountStateGetter accountStateGetter,
     AccountBalanceGetter accountBalanceGetter,
     Address signer
     ) =>
 new AccountStateDeltaImpl(accountStateGetter, accountBalanceGetter, signer);