-
Notifications
You must be signed in to change notification settings - Fork 38.7k
zmq: mempool notifications #7753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
325afe6 to
4e3039b
Compare
|
I was planning to submit a pull request to change this kind of notifications. The current solution is not very elegant and doesn't scale. The command line arguments should be clean. So if you don't mind I'll try to explain here the idea using this example: Usage: Here the notify argument creates one notification pipeline composed by one source of events (mempool), one filter element to transform the event in json and one sink of events (zmqpub), all connected with the operator Is this design, zmq elements are concrete types of sinks. But we could have more, like log to file or pub to nsq queue. We could have chain and wallet sources for instance. We could have filters to transform to other types. WDYT? |
|
concept ACK |
|
@promag I'm all for making it more flexible, but what you're proposing sounds like the gstreamer syntax and that's IMO even harder to use than the current arguments. I've needed to do a few media pipelines in my PhD research but never managed to really master it. Our basic idea with the ZMQ notifications is that one notification system exists. From there on everything (e.g. forward to the notification system of your choice) can be handled by external software. I don't want too much notification-related complexity in core. Aside, this is the wrong place to discuss this. Let's focus on the software change here. Please create a new issue. |
|
@laanwj yes gstreamer all over the comment. I'll move the discussion to a new issue. utACK. |
|
|
||
| #if ENABLE_ZMQ | ||
| pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs); | ||
| pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs, &mempool); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels a bit hacky.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better suggestions?
As I see ti there are two alternatives:
- use the global mempool object (ugly)
- pass the mempool in (slightly les ugly)
Another option would be to move the instantiation of the CZMQPublishMempoolNotifier(mempool) here. But I'd like as little zmq specific code in init. But it may be the least ugly option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this implementation approach is reasonable and I also don't see a more elegant way to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I would rename CreateWithArguments to just Create and move the following from src/init.cpp to Create.
if (pzmqNotificationInterface) {
RegisterValidationInterface(pzmqNotificationInterface);
}
Edit:
Because in your notifier you connect the signals so it also makes sense to connect the remaining signals here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, will move that line.
|
Awesome! Some ideas / conceptual questions:
|
|
Code Review utACK. |
👍 |
What if you use the following sequence:
You may have some duplicates in the first run, e.g., adds which already show up in the mempool requested, removes which were already removed, but I think due to the idempotent nature of the events (just add and remove) the overall state will be the same?
Missing notifications are a possibiltiy with zmq. But I'd say this is a matter of sizing buffers appropriately, and dedicating a thread to listening to zmq requests. To reliably detect missing notifications we could add sequence numbers to the events, as I think zmq guarantees that events from a single source are delivered in order. Then again if we do this we probably want it for all the event types... I actually suggested it for the first zmq proposal.
I thought about sending a generic stats packet with every mempool event, but as you can receive tons of them I don't want to make the individual events too big and include things you can compute yourself. But no problems with just the size / # transactions.
Absolutely, I'll open source it soon, will be part of a bc-monitor repo. Eventually I hope to make a tool like tor-arm (just renamed to nyx IIRC) which allows watching all aspects of a node. |
00b0a36 to
4e3039b
Compare
|
Tested ACK 4e3039b |
|
lightly tested ACK 4e3039b |
src/txmempool.h
Outdated
| /** Reason why a transaction was removed from the mempool, | ||
| * this is passed to the notification signal. | ||
| */ | ||
| enum MemPoolRemovalReason { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This enum seems to be part of the ZMQ API, so we'll probably want some stability across versions. Things like MPR_EXPIRY and MPR_SIZELIMIT seem quite specific to the existing implementation.
|
Ok added two commits:
|
bde966e to
85cbe30
Compare
|
Rebased after #7762 |
Add notification signals to make it possible to subscribe to mempool changes: - NotifyEntryAdded(const CTxMemPoolEntry &)> - NotifyEntryRemoved(const CTxMemPoolEntry &, MemPoolRemovalReason)> Also add a mempool removal reason enumeration, which is passed to the removed notification based on why the transaction was removed from the mempool.
Replace factories list with calls to a function. This simplifies the code (every notifier is only created once anyway), and makes it possible to pass arguments to notifier contructors.
Add notifications when transactions enter or leave the mempool. These can be enabled with `pubmempool`: - `mempooladded`: a transaction was added to the mempool - `mempoolremoved`: a transaction was removed from the mempool This allows third-party software to keep track of what is in the mempool in real time.
Make the registration process less circuitous by making the notifiers listen to their appropriate events themselves
85cbe30 to
1bbe366
Compare
|
Rebased, and changed the enums (both for the mempool and for the zmq protocol) to c++11 enums. |
|
lightly tested ACK 1bbe366 |
|
Needs rebase. |
|
Still needs rebase. |
|
ACK. I have a rebased version of this branch at 'jmcorgan/2016_03_zmq_mempool_notifications'. |
|
@jmcorgan feel free to open a PR of your rebases version and take over the lead. |
|
Continued in #8549 |
|
Closing in favor of #8549 |
Add notifications when transactions enter or leave the mempool.
These can be enabled with
zmqpubmempool:mempooladded: a transaction was added to the mempoolmempoolremoved: a transaction was removed from the mempoolThis allows third-party software to keep track of what is in the mempool in real time. For example a mempool monitor I'm working on:

It also makes it possible to keep statistics on why transactions disappear from the mempool.
Full documentation: https://github.com/bitcoin/bitcoin/blob/325afe68381d59f1b95a690927c4a8ea886ac791/doc/zmq.md#mempooladd
See individual commits for details.
Current issues:
NotifyEntryAdded: WARNING: zmq send failed with code -1spam in log if "-zmqpubmempool" is not enabled.