public void TestClient()
        {
            //todo: test ping deadlock

            using (BitcoinEndpoint endpoint = new BitcoinEndpoint(LoggingMessageHandler))
            {
                endpoint.Connect("localhost", 8333);

                //endpoint.WriteMessage(new GetBlocksMessage(endpoint.ProtocolVersion, new byte[][] {blockHash0}, blockHash2));
                endpoint.WriteMessage(new GetBlocksMessage(endpoint.ProtocolVersion, new byte[][] {new byte[32]}, new byte[32]));
                Thread.Sleep(500);
                endpoint.WriteMessage(new GetDataMessage(new InventoryVector[] {new InventoryVector(InventoryVectorType.MsgBlock, blockHash1)}));

                Thread.Sleep(30000);
            }
        }
        public void OnNodeConnected(BitcoinEndpoint endpoint)
        {
            BlockLocator locator = null;

            lock (lockObject)
            {
                endpoints.Add(endpoint, new EndpointState(endpoint));
                if (requiredBlocks.Any())
                {
                    int minRequiredBlockHeight = requiredBlocks.Values.Min(b => b.Height);
                    int locatorHeight = minRequiredBlockHeight - 1;
                    List<StoredBlock> parentBlocks = node.Blockchain.GetBlocksByHeight(BlockLocator.GetRequiredBlockHeights(locatorHeight));
                    locator = new BlockLocator();
                    foreach (StoredBlock block in parentBlocks)
                    {
                        locator.AddHash(block.Height, block.Hash);
                    }
                }
            }

            if (locator != null)
            {
                endpoint.WriteMessage(new GetBlocksMessage(endpoint.ProtocolVersion, locator.GetHashes(), new byte[32]));
            }
        }
 private static void RequestHeaders(BitcoinEndpoint endpoint, BlockLocator blockLocator)
 {
     endpoint.WriteMessage(new GetHeadersMessage(endpoint.ProtocolVersion, blockLocator.GetHashes(), new byte[32]));
 }
        private void SendDeadlockTestSequence(BitcoinEndpoint client, string peerName)
        {
            byte[][] locatorHashes = new byte[256][];
            for (int i = 0; i < locatorHashes.Length; i++)
            {
                locatorHashes[i] = new byte[32];
            }

            IBitcoinMessage pingMessage = new PingMessage(0);

            IBitcoinMessage bigMessage = new GetBlocksMessage(client.ProtocolVersion, locatorHashes, new byte[32]);
            byte[] messageText = BitcoinStreamWriter.GetBytes(bigMessage.Write);
            Console.WriteLine("{0}: message length is {1}", peerName, messageText.Length);

            Console.WriteLine("{0}: sequence started", peerName);
            for (int i = 0; i < 16; i++)
            {
                client.WriteMessage(bigMessage);
                client.WriteMessage(pingMessage);
            }
            Console.WriteLine("{0}: sequence finished", peerName);
        }
        private bool LoggingMessageHandler(BitcoinEndpoint endpoint, IBitcoinMessage message)
        {
            Console.WriteLine(">>command: {0}", message.Command);

            if (message is InvMessage)
            {
                InvMessage invMessage = (InvMessage) message;
                foreach (InventoryVector vector in invMessage.Inventory)
                {
                    Console.WriteLine("\t{0} {1}", vector.Type.ToString().PadRight(16), BitConverter.ToString(vector.Hash));
                }
            }

            if (message is GetHeadersMessage)
            {
                GetHeadersMessage getHeadersMessage = (GetHeadersMessage) message;

                Console.WriteLine("\tprotocol: {0}", getHeadersMessage.ProtocolVersion);
                foreach (byte[] hash in getHeadersMessage.LocatorHashes)
                {
                    Console.WriteLine("\t{0}", BitConverter.ToString(hash));
                }
                Console.WriteLine("\t{0} (stop)", BitConverter.ToString(getHeadersMessage.HashStop));

                endpoint.WriteMessage(new InvMessage(new InventoryVector[]
                {
                    new InventoryVector(InventoryVectorType.MsgBlock, blockHash1)
                }));
            }

            if (message is GetDataMessage)
            {
                GetDataMessage getDataMessage = (GetDataMessage) message;
                foreach (InventoryVector vector in getDataMessage.Inventory)
                {
                    Console.WriteLine("\t{0} {1}", vector.Type.ToString().PadRight(16), BitConverter.ToString(vector.Hash));
                }
            }

            if (message is BlockMessage)
            {
                BlockMessage blockMessage = (BlockMessage) message;
                foreach (Tx tx in blockMessage.Transactions)
                {
                    Console.WriteLine("\tInputs:");
                    foreach (TxIn input in tx.Inputs)
                    {
                        Console.WriteLine("\t\t{0} seq. {1:X}", BitConverter.ToString(input.PreviousOutput.Hash), input.Sequence);
                    }
                    Console.WriteLine("\tOutputs:");
                    foreach (TxOut output in tx.Outputs)
                    {
                        Console.WriteLine("\t\t{0}, script: {1}", output.Value, BitConverter.ToString(output.PubkeyScript));
                    }
                }
            }
            if (message is MerkleBlockMessage)
            {
                MerkleBlockMessage merkleBlockMessage = (MerkleBlockMessage) message;

                BitArray flagsBitArray = new BitArray(merkleBlockMessage.Flags);
                StringBuilder flagsSb = new StringBuilder();
                foreach (bool flag in flagsBitArray)
                {
                    flagsSb.Append(flag ? "1" : "0");
                }

                Console.WriteLine("\tTotalTransactions: {0}", merkleBlockMessage.TotalTransactions);
                Console.WriteLine("\tFlags:             {0}", flagsSb);

                foreach (byte[] hash in merkleBlockMessage.Hashes)
                {
                    Console.WriteLine("\t\t{0}", BitConverter.ToString(hash));
                }
            }

            if (message is BitcoinMessage)
            {
                BitcoinMessage rawMessage = (BitcoinMessage) message;
                Console.WriteLine(">>payload: {0}", BitConverter.ToString(rawMessage.Payload));
            }

            return true;
        }
        private void ConnectionHandler(BitcoinConnection connection)
        {
            using (BitcoinEndpoint endpoint = new BitcoinEndpoint(LoggingMessageHandler))
            {
                endpoint.Connect(connection);

                Thread.Sleep(1000);
                endpoint.WriteMessage(new BitcoinMessage(InvMessage.Command, new byte[0]));
            }
        }
 private void SendKnownAddresses(BitcoinEndpoint endpoint)
 {
     List<NetAddr> addresses = new List<NetAddr>();
     List<NodeConnection> currentConnections = connectionCollection.GetConnections();
     foreach (NodeConnection connection in currentConnections)
     {
         //todo: filter loopback addresses
         NetAddr addr = new NetAddr(
             //todo: use last message date instead
             (uint) connection.Endpoint.PeerInfo.VersionMessage.Timestamp,
             connection.Endpoint.PeerInfo.VersionMessage.Services,
             endpoint.PeerInfo.IpEndpoint.Address,
             (ushort) endpoint.PeerInfo.IpEndpoint.Port);
         addresses.Add(addr);
     }
     AddrMessage addrMessage = new AddrMessage(addresses.Take(AddrMessage.MaxAddressesPerMessage).ToArray());
     endpoint.WriteMessage(addrMessage);
 }