* Start refactoring BroadcastTransactionTest to use new SpvNodeFundedWalletBitcoind fixture * Double timeout to 10.seconds on spv node disconnect * Attempt to bump disconnect even more * Add more logging around starting and stoping spv node to try and debug failures with fixtures on test suites * move starting of spv node into one place in the fixtures -- createSpvNode() --, also look at ordering of destruction to make sure that the spv node is stopped/destroyed BEFORE bitcoind is stopped/destroyed. If the inverse order happens, our spv node won't receive a response from bitcoind and will hang waiting for the Tcp connection to close gracefully * Try switching from to to get CI to pass * Add more logging and throws to try and debug failures on ci * Add logging in the case we send a close command and peer isn't defined * Match on Tcp.Connect on default receive in P2PClient * Make SpvNode.disconnect() check to see if we are connected before attempting to disconnect * Add more logging in fixtures, change behavior of SpvNode.disconnect() to not throw if we are already disconnected * Switch to preferred way of terminating actor system in tests * Make PeerMessageSender.sendMsg() return a , make sure a message is not sent to P2PClient until we are fully intialized * Switch p2p logging to DEBUG * Complete disconnect promise on peer message recv in the case where we didn't have a peer to begin with * Make SpvNodeTest more robust, fix bug for when we send 'sendheaders' message. We shouldn't do this until our peer has sent us a verack * Only send 'sendheaders' message to our peer after we receive a 'sendheaders' message from our peer. Hopefully this solves async issues where we were sending 'sendheaders' before our handshake was fully completed with our peer which means we wouldn't get headers sent to us * Cleanup pt1 |
||
---|---|---|
.. | ||
src/main/scala/org/bitcoins/node | ||
README.md |
Bitcoin-S SPV node
This module is a Bitcoin SPV (simplified payment verification) node that peers with a Bitcoin Core node over the P2P network. It syncs block headers and does as much verification as possible with the data it has available.
The node supports bloom filters, and provides optional callbacks that notify consumers on events such as new blocks, filtered merkle blocks and transactions.
Caveats:
- This is a heavy work in progress, and should not be used for anything serious yet
- The node can only peer with one node on the P2P network right now, and that node must be passed in on startup. Eventually we want to support peer discovery through DNS seeds, as well as supporting multiple peers at the same time.
- The majority of the P2P code was written in late 2017, and as a consequence does not handle some of the newer P2P messages and functionality (including SegWit related messages).
Interesting files
Currently this project is a heavy WIP. The most important files are
Client
- this handles all of the networking code. Currently this uses Akka but the plan is to move away from Akka in the future and use a networking library with a smaller classpath footprint.PeerMessageReceiver
- this handles messages we receive on the P2P network. All messages are algebraic data types, so we can easily pattern match on them and implement features inPeerMessageReceiver.handleControlPayload
andPeerMessageReceiver.handleDataPayload
PeerMessageReceiverState
- the states that our peer message receiver can be in. It transitions through these states during the connect/disconnect process with our peer.PeerMessageSender
- this handles sending messages to our peer on the P2P network. Since we are a light client, we probably won't be sending a lot of messages to peers so this isn't that interesting.PeerHandler
- this combines aPeerMessageReceiver
and aPeerMessageSender
into a pair.Peer
- The low level socket details need to connect to a peer
Interesting tests
There is still a lot of code commented out on the project, but the tests should pass for the ones that are not. Interesting tests are
ClientTest
- currently tests that we can connect with peersPeerMessageHandlerTest
- tests that we can get our node into thePeerMessageReceiverState.Normal
state. This means we can send/receive arbitrary messages from our peer.- [
SpvNodeTest
] - tests that we can peer with abitcoind
and sync a block header
Main method
There's a main method available in
SpvNodeMain.scala
. Currently
(June 17th, 2019) the node peers with a locally running bitcoind
. It does not do
much interesting beyond that, although you can make it more interesting if you
modify the logging levels (look in
common-logback.xml) and pass in
some callbacks to the node on startup.