Beispiel #1
0
        public override long AppendIndex(
            string @namespace,
            HashDigest <SHA256> hash
            )
        {
            var indexFile = new FileInfo(GetIndexPath(@namespace));

            using (Stream stream = indexFile.Open(
                       FileMode.Append, FileAccess.Write))
            {
                var offset = stream.Position;
                stream.Write(hash.ToByteArray(), 0, hash.ToByteArray().Length);
                return(offset / HashDigest <SHA256> .Size);
            }
        }
        public byte[] Sign(HashDigest <T> messageHash, PrivateKey privateKey)
        {
            var h           = new Sha256Digest();
            var kCalculator = new HMacDsaKCalculator(h);
            var signer      = new ECDsaSigner(kCalculator);

            signer.Init(true, privateKey.KeyParam);
            BigInteger[] rs = signer.GenerateSignature(messageHash.ToByteArray());
            var          r  = rs[0];
            var          s  = rs[1];

            BigInteger otherS = privateKey.KeyParam.Parameters.N.Subtract(s);

            if (s.CompareTo(otherS) == 1)
            {
                s = otherS;
            }

            var bos = new MemoryStream(72);
            var seq = new DerSequenceGenerator(bos);

            seq.AddObject(new DerInteger(r));
            seq.AddObject(new DerInteger(s));
            seq.Close();
            return(bos.ToArray());
        }
Beispiel #3
0
        /// <inheritdoc/>
        public override void StoreStateReference <T>(
            string @namespace,
            IImmutableSet <Address> addresses,
            Block <T> block)
        {
            HashDigest <SHA256> blockHash = block.Hash;
            long blockIndex = block.Index;
            int  hashSize   = HashDigest <SHA256> .Size;

            foreach (Address address in addresses)
            {
                var stateReferenceFile = new FileInfo(
                    GetStateReferencePath(@namespace, address));

                if (!stateReferenceFile.Directory.Exists)
                {
                    stateReferenceFile.Directory.Create();
                }

                using (Stream stream = stateReferenceFile.Open(
                           FileMode.Append, FileAccess.Write))
                {
                    stream.Write(blockHash.ToByteArray(), 0, hashSize);
                    stream.Write(
                        BitConverter.GetBytes(blockIndex), 0, sizeof(long));
                }
            }
        }
Beispiel #4
0
        /// <inheritdoc/>
        public override void StoreStateReference(
            Guid chainId,
            IImmutableSet <string> keys,
            HashDigest <SHA256> blockHash,
            long blockIndex)
        {
            ColumnFamilyHandle cf = GetColumnFamily(_stateRefDb, chainId);

            foreach (string key in keys)
            {
                byte[] keyBytes = StateRefKey(key, blockIndex);
                _stateRefDb.Put(keyBytes, blockHash.ToByteArray(), cf);
            }

            if (!_lastStateRefCaches.ContainsKey(chainId))
            {
                _lastStateRefCaches[chainId] =
                    new LruCache <string, Tuple <HashDigest <SHA256>, long> >();
            }

            LruCache <string, Tuple <HashDigest <SHA256>, long> > stateRefCache =
                _lastStateRefCaches[chainId];

            foreach (string key in keys)
            {
                _logger.Debug($"Try to set cache {key}");
                if (!stateRefCache.TryGetValue(key, out Tuple <HashDigest <SHA256>, long> cache) ||
                    cache.Item2 < blockIndex)
                {
                    stateRefCache[key] =
                        new Tuple <HashDigest <SHA256>, long>(blockHash, blockIndex);
                }
            }
        }
Beispiel #5
0
        public byte[] Sign(HashDigest <T> messageHash, PrivateKey privateKey)
        {
            lock (_instanceLock)
            {
                var secp256K1Signature = new byte[Secp256k1.SIGNATURE_LENGTH];
                var privateKeyBytes    = new byte[Secp256k1.PRIVKEY_LENGTH];

                privateKey.ByteArray.CopyTo(
                    privateKeyBytes,
                    Secp256k1.PRIVKEY_LENGTH - privateKey.ByteArray.Length);

                _instance.Sign(
                    secp256K1Signature,
                    messageHash.ToByteArray(),
                    privateKeyBytes);

                var signature = new byte[Secp256k1.SERIALIZED_DER_SIGNATURE_MAX_SIZE];
                _instance.SignatureSerializeDer(
                    signature,
                    secp256K1Signature,
                    out int signatureLength);

                return(signature.Take(signatureLength).ToArray());
            }
        }
Beispiel #6
0
        /// <inheritdoc/>
        public override void SetBlockStates(
            HashDigest <SHA256> blockHash,
            IImmutableDictionary <Address, IValue> states)
        {
            _statesCache.AddOrUpdate(blockHash, states);
            var serialized = new Bencodex.Types.Dictionary(
                states.Select(kv =>
                              new KeyValuePair <IKey, IValue>(
                                  new Binary(kv.Key.ToByteArray()),
                                  kv.Value
                                  )
                              )
                );

            using (var stream = new MemoryStream())
            {
                _codec.Encode(serialized, stream);
                stream.Seek(0, SeekOrigin.Begin);
                UploadFile(
                    BlockStateFileId(blockHash),
                    ByteUtil.Hex(blockHash.ToByteArray()),
                    stream
                    );
            }
        }
Beispiel #7
0
        public bool Verify(
            HashDigest <T> messageHash,
            byte[] signature,
            PublicKey publicKey)
        {
            try
            {
                Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(signature);

                var rs = new[]
                {
                    ((DerInteger)asn1Sequence[0]).Value,
                    ((DerInteger)asn1Sequence[1]).Value,
                };
                var verifier = new ECDsaSigner();
                verifier.Init(false, publicKey.KeyParam);

                return(verifier.VerifySignature(messageHash.ToByteArray(), rs[0], rs[1]));
            }
            catch (IOException)
            {
                return(false);
            }
            catch (Asn1ParsingException)
            {
                return(false);
            }
        }
Beispiel #8
0
 internal ITrie GetTrie(HashDigest <SHA256> blockHash)
 =>
 new MerkleTrie(
     _stateKeyValueStore,
     new HashNode(
         new HashDigest <SHA256>(
             _stateHashKeyValueStore.Get(blockHash.ToByteArray()))));
Beispiel #9
0
 internal void SetStates <T>(
     Block <T> block,
     HashDigest <SHA256> stateRootHash)
     where T : IAction, new()
 {
     _stateHashKeyValueStore.Set(
         block.Hash.ToByteArray(), stateRootHash.ToByteArray());
 }
Beispiel #10
0
 public static void AssertBytesEqual <T>(
     HashDigest <T>?expected,
     HashDigest <T>?actual
     )
     where T : HashAlgorithm
 {
     AssertBytesEqual(expected?.ToByteArray(), actual?.ToByteArray());
 }
 internal static void AssertBytesEqual <T>(
     HashDigest <T> expected,
     HashDigest <T> actual
     )
     where T : HashAlgorithm
 {
     AssertBytesEqual(expected.ToByteArray(), actual.ToByteArray());
 }
Beispiel #12
0
        public override long AppendIndex(HashDigest <SHA256> hash)
        {
            var indexFile = new FileInfo(_indexPath);

            if (!indexFile.Directory.Exists)
            {
                indexFile.Directory.Create();
            }

            using (Stream stream = indexFile.Open(
                       FileMode.Append, FileAccess.Write))
            {
                var offset = stream.Position;
                stream.Write(hash.ToByteArray(), 0, hash.ToByteArray().Length);
                return(offset / HashDigest <SHA256> .Size);
            }
        }
Beispiel #13
0
 public void StoreTxReferences(TxId txId, HashDigest <SHA256> blockHash, long txNonce)
 {
     Insert("tx_references", new Dictionary <string, object>
     {
         ["tx_id"]      = txId.ToByteArray(),
         ["tx_nonce"]   = txNonce,
         ["block_hash"] = blockHash.ToByteArray(),
     });
 }
Beispiel #14
0
        public IAccountStateDelta EvaluateActions(
            HashDigest <SHA256> blockHash,
            long blockIndex,
            IAccountStateDelta previousStates,
            Address minerAddress,
            bool rehearsal = false
            )
        {
            int seed =
                BitConverter.ToInt32(blockHash.ToByteArray(), 0) ^
                (Signature.Empty() ? 0 : BitConverter.ToInt32(Signature, 0));
            IAccountStateDelta states = previousStates;

            foreach (T action in Actions)
            {
                var context = new ActionContext(
                    signer: Signer,
                    miner: minerAddress,
                    blockIndex: blockIndex,
                    previousStates: states,
                    randomSeed: unchecked (seed++),
                    rehearsal: rehearsal
                    );
                try
                {
                    states = action.Execute(context);
                }
                catch (Exception e)
                {
                    if (!rehearsal)
                    {
                        throw;
                    }

                    var msg =
                        $"The action {action} threw an exception during its " +
                        "rehearsal.  It is probably because the logic of the " +
                        $"action {action} is not enough generic so that it " +
                        "can cover every case including rehearsal mode.\n" +
                        "The IActionContext.Rehearsal property also might be " +
                        "useful to make the action can deal with the case of " +
                        "rehearsal mode.\n" +
                        "See also this exception's InnerException property.";
                    throw new UnexpectedlyTerminatedTxRehearsalException(
                              action, msg, e
                              );
                }
            }

            return(states);
        }
Beispiel #15
0
        /// <inheritdoc/>
        public override void ForkBlockIndexes(
            Guid sourceChainId,
            Guid destinationChainId,
            HashDigest <SHA256> branchPoint)
        {
            HashDigest <SHA256>?genesisHash = IterateIndexes(sourceChainId, 0, 1)
                                              .Cast <HashDigest <SHA256>?>()
                                              .FirstOrDefault();

            if (genesisHash is null || branchPoint.Equals(genesisHash))
            {
                return;
            }

            ColumnFamilyHandle cf = GetColumnFamily(_chainDb, destinationChainId);
            var  writeBatch       = new WriteBatch();
            long index            = 0;

            try
            {
                foreach (Iterator it in IterateDb(_chainDb, IndexKeyPrefix, sourceChainId))
                {
                    byte[] hashBytes = it.Value();
                    writeBatch.Put(it.Key(), hashBytes, cf);
                    index += 1;

                    if (writeBatch.Count() >= ForkWriteBatchSize)
                    {
                        _chainDb.Write(writeBatch);
                        writeBatch.Dispose();
                        writeBatch = new WriteBatch();
                    }

                    if (branchPoint.ToByteArray().SequenceEqual(hashBytes))
                    {
                        break;
                    }
                }
            }
            finally
            {
                _chainDb.Write(writeBatch);
                writeBatch.Dispose();
            }

            _chainDb.Put(
                IndexCountKey,
                RocksDBStoreBitConverter.GetBytes(index),
                cf
                );
        }
Beispiel #16
0
 /// <inheritdoc/>
 public void SetBlockStates(
     HashDigest <SHA256> blockHash,
     AddressStateMap states)
 {
     using (var stream = new MemoryStream())
     {
         var formatter = new BinaryFormatter();
         formatter.Serialize(stream, states);
         stream.Seek(0, SeekOrigin.Begin);
         _db.FileStorage.Upload(
             BlockStateFileId(blockHash),
             ByteUtil.Hex(blockHash.ToByteArray()),
             stream);
     }
 }
Beispiel #17
0
        public bool Verify(
            HashDigest <T> messageHash,
            byte[] signature,
            PublicKey publicKey)
        {
            lock (_instanceLock)
            {
                var secp256K1Signature = new byte[64];
                _instance.SignatureParseDer(secp256K1Signature, signature);

                byte[] secp256K1PublicKey  = new byte[64];
                byte[] serializedPublicKey = publicKey.Format(false);
                _instance.PublicKeyParse(secp256K1PublicKey, serializedPublicKey);

                return(_instance.Verify(secp256K1Signature, messageHash.ToByteArray(), secp256K1PublicKey));
            }
        }
Beispiel #18
0
        public IValue?GetState(
            string stateKey,
            HashDigest <SHA256>?blockHash = null,
            Guid?chainId = null)
        {
            if (blockHash is null)
            {
                throw new ArgumentNullException(nameof(blockHash));
            }

            var stateHash = _stateHashKeyValueStore.Get(blockHash?.ToByteArray() !);
            var stateTrie = new MerkleTrie(
                _stateKeyValueStore, new HashNode(new HashDigest <SHA256>(stateHash)));
            var key = Encoding.UTF8.GetBytes(stateKey);

            return(stateTrie.TryGet(key, out IValue? value) ? value : null);
        }
Beispiel #19
0
        /// <inheritdoc/>
        public override long AppendIndex(Guid chainId, HashDigest <SHA256> hash)
        {
            long index = CountIndex(chainId);

            byte[] indexBytes = RocksDBStoreBitConverter.GetBytes(index);

            byte[]             key = IndexKeyPrefix.Concat(indexBytes).ToArray();
            ColumnFamilyHandle cf  = GetColumnFamily(_chainDb, chainId);

            using var writeBatch = new WriteBatch();

            writeBatch.Put(key, hash.ToByteArray(), cf);
            writeBatch.Put(IndexCountKey, RocksDBStoreBitConverter.GetBytes(index + 1), cf);

            _chainDb.Write(writeBatch);

            return(index);
        }
        /// <summary>
        /// Executes the <paramref name="actions"/> step by step, and emits
        /// <see cref="ActionEvaluation"/> for each step.
        /// </summary>
        /// <param name="blockHash">The <see cref="Block{T}.Hash"/> of <see cref="Block{T}"/> that
        /// <paramref name="actions"/> belongs to.</param>
        /// <param name="blockIndex">The <see cref="Block{T}.Index"/> of <see cref="Block{T}"/> that
        /// <paramref name="actions"/> belongs to.</param>
        /// <param name="txid">The <see cref="Transaction{T}.Id"/> of <see cref="Transaction{T}"/>
        /// that <paramref name="actions"/> belongs to.  This can be <c>null</c> on rehearsal mode
        /// or if an action is a <see cref="IBlockPolicy{T}.BlockAction"/>.</param>
        /// <param name="previousStates">The states immediately before <paramref name="actions"/>
        /// being executed.  Note that its <see cref="IAccountStateDelta.UpdatedAddresses"/> are
        /// remained to the returned next states.</param>
        /// <param name="minerAddress">An address of block miner.</param>
        /// <param name="signer">Signer of the <paramref name="actions"/>.</param>
        /// <param name="signature"><see cref="Transaction{T}"/> signature used to generate random
        /// seeds.</param>
        /// <param name="actions">Actions to evaluate.</param>
        /// <param name="rehearsal">Pass <c>true</c> if it is intended
        /// to be dry-run (i.e., the returned result will be never used).
        /// The default value is <c>false</c>.</param>
        /// <param name="previousBlockStatesTrie">The trie to contain states at previous block.
        /// </param>
        /// <param name="blockAction">Pass <c>true</c> if it is
        /// <see cref="IBlockPolicy{T}.BlockAction"/>.</param>
        /// <returns>Enumerates <see cref="ActionEvaluation"/>s for each one in
        /// <paramref name="actions"/>.  The order is the same to the <paramref name="actions"/>.
        /// Note that each <see cref="IActionContext.Random"/> object
        /// has a unconsumed state.
        /// </returns>
        internal static IEnumerable <ActionEvaluation> EvaluateActionsGradually(
            HashDigest <SHA256> blockHash,
            long blockIndex,
            TxId?txid,
            IAccountStateDelta previousStates,
            Address minerAddress,
            Address signer,
            byte[] signature,
            IImmutableList <IAction> actions,
            bool rehearsal = false,
            ITrie previousBlockStatesTrie = null,
            bool blockAction = false)
        {
            ActionContext CreateActionContext(
                IAccountStateDelta prevStates,
                int randomSeed
                ) =>
            new ActionContext(
                signer: signer,
                miner: minerAddress,
                blockIndex: blockIndex,
                previousStates: prevStates,
                randomSeed: randomSeed,
                rehearsal: rehearsal,
                previousBlockStatesTrie: previousBlockStatesTrie,
                blockAction: blockAction
                );

            byte[] hashedSignature;
            using (var hasher = SHA1.Create())
            {
                hashedSignature = hasher.ComputeHash(signature);
            }

            int seed =
                BitConverter.ToInt32(blockHash.ToByteArray(), 0) ^
                (signature.Any() ? BitConverter.ToInt32(hashedSignature, 0) : 0);

            IAccountStateDelta states = previousStates;
            Exception          exc    = null;

            foreach (IAction action in actions)
            {
                ActionContext      context    = CreateActionContext(states, seed);
                IAccountStateDelta nextStates = context.PreviousStates;
                try
                {
                    DateTimeOffset actionExecutionStarted = DateTimeOffset.Now;
                    nextStates = action.Execute(context);
                    TimeSpan spent = DateTimeOffset.Now - actionExecutionStarted;

                    Log.Verbose($"{action} execution spent {spent.TotalMilliseconds} ms.");
                }
                catch (Exception e)
                {
                    if (rehearsal)
                    {
                        var msg =
                            $"The action {action} threw an exception during its " +
                            "rehearsal.  It is probably because the logic of the " +
                            $"action {action} is not enough generic so that it " +
                            "can cover every case including rehearsal mode.\n" +
                            "The IActionContext.Rehearsal property also might be " +
                            "useful to make the action can deal with the case of " +
                            "rehearsal mode.\n" +
                            "See also this exception's InnerException property.";
                        exc = new UnexpectedlyTerminatedActionException(
                            null, null, null, null, action, msg, e
                            );
                    }
                    else
                    {
                        var stateRootHash = context.PreviousStateRootHash;
                        var msg           =
                            $"The action {action} (block #{blockIndex} {blockHash}, tx {txid}, " +
                            $"state root hash {stateRootHash}) threw an exception " +
                            "during execution.  See also this exception's InnerException property.";
                        Log.Error("{Message}\nInnerException: {ExcMessage}", msg, e.Message);
                        exc = new UnexpectedlyTerminatedActionException(
                            blockHash, blockIndex, txid, stateRootHash, action, msg, e
                            );
                    }
                }

                // As IActionContext.Random is stateful, we cannot reuse
                // the context which is once consumed by Execute().
                ActionContext equivalentContext = CreateActionContext(states, seed);

                yield return(new ActionEvaluation(
                                 action,
                                 equivalentContext,
                                 nextStates,
                                 exc
                                 ));

                states = nextStates;
                unchecked
                {
                    seed++;
                }
            }
        }
Beispiel #21
0
 private byte[] BlockStateKey(HashDigest <SHA256> blockHash)
 {
     return(BlockStateKeyPrefix.Concat(blockHash.ToByteArray()).ToArray());
 }
Beispiel #22
0
 public bool ContainsBlockStates(HashDigest <SHA256> blockHash)
 {
     return(_stateHashKeyValueStore.Exists(blockHash.ToByteArray()));
 }
Beispiel #23
0
 public HashDigest <SHA256> GetRootHash(HashDigest <SHA256> blockHash)
 => new HashDigest <SHA256>(_stateHashKeyValueStore.Get(blockHash.ToByteArray()));
        EvaluateActionsGradually(
            HashDigest <SHA256> blockHash,
            long blockIndex,
            IAccountStateDelta previousStates,
            Address minerAddress,
            bool rehearsal = false
            )
        {
            ActionContext CreateActionContext(
                IAccountStateDelta prevStates,
                int randomSeed
                ) =>
            new ActionContext(
                signer: Signer,
                miner: minerAddress,
                blockIndex: blockIndex,
                previousStates: prevStates,
                randomSeed: randomSeed,
                rehearsal: rehearsal
                );

            int seed =
                BitConverter.ToInt32(blockHash.ToByteArray(), 0) ^
                (Signature.Any() ? BitConverter.ToInt32(Signature, 0) : 0);
            IAccountStateDelta states = previousStates;

            foreach (T action in Actions)
            {
                ActionContext context =
                    CreateActionContext(states, seed);
                IAccountStateDelta nextStates;
                try
                {
                    nextStates = action.Execute(context);
                }
                catch (Exception e)
                {
                    if (!rehearsal)
                    {
                        throw;
                    }

                    var msg =
                        $"The action {action} threw an exception during its " +
                        "rehearsal.  It is probably because the logic of the " +
                        $"action {action} is not enough generic so that it " +
                        "can cover every case including rehearsal mode.\n" +
                        "The IActionContext.Rehearsal property also might be " +
                        "useful to make the action can deal with the case of " +
                        "rehearsal mode.\n" +
                        "See also this exception's InnerException property.";
                    throw new UnexpectedlyTerminatedTxRehearsalException(
                              action, msg, e
                              );
                }

                // As IActionContext.Random is stateful, we cannot reuse
                // the context which is once consumed by Execute().
                ActionContext equivalentContext =
                    CreateActionContext(states, seed);

                yield return(new ActionEvaluation <T>(
                                 action,
                                 equivalentContext,
                                 nextStates
                                 ));

                states = nextStates;
                unchecked
                {
                    seed++;
                }
            }
        }
Beispiel #25
0
        /// <summary>
        /// Executes the <paramref name="actions"/> step by step, and emits
        /// <see cref="ActionEvaluation"/> for each step.
        /// </summary>
        /// <param name="blockHash">The <see cref="Block{T}.Hash"/> of <see cref="Block{T}"/> that
        /// <paramref name="actions"/> belongs to.</param>
        /// <param name="blockIndex">The <see cref="Block{T}.Index"/> of <see cref="Block{T}"/> that
        /// <paramref name="actions"/> belongs to.</param>
        /// <param name="txid">The <see cref="Transaction{T}.Id"/> of <see cref="Transaction{T}"/>
        /// that <paramref name="actions"/> belongs to.  This can be <c>null</c> on rehearsal mode
        /// or if an action is a <see cref="IBlockPolicy{T}.BlockAction"/>.</param>
        /// <param name="previousStates">The states immediately before <paramref name="actions"/>
        /// being executed.  Note that its <see cref="IAccountStateDelta.UpdatedAddresses"/> are
        /// remained to the returned next states.</param>
        /// <param name="minerAddress">An address of block miner.</param>
        /// <param name="signer">Signer of the <paramref name="actions"/>.</param>
        /// <param name="signature"><see cref="Transaction{T}"/> signature used to generate random
        /// seeds.</param>
        /// <param name="actions">Actions to evaluate.</param>
        /// <param name="rehearsal">Pass <c>true</c> if it is intended
        /// to be dry-run (i.e., the returned result will be never used).
        /// The default value is <c>false</c>.</param>
        /// <returns>Enumerates <see cref="ActionEvaluation"/>s for each one in
        /// <paramref name="actions"/>.  The order is the same to the <paramref name="actions"/>.
        /// Note that each <see cref="IActionContext.Random"/> object
        /// has a unconsumed state.
        /// </returns>
        internal static IEnumerable <ActionEvaluation> EvaluateActionsGradually(
            HashDigest <SHA256> blockHash,
            long blockIndex,
            TxId?txid,
            IAccountStateDelta previousStates,
            Address minerAddress,
            Address signer,
            byte[] signature,
            IImmutableList <IAction> actions,
            bool rehearsal = false)
        {
            ActionContext CreateActionContext(
                IAccountStateDelta prevStates,
                int randomSeed
                ) =>
            new ActionContext(
                signer: signer,
                miner: minerAddress,
                blockIndex: blockIndex,
                previousStates: prevStates,
                randomSeed: randomSeed,
                rehearsal: rehearsal
                );

            byte[] hashedSignature;
            using (var hasher = SHA1.Create())
            {
                hashedSignature = hasher.ComputeHash(signature);
            }

            int seed =
                BitConverter.ToInt32(blockHash.ToByteArray(), 0) ^
                (signature.Any() ? BitConverter.ToInt32(hashedSignature, 0) : 0);

            IAccountStateDelta states = previousStates;
            Exception          exc    = null;

            foreach (IAction action in actions)
            {
                ActionContext      context    = CreateActionContext(states, seed);
                IAccountStateDelta nextStates = context.PreviousStates;
                try
                {
                    nextStates = action.Execute(context);
                }
                catch (Exception e)
                {
                    string msg;
                    if (!rehearsal)
                    {
                        // FIXME: The below "exc" object seems never used; Hong Minhee believes
                        // this code's behavior does not follow the intention.
                        msg = $"The action {action} (block #{blockIndex} {blockHash}, tx {txid}) " +
                              "threw an exception during execution.  See also this exception's " +
                              "InnerException property.";
                        exc = new UnexpectedlyTerminatedActionException(
                            blockHash, blockIndex, txid, action, msg, e
                            );
                    }

                    msg =
                        $"The action {action} threw an exception during its " +
                        "rehearsal.  It is probably because the logic of the " +
                        $"action {action} is not enough generic so that it " +
                        "can cover every case including rehearsal mode.\n" +
                        "The IActionContext.Rehearsal property also might be " +
                        "useful to make the action can deal with the case of " +
                        "rehearsal mode.\n" +
                        "See also this exception's InnerException property.";
                    exc = new UnexpectedlyTerminatedActionException(
                        null, null, null, action, msg, e
                        );
                }

                // As IActionContext.Random is stateful, we cannot reuse
                // the context which is once consumed by Execute().
                ActionContext equivalentContext = CreateActionContext(states, seed);

                yield return(new ActionEvaluation(
                                 action,
                                 equivalentContext,
                                 nextStates,
                                 exc
                                 ));

                states = nextStates;
                unchecked
                {
                    seed++;
                }
            }
        }
Beispiel #26
0
 private INode?GetNode(HashDigest <SHA256> nodeHash)
 {
     return(NodeDecoder.Decode(
                _codec.Decode(KeyValueStore.Get(nodeHash.ToByteArray()))));
 }
Beispiel #27
0
 public static IValue Serialize(this HashDigest <SHA256> hashDigest)
 {
     return(new Binary(hashDigest.ToByteArray()));
 }