Exemple #1
0
        /// <inheritdoc />
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var network = (Network)value;

            string networkName = null;

            if (network == NetworkRegistration.GetNetwork("MainNet"))
            {
                networkName = "MainNet";
            }
            else if (network == NetworkRegistration.GetNetwork("TestNet"))
            {
                networkName = "TestNet";
            }
            else if (network == NetworkRegistration.GetNetwork("RegTest"))
            {
                networkName = "RegTest";
            }
            else if (network != null)
            {
                networkName = network.ToString();
            }

            if (networkName != null)
            {
                writer.WriteValue(networkName);
            }
        }
Exemple #2
0
        public static async Task MainAsync(string[] args)
        {
            try
            {
                Network      network      = NetworkRegistration.Register(new SmartContractPosTest());
                NodeSettings nodeSettings = new NodeSettings(network, ProtocolVersion.ALT_PROTOCOL_VERSION, "StratisSC", args: args);

                Bitcoin.IFullNode node = new FullNodeBuilder()
                                         .UseNodeSettings(nodeSettings)
                                         .UseBlockStore()
                                         .AddRPC()
                                         .AddSmartContracts()
                                         .UseSmartContractPosConsensus()
                                         .UseSmartContractPosPowMining()
                                         .UseSmartContractWallet()
                                         .UseReflectionExecutor()
                                         .UseApi()
                                         .UseMempool()
                                         .Build();

                await node.RunAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine("There was a problem initializing the node. Details: '{0}'", ex.ToString());
            }
        }
Exemple #3
0
        public WithdrawalTransactionBuilderTests()
        {
            this.loggerFactory                      = new Mock <ILoggerFactory>();
            this.network                            = NetworkRegistration.Register(new CirrusRegTest());
            this.federationWalletManager            = new Mock <IFederationWalletManager>();
            this.federationWalletTransactionHandler = new Mock <IFederationWalletTransactionHandler>();
            this.federationGatewaySettings          = new Mock <IFederatedPegSettings>();
            this.signals                            = new Mock <ISignals>();

            this.logger = new Mock <ILogger>();
            this.loggerFactory.Setup(x => x.CreateLogger(It.IsAny <string>()))
            .Returns(this.logger.Object);

            this.federationGatewaySettings.Setup(x => x.GetWithdrawalTransactionFee(It.IsAny <int>()))
            .Returns <int>((numInputs) =>
            {
                return(FederatedPegSettings.BaseTransactionFee + FederatedPegSettings.InputTransactionFee * numInputs);
            });

            this.federationWalletManager.Setup(x => x.Secret)
            .Returns(new WalletSecret());

            this.federationWalletTransactionHandler.Setup(x => x.BuildTransaction(It.IsAny <TransactionBuildContext>()))
            .Returns(this.network.CreateTransaction());
        }
        public void RegisterNetworkTwiceReturnsSameNetwork()
        {
            Network main         = KnownNetworks.Main;
            Network reregistered = NetworkRegistration.Register(main);

            Assert.Equal(main, reregistered);
        }
 public void NetworksAreValid()
 {
     foreach (Network network in NetworkRegistration.GetNetworks())
     {
         Assert.NotNull(network);
     }
 }
Exemple #6
0
        private void SetString(string base64)
        {
            if (this._Network == null)
            {
                this._Network = NetworkRegistration.GetNetworkFromBase58Data(base64, this.Type);
                if (this._Network == null)
                {
                    throw new FormatException("Invalid " + GetType().Name);
                }
            }

            byte[] vchTemp         = Encoders.Base58Check.DecodeData(base64);
            byte[] expectedVersion = this._Network.GetVersionBytes(this.Type, true);


            this.vchVersion = vchTemp.SafeSubarray(0, expectedVersion.Length);
            if (!Utils.ArrayEqual(this.vchVersion, expectedVersion))
            {
                throw new FormatException("The version prefix does not match the expected one " + String.Join(",", expectedVersion));
            }

            this.vchData = vchTemp.SafeSubarray(expectedVersion.Length);
            this.wifData = base64;

            if (!this.IsValid)
            {
                throw new FormatException("Invalid " + GetType().Name);
            }
        }
Exemple #7
0
        public static async Task Main(string[] args)
        {
            try
            {
                const string agent = "RedstoneSpv";

                Network network = args.Contains("-testnet")
                    ? NetworkRegistration.Register(new RedstoneTest())
                    : args.Contains("-regnet")
                    ? NetworkRegistration.Register(new RedstoneRegTest())
                    : NetworkRegistration.Register(new RedstoneMain());

                var nodeSettings = new NodeSettings(network: network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, args: args)
                {
                    MinProtocolVersion = ProtocolVersion.ALT_PROTOCOL_VERSION
                };

                var node = new FullNodeBuilder()
                           .UseNodeSettings(nodeSettings)
                           .UseLightWallet()
                           .UseBlockNotification()
                           .UseTransactionNotification()
                           .UseApi()
                           .Build();

                if (node != null)
                {
                    await node.RunAsync();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("There was a problem initializing the node. Details: '{0}'", ex.Message);
            }
        }
        /// <summary>
        /// Initializes the cross-chain transfer tests.
        /// </summary>
        /// <param name="network">The network to run the tests for.</param>
        public CrossChainTestBase(Network network = null, Network counterChainNetwork = null)
        {
            this.network             = network ?? FederatedPegNetwork.NetworksSelector.Regtest();
            this.counterChainNetwork = counterChainNetwork ?? Networks.Stratis.Regtest();
            this.federatedPegOptions = new FederatedPegOptions(counterChainNetwork);

            NetworkRegistration.Register(this.network);

            this.loggerFactory = Substitute.For <ILoggerFactory>();
            this.nodeLifetime  = new NodeLifetime();
            this.logger        = Substitute.For <ILogger>();
            this.signals       = Substitute.For <ISignals>();
            this.asyncProvider = new AsyncProvider(this.loggerFactory, this.signals, this.nodeLifetime);
            this.loggerFactory.CreateLogger(null).ReturnsForAnyArgs(this.logger);
            this.dateTimeProvider                   = DateTimeProvider.Default;
            this.opReturnDataReader                 = new OpReturnDataReader(this.loggerFactory, this.federatedPegOptions);
            this.blockRepository                    = Substitute.For <IBlockRepository>();
            this.fullNode                           = Substitute.For <IFullNode>();
            this.withdrawalTransactionBuilder       = Substitute.For <IWithdrawalTransactionBuilder>();
            this.federationWalletManager            = Substitute.For <IFederationWalletManager>();
            this.federationWalletSyncManager        = Substitute.For <IFederationWalletSyncManager>();
            this.FederationWalletTransactionHandler = Substitute.For <IFederationWalletTransactionHandler>();
            this.walletFeePolicy                    = Substitute.For <IWalletFeePolicy>();
            this.connectionManager                  = Substitute.For <IConnectionManager>();
            this.dBreezeSerializer                  = new DBreezeSerializer(this.network.Consensus.ConsensusFactory);
            this.ibdState                           = Substitute.For <IInitialBlockDownloadState>();
            this.wallet = null;
            this.federationGatewaySettings = Substitute.For <IFederationGatewaySettings>();
            this.ChainIndexer = new ChainIndexer(this.network);

            this.federationGatewaySettings.TransactionFee.Returns(new Money(0.01m, MoneyUnit.BTC));

            // Generate the keys used by the federation members for our tests.
            this.federationKeys = new[]
            {
                "ensure feel swift crucial bridge charge cloud tell hobby twenty people mandate",
                "quiz sunset vote alley draw turkey hill scrap lumber game differ fiction",
                "exchange rent bronze pole post hurry oppose drama eternal voice client state"
            }.Select(m => HdOperations.GetExtendedKey(m)).ToArray();

            SetExtendedKey(0);

            this.fundingTransactions = new List <Transaction>();

            this.blockDict = new Dictionary <uint256, Block>();
            this.blockDict[this.network.GenesisHash] = this.network.GetGenesis();

            this.blockRepository.GetBlocks(Arg.Any <List <uint256> >()).ReturnsForAnyArgs((x) =>
            {
                var hashes = x.ArgAt <List <uint256> >(0);
                var blocks = new List <Block>();
                for (int i = 0; i < hashes.Count; i++)
                {
                    blocks.Add(this.blockDict.TryGetValue(hashes[i], out Block block) ? block : null);
                }

                return(blocks);
            });
        }
Exemple #9
0
        public ColoredCoinsTests()
        {
            NetworkRegistration.Clear();

            this.networkRegTest = KnownNetworks.RegTest;
            this.networkTest    = KnownNetworks.TestNet;
            this.networkMain    = KnownNetworks.Main;
        }
        public Util_Tests()
        {
            NetworkRegistration.Clear();

            this.networkTestNet = KnownNetworks.TestNet;
            this.networkRegTest = KnownNetworks.RegTest;
            this.networkMain    = KnownNetworks.Main;
        }
Exemple #11
0
        public void SendAndReceiveSmartContractTransactions()
        {
            NetworkRegistration.Register(new SmartContractsRegTest());

            using (PoWMockChain chain = new PoWMockChain(2))
            {
                MockChainNode scSender   = chain.Nodes[0];
                MockChainNode scReceiver = chain.Nodes[1];

                // Mining adds coins to wallet.
                var maturity = (int)scSender.CoreNode.FullNode.Network.Consensus.CoinbaseMaturity;
                TestHelper.MineBlocks(scSender.CoreNode, maturity + 5);
                chain.WaitForAllNodesToSync();
                int spendable = GetSpendableBlocks(maturity + 5, maturity);
                Assert.Equal(Money.COIN * spendable * 50, (long)scSender.WalletSpendableBalance);

                // Create a token contract.
                ulong gasPrice = SmartContractMempoolValidator.MinGasPrice;
                var   gasLimit = (RuntimeObserver.Gas)(SmartContractFormatLogic.GasLimitMaximum / 2);

                // Create a transfer token contract.
                var compilationResult = ContractCompiler.CompileFile("SmartContracts/TransferTest.cs");
                Assert.True(compilationResult.Success);

                // Broadcast the token transaction to the network.
                var createTransactionResponse = scSender.SendCreateContractTransaction(compilationResult.Compilation, 0, feeAmount: 0.001M, gasPrice: gasPrice,
                                                                                       gasLimit: gasLimit);

                // Wait for the token transaction to be picked up by the mempool.
                scSender.WaitMempoolCount(1);

                // Mine the token transaction and wait for it to sync.
                scSender.MineBlocks(1);

                // Ensure that both nodes have the contract.
                var tokenContractAddress = createTransactionResponse.NewContractAddress;

                // Ensure that both nodes have the contract.
                Assert.NotNull(scSender.GetCode(tokenContractAddress));
                Assert.NotNull(scReceiver.GetCode(tokenContractAddress));

                // Create a call contract transaction which will transfer funds.
                scSender.SendCallContractTransaction("Test", createTransactionResponse.NewContractAddress, 0.00001M,
                                                     feeAmount: 0.001M, gasPrice: gasPrice, gasLimit: gasLimit);

                scSender.WaitMempoolCount(1);

                // Mine the transaction.
                scSender.MineBlocks(1);

                // The balance should now reflect the transfer.
                Assert.Equal((ulong)900, scSender.GetContractBalance(tokenContractAddress));
            }
        }
Exemple #12
0
        /// <summary>
        ///     Get the network on which to operate.
        /// </summary>
        /// <param name="network">The network</param>
        /// <returns>A <see cref="Network" /> object.</returns>
        public static Network GetNetwork(string network)
        {
            Guard.NotEmpty(network, nameof(network));

            var selectNetwork = NetworkRegistration.GetNetwork(network.ToLowerInvariant());

            if (selectNetwork == null)
            {
                throw new ArgumentException($"Network '{network}' is not a valid network.");
            }

            return(selectNetwork);
        }
        public void CanGetNetworkFromName()
        {
            Network redstoneMain    = RedstoneNetworks.Main;
            Network redstoneTest    = RedstoneNetworks.TestNet;
            Network redstoneRegtest = RedstoneNetworks.RegTest;

            Assert.Equal(NetworkRegistration.GetNetwork("redstoneMain"), redstoneMain);
            Assert.Equal(NetworkRegistration.GetNetwork("RedstoneMain"), redstoneMain);
            Assert.Equal(NetworkRegistration.GetNetwork("RedstoneTest"), redstoneTest);
            Assert.Equal(NetworkRegistration.GetNetwork("RedstoneTest"), redstoneTest);
            Assert.Equal(NetworkRegistration.GetNetwork("redstoneRegtest"), redstoneRegtest);
            Assert.Equal(NetworkRegistration.GetNetwork("RedstoneRegtest"), redstoneRegtest);
            Assert.Null(NetworkRegistration.GetNetwork("invalid"));
        }
 public static void ReadWriteC(this BitcoinStream bs, ref Network network)
 {
     if (bs.Serializing)
     {
         var str = network.ToString();
         bs.ReadWriteC(ref str);
     }
     else
     {
         var str = string.Empty;
         bs.ReadWriteC(ref str);
         network = NetworkRegistration.GetNetwork(str);
     }
 }
        public static async Task Main(string[] args)
        {
            try
            {
                // Get the API uri.
                bool isTestNet = args.Contains("-testnet");
                bool isStratis = args.Contains("stratis");

                string agent = "Breeze";

                NodeSettings nodeSettings;

                if (isStratis)
                {
                    Network network = isTestNet ? NetworkRegistration.Register(new StratisTest()) : NetworkRegistration.Register(new StratisMain());
                    if (isTestNet)
                    {
                        args = args.Append("-addnode=51.141.28.47").ToArray(); // TODO: fix this temp hack
                    }
                    nodeSettings = new NodeSettings(network, ProtocolVersion.ALT_PROTOCOL_VERSION, agent, args: args);
                }
                else
                {
                    nodeSettings = new NodeSettings(agent: agent, args: args);
                }

                IFullNodeBuilder fullNodeBuilder = new FullNodeBuilder()
                                                   .UseNodeSettings(nodeSettings)
                                                   .UseLightWallet()
                                                   .UseBlockNotification()
                                                   .UseTransactionNotification()
                                                   .UseApi();

                IFullNode node = fullNodeBuilder.Build();

                // Start Full Node - this will also start the API.
                if (node != null)
                {
                    await node.RunAsync();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("There was a problem initializing the node. Details: '{0}'", ex.ToString());
            }
        }
Exemple #16
0
        public void Validate_AllowClientConnection_State(bool inIBD, bool isWhiteListed, bool closeClient)
        {
            // Arrange
            var networkPeerFactory = new Mock <INetworkPeerFactory>();

            networkPeerFactory.Setup(npf => npf.CreateConnectedNetworkPeerAsync(It.IsAny <IPEndPoint>(),
                                                                                It.IsAny <NetworkPeerConnectionParameters>(),
                                                                                It.IsAny <NetworkPeerDisposer>())).Returns(Task.FromResult(new Mock <INetworkPeer>().Object));

            var initialBlockDownloadState = new Mock <IInitialBlockDownloadState>();

            initialBlockDownloadState.Setup(i => i.IsInitialBlockDownload()).Returns(inIBD);

            var nodeSettings = new NodeSettings(NetworkRegistration.GetNetwork("RegTest"));
            var connectionManagerSettings = new ConnectionManagerSettings(nodeSettings);

            var endpointAddNode = new IPEndPoint(IPAddress.Parse("::ffff:192.168.0.1"), 80);

            var networkPeerServer = new NetworkPeerServer(this.Network,
                                                          endpointAddNode, endpointAddNode, ProtocolVersion.PROTOCOL_VERSION, this.extendedLoggerFactory,
                                                          networkPeerFactory.Object, initialBlockDownloadState.Object, connectionManagerSettings);

            // Mimic external client
            const int portNumber = 80;
            var       client     = new TcpClient("www.stratisplatform.com", portNumber);

            var ipandport = client.Client.RemoteEndPoint.ToString();
            var ip        = ipandport.Replace(ipandport.Substring(ipandport.IndexOf(':')), "");

            var endpointDiscovered = new IPEndPoint(IPAddress.Parse(ip), portNumber);

            // Include the external client as a NodeServerEndpoint.
            connectionManagerSettings.Listen.Add(new NodeServerEndpoint(endpointDiscovered, isWhiteListed));

            // Act
            var result = networkPeerServer.InvokeMethod("AllowClientConnection", client);

            // Assert
            Assert.True((inIBD && !isWhiteListed) == closeClient);

            this.testOutput.WriteLine(
                $"In IBD : {inIBD.ToString()}, " +
                $"Is White Listed : {isWhiteListed.ToString()}, " +
                $"Close Client : {result.ToString()}");
        }
        /// <inheritdoc />
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                        JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            var networkName = (string)reader.Value;

            if (networkName == null)
            {
                return(null);
            }

            if (networkName.Equals("MainNet", StringComparison.OrdinalIgnoreCase) ||
                networkName.Equals("main", StringComparison.OrdinalIgnoreCase))
            {
                return(NetworkRegistration.GetNetwork("MainNet"));
            }

            if (networkName.Equals("TestNet", StringComparison.OrdinalIgnoreCase) ||
                networkName.Equals("test", StringComparison.OrdinalIgnoreCase))
            {
                return(NetworkRegistration.GetNetwork("TestNet"));
            }

            if (networkName.Equals("RegTest", StringComparison.OrdinalIgnoreCase) ||
                networkName.Equals("reg", StringComparison.OrdinalIgnoreCase))
            {
                return(NetworkRegistration.GetNetwork("RegTest"));
            }

            var network = NetworkRegistration.GetNetwork(networkName);

            if (networkName != null)
            {
                return(networkName);
            }

            throw new JsonObjectException("Unknown network (valid values : main, test, reg)", reader);
        }
        public void CanGetNetworkFromName()
        {
            Network bitcoinMain    = KnownNetworks.Main;
            Network bitcoinTestnet = KnownNetworks.TestNet;
            Network bitcoinRegtest = KnownNetworks.RegTest;

            Assert.Equal(NetworkRegistration.GetNetwork("main"), bitcoinMain);
            Assert.Equal(NetworkRegistration.GetNetwork("mainnet"), bitcoinMain);
            Assert.Equal(NetworkRegistration.GetNetwork("MainNet"), bitcoinMain);
            Assert.Equal(NetworkRegistration.GetNetwork("test"), bitcoinTestnet);
            Assert.Equal(NetworkRegistration.GetNetwork("testnet"), bitcoinTestnet);
            Assert.Equal(NetworkRegistration.GetNetwork("regtest"), bitcoinRegtest);
            Assert.Equal(NetworkRegistration.GetNetwork("reg"), bitcoinRegtest);
            Assert.Equal(NetworkRegistration.GetNetwork("straxmain"), this.straxMain);
            Assert.Equal(NetworkRegistration.GetNetwork("StraxMain"), this.straxMain);
            Assert.Equal(NetworkRegistration.GetNetwork("StraxTest"), this.straxTest);
            Assert.Equal(NetworkRegistration.GetNetwork("straxtest"), this.straxTest);
            Assert.Equal(NetworkRegistration.GetNetwork("StraxRegTest"), this.straxRegTest);
            Assert.Equal(NetworkRegistration.GetNetwork("straxregtest"), this.straxRegTest);
            Assert.Null(NetworkRegistration.GetNetwork("invalid"));
        }
Exemple #19
0
        public static T Parse <T>(string str, Network expectedNetwork) where T : IBitcoinString
        {
            if (str == null)
            {
                throw new ArgumentNullException("str");
            }

            IEnumerable <Network> networks = expectedNetwork == null?NetworkRegistration.GetNetworks() : new[] { expectedNetwork };
            bool maybeb58 = true;

            for (int i = 0; i < str.Length; i++)
            {
                if (!Base58Encoder.pszBase58Chars.Contains(str[i]))
                {
                    maybeb58 = false;
                    break;
                }
            }

            if (maybeb58)
            {
                try
                {
                    Encoders.Base58Check.DecodeData(str);
                }
                catch (FormatException)
                {
                    maybeb58 = false;
                }
                if (maybeb58)
                {
                    foreach (IBase58Data candidate in GetCandidates(networks, str))
                    {
                        bool rightNetwork = expectedNetwork == null || (candidate.Network == expectedNetwork);
                        bool rightType    = candidate is T;
                        if (rightNetwork && rightType)
                        {
                            return((T)(object)candidate);
                        }
                    }
                    throw new FormatException("Invalid base58 string");
                }
            }

            foreach (Network network in networks)
            {
                int i = -1;
                foreach (Bech32Encoder encoder in network.Bech32Encoders)
                {
                    i++;
                    if (encoder == null)
                    {
                        continue;
                    }
                    var type = (Bech32Type)i;
                    try
                    {
                        byte   witVersion;
                        byte[] bytes     = encoder.Decode(str, out witVersion);
                        object candidate = null;

                        if (witVersion == 0 && bytes.Length == 20 && type == Bech32Type.WITNESS_PUBKEY_ADDRESS)
                        {
                            candidate = new BitcoinWitPubKeyAddress(str, network);
                        }
                        if (witVersion == 0 && bytes.Length == 32 && type == Bech32Type.WITNESS_SCRIPT_ADDRESS)
                        {
                            candidate = new BitcoinWitScriptAddress(str, network);
                        }

                        if (candidate is T)
                        {
                            return((T)candidate);
                        }
                    }
                    catch (Bech32FormatException)
                    {
                        throw;
                    }
                    catch (FormatException)
                    {
                        continue;
                    }
                }
            }

            throw new FormatException("Invalid string");
        }
Exemple #20
0
 public Network InitializeNetwork(bool testNet)
 {
     return(testNet ? NetworkRegistration.Register(new RedstoneTest())
             : NetworkRegistration.Register(new RedstoneMain()));
 }
Exemple #21
0
        /// <summary>
        /// Initializes a new instance of the object.
        /// </summary>
        /// <param name="network">The network the node runs on - regtest/testnet/mainnet.</param>
        /// <param name="protocolVersion">Supported protocol version for which to create the configuration.</param>
        /// <param name="agent">The nodes user agent that will be shared with peers.</param>
        /// <param name="args">The command-line arguments.</param>
        /// <param name="networksSelector">A selector class that delayed load a network for either - regtest/testnet/mainnet.</param>
        /// <exception cref="ConfigurationException">Thrown in case of any problems with the configuration file or command line arguments.</exception>
        /// <remarks>
        /// Processing depends on whether a configuration file is passed via the command line.
        /// There are two main scenarios here:
        /// - The configuration file is passed via the command line. In this case we need
        ///   to read it earlier so that it can provide defaults for "testnet" and "regtest".
        /// - Alternatively, if the file name is not supplied then a network-specific file
        ///   name would be determined. In this case we first need to determine the network.
        /// </remarks>
        public NodeSettings(Network network = null, ProtocolVersion protocolVersion = SupportedProtocolVersion,
                            string agent    = "ImpleumNode", string[] args          = null, NetworksSelector networksSelector = null)
        {
            // Create the default logger factory and logger.
            var loggerFactory = new ExtendedLoggerFactory();

            this.LoggerFactory = loggerFactory;
            this.LoggerFactory.AddConsoleWithFilters();
            this.LoggerFactory.AddNLog();
            this.Logger = this.LoggerFactory.CreateLogger(typeof(NodeSettings).FullName);

            // Record arguments.
            this.Network         = network;
            this.ProtocolVersion = protocolVersion;
            this.Agent           = agent;
            this.ConfigReader    = new TextFileConfiguration(args ?? new string[] { });

            // Log arguments.
            this.Logger.LogDebug("Arguments: network='{0}', protocolVersion='{1}', agent='{2}', args='{3}'.",
                                 this.Network == null ? "(None)" : this.Network.Name,
                                 this.ProtocolVersion,
                                 this.Agent,
                                 args == null ? "(None)" : string.Join(" ", args));

            // By default, we look for a file named '<network>.conf' in the network's data directory,
            // but both the data directory and the configuration file path may be changed using the -datadir and -conf command-line arguments.
            this.ConfigurationFile = this.ConfigReader.GetOrDefault <string>("conf", null, this.Logger)?.NormalizeDirectorySeparator();
            this.DataDir           = this.ConfigReader.GetOrDefault <string>("datadir", null, this.Logger)?.NormalizeDirectorySeparator();
            this.DataDirRoot       = this.ConfigReader.GetOrDefault <string>("datadirroot", "ImpleumNode", this.Logger);

            // If the configuration file is relative then assume it is relative to the data folder and combine the paths.
            if (this.DataDir != null && this.ConfigurationFile != null)
            {
                bool isRelativePath = Path.GetFullPath(this.ConfigurationFile).Length > this.ConfigurationFile.Length;
                if (isRelativePath)
                {
                    this.ConfigurationFile = Path.Combine(this.DataDir, this.ConfigurationFile);
                }
            }

            // If the configuration file has been specified on the command line then read it now
            // so that it can provide the defaults for testnet and regtest.
            if (this.ConfigurationFile != null)
            {
                // If the configuration file was specified on the command line then it must exist.
                if (!File.Exists(this.ConfigurationFile))
                {
                    throw new ConfigurationException($"Configuration file does not exist at {this.ConfigurationFile}.");
                }

                // Sets the ConfigReader based on the arguments and the configuration file if it exists.
                this.ReadConfigurationFile();
            }

            // If the network is not known then derive it from the command line arguments.
            if (this.Network == null)
            {
                if (networksSelector == null)
                {
                    throw new ConfigurationException("Network or NetworkSelector not provided.");
                }

                // Find out if we need to run on testnet or regtest from the config file.
                bool testNet = this.ConfigReader.GetOrDefault <bool>("testnet", false, this.Logger);
                bool regTest = this.ConfigReader.GetOrDefault <bool>("regtest", false, this.Logger);

                if (testNet && regTest)
                {
                    throw new ConfigurationException("Invalid combination of regtest and testnet.");
                }

                this.Network = testNet ? networksSelector.Testnet() : regTest?networksSelector.Regtest() : networksSelector.Mainnet();

                this.Logger.LogDebug("Network set to '{0}'.", this.Network.Name);
            }

            // Ensure the network being used is registered and we have the correct Network object reference.
            this.Network = NetworkRegistration.Register(this.Network);

            // Set the full data directory path.
            if (this.DataDir == null)
            {
                // Create the data directories if they don't exist.
                this.DataDir = this.CreateDefaultDataDirectories(Path.Combine(this.DataDirRoot, this.Network.RootFolderName), this.Network);
            }
            else
            {
                // Combine the data directory with the network's root folder and name.
                string directoryPath = Path.Combine(this.DataDir, this.Network.RootFolderName, this.Network.Name);
                this.DataDir = Directory.CreateDirectory(directoryPath).FullName;
                this.Logger.LogDebug("Data directory initialized with path {0}.", this.DataDir);
            }

            // Set the data folder.
            this.DataFolder = new DataFolder(this.DataDir);

            // Attempt to load NLog configuration from the DataFolder.
            loggerFactory.LoadNLogConfiguration(this.DataFolder);

            // Get the configuration file name for the network if it was not specified on the command line.
            if (this.ConfigurationFile == null)
            {
                this.ConfigurationFile = Path.Combine(this.DataDir, this.Network.DefaultConfigFilename);
                this.Logger.LogDebug("Configuration file set to '{0}'.", this.ConfigurationFile);

                if (File.Exists(this.ConfigurationFile))
                {
                    this.ReadConfigurationFile();
                }
            }

            // Create the custom logger factory.
            this.Log = new LogSettings();
            this.Log.Load(this.ConfigReader);
            this.LoggerFactory.AddFilters(this.Log, this.DataFolder);
            this.LoggerFactory.ConfigureConsoleFilters(this.LoggerFactory.GetConsoleSettings(), this.Log);

            // Load the configuration.
            this.LoadConfiguration();
        }
        //https://en.bitcoin.it/wiki/List_of_address_prefixes
        public void CanDetectBase58NetworkAndType()
        {
            var tests = new[]
            {
                new
                {
                    Base58       = "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3",
                    ExpectedType = typeof(BitcoinWitScriptAddress),
                    Network      = this.networkMain
                },
                new
                {
                    Base58       = "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
                    ExpectedType = typeof(BitcoinWitScriptAddress),
                    Network      = this.networkTestNet
                },
                new
                {
                    Base58       = "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4",
                    ExpectedType = typeof(BitcoinWitPubKeyAddress),
                    Network      = this.networkMain
                },
                new
                {
                    Base58       = "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx",
                    ExpectedType = typeof(BitcoinWitPubKeyAddress),
                    Network      = this.networkTestNet
                },
                new
                {
                    Base58       = "bWqaKUZETiECYgmJNbNZUoanBxnAzoVjCNx",
                    ExpectedType = typeof(BitcoinColoredAddress),
                    Network      = this.networkTestNet
                },
                new
                {
                    Base58       = "17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem",
                    ExpectedType = typeof(BitcoinPubKeyAddress),
                    Network      = this.networkMain
                },
                new
                {
                    Base58       = "17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem",
                    ExpectedType = typeof(BitcoinPubKeyAddress),
                    Network      = this.networkMain
                },
                new
                {
                    Base58       = "3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX",
                    ExpectedType = typeof(BitcoinScriptAddress),
                    Network      = this.networkMain
                },
                new
                {
                    Base58       = "mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn",
                    ExpectedType = typeof(BitcoinPubKeyAddress),
                    Network      = this.networkTestNet
                },
                new
                {
                    Base58       = "5Hwgr3u458GLafKBgxtssHSPqJnYoGrSzgQsPwLFhLNYskDPyyA",
                    ExpectedType = typeof(BitcoinSecret),
                    Network      = this.networkMain
                },
                new
                {
                    Base58       = "92Pg46rUhgTT7romnV7iGW6W1gbGdeezqdbJCzShkCsYNzyyNcc",
                    ExpectedType = typeof(BitcoinSecret),
                    Network      = this.networkTestNet
                },
                new
                {
                    Base58       = "3qdi7TXgRo1qR",
                    ExpectedType = (Type)null,
                    Network      = (Network)null
                },
                new
                {
                    Base58       = "6PYLtMnXvfG3oJde97zRyLYFZCYizPU5T3LwgdYJz1fRhh16bU7u6PPmY7",
                    ExpectedType = typeof(BitcoinEncryptedSecretNoEC),
                    Network      = (Network)null
                },
                new
                {
                    Base58       = "6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX",
                    ExpectedType = typeof(BitcoinEncryptedSecretEC),
                    Network      = (Network)null
                },
                new
                {
                    Base58       = "passphrasepxFy57B9v8HtUsszJYKReoNDV6VHjUSGt8EVJmux9n1J3Ltf1gRxyDGXqnf9qm",
                    ExpectedType = typeof(BitcoinPassphraseCode),
                    Network      = (Network)null
                },
                new
                {
                    Base58       = "cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD",
                    ExpectedType = typeof(BitcoinConfirmationCode),
                    Network      = (Network)null
                },
                new
                {
                    Base58       = "xprv9s21ZrQH143K3Gx1VAAD1ueDmwoPQUApekxWYSJ1f4W4m1nUPpRGdV5sTVhixZJT5cP2NqtEMZ2mrwHdW5RWpohCwspWidCpcLALvioXDyz",
                    ExpectedType = typeof(BitcoinExtKey),
                    Network      = this.networkMain
                },
                new
                {
                    Base58       = "xpub661MyMwAqRbcEhHavVcryjNF2uA5woK6JCNRNJB8Z3dxPU8VNBd9E8GP7fusw2bhgYe7BXt6izr5iUaYo483919jjdtfEpG8j97djnEgJqo",
                    ExpectedType = typeof(BitcoinExtPubKey),
                    Network      = this.networkMain
                },
                new
                {
                    Base58       = "akB4NBW9UuCmHuepksob6yfZs6naHtRCPNy",
                    ExpectedType = typeof(BitcoinColoredAddress),
                    Network      = this.networkMain
                }
            };

            foreach (var test in tests)
            {
                if (test.ExpectedType == null)
                {
                    Assert.Throws <FormatException>(() => Network.Parse(test.Base58, null));
                }
                else
                {
                    IBitcoinString result = Network.Parse(test.Base58, null);
                    Assert.True(test.ExpectedType == result.GetType());

                    if (test.Network != null)
                    {
                        if (test.Network.Name.ToLowerInvariant().Contains("test"))
                        {
                            Assert.Contains(result.Network, new[] { KnownNetworks.RegTest, KnownNetworks.TestNet });
                        }
                        else
                        {
                            Assert.Equal(test.Network, result.Network);
                        }
                    }

                    Network.Parse(test.Base58, test.Network);

                    if (test.Network == null)
                    {
                        continue;
                    }

                    foreach (Network network in NetworkRegistration.GetNetworks())
                    {
                        if (test.Network.Name.ToLowerInvariant().Contains("test"))
                        {
                            Assert.Contains(result.Network, new[] { KnownNetworks.RegTest, KnownNetworks.TestNet });
                            break;
                        }
                        else
                        {
                            if (network == test.Network)
                            {
                                break;
                            }
                        }

                        Assert.Throws <FormatException>(() => Network.Parse(test.Base58, network));
                    }
                }
            }
        }
Exemple #23
0
        /// <summary>
        /// The expected sequence of arguments:
        /// <list>
        /// <item>
        /// 1, [network-name] [options] [rpc-command] [rpc-params].
        /// </item>
        /// <item>
        /// 2, [network-name] [options] [api-controller "/" api-command] [api-params].
        /// </item>
        /// </list>
        /// </summary>
        public static void Main(string[] args)
        {
            try
            {
                // Preprocess the command line arguments
                var argList = new List <string>(args);

                string networkName = null;
                if (argList.Any())
                {
                    networkName = argList.First();
                    argList.RemoveAt(0);
                }

                var optionList = new List <string>();
                while ((argList.Any()) && (argList[0].StartsWith('-')))
                {
                    optionList.Add(argList[0]);
                    argList.RemoveAt(0);
                }

                string command = string.Empty;
                if (argList.Any())
                {
                    command = argList.First();
                    argList.RemoveAt(0);
                }

                var commandArgList = new List <string>(argList);

                // Display help if required.
                if (optionList.Contains("-help") || optionList.Contains("--help") || string.IsNullOrWhiteSpace(command))
                {
                    var builder = new StringBuilder();
                    builder.AppendLine("Usage:");
                    builder.AppendLine(" dotnet run <Stratis.Bitcoin.Cli/Stratis.Bitcoin.Cli.dll> [network-name] [options] <command> [arguments]");
                    builder.AppendLine();
                    builder.AppendLine("Command line arguments:");
                    builder.AppendLine();
                    builder.AppendLine("[network-name]                     Name of the network - e.g. \"stratis\", \"stratismain\", \"stratistest\", \"bitcoinmain\", \"bitcointest\".");
                    builder.AppendLine("[options]                          Options for the CLI (optional) - e.g. -help, -rpcuser, see below.");
                    builder.AppendLine("[command]                          Name of RPC method or API <controller>/<method>.");
                    builder.AppendLine("[arguments]                        Argument by position (RPC) or Name = Value pairs (API) (optional).");
                    builder.AppendLine();
                    builder.AppendLine("Options:");
                    builder.AppendLine("-help                              This help message");
                    builder.AppendLine("-rpcconnect=<ip>                   Send commands to node running on <ip> (default: 127.0.0.1)");
                    builder.AppendLine("-rpcport=<port>                    Connect to JSON-RPC on <port> (default for Stratis: 26174 or default for Bitcoin: 8332)");
                    builder.AppendLine("-rpcuser=<user>                    Username for JSON-RPC connections");
                    builder.AppendLine("-rpcpassword=<pw>                  Password for JSON-RPC connections");
                    builder.AppendLine();
                    builder.AppendLine("Examples:");
                    builder.AppendLine();
                    builder.AppendLine("dotnet run stratis Wallet/history WalletName=testwallet - Lists all the historical transactions of the wallet called 'testwallet'.");
                    builder.AppendLine("dotnet run stratis getinfo -rpcuser=stratistestuser -rpcpassword=stratistestpassword -rpcconnect=127.0.0.3 -rpcport=26174 - Displays general information about the Stratis node on the 127.0.0.3:26174, authenticating with the RPC specified user.");
                    builder.AppendLine("dotnet run bitcoin getbalance -rpcuser=btctestuser -rpcpassword=btctestpass - Displays the current balance of the opened wallet on the 127.0.0.1:8332 node, authenticating with the RPC specified user.");
                    Console.WriteLine(builder);
                    return;
                }

                // Determine API port.
                int     defaultRestApiPort = 0;
                Network network            = null;

                if (networkName.Contains("stratis"))
                {
                    defaultRestApiPort = 37221;
                    network            = NetworkRegistration.Register(new StratisMain());
                }
                else
                {
                    defaultRestApiPort = 37220;
                    network            = NetworkRegistration.Register(new BitcoinMain());
                }

                // API calls require both the contoller name and the method name separated by "/".
                // If this is not an API call then assume it is an RPC call.
                if (!command.Contains("/"))
                {
                    // Process RPC call.
                    try
                    {
                        string[] options = optionList.Append("-server").ToArray();

                        var nodeSettings = new NodeSettings(network, args: options);

                        var rpcSettings = new RpcSettings(nodeSettings);

                        // Find the binding to 127.0.0.1 or the first available. The logic in RPC settings ensures there will be at least 1.
                        System.Net.IPEndPoint nodeEndPoint = rpcSettings.Bind.FirstOrDefault(b => b.Address.ToString() == "127.0.0.1") ?? rpcSettings.Bind[0];
                        var rpcUri = new Uri($"http://{nodeEndPoint}");

                        // Process the command line RPC arguments
                        // TODO: this should probably be moved to the NodeSettings.FromArguments
                        if (options.GetValueOf("-rpcbind") != null)
                        {
                            rpcUri = new Uri($"http://{options.GetValueOf("-rpcbind")}");
                        }

                        if (options.GetValueOf("-rpcconnect") != null || options.GetValueOf("-rpcport") != null)
                        {
                            string rpcAddress = options.GetValueOf("-rpcconnect") ?? "127.0.0.1";

                            int rpcPort = rpcSettings.RPCPort;
                            int.TryParse(options.GetValueOf("-rpcport"), out rpcPort);

                            rpcUri = new Uri($"http://{rpcAddress}:{rpcPort}");
                        }
                        rpcSettings.RpcUser     = options.GetValueOf("-rpcuser") ?? rpcSettings.RpcUser;
                        rpcSettings.RpcPassword = options.GetValueOf("-rpcpassword") ?? rpcSettings.RpcPassword;

                        Console.WriteLine($"Connecting to the following RPC node: http://{rpcSettings.RpcUser}:{rpcSettings.RpcPassword}@{rpcUri.Authority}.");

                        // Initialize the RPC client with the configured or passed userid, password and endpoint.
                        var rpcClient = new RPCClient($"{rpcSettings.RpcUser}:{rpcSettings.RpcPassword}", rpcUri, network);

                        // Execute the RPC command
                        Console.WriteLine($"Sending RPC command '{command} {string.Join(" ", commandArgList)}' to '{rpcUri}'.");
                        RPCResponse response = rpcClient.SendCommand(command, commandArgList.ToArray());

                        // Return the result as a string to the console.
                        Console.WriteLine(response.ResultString);
                    }
                    catch (Exception err)
                    {
                        Console.WriteLine(err.Message);
                    }
                }
                else
                {
                    // Process API call.
                    using (var client = new HttpClient())
                    {
                        client.DefaultRequestHeaders.Accept.Clear();
                        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                        string url = $"http://localhost:{defaultRestApiPort}/api/{command}";
                        if (commandArgList.Any())
                        {
                            url += $"?{string.Join("&", commandArgList)}";
                        }
                        try
                        {
                            // Get the response.
                            Console.WriteLine($"Sending API command to {url}.");
                            string response = client.GetStringAsync(url).GetAwaiter().GetResult();

                            // Format and return the result as a string to the console.
                            Console.WriteLine(JsonConvert.SerializeObject(JsonConvert.DeserializeObject <object>(response), Formatting.Indented));
                        }
                        catch (Exception err)
                        {
                            Console.WriteLine(ExceptionToString(err));
                        }
                    }
                }
            }
            catch (Exception err)
            {
                // Report any errors to the console.
                Console.WriteLine(ExceptionToString(err));
            }
        }
        public void BitcoinMainnetIsInitializedCorrectly()
        {
            Assert.Equal(17, this.networkMain.Checkpoints.Count);
            Assert.Equal(6, this.networkMain.DNSSeeds.Count);
            Assert.Equal(512, this.networkMain.SeedNodes.Count);

            Assert.Equal(NetworkRegistration.GetNetwork("main"), this.networkMain);
            Assert.Equal(NetworkRegistration.GetNetwork("mainnet"), this.networkMain);

            Assert.Equal("Main", this.networkMain.Name);
            Assert.Equal(BitcoinMain.BitcoinRootFolderName, this.networkMain.RootFolderName);
            Assert.Equal(BitcoinMain.BitcoinDefaultConfigFilename, this.networkMain.DefaultConfigFilename);
            Assert.Equal(0xD9B4BEF9, this.networkMain.Magic);
            Assert.Equal(8333, this.networkMain.DefaultPort);
            Assert.Equal(8332, this.networkMain.DefaultRPCPort);
            Assert.Equal(BitcoinMain.BitcoinMaxTimeOffsetSeconds, this.networkMain.MaxTimeOffsetSeconds);
            Assert.Equal(BitcoinMain.BitcoinDefaultMaxTipAgeInSeconds, this.networkMain.MaxTipAge);
            Assert.Equal(1000, this.networkMain.MinTxFee);
            Assert.Equal(20000, this.networkMain.FallbackFee);
            Assert.Equal(1000, this.networkMain.MinRelayTxFee);
            Assert.Equal("BTC", this.networkMain.CoinTicker);

            Assert.Equal(2, this.networkMain.Bech32Encoders.Length);
            Assert.Equal(new Bech32Encoder("bc").ToString(), this.networkMain.Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS].ToString());
            Assert.Equal(new Bech32Encoder("bc").ToString(), this.networkMain.Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS].ToString());

            Assert.Equal(12, this.networkMain.Base58Prefixes.Length);
            Assert.Equal(new byte[] { 0 }, this.networkMain.Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS]);
            Assert.Equal(new byte[] { (5) }, this.networkMain.Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS]);
            Assert.Equal(new byte[] { (128) }, this.networkMain.Base58Prefixes[(int)Base58Type.SECRET_KEY]);
            Assert.Equal(new byte[] { 0x01, 0x42 }, this.networkMain.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_NO_EC]);
            Assert.Equal(new byte[] { 0x01, 0x43 }, this.networkMain.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_EC]);
            Assert.Equal(new byte[] { (0x04), (0x88), (0xB2), (0x1E) }, this.networkMain.Base58Prefixes[(int)Base58Type.EXT_PUBLIC_KEY]);
            Assert.Equal(new byte[] { (0x04), (0x88), (0xAD), (0xE4) }, this.networkMain.Base58Prefixes[(int)Base58Type.EXT_SECRET_KEY]);
            Assert.Equal(new byte[] { 0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2 }, this.networkMain.Base58Prefixes[(int)Base58Type.PASSPHRASE_CODE]);
            Assert.Equal(new byte[] { 0x64, 0x3B, 0xF6, 0xA8, 0x9A }, this.networkMain.Base58Prefixes[(int)Base58Type.CONFIRMATION_CODE]);
            Assert.Equal(new byte[] { 0x2a }, this.networkMain.Base58Prefixes[(int)Base58Type.STEALTH_ADDRESS]);
            Assert.Equal(new byte[] { 23 }, this.networkMain.Base58Prefixes[(int)Base58Type.ASSET_ID]);
            Assert.Equal(new byte[] { 0x13 }, this.networkMain.Base58Prefixes[(int)Base58Type.COLORED_ADDRESS]);

            Assert.Equal(210000, this.networkMain.Consensus.SubsidyHalvingInterval);
            Assert.Equal(750, this.networkMain.Consensus.MajorityEnforceBlockUpgrade);
            Assert.Equal(950, this.networkMain.Consensus.MajorityRejectBlockOutdated);
            Assert.Equal(1000, this.networkMain.Consensus.MajorityWindow);
            Assert.Equal(227931, this.networkMain.Consensus.BuriedDeployments[BuriedDeployments.BIP34]);
            Assert.Equal(388381, this.networkMain.Consensus.BuriedDeployments[BuriedDeployments.BIP65]);
            Assert.Equal(363725, this.networkMain.Consensus.BuriedDeployments[BuriedDeployments.BIP66]);
            Assert.Equal(new uint256("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"), this.networkMain.Consensus.BIP34Hash);
            Assert.Equal(new Target(new uint256("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), this.networkMain.Consensus.PowLimit);
            Assert.Equal(new uint256("0x0000000000000000000000000000000000000000002cb971dd56d1c583c20f90"), this.networkMain.Consensus.MinimumChainWork);
            Assert.Equal(TimeSpan.FromSeconds(14 * 24 * 60 * 60), this.networkMain.Consensus.PowTargetTimespan);
            Assert.Equal(TimeSpan.FromSeconds(10 * 60), this.networkMain.Consensus.TargetSpacing);
            Assert.False(this.networkMain.Consensus.PowAllowMinDifficultyBlocks);
            Assert.False(this.networkMain.Consensus.PowNoRetargeting);
            Assert.Equal(2016, this.networkMain.Consensus.MinerConfirmationWindow);
            Assert.Equal(28, this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.TestDummy].Bit);
            Assert.Equal(Utils.UnixTimeToDateTime(1199145601), this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.TestDummy].StartTime);
            Assert.Equal(Utils.UnixTimeToDateTime(1230767999), this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.TestDummy].Timeout);
            Assert.Equal(0, this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.CSV].Bit);
            Assert.Equal(Utils.UnixTimeToDateTime(1462060800), this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.CSV].StartTime);
            Assert.Equal(Utils.UnixTimeToDateTime(1493596800), this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.CSV].Timeout);
            Assert.Equal(1, this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.Segwit].Bit);
            Assert.Equal(Utils.UnixTimeToDateTime(1479168000), this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.Segwit].StartTime);
            Assert.Equal(Utils.UnixTimeToDateTime(1510704000), this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.Segwit].Timeout);
            Assert.Equal(0, this.networkMain.Consensus.CoinType);
            Assert.False(this.networkMain.Consensus.IsProofOfStake);
            Assert.Equal(new uint256("0x0000000000000000000f1c54590ee18d15ec70e68c8cd4cfbadb1b4f11697eee"), this.networkMain.Consensus.DefaultAssumeValid);
            Assert.Equal(100, this.networkMain.Consensus.CoinbaseMaturity);
            Assert.Equal(0, this.networkMain.Consensus.PremineReward);
            Assert.Equal(0, this.networkMain.Consensus.PremineHeight);
            Assert.Equal(Money.Coins(50), this.networkMain.Consensus.ProofOfWorkReward);
            Assert.Equal(Money.Zero, this.networkMain.Consensus.ProofOfStakeReward);
            Assert.Equal((uint)0, this.networkMain.Consensus.MaxReorgLength);
            Assert.Equal(21000000 * Money.COIN, this.networkMain.Consensus.MaxMoney);

            Block genesis = this.networkMain.GetGenesis();

            Assert.Equal(uint256.Parse("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"), genesis.GetHash());
            Assert.Equal(uint256.Parse("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"), genesis.Header.HashMerkleRoot);
        }
 public StratisSmartContractPosNode(string dataDir)
     : base(dataDir)
 {
     this.Network = NetworkRegistration.Register(new SmartContractPosRegTest());
 }
        /// <summary> Prints the help information on how to configure the rpc settings to the logger.</summary>
        /// <param name="network">The network to use.</param>
        public static void PrintHelp(Network network)
        {
            NodeSettings defaults = NodeSettings.Default();
            var          builder  = new StringBuilder();

            builder.AppendLine($"-server=<0 or 1>          Accept command line and JSON-RPC commands. Default false.");
            builder.AppendLine($"-rpcuser=<string>         Username for JSON-RPC connections");
            builder.AppendLine($"-rpcpassword=<string>     Password for JSON-RPC connections");
            builder.AppendLine($"-rpcport=<0-65535>        Listen for JSON-RPC connections on <port>. Default: {network.RPCPort} or (reg)testnet: {NetworkRegistration.Register(new BitcoinTest()).RPCPort}");
            builder.AppendLine($"-rpcbind=<ip:port>        Bind to given address to listen for JSON-RPC connections. This option can be specified multiple times. Default: bind to all interfaces");
            builder.AppendLine($"-rpcallowip=<ip>          Allow JSON-RPC connections from specified source. This option can be specified multiple times.");

            defaults.Logger.LogInformation(builder.ToString());
        }
Exemple #27
0
        /// <summary>
        /// City.Chain daemon can be launched with options to specify coin and network, using the parameters -chain and -testnet. It defaults to City main network.
        /// </summary>
        /// <example>
        /// dotnet city.chain.dll -coin bitcoin -network regtest
        /// dotnet city.chain.dll -coin city -network test
        /// </example>
        /// <param name="args"></param>
        /// <returns></returns>
        public static async Task Main(string[] args)
        {
            try
            {
                // Temporary enforce testnet if anyone launces without -testnet parameter. TODO: Remove before mainnet launch.
                args = args.Append("-testnet").ToArray();

                // To avoid modifying Stratis source, we'll parse the arguments and set some hard-coded defaults for City Chain, like the ports.
                var configReader = new TextFileConfiguration(args ?? new string[] { });

                var networkIdentifier = "main";

                if (configReader.GetOrDefault <bool>("testnet", false))
                {
                    networkIdentifier = "testnet";
                }
                else if (configReader.GetOrDefault <bool>("regtest", false))
                {
                    networkIdentifier = "regtest";
                }

                // City Chain daemon supports multiple networks, supply the chain parameter to change it.
                // Example: -chain=bitcoin
                var chain = configReader.GetOrDefault <string>("chain", "city");

                var networkConfiguration = new NetworkConfigurations().GetNetwork(networkIdentifier, chain);

                if (networkConfiguration == null)
                {
                    throw new ArgumentException($"The supplied chain ({chain}) and network ({networkIdentifier}) parameters did not result in a valid network.");
                }

                var network = GetNetwork(networkConfiguration.Identifier, networkConfiguration.Chain);

                // Register the network found.
                NetworkRegistration.Register(network);

                if (args.Contains("-generate"))
                {
                    GenerateAddressKeyPair(network);
                    return;
                }

                args = args
                       .Append("-apiport=" + networkConfiguration.ApiPort)
                       .Append("-txindex=1") // Required for History (Block) explorer.
                       .Append("-wsport=" + networkConfiguration.WsPort).ToArray();

                var nodeSettings = new NodeSettings(
                    args: args,
                    protocolVersion: ProtocolVersion.ALT_PROTOCOL_VERSION,
                    network: network,
                    agent: "CityChain");

                // Write the schema version, if not already exists.
                var infoPath = System.IO.Path.Combine(nodeSettings.DataDir, "city.info");

                if (!System.IO.File.Exists(infoPath))
                {
                    // For clients earlier than this version, the database already existed so we'll
                    // write that it is currently version 100.
                    var infoBuilder = new System.Text.StringBuilder();

                    // If the chain exists from before, but we did not have .info file, the database is old version.
                    if (System.IO.Directory.Exists(Path.Combine(nodeSettings.DataDir, "chain")))
                    {
                        infoBuilder.AppendLine("dbversion=100");
                    }
                    else
                    {
                        infoBuilder.AppendLine("dbversion=110");
                    }

                    File.WriteAllText(infoPath, infoBuilder.ToString());
                }
                else
                {
                    var fileConfig = new TextFileConfiguration(File.ReadAllText(infoPath));
                    var dbversion  = fileConfig.GetOrDefault <int>("dbversion", 110);
                }

                IFullNode node = new FullNodeBuilder()
                                 .UseNodeSettings(nodeSettings)
                                 .UseBlockStore()
                                 .UsePosConsensus()
                                 .UseMempool()
                                 .UseWallet()
                                 .AddPowPosMining()
                                 //.UseBlockNotification()
                                 //.UseTransactionNotification()
                                 //.AddSimpleWallet()
                                 .UseApi()
                                 //.UseApps()
                                 //.UseDns()
                                 .AddRPC()
                                 .Build();

                if (node != null)
                {
                    await node.RunAsync();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("There was a problem initializing the node. Details: '{0}'", ex.Message);
            }
        }
Exemple #28
0
        public static async Task Main(string[] args)
        {
            try
            {
                Network network = args.Contains("-testnet")
                    ? NetworkRegistration.Register(new RedstoneTest())
                    : args.Contains("-regnet")
                    ? NetworkRegistration.Register(new RedstoneRegTest())
                    : NetworkRegistration.Register(new RedstoneMain());

                var nodeSettings = new NodeSettings(network: network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, args: args.Concat(new[] { "-txIndex=1", "-addressIndex=1" }).ToArray())
                {
                    MinProtocolVersion = ProtocolVersion.ALT_PROTOCOL_VERSION
                };

                bool keyGenerationRequired = RequiresKeyGeneration(nodeSettings);
                if (keyGenerationRequired)
                {
                    GenerateServiceNodeKey(nodeSettings);
                    return;
                }

                var dnsSettings = new DnsSettings(nodeSettings);

                var isDns = !string.IsNullOrWhiteSpace(dnsSettings.DnsHostName) &&
                            !string.IsNullOrWhiteSpace(dnsSettings.DnsNameServer) &&
                            !string.IsNullOrWhiteSpace(dnsSettings.DnsMailBox);

                var builder = new FullNodeBuilder()
                              .UseNodeSettings(nodeSettings);

                if (isDns)
                {
                    // Run as a full node with DNS or just a DNS service?
                    if (dnsSettings.DnsFullNode)
                    {
                        builder = builder
                                  .UseBlockStore()
                                  .UseRedstonePosConsensus()
                                  .UseMempool()
                                  .UseWallet()
                                  .AddRedstoneMining();
                    }
                    else
                    {
                        builder = builder.UsePosConsensus();
                    }

                    builder = builder
                              .UseApi()
                              .AddRPC()
                              .UseDns();
                }
                else
                {
                    builder = builder
                              .UseBlockStore()
                              .UseRedstonePosConsensus()
                              .UseMempool()
                              .UseColdStakingWallet()
                              .AddRedstoneMining()
                              .UseApi()
                              .UseWatchOnlyWallet()
                              .UseBlockNotification()
                              .UseTransactionNotification()
                              .AddServiceNodeRegistration()
                              .UseApps()
                              .UseBlockExplorer()
                              .AddRPC();
                }

                var node = builder.Build();

                if (node != null)
                {
                    await node.RunAsync();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("There was a problem initializing the node. Details: '{0}'", ex.ToString());
            }
        }
Exemple #29
0
        public void SendAndReceiveSmartContractTransactions()
        {
            NetworkRegistration.Register(new SmartContractsRegTest());

            using (SmartContractNodeBuilder builder = SmartContractNodeBuilder.Create(this))
            {
                CoreNode scSender   = builder.CreateSmartContractPowNode().WithWallet().Start();
                CoreNode scReceiver = builder.CreateSmartContractPowNode().WithWallet().Start();

                var callDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializer(scSender.FullNode.Network));

                var       maturity      = (int)scSender.FullNode.Network.Consensus.CoinbaseMaturity;
                HdAddress senderAddress = TestHelper.MineBlocks(scSender, maturity + 5).AddressUsed;

                // The mining should add coins to the wallet.
                int spendableBlocks = GetSpendableBlocks(maturity + 5, maturity);
                var total           = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount);
                Assert.Equal(Money.COIN * spendableBlocks * 50, total);

                // Create a token contract.
                ulong gasPrice  = SmartContractMempoolValidator.MinGasPrice;
                int   vmVersion = 1;
                Gas   gasLimit  = (Gas)(SmartContractFormatRule.GasLimitMaximum / 2);
                ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/TransferTest.cs");
                Assert.True(compilationResult.Success);

                var contractTxData = new ContractTxData(vmVersion, gasPrice, gasLimit, compilationResult.Compilation);

                var contractCreateScript = new Script(callDataSerializer.Serialize(contractTxData));
                var txBuildContext       = new TransactionBuildContext(scSender.FullNode.Network)
                {
                    AccountReference = new WalletAccountReference(WalletName, AccountName),
                    MinConfirmations = maturity,
                    TransactionFee   = new Money(1, MoneyUnit.BTC),
                    FeeType          = FeeType.High,
                    WalletPassword   = Password,
                    Recipients       = new[] { new Recipient {
                                                   Amount = 0, ScriptPubKey = contractCreateScript
                                               } }.ToList()
                };

                Transaction transferContractTransaction = (scSender.FullNode.NodeService <IWalletTransactionHandler>() as SmartContractWalletTransactionHandler).BuildTransaction(txBuildContext);

                // Broadcast the token transaction to the network.
                scSender.FullNode.NodeService <IBroadcasterManager>().BroadcastTransactionAsync(transferContractTransaction);

                // Wait for the token transaction to be picked up by the mempool.
                TestHelper.WaitLoop(() => scSender.CreateRPCClient().GetRawMempool().Length > 0);

                // Mine the token transaction and wait for it to sync.
                TestHelper.MineBlocks(scSender, 1);

                // Sync to the receiver node.
                TestHelper.ConnectAndSync(scSender, scReceiver);

                // Ensure that both nodes have the contract.
                IStateRepositoryRoot senderState      = scSender.FullNode.NodeService <IStateRepositoryRoot>();
                IStateRepositoryRoot receiverState    = scReceiver.FullNode.NodeService <IStateRepositoryRoot>();
                IAddressGenerator    addressGenerator = scSender.FullNode.NodeService <IAddressGenerator>();

                uint160 tokenContractAddress = addressGenerator.GenerateAddress(transferContractTransaction.GetHash(), 0);
                Assert.NotNull(senderState.GetCode(tokenContractAddress));
                Assert.NotNull(receiverState.GetCode(tokenContractAddress));
                scSender.FullNode.MempoolManager().Clear();

                // Create a transfer token contract.
                compilationResult = ContractCompiler.CompileFile("SmartContracts/TransferTest.cs");
                Assert.True(compilationResult.Success);
                contractTxData       = new ContractTxData(vmVersion, gasPrice, gasLimit, compilationResult.Compilation);
                contractCreateScript = new Script(callDataSerializer.Serialize(contractTxData));
                txBuildContext       = new TransactionBuildContext(scSender.FullNode.Network)
                {
                    AccountReference = new WalletAccountReference(WalletName, AccountName),
                    MinConfirmations = maturity,
                    TransactionFee   = new Money(1, MoneyUnit.BTC),
                    FeeType          = FeeType.High,
                    WalletPassword   = Password,
                    Recipients       = new[] { new Recipient {
                                                   Amount = 0, ScriptPubKey = contractCreateScript
                                               } }.ToList()
                };

                // Broadcast the token transaction to the network.
                transferContractTransaction = (scSender.FullNode.NodeService <IWalletTransactionHandler>() as SmartContractWalletTransactionHandler).BuildTransaction(txBuildContext);
                scSender.FullNode.NodeService <IBroadcasterManager>().BroadcastTransactionAsync(transferContractTransaction);

                // Wait for the token transaction to be picked up by the mempool.
                TestHelper.WaitLoop(() => scSender.CreateRPCClient().GetRawMempool().Length > 0);
                TestHelper.MineBlocks(scSender, 1);

                // Ensure both nodes are synced with each other.
                TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender));

                // Ensure that both nodes have the contract.
                senderState          = scSender.FullNode.NodeService <IStateRepositoryRoot>();
                receiverState        = scReceiver.FullNode.NodeService <IStateRepositoryRoot>();
                tokenContractAddress = addressGenerator.GenerateAddress(transferContractTransaction.GetHash(), 0);
                Assert.NotNull(senderState.GetCode(tokenContractAddress));
                Assert.NotNull(receiverState.GetCode(tokenContractAddress));
                scSender.FullNode.MempoolManager().Clear();

                // Create a call contract transaction which will transfer funds.
                contractTxData = new ContractTxData(1, gasPrice, gasLimit, tokenContractAddress, "Test");
                Script contractCallScript = new Script(callDataSerializer.Serialize(contractTxData));
                txBuildContext = new TransactionBuildContext(scSender.FullNode.Network)
                {
                    AccountReference = new WalletAccountReference(WalletName, AccountName),
                    MinConfirmations = maturity,
                    TransactionFee   = new Money(1, MoneyUnit.BTC),
                    FeeType          = FeeType.High,
                    WalletPassword   = Password,
                    Recipients       = new[] { new Recipient {
                                                   Amount = 1000, ScriptPubKey = contractCallScript
                                               } }.ToList()
                };

                // Broadcast the token transaction to the network.
                transferContractTransaction = (scSender.FullNode.NodeService <IWalletTransactionHandler>() as SmartContractWalletTransactionHandler).BuildTransaction(txBuildContext);
                scSender.FullNode.NodeService <IBroadcasterManager>().BroadcastTransactionAsync(transferContractTransaction);
                TestHelper.WaitLoop(() => scSender.CreateRPCClient().GetRawMempool().Length > 0);

                // Mine the transaction.
                TestHelper.MineBlocks(scSender, 1);

                // Ensure the nodes are synced
                TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender));

                // The balance should now reflect the transfer.
                Assert.Equal((ulong)900, senderState.GetCurrentBalance(tokenContractAddress));
            }
        }
 public NodeSyncTests()
 {
     this.posNetwork = NetworkRegistration.Register(new StratisRegTestMaxReorg());
     this.powNetwork = KnownNetworks.RegTest;
 }