public VersionMessage(NetworkParameters networkParams, uint newBestHeight) : base(networkParams) { ClientVersion = NetworkParameters.ProtocolVersion; LocalServices = 0; Time = UnixTime.ToUnixTime(DateTime.UtcNow); // Note that the official client doesn't do anything with these, and finding out your own external IP address // is kind of tricky anyway, so we just put nonsense here for now. MyAddr = new PeerAddress(IPAddress.Loopback, networkParams.Port, 0); TheirAddr = new PeerAddress(IPAddress.Loopback, networkParams.Port, 0); SubVer = "BitCoinSharp 0.3-SNAPSHOT"; BestHeight = newBestHeight; }
/// <summary> /// Connect to the given IP address using the port specified as part of the network parameters. Once construction /// is complete a functioning network channel is set up and running. /// </summary> /// <param name="peerAddress">IP address to connect to. IPv6 is not currently supported by BitCoin. If port is not positive the default port from params is used.</param> /// <param name="networkParams">Defines which network to connect to and details of the protocol.</param> /// <param name="bestHeight">How many blocks are in our best chain</param> /// <param name="connectTimeout">Timeout in milliseconds when initially connecting to peer</param> /// <exception cref="IOException">If there is a network related failure.</exception> /// <exception cref="ProtocolException">If the version negotiation failed.</exception> public NetworkConnection(PeerAddress peerAddress, NetworkParameters networkParams, uint bestHeight, int connectTimeout) { _params = networkParams; remoteIp = peerAddress.Addr; var port = (peerAddress.Port > 0) ? peerAddress.Port : networkParams.Port; var address = new IPEndPoint(remoteIp, port); _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.Connect(address); _socket.SendTimeout = _socket.ReceiveTimeout = connectTimeout; _out = new NetworkStream(_socket, FileAccess.Write); _in = new NetworkStream(_socket, FileAccess.Read); // the version message never uses check-summing. Update check-summing property after version is read. serializer = new BitcoinSerializer(networkParams, true); // SDL: Checksuming now ALWAYS necessary versionMessage = Handshake(networkParams, bestHeight); // newer clients use check-summing serializer.UseChecksumming(versionMessage.ClientVersion >= 209); // Handshake is done! }
/// <summary> /// Called by a <seealso cref="Peer"/> when a transaction is pending and announced by a peer. The more peers announce the /// transaction, the more peers have validated it (assuming your internet connection is not being intercepted). /// If confidence is currently unknown, sets it to <seealso cref="ConfidenceLevel#NOT_SEEN_IN_CHAIN"/>. Listeners will be /// invoked in this case. /// </summary> /// <param name="address"> IP address of the peer, used as a proxy for identity. </param> public virtual void markBroadcastBy(PeerAddress address) { lock (this) { broadcastBy.Add(address); if (ConfidenceLevel == ConfidenceType.UNKNOWN) { confidenceLevel = ConfidenceType.NOT_SEEN_IN_CHAIN; } } OnConfidenceChanged(); }
/// <summary> /// Construct a peer that handles the given network connection and reads/writes from the given block chain. Note that /// communication won't occur until you call connect(). /// </summary> public Peer(NetworkParameters networkParams, PeerAddress address, BlockChain blockChain) : this(networkParams, address, 0, blockChain) { }
/// <summary> /// Construct a peer that handles the given network connection and reads/writes from the given block chain. Note that /// communication won't occur until you call Connect(). /// </summary> /// <param name="bestHeight">Our current best chain height, to facilitate downloading.</param> public Peer(NetworkParameters networkParams, PeerAddress address, uint bestHeight, BlockChain blockChain) { _params = networkParams; _address = address; _bestHeight = bestHeight; _blockChain = blockChain; _pendingGetBlockFutures = new List<GetDataFuture<Block>>(); }
/// <exception cref="ProtocolException"/> protected override void Parse() { var numAddresses = ReadVarInt(); // Guard against ultra large messages that will crash us. if (numAddresses > MaxAddresses) { throw new ProtocolException("Address message too large."); } Addresses = new List<PeerAddress>((int) numAddresses); for (var i = 0UL; i < numAddresses; i++) { var addr = new PeerAddress(Params, Bytes, Cursor, ProtocolVersion); Addresses.Add(addr); Cursor += addr.MessageSize; } }
/// <exception cref="ProtocolException"/> protected override void Parse() { ClientVersion = ReadUint32(); LocalServices = ReadUint64(); Time = ReadUint64(); MyAddr = new PeerAddress(Params, Bytes, Cursor, 0); Cursor += MyAddr.MessageSize; TheirAddr = new PeerAddress(Params, Bytes, Cursor, 0); Cursor += TheirAddr.MessageSize; // uint64 localHostNonce (random data) // We don't care about the localhost nonce. It's used to detect connecting back to yourself in cases where // there are NATs and proxies in the way. However we don't listen for inbound connections so it's irrelevant. _localHostNonce = ReadUint64(); // string subVer (currently "") SubVer = ReadStr(); // int bestHeight (size of known block chain). BestHeight = ReadUint32(); }
/// <summary> /// Add an address to the list of potential peers to connect to. /// </summary> public void AddAddress(PeerAddress peerAddress) { // TODO(miron) consider de-duplication _inactives.Enqueue(peerAddress); }