Bitcoin Forum
June 23, 2024, 10:13:04 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1] 2 »  All
  Print  
Author Topic: Transactions which spend coinbase outputs early  (Read 3119 times)
TierNolan (OP)
Legendary
*
Offline Offline

Activity: 1232
Merit: 1084


View Profile
March 19, 2015, 03:55:53 PM
 #1

What happens if a transaction is submitted that spends a coinbase output early?

Is the transaction just placed in the orphan pool and potentially lost by the time the timeout ends?  In theory, they should be higher priority than normal orphans, since they are guaranteed to be valid eventually.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
March 20, 2015, 03:05:04 AM
 #2

It is an invalid txn.  It won't be relayed or included in a block by default.  If a miner did include it in a block then the block is invalid.  Similar to a txn with a future nlocktime.
TierNolan (OP)
Legendary
*
Offline Offline

Activity: 1232
Merit: 1084


View Profile
March 20, 2015, 06:32:07 PM
 #3

It is an invalid txn.  It won't be relayed or included in a block by default.  If a miner did include it in a block then the block is invalid.  Similar to a txn with a future nlocktime.

Does the node just drop it though?  It could be placed in the orphan pool and then added to the memory pool once the timeout has expired (and thus relayed).

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
CIYAM
Legendary
*
Offline Offline

Activity: 1890
Merit: 1078


Ian Knowles - CIYAM Lead Developer


View Profile WWW
March 20, 2015, 06:35:30 PM
 #4

Does the node just drop it though?  It could be placed in the orphan pool and then added to the memory pool once the timeout has expired (and thus relayed).

Interesting - as a potential attack vector it wouldn't be so easy but I'd guess it still could be such a potential if the txs were relayed wouldn't it?

With CIYAM anyone can create 100% generated C++ web applications in literally minutes.

GPG Public Key | 1ciyam3htJit1feGa26p2wQ4aw6KFTejU
TierNolan (OP)
Legendary
*
Offline Offline

Activity: 1232
Merit: 1084


View Profile
March 20, 2015, 06:49:31 PM
 #5

Interesting - as a potential attack vector it wouldn't be so easy but I'd guess it still could be such a potential if the txs were relayed wouldn't it?

I don't think it is any easier than other transactions.  In effect, it would be a part of the memory pool with a height restriction.  If you spend the coinbase output twice, then the 2nd one wouldn't be relayed, as it is a doublespend.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
CIYAM
Legendary
*
Offline Offline

Activity: 1890
Merit: 1078


Ian Knowles - CIYAM Lead Developer


View Profile WWW
March 20, 2015, 07:10:19 PM
 #6

If you spend the coinbase output twice, then the 2nd one wouldn't be relayed, as it is a doublespend.

Yes - good point - so nice to have a topic with smart people rather than just ad sig posts (but I guess they might be about to follow).

With CIYAM anyone can create 100% generated C++ web applications in literally minutes.

GPG Public Key | 1ciyam3htJit1feGa26p2wQ4aw6KFTejU
StephenMorse
Member
**
Offline Offline

Activity: 88
Merit: 12


View Profile
March 24, 2015, 04:02:22 AM
 #7

What happens if a transaction is submitted that spends a coinbase output early?

Is the transaction just placed in the orphan pool and potentially lost by the time the timeout ends?  In theory, they should be higher priority than normal orphans, since they are guaranteed to be valid eventually.

I don't think they are guaranteed to be valid eventually. For example, it could be the case that the first block in which the coinbase becomes spendable (so 100 blocks after the block it is mined in) sends the funds it to a different address than the one you saved in your mempool.

AFAIK, the current invariant of the mempool is that all the transactions could be gathered up into one big block (assuming the 1 MB restriction doesn't apply). This would have to change to allow relaying of prematures coinbase spends. The block building code would have to take this into account as well, making sure it doesn't build a block that will be invalid.

I like the idea of being able to use this for things like award pool payouts immediately after a block is solved, though.
TierNolan (OP)
Legendary
*
Offline Offline

Activity: 1232
Merit: 1084


View Profile
March 24, 2015, 12:03:19 PM
 #8

I don't think they are guaranteed to be valid eventually. For example, it could be the case that the first block in which the coinbase becomes spendable (so 100 blocks after the block it is mined in) sends the funds it to a different address than the one you saved in your mempool.

That can only happen with a double spend though.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
Cryddit
Legendary
*
Offline Offline

Activity: 924
Merit: 1129


View Profile
March 26, 2015, 06:00:47 PM
 #9


AFAIK, the current invariant of the mempool is that all the transactions could be gathered up into one big block (assuming the 1 MB restriction doesn't apply). This would have to change to allow relaying of prematures coinbase spends. The block building code would have to take this into account as well, making sure it doesn't build a block that will be invalid.


I believe the restriction is more than that; the mempool transactions could be gathered up into one big block (if they fit under the blocksize restriction) *AND* that hypothetical block would be valid as the very next block in the chain. 


DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
March 26, 2015, 07:50:00 PM
 #10

Well I think that was his point right.   Valid is sort of implied (one big block = one big valid block).  The txns in the memory pool could all be included in the next block (outside of size limits).  In fact the core client assumes that by using the memorypool as the as the source for Getblocktemplate.   Partially signed txns and txns with future nlocktimes are not stored in the memory pool (and thus not relayed) for the same reasons.  They aren't valid for inclusion in the next block.
Cryddit
Legendary
*
Offline Offline

Activity: 924
Merit: 1129


View Profile
March 26, 2015, 08:32:51 PM
 #11


I believe the restriction is more than that; the mempool transactions could be gathered up into one big block (if they fit under the blocksize restriction) *AND* that hypothetical block would be valid as the very next block in the chain.  


I have reviewed the source code.  A transaction which contains a spend of a coinbase, when that coinbase's spendable height has not yet arrived, is not accepted into the mempool.  It is not relayed, and the peer reporting it is marked as misbehaving.

Other tx which appear to be valid (and do not actively conflict with tx in the mempool or in the chain as accepted so far),  are retained (as "orphans") even if the transactions that create the txOuts they spend have not yet been received.   "Orphans" would not be valid appearing without their parent transactions in the next block, and they appear to be the only kind of transaction that is retained in the memory pool even though there is any question as to whether it will eventually become valid.  

I don't see a compelling reason why a premature spend of a coinbase should not be treated the same way as an orphan tx.  Both are essentially tx that could (or will) become valid if (or when) some event occurs.  The amount of memory reserved for orphans is limited to prevent transmitting lots of orphans from becoming a memory-exhaustion attack.  

One relevant difference is that it is at least possible that an orphan tx will be in the very next block, whereas a tx that prematurely spends a coinbase would under no circumstances be valid in the very next block.

Cryddit
Legendary
*
Offline Offline

Activity: 924
Merit: 1129


View Profile
March 26, 2015, 08:59:05 PM
 #12

Well I think that was his point right.   Valid is sort of implied (one big block = one big valid block). 

The thing I was talking about was not validity, it was about it being valid AS THE VERY NEXT BLOCK.  A coinbase spend is a valid transaction and does not conflict with any other tx in the mempool, and could eventually appear in the block chain.  But if it can't appear IN THE VERY NEXT BLOCK the implementation just ignores it except to start doubting the sanity of the node reporting it. 

Everything else that could become valid and is not conflicting with anything already in the memory pool gets accepted, even if the conditions for it to be valid have not yet occurred (ie orphan tx which spend outputs not yet visible in any other mempool tx nor in the block chain).

The mempool then is tx that COULD be valid in the very next block - but at any given moment, depending on which txOuts appear in other tx the mempool, you may have tx in there that couldn't appear in a block made exclusively out of your own mempool. 


DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
March 26, 2015, 09:51:46 PM
Last edit: March 26, 2015, 11:37:12 PM by DeathAndTaxes
 #13

Well I think that was his point right.   Valid is sort of implied (one big block = one big valid block).  

The thing I was talking about was not validity, it was about it being valid AS THE VERY NEXT BLOCK.  

Yes I understand and it was implied in the post you replied to as well.  That post can't be read any other way.  Anyways moving on.

Quote
Other tx which appear to be valid (and do not actively conflict with tx in the mempool or in the chain as accepted so far),  are retained (as "orphans") even if the transactions that create the txOuts they spend have not yet been received.

I do not believe that is correct. To be included in the memory pool the inputs of a txn must reference an output in the utxo.  The sending peer is not penalized as there are legitimate reasons but the txn is not added to the memory pool.

https://github.com/bitcoin/bitcoin/blob/687f10d9ec3548f13f929ca14cd813a0919639ec/src/main.cpp#L1021
https://github.com/bitcoin/bitcoin/blob/687f10d9ec3548f13f929ca14cd813a0919639ec/src/main.cpp#L1380
Cryddit
Legendary
*
Offline Offline

Activity: 924
Merit: 1129


View Profile
March 26, 2015, 10:47:44 PM
Last edit: March 26, 2015, 11:31:12 PM by Cryddit
 #14

Well I think that was his point right.   Valid is sort of implied (one big block = one big valid block).  

The thing I was talking about was not validity, it was about it being valid AS THE VERY NEXT BLOCK.  

Yes that was understood and the person and it was understood from the post you replied to as well.  That post can't be read any other way.

Quote
Other tx which appear to be valid (and do not actively conflict with tx in the mempool or in the chain as accepted so far),  are retained (as "orphans") even if the transactions that create the txOuts they spend have not yet been received.

I do not believe that is correct. To be included in the memory pool the inputs of a txn must reference an output in the utxo.  The sending peer is not penalized as there are legitimate reasons but the txn is not added to the memory pool.

https://github.com/bitcoin/bitcoin/blob/687f10d9ec3548f13f929ca14cd813a0919639ec/src/main.cpp#L1021
https://github.com/bitcoin/bitcoin/blob/687f10d9ec3548f13f929ca14cd813a0919639ec/src/main.cpp#L1380


Hm.  Looks like you're right.  But it does keep orphans.  

https://github.com/bitcoin/bitcoin/blob/687f10d9ec3548f13f929ca14cd813a0919639ec/src/main.cpp#L495

I guess they aren't part of "Memory pool?"  

Edit:  I found it.

https://github.com/bitcoin/bitcoin/blob/687f10d9ec3548f13f929ca14cd813a0919639ec/src/main.cpp#L3869

Is where transactions get moved from the orphan map to the memory pool when the tx that complete their inputs are received. 

I had been under the mistaken impression that the orphan map referred to tx which were already stored in the mempool; this makes it clear that they are stored in a separate structure.
StephenMorse
Member
**
Offline Offline

Activity: 88
Merit: 12


View Profile
March 27, 2015, 05:08:32 AM
 #15

If this feature were implemented, the pre-mature spends of coinbase outputs would probably have to be stored in an entirely different structure (similar to the COrphanTx and mapOrphanTransactions), in order to preserve the mempool for block building. Or, you could probably also just make a CMempoolTx struct that stores the transaction and any meta data about how/when it should be included in a block.

The thing I'm not sure about is transaction relaying. Have any versions of the software penalized nodes for forwarding pre-mature spends of coinbase transactions? Because, if so, this feature could end up getting nodes banned. I've looked through a few versions, can't seem to find any misbehavior points being applied for doing this, but I certainly didn't check every version.

Coinbase transactions can have many outputs, and each one of those outputs can be spent by a very large transaction, so the same (or similar) sorts of rate limiting that go into what can be accepted to the mempool has to be applied to these.

I'd be interested to see what some core devs think about this, I'll see if anyone in IRC can weigh in.
StephenMorse
Member
**
Offline Offline

Activity: 88
Merit: 12


View Profile
March 27, 2015, 05:48:47 AM
 #16

Consensus on the bitcoin-dev IRC chat is that no other versions have penalized forwarding of pre-mature spends of coinbase transactions, but that there doesn't seem to be any real use-case for such a feature.
TierNolan (OP)
Legendary
*
Offline Offline

Activity: 1232
Merit: 1084


View Profile
March 27, 2015, 04:41:27 PM
 #17

Consensus on the bitcoin-dev IRC chat is that no other versions have penalized forwarding of pre-mature spends of coinbase transactions, but that there doesn't seem to be any real use-case for such a feature.

I was thinking that it could be used to make the coinbase smaller by paying to a transaction rather than a list of addresses.

This would make automatic mining software easier.  You wouldn't need to hash a 10-20kB coinbase to update the extraNonce.

It requires a way to "pay to transaction", which isn't supported. 

Miners could wait the 100 blocks and as long as at least one of them remembers the transactions, then it doesn't matter about the delay.

A hard-fork rule would be that transactions are allowed to spend the coinbase in the current block.  The outputs of those transactions are considered coinbase outputs for the purposes of the 100 block rule.

The could add an opcode OP_HASH_THIS_TRANSACTION. 

It hashes the current transaction

    TXID for this input is set to 32 zeros
    scriptSig is set to zero length

The scriptPubKey would be

Code:
<hash of tx> OP_HASH_THIS_TRANSACTION OP_EQUALVERIFY

The scriptSig would be empty.  The scriptPubKey does the verification on its own.

Since the new opcode ignores the TXID it can be set after the coinbase is setup.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
Cryddit
Legendary
*
Offline Offline

Activity: 924
Merit: 1129


View Profile
March 27, 2015, 04:55:09 PM
 #18

If you'd like to hard fork to deal with the problem of updating the extranonce, the "correct" solution would be to add it to the header.  But that'll never happen.

That would be the correct solution if CPU or GPU mined.  There is no way in hell that there'd ever be miner support for something that would destroy the value of their investment in ASICs.

TierNolan (OP)
Legendary
*
Offline Offline

Activity: 1232
Merit: 1084


View Profile
March 27, 2015, 05:58:52 PM
 #19

If you'd like to hard fork to deal with the problem of updating the extranonce, the "correct" solution would be to add it to the header.  But that'll never happen.

Agreed.  I asked the question before before making sure everything was actually possible.

I think a hard fork changing the Merkle tree would be better.  It would allow a second header at the top level of the Merkle tree.

Quote
That would be the correct solution if CPU or GPU mined.  There is no way in hell that there'd ever be miner support for something that would destroy the value of their investment in ASICs.

A second header would mean that ASICs are not affected.

The merkle root field would be filled with double_hash(old_merkle_root | aux_header).

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
March 27, 2015, 07:15:00 PM
Last edit: March 27, 2015, 07:40:18 PM by DeathAndTaxes
 #20

There is no way in hell that there'd ever be miner support for something that would destroy the value of their investment in ASICs.

Luckily that is not correct.  A while back I proposed a way to expand the header while still maintaining compatibility with existing ASICs (but would require a hard fork and updated mining software). Maybe I can find a link.  The header will eventually need to be updated when the Unix time value overflows the 32 bit integer but we have a 'little' while before that happens.
Pages: [1] 2 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!