public void transaction_is_addable_to_block_after_fill()
        {
            int chainId     = 5;
            var blockHeader = Build.A.BlockHeader.TestObject;
            var tx          = Build.A.GeneratedTransaction.WithSenderAddress(TestItem.AddressA).TestObject;
            var timestamper = Substitute.For <ITimestamper>();
            var stateReader = Substitute.For <IStateReader>();
            var nodeAddress = TestItem.AddressA;

            UInt256 expectedNonce = 10;

            stateReader.GetNonce(blockHeader.StateRoot, nodeAddress).Returns(expectedNonce);

            ulong expectedTimeStamp = 100;

            timestamper.EpochSeconds.Returns(expectedTimeStamp);

            var gasLimit      = 200;
            var innerTxSource = Substitute.For <ITxSource>();

            innerTxSource.GetTransactions(blockHeader, gasLimit).Returns(new[] { tx });

            TxSealer txSealer          = new TxSealer(new Signer(chainId, Build.A.PrivateKey.TestObject, LimboLogs.Instance), timestamper);
            var      transactionFiller = new GeneratedTxSourceSealer(innerTxSource, txSealer, stateReader, LimboLogs.Instance);

            var txResult = transactionFiller.GetTransactions(blockHeader, gasLimit).First();

            txResult.IsSigned.Should().BeTrue();
            txResult.Nonce.Should().Be(expectedNonce);
            txResult.Hash.Should().Be(tx.CalculateHash());
            txResult.Timestamp.Should().Be(expectedTimeStamp);
        }
        protected override ITxSource CreateTxSourceForProducer(ReadOnlyTxProcessingEnv readOnlyTxProcessingEnv, ReadOnlyTransactionProcessorSource readOnlyTransactionProcessorSource)
        {
            bool CheckAddPosdaoTransactions(IList <ITxSource> list, long auRaPosdaoTransition)
            {
                if (auRaPosdaoTransition < AuRaParameters.TransitionDisabled && _validator is ITxSource validatorSource)
                {
                    list.Insert(0, validatorSource);
                    return(true);
                }

                return(false);
            }

            bool CheckAddRandomnessTransactions(IList <ITxSource> list, IDictionary <long, Address> randomnessContractAddress, ISigner signer)
            {
                IList <IRandomContract> GetRandomContracts(
                    IDictionary <long, Address> randomnessContractAddressPerBlock,
                    IAbiEncoder abiEncoder,
                    IReadOnlyTransactionProcessorSource txProcessorSource,
                    ISigner signer) =>
                randomnessContractAddressPerBlock
                .Select(kvp => new RandomContract(
                            abiEncoder,
                            kvp.Value,
                            txProcessorSource,
                            kvp.Key,
                            signer))
                .ToArray <IRandomContract>();

                if (randomnessContractAddress?.Any() == true)
                {
                    var randomContractTxSource = new RandomContractTxSource(
                        GetRandomContracts(randomnessContractAddress, _context.AbiEncoder,
                                           readOnlyTransactionProcessorSource,
                                           signer),
                        new EciesCipher(_context.CryptoRandom),
                        _context.NodeKey,
                        _context.CryptoRandom);

                    list.Insert(0, randomContractTxSource);
                    return(true);
                }

                return(false);
            }

            if (_context.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(_context.ChainSpec));
            }
            if (_context.BlockTree == null)
            {
                throw new StepDependencyException(nameof(_context.BlockTree));
            }
            if (_context.Signer == null)
            {
                throw new StepDependencyException(nameof(_context.Signer));
            }

            IList <ITxSource> txSources = new List <ITxSource> {
                base.CreateTxSourceForProducer(readOnlyTxProcessingEnv, readOnlyTransactionProcessorSource)
            };
            bool needSigner = false;

            needSigner |= CheckAddPosdaoTransactions(txSources, _context.ChainSpec.AuRa.PosdaoTransition);
            needSigner |= CheckAddRandomnessTransactions(txSources, _context.ChainSpec.AuRa.RandomnessContractAddress, _context.Signer);

            ITxSource txSource = txSources.Count > 1 ? new CompositeTxSource(txSources.ToArray()) : txSources[0];

            if (needSigner)
            {
                TxSealer transactionSealer = new TxSealer(_context.Signer, _context.Timestamper);
                txSource = new GeneratedTxSourceSealer(txSource, transactionSealer, readOnlyTxProcessingEnv.StateReader);
            }

            var txPermissionFilter = GetTxPermissionFilter(readOnlyTxProcessingEnv, readOnlyTransactionProcessorSource);

            if (txPermissionFilter != null)
            {
                txSource = new TxFilterTxSource(txSource, txPermissionFilter);
            }

            return(txSource);
        }