Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: Forp on June 18, 2011, 02:16:01 PM



Title: When are transactions final (in case of a time lock) ?
Post by: Forp on June 18, 2011, 02:16:01 PM
main.h: CTransaction::IsFinal() decides, when a transaction is considered final.  :)

Now, it looks like nLockTime is not really used currently, so if is the line

if (nLockTime == 0) return true;

which usually is doing its job here.  :)

A bit lower in the code there is this little thingie:  ???

if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime))  return true;

which I personally would have expected to be  :-\

   if ((int64)nLockTime < nBlockTime)  return true;

What is the purpose of comparing to BlockHeight in case nLockTime is smaller than 500 000 000. 500 000 000 is definitely in the past?  ??? ??? ???

As nLockTime is compared to GetAdjustedTime() earlier in the code, it is absolute Unix epoch time. 500 000 000 is November 05, 1985, 01:53:20 in my timezone. What's the idea of comparing with this date in the past ?!? Moreover: if nLockTime < 500000000 then almost certainly also nLockTime < nBlockHeight so this earlier test does not make sense ?!?

I would appreciate any ideas shedding some light on this line of code.

And, while being in this part of the code, a bit lower in IsFinal() we find:

   BOOST_FOREACH(const CTxIn& txin, vin) if (!txin.IsFinal()) return false;

The logic is obvious: If an input to a transaction is not final, then the transaction under consideration is not final. But...hm...shouldn't this be the very first thing to check? There are various cases earlier in the function which lets the system decide that a transaction is final - without having made this check.


Title: Re: When are transactions final (in case of a time lock) ?
Post by: riX on June 18, 2011, 03:28:41 PM
I don't understand it either. Maybe 500000000 is just some number inserted to show possible functionality for nLockTime, or maybe for returning the same result as 0 when people thinks nLockTime is a block number instead of a unix timestamp.


Title: Re: When are transactions final (in case of a time lock) ?
Post by: titeuf_87 on June 18, 2011, 09:13:42 PM
This locktime stored in every transaction can be used for two different purposes, from the wiki:
"The block number or timestamp at which this transaction is locked, or 0 if the transaction is always locked. A non-locked transaction must not be included in blocks, and it can be modified by broadcasting a new version before the time has expired (replacement is currently disabled in Bitcoin, however, so this is useless). "

This is the reason why this 500 000 000 is in the condition: if nLockTime is smaller than that, it is assumed to be a block number, otherwise it's assumed to be a timestamp.

If this is not the case and nLockTime is for a time in the future for example, every input from that transaction will be checked, which does this:
Code:
bool IsFinal() const
{
    return (nSequence == UINT_MAX);
}

If the sequence number of every input is equal to UINT_MAX then this transaction is considered final, even though the nLockTime refers to a future block/time.

The reason why this is done is because as long as nLockTime refers to the future, the creator of this transaction can make new versions of it. This is done by increasing the sequence number of the input. If every input has UINT_MAX as sequence number, no new versions of it can be created anymore as otherwise it would result in an overflow.

I hope this helps. I can't guarantee how correct this is, but this is just what I read from both the wiki and the code :)