public static async Task<SynchronizerViewModel> Startup(BlockChainIdentity activeNetwork, string walletAppDataDir, bool searchPath) { // Begin the asynchronous reading of the certificate before starting the wallet // process. This uses filesystem events to know when to begin reading the certificate, // and if there is too much delay between wallet writing the cert and this process // beginning to observe the change, the event may never fire and the cert won't be read. var rootCertificateTask = TransportSecurity.ReadModifiedCertificateAsync(walletAppDataDir); string walletProcessPath = null; if (!searchPath) { walletProcessPath = Portability.ExecutableInstallationPath( Environment.OSVersion.Platform, AssemblyResources.Organization, WalletProcess.ProcessName); } var walletProcess = WalletProcess.Start(activeNetwork, walletAppDataDir, walletProcessPath); WalletClient walletClient; try { var listenAddress = WalletProcess.RpcListenAddress("localhost", activeNetwork); var rootCertificate = await rootCertificateTask; walletClient = await WalletClient.ConnectAsync(listenAddress, rootCertificate); } catch (Exception) { if (walletProcess.HasExited) { throw new Exception("Wallet process closed unexpectedly"); } walletProcess.KillIfExecuting(); throw; } return new SynchronizerViewModel(walletProcess, walletClient); }
private static void KillLeftoverWalletProcess(BlockChainIdentity intendedNetwork) { var v4ListenAddress = WalletProcess.RpcListenAddress("127.0.0.1", intendedNetwork); var walletProcesses = new ManagementObjectSearcher($"SELECT * FROM Win32_Process WHERE Name='{WalletProcess.ProcessName}.exe'").Get(); foreach (var walletProcessInfo in walletProcesses) { var commandLine = (string)walletProcessInfo["CommandLine"]; if (commandLine.Contains($" --experimentalrpclisten={v4ListenAddress}")) { var process = Process.GetProcessById((int)(uint)walletProcessInfo["ProcessID"]); process.KillIfExecuting(); break; } } }
public static void ValidPayToScriptHashAddresses(string encodedAddress, BlockChainIdentity intendedBlockChain) { Address address; Assert.True(Address.TryDecode(encodedAddress, out address)); address = Address.Decode(encodedAddress); Assert.IsType<Address.PayToScriptHash>(address); var p2shAddress = (Address.PayToScriptHash)address; Assert.Same(address.IntendedBlockChain, intendedBlockChain); var newAddress = new Address.PayToSecp256k1PubKeyHash(intendedBlockChain, p2shAddress.ScriptHash); var reencodedAddress = address.Encode(); Assert.Equal(encodedAddress, reencodedAddress); }
public static string RpcListenAddress(string hostnameOrIp, BlockChainIdentity intendedNetwork) { if (intendedNetwork == null) throw new ArgumentNullException(nameof(intendedNetwork)); string port; if (intendedNetwork == BlockChainIdentity.MainNet) port = "9110"; else if (intendedNetwork == BlockChainIdentity.TestNet) port = "19110"; else if (intendedNetwork == BlockChainIdentity.SimNet) port = "19557"; else throw new UnknownBlockChainException(intendedNetwork); return $"{hostnameOrIp}:{port}"; }
public static void ValidPayToSecp256k1PubKeyHashAddresses(string encodedAddress, BlockChainIdentity intendedBlockChain) { // Assert TryDecode and Decode succeed on valid address. Address address; Assert.True(Address.TryDecode(encodedAddress, out address)); address = Address.Decode(encodedAddress); // Assert actual instance type is PayToSecp256k1PubKeyHash Assert.IsType<Address.PayToSecp256k1PubKeyHash>(address); var p2pkhAddress = (Address.PayToSecp256k1PubKeyHash)address; // Assert address is for the correct intended network. Assert.Same(address.IntendedBlockChain, intendedBlockChain); // Assert reencoded address string is equal to the test input. var newAddress = new Address.PayToSecp256k1PubKeyHash(intendedBlockChain, p2pkhAddress.PubKeyHash); var reencodedAddress = newAddress.Encode(); Assert.Equal(encodedAddress, reencodedAddress); }
public static string RpcListenAddress(string hostnameOrIp, BlockChainIdentity intendedNetwork) { if (intendedNetwork == null) throw new ArgumentNullException(nameof(intendedNetwork)); // Note: The standard ports for dcrwallet RPC are 9110, 19110, and 19557. // The ports used by Paymetheus are 2 greater than this to avoid conflicts with // other running dcrwallet instances using the default settings. // The +1 port is reserved for running dcrd on a nonstandard port as well. string port; if (intendedNetwork == BlockChainIdentity.MainNet) port = "9112"; else if (intendedNetwork == BlockChainIdentity.TestNet) port = "19112"; else if (intendedNetwork == BlockChainIdentity.SimNet) port = "19559"; else throw new UnknownBlockChainException(intendedNetwork); return $"{hostnameOrIp}:{port}"; }
public static Process Start(BlockChainIdentity intendedNetwork, string appDataDirectory, string executablePath = null, string extraArgs = null) { if (intendedNetwork == null) throw new ArgumentNullException(nameof(intendedNetwork)); if (appDataDirectory == null) throw new ArgumentNullException(nameof(appDataDirectory)); var networkFlag = ""; if (intendedNetwork != BlockChainIdentity.MainNet) { networkFlag = $"--{intendedNetwork.Name}"; } var v4ListenAddress = RpcListenAddress("127.0.0.1", intendedNetwork); extraArgs = extraArgs ?? ""; var processInfo = new ProcessStartInfo(); processInfo.FileName = executablePath ?? ProcessName; processInfo.Arguments = $"{networkFlag} --noinitialload --experimentalrpclisten={v4ListenAddress} --onetimetlskey --appdata=\"{appDataDirectory}\" {extraArgs}"; processInfo.UseShellExecute = false; processInfo.RedirectStandardError = true; processInfo.RedirectStandardOutput = true; processInfo.CreateNoWindow = true; try { var process = Process.Start(processInfo); process.ErrorDataReceived += (sender, args) => Console.WriteLine("err> {0}", args.Data); process.OutputDataReceived += (sender, args) => Console.WriteLine("{0}", args.Data); process.BeginErrorReadLine(); process.BeginOutputReadLine(); return process; } catch (System.ComponentModel.Win32Exception w32ex) when (w32ex.NativeErrorCode == ErrorFileNotFound) { throw new ProcessNotFoundException(processInfo.FileName, w32ex); } }
public static int BlocksUntilTicketPriceRetarget(int blockHeight, BlockChainIdentity blockChain) { var sdiffInterval = blockChain.StakeDifficultyRetargetInterval; return(sdiffInterval - (blockHeight % sdiffInterval)); }
public static bool IsMatured(int blockchainHeight, int txHeight, BlockChainIdentity blockChain) => IsConfirmed(blockchainHeight, txHeight, blockChain.Maturity);
public UnknownBlockChainException(BlockChainIdentity identity) : base($"Unknown blockchain `{identity.Name}`") { }
private ProcessArguments(BlockChainIdentity intendedNetwork, bool searchPathForWalletProcess) { IntendedNetwork = intendedNetwork; SearchPathForProcesses = searchPathForWalletProcess; }
private ProcessArguments(BlockChainIdentity intendedNetwork, bool searchPathForWalletProcess, string extraWalletArgs) { IntendedNetwork = intendedNetwork; SearchPathForWalletProcess = searchPathForWalletProcess; ExtraWalletArgs = extraWalletArgs; }