Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: joshlang on August 26, 2013, 05:21:57 PM



Title: Transactions with input & output count == 0??
Post by: joshlang on August 26, 2013, 05:21:57 PM
I've been receiving "tx" messages across the wire with 0 inputs and 0 outputs.  Literally the payload is 10 bytes { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }.  (Version = 1, 0 inputs, 0 outputs, LockTime = 0)

Any idea what those are all about?  It's just occasionally.  Do they have special purposes or are they just a misbehaving client?


Title: Re: Transactions with input & output count == 0??
Post by: gmaxwell on August 26, 2013, 06:49:12 PM
Somehow these end up in some reference client wallets, and then they rebroadcast them.

It's been observed a number of times, but a cause has not been determined.


Title: Re: Transactions with input & output count == 0??
Post by: sebastian on August 27, 2013, 02:50:26 AM
Can be 2 causes:

1: Certain clients use these transactions as "ping" or "keepalive" to make sure NATs do not tear down the Connection due to inactivity.
2: Malwritten clients, when served with a amount to send = 0 BTC by the end user (propably by mistake, user simply forgot to enter amount), do not validate that the clients amount exceed 0 Before attempting to create a transaction. When the client attempt to create the transaction, it finds out that theres no need for inputs anymore ("do until"-loop) because the amount has been fulfilled. And theres no outputs to add, because the client automatically deletes any outputs with amount=0.
Then it ends up with a "empty" transaction, and sends the "empty" transaction.

Those transactions should not harm the network, since each client can only "hold" one such transaction at one time, since its not unique. So its not possible to "flood" a client with such transactions since it will only store one copy of each transaction newertless.

So each block will only store one single copy of these transactions, and each client will only store one such transaction in memory.

So maybe its not a bad idea to keep the possibility for these transactions since they propably fulfil a function to keep holes in NAT open.


Title: Re: Transactions with input & output count == 0??
Post by: TierNolan on August 27, 2013, 09:54:45 AM
Can be 2 causes:

1: Certain clients use these transactions as "ping" or "keepalive" to make sure NATs do not tear down the Connection due to inactivity.

There is a ping/pong system already as part of the protocol.

Quote
Those transactions should not harm the network, since each client can only "hold" one such transaction at one time, since its not unique. So its not possible to "flood" a client with such transactions since it will only store one copy of each transaction newertless.

Heh, true.  Are 0 input/output transactions actually valid.  I thought at least 1 input and 1 output was mandatory (or 0 inputs for coinbase).  You can have 0 valued outputs though.

Quote
So each block will only store one single copy of these transactions, and each client will only store one such transaction in memory.

Have any actually ended up in the block chain?


Title: Re: Transactions with input & output count == 0??
Post by: piotr_n on August 27, 2013, 10:39:29 AM
I've been receiving "tx" messages across the wire with 0 inputs and 0 outputs.  Literally the payload is 10 bytes { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }.  (Version = 1, 0 inputs, 0 outputs, LockTime = 0)

Any idea what those are all about?  It's just occasionally.  Do they have special purposes or are they just a misbehaving client?
Misbehaving client - I immediately ban nodes sending me a tx with no inputs, though still received 52 of such in the last 40 hours.
It's not a big problem for the network - much bigger problem are big txs with "correct horse battery staple" inputs, since these are technically valid (thus no reason to ban a peer), but they take so much more of our b/w (and CPU, if your node gets to verify them).


Title: Re: Transactions with input & output count == 0??
Post by: joshlang on August 27, 2013, 11:55:01 AM
Quote from: TierNolan
Heh, true.  Are 0 input/output transactions actually valid.  I thought at least 1 input and 1 output was mandatory (or 0 inputs for coinbase).  You can have 0 valued outputs though.

Meh.  According to spec, no, they're not valid.  But they get serialized fine, it's just nothing happens with them.

Quote from: TierNolan
Have any actually ended up in the block chain?

No.

Quote from: sebastian
2: Malwritten clients, when served with a amount to send = 0 BTC by the end user (propably by mistake, user simply forgot to enter amount), do not validate that the clients amount exceed 0 Before attempting to create a transaction. When the client attempt to create the transaction, it finds out that theres no need for inputs anymore ("do until"-loop) because the amount has been fulfilled. And theres no outputs to add, because the client automatically deletes any outputs with amount=0.
Then it ends up with a "empty" transaction, and sends the "empty" transaction.

...All sounds good.  except... ZOMG ZE END OF ZE WORLD!@@!   A "DO UNTIL" LOOP?#^%#$^)   kill me now%!##  I'm having flashbacks to my pascal/delphi days lol




....And Piotr, wtf is a "correct horse battery staple" input :)  besides my favorite xkcd reference, that is :P


Title: Re: Transactions with input & output count == 0??
Post by: piotr_n on August 27, 2013, 12:56:00 PM
....And Piotr, wtf is a "correct horse battery staple" input :)  besides my favorite xkcd reference, that is :P
It is a default/example password for brainwallet (http://brainwallet.org/) that leads to address 1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T with its publicly known private key.

This address currently has 0.38667139 BTC in 141462 unspent outputs, that are being used to spam the network.

https://blockchain.info/tx/8923d74c3a653eb1562d236f07ae969da2c42f8570204162c12d1c71355947b2
https://blockchain.info/tx/7aab325941ff46aa17eda6fa1cc2588294b098f11603a7259f836c93516a3656
https://blockchain.info/tx/7a1be184fd25f258210dda9df6f488f81ad75c184622607fa82f86ba65811c7a
and so on...


Title: Re: Transactions with input & output count == 0??
Post by: piotr_n on August 27, 2013, 03:38:17 PM
There will be spam for as long as stupid pool owners and solo miners allow transactions smaller than 5430 Satoshis.
Luckily, I think it happened already.

Number of UTXO records was growing very quickly, yet like 3 months ago.
But after the change that blocks the dust, after people upgraded their clients, it stopped below 7 millions and have been quite steady ever since then.

The idea to treat transactions with outputs below 0.00005430 as non-standard really helped a lot - one of a few realized ideas, of the dev team, that I really and honestly appreciate :)

Still there are the 141462 unspent horse outputs that anyone can use to spam the net - the best solution I see to get rid of them is asking miners to slowly claim them for themselves.


Title: Re: Transactions with input & output count == 0??
Post by: jl2012 on August 27, 2013, 04:25:55 PM

Have any actually ended up in the block chain?

Never: you can search d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43 with google

However, I wonder if this is a valid transaction (if someone put it in a block, is the block still valid?)


Title: Re: Transactions with input & output count == 0??
Post by: piotr_n on August 27, 2013, 04:31:31 PM
However, I wonder if this is a valid transaction (if someone put it in a block, is the block still valid?)
I think it is not, though ATM I cannot point out the exact satoshi's code that discards it. But I am pretty sure it is there...


Title: Re: Transactions with input & output count == 0??
Post by: Peter Todd on August 27, 2013, 04:36:20 PM

Have any actually ended up in the block chain?

Never: you can search d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43 with google

However, I wonder if this is a valid transaction (if someone put it in a block, is the block still valid?)

It's not:

Code:
bool CheckTransaction(const CTransaction& tx, CValidationState &state)
{
    // Basic checks that don't depend on any context
    if (tx.vin.empty())
        return state.DoS(10, error("CheckTransaction() : vin empty"));
    if (tx.vout.empty())
        return state.DoS(10, error("CheckTransaction() : vout empty"));

and in CheckBlock():

Code:
    // Check transactions
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
        if (!CheckTransaction(tx, state))
            return error("CheckBlock() : CheckTransaction failed");