Skip to content
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

Add -walletnotify to call an external script on wallet transactions #1974

Merged
merged 1 commit into from
Feb 22, 2013

Conversation

kjj2
Copy link

@kjj2 kjj2 commented Nov 3, 2012

Exactly like -blocknotify, except that it gives the TxID of transactions that hit the wallet.

Note that this is NOT a payment notification. It will trigger on outgoing transactions too, and can trigger multiple times on the same transaction.

@freewil
Copy link
Contributor

freewil commented Nov 3, 2012

This is repetitive and doesn't add any new functionality. You can check for new incoming transactions after -blocknotify and obviously you will already know about outgoing transactions.

@kjj2
Copy link
Author

kjj2 commented Nov 3, 2012

No, this triggers when a transaction comes in or goes out in any way, not just when blocks hit. And now that we have the raw transaction API and offline signing and transmission is relatively easy, it is no longer obvious when transactions go out.

@sipa
Copy link
Member

sipa commented Nov 5, 2012

This is probably useful for a lot of people who would otherwise depend on polling (or using centralized services to know when to poll), but it hopefully doesn't inspire people to do 0-conf accepts.

ACK.

if ( !strCmd.empty())
{
boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
boost::thread t(runCommand, strCmd); // thread runs free
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This opens up a potential DoS, I can send you a gazillion tiny transactions to try to get you to spawn gazillions of threads.

I'd suggest not notifying transactions that are less than MIN_TX_FEE/-mintxfee (see code after // Fee-per-kilobyte amount considered the same as "free" in main.cpp)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh. I'd worry that callers wouldn't be aware of that subtle detail and would have applications which missed small transactions.

If the API worked in a way that it could simply be rate limited to not notify more than X times per second then that would be a preferable option, but the 1:1 behavior doesn't seem to work for that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this triggers when a transaction updates the wallet, a potential DOS attacker would need to know both your IP (because no one will relay), and one of your addresses (pubkeys) to do their dust attack. In my opinion, there are easier ways for them to DOS you at that point.

Also, the fee calculations are not trivial. Adding that would require either duplicating a lot of code, or moving those calculations into their own function.

Rate limiting would be a bit easier, but the best way to do it would be open to question. Make a queue to toss them into, and then have a thread poll and dump that queue every 30 seconds or so?

I made this after two people popped into IRC, within an hour or two of each other, both having problems figuring out the "right" way to spot new transactions coming in to their wallets. This solves their problems quickly and simply. I'd rather see this get out quickly for those people, along with a note or something about the potential danger (and how to mitigate it for critical nodes) than make them keep waiting while we figure out how to make it safer under circumstances that may or may not ever happen.

Then again, no one comes bitching to me when things don't work, so I defer to the judgment of the more experienced developers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be curious to see what happens if you run this experiment on testnet:

  • Create 100 transactions, each with 1 well-aged input and (oh, I dunno) 100 output that all go to the same wallet (100 different addresses, though).
  • Now send them all at the same time.

If the inputs are old enough and large enough, you could perform the above attack paying minimal transaction fees.

I predict Bad Things will happen as the bitcoin process forks 10,000 times. -blocknotify doesn't have to worry about these issues because we've got one block on average every 10 minutes.

-walletnotify=/path/to/named_pipe would be safer. Actually, -blocknotify=/path/to/named_pipe might be useful, too...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only have one live wallet with RPC access at the moment, so I wasn't able to test your setup exactly. But I did create 10 new keys in my wallet, and I made a sendtomany raw transaction that sent something to each of them, then signed it offline and relayed it through a different node.

http://blockexplorer.com/tx/7650e6a4ef61485a3f6c44fbeaa1063c6ea0bbe4bf040fb91c6fd71888a81677

That transaction triggered walletnotify exactly twice on my box, once when it entered the memory pool, and once when the block containing it arrived. It doesn't trigger for each input or each output of a transaction, just for each transaction-event.

I like the named pipe thing too. I'll look into it.

@jgarzik
Copy link
Contributor

jgarzik commented Nov 16, 2012

ACK... with maybe some doc describing some usage issues like what Gavin raised.

@CodeShark
Copy link
Contributor

I've had a need for this kind of alert in applications before and as a result ended up writing a custom bitcoin client with its own internal filtering. I would love to be able to attach a listener to the mempool (perhaps SyncWithWallets could be extended to this end) which can perform filtering beyond just CWallet::IsMine(). Perhaps we can also filter out transactions below a certain size threshold, for instance.

The need for being able to monitor transactions actually motivated #2121, which combined with -walletnotify would allow realtime tracking of payments without having to store any private keys at all.

@rebroad
Copy link
Contributor

rebroad commented Dec 24, 2012

How about instead an option to output transaction information to a file instead? That way, a separate program can deal with the problem of flooding, etc, and triggering commands from output as it appears in the file.

@gavinandresen
Copy link
Contributor

Couple of ACKS... this is definitely better than what we have now. I'm going to pull.

gavinandresen added a commit that referenced this pull request Feb 22, 2013
Add -walletnotify to call an external script on wallet transactions
@gavinandresen gavinandresen merged commit 49e332f into bitcoin:master Feb 22, 2013
Bobalot pushed a commit to Bobalot/bitcoin that referenced this pull request Mar 21, 2013
Add -walletnotify to call an external script on wallet transactions
laudney pushed a commit to reddcoin-project/reddcoin-3.10 that referenced this pull request Mar 19, 2014
Add -walletnotify to call an external script on wallet transactions
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants