コード例 #1
0
        public async Task Can_UnBan_Peer_From_ApiAsync()
        {
            using (var builder = NodeBuilder.Create(this))
            {
                var network = new StratisRegTest();

                var nodeA = builder.CreateStratisPosNode(network, "nc-2-nodeA").Start();

                var nodeB_Ip        = "127.0.0.2";
                var nodeB_IpAddress = IPAddress.Parse(nodeB_Ip);
                var nodeB_EndPoint  = new IPEndPoint(nodeB_IpAddress, 0);

                var nodeAaddressManager = nodeA.FullNode.NodeService <IPeerAddressManager>();
                nodeAaddressManager.AddPeer(new IPEndPoint(nodeB_IpAddress, 0), IPAddress.Loopback);

                var peerBanning = nodeA.FullNode.NodeService <IPeerBanning>();
                peerBanning.BanAndDisconnectPeer(nodeB_EndPoint);
                Assert.True(peerBanning.IsBanned(nodeB_EndPoint));

                var unBanPeerModel = new SetBanPeerViewModel()
                {
                    BanCommand  = "remove",
                    PeerAddress = nodeB_Ip
                };

                await $"http://localhost:{nodeA.ApiPort}/api".AppendPathSegment("network/setban").PostJsonAsync(unBanPeerModel);

                Assert.False(peerBanning.IsBanned(nodeB_EndPoint));
            }
        }
コード例 #2
0
        public void Mempool_SendTransactionWithEarlyTimestamp_ShouldRejectByMempool()
        {
            var network = new StratisRegTest();

            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode stratisSender = builder.CreateStratisPosNode(network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest10Miner).Start();

                TestHelper.MineBlocks(stratisSender, 5);

                // Send coins to the receiver
                var context = WalletTests.CreateContext(network, new WalletAccountReference(WalletName, Account), Password, new Key().PubKey.GetAddress(network).ScriptPubKey, Money.COIN * 100, FeeType.Medium, 1);

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

                // Use timestamp value that is definitely earlier than the input's timestamp
                ((PosTransaction)trx).Time = 1;

                // Sign trx again after mutating timestamp
                trx = context.TransactionBuilder.SignTransaction(trx);

                // Enable standard policy relay.
                stratisSender.FullNode.NodeService <MempoolSettings>().RequireStandard = true;

                var broadcaster = stratisSender.FullNode.NodeService <IBroadcasterManager>();

                broadcaster.BroadcastTransactionAsync(trx).GetAwaiter().GetResult();
                var entry = broadcaster.GetTransaction(trx.GetHash());

                Assert.Equal("timestamp earlier than input", entry.ErrorMessage);
            }
        }
コード例 #3
0
        public void Mempool_SendPosTransaction_AheadOfFutureDrift_ShouldRejectByMempool()
        {
            var network = new StratisRegTest();

            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode stratisSender = builder.CreateStratisPosNode(network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest10Miner).Start();

                TestHelper.MineBlocks(stratisSender, 5);

                // Send coins to the receiver
                var context = WalletTests.CreateContext(network, new WalletAccountReference(WalletName, Account), Password, new Key().PubKey.GetAddress(network).ScriptPubKey, Money.COIN * 100, FeeType.Medium, 1);

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

                // This should make the mempool reject a POS trx.
                ((PosTransaction)trx).Time = Utils.DateTimeToUnixTime(Utils.UnixTimeToDateTime(((PosTransaction)trx).Time).AddMinutes(5));

                // Sign trx again after changing the time property.
                trx = context.TransactionBuilder.SignTransaction(trx);

                // Enable standard policy relay.
                stratisSender.FullNode.NodeService <MempoolSettings>().RequireStandard = true;

                var broadcaster = stratisSender.FullNode.NodeService <IBroadcasterManager>();

                broadcaster.BroadcastTransactionAsync(trx).GetAwaiter().GetResult();
                var entry = broadcaster.GetTransaction(trx.GetHash());

                Assert.Equal("time-too-new", entry.ErrorMessage);
            }
        }
コード例 #4
0
        public void Mempool_SendOversizeTransaction_ShouldRejectByMempool()
        {
            var network = new StratisRegTest();

            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode stratisSender = builder.CreateStratisPosNode(network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest10Miner).Start();

                TestHelper.MineBlocks(stratisSender, 5);

                // Send coins to the receiver
                var context = WalletTests.CreateContext(network, new WalletAccountReference(WalletName, Account), Password, new Key().PubKey.GetAddress(network).ScriptPubKey, Money.COIN * 100, FeeType.Medium, 1);

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

                // Add nonsense script to make tx large.
                Script script = Script.FromBytesUnsafe(new string('A', network.Consensus.Options.MaxStandardTxWeight).Select(c => (byte)c).ToArray());
                trx.Outputs.Add(new TxOut(new Money(1), script));

                // Sign trx again after adding an output
                trx = context.TransactionBuilder.SignTransaction(trx);

                // Enable standard policy relay.
                stratisSender.FullNode.NodeService <MempoolSettings>().RequireStandard = true;

                var broadcaster = stratisSender.FullNode.NodeService <IBroadcasterManager>();

                broadcaster.BroadcastTransactionAsync(trx).GetAwaiter().GetResult();
                var entry = broadcaster.GetTransaction(trx.GetHash());

                Assert.Equal("tx-size", entry.ErrorMessage);
            }
        }
コード例 #5
0
        public void SBFNMinesBlocksXSyncs()
        {
            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();
                CoreNode stratisNode  = builder.CreateStratisPosNode(network).WithWallet().Start();

                RPCClient stratisXRpc    = stratisXNode.CreateRPCClient();
                RPCClient stratisNodeRpc = stratisNode.CreateRPCClient();

                // TODO: Need to troubleshoot why TestHelper.Connect() does not work here, possibly unsupported RPC method.
                stratisXRpc.AddNode(stratisNode.Endpoint, false);
                stratisNodeRpc.AddNode(stratisXNode.Endpoint, false);

                // TODO: Similarly, the 'generate' RPC call is problematic on X. Possibly returning an unexpected JSON format.
                TestHelper.MineBlocks(stratisNode, 10);

                // As we are not actually sending transactions, it does not
                // matter that the datetime provider is substituted for this
                // test. The blocks get accepted by X despite getting generated
                // very rapidly.
                var cancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token;
                TestHelper.WaitLoop(() => stratisNode.CreateRPCClient().GetBestBlockHash() == stratisXNode.CreateRPCClient().GetBestBlockHash(), cancellationToken: cancellationToken);
            }
        }
コード例 #6
0
        public void SBFNMinesBlocks_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();
                CoreNode sbfnNode     = builder.CreateStratisPosNode(network).WithWallet().Start();

                RPCClient stratisXRpc = stratisXNode.CreateRPCClient();
                RPCClient sbfnNodeRpc = sbfnNode.CreateRPCClient();

                // TODO: Need to troubleshoot why TestHelper.Connect() does not work here, possibly unsupported RPC method (it seems that addnode does not work for X).
                sbfnNodeRpc.AddNode(stratisXNode.Endpoint, false);

                // TODO: Similarly, the 'generate' RPC call is problematic on X. Possibly returning an unexpected JSON format.
                TestHelper.MineBlocks(sbfnNode, 10);

                var cancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token;

                TestBase.WaitLoop(() => sbfnNodeRpc.GetBlockCount() >= 10, cancellationToken: cancellationToken);
                TestBase.WaitLoop(() => sbfnNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: cancellationToken);
            }
        }
コード例 #7
0
        private static Transaction CreateTransactionThatSpendCoinstake(StratisRegTest network, CoreNode minerA, CoreNode minerB, TxIn coinstake, Transaction txWithBigPremine)
        {
            Transaction txThatSpendCoinstake = network.CreateTransaction();

            txThatSpendCoinstake.AddInput(new TxIn(new OutPoint(txWithBigPremine, 0), PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(minerA.MinerSecret.PubKey)));
            txThatSpendCoinstake.AddOutput(new TxOut
            {
                Value        = txWithBigPremine.Outputs[0].Value - new Money(1, MoneyUnit.BTC),
                ScriptPubKey = minerB.MinerHDAddress.ScriptPubKey
            });

            var dateTimeProvider = minerA.FullNode.NodeService <IDateTimeProvider>();

            if (txThatSpendCoinstake is IPosTransactionWithTime posTrx)
            {
                posTrx.Time = (uint)dateTimeProvider.GetAdjustedTimeAsUnixTimestamp();
            }

            Coin         spentCoin = new Coin(txWithBigPremine, 0);
            List <ICoin> coins     = new List <ICoin> {
                spentCoin
            };

            txThatSpendCoinstake.Sign(minerA.FullNode.Network, minerA.MinerSecret, coins[0]);

            return(txThatSpendCoinstake);
        }
コード例 #8
0
        private Network InitRegTest()
        {
            Network network = new StratisRegTest();

            network.MoneyUnits = GetMoneyUnitsTest();
            return(network);
        }
コード例 #9
0
        public void XMinesBlocks_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();
                CoreNode stratisNode  = builder.CreateStratisPosNode(network).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;

                TestHelper.WaitLoop(() => stratisXRpc.GetBlockCount() >= 10, cancellationToken: cancellationToken);
                TestHelper.WaitLoop(() => stratisXRpc.GetBestBlockHash() == stratisNodeRpc.GetBestBlockHash(), cancellationToken: cancellationToken);
            }
        }
コード例 #10
0
        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);
            }
        }
コード例 #11
0
        public void ConsensusManager_Fork_Occurs_When_Same_Coins_Are_Staked_On_Different_Chains()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                var network = new StratisRegTest();

                var minerA = builder.CreateStratisPosNode(network, "cm-11-minerA").OverrideDateTimeProvider().WithWallet().Start();
                var minerB = builder.CreateStratisPosNode(network, "cm-11-minerB").OverrideDateTimeProvider().Start();

                minerB.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase, minerA.Mnemonic);

                var coinbaseMaturity = (int)network.Consensus.CoinbaseMaturity;

                // MinerA mines maturity +2 blocks to get the big premine coin and make it stakable.
                TestHelper.MineBlocks(minerA, coinbaseMaturity + 2);

                // Sync the peers A and B (height 12)
                TestHelper.ConnectAndSync(minerA, minerB);

                // Disconnect Miner A and B.
                TestHelper.DisconnectAll(minerA, minerB);

                // Miner A stakes one coin. (height 13)
                var minterA      = minerA.FullNode.NodeService <IPosMinting>();
                var minterAHeigh = minerA.FullNode.ConsensusManager().Tip.Height;
                minterA.Stake(new WalletSecret()
                {
                    WalletName = WalletName, WalletPassword = Password
                });
                Assert.True(TestHelper.IsNodeSyncedAtHeight(minerA, minterAHeigh + 1));

                minterA.StopStake();

                var minterB      = minerB.FullNode.NodeService <IPosMinting>();
                var minterBHeigh = minerB.FullNode.ConsensusManager().Tip.Height;
                minterB.Stake(new WalletSecret()
                {
                    WalletName = WalletName, WalletPassword = Password
                });
                Assert.True(TestHelper.IsNodeSyncedAtHeight(minerB, minterBHeigh + 1));

                minterB.StopStake();

                // MinerB mines 1 block on its own fork. (heightB 13)
                TestHelper.MineBlocks(minerA, 2);
                TestHelper.MineBlocks(minerB, 3);

                TestHelper.ConnectAndSync(minerA, minerB);

                TestBase.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.HashBlock == minerB.FullNode.ConsensusManager().Tip.HashBlock);
                Assert.True(minerA.FullNode.ConsensusManager().Tip.HashBlock == minerB.FullNode.ConsensusManager().Tip.HashBlock);
            }
        }
コード例 #12
0
        public void Mempool_SendTransactionWithLargeOpReturn_ShouldRejectByMempool()
        {
            var network = new StratisRegTest();

            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode stratisSender = builder.CreateStratisPosNode(network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest10Miner).Start();

                TestHelper.MineBlocks(stratisSender, 5);

                // Send coins to the receiver.
                var context = WalletTests.CreateContext(network, new WalletAccountReference(WalletName, Account), Password, new Key().PubKey.GetAddress(network).ScriptPubKey, Money.COIN * 100, FeeType.Medium, 1);
                context.OpReturnData   = "1";
                context.OpReturnAmount = Money.Coins(0.01m);
                Transaction trx = stratisSender.FullNode.WalletTransactionHandler().BuildTransaction(context);

                foreach (TxOut output in trx.Outputs)
                {
                    if (output.ScriptPubKey.IsUnspendable)
                    {
                        int[] data =
                        {
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
                        };
                        var ops = new Op[data.Length + 1];
                        ops[0] = OpcodeType.OP_RETURN;
                        for (int i = 0; i < data.Length; i++)
                        {
                            ops[1 + i] = Op.GetPushOp(data[i]);
                        }

                        output.ScriptPubKey = new Script(ops);
                    }
                }

                // Sign trx again after lengthening nulldata output.
                trx = context.TransactionBuilder.SignTransaction(trx);

                // Enable standard policy relay.
                stratisSender.FullNode.NodeService <MempoolSettings>().RequireStandard = true;

                var broadcaster = stratisSender.FullNode.NodeService <IBroadcasterManager>();

                broadcaster.BroadcastTransactionAsync(trx).GetAwaiter().GetResult();
                var entry = broadcaster.GetTransaction(trx.GetHash());

                Assert.Equal("scriptpubkey", entry.ErrorMessage);
            }
        }
コード例 #13
0
        public void ConsensusManager_Fork_Occurs_When_Stake_Coins_Are_Mined_And_Found_In_Rewind_Data()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                var network = new StratisRegTest();

                var sharedMnemonic = new Mnemonic(Wordlist.English, WordCount.Twelve).ToString();

                // MinerA requires an physical wallet to stake with.
                var minerA = builder.CreateStratisPosNode(network, "cm-10-minerA").OverrideDateTimeProvider().WithWallet(walletMnemonic: sharedMnemonic).Start();
                var minerB = builder.CreateStratisPosNode(network, "cm-10-minerB").OverrideDateTimeProvider().WithWallet(walletMnemonic: sharedMnemonic).Start();

                // MinerA mines 2 blocks to get the big premine coin and mature them (regtest maturity is 10).
                TestHelper.MineBlocks(minerA, 12);

                // Sync the peers A and B (height 12)
                TestHelper.ConnectAndSync(minerA, minerB);

                // Disconnect Miner A and B.
                TestHelper.DisconnectAll(minerA, minerB);

                // Miner A stakes one coin. (height 13)
                var minterA = minerA.FullNode.NodeService <IPosMinting>();
                minterA.Stake(new WalletSecret()
                {
                    WalletName = "mywallet", WalletPassword = "******"
                });
                TestBase.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 13);
                minterA.StopStake();

                TestHelper.MineBlocks(minerB, 2); // this will push minerB total work to be highest
                var minterB = minerB.FullNode.NodeService <IPosMinting>();
                minterB.Stake(new WalletSecret()
                {
                    WalletName = WalletName, WalletPassword = Password
                });
                TestBase.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 15);
                minterB.StopStake();

                var expectedValidChainHeight = minerB.FullNode.ConsensusManager().Tip.Height;

                // Sync the network, minerA should switch to minerB.
                TestHelper.ConnectAndSync(minerA, minerB);

                Assert.True(TestHelper.IsNodeSyncedAtHeight(minerA, expectedValidChainHeight));
                Assert.True(TestHelper.IsNodeSyncedAtHeight(minerB, expectedValidChainHeight));
            }
        }
コード例 #14
0
        public void MiningAndPropagatingPOS_MineBlockCheckPeerHasNewBlock()
        {
            using (NodeBuilder nodeBuilder = NodeBuilder.Create(this))
            {
                var network = new StratisRegTest();

                CoreNode node   = nodeBuilder.CreateStratisPosNode(network).WithDummyWallet().Start();
                CoreNode syncer = nodeBuilder.CreateStratisPosNode(network).Start();

                TestHelper.MineBlocks(node, 1);
                Assert.NotEqual(node.FullNode.ConsensusManager().Tip, syncer.FullNode.ConsensusManager().Tip);

                TestHelper.ConnectAndSync(node, syncer);
                Assert.Equal(node.FullNode.ConsensusManager().Tip, syncer.FullNode.ConsensusManager().Tip);
            }
        }
コード例 #15
0
        public async Task TestScanRPCCapabilitiesOnStratisNetworkAsync()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                Network   network   = new StratisRegTest();
                var       node      = builder.CreateStratisPosNode(network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest10Miner).Start();
                RPCClient rpcClient = node.CreateRPCClient();

                RPCCapabilities capabilities = await rpcClient.ScanRPCCapabilitiesAsync();

                capabilities.SupportEstimateSmartFee.Should().BeFalse();
                capabilities.SupportGetNetworkInfo.Should().BeTrue();
                capabilities.SupportScanUTXOSet.Should().BeFalse();
                capabilities.SupportSignRawTransactionWith.Should().BeFalse();
                capabilities.SupportSegwit.Should().BeTrue();
                capabilities.SupportGenerateToAddress.Should().BeTrue();
            }
        }
コード例 #16
0
        public async Task Can_BanAndDisconnect_Peer_From_ApiAsync()
        {
            using (var builder = NodeBuilder.Create(this))

            {
                var network = new StratisRegTest();

                var nodeA = builder.CreateStratisPosNode(network, "nc-1-nodeA").Start();

                var nodeBIp        = "127.0.0.2";
                var nodeBIpAddress = IPAddress.Parse(nodeBIp);

                var nodeBConfig = new NodeConfigParameters
                {
                    { "-externalip", nodeBIp }
                };

                var nodeB = builder.CreateStratisPosNode(network, agent: "nc-1-nodeB", configParameters: nodeBConfig).Start();

                var nodeAaddressManager = nodeA.FullNode.NodeService <IPeerAddressManager>();
                nodeAaddressManager.AddPeer(new IPEndPoint(nodeBIpAddress, nodeB.Endpoint.Port), IPAddress.Loopback);

                TestHelper.Connect(nodeA, nodeB);

                var banPeerModel = new SetBanPeerViewModel()
                {
                    BanDurationSeconds = 100,
                    BanCommand         = "add",
                    PeerAddress        = nodeBIp
                };

                await $"http://localhost:{nodeA.ApiPort}/api".AppendPathSegment("network/setban").PostJsonAsync(banPeerModel);

                TestBase.WaitLoop(() => !TestHelper.IsNodeConnectedTo(nodeA, nodeB));

                var nodeBEndPoint = new IPEndPoint(nodeBIpAddress, nodeB.Endpoint.Port);

                var addressManager = nodeA.FullNode.NodeService <IPeerAddressManager>();
                var peer           = nodeAaddressManager.FindPeer(nodeBEndPoint);

                var peerBanning = nodeA.FullNode.NodeService <IPeerBanning>();
                Assert.True(peerBanning.IsBanned(nodeBEndPoint));
            }
        }
コード例 #17
0
        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);
            }
        }
コード例 #18
0
        public void PullerVsMinerRaceCondition()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                var stratisRegTest = new StratisRegTest();

                // This represents local node.
                CoreNode stratisMinerLocal = builder.CreateStratisPosNode(stratisRegTest).OverrideDateTimeProvider().WithDummyWallet().Start();

                // This represents remote, which blocks are received by local node using its puller.
                CoreNode stratisMinerRemote = builder.CreateStratisPosNode(stratisRegTest).OverrideDateTimeProvider().WithDummyWallet().Start();

                // Let's mine block Ap and Bp.
                TestHelper.MineBlocks(stratisMinerRemote, 2);

                // Wait for block repository for block sync to work.
                TestHelper.ConnectAndSync(stratisMinerLocal, stratisMinerRemote);

                // Now disconnect the peers and mine block C2p on remote.
                TestHelper.Disconnect(stratisMinerLocal, stratisMinerRemote);

                // Mine block C2p.
                TestHelper.MineBlocks(stratisMinerRemote, 1);
                Thread.Sleep(2000);

                // Now reconnect nodes and mine block C1s before C2p arrives.
                TestHelper.Connect(stratisMinerLocal, stratisMinerRemote);
                TestHelper.MineBlocks(stratisMinerLocal, 1);

                // Mine block Dp.
                uint256 dpHash = TestHelper.MineBlocks(stratisMinerRemote, 1, false).BlockHashes[0];

                // Now we wait until the local node's chain tip has correct hash of Dp.
                TestHelper.WaitLoop(() => stratisMinerLocal.FullNode.Chain.Tip.HashBlock.Equals(dpHash));

                // Then give it time to receive the block from the puller.
                Thread.Sleep(2500);

                // Check that local node accepted the Dp as consensus tip.
                Assert.Equal(stratisMinerLocal.FullNode.ChainBehaviorState.ConsensusTip.HashBlock, dpHash);
            }
        }
コード例 #19
0
        public async Task Can_GetBannedPeers_From_ApiAsync()
        {
            using (var builder = NodeBuilder.Create(this))
            {
                var network = new StratisRegTest();

                var nodeA = builder.CreateStratisPosNode(network, "nc-4-nodeA").Start();

                var nodeB_Ip        = "127.0.0.2";
                var nodeB_IpAddress = IPAddress.Parse(nodeB_Ip);
                var nodeB_EndPoint  = new IPEndPoint(nodeB_IpAddress, 0);

                var nodeB_Ip2        = "127.0.0.3";
                var nodeB_IpAddress2 = IPAddress.Parse(nodeB_Ip2);
                var nodeB_EndPoint2  = new IPEndPoint(nodeB_IpAddress2, 0);

                var nodeAaddressManager = nodeA.FullNode.NodeService <IPeerAddressManager>();
                nodeAaddressManager.AddPeer(new IPEndPoint(nodeB_IpAddress, 0), IPAddress.Loopback);

                var peerBanning = nodeA.FullNode.NodeService <IPeerBanning>();
                peerBanning.BanAndDisconnectPeer(nodeB_EndPoint, "This peer is banned because of a reason");
                Assert.True(peerBanning.IsBanned(nodeB_EndPoint));

                peerBanning.BanAndDisconnectPeer(nodeB_EndPoint2, "This peer is banned because of another reason");
                Assert.True(peerBanning.IsBanned(nodeB_EndPoint2));

                var bannedPeers = await $"http://localhost:{nodeA.ApiPort}/api".AppendPathSegment("network/getbans").GetJsonAsync <List <BannedPeerModel> >();

                Assert.Equal(2, bannedPeers.Count);
                bannedPeers = bannedPeers.OrderBy(b => b.EndPoint).ToList();

                var bannedPeer = bannedPeers[0];
                Assert.Equal("This peer is banned because of a reason", bannedPeer.BanReason);
                Assert.True(DateTime.UtcNow < bannedPeer.BanUntil.Value);
                Assert.Equal("[::ffff:127.0.0.2]:0", bannedPeer.EndPoint);

                bannedPeer = bannedPeers[1];
                Assert.Equal("This peer is banned because of another reason", bannedPeer.BanReason);
                Assert.True(DateTime.UtcNow < bannedPeer.BanUntil.Value);
                Assert.Equal("[::ffff:127.0.0.3]:0", bannedPeer.EndPoint);
            }
        }
コード例 #20
0
        public void correctly_identify_mainchain()
        {
            var stratisRegTest = new StratisRegTest();
            var chain          = stratisRegTest.ToChain();

            chain.Should().Be(Chain.Mainchain);
            chain.Should().NotBe(Chain.Sidechain);

            var stratisTest = new StratisTest();

            chain = stratisTest.ToChain();
            chain.Should().Be(Chain.Mainchain);
            chain.Should().NotBe(Chain.Sidechain);

            var stratisMain = new StratisMain();

            chain = stratisMain.ToChain();
            chain.Should().Be(Chain.Mainchain);
            chain.Should().NotBe(Chain.Sidechain);
        }
コード例 #21
0
        public void ConsensusManager_Block_That_Failed_Partial_Validation_Is_Rejected()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                var network = new StratisRegTest();

                // MinerA requires a physical wallet to stake with.
                var minerA = builder.CreateStratisPosNode(network, "minerA").WithWallet().Start();
                var minerB = builder.CreateStratisPosNode(network, "minerB").Start();
                var minerC = builder.CreateStratisPosNode(network, "minerC").Start();

                // MinerA mines to height 5.
                TestHelper.MineBlocks(minerA, 5);

                // Connect and sync minerA and minerB.
                TestHelper.ConnectAndSync(minerA, minerB);

                TestHelper.Disconnect(minerA, minerB);

                // Mark block 5 as invalid by changing the signature of the block in memory.
                (minerB.FullNode.ChainIndexer.GetHeader(5).Block as PosBlock).BlockSignature.Signature = new byte[] { 0 };

                // Connect and sync minerB and minerC.
                TestHelper.ConnectNoCheck(minerB, minerC);

                // TODO: when signaling failed blocks is enabled we should check this here.

                // Wait for the nodes to disconnect due to invalid block.
                TestBase.WaitLoop(() => !TestHelper.IsNodeConnectedTo(minerB, minerC));

                Assert.True(minerC.FullNode.NodeService <IPeerBanning>().IsBanned(minerB.Endpoint));

                minerC.FullNode.NodeService <IPeerBanning>().UnBanPeer(minerA.Endpoint);

                TestHelper.ConnectAndSync(minerC, minerA);

                TestBase.WaitLoop(() => TestHelper.AreNodesSyncedMessage(minerA, minerC).Passed);
            }
        }
コード例 #22
0
        public void Mempool_SendPosTransaction_WithFutureLockTime_ShouldBeRejectedByMempool()
        {
            // See AcceptToMemoryPool_TxFinalCannotMine_ReturnsFalseAsync for the 'unit test' version

            var network = new StratisRegTest();

            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode stratisSender = builder.CreateStratisPosNode(network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest10Miner).Start();

                TestHelper.MineBlocks(stratisSender, 5);

                // Send coins to the receiver.
                var context = WalletTests.CreateContext(network, new WalletAccountReference(WalletName, Account), Password, new Key().PubKey.GetAddress(network).ScriptPubKey, Money.COIN * 100, FeeType.Medium, 1);

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

                // Treat the locktime as absolute, not relative.
                trx.Inputs.First().Sequence = new Sequence(Sequence.SEQUENCE_LOCKTIME_DISABLE_FLAG);

                // Set the nLockTime to be ahead of the current tip so that locktime has not elapsed.
                trx.LockTime = new LockTime(stratisSender.FullNode.ChainIndexer.Height + 1);

                // Sign trx again after changing the nLockTime.
                trx = context.TransactionBuilder.SignTransaction(trx);

                // Enable standard policy relay.
                stratisSender.FullNode.NodeService <MempoolSettings>().RequireStandard = true;

                var broadcaster = stratisSender.FullNode.NodeService <IBroadcasterManager>();

                broadcaster.BroadcastTransactionAsync(trx).GetAwaiter().GetResult();
                var entry = broadcaster.GetTransaction(trx.GetHash());

                Assert.Equal("non-final", entry.ErrorMessage);
            }
        }
コード例 #23
0
        public void Mempool_SendPosTransaction_WithElapsedLockTime_ShouldBeAcceptedByMempool()
        {
            // See CheckFinalTransaction_WithElapsedLockTime_ReturnsTrueAsync for the 'unit test' version

            var network = new StratisRegTest();

            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode stratisSender = builder.CreateStratisPosNode(network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest10Miner).Start();

                TestHelper.MineBlocks(stratisSender, 5);

                // Send coins to the receiver.
                var context = WalletTests.CreateContext(network, new WalletAccountReference(WalletName, Account), Password, new Key().PubKey.GetAddress(network).ScriptPubKey, Money.COIN * 100, FeeType.Medium, 1);

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

                // Treat the locktime as absolute, not relative.
                trx.Inputs.First().Sequence = new Sequence(Sequence.SEQUENCE_LOCKTIME_DISABLE_FLAG);

                // Set the nLockTime to be behind the current tip so that locktime has elapsed.
                trx.LockTime = new LockTime(stratisSender.FullNode.ChainIndexer.Height - 1);

                // Sign trx again after changing the nLockTime.
                trx = context.TransactionBuilder.SignTransaction(trx);

                // Enable standard policy relay.
                stratisSender.FullNode.NodeService <MempoolSettings>().RequireStandard = true;

                var broadcaster = stratisSender.FullNode.NodeService <IBroadcasterManager>();

                broadcaster.BroadcastTransactionAsync(trx);

                TestBase.WaitLoop(() => stratisSender.CreateRPCClient().GetRawMempool().Length == 1);
            }
        }
コード例 #24
0
        public async Task Can_ClearAll_Banned_PeersAsync()
        {
            using (var builder = NodeBuilder.Create(this))
            {
                var network = new StratisRegTest();

                var nodeA = builder.CreateStratisPosNode(network, "nc-3-nodeA").Start();

                var nodeB_Ip        = "127.0.0.2";
                var nodeB_IpAddress = IPAddress.Parse(nodeB_Ip);
                var nodeB_EndPoint  = new IPEndPoint(nodeB_IpAddress, 0);

                var nodeAaddressManager = nodeA.FullNode.NodeService <IPeerAddressManager>();
                nodeAaddressManager.AddPeer(new IPEndPoint(nodeB_IpAddress, 0), IPAddress.Loopback);

                var peerBanning = nodeA.FullNode.NodeService <IPeerBanning>();
                peerBanning.BanAndDisconnectPeer(nodeB_EndPoint);
                Assert.True(peerBanning.IsBanned(nodeB_EndPoint));

                await $"http://localhost:{nodeA.ApiPort}/api".AppendPathSegment("network/clearbanned").PostJsonAsync(null);

                Assert.False(peerBanning.IsBanned(nodeB_EndPoint));
            }
        }
コード例 #25
0
        public void Staking_Wallet_Can_Mint_New_Coins()
        {
            using (var builder = NodeBuilder.Create(this))
            {
                var configParameters = new NodeConfigParameters {
                    { "savetrxhex", "true" }
                };
                var network = new StratisRegTest();

                var minerA = builder.CreateStratisPosNode(network, "stake-1-minerA", configParameters: configParameters).OverrideDateTimeProvider().WithWallet().Start();

                var addressUsed = TestHelper.MineBlocks(minerA, (int)network.Consensus.PremineHeight).AddressUsed;

                // Since the pre-mine will not be immediately spendable, the transactions have to be counted directly from the address.
                addressUsed.Transactions.Count().Should().Be((int)network.Consensus.PremineHeight);

                addressUsed.Transactions.Sum(s => s.Amount).Should().Be(network.Consensus.PremineReward + network.Consensus.ProofOfWorkReward);

                // Mine blocks to maturity
                TestHelper.MineBlocks(minerA, (int)network.Consensus.CoinbaseMaturity + 10);

                // Get set of transaction IDs present in wallet before staking is started.
                this.transactionsBeforeStaking.Clear();
                foreach (TransactionData transactionData in this.GetTransactionsSnapshot(minerA))
                {
                    this.transactionsBeforeStaking.Add(transactionData.Id);
                }

                // Start staking on the node.
                var minter = minerA.FullNode.NodeService <IPosMinting>();
                minter.Stake(new WalletSecret()
                {
                    WalletName = "mywallet", WalletPassword = "******"
                });

                // If new transactions are appearing in the wallet, staking has been successful. Due to coin maturity settings the
                // spendable balance of the wallet actually drops after staking, so the wallet balance should not be used to
                // determine whether staking occurred.
                TestBase.WaitLoop(() =>
                {
                    List <TransactionData> transactions = this.GetTransactionsSnapshot(minerA);

                    foreach (TransactionData transactionData in transactions)
                    {
                        if (!this.transactionsBeforeStaking.Contains(transactionData.Id) && (transactionData.IsCoinStake ?? false))
                        {
                            return(true);
                        }
                    }

                    return(false);
                });

                // build a dictionary of coinstake tx's indexed by tx id.
                foreach (var tx in this.GetTransactionsSnapshot(minerA))
                {
                    this.transactionLookup[tx.Id] = tx;
                }

                TestBase.WaitLoop(() =>
                {
                    List <TransactionData> transactions = this.GetTransactionsSnapshot(minerA);

                    foreach (TransactionData transactionData in transactions)
                    {
                        if (!this.transactionsBeforeStaking.Contains(transactionData.Id) && (transactionData.IsCoinStake ?? false))
                        {
                            Transaction coinstakeTransaction = minerA.FullNode.Network.CreateTransaction(transactionData.Hex);
                            var balance = new Money(0);

                            // Add coinstake outputs to balance.
                            foreach (TxOut output in coinstakeTransaction.Outputs)
                            {
                                balance += output.Value;
                            }

                            // Subtract coinstake inputs from balance.
                            foreach (TxIn input in coinstakeTransaction.Inputs)
                            {
                                this.transactionLookup.TryGetValue(input.PrevOut.Hash, out TransactionData prevTransactionData);

                                if (prevTransactionData == null)
                                {
                                    continue;
                                }

                                Transaction prevTransaction = minerA.FullNode.Network.CreateTransaction(prevTransactionData.Hex);

                                balance -= prevTransaction.Outputs[input.PrevOut.N].Value;
                            }

                            Assert.Equal(minerA.FullNode.Network.Consensus.ProofOfStakeReward, balance);

                            return(true);
                        }
                    }

                    return(false);
                });
            }
        }
コード例 #26
0
        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);
            }
        }
コード例 #27
0
        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);
            }
        }
コード例 #28
0
        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);
            }
        }
コード例 #29
0
        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);
            }
        }
コード例 #30
0
        public void Staking_Wont_Include_Time_Ahead_Of_Coinstake_Timestamp()
        {
            using (var builder = NodeBuilder.Create(this))
            {
                var configParameters = new NodeConfigParameters {
                    { "savetrxhex", "true" }
                };
                var network = new StratisRegTest();

                var minerA = builder.CreateStratisPosNode(network, "stake-1-minerA", configParameters: configParameters).OverrideDateTimeProvider().WithWallet().Start();

                var addressUsed = TestHelper.MineBlocks(minerA, (int)network.Consensus.PremineHeight).AddressUsed;
                var wallet      = minerA.FullNode.WalletManager().Wallets.Single(w => w.Name == "mywallet");
                var allTrx      = wallet.walletStore.GetForAddress(addressUsed.Address);

                // Since the pre-mine will not be immediately spendable, the transactions have to be counted directly from the address.
                allTrx.Count().Should().Be((int)network.Consensus.PremineHeight);

                allTrx.Sum(s => s.Amount).Should().Be(network.Consensus.PremineReward + network.Consensus.ProofOfWorkReward);
                var balance = minerA.FullNode.WalletManager().GetAddressBalance(addressUsed.Address);
                balance.AmountConfirmed.Should().Be(network.Consensus.PremineReward + network.Consensus.ProofOfWorkReward);

                // Mine blocks to maturity.
                TestHelper.MineBlocks(minerA, (int)network.Consensus.CoinbaseMaturity + 1);

                // Create a transaction and set its timestamp to one that will be rejected from the block.
                Transaction tx = minerA.FullNode.WalletTransactionHandler().BuildTransaction(new TransactionBuildContext(network)
                {
                    Recipients = new List <Recipient>()
                    {
                        new Recipient
                        {
                            ScriptPubKey = addressUsed.ScriptPubKey,
                            Amount       = Money.Coins(1m)
                        }
                    },
                    AccountReference = new WalletAccountReference(minerA.WalletName, "account 0"),
                    WalletPassword   = minerA.WalletPassword,
                    Time             = (uint)minerA.FullNode.DateTimeProvider.GetAdjustedTimeAsUnixTimestamp()
                });
                minerA.AddToStratisMempool(tx);

                TestBase.WaitLoop(() => minerA.FullNode.MempoolManager().InfoAll().Count == 1);

                // Get our height right now.
                int currentHeight = minerA.FullNode.ChainIndexer.Height;

                // Start staking on the node.
                var minter = minerA.FullNode.NodeService <IPosMinting>();
                minter.Stake(new WalletSecret()
                {
                    WalletName = minerA.WalletName, WalletPassword = minerA.WalletPassword
                });

                // Ensure we've staked a block.
                TestBase.WaitLoop(() => minerA.FullNode.ChainIndexer.Height > currentHeight);

                // Get the staked block.
                ChainedHeader header = minerA.FullNode.ChainIndexer.GetHeader(currentHeight + 1);
                Block         block  = minerA.FullNode.BlockStore().GetBlock(header.HashBlock);

                // The transaction should not be in it.
                Assert.DoesNotContain(block.Transactions, x => x.GetHash() == tx.GetHash());
            }
        }