Example #1
0
        public virtual void TestInitialize()
        {
            Initialize(mockedServices: false);

            var bitcoindConfigKey = "BitcoindFullPath";

            bitcoindFullPath = Configuration[bitcoindConfigKey];
            if (string.IsNullOrEmpty(bitcoindFullPath))
            {
                throw new Exception($"Required parameter {bitcoindConfigKey} is missing from configuration");
            }

            var alternativeIp = Configuration["HostIp"];

            if (!string.IsNullOrEmpty(alternativeIp))
            {
                hostIp = alternativeIp;
            }

            bool skipNodeStart = GetType().GetMethod(TestContext.TestName).GetCustomAttributes(true).Any(a => a.GetType() == typeof(SkipNodeStartAttribute));

            if (!skipNodeStart)
            {
                zmqSubscribedEventSubscription = eventBus.Subscribe <ZMQSubscribedEvent>();
                node0      = CreateAndStartNode(0);
                _          = zmqSubscribedEventSubscription.ReadAsync(CancellationToken.None).Result;
                rpcClient0 = node0.RpcClient;
                SetupChain(rpcClient0);
            }
        }
Example #2
0
        public void StopBitcoind(BitcoindProcess bitcoind)
        {
            if (!bitcoindProcesses.Contains(bitcoind))
            {
                throw new Exception($"Can not stop a bitcoind that was not started by {nameof(StartBitcoind)} ");
            }

            bitcoind.Dispose();
        }
Example #3
0
        public async Task MultipleInputsWithDS()
        {
            using CancellationTokenSource cts = new(30000);

            // startup another node and link it to the first node
            node1 = StartBitcoind(1, new BitcoindProcess[] { node0 });
            var syncTask = SyncNodesBlocksAsync(cts.Token, node0, node1);

            StartupLiveMAPI();
            var coin0 = availableCoins.Dequeue();
            var coin2 = availableCoins.Dequeue();

            var tx1    = CreateDS_OP_RETURN_Tx(new Coin[] { coin0, availableCoins.Dequeue(), coin2, availableCoins.Dequeue() }, 0, 2);
            var tx1Hex = tx1.ToHex();
            var tx1Id  = tx1.GetHash().ToString();

            var payload = await SubmitTransactions(new string[] { tx1Hex });

            loggerTest.LogInformation($"Submiting {tx1Id} with dsCheck enabled");
            var httpResponse = await PerformRequestAsync(Client, HttpMethod.Get, MapiServer.ApiDSQuery + "/" + tx1Id);

            // Wait for tx to be propagated to node 1 before submiting a doublespend tx to node 1
            await WaitForTxToBeAcceptedToMempool(node1, tx1Id, cts.Token);

            // Create double spend tx and submit it to node 1
            var(txHex2, txId2) = CreateNewTransaction(coin0, new Money(1000L));

            await syncTask;

            loggerTest.LogInformation($"Submiting {txId2} with doublespend");
            await Assert.ThrowsExceptionAsync <RpcException>(async() => await node1.RpcClient.SendRawTransactionAsync(HelperTools.HexStringToByteArray(txHex2), true, false));

            // Wait for a bit for node and Live mAPI to process all events
            await Task.Delay(3000);

            loggerTest.LogInformation("Retrieving notification data");
            var notifications = await TxRepositoryPostgres.GetNotificationsForTestsAsync();

            Assert.AreEqual(1, notifications.Length);
            Assert.AreEqual(txId2, new uint256(notifications.Single().DoubleSpendTxId).ToString());

            //Create another DS tx which should not trigger another notification
            var(txHex3, txId3) = CreateNewTransaction(coin2, new Money(5000L));

            loggerTest.LogInformation($"Submiting {txId3} with doublespend");
            await Assert.ThrowsExceptionAsync <RpcException>(async() => await node1.RpcClient.SendRawTransactionAsync(HelperTools.HexStringToByteArray(txHex3), true, false));

            await Task.Delay(3000);

            notifications = await TxRepositoryPostgres.GetNotificationsForTestsAsync();

            Assert.AreEqual(1, notifications.Length);
            await StopMAPI();
        }
Example #4
0
        public BitcoindProcess StartBitcoind(int nodeIndex)
        {
            string testPerfix = TestContext.FullyQualifiedTestClassName;

            if (testPerfix.StartsWith(commonTestPrefix))
            {
                testPerfix = testPerfix.Substring(commonTestPrefix.Length);
            }

            var dataDirRoot = Path.Combine(TestContext.TestRunDirectory, "node" + nodeIndex, testPerfix, TestContext.TestName);

            if (Environment.OSVersion.Platform == PlatformID.Win32NT && dataDirRoot.Length + bitcoindInternalPathLength >= 260)
            {
                // LevelDB refuses to open file with path length  longer than 260
                throw new Exception($"Length of data directory path is too long. This might cause problems when running bitcoind on Windows. Please run tests from directory with a short path. Data directory path: {dataDirRoot}");
            }
            var bitcoind = new BitcoindProcess(
                bitcoindFullPath,
                dataDirRoot,
                nodeIndex, hostIp, zmqIp, loggerFactory);

            bitcoindProcesses.Add(bitcoind);
            return(bitcoind);
        }