예제 #1
0
        public void GetAppDataFolder_EmptyStringRelative_ReturnsAppDataFolder()
        {
            var old = Environment.GetEnvironmentVariable("APPDATA");

            const string fakeFolder = @"C:\appdata";

            Environment.SetEnvironmentVariable("APPDATA", fakeFolder);

            var folder = MultiChainTools.GetAppDataFolder("");

            Environment.SetEnvironmentVariable("APPDATA", old);
            Assert.AreEqual(fakeFolder, folder);
        }
예제 #2
0
        public async Task Connect(string hostname, int port, string blockchainName)
        {
            // Only connect to one multichain at a time
            if (Connected)
            {
                throw new Exception("Must disconnect from blockchain before connecting to a new one");
            }

            var localPort = MultiChainTools.GetNewPort(EPortType.ClientMultichainD);
            var rpcPort   = MultiChainTools.GetNewPort(EPortType.ClientRpc);

            _multichain = await _multiChainHandler.Connect(hostname, blockchainName, port, localPort, rpcPort, false);
        }
예제 #3
0
        public void GetAppDataFolder_Relative_ReturnsRelativeAppDataFolder()
        {
            var old = Environment.GetEnvironmentVariable("APPDATA");

            const string fakeFolder    = @"C:\appdata";
            const string fakeSubFolder = "testing";

            Environment.SetEnvironmentVariable("APPDATA", fakeFolder);

            var folder = MultiChainTools.GetAppDataFolder(fakeSubFolder);

            Environment.SetEnvironmentVariable("APPDATA", old);
            Assert.AreEqual(Path.Combine(fakeFolder, fakeSubFolder), folder);
        }
예제 #4
0
        public async Task Create_NotExist_Ok()
        {
            const string bName = "myBlockchain";
            var          dir   = Path.Combine(MultiChainTools.GetAppDataFolder(), bName);

            if (Directory.Exists(dir))
            {
                Directory.Delete(dir, true);
            }

            await MultiChainUtilHandler.CreateBlockchain(bName);

            Assert.IsTrue(Directory.Exists(dir));
        }
예제 #5
0
        public void GetAppDataFolder_NotSet_SystemException()
        {
            var old = Environment.GetEnvironmentVariable("APPDATA");

            try
            {
                Environment.SetEnvironmentVariable("APPDATA", null);
                MultiChainTools.GetAppDataFolder();
            }
            catch
            {
                Environment.SetEnvironmentVariable("APPDATA", old);
                throw;
            }
        }
예제 #6
0
        public static void StartBlockchains()
        {
            var handler         = NinjectWebCommon.Kernel.Get <MultiChainHandler>();
            var blockchainStore = NinjectWebCommon.Kernel.Get <IRegiBlockchainStore>();
            var blockchainsTask = blockchainStore.GetAllBlockchains();

            blockchainsTask.Wait();

            Task.WaitAll(
                blockchainsTask.Result.Select(
                    blockchain =>
                    // We're the host/master node, so local port = remote port
                    handler.Connect(IPAddress.Loopback.ToString(), blockchain.ChainString, blockchain.Port,
                                    blockchain.Port, MultiChainTools.GetNewPort(EPortType.Rpc), false))
                .Cast <Task>()
                .ToArray());
        }
예제 #7
0
        private static void UpdateParams(CreateBlockchain model)
        {
            var p = MultiChainTools.GetBlockchainConfig(model.ChainString);

            p["anyone-can-connect"] = true;
            p["anyone-can-send"]    = true;
            p["anyone-can-receive"] = true;
            p["anyone-can-mine"]    = true;

            p["root-stream-open"] = false;

            // Target block time must be between 5 and 86400 seconds
            if ((model.BlockSpeed >= 5) && (model.BlockSpeed <= 86400))
            {
                p["target-block-time"] = model.BlockSpeed;
            }

            MultiChainTools.WriteBlockchainConfig(model.ChainString, p);
        }
예제 #8
0
        public async Task Create_Exists_Exception()
        {
            const string bName = "myBlockchain";
            var          dir   = Path.Combine(MultiChainTools.GetAppDataFolder(), bName);

            if (Directory.Exists(dir))
            {
                Directory.Delete(dir, true);
            }

            await MultiChainUtilHandler.CreateBlockchain(bName);

            // Attempt to create it again
            try
            {
                await MultiChainUtilHandler.CreateBlockchain(bName);
            }
            catch (CouldNotCreateBlockchainException e)
            {
                Assert.AreEqual("ERROR: Blockchain parameter set was not generated.", e.Message);
            }
        }
예제 #9
0
        public void RandomString_1_Length1()
        {
            var rs = MultiChainTools.RandomString(1);

            Assert.AreEqual(1, rs.Length);
        }
예제 #10
0
        public void RandomString_20_Length20()
        {
            var rs = MultiChainTools.RandomString(20);

            Assert.AreEqual(20, rs.Length);
        }
예제 #11
0
        public async Task <IHttpActionResult> CreateBlockchain(CreateBlockchain model)
        {
            // Must have at least one question
            if ((model.Questions == null) || !model.Questions.Any())
            {
                ModelState.AddModelError("Questions", "At least one question is required");
                return(BadRequest(ModelState));
            }

            // All questions must have at least one answer (although should probably have at least two?)
            if (model.Questions.Any(q => (q.Answers == null) || !q.Answers.Any()))
            {
                ModelState.AddModelError("Questions", "All questions must have at least one answer");
                return(BadRequest(ModelState));
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            // Check we're not going to have a ChainString collision
            try
            {
                await _blockchainStore.GetBlockchainByChainString(model.ChainString);

                return(BadRequest("A Blockchain already exists with the same name as this!"));
            }
            catch (RecordNotFoundException)
            {
                // This is good
            }

            // multichain-util create {model.ChainString}
            await MultiChainUtilHandler.CreateBlockchain(model.ChainString);

            // Find a Port to run multichaind on
            var blockchains = await _blockchainStore.GetAllBlockchains();

            int port;

            while (true)
            {
                port = MultiChainTools.GetNewPort(EPortType.MultichainD);
                if (blockchains.All(b => b.Port != port))
                {
                    break;
                }
            }

            // Update the default multichain.params to adjust permissions etc.
            UpdateParams(model);

            // Run the blockchain for the first time
            var rpcPort = MultiChainTools.GetNewPort(EPortType.MultichainD);
            var chain   =
                await _multichaind.Connect(IPAddress.Loopback.ToString(), model.ChainString, port, port, rpcPort, false);

            // Convert questions. Each has a unique number (per blockchain) starting from 1
            var questionNumber = 1;

            foreach (var q in model.Questions.Select(q => RequestToBlockchainQuestion(q, ref questionNumber)))
            {
                await chain.WriteToStream(MultiChainTools.ROOT_STREAM_NAME, MultiChainTools.QUESTIONS_KEY, q);
            }

            // Create a new wallet ID for votes to be sent to
            var walletId = await chain.GetNewWalletAddress();

            var blockchain = new RegiBlockchain
            {
                Name        = model.Name,
                ExpiryDate  = model.ExpiryDate,
                Info        = model.Info,
                ChainString = model.ChainString,
                WalletId    = walletId,
                Port        = port
            };

            // Encrypt blockchain results
            if (model.Encrypted)
            {
                // Create encryption key TODO: Don't store on disk?
                var key = RsaTools.CreateKeyAndSave(blockchain.ChainString + "-encrypt");
                blockchain.EncryptKey = RsaTools.KeyToString(key.Public);
            }

            // Save blockchain data in store
            await _blockchainStore.CreateBlockchain(blockchain);

            // Create RSA keypair for blind signing
            RsaTools.CreateKeyAndSave(blockchain.ChainString);

            return(Ok());
        }