BitcoinTalk
I broke my wallet, sends never confirm now.

View Satoshi only

External link

Nothing I send gets confirmed now. 

Here's how I did it:

I was sending out payments under .01 in size and not paying a transaction fee, which of course were never confirmed.

Here's a guess as to why it broke my wallet:

Because the change leftover was also then never confirmed, yet my client treats it as if it was so includes those amounts in the amounts it sends out.



I've only lost 100btc, so I'm not real worried, but if you know how to fix it without too much trouble, that'd be nice.
You could edit your client to make it include into blocks any transactions without looking at the fee. And then wait a month or so until you make a block which will include your transactions... Or wait until someone else with a custom client includes your transactions in his block.
Quote from: kermit
Because the change leftover was also then never confirmed, yet my client treats it as if it was so includes those amounts in the amounts it sends out.

This seems likely. Try sending a ton of 0.01 transactions -- most of these transactions will work if this is the case.

Or wait until someone else with a custom client includes your transactions in his block.

For this you'll want to use the -maxconnections switch with a high number of connections, because propagation of your invalid transaction will be very poor.

You could also "double-spend" your pre-experiment coins by acting as though the unconfirmed transactions never happened. A wallet backup would roll things back, for example.
For this you'll want to use the -maxconnections switch with a high number of connections, because propagation of your invalid transaction will be very poor.

Huh? Clients don't propagate what they consider invalid? I thought that they just didn't include it in their blocks...
Huh? Clients don't propagate what they consider invalid? I thought that they just didn't include it in their blocks...

Hmm; I'm not sure about this case. They're not working on your new transaction because the previous transaction wasn't in a previous block and isn't in their memory pool. I don't know if they'd relay it.
Hey, so i've been the recipient of a few of these microtransactions
so now i have several transactions in my wallet that are now perpetually in the '0/unconfirmed' state

so the question is, if i send stuff, will it include those bitcoins in my sends, thus propagating the invalid chain? what is to be done here?

note also that this seems like a valid way to spam the network - send a bunch of microtransactions without the fee, so you can effectively multispend the same bit of btc and spam everyone's wallets with bogus microtransactions at no cost to you?
Hey, so i've been the recipient of a few of these microtransactions
so now i have several transactions in my wallet that are now perpetually in the '0/unconfirmed' state
They will get confirmed when someone that doesn't require fees include them in his/her block.
so the question is, if i send stuff, will it include those bitcoins in my sends, thus propagating the invalid chain? what is to be done here?
There is no invalid chain just because someone didn't want to pay the fee. It will just take longer for them to get included in a block and until then they can be double spend if someone hasn't heard about them. BTW if nodes don't propagate transactions just because they don't like them it will be dangerous since it will be easier for someone to double spend bitcoins.
note also that this seems like a valid way to spam the network - send a bunch of microtransactions without the fee, so you can effectively multispend the same bit of btc and spam everyone's wallets with bogus microtransactions at no cost to you?
You can also send the same 1BTC back and forth between two clients, using different addresses every time. If you do it fast enough you will probably be able to fill up the block that everyone is trying to generate and therefore make the network really slow and lower the chances for legitimate transactions to get into blocks... Also if you do it reeeealllly fast you could saturate the network for a long time, even after you exit the network. You will just leave the rest trying to fit hundreds of thousands of transactions into blocks... I don't know if there is any protection in the protocol from this kind of attacks... If not, they are quite easy to be done. We really need fixed transaction fees with the option to change your preferences on what is the fixed price you accept and what fee to include in your own transactions.
it seems this could take down the whole network depending on the logic behind combining lots.. as in if the micropayment without fee is combined with a normal transaction and has change, both the send and the change would never confirm either.  so now you have 2 lots that will never confirm.  repeat.

and it does seem the client lets you spend unconfirmed coin.
Hey, so i've been the recipient of a few of these microtransactions
so now i have several transactions in my wallet that are now perpetually in the '0/unconfirmed' state
They will get confirmed when someone that doesn't require fees include them in his/her block.

yes and.... at this point /all/ clients require fees for transactions <0.01, do you have any reason to expect that this will change at any point in the future? i don't. so "never will get confirmed" seems a reasonable approximation to reality.

Quote
so the question is, if i send stuff, will it include those bitcoins in my sends, thus propagating the invalid chain? what is to be done here?
There is no invalid chain just because someone didn't want to pay the fee. It will just take longer for them to get included in a block and until then they can be double spend if someone hasn't heard about them. BTW if nodes don't propagate transactions just because they don't like them it will be dangerous since it will be easier for someone to double spend bitcoins.

yes but the problem is that the client doesn't let the user choose which coins to spend, it does it all "automagically" behind the scenes. so how would a user know if he's sending confirmed coins or unconfirmed coins?

Quote
note also that this seems like a valid way to spam the network - send a bunch of microtransactions without the fee, so you can effectively multispend the same bit of btc and spam everyone's wallets with bogus microtransactions at no cost to you?
You can also send the same 1BTC back and forth between two clients, using different addresses every time. If you do it fast enough you will probably be able to fill up the block that everyone is trying to generate and therefore make the network really slow and lower the chances for legitimate transactions to get into blocks... Also if you do it reeeealllly fast you could saturate the network for a long time, even after you exit the network. You will just leave the rest trying to fit hundreds of thousands of transactions into blocks... I don't know if there is any protection in the protocol from this kind of attacks... If not, they are quite easy to be done. We really need fixed transaction fees with the option to change your preferences on what is the fixed price you accept and what fee to include in your own transactions.

yes, but that's a separate issue. i'm really trying to figure out what, if anything, to be doing about the handful of never-to-be-confirmed transactions i have in my wallet, whether the client will prioritize sending other coins first or not, and if not... that means it's possible that i'll never be able to make a send transaction that will be confirmed, because the unconfirmed bits of coin will be included. which would in turn mean that my whole wallet is foobar.
I checked the code. It seems that the transactions will be relayed, since they pass AcceptToMemoryPool. The network will tend to forget these transactions because the memory pool is cleared when Bitcoin shuts down, and as far as I can tell nodes never relay transactions that they already have in their memory pool.

Quote from: Tritonio
I don't know if there is any protection in the protocol from this kind of attacks

There is. The more transactions waiting to be included in a block, the higher the transaction fee has to be for one to get in.
And in the future node could certainly drop connections from nodes that generate bad transactions.
I checked the code. It seems that the transactions will be relayed, since they pass AcceptToMemoryPool. The network will tend to forget these transactions because the memory pool is cleared when Bitcoin shuts down, and as far as I can tell nodes never relay transactions that they already have in their memory pool.

Quote from: Tritonio
I don't know if there is any protection in the protocol from this kind of attacks

There is. The more transactions waiting to be included in a block, the higher the transaction fee has to be for one to get in.

theymos: well... the problem is that it causes problems for the wallets that happen to have received those transactions. my wallet now includes a bunch of small transactions that will never be confirmed (due to their not having paid the requisite fees).

since the client does not let the user control which coins to send, any transaction i send out in the future is liable to try to include those coins in the outgoing payment, which, in turn, will never get confirmed, thus borking my whole wallet.

so say a 'rogue' client harvests a bunch of addresses of the net (these forums are a good and ripe place), and starts sending out a bunch of .000001 payments with no fee. now these wallets will all be contaminated with these never-to-be-confirmed payments, and since the client doesn't allow one to choose which coins get sent, they may be included in future outgoing payments, which will also never get confirmed.

so what should i do to 'clear' my wallet? i'd need some custom tool to be able to send /specific coins/, so that i can send them all to another wallet and drop the contaminated one.

and more importantly, for the future - how do we address this problem?
At (roughly) line 3191 in main.cpp (SelectCoins), change the if statement to this:
Code:
if (!pcoin->IsFinal() || pcoin->fSpent || pcoin->GetDepthInMainChain() < 1)

Your client will then no longer consider coins with 0 confirmations when choosing coins.
At (roughly) line 3191 in main.cpp (SelectCoins), change the if statement to this:
Code:
if (!pcoin->IsFinal() || pcoin->fSpent || pcoin->GetDepthInMainChain() < 1)

Your client will then no longer consider coins with 0 confirmations when choosing coins.

IMO, this should make it into the upstream bitcoin client, as either
  • a command line switch, requiring confirmation for all sent coins
  • a two-pass search:  search first for confirmed coins.  if not enough confirmed coins are available, use unconfirmed coins.
The best option might be four passes at 120, 6, 1, and 0, to somewhat prioritize based on depth.
and more importantly, for the future - how do we address this problem?

I really don't care about extremelly fast transactions. It would be enough for me if Bitcoin didn't even show unconfirmed transactions and didn't even try to spend them before they get confirmed. FFS just wait 10minutes for a block to appear confirming them.  Grin
At (roughly) line 3191 in main.cpp (SelectCoins), change the if statement to this:
Code:
if (!pcoin->IsFinal() || pcoin->fSpent || pcoin->GetDepthInMainChain() < 1)

Your client will then no longer consider coins with 0 confirmations when choosing coins.

thanks theymos for the patch!

i guess now i have to figure out how to build bitcoind.... Smiley

or maybe i'll just wait around for this to make it into the next official release...
if satoshi agrees with jgarzik as far as including those options in mainline, maybe i don't have to wait that long...
Some people might want to add the

pcoin->GetDepthInMainChain() < 1

in GetBalance() too.
Some people might want to add the

pcoin->GetDepthInMainChain() < 1

in GetBalance() too.

Well, I would rather split "balance" in two:  confirmed and unconfirmed balances.
ok, so i built a modified bitcoind, with the addition of 'pcoin->GetDepthInMainChain() < 1' to both SelectCoins and GetBalance.

My 'stock client' balance shows as 131.00139787, and my modified client balance shows as 130.92112098, so i have about 0.08xx of "bad" bitcoins' worth of transactions in my wallet.

So I guess now, all i need to do is create another wallet, and then send all the "good coins" from my old wallet to my new one (or, i guess... i could just use the same wallet, since my bitcoind won't try to send the bad coins, i can just ignore them....)

But yes, I hope the modifications as described by jgarzik (being configurable with cli switches/checkboxes) do make it into mainline - because otherwise it's too easy to 'poison' people's wallets with bogus transactions.
As you figured out, the root problem is we shouldn't be counting or spending transactions until they have at least 1 confirmation.  0/unconfirmed transactions are very much second class citizens.  At most, they are advice that something has been received, but counting them as balance or spending them is premature.

I made changes so they show up in lighter print, with the credit amount in square brackets like [+1.23], and the amount not counted towards your balance and not available for spending.  This doesn't apply to transactions you sent, which you implicitly trust, since you wrote them.

I didn't make it (+1.23) because parenthesis in accounting means negative.  I hope square brackets is different enough to be clear what is meant.

The JSON-RPC interface can still see 0/unconfirmed if it wants by specifying 0 confirmations.

I uploaded the changes to SVN rev 158.  I will post a 0.3.13 RC shortly.

If you have any of these transactions in your wallet, do not send any payments until you've upgraded to 0.3.13, which will be coming soon.

If you've already sent any of these transactions, or you're the creator of them, then use theymos' patch or make the following change and use it to send your clean transactions to a new wallet to clean things up.

change:
    if (pcoin->GetDepthInMainChain() < 1 && pcoin->GetDebit() <= 0)
        continue;
to:
    if (pcoin->GetDepthInMainChain() < 1)
        continue;
So in .13 1 confirm is good enough to pay someone with, but it takes 6 to display "confirmed" in the GUI.   This is inconsistant.  This coin is good enough to pay you with but not good enough for me to accept?  I don't know the logic behind the 6, but whatever it is, if its only used to decide which word to display, then is it really  representing anything at all?
That's going to be more of a SelectCoins thing.

SVN rev 161 has a refinement to recursively determine if your own unconfirmed transactions can be spent.  This is needed because you should be able to spend your own change right away.

The new recursive determination is: 0/unconfirmed can be spent if it's yours and all its dependencies are either in a block or also yours.

Here's a Windows build:
http://www.bitcoin.org/download/bitcoin-0.3.13.2-win32-setup.exe

This version is an improvement if you already had a 0/unconfirmed transaction and might have already spent it.  If you were the original creator of a 0/unconfirmed transaction, you still need theymos' patch instead.