public async Task NodeCanMineAsync() { var network = new TestPoANetwork(); using (PoANodeBuilder builder = PoANodeBuilder.CreatePoANodeBuilder(this)) { CoreNode node = builder.CreatePoANode(network, network.FederationKey1).Start(); int tipBefore = node.GetTip().Height; await node.MineBlocksAsync(5).ConfigureAwait(false); Assert.True(node.GetTip().Height >= tipBefore + 5); } }
public void NodeCanLoadFederationKey() { var network = new TestPoANetwork(); using (PoANodeBuilder builder = PoANodeBuilder.CreatePoANodeBuilder(this)) { // Create first node as fed member. Key key = network.FederationKey1; CoreNode node = builder.CreatePoANode(network, key).Start(); Assert.True(node.FullNode.NodeService <IFederationManager>().IsFederationMember); Assert.Equal(node.FullNode.NodeService <IFederationManager>().CurrentFederationKey, key); // Create second node as normal node. CoreNode node2 = builder.CreatePoANode(network).Start(); Assert.False(node2.FullNode.NodeService <IFederationManager>().IsFederationMember); Assert.Equal(node2.FullNode.NodeService <IFederationManager>().CurrentFederationKey, null); } }
public void PremineIsReceived() { TestPoANetwork network = new TestPoANetwork(); using (PoANodeBuilder builder = PoANodeBuilder.CreatePoANodeBuilder(this)) { string walletName = "mywallet"; CoreNode node = builder.CreatePoANode(network, network.FederationKey1).WithWallet("pass", walletName).Start(); node.EnableFastMining(); IWalletManager walletManager = node.FullNode.NodeService <IWalletManager>(); long balanceOnStart = walletManager.GetBalances(walletName, "account 0").Sum(x => x.AmountConfirmed); Assert.Equal(0, balanceOnStart); TestHelper.WaitLoop(() => node.GetTip().Height >= network.Consensus.PremineHeight + network.Consensus.CoinbaseMaturity + 1); long balanceAfterPremine = walletManager.GetBalances(walletName, "account 0").Sum(x => x.AmountConfirmed); Assert.Equal(network.Consensus.PremineReward.Satoshi, balanceAfterPremine); } }
public async Task PremineIsReceivedAsync() { TestPoANetwork network = new TestPoANetwork(); using (PoANodeBuilder builder = PoANodeBuilder.CreatePoANodeBuilder(this)) { string walletName = "mywallet"; CoreNode node = builder.CreatePoANode(network, network.FederationKey1).WithWallet("pass", walletName).Start(); IWalletManager walletManager = node.FullNode.NodeService <IWalletManager>(); long balanceOnStart = walletManager.GetBalances(walletName, "account 0").Sum(x => x.AmountConfirmed); Assert.Equal(0, balanceOnStart); long toMineCount = network.Consensus.PremineHeight + network.Consensus.CoinbaseMaturity + 1 - node.GetTip().Height; await node.MineBlocksAsync((int)toMineCount).ConfigureAwait(false); long balanceAfterPremine = walletManager.GetBalances(walletName, "account 0").Sum(x => x.AmountConfirmed); Assert.Equal(network.Consensus.PremineReward.Satoshi, balanceAfterPremine); } }
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); } }
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); Assert.True(context.TransactionBuilder.Verify(trx, out _)); 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 == (transferAmount + feeAmount)); }); } }