Esempio n. 1
0
 public void Unlock()
 {
     Debug.Assert(Locked);
     lock (this)
     {
         OwningTransaction = null;
         LinkedListNode <KeyValuePair <Transaction, ManualResetEvent> > node = null;
         if (PendingTransactions.Count > 0)
         {
             node = PendingTransactions.First;
             PendingTransactions.RemoveFirst();
         }
         if (node != null)
         {
             Transaction      transaction = node.Value.Key;
             ManualResetEvent manualEvent = node.Value.Value;
             Lock(transaction);
             lock (manualEvent)
             {
                 if (!manualEvent.SafeWaitHandle.IsClosed)
                 {
                     manualEvent.Set();
                 }
             }
         }
     }
 }
Esempio n. 2
0
        private Block BuildBlock()
        {
            var   lastBlock = BlockChain.Last().Value;
            Block tempBlock = Block.BuildBlockForMiner(lastBlock.Index + 1, PendingTransactions.ToList(), lastBlock.BlockHash, Difficulty);

            return(tempBlock);
        }
Esempio n. 3
0
 public override bool addTransaction(Transaction tx, bool force_broadcast)
 {
     // TODO Send to peer if directly connectable
     CoreProtocolMessage.broadcastProtocolMessage(new char[] { 'M', 'H' }, ProtocolMessageCode.transactionData, tx.getBytes(), null);
     PendingTransactions.addPendingLocalTransaction(tx);
     return(true);
 }
Esempio n. 4
0
        // Broadcasts the solution to the network
        public void sendSolution(byte[] nonce)
        {
            byte[] pubkey = Node.walletStorage.getPrimaryPublicKey();
            // Check if this wallet's public key is already in the WalletState
            Wallet mywallet = Node.walletState.getWallet(Node.walletStorage.getPrimaryAddress());

            if (mywallet.publicKey != null && mywallet.publicKey.SequenceEqual(pubkey))
            {
                // Walletstate public key matches, we don't need to send the public key in the transaction
                pubkey = null;
            }

            byte[] data = null;

            using (MemoryStream mw = new MemoryStream())
            {
                using (BinaryWriter writerw = new BinaryWriter(mw))
                {
                    writerw.Write(activeBlock.blockNum);
                    writerw.Write(Crypto.hashToString(nonce));
                    data = mw.ToArray();
                }
            }

            Transaction tx = new Transaction((int)Transaction.Type.PoWSolution, new IxiNumber(0), new IxiNumber(0), ConsensusConfig.ixianInfiniMineAddress, Node.walletStorage.getPrimaryAddress(), data, pubkey, Node.blockChain.getLastBlockNum());

            if (TransactionPool.addTransaction(tx))
            {
                PendingTransactions.addPendingLocalTransaction(tx);
            }
            else
            {
                Logging.error("An unknown error occured while sending PoW solution.");
            }
        }
Esempio n. 5
0
        private void ValidateTransaction(Transaction transaction)
        {
            if (!CryptoUtil.IsAddressValid(transaction.FromAddress))
            {
                throw new AddressNotValidException($"{transaction.FromAddress} is not valid address");
            }

            if (!CryptoUtil.IsAddressValid(transaction.ToAddress))
            {
                throw new AddressNotValidException($"{transaction.ToAddress} is not valid address");
            }

            if (transaction == null)
            {
                throw new ArgumentException("'transaction' object cannot be null");
            }

            //check whetehr we know that transaction
            if (PendingTransactions.FirstOrDefault(t => t.TransactionHash == transaction.TransactionHash) != null)
            {
                return;
            }

            //check whether transaction is already mined
            if (BlockChain.Any(b => b.Value.Transactions.Any(t => t.TransactionHash == transaction.TransactionHash)))
            {
                return;
            }

            if (string.IsNullOrWhiteSpace(transaction.SenderPublicKey))
            {
                throw new TransactionNotValidException("Sender signature cannot be empty");
            }

            bool isHashValid = TransactionValidator.IsValidateHash(transaction);

            if (!isHashValid)
            {
                throw new TransactionNotValidException("Transaction not Valid! Tranascion is chnaged by middle man");
            }

            bool isVerified = TransactionValidator.IsValid(transaction);

            if (!isVerified)
            {
                throw new TransactionNotValidException("Transaction not Valid! Signutre is not valid");
            }

            string address = TransactionValidator.GetAddress(transaction.SenderPublicKey);

            if (address != transaction.FromAddress)
            {
                throw new TransactionNotValidException("Provided address is not valid.");
            }
        }
Esempio n. 6
0
        void handleStatus()
        {
            Console.WriteLine("Last Block Height: {0}", IxianHandler.getLastBlockHeight());
            Console.WriteLine("Network Block Height: {0}", IxianHandler.getHighestKnownNetworkBlockHeight());

            int connectionsOut = NetworkClientManager.getConnectedClients(true).Count();

            Console.WriteLine("Connections: {0}", connectionsOut);

            Console.WriteLine("Pending transactions: {0}\n", PendingTransactions.pendingTransactionCount());
        }
Esempio n. 7
0
        //Mining of block
        public void MinePendingTransactions(string miningRewardAddress)
        {
            Block block = new Block(DateTime.Now, PendingTransactions, GetLastestBlock.CurrentHash);

            block.MineBlock(Diffuclty);

            Console.WriteLine("Block successfully mined!");
            Chain.Add(block);

            PendingTransactions.Add(new Transaction(null, miningRewardAddress, MiningReward));
        }
Esempio n. 8
0
        public override void receivedTransactionInclusionVerificationResponse(byte[] txid, bool verified)
        {
            string status = "NOT VERIFIED";

            if (verified)
            {
                status = "VERIFIED";
                PendingTransactions.remove(txid);
            }
            Console.WriteLine("Transaction {0} is {1}\n", Transaction.txIdV8ToLegacy(txid), status);
        }
Esempio n. 9
0
        public void CreateTransaction(TransactionInfo transaction)
        {
            PendingTransactions.Add(transaction);

            if (PendingTransactions.Count < TransactionThreshold)
            {
                return;
            }

            var block = new BlockInfo {
                PreviousHash = Blocks[^ 1].Hash,
 public void AddTransaction(Transaction someTransaction, Hashtable transactions, List <Account> ListOfAllAccounts)
 {
     if (IsValidTransaction(someTransaction, transactions, ListOfAllAccounts))
     {
         PendingTransactions.Add(someTransaction);
     }
     else
     {
         RejectedTransactions.Add(someTransaction);
     }
 }
Esempio n. 11
0
        public void ProcessPendingTransactions(DateTime date, string miner)
        {
            Block lastBlock = Chain.Last();
            Block newBlock  = new Block(date, lastBlock, PendingTransactions);

            newBlock.Transactions.Add(new Transaction(null, miner, Reward, date));
            newBlock.Mine(Difficulty);
            AddUsersOfBlock(newBlock);
            Chain.Add(newBlock);
            PendingTransactions.Clear();
        }
Esempio n. 12
0
 //CreateTransaction
 public bool CreateTransaction(Transaction transaction)
 {
     if (transaction != null)
     {
         PendingTransactions.Add(transaction);
         return(true);
     }
     else
     {
         return(false);
     }
 }
Esempio n. 13
0
        public void MinePendingTransactions(User miningRewardUser)
        {
            PendingTransactions.Add(new Transaction(null, miningRewardUser, 150));

            Block block = new Block(DateTime.Now, PendingTransactions, GetLastestBlock.CurrentHash);

            block.MineBlock(Diffuclty);

            Console.WriteLine("Block successfully mined!");
            Blocks.Add(block);

            PendingTransactions = new List <Transaction>();
        }
Esempio n. 14
0
        public void AddTransaction(Transaction transaction)
        {
            if (string.IsNullOrEmpty(transaction.FromAddress) || string.IsNullOrEmpty(transaction.ToAddress))
            {
                throw new Exception("Transaction must include from and to address");
            }

            if (!transaction.IsValid())
            {
                throw new Exception("Cannot add invalid transaction to chain");
            }

            PendingTransactions.Add(transaction);
        }
Esempio n. 15
0
        public void AttachBroadcastedBlock(BlockSyncApiModel block, string nodeAddress)
        {
            bool isPastBlock = block.Index <= LastBlock.Index;

            if (isPastBlock)
            {
                return;
            }

            Block minedBlock = Block.ReCreateBlock(block);

            ValidateBlockHash(minedBlock, minedBlock.Nonce, minedBlock.BlockHash);

            // replace blockchain if another blockain is longer
            int nodeDifference = minedBlock.Index - BlockChain.Count;

            if (nodeDifference >= 6)
            {
                int          startIndex   = minedBlock.Index - nodeDifference;
                List <Block> forkedBlocks = NodeSynchornizator.GetBlocksForSync(nodeAddress);

                foreach (var bl in forkedBlocks)
                {
                    RevalidateBlock(bl);
                    BlockChain.AddOrUpdate(bl.Index, bl, (index, curBlock) => { return(bl); });
                }

                List <string> blockTxs = forkedBlocks.SelectMany(b => b.Transactions).Select(t => t.TransactionHash).ToList();

                PendingTransactions = new ConcurrentBag <Transaction>(PendingTransactions.
                                                                      Where(t => !blockTxs.Contains(t.TransactionHash)));
            }
            else
            {
                bool isFutureBlock = LastBlock.BlockHash != minedBlock.PreviousBlockHash;
                if (isFutureBlock)
                {
                    return;
                }

                RevalidateBlock(minedBlock);

                // remove mined transactions from pending transactions
                List <string> minedTxIds = minedBlock.Transactions.Select(t => t.TransactionHash).ToList();
                PendingTransactions = new ConcurrentBag <Transaction>(PendingTransactions.Where(t => !minedTxIds.Contains(t.TransactionHash)).ToList());

                BlockChain.TryAdd(minedBlock.Index, minedBlock);
            }
        }
Esempio n. 16
0
 void Lock(Transaction transaction)
 {
     Monitor.Enter(this);
     if (OwningTransaction == null)
     {
         //Acquire the transaction lock if(transaction != null)
         OwningTransaction = transaction;
         Monitor.Exit(this);
         return;
     }
     else //Some transaction owns the lock
     {
         //We're done if it's the same one as the method parameter
         if (OwningTransaction == transaction)
         {
             Monitor.Exit(this);
             return;
         } //Otherwise, need to acquire the transaction lock
         else
         {
             ManualResetEvent manualEvent = new ManualResetEvent(false);
             KeyValuePair <Transaction, ManualResetEvent> pair = new KeyValuePair <Transaction, ManualResetEvent>(transaction, manualEvent);
             PendingTransactions.AddLast(pair);
             if (transaction != null)
             {
                 transaction.TransactionCompleted += (sender, e) =>
                 {
                     lock (this)
                     {
                         //Pair may have already been removed if unlocked
                         PendingTransactions.Remove(pair);
                     }
                     lock (manualEvent)
                     {
                         if (!manualEvent.SafeWaitHandle.IsClosed)
                         {
                             manualEvent.Set();
                         }
                     }
                 };
             }
             Monitor.Exit(this);
             //Block the transaction or the calling thread
             manualEvent.WaitOne();
             lock (manualEvent)
                 manualEvent.Close();
         }
     }
 }
Esempio n. 17
0
        public override void receivedTransactionInclusionVerificationResponse(byte[] txid, bool verified)
        {
            // TODO implement error
            // TODO implement blocknum

            ActivityStatus status = ActivityStatus.Pending;

            if (verified)
            {
                status = ActivityStatus.Final;
                PendingTransactions.remove(txid);
            }

            ActivityStorage.updateStatus(txid, status, 0);
        }
Esempio n. 18
0
        public void MinePendingTransactions(string miningRewardAddress)
        {
            if (!isMining)
            {
                isMining = true;
                Transaction rewardTx = new Transaction(null, miningRewardAddress, MiningReward);
                PendingTransactions.Add(rewardTx);

                // TO-DO limit amount of transactions
                Block block = new Block(DateTime.UtcNow.ToString("g"), PendingTransactions, GetLatestBlock().Hash);
                block.MineBlock(Difficulty);
                Chain.Add(block);

                PendingTransactions = new List <Transaction>();
                isMining            = false;
            }
        }
Esempio n. 19
0
        internal ICollection <Transaction> GetTransactions(string address, bool includeUncofirmed = false, bool onlySuccessful = false)
        {
            var query = BlockChain.SelectMany(b => b.Value.Transactions).Where(t => t.FromAddress == address || t.ToAddress == address);

            if (onlySuccessful)
            {
                query = query.Where(t => t.TranserSuccessfull);
            }

            var result = query.ToList();

            if (includeUncofirmed)
            {
                result.AddRange(PendingTransactions
                                .Where(t => (t.FromAddress == address || t.ToAddress == address) &&
                                       (!onlySuccessful || t.TranserSuccessfull))
                                .ToList());
            }

            return(result);
        }
Esempio n. 20
0
        public void NonceFound(string minerAddress, int nonce, string hash)
        {
            lock (_nonceFoundLock)
            {
                Block block = BlocksInProgress[minerAddress];
                if (block == null)
                {
                    return;
                }

                if (!CryptoUtil.IsAddressValid(minerAddress))
                {
                    throw new AddressNotValidException($"Miner address '{minerAddress}' is not valid");
                }

                if (block.Index != BlockChain.Last().Key + 1)
                {
                    throw new NonceUselessException();
                }

                ValidateBlockHash(block, nonce, hash);
                block.BlockMined(nonce, hash, minerAddress);

                int minedTransactionsCount = block.Transactions.Count;

                List <Transaction> notMinedTxs = new List <Transaction>();
                var allTx = PendingTransactions.ToList();

                for (int i = minedTransactionsCount; i < allTx.Count; i++)
                {
                    notMinedTxs.Add(allTx[i]);
                }

                PendingTransactions = new ConcurrentBag <Transaction>(notMinedTxs);

                BlockChain.TryAdd(block.Index, block);
                BlocksInProgress[minerAddress] = null;
                NodeSynchornizator.BroadcastBlock(block);
            }
        }
Esempio n. 21
0
        public string MineFirstPendingTransaction(int minerId)
        {
            if (this.PendingTransactions.Count < 1)
            {
                return("No transactions to mine!");
            }

            List <Transaction> minedTransactions = new List <Transaction>();

            minedTransactions.Add(PendingTransactions[0]);

            Block newBlock = new Block(DateTime.Now, minedTransactions, this.Chain.Last().Hash);

            newBlock.MineBlock(this.Difficulty);
            this.Chain.Add(newBlock);

            Transaction reward = new Transaction(0, minerId, MiningReward);

            PendingTransactions.Add(reward);

            return("Transaction Successfully mined!");
        }
Esempio n. 22
0
        public override void receivedTransactionInclusionVerificationResponse(byte[] txid, bool verified)
        {
            // TODO implement error
            // TODO implement blocknum

            ActivityStatus status = ActivityStatus.Pending;

            if (verified)
            {
                status = ActivityStatus.Final;
                PendingTransaction p_tx = PendingTransactions.getPendingTransaction(txid);
                if (p_tx != null)
                {
                    if (p_tx.messageId != null)
                    {
                        StreamProcessor.confirmMessage(p_tx.messageId);
                    }
                    PendingTransactions.remove(txid);
                }
            }

            ActivityStorage.updateStatus(txid, status, 0);
        }
Esempio n. 23
0
        public void AddTransaction(Transaction transaction, bool broadcast = true)
        {
            ValidateTransaction(transaction);

            ulong senderBalance = CalculateBalance(transaction.FromAddress, true, true);

            if (senderBalance >= transaction.Fee)
            {
                transaction.TranserSuccessfull = senderBalance >= transaction.Amount + transaction.Fee;
                PendingTransactions.Add(transaction);
                if (broadcast)
                {
                    NodeSynchornizator.BroadcastTransaction(transaction);
                }
                if (!transaction.TranserSuccessfull)
                {
                    throw new BalanceNotEnoughException($"Address '{transaction.FromAddress}' trying to send {transaction.Amount.GetFormattedTokens()}, but balance is {senderBalance.GetFormattedTokens()}. Transaction fee will be deducted !!!");
                }
            }
            else
            {
                throw new BalanceNotEnoughException($"Address '{transaction.FromAddress}' does not have enough money even for paying the fee");
            }
        }
Esempio n. 24
0
        // Unified protocol message parsing
        public static void parseProtocolMessage(ProtocolMessageCode code, byte[] data, RemoteEndpoint endpoint)
        {
            if (endpoint == null)
            {
                Logging.error("Endpoint was null. parseProtocolMessage");
                return;
            }
            try
            {
                switch (code)
                {
                case ProtocolMessageCode.hello:
                    handleHello(data, endpoint);
                    break;

                case ProtocolMessageCode.helloData:
                    handleHelloData(data, endpoint);
                    break;

                case ProtocolMessageCode.s2data:
                    StreamProcessor.receiveData(data, endpoint);
                    break;

                case ProtocolMessageCode.s2failed:
                    Logging.error("Failed to send s2 data");
                    break;

                case ProtocolMessageCode.s2signature:
                    StreamProcessor.receivedTransactionSignature(data, endpoint);
                    break;

                case ProtocolMessageCode.newTransaction:
                case ProtocolMessageCode.transactionData:
                {
                    Transaction tx = new Transaction(data, true);

                    if (endpoint.presenceAddress.type == 'M' || endpoint.presenceAddress.type == 'H')
                    {
                        PendingTransactions.increaseReceivedCount(tx.id, endpoint.presence.wallet);
                    }

                    Node.tiv.receivedNewTransaction(tx);
                    Logging.info("Received new transaction {0}", tx.id);

                    Node.addTransactionToActivityStorage(tx);
                }
                break;

                case ProtocolMessageCode.updatePresence:
                    // Parse the data and update entries in the presence list
                    PresenceList.updateFromBytes(data);
                    break;

                case ProtocolMessageCode.keepAlivePresence:
                    byte[] address   = null;
                    long   last_seen = 0;
                    byte[] device_id = null;
                    bool   updated   = PresenceList.receiveKeepAlive(data, out address, out last_seen, out device_id, endpoint);
                    break;

                case ProtocolMessageCode.getPresence:
                    handleGetPresence(data, endpoint);
                    break;

                case ProtocolMessageCode.getPresence2:
                    handleGetPresence2(data, endpoint);
                    break;

                case ProtocolMessageCode.balance:
                    handleBalance(data, endpoint);
                    break;

                case ProtocolMessageCode.balance2:
                    handleBalance2(data, endpoint);
                    break;

                case ProtocolMessageCode.bye:
                    CoreProtocolMessage.processBye(data, endpoint);
                    break;

                case ProtocolMessageCode.blockHeaders2:
                    // Forward the block headers to the TIV handler
                    Node.tiv.receivedBlockHeaders2(data, endpoint);
                    break;

                case ProtocolMessageCode.pitData2:
                    Node.tiv.receivedPIT2(data, endpoint);
                    break;

                default:
                    break;
                }
            }
            catch (Exception e)
            {
                Logging.error(string.Format("Error parsing network message. Details: {0}", e.ToString()));
            }
        }
Esempio n. 25
0
 //Creates a new transaction
 public void CreateTransaction(Transaction transaction)
 {
     PendingTransactions.Add(transaction);
 }
Esempio n. 26
0
        // Unified protocol message parsing
        public static void parseProtocolMessage(ProtocolMessageCode code, byte[] data, RemoteEndpoint endpoint)
        {
            if (endpoint == null)
            {
                Logging.error("Endpoint was null. parseProtocolMessage");
                return;
            }
            try
            {
                switch (code)
                {
                case ProtocolMessageCode.hello:
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            bool processed = false;
                            processed = CoreProtocolMessage.processHelloMessageV6(endpoint, reader, false);

                            if (!processed || (Config.whiteList.Count > 0 && !Config.whiteList.Contains(endpoint.presence.wallet, new ByteArrayComparer())))
                            {
                                CoreProtocolMessage.sendBye(endpoint, ProtocolByeCode.bye, string.Format("Access denied."), "", true);
                                return;
                            }

                            endpoint.helloReceived = true;
                        }
                    }
                    break;


                case ProtocolMessageCode.helloData:
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            if (CoreProtocolMessage.processHelloMessageV6(endpoint, reader))
                            {
                                char node_type = endpoint.presenceAddress.type;
                                if (node_type != 'M' && node_type != 'H')
                                {
                                    CoreProtocolMessage.sendBye(endpoint, ProtocolByeCode.expectingMaster, string.Format("Expecting master node."), "", true);
                                    return;
                                }

                                ulong last_block_num = reader.ReadIxiVarUInt();

                                int    bcLen          = (int)reader.ReadIxiVarUInt();
                                byte[] block_checksum = reader.ReadBytes(bcLen);

                                endpoint.blockHeight = last_block_num;

                                int block_version = (int)reader.ReadIxiVarUInt();

                                try
                                {
                                    string public_ip = reader.ReadString();
                                    ((NetworkClient)endpoint).myAddress = public_ip;
                                }
                                catch (Exception)
                                {
                                }

                                string address = NetworkClientManager.getMyAddress();
                                if (address != null)
                                {
                                    if (IxianHandler.publicIP != address)
                                    {
                                        Logging.info("Setting public IP to " + address);
                                        IxianHandler.publicIP = address;
                                    }
                                }

                                // Process the hello data
                                endpoint.helloReceived = true;
                                NetworkClientManager.recalculateLocalTimeDifference();

                                Node.setNetworkBlock(last_block_num, block_checksum, block_version);

                                // Get random presences
                                endpoint.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                                    (byte)'M'
                                });
                                endpoint.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                                    (byte)'H'
                                });

                                CoreProtocolMessage.subscribeToEvents(endpoint);
                            }
                        }
                    }
                    break;

                case ProtocolMessageCode.s2data:
                {
                    StreamProcessor.receiveData(data, endpoint);
                }
                break;

                case ProtocolMessageCode.s2failed:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            Logging.error("Failed to send s2 data");
                        }
                    }
                }
                break;

                case ProtocolMessageCode.transactionData:
                {
                    Transaction tx = new Transaction(data, true);

                    if (endpoint.presenceAddress.type == 'M' || endpoint.presenceAddress.type == 'H')
                    {
                        PendingTransactions.increaseReceivedCount(tx.id, endpoint.presence.wallet);
                    }

                    Node.tiv.receivedNewTransaction(tx);
                    Logging.info("Received new transaction {0}", tx.id);

                    Node.addTransactionToActivityStorage(tx);
                }
                break;

                case ProtocolMessageCode.updatePresence:
                {
                    // Parse the data and update entries in the presence list
                    PresenceList.updateFromBytes(data, 0);
                }
                break;


                case ProtocolMessageCode.keepAlivePresence:
                {
                    byte[] address   = null;
                    long   last_seen = 0;
                    byte[] device_id = null;
                    bool   updated   = PresenceList.receiveKeepAlive(data, out address, out last_seen, out device_id, endpoint);
                }
                break;

                case ProtocolMessageCode.getPresence:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int      walletLen = reader.ReadInt32();
                            byte[]   wallet    = reader.ReadBytes(walletLen);
                            Presence p         = PresenceList.getPresenceByAddress(wallet);
                            if (p != null)
                            {
                                lock (p)
                                {
                                    byte[][] presence_chunks = p.getByteChunks();
                                    foreach (byte[] presence_chunk in presence_chunks)
                                    {
                                        endpoint.sendData(ProtocolMessageCode.updatePresence, presence_chunk, null);
                                    }
                                }
                            }
                            else
                            {
                                // TODO blacklisting point
                                Logging.warn(string.Format("Node has requested presence information about {0} that is not in our PL.", Base58Check.Base58CheckEncoding.EncodePlain(wallet)));
                            }
                        }
                    }
                }
                break;

                case ProtocolMessageCode.getPresence2:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int      walletLen = (int)reader.ReadIxiVarUInt();
                            byte[]   wallet    = reader.ReadBytes(walletLen);
                            Presence p         = PresenceList.getPresenceByAddress(wallet);
                            if (p != null)
                            {
                                lock (p)
                                {
                                    byte[][] presence_chunks = p.getByteChunks();
                                    foreach (byte[] presence_chunk in presence_chunks)
                                    {
                                        endpoint.sendData(ProtocolMessageCode.updatePresence, presence_chunk, null);
                                    }
                                }
                            }
                            else
                            {
                                // TODO blacklisting point
                                Logging.warn(string.Format("Node has requested presence information about {0} that is not in our PL.", Base58Check.Base58CheckEncoding.EncodePlain(wallet)));
                            }
                        }
                    }
                }
                break;

                case ProtocolMessageCode.balance:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int    address_length = reader.ReadInt32();
                            byte[] address        = reader.ReadBytes(address_length);

                            // Retrieve the latest balance
                            IxiNumber balance = reader.ReadString();

                            if (address.SequenceEqual(IxianHandler.getWalletStorage().getPrimaryAddress()))
                            {
                                // Retrieve the blockheight for the balance
                                ulong block_height = reader.ReadUInt64();

                                if (block_height > Node.balance.blockHeight && (Node.balance.balance != balance || Node.balance.blockHeight == 0))
                                {
                                    byte[] block_checksum = reader.ReadBytes(reader.ReadInt32());

                                    Node.balance.address       = address;
                                    Node.balance.balance       = balance;
                                    Node.balance.blockHeight   = block_height;
                                    Node.balance.blockChecksum = block_checksum;
                                    Node.balance.lastUpdate    = Clock.getTimestamp();
                                    Node.balance.verified      = false;
                                }
                            }
                        }
                    }
                }
                break;

                case ProtocolMessageCode.balance2:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int    address_length = (int)reader.ReadIxiVarUInt();
                            byte[] address        = reader.ReadBytes(address_length);

                            // Retrieve the latest balance
                            IxiNumber balance = new IxiNumber(new BigInteger(reader.ReadBytes((int)reader.ReadIxiVarUInt())));

                            if (address.SequenceEqual(IxianHandler.getWalletStorage().getPrimaryAddress()))
                            {
                                // Retrieve the blockheight for the balance
                                ulong block_height = reader.ReadIxiVarUInt();

                                if (block_height > Node.balance.blockHeight && (Node.balance.balance != balance || Node.balance.blockHeight == 0))
                                {
                                    byte[] block_checksum = reader.ReadBytes((int)reader.ReadIxiVarUInt());

                                    Node.balance.address       = address;
                                    Node.balance.balance       = balance;
                                    Node.balance.blockHeight   = block_height;
                                    Node.balance.blockChecksum = block_checksum;
                                    Node.balance.lastUpdate    = Clock.getTimestamp();
                                    Node.balance.verified      = false;
                                }
                            }
                        }
                    }
                }
                break;

                case ProtocolMessageCode.bye:
                    CoreProtocolMessage.processBye(data, endpoint);
                    break;

                case ProtocolMessageCode.blockHeaders2:
                {
                    // Forward the block headers to the TIV handler
                    Node.tiv.receivedBlockHeaders2(data, endpoint);
                }
                break;

                case ProtocolMessageCode.pitData2:
                {
                    Node.tiv.receivedPIT2(data, endpoint);
                }
                break;

                default:
                    break;
                }
            }
            catch (Exception e)
            {
                Logging.error(string.Format("Error parsing network message. Details: {0}", e.ToString()));
            }
        }
Esempio n. 27
0
 public void BuyCoins(User user, double amount)
 {
     //Логика для покупки криптовалюты пока что нету обменников(но есть возможность поменять QIWI,WEBMONEY и другии веб - деньги или настоящие деньги на криптовалюту.)
     PendingTransactions.Add(new Transaction(null, user, amount));
 }
        // Unified protocol message parsing
        public static void parseProtocolMessage(ProtocolMessageCode code, byte[] data, RemoteEndpoint endpoint)
        {
            if (endpoint == null)
            {
                Logging.error("Endpoint was null. parseProtocolMessage");
                return;
            }
            try
            {
                switch (code)
                {
                case ProtocolMessageCode.hello:
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            if (CoreProtocolMessage.processHelloMessage(endpoint, reader))
                            {
                                byte[] challenge_response = null;

                                int    challenge_len = reader.ReadInt32();
                                byte[] challenge     = reader.ReadBytes(challenge_len);

                                challenge_response = CryptoManager.lib.getSignature(challenge, Node.walletStorage.getPrimaryPrivateKey());

                                CoreProtocolMessage.sendHelloMessage(endpoint, true, challenge_response);
                                endpoint.helloReceived = true;
                                return;
                            }
                        }
                    }
                    break;


                case ProtocolMessageCode.helloData:
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            if (CoreProtocolMessage.processHelloMessage(endpoint, reader))
                            {
                                char node_type = endpoint.presenceAddress.type;
                                if (node_type != 'M' && node_type != 'H')
                                {
                                    CoreProtocolMessage.sendBye(endpoint, ProtocolByeCode.expectingMaster, string.Format("Expecting master node."), "", true);
                                    return;
                                }

                                ulong last_block_num = reader.ReadUInt64();

                                int    bcLen          = reader.ReadInt32();
                                byte[] block_checksum = reader.ReadBytes(bcLen);

                                int    wsLen = reader.ReadInt32();
                                byte[] walletstate_checksum = reader.ReadBytes(wsLen);

                                int consensus = reader.ReadInt32();

                                endpoint.blockHeight = last_block_num;

                                int block_version = reader.ReadInt32();

                                // Check for legacy level
                                ulong legacy_level = reader.ReadUInt64();     // deprecated

                                int    challenge_response_len = reader.ReadInt32();
                                byte[] challenge_response     = reader.ReadBytes(challenge_response_len);
                                if (!CryptoManager.lib.verifySignature(endpoint.challenge, endpoint.serverPubKey, challenge_response))
                                {
                                    CoreProtocolMessage.sendBye(endpoint, ProtocolByeCode.authFailed, string.Format("Invalid challenge response."), "", true);
                                    return;
                                }

                                // Process the hello data
                                endpoint.helloReceived = true;
                                NetworkClientManager.recalculateLocalTimeDifference();

                                if (endpoint.presenceAddress.type == 'M')
                                {
                                    Node.setNetworkBlock(last_block_num, block_checksum, block_version);

                                    // Get random presences
                                    endpoint.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                                        (byte)'M'
                                    });

                                    CoreProtocolMessage.subscribeToEvents(endpoint);
                                }
                            }
                        }
                    }
                    break;

                case ProtocolMessageCode.balance:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int    address_length = reader.ReadInt32();
                            byte[] address        = reader.ReadBytes(address_length);

                            // Retrieve the latest balance
                            IxiNumber balance = reader.ReadString();

                            if (address.SequenceEqual(Node.walletStorage.getPrimaryAddress()))
                            {
                                // Retrieve the blockheight for the balance
                                ulong block_height = reader.ReadUInt64();

                                if (block_height > Node.balance.blockHeight && (Node.balance.balance != balance || Node.balance.blockHeight == 0))
                                {
                                    byte[] block_checksum = reader.ReadBytes(reader.ReadInt32());

                                    Node.balance.address       = address;
                                    Node.balance.balance       = balance;
                                    Node.balance.blockHeight   = block_height;
                                    Node.balance.blockChecksum = block_checksum;
                                    Node.balance.verified      = false;
                                }
                            }
                        }
                    }
                }
                break;

                case ProtocolMessageCode.updatePresence:
                {
                    // Parse the data and update entries in the presence list
                    PresenceList.updateFromBytes(data);
                }
                break;

                case ProtocolMessageCode.blockHeaders:
                {
                    // Forward the block headers to the TIV handler
                    Node.tiv.receivedBlockHeaders(data, endpoint);
                }
                break;

                case ProtocolMessageCode.pitData:
                {
                    Node.tiv.receivedPIT(data, endpoint);
                }
                break;

                case ProtocolMessageCode.newTransaction:
                case ProtocolMessageCode.transactionData:
                {
                    Transaction tx = new Transaction(data, true);

                    PendingTransactions.increaseReceivedCount(tx.id);

                    Node.tiv.receivedNewTransaction(tx);
                    Console.WriteLine("Received new transaction {0}", tx.id);
                }
                break;

                default:
                    break;
                }
            }
            catch (Exception e)
            {
                Logging.error(string.Format("Error parsing network message. Details: {0}", e.ToString()));
            }

            if (waitingFor == code)
            {
                blocked = false;
            }
        }
Esempio n. 29
0
        // Unified protocol message parsing
        public static void parseProtocolMessage(ProtocolMessageCode code, byte[] data, RemoteEndpoint endpoint)
        {
            if (endpoint == null)
            {
                Logging.error("Endpoint was null. parseProtocolMessage");
                return;
            }
            try
            {
                switch (code)
                {
                case ProtocolMessageCode.hello:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            CoreProtocolMessage.processHelloMessageV6(endpoint, reader);
                        }
                    }
                }
                break;


                case ProtocolMessageCode.helloData:
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            if (!CoreProtocolMessage.processHelloMessageV6(endpoint, reader))
                            {
                                return;
                            }

                            ulong  last_block_num = reader.ReadIxiVarUInt();
                            int    bcLen          = (int)reader.ReadIxiVarUInt();
                            byte[] block_checksum = reader.ReadBytes(bcLen);

                            endpoint.blockHeight = last_block_num;

                            int block_version = (int)reader.ReadIxiVarUInt();

                            if (endpoint.presenceAddress.type != 'C')
                            {
                                ulong highest_block_height = IxianHandler.getHighestKnownNetworkBlockHeight();
                                if (last_block_num + 10 < highest_block_height)
                                {
                                    CoreProtocolMessage.sendBye(endpoint, ProtocolByeCode.tooFarBehind, string.Format("Your node is too far behind, your block height is {0}, highest network block height is {1}.", last_block_num, highest_block_height), highest_block_height.ToString(), true);
                                    return;
                                }
                            }

                            // Process the hello data
                            endpoint.helloReceived = true;
                            NetworkClientManager.recalculateLocalTimeDifference();

                            if (endpoint.presenceAddress.type == 'R')
                            {
                                string[] connected_servers = StreamClientManager.getConnectedClients(true);
                                if (connected_servers.Count() == 1 || !connected_servers.Contains(StreamClientManager.primaryS2Address))
                                {
                                    if (StreamClientManager.primaryS2Address == "")
                                    {
                                        FriendList.requestAllFriendsPresences();
                                    }
                                    // TODO set the primary s2 host more efficiently, perhaps allow for multiple s2 primary hosts
                                    StreamClientManager.primaryS2Address = endpoint.getFullAddress(true);
                                    // TODO TODO do not set if directly connectable
                                    IxianHandler.publicIP           = endpoint.address;
                                    IxianHandler.publicPort         = endpoint.incomingPort;
                                    PresenceList.forceSendKeepAlive = true;
                                    Logging.info("Forcing KA from networkprotocol");
                                }
                            }
                            else if (endpoint.presenceAddress.type == 'C')
                            {
                                Friend f = FriendList.getFriend(endpoint.presence.wallet);
                                if (f != null && f.bot)
                                {
                                    StreamProcessor.sendGetBotInfo(f);
                                }
                            }

                            if (endpoint.presenceAddress.type == 'M' || endpoint.presenceAddress.type == 'H')
                            {
                                Node.setNetworkBlock(last_block_num, block_checksum, block_version);

                                // Get random presences
                                endpoint.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                                    (byte)'R'
                                });
                                endpoint.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                                    (byte)'M'
                                });
                                endpoint.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                                    (byte)'H'
                                });

                                subscribeToEvents(endpoint);
                            }
                        }
                    }
                    break;

                case ProtocolMessageCode.s2data:
                {
                    StreamProcessor.receiveData(data, endpoint);
                }
                break;

                case ProtocolMessageCode.updatePresence:
                {
                    Logging.info("NET: Receiving presence list update");
                    // Parse the data and update entries in the presence list
                    Presence p = PresenceList.updateFromBytes(data);
                    if (p == null)
                    {
                        return;
                    }

                    Friend f = FriendList.getFriend(p.wallet);
                    if (f != null)
                    {
                        f.relayIP = p.addresses[0].address;
                    }
                }
                break;

                case ProtocolMessageCode.keepAlivePresence:
                {
                    byte[]   address   = null;
                    long     last_seen = 0;
                    byte[]   device_id = null;
                    bool     updated   = PresenceList.receiveKeepAlive(data, out address, out last_seen, out device_id, endpoint);
                    Presence p         = PresenceList.getPresenceByAddress(address);
                    if (p == null)
                    {
                        return;
                    }

                    Friend f = FriendList.getFriend(p.wallet);
                    if (f != null)
                    {
                        f.relayIP = p.addresses[0].address;
                    }
                }
                break;

                case ProtocolMessageCode.getPresence:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int    walletLen = reader.ReadInt32();
                            byte[] wallet    = reader.ReadBytes(walletLen);

                            Presence p = PresenceList.getPresenceByAddress(wallet);
                            if (p != null)
                            {
                                lock (p)
                                {
                                    byte[][] presence_chunks = p.getByteChunks();
                                    foreach (byte[] presence_chunk in presence_chunks)
                                    {
                                        endpoint.sendData(ProtocolMessageCode.updatePresence, presence_chunk, null);
                                    }
                                }
                            }
                            else
                            {
                                // TODO blacklisting point
                                Logging.warn(string.Format("Node has requested presence information about {0} that is not in our PL.", Base58Check.Base58CheckEncoding.EncodePlain(wallet)));
                            }
                        }
                    }
                }
                break;

                case ProtocolMessageCode.getPresence2:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int    walletLen = (int)reader.ReadIxiVarUInt();
                            byte[] wallet    = reader.ReadBytes(walletLen);

                            Presence p = PresenceList.getPresenceByAddress(wallet);
                            if (p != null)
                            {
                                lock (p)
                                {
                                    byte[][] presence_chunks = p.getByteChunks();
                                    foreach (byte[] presence_chunk in presence_chunks)
                                    {
                                        endpoint.sendData(ProtocolMessageCode.updatePresence, presence_chunk, null);
                                    }
                                }
                            }
                            else
                            {
                                // TODO blacklisting point
                                Logging.warn(string.Format("Node has requested presence information about {0} that is not in our PL.", Base58Check.Base58CheckEncoding.EncodePlain(wallet)));
                            }
                        }
                    }
                }
                break;

                case ProtocolMessageCode.balance:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int    address_length = reader.ReadInt32();
                            byte[] address        = reader.ReadBytes(address_length);

                            // Retrieve the latest balance
                            IxiNumber balance = reader.ReadString();

                            if (address.SequenceEqual(Node.walletStorage.getPrimaryAddress()))
                            {
                                // Retrieve the blockheight for the balance
                                ulong block_height = reader.ReadUInt64();

                                if (block_height > Node.balance.blockHeight && (Node.balance.balance != balance || Node.balance.blockHeight == 0))
                                {
                                    byte[] block_checksum = reader.ReadBytes(reader.ReadInt32());

                                    Node.balance.address       = address;
                                    Node.balance.balance       = balance;
                                    Node.balance.blockHeight   = block_height;
                                    Node.balance.blockChecksum = block_checksum;
                                    Node.balance.verified      = false;
                                }
                                Node.balance.lastUpdate = Clock.getTimestamp();
                            }
                        }
                    }
                }
                break;

                case ProtocolMessageCode.balance2:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int    address_length = (int)reader.ReadIxiVarUInt();
                            byte[] address        = reader.ReadBytes(address_length);

                            // Retrieve the latest balance
                            IxiNumber balance = new IxiNumber(new BigInteger(reader.ReadBytes((int)reader.ReadIxiVarUInt())));

                            if (address.SequenceEqual(Node.walletStorage.getPrimaryAddress()))
                            {
                                // Retrieve the blockheight for the balance
                                ulong block_height = reader.ReadIxiVarUInt();

                                if (block_height > Node.balance.blockHeight && (Node.balance.balance != balance || Node.balance.blockHeight == 0))
                                {
                                    byte[] block_checksum = reader.ReadBytes((int)reader.ReadIxiVarUInt());

                                    Node.balance.address       = address;
                                    Node.balance.balance       = balance;
                                    Node.balance.blockHeight   = block_height;
                                    Node.balance.blockChecksum = block_checksum;
                                    Node.balance.verified      = false;
                                }
                                Node.balance.lastUpdate = Clock.getTimestamp();
                            }
                        }
                    }
                }
                break;

                case ProtocolMessageCode.newTransaction:
                case ProtocolMessageCode.transactionData:
                {
                    // TODO: check for errors/exceptions
                    Transaction transaction = new Transaction(data, true);

                    if (endpoint.presenceAddress.type == 'M' || endpoint.presenceAddress.type == 'H')
                    {
                        PendingTransactions.increaseReceivedCount(transaction.id, endpoint.presence.wallet);
                    }

                    TransactionCache.addUnconfirmedTransaction(transaction);

                    Node.tiv.receivedNewTransaction(transaction);
                }
                break;

                case ProtocolMessageCode.bye:
                    CoreProtocolMessage.processBye(data, endpoint);
                    break;

                case ProtocolMessageCode.blockHeaders2:
                {
                    // Forward the block headers to the TIV handler
                    Node.tiv.receivedBlockHeaders2(data, endpoint);
                }
                break;

                case ProtocolMessageCode.pitData2:
                {
                    Node.tiv.receivedPIT2(data, endpoint);
                }
                break;

                default:
                    break;
                }
            }
            catch (Exception e)
            {
                Logging.error("Error parsing network message. Details: {0}", e.ToString());
            }
        }
Esempio n. 30
0
        public JsonResponse onStatus(Dictionary <string, object> parameters)
        {
            JsonError error = null;

            Dictionary <string, object> networkArray = new Dictionary <string, object>();

            networkArray.Add("Core Version", CoreConfig.version);
            networkArray.Add("Node Version", CoreConfig.productVersion);
            string netType = "mainnet";

            if (CoreConfig.isTestNet)
            {
                netType = "testnet";
            }
            networkArray.Add("Network type", netType);
            networkArray.Add("My time", Clock.getTimestamp());
            networkArray.Add("Network time difference", Core.networkTimeDifference);
            networkArray.Add("My External IP", IxianHandler.publicIP);
            //networkArray.Add("Listening interface", context.Request.RemoteEndPoint.Address.ToString());
            networkArray.Add("Queues", "Rcv: " + NetworkQueue.getQueuedMessageCount() + ", RcvTx: " + NetworkQueue.getTxQueuedMessageCount()
                             + ", SendClients: " + NetworkServer.getQueuedMessageCount() + ", SendServers: " + NetworkClientManager.getQueuedMessageCount()
                             + ", Storage: " + Storage.getQueuedQueryCount() + ", Logging: " + Logging.getRemainingStatementsCount() + ", Pending Transactions: " + PendingTransactions.pendingTransactionCount());
            networkArray.Add("Node Deprecation Block Limit", Config.nodeDeprecationBlock);

            string dltStatus = "Active";

            if (Node.blockSync.synchronizing)
            {
                dltStatus = "Synchronizing";
            }

            if (Node.blockChain.getTimeSinceLastBLock() > 1800) // if no block for over 1800 seconds
            {
                dltStatus = "ErrorLongTimeNoBlock";
            }

            if (Node.blockProcessor.networkUpgraded)
            {
                dltStatus = "ErrorForkedViaUpgrade";
            }

            networkArray.Add("Update", checkUpdate());

            networkArray.Add("DLT Status", dltStatus);

            string bpStatus = "Stopped";

            if (Node.blockProcessor.operating)
            {
                bpStatus = "Running";
            }
            networkArray.Add("Block Processor Status", bpStatus);

            networkArray.Add("Block Height", Node.blockChain.getLastBlockNum());
            networkArray.Add("Block Version", Node.blockChain.getLastBlockVersion());
            networkArray.Add("Network Block Height", IxianHandler.getHighestKnownNetworkBlockHeight());
            networkArray.Add("Node Type", PresenceList.myPresenceType);
            networkArray.Add("Connectable", NetworkServer.isConnectable());

            if (parameters.ContainsKey("verbose"))
            {
                networkArray.Add("Required Consensus", Node.blockChain.getRequiredConsensus());

                networkArray.Add("Wallets", Node.walletState.numWallets);
                networkArray.Add("Presences", PresenceList.getTotalPresences());
                networkArray.Add("Supply", Node.walletState.calculateTotalSupply().ToString());
                networkArray.Add("Applied TX Count", TransactionPool.getTransactionCount() - TransactionPool.getUnappliedTransactions().Count());
                networkArray.Add("Unapplied TX Count", TransactionPool.getUnappliedTransactions().Count());
                networkArray.Add("WS Checksum", Crypto.hashToString(Node.walletState.calculateWalletStateChecksum()));
                networkArray.Add("WS Delta Checksum", Crypto.hashToString(Node.walletState.calculateWalletStateChecksum(true)));

                networkArray.Add("Network Clients", NetworkServer.getConnectedClients());
                networkArray.Add("Network Servers", NetworkClientManager.getConnectedClients(true));
            }

            networkArray.Add("Masters", PresenceList.countPresences('M'));
            networkArray.Add("Relays", PresenceList.countPresences('R'));
            networkArray.Add("Clients", PresenceList.countPresences('C'));
            networkArray.Add("Workers", PresenceList.countPresences('W'));


            return(new JsonResponse {
                result = networkArray, error = error
            });
        }