Exemplo n.º 1
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;
            }
        }
Exemplo n.º 2
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;
            }
        }
Exemplo n.º 3
0
        EvaluateActionsPerTx(AccountStateGetter accountStateGetter = null)
        {
            IAccountStateDelta delta =
                new AccountStateDeltaImpl(
                    accountStateGetter ?? (a => null)
                    );

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

                    delta = evaluation.OutputStates;
                }

                delta = new AccountStateDeltaImpl(delta.GetState);
            }
        }
Exemplo n.º 4
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{T}"/>
 /// for each <see cref="IAction"/>.</para>
 /// </summary>
 /// <param name="currentTime">The current time to validate
 /// time-wise conditions.</param>
 /// <param name="accountStateGetter">The getter of previous states.
 /// This affects the execution of <see cref="Transaction{T}.Actions"/>.
 /// </param>
 /// <returns>An <see cref="ActionEvaluation{T}"/> for each
 /// <see cref="IAction"/>.</returns>
 /// <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="InvalidTxSignatureException">Thrown when its
 /// <see cref="Transaction{T}.Signature"/> is invalid or not signed by
 /// the account who corresponds to its
 /// <see cref="Transaction{T}.PublicKey"/>.</exception>
 /// <exception cref="InvalidTxPublicKeyException">Thrown when its
 /// <see cref="Transaction{T}.Signer"/> is not derived from its
 /// <see cref="Transaction{T}.PublicKey"/>.</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>
 public IEnumerable <ActionEvaluation <T> > Evaluate(
     DateTimeOffset currentTime,
     AccountStateGetter accountStateGetter
     )
 {
     Validate(currentTime);
     (Transaction <T>, ActionEvaluation <T>)[] txEvaluations =
Exemplo n.º 5
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;
 }
Exemplo n.º 7
0
        public IEnumerable <IAccountStateDelta> EvaluateActions(
            AccountStateGetter accountStateGetter = null
            )
        {
            IAccountStateDelta delta =
                new AccountStateDeltaImpl(
                    accountStateGetter ?? (a => null)
                    );

            foreach (Transaction <T> tx in Transactions)
            {
                delta = tx.EvaluateActions(
                    Hash, Index, delta, Miner.Value);
                yield return(delta);

                delta = new AccountStateDeltaImpl(delta.GetState);
            }
        }
Exemplo n.º 8
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));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Validates the integrity of the <see cref="Block{T}"/>.
        /// <para>It throws an <see cref="InvalidBlockException"/> or
        /// an <see cref="InvalidTxException"/> if there is any
        /// integrity error.</para>
        /// <para>Otherwise it returns an <see cref="IAccountStateDelta"/>
        /// which represents the final states and maintains the changes
        /// from the states of the previous <see cref="Block{T}"/>.</para>
        /// </summary>
        /// <param name="currentTime">The current time to validate
        /// time-wise conditions.</param>
        /// <param name="accountStateGetter">The getter of previous states.
        /// This affects the execution of <see cref="Transaction{T}.Actions"/>.
        /// </param>
        /// <returns>An <see cref="IAccountStateDelta"/> of the states
        /// right after all <see cref="Transaction{T}.Actions"/> of
        /// <see cref="Transactions"/>, which maintains the changes from
        /// the states of the previous <see cref="Block{T}"/>.</returns>
        /// <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="InvalidTxSignatureException">Thrown when its
        /// <see cref="Transaction{T}.Signature"/> is invalid or not signed by
        /// the account who corresponds to its
        /// <see cref="Transaction{T}.PublicKey"/>.</exception>
        /// <exception cref="InvalidTxPublicKeyException">Thrown when its
        /// <see cref="Transaction{T}.Signer"/> is not derived from its
        /// <see cref="Transaction{T}.PublicKey"/>.</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>
        public IAccountStateDelta Validate(
            DateTimeOffset currentTime,
            AccountStateGetter accountStateGetter
            )
        {
            Validate(currentTime);
            IEnumerable <IAccountStateDelta> deltas =
                EvaluateActions(accountStateGetter);
            IAccountStateDelta result = new AccountStateDeltaImpl(
                accountStateGetter
                );

            var txUpdatedAddressesPairs = Transactions.Zip(
                deltas,
                (tx, d) => (tx, d)
                );

            foreach (var(tx, delta) in txUpdatedAddressesPairs)
            {
                IImmutableSet <Address> updatedAddresses =
                    delta.UpdatedAddresses;

                if (!tx.UpdatedAddresses.IsSupersetOf(updatedAddresses))
                {
                    var msg =
                        "Actions in the transaction try to update " +
                        "the addresses not granted.";
                    throw new InvalidTxUpdatedAddressesException(
                              tx.Id,
                              tx.UpdatedAddresses,
                              updatedAddresses,
                              msg
                              );
                }

                foreach (var pair in delta.GetUpdatedStates())
                {
                    result = result.SetState(pair.Key, pair.Value);
                }
            }

            return(result);
        }
Exemplo n.º 10
0
        public IEnumerable <IAccountStateDelta> EvaluateActions(
            AccountStateGetter accountStateGetter = null
            )
        {
            var pairs = EvaluateActionsPerTx(accountStateGetter);
            int i     = 0;

            foreach (var(tx, evaluation) in pairs)
            {
                if (++i < tx.Actions.Count)
                {
                    continue;
                }

                yield return(evaluation.OutputStates);

                i = 0;
            }
        }
Exemplo n.º 11
0
        public static AvatarState GetAvatarState(this AccountStateGetter accountStateGetter, Address avatarAddress)
        {
            if (accountStateGetter(avatarAddress) is Dictionary dictionary)
            {
                string[] keys =
                {
                    LegacyInventoryKey,
                    LegacyWorldInformationKey,
                    LegacyQuestListKey,
                };

                bool v1 = false;
                var  serializedAvatar = dictionary;

                foreach (var key in keys)
                {
                    var keyAddress = avatarAddress.Derive(key);
                    var serialized = accountStateGetter(keyAddress);
                    if (serialized is null)
                    {
                        v1 = true;
                        break;
                    }

                    serializedAvatar = serializedAvatar.SetItem(key, serialized);
                }

                if (v1)
                {
                    return(new AvatarState(dictionary));
                }

                return(new AvatarState(serializedAvatar));
            }

            throw new InvalidAddressException($"Can't find {nameof(AvatarState)} from {avatarAddress}");
        }
Exemplo n.º 12
0
 /// <summary>
 /// Creates a null delta from the given
 /// <paramref name="accountStateGetter"/>.
 /// </summary>
 /// <param name="accountStateGetter">A view to the &#x201c;epoch&#x201d;
 /// states.</param>
 internal AccountStateDeltaImpl(AccountStateGetter accountStateGetter)
 {
     _accountStateGetter = accountStateGetter;
     _updatedStates      = ImmutableDictionary <Address, object> .Empty;
 }
Exemplo n.º 13
0
 /// <summary>
 /// Creates a null delta from the given
 /// <paramref name="accountStateGetter"/>.
 /// </summary>
 /// <param name="accountStateGetter">A view to the &#x201c;epoch&#x201d;
 /// states.</param>
 internal AccountStateDeltaImpl(AccountStateGetter accountStateGetter)
 {
     _accountStateGetter = accountStateGetter;
     _updatedStates      = default(Dictionary);
 }
 public override IAccountStateDelta CreateInstance(
     AccountStateGetter accountStateGetter,
     AccountBalanceGetter accountBalanceGetter,
     Address signer
     ) =>
 new AccountStateDeltaImpl(accountStateGetter, accountBalanceGetter, signer);