示例#1
0
        public async Task CanLoadLegalDocsAsync()
        {
            var legalDir = Common.GetWorkDir();

            if (Directory.Exists(legalDir))
            {
                await IoHelpers.TryDeleteDirectoryAsync(legalDir);
            }

            Directory.CreateDirectory(legalDir);

            var res = await LegalDocuments.LoadAgreedAsync(legalDir);

            Assert.Null(res);

            var version = new Version(1, 1);

            // Deletes them if multiple legal docs found.
            var candidate = File.Create(Path.Combine(legalDir, $"{version}.txt"));
            await candidate.DisposeAsync();

            res = await LegalDocuments.LoadAgreedAsync(legalDir);

            Assert.NotNull(res);
            Assert.Single(Directory.GetFiles(legalDir));
            Assert.Empty(Directory.GetDirectories(legalDir));
            Assert.Equal(version, res?.Version);
        }
示例#2
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)
        }
示例#3
0
    public async Task ChecksConfigChangesAsync()
    {
        var workDir = Common.GetWorkDir();
        await IoHelpers.TryDeleteDirectoryAsync(workDir);

        CoordinatorParameters coordinatorParameters = new(workDir);

        using WabiSabiCoordinator coordinator = new(coordinatorParameters, NewMockRpcClient(), new CoinJoinIdStore());
        await coordinator.StartAsync(CancellationToken.None);

        var            configPath    = Path.Combine(workDir, "WabiSabiConfig.json");
        WabiSabiConfig configChanger = new(configPath);

        configChanger.LoadOrCreateDefaultFile();
        var newTarget = 729u;

        configChanger.ConfirmationTarget = newTarget;
        Assert.NotEqual(newTarget, coordinator.Config.ConfirmationTarget);
        configChanger.ToFile();
        var configWatcher = coordinator.ConfigWatcher;
        await configWatcher.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

        Assert.Equal(newTarget, coordinator.Config.ConfirmationTarget);

        // Do it one more time.
        newTarget = 372;
        configChanger.ConfirmationTarget = newTarget;
        Assert.NotEqual(newTarget, coordinator.Config.ConfirmationTarget);
        configChanger.ToFile();
        await configWatcher.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

        Assert.Equal(newTarget, coordinator.Config.ConfirmationTarget);

        await coordinator.StopAsync(CancellationToken.None);
    }
        public async Task ReleasesInmatesAsync()
        {
            var workDir = Common.GetWorkDir();
            await IoHelpers.TryDeleteDirectoryAsync(workDir);

            // Create prison.
            CoordinatorParameters coordinatorParameters = new(workDir);

            coordinatorParameters.RuntimeCoordinatorConfig.ReleaseUtxoFromPrisonAfter = TimeSpan.FromMilliseconds(1);

            using var w = new Warden(coordinatorParameters.UtxoWardenPeriod, coordinatorParameters.PrisonFilePath, coordinatorParameters.RuntimeCoordinatorConfig);
            await w.StartAsync(CancellationToken.None);

            var i1 = new Inmate(BitcoinFactory.CreateOutPoint(), Punishment.Noted, DateTimeOffset.FromUnixTimeSeconds(DateTimeOffset.UtcNow.ToUnixTimeSeconds()), uint256.Zero);
            var i2 = new Inmate(BitcoinFactory.CreateOutPoint(), Punishment.Banned, DateTimeOffset.FromUnixTimeSeconds(DateTimeOffset.UtcNow.ToUnixTimeSeconds()), uint256.Zero);
            var p  = w.Prison;

            p.Punish(i1);
            p.Punish(i2);
            Assert.NotEmpty(p.GetInmates());

            // Wait until releases from prison.
            await w.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

            Assert.Empty(p.GetInmates());
            await w.StopAsync(CancellationToken.None);
        }
示例#5
0
    public async Task LoadsConfigAsync()
    {
        var workDir = Common.GetWorkDir();
        await IoHelpers.TryDeleteDirectoryAsync(workDir);

        CoordinatorParameters coordinatorParameters = new(workDir);

        // Create the config first with default value.
        using WabiSabiCoordinator coordinator = new(coordinatorParameters, NewMockRpcClient(), new CoinJoinIdStore());
        await coordinator.StartAsync(CancellationToken.None);

        await coordinator.StopAsync(CancellationToken.None);

        // Change the file.
        var            configPath    = Path.Combine(workDir, "WabiSabiConfig.json");
        WabiSabiConfig configChanger = new(configPath);

        configChanger.LoadOrCreateDefaultFile();
        var newTarget = 729u;

        configChanger.ConfirmationTarget = newTarget;
        Assert.NotEqual(newTarget, coordinator.Config.ConfirmationTarget);
        configChanger.ToFile();

        // Assert the new value is loaded and not the default one.
        using WabiSabiCoordinator coordinator2 = new(coordinatorParameters, NewMockRpcClient(), new CoinJoinIdStore());
        await coordinator2.StartAsync(CancellationToken.None);

        Assert.Equal(newTarget, coordinator2.Config.ConfirmationTarget);
        await coordinator2.StopAsync(CancellationToken.None);
    }
        public async Task NoPrisonSerializationAsync()
        {
            // Don't serialize when there's no change.
            var workDir = Common.GetWorkDir();
            await IoHelpers.TryDeleteDirectoryAsync(workDir);

            // Create prison.
            CoordinatorParameters coordinatorParameters = new(workDir);

            using var w = new Warden(coordinatorParameters.UtxoWardenPeriod, coordinatorParameters.PrisonFilePath, coordinatorParameters.RuntimeCoordinatorConfig);
            await w.StartAsync(CancellationToken.None);

            var i1 = new Inmate(BitcoinFactory.CreateOutPoint(), Punishment.Noted, DateTimeOffset.FromUnixTimeSeconds(DateTimeOffset.UtcNow.ToUnixTimeSeconds()), uint256.Zero);
            var i2 = new Inmate(BitcoinFactory.CreateOutPoint(), Punishment.Banned, DateTimeOffset.FromUnixTimeSeconds(DateTimeOffset.UtcNow.ToUnixTimeSeconds()), uint256.Zero);

            w.Prison.Punish(i1);
            w.Prison.Punish(i2);

            // Wait until serializes.
            await w.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

            // Make sure it does not serialize again as there was no change.
            File.Delete(w.PrisonFilePath);
            await w.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

            Assert.False(File.Exists(w.PrisonFilePath));
            await w.StopAsync(CancellationToken.None);
        }
示例#7
0
        private async Task <(string walletsPath, string walletsBackupPath)> CleanupWalletDirectoriesAsync(string baseDir)
        {
            var walletsPath       = Path.Combine(baseDir, WalletDirectories.WalletsDirName);
            var walletsBackupPath = Path.Combine(baseDir, WalletDirectories.WalletsBackupDirName);
            await IoHelpers.TryDeleteDirectoryAsync(walletsPath);

            await IoHelpers.TryDeleteDirectoryAsync(walletsBackupPath);

            return(walletsPath, walletsBackupPath);
        }
示例#8
0
    private static async Task SignAsync()
    {
        foreach (string target in Targets)
        {
            if (target.StartsWith("win", StringComparison.OrdinalIgnoreCase))
            {
                string publishedFolder = Path.Combine(BinDistDirectory, target);

                Console.WriteLine("Move created .msi");
                var msiPath = Path.Combine(WixProjectDirectory, "bin", "Release", "Wasabi.msi");
                if (!File.Exists(msiPath))
                {
                    throw new Exception(".msi does not exist. Expected path: Wasabi.msi.");
                }
                var msiFileName = Path.GetFileNameWithoutExtension(msiPath);
                var newMsiPath  = Path.Combine(BinDistDirectory, $"{msiFileName}-{VersionPrefix}.msi");
                File.Copy(msiPath, newMsiPath);

                Console.Write("Enter Code Signing Certificate Password: "******"cmd", BinDistDirectory, $"signtool sign /d \"Wasabi Wallet\" /f \"{PfxPath}\" /p {pfxPassword} /t http://timestamp.digicert.com /a \"{newMsiPath}\" && exit");

                await IoHelpers.TryDeleteDirectoryAsync(publishedFolder).ConfigureAwait(false);

                Console.WriteLine($"Deleted {publishedFolder}");
            }
            else if (target.StartsWith("osx", StringComparison.OrdinalIgnoreCase))
            {
                string dmgFilePath = Path.Combine(BinDistDirectory, $"Wasabi-{VersionPrefix}.dmg");
                if (!File.Exists(dmgFilePath))
                {
                    throw new Exception(".dmg does not exist.");
                }
                string zipFilePath = Path.Combine(BinDistDirectory, $"Wasabi-osx-{VersionPrefix}.zip");
                if (File.Exists(zipFilePath))
                {
                    File.Delete(zipFilePath);
                }
            }
        }

        Console.WriteLine("Signing final files...");
        var finalFiles = Directory.GetFiles(BinDistDirectory);

        foreach (var finalFile in finalFiles)
        {
            StartProcessAndWaitForExit("cmd", BinDistDirectory, $"gpg --armor --detach-sign {finalFile} && exit");

            StartProcessAndWaitForExit("cmd", WixProjectDirectory, $"git checkout -- ComponentsGenerated.wxs && exit");
        }

        IoHelpers.OpenFolderInFileExplorer(BinDistDirectory);
    }
    private async Task <(string dir, string matureFilters, string immatureFilters)> GetIndexStorePathsAsync([CallerFilePath] string callerFilePath = "", [CallerMemberName] string callerMemberName = "")
    {
        var dir = Path.Combine(Common.GetWorkDir(callerFilePath, callerMemberName), "IndexStore");
        await IoHelpers.TryDeleteDirectoryAsync(dir);

        var matureFilters   = Path.Combine(dir, "MatureIndex.dat");
        var immatureFilters = Path.Combine(dir, "ImmatureIndex.dat");

        IoHelpers.EnsureContainingDirectoryExists(matureFilters);
        IoHelpers.EnsureContainingDirectoryExists(immatureFilters);
        return(dir, matureFilters, immatureFilters);
    }
        public async Task CanStartAndStopAsync()
        {
            var workDir = Common.GetWorkDir();
            await IoHelpers.TryDeleteDirectoryAsync(workDir);

            CoordinatorParameters coordinatorParameters = new(workDir);

            using var w = new Warden(coordinatorParameters.UtxoWardenPeriod, coordinatorParameters.PrisonFilePath, coordinatorParameters.RuntimeCoordinatorConfig);
            await w.StartAsync(CancellationToken.None);

            await w.StopAsync(CancellationToken.None);
        }
    public async Task CanLiveAsync()
    {
        var workDir = Common.GetWorkDir();
        await IoHelpers.TryDeleteDirectoryAsync(workDir);

        CoordinatorParameters coordinatorParameters = new(workDir);

        using WabiSabiCoordinator coordinator = new(coordinatorParameters, NewMockRpcClient());
        await coordinator.StartAsync(CancellationToken.None);

        await coordinator.StopAsync(CancellationToken.None);
    }
示例#12
0
    public async Task CreatesConfigAsync()
    {
        var workDir = Common.GetWorkDir();
        await IoHelpers.TryDeleteDirectoryAsync(workDir);

        CoordinatorParameters coordinatorParameters = new(workDir);

        using WabiSabiCoordinator coordinator = new(coordinatorParameters, NewMockRpcClient(), new CoinJoinIdStore());
        await coordinator.StartAsync(CancellationToken.None);

        Assert.True(File.Exists(Path.Combine(workDir, "WabiSabiConfig.json")));

        await coordinator.StopAsync(CancellationToken.None);
    }
示例#13
0
        public async Task ResolvesConflictsAsync()
        {
            var legalDir = Common.GetWorkDir();

            if (Directory.Exists(legalDir))
            {
                await IoHelpers.TryDeleteDirectoryAsync(legalDir);
            }

            Directory.CreateDirectory(legalDir);

            var res = await LegalDocuments.LoadAgreedAsync(legalDir);

            Assert.Null(res);

            // Deletes them if multiple legal docs found.
            var candidate1 = File.Create(Path.Combine(legalDir, "1.1.txt"));
            var candidate2 = File.Create(Path.Combine(legalDir, "1.2.txt"));
            await candidate1.DisposeAsync();

            await candidate2.DisposeAsync();

            res = await LegalDocuments.LoadAgreedAsync(legalDir);

            Assert.Null(res);
            Assert.Empty(Directory.GetFiles(legalDir));
            Assert.Empty(Directory.GetDirectories(legalDir));

            // Only the candidates are deleted.
            var trash = File.Create(Path.Combine(legalDir, "1.txt"));

            candidate1 = File.Create(Path.Combine(legalDir, "1.1.txt"));
            candidate2 = File.Create(Path.Combine(legalDir, "1.2.txt"));
            await trash.DisposeAsync();

            await candidate1.DisposeAsync();

            await candidate2.DisposeAsync();

            res = await LegalDocuments.LoadAgreedAsync(legalDir);

            Assert.Null(res);
            Assert.Single(Directory.GetFiles(legalDir));
            Assert.Empty(Directory.GetDirectories(legalDir));
        }
    public async Task CanCancelAsync()
    {
        var workDir = Common.GetWorkDir();
        await IoHelpers.TryDeleteDirectoryAsync(workDir);

        CoordinatorParameters coordinatorParameters = new(workDir);

        using WabiSabiCoordinator coordinator = new(coordinatorParameters, NewMockRpcClient());
        using CancellationTokenSource cts     = new();
        cts.Cancel();
        await coordinator.StartAsync(cts.Token);

        await coordinator.StopAsync(CancellationToken.None);

        using WabiSabiCoordinator coordinator2 = new(coordinatorParameters, NewMockRpcClient());
        using CancellationTokenSource cts2     = new();
        await coordinator2.StartAsync(cts2.Token);

        cts2.Cancel();
        await coordinator2.StopAsync(CancellationToken.None);

        using WabiSabiCoordinator coordinator3 = new(coordinatorParameters, NewMockRpcClient());
        using CancellationTokenSource cts3     = new();
        var t = coordinator3.StartAsync(cts3.Token);

        cts3.Cancel();
        await t;
        await coordinator3.StopAsync(CancellationToken.None);

        using WabiSabiCoordinator coordinator4 = new(coordinatorParameters, NewMockRpcClient());
        await coordinator4.StartAsync(CancellationToken.None);

        using CancellationTokenSource cts4 = new();
        cts4.Cancel();
        await coordinator4.StopAsync(cts4.Token);

        using WabiSabiCoordinator coordinator5 = new(coordinatorParameters, NewMockRpcClient());
        await coordinator5.StartAsync(CancellationToken.None);

        using CancellationTokenSource cts5 = new();
        t = coordinator5.StopAsync(cts5.Token);
        cts5.Cancel();
        await t;
    }
        public async Task PrisonSerializationAsync()
        {
            var workDir = Common.GetWorkDir();
            await IoHelpers.TryDeleteDirectoryAsync(workDir);

            // Create prison.
            CoordinatorParameters coordinatorParameters = new(workDir);

            using var w = new Warden(coordinatorParameters.UtxoWardenPeriod, coordinatorParameters.PrisonFilePath, coordinatorParameters.RuntimeCoordinatorConfig);
            await w.StartAsync(CancellationToken.None);

            var i1 = new Inmate(BitcoinFactory.CreateOutPoint(), Punishment.Noted, DateTimeOffset.FromUnixTimeSeconds(DateTimeOffset.UtcNow.ToUnixTimeSeconds()), uint256.Zero);
            var i2 = new Inmate(BitcoinFactory.CreateOutPoint(), Punishment.Banned, DateTimeOffset.FromUnixTimeSeconds(DateTimeOffset.UtcNow.ToUnixTimeSeconds()), uint256.Zero);

            w.Prison.Punish(i1);
            w.Prison.Punish(i2);

            // Wait until serializes.
            await w.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7));

            await w.StopAsync(CancellationToken.None);

            // See if prev UTXOs are loaded.
            CoordinatorParameters coordinatorParameters2 = new(workDir);

            using var w2 = new Warden(coordinatorParameters2.UtxoWardenPeriod, coordinatorParameters2.PrisonFilePath, coordinatorParameters2.RuntimeCoordinatorConfig);
            await w2.StartAsync(CancellationToken.None);

            Assert.True(w2.Prison.TryGet(i1.Utxo, out var sameI1));
            Assert.True(w2.Prison.TryGet(i2.Utxo, out var sameI2));
            Assert.Equal(i1.LastDisruptedRoundId, sameI1 !.LastDisruptedRoundId);
            Assert.Equal(i2.LastDisruptedRoundId, sameI2 !.LastDisruptedRoundId);
            Assert.Equal(i1.Punishment, sameI1 !.Punishment);
            Assert.Equal(i2.Punishment, sameI2 !.Punishment);
            Assert.Equal(i1.Started, sameI1 !.Started);
            Assert.Equal(i2.Started, sameI2 !.Started);

            await w2.StopAsync(CancellationToken.None);
        }
示例#16
0
        public async Task LeavesTrashAloneAsync()
        {
            var legalDir = Common.GetWorkDir();

            if (Directory.Exists(legalDir))
            {
                await IoHelpers.TryDeleteDirectoryAsync(legalDir);
            }

            Directory.CreateDirectory(legalDir);

            var res = await LegalDocuments.LoadAgreedAsync(legalDir);

            Assert.Null(res);

            // Leaves one trash alone.
            var trash1 = File.Create(Path.Combine(legalDir, "foo"));
            await trash1.DisposeAsync();

            res = await LegalDocuments.LoadAgreedAsync(legalDir);

            Assert.Null(res);
            Assert.Single(Directory.GetFiles(legalDir));
            Assert.Empty(Directory.GetDirectories(legalDir));

            // Leaves 3 trash alone.
            var trash2 = File.Create(Path.Combine(legalDir, "foo.txt"));
            var trash3 = File.Create(Path.Combine(legalDir, "foo2"));
            await trash2.DisposeAsync();

            await trash3.DisposeAsync();

            res = await LegalDocuments.LoadAgreedAsync(legalDir);

            Assert.Null(res);
            Assert.Equal(3, Directory.GetFiles(legalDir).Length);
            Assert.Empty(Directory.GetDirectories(legalDir));
        }
示例#17
0
    public async Task LoadsIncompleteConfigAsync()
    {
        var workDir = Common.GetWorkDir();
        await IoHelpers.TryDeleteDirectoryAsync(workDir);

        CoordinatorParameters coordinatorParameters = new(workDir);

        // Create the config first with default value.
        using WabiSabiCoordinator coordinator = new(coordinatorParameters, NewMockRpcClient(), new CoinJoinIdStore());
        await coordinator.StartAsync(CancellationToken.None);

        await coordinator.StopAsync(CancellationToken.None);

        // Remove a line.
        var configPath      = Path.Combine(workDir, "WabiSabiConfig.json");
        var lines           = File.ReadAllLines(configPath);
        var incompleteLines = lines.Where(x => !x.Contains("ReleaseUtxoFromPrisonAfter", StringComparison.Ordinal)).ToArray();

        Assert.NotEqual(lines.Length, incompleteLines.Length);
        File.WriteAllLines(configPath, incompleteLines);

        // Assert the new default value is loaded.
        CoordinatorParameters coordinatorParameters2 = new(workDir);

        using WabiSabiCoordinator coordinator2 = new(coordinatorParameters2, NewMockRpcClient(), new CoinJoinIdStore());
        await coordinator2.StartAsync(CancellationToken.None);

        var defaultValue = TimeSpanJsonConverter.Parse("0d 3h 0m 0s");

        Assert.Equal(TimeSpan.FromHours(3), defaultValue);
        Assert.Equal(defaultValue, coordinator2.Config.ReleaseUtxoFromPrisonAfter);
        await coordinator2.StopAsync(CancellationToken.None);

        // Assert the new default value is serialized.
        lines = File.ReadAllLines(configPath);
        Assert.Contains(lines, x => x.Contains("\"ReleaseUtxoFromPrisonAfter\": \"0d 3h 0m 0s\"", StringComparison.Ordinal));
    }
示例#18
0
        private static void CreateDigests()
        {
            var tempDir = "DigestTempDir";

            IoHelpers.TryDeleteDirectoryAsync(tempDir).GetAwaiter().GetResult();
            Directory.CreateDirectory(tempDir);

            var    torDaemonsDir = Path.Combine(LibraryProjectDirectory, "TorDaemons");
            string torWinZip     = Path.Combine(torDaemonsDir, "tor-win64.zip");

            IoHelpers.BetterExtractZipToDirectoryAsync(torWinZip, tempDir).GetAwaiter().GetResult();
            File.Move(Path.Combine(tempDir, "Tor", "tor.exe"), Path.Combine(tempDir, "TorWin"));

            string torLinuxZip = Path.Combine(torDaemonsDir, "tor-linux64.zip");

            IoHelpers.BetterExtractZipToDirectoryAsync(torLinuxZip, tempDir).GetAwaiter().GetResult();
            File.Move(Path.Combine(tempDir, "Tor", "tor"), Path.Combine(tempDir, "TorLin"));

            string torOsxZip = Path.Combine(torDaemonsDir, "tor-osx64.zip");

            IoHelpers.BetterExtractZipToDirectoryAsync(torOsxZip, tempDir).GetAwaiter().GetResult();
            File.Move(Path.Combine(tempDir, "Tor", "tor.real"), Path.Combine(tempDir, "TorOsx"));

            var tempDirInfo = new DirectoryInfo(tempDir);
            var binaries    = tempDirInfo.GetFiles();

            Console.WriteLine("Digests:");
            foreach (var file in binaries)
            {
                var filePath = file.FullName;
                var hash     = ByteHelpers.ToHex(IoHelpers.GetHashFile(filePath)).ToLowerInvariant();
                Console.WriteLine($"{file.Name}: {hash}");
            }

            IoHelpers.TryDeleteDirectoryAsync(tempDir).GetAwaiter().GetResult();
        }
示例#19
0
    private static async Task PublishAsync()
    {
        if (Directory.Exists(BinDistDirectory))
        {
            await IoHelpers.TryDeleteDirectoryAsync(BinDistDirectory).ConfigureAwait(false);

            Console.WriteLine($"Deleted {BinDistDirectory}");
        }

        StartProcessAndWaitForExit("dotnet", DesktopProjectDirectory, arguments: "clean --configuration Release");

        var desktopBinReleaseDirectory = Path.GetFullPath(Path.Combine(DesktopProjectDirectory, "bin", "Release"));
        var libraryBinReleaseDirectory = Path.GetFullPath(Path.Combine(LibraryProjectDirectory, "bin", "Release"));

        if (Directory.Exists(desktopBinReleaseDirectory))
        {
            await IoHelpers.TryDeleteDirectoryAsync(desktopBinReleaseDirectory).ConfigureAwait(false);

            Console.WriteLine($"Deleted {desktopBinReleaseDirectory}");
        }
        if (Directory.Exists(libraryBinReleaseDirectory))
        {
            await IoHelpers.TryDeleteDirectoryAsync(libraryBinReleaseDirectory).ConfigureAwait(false);

            Console.WriteLine($"Deleted {libraryBinReleaseDirectory}");
        }

        var deterministicFileNameTag = IsContinuousDelivery ? $"{DateTimeOffset.UtcNow:ddMMyyyy}{DateTimeOffset.UtcNow.TimeOfDay.TotalSeconds}" : VersionPrefix;
        var deliveryPath             = IsContinuousDelivery ? Path.Combine(BinDistDirectory, "cdelivery") : BinDistDirectory;

        IoHelpers.EnsureDirectoryExists(deliveryPath);
        Console.WriteLine($"Binaries will be delivered here: {deliveryPath}");

        string buildInfoJson = GetBuildInfoData();

        CheckUncommittedGitChanges();

        foreach (string target in Targets)
        {
            string publishedFolder         = Path.Combine(BinDistDirectory, target);
            string currentBinDistDirectory = publishedFolder;

            Console.WriteLine();
            Console.WriteLine($"{nameof(currentBinDistDirectory)}:\t{currentBinDistDirectory}");

            Console.WriteLine();
            if (!Directory.Exists(currentBinDistDirectory))
            {
                Directory.CreateDirectory(currentBinDistDirectory);
                Console.WriteLine($"Created {currentBinDistDirectory}");
            }

            string buildInfoPath = Path.Combine(currentBinDistDirectory, "BUILDINFO.json");
            File.WriteAllText(buildInfoPath, buildInfoJson);

            StartProcessAndWaitForExit("dotnet", DesktopProjectDirectory, arguments: "clean");

            // https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore21
            // -c|--configuration {Debug|Release}
            //		Defines the build configuration. The default value is Debug.
            // --force
            //		Forces all dependencies to be resolved even if the last restore was successful. Specifying this flag is the same as deleting the project.assets.json file.
            // -o|--output <OUTPUT_DIRECTORY>
            //		Specifies the path for the output directory.
            //		If not specified, it defaults to ./bin/[configuration]/[framework]/publish/ for a framework-dependent deployment or
            //		./bin/[configuration]/[framework]/[runtime]/publish/ for a self-contained deployment.
            //		If the path is relative, the output directory generated is relative to the project file location, not to the current working directory.
            // --self-contained
            //		Publishes the .NET Core runtime with your application so the runtime does not need to be installed on the target machine.
            //		If a runtime identifier is specified, its default value is true. For more information about the different deployment types, see .NET Core application deployment.
            // -r|--runtime <RUNTIME_IDENTIFIER>
            //		Publishes the application for a given runtime. This is used when creating a self-contained deployment (SCD).
            //		For a list of Runtime Identifiers (RIDs), see the RID catalog. Default is to publish a framework-dependent deployment (FDD).
            // --version-suffix <VERSION_SUFFIX>
            //		Defines the version suffix to replace the asterisk (*) in the version field of the project file.
            // https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-restore?tabs=netcore2x
            // --disable-parallel
            //		Disables restoring multiple projects in parallel.
            // --no-cache
            //		Specifies to not cache packages and HTTP requests.
            // https://github.com/dotnet/docs/issues/7568
            // /p:Version=1.2.3.4
            //		"dotnet publish" supports msbuild command line options like /p:Version=1.2.3.4

            string dotnetProcessArgs = string.Join(
                " ",
                $"publish",
                $"--configuration Release",
                $"--force",
                $"--output \"{currentBinDistDirectory}\"",
                $"--self-contained true",
                $"--runtime \"{target}\"",
                $"--disable-parallel",
                $"--no-cache",
                $"/p:VersionPrefix={VersionPrefix}",
                $"/p:DebugType=none",
                $"/p:DebugSymbols=false",
                $"/p:ErrorReport=none",
                $"/p:DocumentationFile=\"\"",
                $"/p:Deterministic=true",
                $"/p:RestoreLockedMode=true");

            StartProcessAndWaitForExit(
                "dotnet",
                DesktopProjectDirectory,
                arguments: dotnetProcessArgs,
                redirectStandardOutput: true);

            Tools.ClearSha512Tags(currentBinDistDirectory);

            // Remove Tor binaries that are not relevant to the platform.
            var toNotRemove = "";
            if (target.StartsWith("win"))
            {
                toNotRemove = "win";
            }
            else if (target.StartsWith("linux"))
            {
                toNotRemove = "lin";
            }
            else if (target.StartsWith("osx"))
            {
                toNotRemove = "osx";
            }

            // Remove binaries that are not relevant to the platform.
            var binaryFolder = new DirectoryInfo(Path.Combine(currentBinDistDirectory, "Microservices", "Binaries"));

            foreach (var dir in binaryFolder.EnumerateDirectories())
            {
                if (!dir.Name.Contains(toNotRemove, StringComparison.OrdinalIgnoreCase))
                {
                    await IoHelpers.TryDeleteDirectoryAsync(dir.FullName).ConfigureAwait(false);
                }
            }

            // Rename the final exe.
            string oldExecutablePath;
            string newExecutablePath;
            if (target.StartsWith("win"))
            {
                oldExecutablePath = Path.Combine(currentBinDistDirectory, "WalletWasabi.Fluent.Desktop.exe");
                newExecutablePath = Path.Combine(currentBinDistDirectory, $"{ExecutableName}.exe");

                // Delete unused executables.
                File.Delete(Path.Combine(currentBinDistDirectory, "WalletWasabi.Fluent.exe"));
            }
            else             // Linux & OSX
            {
                oldExecutablePath = Path.Combine(currentBinDistDirectory, "WalletWasabi.Fluent.Desktop");
                newExecutablePath = Path.Combine(currentBinDistDirectory, ExecutableName);

                // Delete unused executables.
                File.Delete(Path.Combine(currentBinDistDirectory, "WalletWasabi.Fluent"));
            }
            File.Move(oldExecutablePath, newExecutablePath);

            long installedSizeKb = Tools.DirSize(new DirectoryInfo(publishedFolder)) / 1000;

            if (target.StartsWith("win"))
            {
                // IF IT'S IN ONLYBINARIES MODE DON'T DO ANYTHING FANCY PACKAGING AFTER THIS!!!
                if (OnlyBinaries)
                {
                    continue;                     // In Windows build at this moment it does not matter though.
                }

                ZipFile.CreateFromDirectory(currentBinDistDirectory, Path.Combine(deliveryPath, $"Wasabi-{deterministicFileNameTag}-{target}.zip"));

                if (IsContinuousDelivery)
                {
                    continue;
                }
            }
            else if (target.StartsWith("osx"))
            {
                // IF IT'S IN ONLYBINARIES MODE DON'T DO ANYTHING FANCY PACKAGING AFTER THIS!!!
                if (OnlyBinaries)
                {
                    continue;
                }

                ZipFile.CreateFromDirectory(currentBinDistDirectory, Path.Combine(deliveryPath, $"Wasabi-{deterministicFileNameTag}-{target}.zip"));

                if (IsContinuousDelivery)
                {
                    continue;
                }

                ZipFile.CreateFromDirectory(currentBinDistDirectory, Path.Combine(BinDistDirectory, $"Wasabi-osx-{VersionPrefix}.zip"));

                await IoHelpers.TryDeleteDirectoryAsync(currentBinDistDirectory).ConfigureAwait(false);

                Console.WriteLine($"Deleted {currentBinDistDirectory}");
            }
            else if (target.StartsWith("linux"))
            {
                // IF IT'S IN ONLYBINARIES MODE DON'T DO ANYTHING FANCY PACKAGING AFTER THIS!!!
                if (OnlyBinaries)
                {
                    continue;
                }

                ZipFile.CreateFromDirectory(currentBinDistDirectory, Path.Combine(deliveryPath, $"Wasabi-{deterministicFileNameTag}-{target}.zip"));

                if (IsContinuousDelivery)
                {
                    continue;
                }

                Console.WriteLine("Create Linux .tar.gz");
                if (!Directory.Exists(publishedFolder))
                {
                    throw new Exception($"{publishedFolder} does not exist.");
                }
                var newFolderName = $"Wasabi-{VersionPrefix}";
                var newFolderPath = Path.Combine(BinDistDirectory, newFolderName);
                Directory.Move(publishedFolder, newFolderPath);
                publishedFolder = newFolderPath;

                var driveLetterUpper = BinDistDirectory[0];
                var driveLetterLower = char.ToLower(driveLetterUpper);

                var linuxPath = $"/mnt/{driveLetterLower}/{Tools.LinuxPath(BinDistDirectory[3..])}";
示例#20
0
    private static async Task PublishAsync()
    {
        if (Directory.Exists(BinDistDirectory))
        {
            await IoHelpers.TryDeleteDirectoryAsync(BinDistDirectory).ConfigureAwait(false);

            Console.WriteLine($"# Deleted {BinDistDirectory}");
        }

        Console.WriteLine($"# Run dotnet restore");
        StartProcessAndWaitForExit("dotnet", DesktopProjectDirectory, arguments: "restore --locked-mode");

        Console.WriteLine($"# Run dotnet clean");
        StartProcessAndWaitForExit("dotnet", DesktopProjectDirectory, arguments: "clean --configuration Release");

        string desktopBinReleaseDirectory = Path.GetFullPath(Path.Combine(DesktopProjectDirectory, "bin", "Release"));
        string libraryBinReleaseDirectory = Path.GetFullPath(Path.Combine(LibraryProjectDirectory, "bin", "Release"));

        if (Directory.Exists(desktopBinReleaseDirectory))
        {
            await IoHelpers.TryDeleteDirectoryAsync(desktopBinReleaseDirectory).ConfigureAwait(false);

            Console.WriteLine($"#Deleted {desktopBinReleaseDirectory}");
        }

        if (Directory.Exists(libraryBinReleaseDirectory))
        {
            await IoHelpers.TryDeleteDirectoryAsync(libraryBinReleaseDirectory).ConfigureAwait(false);

            Console.WriteLine($"# Deleted {libraryBinReleaseDirectory}");
        }

        var deterministicFileNameTag = IsContinuousDelivery ? $"{DateTimeOffset.UtcNow:ddMMyyyy}{DateTimeOffset.UtcNow.TimeOfDay.TotalSeconds}" : VersionPrefix;
        var deliveryPath             = IsContinuousDelivery ? Path.Combine(BinDistDirectory, "cdelivery") : BinDistDirectory;

        IoHelpers.EnsureDirectoryExists(deliveryPath);
        Console.WriteLine($"# Binaries will be delivered here: {deliveryPath}");

        string buildInfoJson = GetBuildInfoData();

        CheckUncommittedGitChanges();

        foreach (string target in Targets)
        {
            string publishedFolder         = Path.Combine(BinDistDirectory, target);
            string currentBinDistDirectory = publishedFolder;

            Console.WriteLine();
            Console.WriteLine($"{nameof(currentBinDistDirectory)}:\t{currentBinDistDirectory}");

            Console.WriteLine();
            if (!Directory.Exists(currentBinDistDirectory))
            {
                Directory.CreateDirectory(currentBinDistDirectory);
                Console.WriteLine($"# Created {currentBinDistDirectory}");
            }

            string buildInfoPath = Path.Combine(currentBinDistDirectory, "BUILDINFO.json");
            File.WriteAllText(buildInfoPath, buildInfoJson);

            StartProcessAndWaitForExit("dotnet", DesktopProjectDirectory, arguments: "clean");

            // See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish for details.
            string dotnetProcessArgs = string.Join(
                " ",
                $"publish",
                $"--configuration Release",
                $"--force",
                $"--output \"{currentBinDistDirectory}\"",
                $"--self-contained true",
                $"--runtime \"{target}\"",
                $"--disable-parallel",
                $"--no-cache",
                $"--no-restore",
                $"/p:VersionPrefix={VersionPrefix}",
                $"/p:DebugType=none",
                $"/p:DebugSymbols=false",
                $"/p:ErrorReport=none",
                $"/p:DocumentationFile=\"\"",
                $"/p:Deterministic=true");

            StartProcessAndWaitForExit(
                "dotnet",
                DesktopProjectDirectory,
                arguments: dotnetProcessArgs,
                redirectStandardOutput: true);

            Tools.ClearSha512Tags(currentBinDistDirectory);

            // Remove Tor binaries that are not relevant to the platform.
            var toNotRemove = "";
            if (target.StartsWith("win"))
            {
                toNotRemove = "win";
            }
            else if (target.StartsWith("linux"))
            {
                toNotRemove = "lin";
            }
            else if (target.StartsWith("osx"))
            {
                toNotRemove = "osx";
            }

            // Remove binaries that are not relevant to the platform.
            var binaryFolder = new DirectoryInfo(Path.Combine(currentBinDistDirectory, "Microservices", "Binaries"));

            foreach (var dir in binaryFolder.EnumerateDirectories())
            {
                if (!dir.Name.Contains(toNotRemove, StringComparison.OrdinalIgnoreCase))
                {
                    await IoHelpers.TryDeleteDirectoryAsync(dir.FullName).ConfigureAwait(false);
                }
            }

            // Rename the final exe.
            string oldExecutablePath;
            string newExecutablePath;
            if (target.StartsWith("win"))
            {
                oldExecutablePath = Path.Combine(currentBinDistDirectory, "WalletWasabi.Fluent.Desktop.exe");
                newExecutablePath = Path.Combine(currentBinDistDirectory, $"{ExecutableName}.exe");

                // Delete unused executables.
                File.Delete(Path.Combine(currentBinDistDirectory, "WalletWasabi.Fluent.exe"));
            }
            else             // Linux & OSX
            {
                oldExecutablePath = Path.Combine(currentBinDistDirectory, "WalletWasabi.Fluent.Desktop");
                newExecutablePath = Path.Combine(currentBinDistDirectory, ExecutableName);

                // Delete unused executables.
                File.Delete(Path.Combine(currentBinDistDirectory, "WalletWasabi.Fluent"));
            }
            File.Move(oldExecutablePath, newExecutablePath);

            long installedSizeKb = Tools.DirSize(new DirectoryInfo(publishedFolder)) / 1000;

            if (target.StartsWith("win"))
            {
                // IF IT'S IN ONLYBINARIES MODE DON'T DO ANYTHING FANCY PACKAGING AFTER THIS!!!
                if (OnlyBinaries)
                {
                    continue;                     // In Windows build at this moment it does not matter though.
                }

                ZipFile.CreateFromDirectory(currentBinDistDirectory, Path.Combine(deliveryPath, $"Wasabi-{deterministicFileNameTag}-{GetPackageTargetPostfix(target)}.zip"));

                if (IsContinuousDelivery)
                {
                    continue;
                }
            }
            else if (target.StartsWith("osx"))
            {
                // IF IT'S IN ONLYBINARIES MODE DON'T DO ANYTHING FANCY PACKAGING AFTER THIS!!!
                if (OnlyBinaries)
                {
                    continue;
                }

                ZipFile.CreateFromDirectory(currentBinDistDirectory, Path.Combine(deliveryPath, $"Wasabi-{deterministicFileNameTag}-{GetPackageTargetPostfix(target)}.zip"));

                if (IsContinuousDelivery)
                {
                    continue;
                }

                // Only add postfix to the final package if arm64, otherwise nothing.
                var postfix = target.Contains("arm64") ? "-arm64" : "";

                // After notarization this will be the filename of the dmg file.
                var zipFileName = $"WasabiToNotarize-{deterministicFileNameTag}{postfix}.zip";
                var zipFilePath = Path.Combine(BinDistDirectory, zipFileName);

                ZipFile.CreateFromDirectory(currentBinDistDirectory, zipFilePath);

                await IoHelpers.TryDeleteDirectoryAsync(currentBinDistDirectory).ConfigureAwait(false);

                Console.WriteLine($"# Deleted {currentBinDistDirectory}");

                try
                {
                    var drive          = Tools.GetSingleUsbDrive();
                    var targetFilePath = Path.Combine(drive, zipFileName);

                    Console.WriteLine($"# Trying to move unsigned zip file to removable ('{targetFilePath}').");
                    File.Move(zipFilePath, targetFilePath, overwrite: true);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"# There was an error during copying the file to removable: '{ex.Message}'");
                }
            }
            else if (target.StartsWith("linux"))
            {
                // IF IT'S IN ONLYBINARIES MODE DON'T DO ANYTHING FANCY PACKAGING AFTER THIS!!!
                if (OnlyBinaries)
                {
                    continue;
                }

                ZipFile.CreateFromDirectory(currentBinDistDirectory, Path.Combine(deliveryPath, $"Wasabi-{deterministicFileNameTag}-{GetPackageTargetPostfix(target)}.zip"));

                if (IsContinuousDelivery)
                {
                    continue;
                }

                Console.WriteLine("# Create Linux .tar.gz");
                if (!Directory.Exists(publishedFolder))
                {
                    throw new Exception($"{publishedFolder} does not exist.");
                }
                var newFolderName = $"Wasabi-{VersionPrefix}";
                var newFolderPath = Path.Combine(BinDistDirectory, newFolderName);
                Directory.Move(publishedFolder, newFolderPath);
                publishedFolder = newFolderPath;

                var driveLetterUpper = BinDistDirectory[0];
                var driveLetterLower = char.ToLower(driveLetterUpper);

                var linuxPath = $"/mnt/{driveLetterLower}/{Tools.LinuxPath(BinDistDirectory[3..])}";
示例#21
0
        private static void Publish()
        {
            if (Directory.Exists(BinDistDirectory))
            {
                IoHelpers.TryDeleteDirectoryAsync(BinDistDirectory).GetAwaiter().GetResult();
                Console.WriteLine($"Deleted {BinDistDirectory}");
            }

            using (var process = Process.Start(new ProcessStartInfo
            {
                FileName = "cmd",
                RedirectStandardInput = true,
                WorkingDirectory = GuiProjectDirectory
            }))
            {
                process.StandardInput.WriteLine("dotnet clean --configuration Release && exit");
                process.WaitForExit();
            }

            var guiBinReleaseDirectory     = Path.GetFullPath(Path.Combine(GuiProjectDirectory, "bin", "Release"));
            var libraryBinReleaseDirectory = Path.GetFullPath(Path.Combine(LibraryProjectDirectory, "bin", "Release"));

            if (Directory.Exists(guiBinReleaseDirectory))
            {
                IoHelpers.TryDeleteDirectoryAsync(guiBinReleaseDirectory).GetAwaiter().GetResult();
                Console.WriteLine($"Deleted {guiBinReleaseDirectory}");
            }
            if (Directory.Exists(libraryBinReleaseDirectory))
            {
                IoHelpers.TryDeleteDirectoryAsync(libraryBinReleaseDirectory).GetAwaiter().GetResult();
                Console.WriteLine($"Deleted {libraryBinReleaseDirectory}");
            }

            var deterministicFileNameTag = IsContinuousDelivery ? $"{DateTimeOffset.UtcNow:ddMMyyyy}{DateTimeOffset.UtcNow.TimeOfDay.TotalSeconds}" : VersionPrefix;
            var deliveryPath             = IsContinuousDelivery ? Path.Combine(BinDistDirectory, "cdelivery") : BinDistDirectory;

            IoHelpers.EnsureDirectoryExists(deliveryPath);
            Console.WriteLine($"Binaries will be delivered here: {deliveryPath}");

            foreach (string target in Targets)
            {
                string publishedFolder         = Path.Combine(BinDistDirectory, target);
                string currentBinDistDirectory = publishedFolder;

                Console.WriteLine();
                Console.WriteLine($"{nameof(currentBinDistDirectory)}:\t{currentBinDistDirectory}");

                Console.WriteLine();
                if (!Directory.Exists(currentBinDistDirectory))
                {
                    Directory.CreateDirectory(currentBinDistDirectory);
                    Console.WriteLine($"Created {currentBinDistDirectory}");
                }

                using (var process = Process.Start(new ProcessStartInfo
                {
                    FileName = "dotnet",
                    Arguments = $"clean",
                    WorkingDirectory = GuiProjectDirectory
                }))
                {
                    process.WaitForExit();
                }

                // https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore21
                // -c|--configuration {Debug|Release}
                //		Defines the build configuration. The default value is Debug.
                // --force
                //		Forces all dependencies to be resolved even if the last restore was successful. Specifying this flag is the same as deleting the project.assets.json file.
                // -o|--output <OUTPUT_DIRECTORY>
                //		Specifies the path for the output directory.
                //		If not specified, it defaults to ./bin/[configuration]/[framework]/publish/ for a framework-dependent deployment or
                //		./bin/[configuration]/[framework]/[runtime]/publish/ for a self-contained deployment.
                //		If the path is relative, the output directory generated is relative to the project file location, not to the current working directory.
                // --self-contained
                //		Publishes the .NET Core runtime with your application so the runtime does not need to be installed on the target machine.
                //		If a runtime identifier is specified, its default value is true. For more information about the different deployment types, see .NET Core application deployment.
                // -r|--runtime <RUNTIME_IDENTIFIER>
                //		Publishes the application for a given runtime. This is used when creating a self-contained deployment (SCD).
                //		For a list of Runtime Identifiers (RIDs), see the RID catalog. Default is to publish a framework-dependent deployment (FDD).
                // --version-suffix <VERSION_SUFFIX>
                //		Defines the version suffix to replace the asterisk (*) in the version field of the project file.
                // https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-restore?tabs=netcore2x
                // --disable-parallel
                //		Disables restoring multiple projects in parallel.
                // --no-cache
                //		Specifies to not cache packages and HTTP requests.
                // https://github.com/dotnet/docs/issues/7568
                // /p:Version=1.2.3.4
                //		"dotnet publish" supports msbuild command line options like /p:Version=1.2.3.4
                using (var process = Process.Start(new ProcessStartInfo
                {
                    FileName = "dotnet",
                    Arguments = string.Join(" ",
                                            $"publish",
                                            $"--configuration Release",
                                            $"--force",
                                            $"--output \"{currentBinDistDirectory}\"",
                                            $"--self-contained true",
                                            $"--runtime \"{target}\"",
                                            $"--disable-parallel",
                                            $"--no-cache",
                                            $"/p:VersionPrefix={VersionPrefix}",
                                            $"/p:DebugType=none",
                                            $"/p:DebugSymbols=false",
                                            $"/p:ErrorReport=none",
                                            $"/p:DocumentationFile=\"\"",
                                            $"/p:Deterministic=true",
                                            $"/p:RestoreLockedMode=true"),
                    WorkingDirectory = GuiProjectDirectory,
                    RedirectStandardOutput = true
                }))
                {
                    string error = process.StandardOutput.ReadToEnd();
                    process.WaitForExit();
                    if (process.ExitCode != 0)
                    {
                        throw new InvalidOperationException($"dotnet publish returned with error code {process.ExitCode}. Error message was: {error ?? "none"}");
                    }
                }

                Tools.ClearSha512Tags(currentBinDistDirectory);

                // Remove Tor binaries that are not relevant to the platform.
                var torFolder   = new DirectoryInfo(Path.Combine(currentBinDistDirectory, "TorDaemons"));
                var toNotRemove = "";
                if (target.StartsWith("win"))
                {
                    toNotRemove = "win";
                }
                else if (target.StartsWith("linux"))
                {
                    toNotRemove = "lin";
                }
                else if (target.StartsWith("osx"))
                {
                    toNotRemove = "osx";
                }

                foreach (var file in torFolder.EnumerateFiles())
                {
                    if (!file.Name.Contains("data", StringComparison.OrdinalIgnoreCase) && !file.Name.Contains(toNotRemove, StringComparison.OrdinalIgnoreCase))
                    {
                        File.Delete(file.FullName);
                    }
                }

                // Remove binaries that are not relevant to the platform.
                var binaryFolder = new DirectoryInfo(Path.Combine(currentBinDistDirectory, "Microservices", "Binaries"));

                foreach (var dir in binaryFolder.EnumerateDirectories())
                {
                    if (!dir.Name.Contains(toNotRemove, StringComparison.OrdinalIgnoreCase))
                    {
                        IoHelpers.TryDeleteDirectoryAsync(dir.FullName).GetAwaiter().GetResult();
                    }
                }

                // Rename the final exe.
                string oldExecutablePath;
                string newExecutablePath;
                if (target.StartsWith("win"))
                {
                    oldExecutablePath = Path.Combine(currentBinDistDirectory, "WalletWasabi.Gui.exe");
                    newExecutablePath = Path.Combine(currentBinDistDirectory, $"{ExecutableName}.exe");
                }
                else                 // Linux & OSX
                {
                    oldExecutablePath = Path.Combine(currentBinDistDirectory, "WalletWasabi.Gui");
                    newExecutablePath = Path.Combine(currentBinDistDirectory, ExecutableName);
                }
                File.Move(oldExecutablePath, newExecutablePath);

                long installedSizeKb = Tools.DirSize(new DirectoryInfo(publishedFolder)) / 1000;

                if (target.StartsWith("win"))
                {
                    var daemonExePath = newExecutablePath[0..^ 4] + "d.exe";
示例#22
0
        private static void Sign()
        {
            foreach (string target in Targets)
            {
                if (target.StartsWith("win", StringComparison.OrdinalIgnoreCase))
                {
                    string publishedFolder = Path.Combine(BinDistDirectory, target);

                    Console.WriteLine("Move created .msi");
                    var msiPath = Path.Combine(WixProjectDirectory, "bin", "Release", "GroestlMix.msi");
                    if (!File.Exists(msiPath))
                    {
                        throw new Exception(".msi does not exist. Expected path: GroestlMix.msi.");
                    }
                    var msiFileName = Path.GetFileNameWithoutExtension(msiPath);
                    var newMsiPath  = Path.Combine(BinDistDirectory, $"{msiFileName}-{VersionPrefix}.msi");
                    File.Move(msiPath, newMsiPath);

                    Console.Write("Enter Code Signing Certificate Password: "******"cmd",
                        RedirectStandardInput = true,
                        WorkingDirectory = BinDistDirectory
                    }))
                    {
                        process.StandardInput.WriteLine($"signtool sign /d \"GroestlMix Wallet\" /f \"{PfxPath}\" /p {pfxPassword} /t http://timestamp.digicert.com /a \"{newMsiPath}\" && exit");
                        process.WaitForExit();
                    }

                    IoHelpers.TryDeleteDirectoryAsync(publishedFolder).GetAwaiter().GetResult();
                    Console.WriteLine($"Deleted {publishedFolder}");
                }
                else if (target.StartsWith("osx", StringComparison.OrdinalIgnoreCase))
                {
                    string dmgFilePath = Path.Combine(BinDistDirectory, $"Wasabi-{VersionPrefix}.dmg");
                    if (!File.Exists(dmgFilePath))
                    {
                        throw new Exception(".dmg does not exist.");
                    }
                    string zipFilePath = Path.Combine(BinDistDirectory, $"Wasabi-osx-{VersionPrefix}.zip");
                    if (File.Exists(zipFilePath))
                    {
                        File.Delete(zipFilePath);
                    }
                }
            }

            Console.WriteLine("Signing final files...");
            var finalFiles = Directory.GetFiles(BinDistDirectory);

            foreach (var finalFile in finalFiles)
            {
                using (var process = Process.Start(new ProcessStartInfo
                {
                    FileName = "cmd",
                    RedirectStandardInput = true,
                    WorkingDirectory = BinDistDirectory
                }))
                {
                    process.StandardInput.WriteLine($"gpg --armor --detach-sign {finalFile} && exit");
                    process.WaitForExit();
                }

                using (var process = Process.Start(new ProcessStartInfo
                {
                    FileName = "cmd",
                    RedirectStandardInput = true,
                    WorkingDirectory = WixProjectDirectory
                }))
                {
                    process.StandardInput.WriteLine($"git checkout -- ComponentsGenerated.wxs && exit");
                    process.WaitForExit();
                }
            }

            IoHelpers.OpenFolderInFileExplorer(BinDistDirectory);
        }
        public static async Task <CoreNode> CreateAsync(CoreNodeParams coreNodeParams, CancellationToken cancel)
        {
            Guard.NotNull(nameof(coreNodeParams), coreNodeParams);
            using (BenchmarkLogger.Measure())
            {
                var coreNode = new CoreNode
                {
                    HostedServices = coreNodeParams.HostedServices,
                    DataDir        = coreNodeParams.DataDir,
                    Network        = coreNodeParams.Network,
                    MempoolService = coreNodeParams.MempoolService
                };

                var configPath = Path.Combine(coreNode.DataDir, "bitcoin.conf");
                coreNode.Config = new CoreConfig();
                if (File.Exists(configPath))
                {
                    var configString = await File.ReadAllTextAsync(configPath, cancel).ConfigureAwait(false);

                    coreNode.Config.AddOrUpdate(configString);                     // Bitcoin Core considers the last entry to be valid.
                }
                cancel.ThrowIfCancellationRequested();

                var configTranslator = new CoreConfigTranslator(coreNode.Config, coreNode.Network);

                string?   rpcUser           = configTranslator.TryGetRpcUser();
                string?   rpcPassword       = configTranslator.TryGetRpcPassword();
                string?   rpcCookieFilePath = configTranslator.TryGetRpcCookieFile();
                string?   rpcHost           = configTranslator.TryGetRpcBind();
                int?      rpcPort           = configTranslator.TryGetRpcPort();
                WhiteBind whiteBind         = configTranslator.TryGetWhiteBind();

                string authString;
                bool   cookieAuth = rpcCookieFilePath is { };
                if (cookieAuth)
                {
                    authString = $"cookiefile={rpcCookieFilePath}";
                }
                else
                {
                    rpcUser ??= Encoders.Hex.EncodeData(RandomUtils.GetBytes(21));
                    rpcPassword ??= Encoders.Hex.EncodeData(RandomUtils.GetBytes(21));
                    authString = $"{rpcUser}:{rpcPassword}";
                }

                coreNode.P2pEndPoint = whiteBind?.EndPoint ?? coreNodeParams.P2pEndPointStrategy.EndPoint;

                if (rpcHost is null)
                {
                    coreNodeParams.RpcEndPointStrategy.EndPoint.TryGetHost(out rpcHost);
                }

                if (rpcPort is null)
                {
                    coreNodeParams.RpcEndPointStrategy.EndPoint.TryGetPort(out rpcPort);
                }

                EndPointParser.TryParse($"{rpcHost}:{rpcPort}", coreNode.Network.RPCPort, out EndPoint rpce);
                coreNode.RpcEndPoint = rpce;

                var rpcClient = new RPCClient(
                    $"{authString}",
                    coreNode.RpcEndPoint.ToString(coreNode.Network.DefaultPort),
                    coreNode.Network);
                coreNode.RpcClient = new CachedRpcClient(rpcClient, coreNodeParams.Cache);

                if (coreNodeParams.TryRestart)
                {
                    await coreNode.TryStopAsync(false).ConfigureAwait(false);
                }
                cancel.ThrowIfCancellationRequested();

                if (coreNodeParams.TryDeleteDataDir)
                {
                    await IoHelpers.TryDeleteDirectoryAsync(coreNode.DataDir).ConfigureAwait(false);
                }
                cancel.ThrowIfCancellationRequested();

                IoHelpers.EnsureDirectoryExists(coreNode.DataDir);

                var configPrefix             = NetworkTranslator.GetConfigPrefix(coreNode.Network);
                var whiteBindPermissionsPart = !string.IsNullOrWhiteSpace(whiteBind?.Permissions) ? $"{whiteBind?.Permissions}@" : "";

                if (!coreNode.RpcEndPoint.TryGetHost(out string?rpcBindParameter) || !coreNode.RpcEndPoint.TryGetPort(out int?rpcPortParameter))
                {
                    throw new ArgumentException("Endpoint type is not supported.", nameof(coreNode.RpcEndPoint));
                }

                var desiredConfigLines = new List <string>()
                {
                    $"{configPrefix}.server			= 1",
                    $"{configPrefix}.listen			= 1",
                    $"{configPrefix}.whitebind		= {whiteBindPermissionsPart}{coreNode.P2pEndPoint.ToString(coreNode.Network.DefaultPort)}",
                    $"{configPrefix}.rpcbind		= {rpcBindParameter}",
                    $"{configPrefix}.rpcallowip		= {IPAddress.Loopback}",
                    $"{configPrefix}.rpcport		= {rpcPortParameter}"
                };

                if (!cookieAuth)
                {
                    desiredConfigLines.Add($"{configPrefix}.rpcuser		= {coreNode.RpcClient.CredentialString.UserPassword.UserName}");
                    desiredConfigLines.Add($"{configPrefix}.rpcpassword	= {coreNode.RpcClient.CredentialString.UserPassword.Password}");
                }

                if (coreNodeParams.TxIndex is { })