public async Task NodesDifferAsync()
        {
            using var services1 = new HostedServices();
            using var services2 = new HostedServices();
            var coreNodes = await Task.WhenAll(TestNodeBuilder.CreateAsync(services1, additionalFolder: "0"), TestNodeBuilder.CreateAsync(services2, additionalFolder: "1"));

            await services1.StartAllAsync(CancellationToken.None);

            await services2.StartAllAsync(CancellationToken.None);

            CoreNode node1 = coreNodes[0];
            CoreNode node2 = coreNodes[1];

            try
            {
                Assert.NotEqual(node1.DataDir, node2.DataDir);
                Assert.NotEqual(node1.P2pEndPoint, node2.P2pEndPoint);
                Assert.NotEqual(node1.RpcEndPoint, node2.RpcEndPoint);
            }
            finally
            {
                await services1.StopAllAsync(CancellationToken.None);

                await services2.StopAllAsync(CancellationToken.None);

                await Task.WhenAll(node1.TryStopAsync(), node2.TryStopAsync());
            }
        }
Exemplo n.º 2
0
        public async Task AllFeeEstimateAsync()
        {
            var coreNode = await TestNodeBuilder.CreateAsync();

            try
            {
                var rpc         = coreNode.RpcClient;
                var estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, simulateIfRegTest : true, tolerateBitcoinCoreBrainfuck : true);

                Assert.Equal(WalletWasabi.Helpers.Constants.OneDayConfirmationTarget, estimations.Estimations.Count);
                Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key);
                Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value);
                Assert.Equal(EstimateSmartFeeMode.Conservative, estimations.Type);
                estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Economical, simulateIfRegTest : true, tolerateBitcoinCoreBrainfuck : true);

                Assert.Equal(145, estimations.Estimations.Count);
                Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key);
                Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value);
                Assert.Equal(EstimateSmartFeeMode.Economical, estimations.Type);
                estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Economical, simulateIfRegTest : true, tolerateBitcoinCoreBrainfuck : false);

                Assert.Equal(145, estimations.Estimations.Count);
                Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key);
                Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value);
                Assert.Equal(EstimateSmartFeeMode.Economical, estimations.Type);
            }
            finally
            {
                await coreNode.StopAsync();
            }
        }
Exemplo n.º 3
0
        public async Task AllFeeEstimateAsync()
        {
            using var services = new HostedServices();
            var coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync(CancellationToken.None);

            try
            {
                var rpc         = coreNode.RpcClient;
                var estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, simulateIfRegTest : true);

                Assert.Equal(WalletWasabi.Helpers.Constants.OneDayConfirmationTarget, estimations.Estimations.Count);
                Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key);
                Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value);
                Assert.Equal(EstimateSmartFeeMode.Conservative, estimations.Type);
                estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Economical, simulateIfRegTest : true);

                Assert.Equal(145, estimations.Estimations.Count);
                Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key);
                Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value);
                Assert.Equal(EstimateSmartFeeMode.Economical, estimations.Type);
            }
            finally
            {
                await services.StopAllAsync(CancellationToken.None);

                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 4
0
        public async Task MempoolNotifiesAsync()
        {
            using var services = new HostedServices();
            var coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync(CancellationToken.None);

            using var node = await coreNode.CreateNewP2pNodeAsync();

            try
            {
                var network          = coreNode.Network;
                var rpc              = coreNode.RpcClient;
                var dir              = Path.Combine(Global.Instance.DataDir, EnvironmentHelpers.GetCallerFileName(), EnvironmentHelpers.GetMethodName());
                var indexStore       = new IndexStore(Path.Combine(dir, "indexStore"), network, new SmartHeaderChain());
                var transactionStore = new AllTransactionStore(Path.Combine(dir, "transactionStore"), network);
                var mempoolService   = new MempoolService();
                var blocks           = new FileSystemBlockRepository(Path.Combine(dir, "blocks"), network);
                var bitcoinStore     = new BitcoinStore(indexStore, transactionStore, mempoolService, blocks);
                await bitcoinStore.InitializeAsync();

                await rpc.GenerateAsync(101);

                node.Behaviors.Add(bitcoinStore.CreateUntrustedP2pBehavior());
                node.VersionHandshake();

                var addr = new Key().PubKey.GetSegwitAddress(network);

                var txNum        = 10;
                var eventAwaiter = new EventsAwaiter <SmartTransaction>(
                    h => bitcoinStore.MempoolService.TransactionReceived += h,
                    h => bitcoinStore.MempoolService.TransactionReceived -= h,
                    txNum);

                var txTasks = new List <Task <uint256> >();
                var batch   = rpc.PrepareBatch();
                for (int i = 0; i < txNum; i++)
                {
                    txTasks.Add(batch.SendToAddressAsync(addr, Money.Coins(1)));
                }
                var batchTask = batch.SendBatchAsync();

                var stxs = await eventAwaiter.WaitAsync(TimeSpan.FromSeconds(21));

                await batchTask;
                var   hashes = await Task.WhenAll(txTasks);

                foreach (var stx in stxs)
                {
                    Assert.Contains(stx.GetHash(), hashes);
                }
            }
            finally
            {
                await services.StopAllAsync(CancellationToken.None);

                node.Disconnect();
                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 5
0
        private volatile bool _disposedValue = false;         // To detect redundant calls

        public RegTestFixture()
        {
            RuntimeParams.SetDataDir(Path.Combine(Common.DataDir, "RegTests", "Backend"));
            RuntimeParams.LoadAsync().GetAwaiter().GetResult();
            var hostedServices = new HostedServices();

            BackendRegTestNode = TestNodeBuilder.CreateAsync(hostedServices, callerFilePath: "RegTests", callerMemberName: "BitcoinCoreData").GetAwaiter().GetResult();

            var testnetBackendDir = EnvironmentHelpers.GetDataDir(Path.Combine("WalletWasabi", "Tests", "RegTests", "Backend"));

            IoHelpers.TryDeleteDirectoryAsync(testnetBackendDir).GetAwaiter().GetResult();
            Thread.Sleep(100);
            Directory.CreateDirectory(testnetBackendDir);
            Thread.Sleep(100);
            var config = new Config(
                BackendRegTestNode.RpcClient.Network,
                BackendRegTestNode.RpcClient.CredentialString.ToString(),
                new IPEndPoint(IPAddress.Loopback, Network.Main.DefaultPort),
                new IPEndPoint(IPAddress.Loopback, Network.TestNet.DefaultPort),
                BackendRegTestNode.P2pEndPoint,
                new IPEndPoint(IPAddress.Loopback, Network.Main.RPCPort),
                new IPEndPoint(IPAddress.Loopback, Network.TestNet.RPCPort),
                BackendRegTestNode.RpcEndPoint);
            var configFilePath = Path.Combine(testnetBackendDir, "Config.json");

            config.SetFilePath(configFilePath);
            config.ToFile();

            var roundConfig         = CreateRoundConfig(Money.Coins(0.1m), Constants.OneDayConfirmationTarget, 0.7, 0.1m, 100, 120, 60, 60, 60, 1, 24, true, 11);
            var roundConfigFilePath = Path.Combine(testnetBackendDir, "CcjRoundConfig.json");

            roundConfig.SetFilePath(roundConfigFilePath);
            roundConfig.ToFile();

            var conf = new ConfigurationBuilder()
                       .AddInMemoryCollection(new[] { new KeyValuePair <string, string>("datadir", testnetBackendDir) })
                       .Build();

            BackendEndPoint       = $"http://localhost:{CryptoHelpers.RandomInt(37130, 37999)}/";
            BackendEndPointUri    = new Uri(BackendEndPoint);
            BackendEndPointApiUri = new Uri(BackendEndPointUri, $"/api/v{Constants.BackendMajorVersion}/");

            BackendHost = Host.CreateDefaultBuilder()
                          .ConfigureWebHostDefaults(webBuilder => webBuilder
                                                    .UseStartup <Startup>()
                                                    .UseConfiguration(conf)
                                                    .UseWebRoot("../../../../WalletWasabi.Backend/wwwroot")
                                                    .UseUrls(BackendEndPoint))
                          .Build();

            Global = (Global)BackendHost.Services.GetService(typeof(Global));
            Global.HostedServices = hostedServices;
            var hostInitializationTask = BackendHost.RunWithTasksAsync();

            Logger.LogInfo($"Started Backend webhost: {BackendEndPoint}");

            var delayTask = Task.Delay(3000);

            Task.WaitAny(delayTask, hostInitializationTask);             // Wait for server to initialize (Without this OSX CI will fail)
        }
Exemplo n.º 6
0
    public async Task AllFeeEstimateAsync()
    {
        var coreNode = await TestNodeBuilder.CreateAsync();

        try
        {
            var rpc         = coreNode.RpcClient;
            var estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, simulateIfRegTest : true);

            Assert.Equal(7, estimations.Estimations.Count);
            Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key);
            Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value);
            Assert.Equal(EstimateSmartFeeMode.Conservative, estimations.Type);
            estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Economical, simulateIfRegTest : true);

            Assert.Equal(7, estimations.Estimations.Count);
            Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key);
            Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value);
            Assert.Equal(EstimateSmartFeeMode.Economical, estimations.Type);
        }
        finally
        {
            await coreNode.TryStopAsync();
        }
    }
Exemplo n.º 7
0
        public async Task TrustedNotifierNotifiesTxAsync()
        {
            var coreNode = await TestNodeBuilder.CreateAsync();

            try
            {
                var rpc = coreNode.RpcClient;
                await rpc.GenerateAsync(101);

                var network = rpc.Network;

                var dir = Path.Combine(Global.Instance.DataDir, EnvironmentHelpers.GetMethodName());

                var addr     = new Key().PubKey.GetSegwitAddress(network);
                var notifier = coreNode.TrustedNodeNotifyingBehavior;

                var txNum             = 10;
                var txInvEventAwaiter = new EventsAwaiter <uint256>(
                    h => notifier.TransactionInv += h,
                    h => notifier.TransactionInv -= h,
                    txNum);

                var txEventAwaiter = new EventsAwaiter <SmartTransaction>(
                    h => notifier.Transaction += h,
                    h => notifier.Transaction -= h,
                    txNum);

                var txTasks = new List <Task <uint256> >();
                var batch   = rpc.PrepareBatch();
                for (int i = 0; i < txNum; i++)
                {
                    txTasks.Add(batch.SendToAddressAsync(addr, Money.Coins(1)));
                }
                var batchTask = batch.SendBatchAsync();

                var aht        = txInvEventAwaiter.WaitAsync(TimeSpan.FromSeconds(21));
                var arrivedTxs = await txEventAwaiter.WaitAsync(TimeSpan.FromSeconds(21));

                var arrivedHashes = await aht;

                await batchTask;
                var   hashes = await Task.WhenAll(txTasks);

                foreach (var hash in arrivedHashes)
                {
                    Assert.Contains(hash, hashes);
                }
                foreach (var hash in arrivedTxs.Select(x => x.GetHash()))
                {
                    Assert.Contains(hash, hashes);
                }
            }
            finally
            {
                await coreNode.TryStopAsync();
            }
        }
    public async Task CanHandleConfirmationAsync()
    {
        var coreNode = await TestNodeBuilder.CreateAsync();

        using HostedServices services = new();
        services.Register <MempoolMirror>(() => new MempoolMirror(TimeSpan.FromSeconds(2), coreNode.RpcClient, coreNode.P2pNode), "Mempool Mirror");
        try
        {
            var rpc     = coreNode.RpcClient;
            var network = rpc.Network;
            await services.StartAllAsync();

            var mempoolInstance = services.Get <MempoolMirror>();

            var walletName = "RandomWalletName";
            await rpc.CreateWalletAsync(walletName);

            var spendAmount = new Money(0.0004m, MoneyUnit.BTC);

            await rpc.GenerateAsync(101);

            var rpcMempoolBeforeSend = await rpc.GetRawMempoolAsync();

            var localMempoolBeforeSend = mempoolInstance.GetMempoolHashes();
            Assert.Equal(rpcMempoolBeforeSend.Length, localMempoolBeforeSend.Count);

            await rpc.SendToAddressAsync(BitcoinFactory.CreateBitcoinAddress(network), spendAmount);

            while (!(await rpc.GetRawMempoolAsync()).Any())
            {
                await Task.Delay(50);
            }

            await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

            var localMempoolAfterSend = mempoolInstance.GetMempoolHashes();
            Assert.Equal(1, localMempoolAfterSend.Count);
            Assert.Single(localMempoolAfterSend);

            await rpc.GenerateAsync(1);

            while ((await rpc.GetRawMempoolAsync()).Any())
            {
                await Task.Delay(50);
            }
            await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

            var localMempoolAfterBlockMined = mempoolInstance.GetMempoolHashes();
            Assert.Empty(localMempoolAfterBlockMined);
        }
        finally
        {
            await services.StopAllAsync();

            await coreNode.TryStopAsync();
        }
    }
    public async Task CanHandleTheSameTxSentManyTimesAsync()
    {
        var coreNode = await TestNodeBuilder.CreateAsync();

        using HostedServices services = new();
        services.Register <MempoolMirror>(() => new MempoolMirror(TimeSpan.FromSeconds(2), coreNode.RpcClient, coreNode.P2pNode), "Mempool Mirror");
        try
        {
            var rpc     = coreNode.RpcClient;
            var network = rpc.Network;
            await services.StartAllAsync();

            var mempoolInstance = services.Get <MempoolMirror>();

            var walletName = "RandomWalletName";
            await rpc.CreateWalletAsync(walletName);

            using var k1 = new Key();
            var blockIds = await rpc.GenerateToAddressAsync(1, k1.PubKey.WitHash.GetAddress(network));

            var block = await rpc.GetBlockAsync(blockIds[0]);

            var coinBaseTx = block.Transactions[0];

            var tx = Transaction.Create(network);
            tx.Inputs.Add(coinBaseTx, 0);
            tx.Outputs.Add(Money.Coins(49.9999m), BitcoinFactory.CreateBitcoinAddress(network));
            tx.Sign(k1.GetBitcoinSecret(network), coinBaseTx.Outputs.AsCoins().First());
            var valid = tx.Check();

            await rpc.GenerateAsync(101);

            for (int i = 0; i < 5; i++)
            {
                await rpc.SendRawTransactionAsync(tx);
            }

            while (!(await rpc.GetRawMempoolAsync()).Any())
            {
                await Task.Delay(50);
            }

            await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

            var localMempoolHashes = mempoolInstance.GetMempoolHashes();

            Assert.Single(localMempoolHashes);
            Assert.Contains(tx.GetHash(), localMempoolHashes);
        }
        finally
        {
            await services.StopAllAsync();

            await coreNode.TryStopAsync();
        }
    }
        public async Task CanBuildCoreNodeAsync()
        {
            using var services = new HostedServices();
            var coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync(CancellationToken.None);

            await coreNode.TryStopAsync();

            await services.StopAllAsync(CancellationToken.None);
        }
Exemplo n.º 11
0
        public async Task TrustedNotifierNotifiesTxAsync()
        {
            using HostedServices services = new();
            var coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync();

            try
            {
                var rpc        = coreNode.RpcClient;
                var walletName = "wallet.dat";
                await rpc.CreateWalletAsync(walletName);

                await rpc.GenerateAsync(101);

                var network = rpc.Network;

                var dir = Common.GetWorkDir();

                using Key k = new();
                var addr     = k.PubKey.GetSegwitAddress(network);
                var notifier = coreNode.MempoolService;

                var txNum = 10;
                EventsAwaiter <SmartTransaction> txEventAwaiter = new(
                    h => notifier.TransactionReceived += h,
                    h => notifier.TransactionReceived -= h,
                    txNum);

                List <Task <uint256> > txTasks = new();
                var batch = rpc.PrepareBatch();
                for (int i = 0; i < txNum; i++)
                {
                    txTasks.Add(batch.SendToAddressAsync(addr, Money.Coins(1)));
                }
                var batchTask = batch.SendBatchAsync();

                var arrivedTxs = await txEventAwaiter.WaitAsync(TimeSpan.FromSeconds(21));

                await batchTask;
                var   hashes = await Task.WhenAll(txTasks);

                foreach (var hash in arrivedTxs.Select(x => x.GetHash()))
                {
                    Assert.Contains(hash, hashes);
                }
            }
            finally
            {
                await services.StopAllAsync();

                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 12
0
        public async Task MempoolNotifiesAsync()
        {
            var coreNode = await TestNodeBuilder.CreateAsync();

            using var node = await coreNode.CreateP2pNodeAsync();

            try
            {
                var rpc = coreNode.RpcClient;
                await rpc.GenerateAsync(101);

                var network      = rpc.Network;
                var bitcoinStore = new BitcoinStore();

                var dir = Path.Combine(Global.Instance.DataDir, EnvironmentHelpers.GetMethodName());
                await bitcoinStore.InitializeAsync(dir, network);

                node.Behaviors.Add(bitcoinStore.CreateMempoolBehavior());
                node.VersionHandshake();

                var addr = new Key().PubKey.GetSegwitAddress(network);

                var txNum        = 10;
                var eventAwaiter = new EventsAwaiter <SmartTransaction>(
                    h => bitcoinStore.MempoolService.TransactionReceived += h,
                    h => bitcoinStore.MempoolService.TransactionReceived -= h,
                    txNum);

                var txTasks = new List <Task <uint256> >();
                var batch   = rpc.PrepareBatch();
                for (int i = 0; i < txNum; i++)
                {
                    txTasks.Add(batch.SendToAddressAsync(addr, Money.Coins(1)));
                }
                var batchTask = batch.SendBatchAsync();

                var stxs = await eventAwaiter.WaitAsync(TimeSpan.FromSeconds(21));

                await batchTask;
                var   hashes = await Task.WhenAll(txTasks);

                foreach (var stx in stxs)
                {
                    Assert.Contains(stx.GetHash(), hashes);
                }
            }
            finally
            {
                node.Disconnect();
                await coreNode.StopAsync();
            }
        }
Exemplo n.º 13
0
        public async Task CanBuildCoreNodeAsync()
        {
            var coreNode = await TestNodeBuilder.CreateAsync();

            try
            {
                Assert.False(coreNode.Process.HasExited);
            }
            finally
            {
                await coreNode.StopAsync();
            }
        }
Exemplo n.º 14
0
    public async Task GetRawTransactionsAsync()
    {
        var coreNode = await TestNodeBuilder.CreateAsync();

        try
        {
            var rpc = coreNode.RpcClient;
            var txs = await rpc.GetRawTransactionsAsync(new[] { BitcoinFactory.CreateUint256(), BitcoinFactory.CreateUint256() }, CancellationToken.None);

            Assert.Empty(txs);

            await rpc.CreateWalletAsync("wallet");

            await rpc.GenerateAsync(101);

            var txid = await rpc.SendToAddressAsync(BitcoinFactory.CreateScript().GetDestinationAddress(Network.RegTest), Money.Coins(1));

            txs = await rpc.GetRawTransactionsAsync(new[] { txid }, CancellationToken.None);

            Assert.Single(txs);

            List <uint256> txids = new();
            for (int i = 0; i < 2; i++)
            {
                var txid2 = await rpc.SendToAddressAsync(BitcoinFactory.CreateScript().GetDestinationAddress(Network.RegTest), Money.Coins(1));

                txids.Add(txid2);
            }

            txs = await rpc.GetRawTransactionsAsync(txids, CancellationToken.None);

            Assert.Equal(2, txs.Count());

            txids = new();
            for (int i = 0; i < 20; i++)
            {
                var txid2 = await rpc.SendToAddressAsync(BitcoinFactory.CreateScript().GetDestinationAddress(Network.RegTest), Money.Coins(1));

                txids.Add(txid2);
            }

            txs = await rpc.GetRawTransactionsAsync(txids, CancellationToken.None);

            Assert.Equal(20, txs.Count());
        }
        finally
        {
            await coreNode.TryStopAsync();
        }
    }
    public async Task CanHandleManyTxsAsync()
    {
        var coreNode = await TestNodeBuilder.CreateAsync();

        using HostedServices services = new();
        services.Register <MempoolMirror>(() => new MempoolMirror(TimeSpan.FromSeconds(2), coreNode.RpcClient, coreNode.P2pNode), "Mempool Mirror");
        try
        {
            var rpc     = coreNode.RpcClient;
            var network = rpc.Network;
            await services.StartAllAsync();

            var mempoolInstance = services.Get <MempoolMirror>();

            var walletName = "RandomWalletName";
            await rpc.CreateWalletAsync(walletName);

            using var k1 = new Key();
            var blockIds = await rpc.GenerateToAddressAsync(1, k1.PubKey.WitHash.GetAddress(network));

            var block = await rpc.GetBlockAsync(blockIds[0]);

            var coinBaseTx = block.Transactions[0];

            await rpc.GenerateAsync(101);

            for (int i = 0; i < 5; i++)
            {
                await rpc.SendToAddressAsync(BitcoinFactory.CreateBitcoinAddress(network), new Money(0.0004m, MoneyUnit.BTC));
            }

            while ((await rpc.GetRawMempoolAsync()).Length != 5)
            {
                await Task.Delay(50);
            }

            await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

            var localMempoolHashes = mempoolInstance.GetMempoolHashes();

            Assert.Equal(5, localMempoolHashes.Count);
        }
        finally
        {
            await services.StopAllAsync();

            await coreNode.TryStopAsync();
        }
    }
Exemplo n.º 16
0
        public async Task CantDoubleSpendAsync()
        {
            using var services = new HostedServices();
            var coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync(CancellationToken.None);

            try
            {
                var rpc     = coreNode.RpcClient;
                var network = rpc.Network;

                var walletName = "wallet.dat";
                await rpc.CreateWalletAsync(walletName);

                using var k1 = new Key();
                var blockId = await rpc.GenerateToAddressAsync(1, k1.PubKey.WitHash.GetAddress(network));

                var block = await rpc.GetBlockAsync(blockId[0]);

                var coinBaseTx = block.Transactions[0];

                var tx = Transaction.Create(network);
                tx.Inputs.Add(coinBaseTx, 0);
                using var k2 = new Key();
                tx.Outputs.Add(Money.Coins(49.9999m), k2.PubKey.WitHash.GetAddress(network));
                tx.Sign(k1.GetBitcoinSecret(network), coinBaseTx.Outputs.AsCoins().First());
                var valid = tx.Check();

                var doubleSpend = Transaction.Create(network);
                doubleSpend.Inputs.Add(coinBaseTx, 0);
                using var k3 = new Key();
                doubleSpend.Outputs.Add(Money.Coins(49.998m), k3.PubKey.WitHash.GetAddress(network));
                doubleSpend.Sign(k1.GetBitcoinSecret(network), coinBaseTx.Outputs.AsCoins().First());
                valid = doubleSpend.Check();

                await rpc.GenerateAsync(101);

                var txId = await rpc.SendRawTransactionAsync(tx);

                await Assert.ThrowsAsync <RPCException>(async() => await rpc.SendRawTransactionAsync(doubleSpend));
            }
            finally
            {
                await services.StopAllAsync(CancellationToken.None);

                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 17
0
        public async Task RpcWorksAsync()
        {
            var coreNode = await TestNodeBuilder.CreateAsync();

            try
            {
                var blockCount = await coreNode.RpcClient.GetBlockCountAsync();

                Assert.Equal(0, blockCount);
            }
            finally
            {
                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 18
0
    public async Task FeeEstimationCanCancelAsync()
    {
        var coreNode = await TestNodeBuilder.CreateAsync();

        try
        {
            var rpc = coreNode.RpcClient;
            using CancellationTokenSource cts = new(TimeSpan.Zero);
            await Assert.ThrowsAsync <TaskCanceledException>(async() => await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, true, cts.Token));
        }
        finally
        {
            await coreNode.TryStopAsync();
        }
    }
Exemplo n.º 19
0
    public async Task VerboseBlockInfoAsync()
    {
        var coreNode = await TestNodeBuilder.CreateAsync();

        try
        {
            var rpc       = coreNode.RpcClient;
            var blockInfo = await rpc.GetVerboseBlockAsync(coreNode.Network.GenesisHash);

            Assert.NotNull(blockInfo.Transactions.ElementAt(0).Inputs.ElementAt(0).Coinbase);
        }
        finally
        {
            await coreNode.TryStopAsync();
        }
    }
Exemplo n.º 20
0
        public async Task P2pWorksAsync()
        {
            var coreNode = await TestNodeBuilder.CreateAsync();

            using var node = await coreNode.CreateNewP2pNodeAsync();

            try
            {
                var blocks  = node.GetBlocks(new[] { Network.RegTest.GenesisHash });
                var genesis = Assert.Single(blocks);
                Assert.Equal(genesis.GetHash(), Network.RegTest.GenesisHash);
            }
            finally
            {
                node.Disconnect();
                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 21
0
        public async Task NodesDifferAsync()
        {
            var coreNodes = await Task.WhenAll(TestNodeBuilder.CreateAsync(additionalFolder: "0"), TestNodeBuilder.CreateAsync(additionalFolder: "1"));

            CoreNode node1 = coreNodes[0];
            CoreNode node2 = coreNodes[1];

            try
            {
                Assert.NotEqual(node1.DataDir, node2.DataDir);
                Assert.NotEqual(node1.P2pEndPoint, node2.P2pEndPoint);
                Assert.NotEqual(node1.RpcEndPoint, node2.RpcEndPoint);
            }
            finally
            {
                await Task.WhenAll(node1.TryStopAsync(), node2.TryStopAsync());
            }
        }
    public async Task CanCopyMempoolFromRpcAsync()
    {
        var coreNode = await TestNodeBuilder.CreateAsync();

        using HostedServices services = new();
        services.Register <MempoolMirror>(() => new MempoolMirror(TimeSpan.FromSeconds(2), coreNode.RpcClient, coreNode.P2pNode), "Mempool Mirror");
        try
        {
            var rpc             = coreNode.RpcClient;
            var network         = rpc.Network;
            var mempoolInstance = services.Get <MempoolMirror>();
            var walletName      = "RandomWalletName";
            await rpc.CreateWalletAsync(walletName);

            var spendAmount  = new Money(0.0004m, MoneyUnit.BTC);
            var spendAmount2 = new Money(0.0004m, MoneyUnit.BTC);
            await rpc.GenerateAsync(101);

            var txid = await rpc.SendToAddressAsync(BitcoinFactory.CreateBitcoinAddress(network), spendAmount);

            var txid2 = await rpc.SendToAddressAsync(BitcoinFactory.CreateBitcoinAddress(network), spendAmount2);

            while ((await rpc.GetRawMempoolAsync()).Length != 2)
            {
                await Task.Delay(50);
            }

            await services.StartAllAsync();

            await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

            var localMempoolHashes = mempoolInstance.GetMempoolHashes();

            Assert.Equal(2, localMempoolHashes.Count);
            Assert.Contains(txid, localMempoolHashes);
            Assert.Contains(txid2, localMempoolHashes);
        }
        finally
        {
            await services.StopAllAsync();

            await coreNode.TryStopAsync();
        }
    }
        public async Task RpcWorksAsync()
        {
            using var services = new HostedServices();
            var coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync(CancellationToken.None);

            try
            {
                var blockCount = await coreNode.RpcClient.GetBlockCountAsync();

                Assert.Equal(0, blockCount);
            }
            finally
            {
                await services.StopAllAsync(CancellationToken.None);

                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 24
0
        public async Task VerboseBlockInfoAsync()
        {
            using var services = new HostedServices();
            var coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync(CancellationToken.None);

            try
            {
                var rpc       = coreNode.RpcClient;
                var blockInfo = await rpc.GetVerboseBlockAsync(coreNode.Network.GenesisHash);

                Assert.NotNull(blockInfo.Transactions.ElementAt(0).Inputs.ElementAt(0).Coinbase);
            }
            finally
            {
                await services.StopAllAsync(CancellationToken.None);

                await coreNode.TryStopAsync();
            }
        }
        public async Task P2pWorksAsync()
        {
            using var services = new HostedServices();
            var coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync(CancellationToken.None);

            using var node = await coreNode.CreateNewP2pNodeAsync();

            try
            {
                var blocks  = node.GetBlocks(new[] { Network.RegTest.GenesisHash });
                var genesis = Assert.Single(blocks);
                Assert.Equal(genesis.GetHash(), Network.RegTest.GenesisHash);
            }
            finally
            {
                await services.StopAllAsync(CancellationToken.None);

                node.Disconnect();
                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 26
0
        public async Task MempoolNotifiesAsync()
        {
            using HostedServices services = new();
            CoreNode coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync();

            using var node = await coreNode.CreateNewP2pNodeAsync();

            try
            {
                string dir     = Common.GetWorkDir();
                var    network = coreNode.Network;
                var    rpc     = coreNode.RpcClient;

                var walletName = "wallet.dat";
                await rpc.CreateWalletAsync(walletName);

                await using IndexStore indexStore = new(Path.Combine(dir, "indexStore"), network, new SmartHeaderChain());
                await using AllTransactionStore transactionStore = new(Path.Combine(dir, "transactionStore"), network);
                MempoolService            mempoolService = new();
                FileSystemBlockRepository blocks         = new(Path.Combine(dir, "blocks"), network);

                // Construct BitcoinStore.
                await using BitcoinStore bitcoinStore = new(indexStore, transactionStore, mempoolService, blocks);
                await bitcoinStore.InitializeAsync();

                await rpc.GenerateAsync(blockCount : 101);

                node.Behaviors.Add(bitcoinStore.CreateUntrustedP2pBehavior());
                node.VersionHandshake();

                using Key k = new();
                BitcoinWitPubKeyAddress address = k.PubKey.GetSegwitAddress(network);

                // Number of transactions to send.
                const int TransactionsCount = 10;

                EventsAwaiter <SmartTransaction> eventAwaiter = new(
                    subscribe : h => mempoolService.TransactionReceived += h,
                    unsubscribe : h => mempoolService.TransactionReceived -= h,
                    count : TransactionsCount);

                List <Task <uint256> > txHashesList = new();
                IRPCClient             rpcBatch     = rpc.PrepareBatch();

                // Add to the batch 10 RPC commands: Send 1 coin to the same address.
                for (int i = 0; i < TransactionsCount; i++)
                {
                    txHashesList.Add(rpcBatch.SendToAddressAsync(address, Money.Coins(1)));
                }

                // Publish the RPC batch.
                Task rpcBatchTask = rpcBatch.SendBatchAsync();

                // Wait until the mempool service receives all the sent transactions.
                IEnumerable <SmartTransaction> mempoolSmartTxs = await eventAwaiter.WaitAsync(TimeSpan.FromMinutes(2));

                await rpcBatchTask;

                // Collect all the transaction hashes of the sent transactions.
                uint256[] hashes = await Task.WhenAll(txHashesList);

                // Check that all the received transaction hashes are in the set of sent transaction hashes.
                foreach (SmartTransaction tx in mempoolSmartTxs)
                {
                    Assert.Contains(tx.GetHash(), hashes);
                }
            }
            finally
            {
                await services.StopAllAsync();

                node.Disconnect();
                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 27
0
        public async Task BlockNotifierTestsAsync()
        {
            using HostedServices services = new();
            var coreNode = await TestNodeBuilder.CreateAsync(services);

            await services.StartAllAsync();

            try
            {
                var rpc        = coreNode.RpcClient;
                var walletName = "wallet.dat";
                await rpc.CreateWalletAsync(walletName);

                BlockNotifier notifier = services.FirstOrDefault <BlockNotifier>();

                // Make sure we get notification for one block.
                EventAwaiter <Block> blockEventAwaiter = new(h => notifier.OnBlock += h, h => notifier.OnBlock -= h);

                var hash  = (await rpc.GenerateAsync(1)).First();
                var block = await blockEventAwaiter.WaitAsync(TimeSpan.FromSeconds(21));

                Assert.Equal(hash, block.GetHash());

                // Make sure we get notifications about 10 blocks created at the same time.
                var blockNum = 10;
                EventsAwaiter <Block> blockEventsAwaiter = new(h => notifier.OnBlock += h, h => notifier.OnBlock -= h, blockNum);

                var hashes = (await rpc.GenerateAsync(blockNum)).ToArray();

                var arrivedBlocks = (await blockEventsAwaiter.WaitAsync(TimeSpan.FromSeconds(21))).ToArray();

                for (int i = 0; i < hashes.Length; i++)
                {
                    var expected = hashes[i];
                    var actual   = arrivedBlocks[i].GetHash();
                    Assert.Equal(expected, actual);
                }

                // Make sure we get reorg notifications.
                var reorgNum    = 3;
                var newBlockNum = reorgNum + 1;
                EventsAwaiter <uint256> reorgEventsAwaiter = new(h => notifier.OnReorg += h, h => notifier.OnReorg -= h, reorgNum);
                blockEventsAwaiter = new(
                    h => notifier.OnBlock += h,
                    h => notifier.OnBlock -= h,
                    newBlockNum);

                var reorgedHashes = hashes.TakeLast(reorgNum).ToArray();
                await rpc.InvalidateBlockAsync(reorgedHashes[0]);

                var newHashes = (await rpc.GenerateAsync(newBlockNum)).ToArray();

                var reorgedHeaders = (await reorgEventsAwaiter.WaitAsync(TimeSpan.FromSeconds(21))).ToArray();
                var newBlocks      = (await blockEventsAwaiter.WaitAsync(TimeSpan.FromSeconds(21))).ToArray();

                reorgedHashes = reorgedHashes.Reverse().ToArray();
                for (int i = 0; i < reorgedHashes.Length; i++)
                {
                    var expected = reorgedHashes[i];
                    var actual   = reorgedHeaders[i];
                    Assert.Equal(expected, actual);
                }

                for (int i = 0; i < newHashes.Length; i++)
                {
                    var expected = newHashes[i];
                    var actual   = newBlocks[i].GetHash();
                    Assert.Equal(expected, actual);
                }
            }
            finally
            {
                await services.StopAllAsync();

                await coreNode.TryStopAsync();
            }
        }
Exemplo n.º 28
0
        public async Task CanBuildCoreNodeAsync()
        {
            var coreNode = await TestNodeBuilder.CreateAsync();

            await coreNode.TryStopAsync();
        }