MetacoSA / NBitcoin

Comprehensive Bitcoin library for the .NET framework.
MIT License
1.88k stars 847 forks source link

Unable to cast object of type 'NBitcoin.Protocol.VerAckPayload' to type 'NBitcoin.Protocol.VersionPayload' #573

Open GSPP opened 6 years ago

GSPP commented 6 years ago

This exception can happen in VersionHandshake at https://github.com/MetacoSA/NBitcoin/blob/fb897dfbf87a3d9511062e662964c867b015041d/NBitcoin/Protocol/Node.cs#L1071

System.InvalidCastException: 'Unable to cast object of type 'NBitcoin.Protocol.VerAckPayload' to type 'NBitcoin.Protocol.VersionPayload'.'

NicolasDorier commented 6 years ago

The problem is not with the code, but with the node software which sent you a VerAck as first message when you initiate the connection.

GSPP commented 6 years ago

The code seems to explicitly expect such a message: https://github.com/MetacoSA/NBitcoin/blob/fb897dfbf87a3d9511062e662964c867b015041d/NBitcoin/Protocol/Node.cs#L1062

In any case a protocol error should not crash the local code with an InvalidCastException.

NicolasDorier commented 6 years ago

so you would like another clearer exception?

GSPP commented 6 years ago

I do not quite know what the right solution is. Why is this invalid message being explicitly allowed just to lead to a crash? It seems either it should be filtered away or a sane exception be raised.

It seems the normal approach for VersionHandshake is to simply ignore all irrelevant messages. Not sure why this is different.

I used NBitcoin to crawl and connect to the entire network. I saw this case appear multiple times.

NicolasDorier commented 6 years ago

Before sending any message to the other peer the handshake need to be complete. I can't ignore it because I need to know what the other peer accept as protocols.

Some other peers do not follow the protocol, you should try/catch and disconnect from them. Not trying to continue interacting with them.