/// <summary>
/// Runs in the peers network loop and manages communication with the peer.
/// </summary>
/// <remarks>
/// Connect() must be called first.
/// </remarks>
/// <exception cref="PeerException">When there is a temporary problem with the peer and we should retry later.</exception>
public void Run()
{
// This should be called in the network loop thread for this peer
if (_conn == null)
{
throw new Exception("please call connect() first");
}
_running = true;
try
{
while (true)
{
var m = _conn.ReadMessage();
if (m is InventoryMessage)
{
ProcessInv((InventoryMessage)m);
}
else if (m is Block)
{
ProcessBlock((Block)m);
}
else if (m is AddressMessage)
{
// We don't care about addresses of the network right now. But in future,
// we should save them in the wallet so we don't put too much load on the seed nodes and can
// properly explore the network.
}
else
{
// TODO: Handle the other messages we can receive.
_log.WarnFormat("Received unhandled message: {0}", m);
}
}
}
catch (IOException e)
{
if (!_running)
{
// This exception was expected because we are tearing down the socket as part of quitting.
_log.Info("Shutting down peer loop");
}
else
{
Disconnect();
throw new PeerException(e);
}
}
catch (ProtocolException e)
{
Disconnect();
throw new PeerException(e);
}
catch (Exception e)
{
Disconnect();
_log.Error("unexpected exception in peer loop", e);
throw;
}
Disconnect();
}