Exemple #1
0
        // Checks that node can sync from scratch if federation voted in favor of adding a new fed member.
        public async Task CanSyncIfFedMemberAddedAsync()
        {
            int originalFedMembersCount = this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count;

            TestHelper.Connect(this.node1, this.node2);

            var model = new HexPubKeyModel()
            {
                PubKeyHex = "03025fcadedd28b12665de0542c8096f4cd5af8e01791a4d057f67e2866ca66ba7"
            };

            this.node1.FullNode.NodeService <FederationVotingController>().VoteAddFedMember(model);
            this.node2.FullNode.NodeService <FederationVotingController>().VoteAddFedMember(model);

            await this.node1.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            await this.node2.MineBlocksAsync((int)this.network.Consensus.MaxReorgLength * 3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Equal(originalFedMembersCount + 1, this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count);

            TestHelper.Connect(this.node2, this.node3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);
        }
Exemple #2
0
        public async Task ReorgRevertsAppliedChangesAsync()
        {
            TestHelper.Connect(this.node1, this.node2);

            var model = new HexPubKeyModel()
            {
                PubKeyHex = this.testPubKey.ToHex()
            };

            this.node1.FullNode.NodeService <FederationVotingController>().VoteAddFedMember(model);
            this.node1.FullNode.NodeService <FederationVotingController>().VoteKickFedMember(model);
            await this.node1.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            this.node2.FullNode.NodeService <FederationVotingController>().VoteAddFedMember(model);
            await this.node2.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Single(this.node2.FullNode.NodeService <VotingManager>().GetPendingPolls());
            Assert.Single(this.node2.FullNode.NodeService <VotingManager>().GetFinishedPolls());

            await this.node3.MineBlocksAsync(4);

            TestHelper.Connect(this.node2, this.node3);
            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);

            Assert.Empty(this.node2.FullNode.NodeService <VotingManager>().GetPendingPolls());
            Assert.Empty(this.node2.FullNode.NodeService <VotingManager>().GetFinishedPolls());
        }
        // Checks that node can sync from scratch if federation voted in favor of kicking a fed member.
        public async Task CanSyncIfFedMemberKickedAsync()
        {
            int originalFedMembersCount = this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count;

            TestHelper.Connect(this.node1, this.node2);

            byte[] fedMemberBytes = (this.poaNetwork.Consensus.ConsensusFactory as PoAConsensusFactory).SerializeFederationMember(new FederationMember(this.poaNetwork.FederationKey2.PubKey));
            var    votingData     = new VotingData()
            {
                Key  = VoteKey.KickFederationMember,
                Data = fedMemberBytes
            };

            this.node1.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);
            this.node2.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);

            await this.node2.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            await this.node1.MineBlocksAsync((int)this.poaNetwork.Consensus.MaxReorgLength * 3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Equal(originalFedMembersCount - 1, this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count);

            TestHelper.Connect(this.node2, this.node3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);
        }
Exemple #4
0
        // Checks that node can sync from scratch if federation voted in favor of kicking a fed member.
        public async Task CanSyncIfFedMemberKickedAsync()
        {
            int originalFedMembersCount = this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count;

            TestHelper.Connect(this.node1, this.node2);

            var model = new HexPubKeyModel()
            {
                PubKeyHex = this.network.FederationKey2.PubKey.ToHex()
            };

            this.node1.FullNode.NodeService <FederationVotingController>().VoteKickFedMember(model);
            this.node2.FullNode.NodeService <FederationVotingController>().VoteKickFedMember(model);

            await this.node2.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            await this.node1.MineBlocksAsync((int)this.network.Consensus.MaxReorgLength * 3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Equal(originalFedMembersCount - 1, this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count);

            TestHelper.Connect(this.node2, this.node3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);
        }
        // Checks that node can sync from scratch if federation voted in favor of adding a new fed member.
        public async Task CanSyncIfFedMemberAddedAsync()
        {
            List <IFederationMember> originalFedMembers = this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers();

            TestHelper.Connect(this.node1, this.node2);

            IFederationMember federationMember = new FederationMember(new PubKey("03025fcadedd28b12665de0542c8096f4cd5af8e01791a4d057f67e2866ca66ba7"));

            byte[] fedMemberBytes = (this.poaNetwork.Consensus.ConsensusFactory as PoAConsensusFactory).SerializeFederationMember(federationMember);
            var    votingData     = new VotingData()
            {
                Key  = VoteKey.AddFederationMember,
                Data = fedMemberBytes
            };

            this.node1.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);
            this.node2.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);

            await this.node1.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            await this.node2.MineBlocksAsync((int)this.poaNetwork.Consensus.MaxReorgLength * 3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            List <IFederationMember> newFedMembers = this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers();

            Assert.Equal(originalFedMembers.Count + 1, newFedMembers.Count);

            TestHelper.Connect(this.node2, this.node3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);
        }
Exemple #6
0
        public async Task CanMineVotingRequestTransactionAsync()
        {
            var network = new TestPoACollateralNetwork(true, Guid.NewGuid().ToString());

            using (PoANodeBuilder builder = PoANodeBuilder.CreatePoANodeBuilder(this))
            {
                string walletName     = "mywallet";
                string walletPassword = "******";
                string walletAccount  = "account 0";

                Money transferAmount = Money.Coins(0.01m);
                Money feeAmount      = Money.Coins(0.0001m);

                var counterchainNetwork = new StraxTest();

                CoreNode nodeA = builder.CreatePoANodeWithCounterchain(network, counterchainNetwork, network.FederationKey1).WithWallet(walletPassword, walletName).Start();
                CoreNode nodeB = builder.CreatePoANodeWithCounterchain(network, counterchainNetwork, network.FederationKey2).WithWallet(walletPassword, walletName).Start();

                TestHelper.Connect(nodeA, nodeB);

                long toMineCount = network.Consensus.PremineHeight + network.Consensus.CoinbaseMaturity + 1 - nodeA.GetTip().Height;

                // Get coins on nodeA via the premine.
                await nodeA.MineBlocksAsync((int)toMineCount).ConfigureAwait(false);

                CoreNodePoAExtensions.WaitTillSynced(nodeA, nodeB);

                // Create voting-request transaction.
                var minerKey      = new Key();
                var collateralKey = new Key();
                var request       = new JoinFederationRequest(minerKey.PubKey, new Money(CollateralFederationMember.MinerCollateralAmount, MoneyUnit.BTC), collateralKey.PubKey.Hash);

                // In practice this signature will come from calling the counter-chain "signmessage" API.
                request.AddSignature(collateralKey.SignMessage(request.SignatureMessage));

                var         encoder = new JoinFederationRequestEncoder(nodeA.FullNode.NodeService <Microsoft.Extensions.Logging.ILoggerFactory>());
                Transaction trx     = JoinFederationRequestBuilder.BuildTransaction(nodeA.FullNode.WalletTransactionHandler(), this.network, request, encoder, walletName, walletAccount, walletPassword);

                await nodeA.FullNode.NodeController <WalletController>().SendTransaction(new SendTransactionRequest(trx.ToHex()));

                TestBase.WaitLoop(() => nodeA.CreateRPCClient().GetRawMempool().Length == 1 && nodeB.CreateRPCClient().GetRawMempool().Length == 1);

                await nodeB.MineBlocksAsync((int)toMineCount).ConfigureAwait(false);

                TestBase.WaitLoop(() => nodeA.CreateRPCClient().GetRawMempool().Length == 0 && nodeB.CreateRPCClient().GetRawMempool().Length == 0);

                IWalletManager walletManager = nodeB.FullNode.NodeService <IWalletManager>();

                TestBase.WaitLoop(() =>
                {
                    long balance = walletManager.GetBalances(walletName, walletAccount).Sum(x => x.AmountConfirmed);

                    return(balance == feeAmount);
                });

                Assert.Single(nodeA.FullNode.NodeService <VotingManager>().GetPendingPolls());
                Assert.Single(nodeB.FullNode.NodeService <VotingManager>().GetPendingPolls());
            }
        }
        public async Task TransactionSentFeesReceivedByMinerAsync()
        {
            TestPoANetwork network = new TestPoANetwork();

            using (PoANodeBuilder builder = PoANodeBuilder.CreatePoANodeBuilder(this))
            {
                string walletName     = "mywallet";
                string walletPassword = "******";
                string walletAccount  = "account 0";

                Money transferAmount = Money.Coins(1m);
                Money feeAmount      = Money.Coins(0.0001m);

                CoreNode nodeA = builder.CreatePoANode(network, network.FederationKey1).WithWallet(walletPassword, walletName).Start();
                CoreNode nodeB = builder.CreatePoANode(network, network.FederationKey2).WithWallet(walletPassword, walletName).Start();

                TestHelper.Connect(nodeA, nodeB);

                long toMineCount = network.Consensus.PremineHeight + network.Consensus.CoinbaseMaturity + 1 - nodeA.GetTip().Height;

                // Get coins on nodeA via the premine.
                await nodeA.MineBlocksAsync((int)toMineCount).ConfigureAwait(false);

                CoreNodePoAExtensions.WaitTillSynced(nodeA, nodeB);

                // Will send funds to one of nodeB's addresses.
                Script destination = nodeB.FullNode.WalletManager().GetUnusedAddress().ScriptPubKey;

                var context = new TransactionBuildContext(network)
                {
                    AccountReference = new WalletAccountReference(walletName, walletAccount),
                    MinConfirmations = 0,
                    FeeType          = FeeType.High,
                    WalletPassword   = walletPassword,
                    Recipients       = new[] { new Recipient {
                                                   Amount = transferAmount, ScriptPubKey = destination
                                               } }.ToList()
                };

                Transaction trx = nodeA.FullNode.WalletTransactionHandler().BuildTransaction(context);

                nodeA.FullNode.NodeController <WalletController>().SendTransaction(new SendTransactionRequest(trx.ToHex()));

                TestBase.WaitLoop(() => nodeA.CreateRPCClient().GetRawMempool().Length == 1 && nodeB.CreateRPCClient().GetRawMempool().Length == 1);

                await nodeB.MineBlocksAsync((int)toMineCount).ConfigureAwait(false);

                TestBase.WaitLoop(() => nodeA.CreateRPCClient().GetRawMempool().Length == 0 && nodeB.CreateRPCClient().GetRawMempool().Length == 0);

                IWalletManager walletManager = nodeB.FullNode.NodeService <IWalletManager>();
                long           balance       = walletManager.GetBalances(walletName, walletAccount).Sum(x => x.AmountConfirmed);

                Assert.True(balance == transferAmount + feeAmount);
            }
        }
        // Checks that fed members cant vote twice.
        // Checks that miner adds voting data if it exists.
        public async Task CantVoteTwiceAsync()
        {
            int originalFedMembersCount = this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count;

            TestHelper.Connect(this.node1, this.node2);

            await this.node1.MineBlocksAsync(3);

            IFederationMember federationMember = new FederationMember(new PubKey("03025fcadedd28b12665de0542c8096f4cd5af8e01791a4d057f67e2866ca66ba7"));

            byte[] fedMemberBytes = (this.poaNetwork.Consensus.ConsensusFactory as PoAConsensusFactory).SerializeFederationMember(federationMember);
            var    votingData     = new VotingData()
            {
                Key  = VoteKey.AddFederationMember,
                Data = fedMemberBytes
            };

            this.node1.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);

            Assert.Single(this.node1.FullNode.NodeService <VotingManager>().GetScheduledVotes());
            Assert.Empty(this.node1.FullNode.NodeService <VotingManager>().GetPendingPolls());

            await this.node1.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Empty(this.node1.FullNode.NodeService <VotingManager>().GetScheduledVotes());
            Assert.Single(this.node1.FullNode.NodeService <VotingManager>().GetPendingPolls());

            // Vote 2nd time and make sure nothing changed.
            this.node1.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);
            await this.node1.MineBlocksAsync(1);

            Assert.Empty(this.node1.FullNode.NodeService <VotingManager>().GetScheduledVotes());
            Assert.Single(this.node1.FullNode.NodeService <VotingManager>().GetPendingPolls());

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            // Node 2 votes. After that it will be enough to change the federation.
            this.node2.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);

            await this.node2.MineBlocksAsync((int)this.poaNetwork.Consensus.MaxReorgLength + 1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Equal(originalFedMembersCount + 1, this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count);
            Assert.Equal(originalFedMembersCount + 1, this.node2.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count);

            TestHelper.Connect(this.node2, this.node3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);
        }
        private async Task VoteAndMineBlockAsync(PubKey key, bool add, CoreNode node)
        {
            byte[] fedMemberBytes = (this.poaNetwork.Consensus.ConsensusFactory as PoAConsensusFactory).SerializeFederationMember(new FederationMember(key));
            var    votingData     = new VotingData()
            {
                Key  = add ? VoteKey.AddFederationMember : VoteKey.KickFederationMember,
                Data = fedMemberBytes
            };

            node.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);

            await node.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);
        }
Exemple #10
0
        // Checks that fed members cant vote twice.
        // Checks that miner adds voting data if it exists.
        public async Task CantVoteTwiceAsync()
        {
            int originalFedMembersCount = this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count;

            TestHelper.Connect(this.node1, this.node2);

            await this.node1.MineBlocksAsync(3);

            var model = new HexPubKeyModel()
            {
                PubKeyHex = "03025fcadedd28b12665de0542c8096f4cd5af8e01791a4d057f67e2866ca66ba7"
            };

            this.node1.FullNode.NodeService <FederationVotingController>().VoteAddFedMember(model);

            Assert.Single(this.node1.FullNode.NodeService <VotingManager>().GetScheduledVotes());
            Assert.Empty(this.node1.FullNode.NodeService <VotingManager>().GetPendingPolls());

            await this.node1.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Empty(this.node1.FullNode.NodeService <VotingManager>().GetScheduledVotes());
            Assert.Single(this.node1.FullNode.NodeService <VotingManager>().GetPendingPolls());

            // Vote 2nd time and make sure nothing changed.
            this.node1.FullNode.NodeService <FederationVotingController>().VoteAddFedMember(model);
            await this.node1.MineBlocksAsync(1);

            Assert.Empty(this.node1.FullNode.NodeService <VotingManager>().GetScheduledVotes());
            Assert.Single(this.node1.FullNode.NodeService <VotingManager>().GetPendingPolls());

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            // Node 2 votes. After that it will be enough to change the federation.
            this.node2.FullNode.NodeService <FederationVotingController>().VoteAddFedMember(model);

            await this.node2.MineBlocksAsync((int)this.network.Consensus.MaxReorgLength + 1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Equal(originalFedMembersCount + 1, this.node1.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count);
            Assert.Equal(originalFedMembersCount + 1, this.node2.FullNode.NodeService <IFederationManager>().GetFederationMembers().Count);

            TestHelper.Connect(this.node2, this.node3);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);
        }
Exemple #11
0
        public async Task CanVoteToWhitelistAndRemoveHashesAsync()
        {
            int maxReorg = (int)this.network.Consensus.MaxReorgLength;

            Assert.Empty(this.node1.FullNode.NodeService <IWhitelistedHashesRepository>().GetHashes());
            TestHelper.Connect(this.node1, this.node2);

            await this.node1.MineBlocksAsync(1);

            var model = new HashModel()
            {
                Hash = Hashes.Hash256(RandomUtils.GetUInt64().ToBytes()).ToString()
            };

            // Node 1 votes to add hash
            this.node1.FullNode.NodeService <DefaultVotingController>().VoteWhitelistHash(model);
            await this.node1.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            // Node 2 votes to add hash
            this.node2.FullNode.NodeService <DefaultVotingController>().VoteWhitelistHash(model);
            await this.node2.MineBlocksAsync(maxReorg + 2);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Single(this.node1.FullNode.NodeService <IWhitelistedHashesRepository>().GetHashes());

            // Node 1 votes to remove hash
            this.node1.FullNode.NodeService <DefaultVotingController>().VoteRemoveHash(model);
            await this.node1.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            // Node 2 votes to remove hash
            this.node2.FullNode.NodeService <DefaultVotingController>().VoteRemoveHash(model);
            await this.node2.MineBlocksAsync(maxReorg + 2);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Empty(this.node1.FullNode.NodeService <IWhitelistedHashesRepository>().GetHashes());
        }
Exemple #12
0
        private async Task VoteAndMineBlockAsync(PubKey key, bool add, CoreNode node)
        {
            var model = new HexPubKeyModel()
            {
                PubKeyHex = key.ToHex()
            };

            if (add)
            {
                node.FullNode.NodeService <FederationVotingController>().VoteAddFedMember(model);
            }
            else
            {
                node.FullNode.NodeService <FederationVotingController>().VoteKickFedMember(model);
            }

            await node.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);
        }
        public async Task ReorgRevertsAppliedChangesAsync()
        {
            TestHelper.Connect(this.node1, this.node2);

            byte[] fedMemberBytes = (this.poaNetwork.Consensus.ConsensusFactory as PoAConsensusFactory).SerializeFederationMember(new FederationMember(this.testPubKey));
            var    votingData     = new VotingData()
            {
                Key = VoteKey.AddFederationMember, Data = fedMemberBytes
            };

            this.node1.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);

            votingData = new VotingData()
            {
                Key = VoteKey.KickFederationMember, Data = fedMemberBytes
            };
            this.node1.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);
            await this.node1.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            votingData = new VotingData()
            {
                Key = VoteKey.AddFederationMember, Data = fedMemberBytes
            };
            this.node2.FullNode.NodeService <VotingManager>().ScheduleVote(votingData);
            await this.node2.MineBlocksAsync(1);

            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2);

            Assert.Single(this.node2.FullNode.NodeService <VotingManager>().GetPendingPolls());
            Assert.Single(this.node2.FullNode.NodeService <VotingManager>().GetApprovedPolls());

            await this.node3.MineBlocksAsync(4);

            TestHelper.Connect(this.node2, this.node3);
            CoreNodePoAExtensions.WaitTillSynced(this.node1, this.node2, this.node3);

            Assert.Empty(this.node2.FullNode.NodeService <VotingManager>().GetPendingPolls());
            Assert.Empty(this.node2.FullNode.NodeService <VotingManager>().GetApprovedPolls());
        }
Exemple #14
0
        public async Task EnableAutoKickAsync()
        {
            using (var builder = PoANodeBuilder.CreatePoANodeBuilder(this))
            {
                const int idleTimeSeconds = 10 * 60;

                // Have a network that mimics Cirrus where voting is on and kicking is off.
                var votingNetwork1 = new TestPoANetwork("VoteNetwork1");
                var votingNetwork2 = new TestPoANetwork("VoteNetwork2");

                var oldOptions = (PoAConsensusOptions)votingNetwork1.Consensus.Options;

                votingNetwork1.Consensus.Options = new PoAConsensusOptions(maxBlockBaseSize: oldOptions.MaxBlockBaseSize,
                                                                           maxStandardVersion: oldOptions.MaxStandardVersion,
                                                                           maxStandardTxWeight: oldOptions.MaxStandardTxWeight,
                                                                           maxBlockSigopsCost: oldOptions.MaxBlockSigopsCost,
                                                                           maxStandardTxSigopsCost: oldOptions.MaxStandardTxSigopsCost,
                                                                           genesisFederationMembers: oldOptions.GenesisFederationMembers,
                                                                           targetSpacingSeconds: 60,
                                                                           votingEnabled: true,
                                                                           autoKickIdleMembers: false,
                                                                           federationMemberMaxIdleTimeSeconds: oldOptions.FederationMemberMaxIdleTimeSeconds);

                CoreNode node1 = builder.CreatePoANode(votingNetwork1, votingNetwork1.FederationKey1).Start();
                CoreNode node2 = builder.CreatePoANode(votingNetwork2, votingNetwork2.FederationKey2).Start();
                TestHelper.Connect(node1, node2);

                // Mine a block on this network from each node. Confirm it's alive.
                await node1.MineBlocksAsync(1);

                CoreNodePoAExtensions.WaitTillSynced(node1, node2);
                await node2.MineBlocksAsync(1);

                CoreNodePoAExtensions.WaitTillSynced(node1, node2);

                // Edit the consensus options so that kicking is turned on.
                votingNetwork1.Consensus.Options = new PoAConsensusOptions(maxBlockBaseSize: oldOptions.MaxBlockBaseSize,
                                                                           maxStandardVersion: oldOptions.MaxStandardVersion,
                                                                           maxStandardTxWeight: oldOptions.MaxStandardTxWeight,
                                                                           maxBlockSigopsCost: oldOptions.MaxBlockSigopsCost,
                                                                           maxStandardTxSigopsCost: oldOptions.MaxStandardTxSigopsCost,
                                                                           genesisFederationMembers: oldOptions.GenesisFederationMembers,
                                                                           targetSpacingSeconds: 60,
                                                                           votingEnabled: true,
                                                                           autoKickIdleMembers: true,
                                                                           federationMemberMaxIdleTimeSeconds: idleTimeSeconds);

                // Restart node 1 to ensure that we have the new network consensus options which reflects
                // the autokicking enabled.
                node1.Restart();

                // Lets get our 2 nodes to actively mine some blocks.
                // In doing so, their test datetimeprovider will increment by minutes at a time.
                for (int i = 0; i < 5; i++)
                {
                    await node1.MineBlocksAsync(1);

                    CoreNodePoAExtensions.WaitTillSynced(node1, node2);

                    await node2.MineBlocksAsync(1);

                    CoreNodePoAExtensions.WaitTillSynced(node1, node2);
                }

                // Enough time has passed - Check that our new node wants to vote the third fed member out, who has not mined at all.
                // Check that we have a single active poll to vote him out.
                List <Poll> activePolls = node1.FullNode.NodeService <VotingManager>().GetPendingPolls();
                Assert.Single(activePolls);
                Assert.Equal(VoteKey.KickFederationMember, activePolls[0].VotingData.Key);
                byte[] lastMemberBytes = (votingNetwork1.Consensus.ConsensusFactory as PoAConsensusFactory).SerializeFederationMember(votingNetwork1.ConsensusOptions.GenesisFederationMembers[2]);
                Assert.Equal(lastMemberBytes, activePolls[0].VotingData.Data);
            }
        }