public void Mempool_SendTransactionWithEarlyTimestamp_ShouldRejectByMempool()
        {
            var network = KnownNetworks.StratisRegTest;

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

                int maturity = (int)network.Consensus.CoinbaseMaturity;
                TestHelper.MineBlocks(stratisSender, maturity + 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
                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);
            }
        }
        public void Mempool_SendOversizeTransaction_ShouldRejectByMempool()
        {
            var network = KnownNetworks.StratisRegTest;

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

                int maturity = (int)network.Consensus.CoinbaseMaturity;
                TestHelper.MineBlocks(stratisSender, maturity + 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);
            }
        }
        public void Mempool_SendPosTransaction_AheadOfFutureDrift_ShouldRejectByMempool()
        {
            var network = KnownNetworks.StratisRegTest;

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

                int maturity = (int)network.Consensus.CoinbaseMaturity;
                TestHelper.MineBlocks(stratisSender, maturity + 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.
                trx.Time = Utils.DateTimeToUnixTime(Utils.UnixTimeToDateTime(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);
            }
        }
        public void Mempool_SendTransactionWithLargeOpReturn_ShouldRejectByMempool()
        {
            var network = KnownNetworks.StratisRegTest;

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

                int maturity = (int)network.Consensus.CoinbaseMaturity;
                TestHelper.MineBlocks(stratisSender, maturity + 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);
            }
        }
Beispiel #5
0
        public void Miner_PosNetwork_CreatePowTransaction_AheadOfFutureDrift_ShouldNotBeIncludedInBlock()
        {
            var network = KnownNetworks.StratisRegTest;

            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode stratisMiner = builder.CreateStratisPosNode(network).WithWallet().Start();

                int maturity = (int)network.Consensus.CoinbaseMaturity;
                TestHelper.MineBlocks(stratisMiner, maturity + 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 = stratisMiner.FullNode.WalletTransactionHandler().BuildTransaction(context);

                // This should make the mempool reject a POS trx.
                if (trx is IPosTransactionWithTime posTrx)
                {
                    posTrx.Time = Utils.DateTimeToUnixTime(Utils.UnixTimeToDateTime(posTrx.Time).AddMinutes(5));
                }

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

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

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

                Assert.Equal(TransactionBroadcastState.ReadyToBroadcast, entry.TransactionBroadcastState);

                Assert.NotNull(stratisMiner.FullNode.MempoolManager().GetTransaction(trx.GetHash()).Result);

                TestHelper.MineBlocks(stratisMiner, 1);

                Assert.NotNull(stratisMiner.FullNode.MempoolManager().GetTransaction(trx.GetHash()).Result);
            }
        }
        public void Mempool_SendPosTransaction_WithFutureLockTime_ShouldBeRejectedByMempool()
        {
            // See AcceptToMemoryPool_TxFinalCannotMine_ReturnsFalseAsync for the 'unit test' version

            var network = KnownNetworks.StratisRegTest;

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

                int maturity = (int)network.Consensus.CoinbaseMaturity;
                TestHelper.MineBlocks(stratisSender, maturity + 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.Chain.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);
            }
        }
        public void Mempool_SendPosTransaction_WithElapsedLockTime_ShouldBeAcceptedByMempool()
        {
            // See CheckFinalTransaction_WithElapsedLockTime_ReturnsTrueAsync for the 'unit test' version

            var network = KnownNetworks.StratisRegTest;

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

                int maturity = (int)network.Consensus.CoinbaseMaturity;
                TestHelper.MineBlocks(stratisSender, maturity + 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.Chain.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);

                TestHelper.WaitLoop(() => stratisSender.CreateRPCClient().GetRawMempool().Length == 1);
            }
        }
Beispiel #8
0
        private void SendCoins(CoreNode from, CoreNode to, Money coins, HdAddress toAddress = null)
        {
            // Get a receive address.
            if (toAddress == null)
            {
                toAddress = to.FullNode.WalletManager().GetUnusedAddress(new WalletAccountReference(walletName, accountName));
            }

            // Send 10 coins to node.
            var transaction = from.FullNode.WalletTransactionHandler().BuildTransaction(WalletTests.CreateContext(from.FullNode.Network, new WalletAccountReference(walletName, accountName), password, toAddress.ScriptPubKey, coins, FeeType.Medium, 10));

            from.FullNode.NodeController <WalletController>().SendTransaction(new SendTransactionRequest(transaction.ToHex()));

            TestBase.WaitLoop(() => from.CreateRPCClient().GetRawMempool().Length > 0);

            // Mine the transaction.
            TestHelper.MineBlocks(this.miner, 10);
            TestBase.WaitLoop(() => TestHelper.AreNodesSynced(from, to));
            TestBase.WaitLoop(() => to.FullNode.WalletManager().GetSpendableTransactionsInWallet(walletName).Sum(x => x.Transaction.Amount) > 0);
        }
        public void MineBlocksBlockOrphanedAfterReorgTxsReturnedToMempool()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                // Setup two synced nodes with some mined blocks.
                string password    = "******";
                string name        = "mywallet";
                string accountName = "account 0";

                CoreNode node1 = builder.CreateStratisPowNode(new BitcoinRegTest()).WithWallet().Start();
                CoreNode node2 = builder.CreateStratisPowNode(new BitcoinRegTest()).WithWallet().Start();

                var mempoolValidationState = new MempoolValidationState(true);

                int maturity = (int)node1.FullNode.Network.Consensus.CoinbaseMaturity;
                TestHelper.MineBlocks(node1, maturity + 20);
                TestHelper.ConnectAndSync(node1, node2);

                // Nodes disconnect.
                TestHelper.Disconnect(node1, node2);

                // Create tx and node 1 has this in mempool.
                HdAddress   receivingAddress = node2.FullNode.WalletManager().GetUnusedAddress(new WalletAccountReference(name, accountName));
                Transaction transaction      = node1.FullNode.WalletTransactionHandler().BuildTransaction(WalletTests.CreateContext(node1.FullNode.Network,
                                                                                                                                    new WalletAccountReference(name, accountName), password, receivingAddress.ScriptPubKey, Money.COIN * 100, FeeType.Medium, 101));

                Assert.True(node1.FullNode.MempoolManager().Validator.AcceptToMemoryPool(mempoolValidationState, transaction).Result);
                Assert.Contains(transaction.GetHash(), node1.FullNode.MempoolManager().GetMempoolAsync().Result);

                // Node 2 has none in its mempool.
                TestHelper.WaitLoop(() => node2.FullNode.MempoolManager().MempoolSize().Result == 0);

                // Node 1 mines new tx into block - removed from mempool.
                (HdAddress addressUsed, List <uint256> blockHashes) = TestHelper.MineBlocks(node1, 1);
                uint256 minedBlockHash = blockHashes.Single();
                TestHelper.WaitLoop(() => node1.FullNode.MempoolManager().MempoolSize().Result == 0);

                // Node 2 mines two blocks to have greatest chainwork.
                TestHelper.MineBlocks(node2, 2);

                // Sync nodes and reorg occurs.
                TestHelper.ConnectAndSync(node1, true, node2);

                // Block mined by Node 1 is orphaned.
                Assert.Null(node1.FullNode.ChainBehaviorState.ConsensusTip.FindAncestorOrSelf(minedBlockHash));

                // Tx is returned to mempool.
                Assert.Contains(transaction.GetHash(), node1.FullNode.MempoolManager().GetMempoolAsync().Result);

                // New mined block contains this transaction from the orphaned block.
                TestHelper.MineBlocks(node1, 1);
                Assert.Contains(transaction, node1.FullNode.Chain.Tip.Block.Transactions);
            }
        }