/// <summary> /// Creates a cold staking node. /// </summary> /// <param name="nodeBuilder">The node builder that will be used to build the node.</param> /// <param name="network">The network that the node is being built for.</param> /// <param name="dataDir">The data directory used by the node.</param> /// <param name="coldStakeNode">Set to <c>false</c> to create a normal (non-cold-staking) node.</param> /// <returns>The created cold staking node.</returns> private CoreNode CreatePowPosMiningNode(NodeBuilder nodeBuilder, Network network, string dataDir, bool coldStakeNode) { var extraParams = new NodeConfigParameters { { "datadir", dataDir } }; var buildAction = new Action <IFullNodeBuilder>(builder => { builder.UseBlockStore() .UsePosConsensus() .UseMempool(); if (coldStakeNode) { builder.UseColdStakingWallet(); } else { builder.UseWallet(); } builder .AddPowPosMining() .AddRPC() .UseNodeHost() .UseTestChainedHeaderTree() .MockIBD(); }); return(nodeBuilder.CreateCustomNode(buildAction, network, ProtocolVersion.PROVEN_HEADER_VERSION, configParameters: extraParams)); }
/// <summary> /// Creates a cold staking node. /// </summary> /// <param name="nodeBuilder">The node builder that will be used to build the node.</param> /// <param name="network">The network that the node is being built for.</param> /// <param name="dataDir">The data directory used by the node.</param> /// <param name="coldStakeNode">Set to <c>false</c> to create a normal (non-cold-staking) node.</param> /// <returns>The created cold staking node.</returns> private CoreNode CreatePowPosMiningNode(NodeBuilder nodeBuilder, Network network, string dataDir, bool coldStakeNode) { var extraParams = new NodeConfigParameters { { "datadir", dataDir } }; var buildAction = new Action <IFullNodeBuilder>(builder => { builder.UseBlockStore() .UsePosConsensus() .UseMempool(); if (coldStakeNode) { builder.UseColdStakingWallet(); } else { builder.UseWallet(); } builder .AddPowPosMining() .AddRPC() .UseApi() .MockIBD(); }); return(nodeBuilder.CreateCustomNode(buildAction, KnownNetworks.StratisRegTest, ProtocolVersion.ALT_PROTOCOL_VERSION, configParameters: extraParams)); }
public void Transaction_CreatedByXNode_TraversesSBFN_ReachesSecondXNode() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // TODO: Add the necessary executables for Linux & OSX return; } using (NodeBuilder builder = NodeBuilder.Create(this)) { var network = new StratisRegTest(); CoreNode xNode1 = builder.CreateStratisXNode(version: "2.0.0.5").Start(); var callback = new Action <IFullNodeBuilder>(build => build .UseBlockStore() .UsePosConsensus() .UseMempool() .UseWallet() .AddPowPosMining() .AddRPC()); var config = new NodeConfigParameters(); config.Add("whitelist", xNode1.Endpoint.ToString()); config.Add("gateway", "1"); CoreNode sbfnNode2 = builder .CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, minProtocolVersion: ProtocolVersion.POS_PROTOCOL_VERSION, configParameters: config) .WithWallet().Start(); CoreNode xNode3 = builder.CreateStratisXNode(version: "2.0.0.5").Start(); RPCClient xRpc1 = xNode1.CreateRPCClient(); RPCClient sbfnRpc2 = sbfnNode2.CreateRPCClient(); RPCClient xRpc3 = xNode3.CreateRPCClient(); // Connect the nodes linearly. X does not appear to respond properly to the addnode RPC so SBFN needs to initiate. sbfnRpc2.AddNode(xNode1.Endpoint, false); sbfnRpc2.AddNode(xNode3.Endpoint, false); xRpc1.SendCommand(RPCOperations.generate, 11); var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; TestBase.WaitLoop(() => xRpc1.GetBlockCount() >= 11, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => xRpc1.GetBestBlockHash() == sbfnRpc2.GetBestBlockHash(), cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => xRpc1.GetBestBlockHash() == xRpc3.GetBestBlockHash(), cancellationToken: shortCancellationToken); // Send transaction to arbitrary address. var alice = new Key().GetBitcoinSecret(network); var aliceAddress = alice.GetAddress(); xRpc1.SendCommand(RPCOperations.sendtoaddress, aliceAddress.ToString(), 1); TestBase.WaitLoop(() => xRpc1.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => sbfnRpc2.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => xRpc3.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); } }
public CoreNode CreateNode(NodeBuilder nodeBuilder, string agent, ProtocolVersion version = ProtocolVersion.ALT_PROTOCOL_VERSION, NodeConfigParameters configParameters = null) { var callback = new Action <IFullNodeBuilder>(builder => builder .UseBlockStore() .UsePosConsensus() .UseMempool() .AddRPC() .UseNodeHost() .UseTestChainedHeaderTree() .MockIBD() ); return(nodeBuilder.CreateCustomNode(callback, new StratisOverrideRegTest(), ProtocolVersion.PROVEN_HEADER_VERSION, agent: agent, configParameters: configParameters)); }
public void XMinesBlocks_SBFNSyncs() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // TODO: Add the necessary executables for Linux & OSX return; } using (NodeBuilder builder = NodeBuilder.Create(this).WithLogsEnabled()) { var network = new StratisRegTest(); CoreNode stratisXNode = builder.CreateStratisXNode(version: "2.0.0.5").Start(); var callback = new Action <IFullNodeBuilder>(build => build .UseBlockStore() .UsePosConsensus() .UseMempool() .UseWallet() .AddPowPosMining() .AddRPC()); var config = new NodeConfigParameters(); config.Add("whitelist", stratisXNode.Endpoint.ToString()); config.Add("gateway", "1"); CoreNode stratisNode = builder .CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, minProtocolVersion: ProtocolVersion.POS_PROTOCOL_VERSION, configParameters: config) .WithWallet().Start(); RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); RPCClient stratisNodeRpc = stratisNode.CreateRPCClient(); stratisNodeRpc.AddNode(stratisXNode.Endpoint, false); stratisXRpc.SendCommand(RPCOperations.generate, 10); var cancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; TestBase.WaitLoop(() => stratisXRpc.GetBlockCount() >= 10, cancellationToken: cancellationToken); TestBase.WaitLoop(() => stratisXRpc.GetBestBlockHash() == stratisNodeRpc.GetBestBlockHash(), cancellationToken: cancellationToken); } }
public static void BuildStartAndRegisterNode(NodeBuilder nodeBuilder, Action <IFullNodeBuilder> buildNodeAction, NodeKey nodeKey, IDictionary <NodeKey, CoreNode> nodesByKey, Network network, Action <CoreNode> addParameters = null, ProtocolVersion protocolVersion = ProtocolVersion.PROTOCOL_VERSION) { var node = nodeBuilder.CreateCustomNode( false, buildNodeAction, network, agent: nodeKey.Name, protocolVersion: protocolVersion); addParameters?.Invoke(node); nodesByKey.Add(nodeKey, node); node.Start(); node.NotInIBD(); WaitLoop(() => node.State == CoreNodeState.Running); }
public void Transaction_TraversesNodes_AndIsMined_AndNodesSync() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // TODO: Add the necessary executables for Linux & OSX return; } using (NodeBuilder builder = NodeBuilder.Create(this)) { var network = new StratisRegTest(); CoreNode xNode1 = builder.CreateStratisXNode(version: "2.0.0.5").Start(); var callback = new Action <IFullNodeBuilder>(build => build .UseBlockStore() .UsePosConsensus() .UseMempool() .UseWallet() .AddPowPosMining() .AddRPC()); var config = new NodeConfigParameters(); config.Add("whitelist", xNode1.Endpoint.ToString()); config.Add("gateway", "1"); CoreNode sbfnNode2 = builder .CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, minProtocolVersion: ProtocolVersion.POS_PROTOCOL_VERSION, configParameters: config) .WithWallet().Start(); CoreNode xNode3 = builder.CreateStratisXNode(version: "2.0.0.5").Start(); RPCClient xRpc1 = xNode1.CreateRPCClient(); RPCClient sbfnRpc2 = sbfnNode2.CreateRPCClient(); RPCClient xRpc3 = xNode3.CreateRPCClient(); sbfnRpc2.AddNode(xNode1.Endpoint, false); sbfnRpc2.AddNode(xNode3.Endpoint, false); xRpc1.SendCommand(RPCOperations.generate, 11); var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; TestBase.WaitLoop(() => xRpc1.GetBlockCount() >= 11, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => xRpc1.GetBestBlockHash() == sbfnRpc2.GetBestBlockHash(), cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => xRpc1.GetBestBlockHash() == xRpc3.GetBestBlockHash(), cancellationToken: shortCancellationToken); // Send transaction to arbitrary address. var alice = new Key().GetBitcoinSecret(network); var aliceAddress = alice.GetAddress(); xRpc1.SendCommand(RPCOperations.sendtoaddress, aliceAddress.ToString(), 1); TestBase.WaitLoop(() => xRpc1.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => sbfnRpc2.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => xRpc3.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); // TODO: Until #2468 is fixed we need an X node to mine the block so it doesn't get rejected. xRpc1.SendCommand(RPCOperations.generate, 1); TestBase.WaitLoop(() => xRpc1.GetBlockCount() >= 12, cancellationToken: shortCancellationToken); // We expect that SBFN and the other X node will sync correctly. TestBase.WaitLoop(() => sbfnRpc2.GetBestBlockHash() == xRpc1.GetBestBlockHash(), cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => xRpc3.GetBestBlockHash() == xRpc1.GetBestBlockHash(), cancellationToken: shortCancellationToken); // Sanity check - mempools should all become empty. TestBase.WaitLoop(() => xRpc1.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => sbfnRpc2.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => xRpc3.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); } }
public void XMinesTransaction_SBFNSyncs() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // TODO: Add the necessary executables for Linux & OSX return; } using (NodeBuilder builder = NodeBuilder.Create(this)) { var network = new StratisRegTest(); CoreNode stratisXNode = builder.CreateStratisXNode(version: "2.0.0.5").Start(); var callback = new Action <IFullNodeBuilder>(build => build .UseBlockStore() .UsePosConsensus() .UseMempool() .UseWallet() .AddPowPosMining() .AddRPC()); var config = new NodeConfigParameters(); config.Add("whitelist", stratisXNode.Endpoint.ToString()); config.Add("gateway", "1"); CoreNode stratisNode = builder .CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, minProtocolVersion: ProtocolVersion.POS_PROTOCOL_VERSION, configParameters: config) .WithWallet().Start(); RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); RPCClient stratisNodeRpc = stratisNode.CreateRPCClient(); stratisXRpc.AddNode(stratisNode.Endpoint, false); stratisNodeRpc.AddNode(stratisXNode.Endpoint, false); stratisXRpc.SendCommand(RPCOperations.generate, 11); var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(2)).Token; // Without this there seems to be a race condition between the blocks all getting generated and SBFN syncing high enough to fall through the getbestblockhash check. TestBase.WaitLoop(() => stratisXRpc.GetBlockCount() >= 11, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: shortCancellationToken); // Send transaction to arbitrary address from X side. var alice = new Key().GetBitcoinSecret(network); var aliceAddress = alice.GetAddress(); stratisXRpc.SendCommand(RPCOperations.sendtoaddress, aliceAddress.ToString(), 1); TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); // Transaction should percolate through to SBFN's mempool. TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); // Now X must mine the block. stratisXRpc.SendCommand(RPCOperations.generate, 1); TestBase.WaitLoop(() => stratisXRpc.GetBlockCount() >= 12, cancellationToken: shortCancellationToken); // We expect that SBFN will sync correctly. TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: shortCancellationToken); // Sanity check - mempools should both become empty. TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); } }
public void SBFNCreatesOpReturnTransaction_XSyncs() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // TODO: Add the necessary executables for Linux & OSX return; } using (NodeBuilder builder = NodeBuilder.Create(this)) { var network = new StratisRegTest(); CoreNode stratisXNode = builder.CreateStratisXNode(version: "2.0.0.5").Start(); // We do not want the datetime provider to be substituted, // so a custom builder callback has to be used. var callback = new Action <IFullNodeBuilder>(build => build .UseBlockStore() .UsePosConsensus() .UseMempool() .UseWallet() .AddPowPosMining() .AddRPC() .UseTestChainedHeaderTree() .MockIBD()); CoreNode stratisNode = builder.CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.POS_PROTOCOL_VERSION, minProtocolVersion: ProtocolVersion.POS_PROTOCOL_VERSION).WithWallet().Start(); RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); RPCClient stratisNodeRpc = stratisNode.CreateRPCClient(); stratisXRpc.AddNode(stratisNode.Endpoint, false); stratisNodeRpc.AddNode(stratisXNode.Endpoint, false); TestHelper.MineBlocks(stratisNode, 11); // It takes a reasonable amount of time for blocks to be generated without // the datetime provider substitution. var longCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(15)).Token; var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: longCancellationToken); // Send transaction to arbitrary address from SBFN side. var alice = new Key().GetBitcoinSecret(network); var aliceAddress = alice.GetAddress(); //stratisNodeRpc.WalletPassphrase("password", 60); var transactionBuildContext = new TransactionBuildContext(stratisNode.FullNode.Network) { AccountReference = new WalletAccountReference("mywallet", "account 0"), MinConfirmations = 1, OpReturnData = "test", OpReturnAmount = Money.Coins(0.01m), WalletPassword = "******", Recipients = new List <Recipient>() { new Recipient() { Amount = Money.Coins(1), ScriptPubKey = aliceAddress.ScriptPubKey } } }; var transaction = stratisNode.FullNode.WalletTransactionHandler().BuildTransaction(transactionBuildContext); stratisNode.FullNode.NodeController <WalletController>().SendTransaction(new SendTransactionRequest(transaction.ToHex())); TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); // Transaction should percolate through to X's mempool. TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); } }
public void SBFNMinesTransaction_XSyncs() { // TODO: Currently fails due to issue #2468 (coinbase // reward on stratisX cannot be >4. No fees are allowed) if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // TODO: Add the necessary executables for Linux & OSX return; } using (NodeBuilder builder = NodeBuilder.Create(this)) { var network = new StratisRegTest(); CoreNode stratisXNode = builder.CreateStratisXNode(version: "2.0.0.5").Start(); // We do not want the datetime provider to be substituted, // so a custom builder callback has to be used. var callback = new Action <IFullNodeBuilder>(build => build .UseBlockStore() .UsePosConsensus() .UseMempool() .UseWallet() .AddPowPosMining() .AddRPC() .UseTestChainedHeaderTree() .MockIBD()); CoreNode stratisNode = builder.CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.POS_PROTOCOL_VERSION).WithWallet().Start(); RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); RPCClient stratisNodeRpc = stratisNode.CreateRPCClient(); stratisXRpc.AddNode(stratisNode.Endpoint, false); stratisNodeRpc.AddNode(stratisXNode.Endpoint, false); TestHelper.MineBlocks(stratisNode, 11); // It takes a reasonable amount of time for blocks to be generated without // the datetime provider substitution. var longCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(15)).Token; var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: longCancellationToken); // Send transaction to arbitrary address from SBFN side. var alice = new Key().GetBitcoinSecret(network); var aliceAddress = alice.GetAddress(); stratisNodeRpc.WalletPassphrase("password", 60); stratisNodeRpc.SendToAddress(aliceAddress, Money.Coins(1.0m)); TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); // Transaction should percolate through to X's mempool. TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); // Now SBFN must mine the block. TestHelper.MineBlocks(stratisNode, 1); // We expect that X will sync correctly. TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: shortCancellationToken); // Sanity check - mempools should both become empty. TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); } }