Пример #1
0
        public bool Connect(int Timeout)
        {
            if (Program.DEBUG)
            {
                CIO.DebugOut("Connecting to " + mIp + ":" + mPort);
            }
            SocketAsyncEventArgs asyncConnection = new SocketAsyncEventArgs();
            bool SuccessfulConnected             = false;

            asyncConnection.Completed     += (object sender, SocketAsyncEventArgs e) => { SuccessfulConnected = true; };
            asyncConnection.RemoteEndPoint = new IPEndPoint(mIp, mPort);
            mSocket.ConnectAsync(asyncConnection);
            Thread.Sleep(Timeout);
            if (SuccessfulConnected)
            {
                if (Program.DEBUG)
                {
                    CIO.DebugOut("Connection with " + mIp + ":" + mPort + " enstablished!");
                }
                mIsConnected = true;
                StartListening();
                return(true);
            }
            else
            {
                if (Program.DEBUG)
                {
                    CIO.DebugOut("Connection with " + mIp + ":" + mPort + " failed!");
                }
                mSocket.Close();
                mSocket.Dispose();
                asyncConnection.Dispose();
                return(false);
            }
        }
Пример #2
0
        /// <summary>
        /// Aggiunge il proof of work(l'hash) al blocco.
        /// </summary>
        /// <param name="Block">Blocco su cui calcolare il proof of work.</param>
        public static void AddProof(CBlock Block) //TODO: implementare evento per l'uscita in caso sia stato trovato un blocco parallelo. Implementare multithreading
        {
            string hash  = "";
            bool   found = false;

            while (!found)
            {
                Block.Timestamp = DateTime.Now;
                Block.Nonce++;            //incremento della nonce per cambiare hash
                hash  = HashBlock(Block); //calcola l'hash secondo il template di scrypt usato da litecoin
                found = true;
                for (int i = 0; i < Block.Difficulty && found; i++)
                {
                    if (hash[i] != '0')
                    {
                        found = false;
                    }
                }
            }
            if (Program.DEBUG)
            {
                CIO.DebugOut("Found hash for block " + Block.Header.BlockNumber + ": " + hash);
            }
            Block.Header.Hash = hash;
        }
Пример #3
0
 private void SendString(string Msg)
 {
     SendData(ASCIIEncoding.ASCII.GetBytes(Msg));
     if (Program.DEBUG)
     {
         CIO.DebugOut("Sent string " + Msg + ".");
     }
 }
Пример #4
0
 //sincronizza la blockchain
 public void SyncBlockchain()
 {
     if (Program.DEBUG)
     {
         CIO.DebugOut("Start update blockchain...");
     }
     mThreadSyncBlockChain      = new Thread(new ThreadStart(UpdateBlockchain));
     mThreadSyncBlockChain.Name = "SyncBlockchain";
     mThreadSyncBlockChain.Start();
 }
Пример #5
0
        private string ReceiveString()
        {
            string msg = ASCIIEncoding.ASCII.GetString(Receive());

            if (Program.DEBUG)
            {
                CIO.DebugOut("Received string " + msg + ".");
            }
            return(msg);
        }
Пример #6
0
        //attende il collegamento di nuovi peer
        private void StartAcceptUsersConnection()
        {
            if (Program.DEBUG)
            {
                CIO.DebugOut("Initialize the Listener...");
            }
            //crea un socket che attende connessioni in ingresso di peer che vogliono collegarsi, in ascolto sulla porta DEFOULT_PORT
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, DEFAULT_PORT);

            mListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            mListener.Bind(localEndPoint);
            mListener.Listen(DEFAULT_PORT);

            //crea un eventargs per una richiesta di connessione asincrona, se la lista dei peers non è ancora piena inizia ad attendere fino a quando non riceve
            //una richiesta di connessione o il segnale d'arresto. Se viene ricevuta una richiesta di connessione viene chiamata la funzione InsertNewPeer che
            //inserisce il nuovo peer nella lista dei peer mPeers

            //è asincrono perchè altrimenti al segnale di spegnimento non si fermerebbe
            SocketAsyncEventArgs asyncConnection;
            bool IncomingConnection = false;

            if (Program.DEBUG)
            {
                CIO.DebugOut("Attending connection...");
            }
            while (!IsStopped)
            {
                if (ConnectedPeers < MAX_PEERS)
                {
                    IncomingConnection         = false;
                    asyncConnection            = new SocketAsyncEventArgs();
                    asyncConnection.Completed += (object sender, SocketAsyncEventArgs e) => { IncomingConnection = true; };
                    mListener.AcceptAsync(asyncConnection);
                    while (!IncomingConnection && !IsStopped)
                    {
                        Thread.Sleep(1000);
                    }
                    if (IncomingConnection)
                    {
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("Established connection with " + ((IPEndPoint)asyncConnection.AcceptSocket.RemoteEndPoint).Address + " !");
                        }
                        InsertNewPeer(asyncConnection.AcceptSocket);
                    }
                    asyncConnection.Dispose();
                }
                else
                {
                    Thread.Sleep(10000);
                }
            }
        }
Пример #7
0
 //avvia il thread del miner
 public void StartMining()
 {
     if (mThreadMiner == null)
     {
         if (Program.DEBUG)
         {
             CIO.DebugOut("Start Miner...");
         }
         mThreadMiner      = new Thread(new ThreadStart(StartMiner));
         mThreadMiner.Name = "Miner";
         mThreadMiner.Start();
     }
 }
Пример #8
0
        private void UpdatePeers()
        {
            int id;

            string[] listsPeer;
            string[] peers;
            string   msg = "";
            string   ris = "";
            CPeer    receivedPeer;

            foreach (CPeer p in Peers)
            {
                try
                {
                    id   = p.SendRequest(new CMessage(EMessageType.Request, ERequestType.UpdPeers));
                    msg  = p.ReceiveData(id, 5000).Data;
                    ris += msg + "/";
                }
                catch
                {
                    if (Program.DEBUG)
                    {
                        CIO.DebugOut("Nessuna risposta da " + p.IP + " durante la richiesta dei peer." +
                                     "Disconnessione da " + p.IP);
                    }
                    p.Disconnect();
                }
            }

            ris = ris.TrimEnd('/');

            if (ris != "")
            {
                string publicIp = CServer.GetPublicIPAddress();
                string localIp  = CServer.GetLocalIPAddress();
                listsPeer = ris.Split('/');
                foreach (string l in listsPeer)
                {
                    peers = l.Split(';');
                    foreach (string rp in peers)
                    {
                        receivedPeer = CPeer.Deserialize(rp);
                        if (!(receivedPeer.IP == publicIp || receivedPeer.IP == localIp))
                        {
                            Insert(receivedPeer);
                        }
                    }
                }
            }
        }
Пример #9
0
 public static string GetPublicIPAddress()
 {
     try
     {
         if (mPublicIp == "")
         {
             mPublicIp = new WebClient().DownloadString("http://icanhazip.com");
         }
         return(mPublicIp.Trim('\n'));
     }
     catch
     {
         if (Program.DEBUG)
         {
             CIO.DebugOut("Error: can't get public ip.");
         }
         return("");
     }
 }
Пример #10
0
        private bool IsStopped = false; //set true per fermare il server

        private CServer()
        {
            rsaKeyPair = RSA.GenRSAKey();                 // crea oggetto CSP per generare o caricare il keypair

            if (File.Exists(RSA.PATH + "\\keystore.xml")) // Se il file di keystore esiste viene caricato in memoria dal disco, altrimenti viene creato e salvato su disco
            {
                string xmlString = File.ReadAllText(RSA.PATH + "\\keystore.xml");
                rsaKeyPair.FromXmlString(xmlString);
            }
            else//se il file non esiste ne viene generato uno
            {
                string xmlString = rsaKeyPair.ToXmlString(true);
                File.WriteAllText(RSA.PATH + "\\keystore.xml", xmlString);
            }

            if (Program.DEBUG)
            {
                CIO.DebugOut("Last block number: " + CBlockChain.Instance.LastValidBlock.Header.BlockNumber + ".");
            }
        }
Пример #11
0
        public void InitializePeersList(List <CPeer> peers)
        {
            if (Program.DEBUG)
            {
                CIO.DebugOut("Initialize mPeers...");
            }
            mPeers = new CPeers(MAX_PEERS, RESERVED_CONNECTION);
            if (Program.DEBUG)
            {
                CIO.DebugOut("Begin to enstablish connections to initial peers...");
            }
            //si collega ai peer inseriti nella lista iniziale.
            foreach (CPeer p in peers)
            {
                if (p.Connect(500))
                {
                    if (!mPeers.Insert(p))
                    {
                        break;
                    }
                }
            }

            if (Program.DEBUG)
            {
                CIO.DebugOut("Begin to enstablish connections to other peers...");
            }
            mThreadUpdatePeers      = new Thread(new ThreadStart(UpdatePeersList));
            mThreadUpdatePeers.Name = "mUpdatePeers";
            mThreadUpdatePeers.Start();

            if (Program.DEBUG)
            {
                CIO.DebugOut("Start listening...");
            }
            mThreadListener      = new Thread(new ThreadStart(StartAcceptUsersConnection));
            mThreadListener.Name = "Listener";
            mThreadListener.Start();
        }
Пример #12
0
        public static short CalculateDifficulty()
        {
            int numberOfBlocks = 300;

            CBlock lastBlock = CBlockChain.Instance.LastBlock;
            CBlock previousBlock;
            short  newBlockDifficulty = 0;
            ulong  highAverangeTimeLimit = 70, lowAverangeTimeLimit = 30;
            ulong  averangeBlockTime = 0;

            if (lastBlock.Header.BlockNumber > (ulong)numberOfBlocks)
            {
                previousBlock = CBlockChain.Instance.RetriveBlock(lastBlock.Header.BlockNumber - (ulong)numberOfBlocks, true);
            }
            else
            {
                previousBlock = CBlockChain.Instance.RetriveBlock(1, true);
            }

            if (previousBlock != null)
            {
                averangeBlockTime = CBlockChain.Instance.AverageBlockTime(previousBlock, lastBlock); //in secondi
            }
            else
            {
                averangeBlockTime = 60;
            }


            if (averangeBlockTime > highAverangeTimeLimit)
            {
                newBlockDifficulty = (short)(lastBlock.Difficulty - 1);
                if (newBlockDifficulty <= 0)
                {
                    newBlockDifficulty = 1;
                }
                if (Program.DEBUG)
                {
                    CIO.DebugOut("La nuova difficoltà è: " + newBlockDifficulty);
                    //Thread.Sleep(1000);
                }
            }
            else if (averangeBlockTime < lowAverangeTimeLimit)
            {
                newBlockDifficulty = (short)(lastBlock.Difficulty + 1);


                if (newBlockDifficulty >= 4)
                {
                    newBlockDifficulty = 4;
                }


                if (Program.DEBUG)
                {
                    CIO.DebugOut("La nuova difficoltà è: " + newBlockDifficulty);
                    //Thread.Sleep(1000);
                }
            }
            else
            {
                newBlockDifficulty = (short)lastBlock.Difficulty;
                if (Program.DEBUG)
                {
                    CIO.DebugOut("La nuova difficoltà è: " + newBlockDifficulty);
                    //Thread.Sleep(1000);
                }
            }
            return(3);
        }
Пример #13
0
        static void Main(string[] args)
        {
            //Apre il canale di comunicazione per GUI https://github.com/Kojee/BlockChainGUI
            OpenWCFServices();

            //List<CPeer> lp = GenPeersList();
            List <CPeer> lp = new List <CPeer>();

            CIO.WriteLine("Enter the peer address:");
            string firstPeerIP = Console.ReadLine();

            try
            {
                if (!IPAddress.TryParse(firstPeerIP, out var IP))
                {
                    firstPeerIP = "192.168.1.1";
                }
            }
            catch
            {
                firstPeerIP = "192.168.1.1";
            }
            lp.Add(CPeer.CreatePeer(firstPeerIP, 4000));


            CServer.Instance.InitializePeersList(lp);
            Services cmd = new Services();
            bool     b   = true;

            while (b)
            {
                string command = Console.ReadLine().ToLower();
                switch (command)
                {
                case "transaction":
                {
                    CIO.WriteLine("Enter destination address:");
                    string hashReceiver = Console.ReadLine();
                    CIO.WriteLine("Enter the amout of coins to send:");
                    double      amount = Convert.ToDouble(Console.ReadLine());
                    Transaction tx     = new Transaction(amount, hashReceiver, CServer.rsaKeyPair);
                    break;
                }

                case "miner":
                {
                    CServer.Instance.StartMining();
                    break;
                }

                case "sync":
                {
                    CServer.Instance.SyncBlockchain();
                    break;
                }

                case "address":
                {
                    CIO.WriteLine(cmd.GetKeystore());
                    break;
                }

                case "balance":
                {
                    CIO.WriteLine(cmd.GetBalance().ToString());
                    break;
                }

                case "stop":
                {
                    b = false;
                    Environment.Exit(1);
                    break;
                }

                default:
                {
                    CIO.WriteLine("Invalid command.");
                    break;
                }
                }
            }
        }
Пример #14
0
        private void UpdateBlockchain()
        {
            bool  isSynced    = false;
            ulong addedBlocks = 0;

            CTemporaryBlock[] DownloadedBlock;
            CTemporaryBlock[] newBlocks;
            CHeaderChain[]    forkChains;
            CHeaderChain      bestChain;
            CBlock            lastCommonBlock;
            CTemporaryBlock   otherLastValidBlock;

            lastCommonBlock     = mPeers.DoRequest(ERequest.LastCommonValidBlock) as CBlock;    //trova l'utlimo blocco comune tra i peers
            otherLastValidBlock = mPeers.DoRequest(ERequest.LastValidBlock) as CTemporaryBlock; //trova l'ultimo blocco valido tra i peer

            if (Program.DEBUG)
            {
                if (otherLastValidBlock != null)
                {
                    CIO.DebugOut("Il numero di blocco di otherLastValidBlock è " + otherLastValidBlock.Header.BlockNumber + ".");
                }
                else
                {
                    CIO.DebugOut("Nessun otherLastValidBlock ricevuto.");
                }
            }

            if (CBlockChain.Instance.LastValidBlock.Header.BlockNumber < otherLastValidBlock?.Header.BlockNumber)
            {
                isSynced = false;
            }
            else if (otherLastValidBlock != null && CBlockChain.Instance.RetriveBlock(otherLastValidBlock.Header.BlockNumber).Header.Hash == otherLastValidBlock.Header.Hash)
            {
                isSynced = true;
            }
            else if (otherLastValidBlock != null)
            {
                isSynced = true;
                otherLastValidBlock.Sender.Disconnect();
            }
            else
            {
                isSynced = true;
            }


            //TODO potrebbero dover essere scaricati un numero maggiore di MAXINT blocchi
            while (!isSynced)
            {
                newBlocks = mPeers.DoRequest(ERequest.DownloadMissingBlock, new object[] { CBlockChain.Instance.LastValidBlock.Header.BlockNumber + 1, lastCommonBlock.Header.BlockNumber + 1 }) as CTemporaryBlock[];

                /*foreach (CTemporaryBlock block in newBlocks)
                 * {
                 *  UTXOManager.Instance.ApplyBlock(block);
                 * }*/
                CBlockChain.Instance.Add(newBlocks);
                forkChains = mPeers.DoRequest(ERequest.FindParallelChain, lastCommonBlock) as CHeaderChain[];
                if (forkChains.Length > 0)
                {
                    foreach (CHeaderChain hc in forkChains)
                    {
                        hc.DownloadHeaders();
                    }
                    bestChain = CBlockChain.Instance.BestChain(forkChains);
                    if (CValidator.ValidateHeaderChain(bestChain))
                    {
                        DownloadedBlock = CPeers.Instance.DistribuiteDownloadBlocks(bestChain.InitialIndex + 1, bestChain.FinalIndex);

                        /*foreach(CTemporaryBlock block in DownloadedBlock)
                         * {
                         *  UTXOManager.Instance.ApplyBlock(block);
                         * }*/
                        mPeers.ValidPeers(bestChain.Peers);
                        addedBlocks = CBlockChain.Instance.Add(DownloadedBlock);
                        if (addedBlocks >= bestChain.Length)    //solo se scarica tutti i blocchi
                        {
                            isSynced = true;
                        }
                    }
                    else
                    {
                        mPeers.InvalidPeers(bestChain.Peers);
                        otherLastValidBlock = mPeers.DoRequest(ERequest.LastValidBlock) as CTemporaryBlock;
                        lastCommonBlock     = mPeers.DoRequest(ERequest.LastCommonValidBlock) as CTemporaryBlock;
                    }
                }
            }
            if (Program.DEBUG)
            {
                CIO.DebugOut("Sincronizzazione Blockchain terminata!");
            }
            mPeers.CanReceiveBlock = true;
        }
Пример #15
0
        private void ExecuteRequest()
        {
            CMessage rqs;

            while (mIsConnected)
            {
                Thread.Sleep(100);

                if (RequestQueue.Count > 0)
                {
                    rqs = RequestQueue.Dequeue();
                    switch (rqs.RqsType)
                    {
                    case ERequestType.UpdPeers:
                    {
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("UpdPeers received by " + mIp);
                        }
                        //(!) è meglio farsi ritornare la lista e poi usare json?
                        SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.PeersList,
                                                 CPeers.Instance.PeersList(), rqs.ID));
                        break;
                    }

                    case ERequestType.NewBlockMined:
                    {
                        if (CPeers.Instance.CanReceiveBlock)
                        {
                            if (Program.DEBUG)
                            {
                                CIO.DebugOut("NewBlockMined received by " + mIp);
                            }

                            CTemporaryBlock newBlock = new CTemporaryBlock(CBlock.Deserialize(rqs.Data), this);
                            if (!CValidator.ValidateBlock(newBlock) && newBlock.Header.BlockNumber < CBlockChain.Instance.LastValidBlock.Header.BlockNumber)
                            {
                                Disconnect();
                                break;
                            }
                            //TODO scaricare i blocchi mancanti se ne mancano(sono al blocco 10 e mi arriva il blocco 50)
                            if (!CBlockChain.Instance.AddNewMinedBlock(newBlock))
                            {
                                Stack <CTemporaryBlock> blocks = new Stack <CTemporaryBlock>();
                                int ID = 0;
                                blocks.Push(newBlock);
                                for (ulong i = newBlock.Header.BlockNumber - 1; i > CBlockChain.Instance.LastValidBlock.Header.BlockNumber; i--)
                                {
                                    ID = SendRequest(new CMessage(EMessageType.Request, ERequestType.DownloadBlock, EDataType.ULong, Convert.ToString(i)));
                                    blocks.Push(new CTemporaryBlock(JsonConvert.DeserializeObject <CBlock>(ReceiveData(ID, 5000).Data), this));
                                    if (!CValidator.ValidateBlock(blocks.Peek()) && blocks.Peek().Header.BlockNumber < CBlockChain.Instance.LastValidBlock.Header.BlockNumber)
                                    {
                                        Disconnect();
                                        break;
                                    }
                                    if (CBlockChain.Instance.AddNewMinedBlock(blocks.Peek()))
                                    {
                                        blocks.Pop();
                                        for (int j = blocks.Count; j > 0; j--)
                                        {
                                            CBlockChain.Instance.AddNewMinedBlock(blocks.Pop());
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    }

                    case ERequestType.GetLastHeader:
                    {
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("GetLastHeader received by " + mIp);
                        }
                        SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.Header,
                                                 JsonConvert.SerializeObject(CBlockChain.Instance.LastValidBlock.Header), rqs.ID));
                        break;
                    }

                    case ERequestType.ChainLength:
                    {
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("ChainLength received by " + mIp);
                        }
                        SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.ULong,
                                                 Convert.ToString(CBlockChain.Instance.LastValidBlock.Header.BlockNumber), rqs.ID));
                        break;
                    }

                    case ERequestType.GetLastValid:
                    {
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("GetLastValid received by " + mIp);
                        }
                        SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.Block,
                                                 CBlockChain.Instance.LastValidBlock.Serialize(), rqs.ID));
                        break;
                    }

                    case ERequestType.DownloadBlock:
                    {
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("DownloadBlock received by " + mIp);
                        }

                        SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.Block,
                                                 JsonConvert.SerializeObject(CBlockChain.Instance.RetriveBlock(Convert.ToUInt64(rqs.Data), true)), rqs.ID));
                        break;
                    }

                    case ERequestType.DownloadBlocks:
                    {
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("DownloadBlocks received by " + mIp);
                        }

                        SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.BlockList,
                                                 JsonConvert.SerializeObject(CBlockChain.Instance.RetriveBlocks(Convert.ToUInt64(rqs.Data.Split(';')[0]), Convert.ToUInt64(rqs.Data.Split(';')[1]))), rqs.ID));
                        break;
                    }

                    case ERequestType.DownloadHeaders:
                    {
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("DownloadBlocks received by " + mIp);
                        }

                        SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.HeaderList,
                                                 JsonConvert.SerializeObject(CBlockChain.Instance.RetriveHeaders(Convert.ToUInt64(rqs.Data.Split(';')[0]), Convert.ToUInt64(rqs.Data.Split(';')[1]))), rqs.ID));
                        break;
                    }

                    case ERequestType.GetHeader:
                    {
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("GetLastHeader received by " + mIp);
                        }
                        SendRequest(new CMessage(EMessageType.Data, ERequestType.NULL, EDataType.Header,
                                                 JsonConvert.SerializeObject(CBlockChain.Instance.RetriveBlock(Convert.ToUInt64(rqs.Data)).Header), rqs.ID));
                        break;
                    }

                    case ERequestType.NewTransaction:
                    {
                        Transaction t = JsonConvert.DeserializeObject <Transaction>(rqs.Data);
                        if (t.Verify())
                        {
                            MemPool.Instance.AddUTX(t);
                        }
                        break;
                    }

                    default:
                        if (Program.DEBUG)
                        {
                            CIO.DebugOut("Ricevuto comando sconosciuto: " + rqs.RqsType + " da " + IP);
                        }
                        break;
                    }
                }
            }
        }