Author

Topic: locktime (Read 2000 times)

newbie
Activity: 36
Merit: 0
January 13, 2015, 03:09:30 AM
#17
cjp your logic is OK. Either expired locktime or ALL sequence numbers ffffffff mark transaction as final, everything else means it's not final.

The same expressed in simple JS: https://curiosity-driven.org/low-level-bitcoin#locktime
cjp
full member
Activity: 210
Merit: 124
January 12, 2015, 01:41:38 PM
#16
As far as I can tell, you're correct.

Thanks. So I guess this means that, at the moment, sequence numbers have no meaning, except that the special value 0xffffffff makes transactions final. For the rest, it makes no difference what sequence numbers you use.
newbie
Activity: 17
Merit: 0
January 11, 2015, 05:33:52 PM
#15

But, please, PLEASE answer my question in post #12. It's much more urgent to me than this discussion about transaction replacement.


As far as I can tell, you're correct. The terminology for transactions you call "OK" and "Not OK" is "final" and "non-final." One wrinkle is that there was some divergent behaviour in the testnet, where non-final transactions (nLockTime in future & sequence number < UINT_MAX) were being accepted but not replaced. This was fixed just a few days ago.

In any case: there is no code in Bitcoin Core to replace transactions based on sequence number, and mainnet nodes don't accept non-final transactions into the mempool.

Oh yeah, and a non-final transaction can't be included in a block until it turns final. It makes the block invalid, which will fork anyone who accepts it off the blockchain.
cjp
full member
Activity: 210
Merit: 124
January 11, 2015, 01:25:10 PM
#14
Thats unsafe.
Do you mean unsafe for a miner who considers accepting a transaction into his block, or unsafe for a recipient of one of the versions of a transaction (who might receive less or nothing at all in an update)? The second one really depends on the greater "scheme" in which transaction replacement is used; I haven't given the first one much thought yet.

Consider an attacker who floods the network concurrently with many different spends all the time.
That's just like double spending, right? So it isn't unique to transaction replacement at all: even without transaction replacement, attackers can "flood the network"(*) with double-spends, until one of them gets accepted into a block. The only difference created by transaction replacement is that the attacker, like a legitimate user, can indicate which of the "double-spends" should be chosen over the other ones. This can also be indicated without transaction replacement, in a more implicit, economical way, by increasing the transaction fee. If there is any difference at all, the explicit way with sequence numbers should be more reliable.

Again, the consequences for a recipient of one of the versions of a transaction completely depend on the greater "scheme" in which transaction replacement is used. The "scheme" I'm thinking of is a microtransaction channel; in that case, one of the sides of the channel can not attack the other side of the channel by flooding the network with transaction updates: the signatures of both sides are needed to create a valid transaction update.

But, please, PLEASE answer my question in post #12. It's much more urgent to me than this discussion about transaction replacement.

(*) I'm not exactly sure what you mean with that phrase. Do you mean it could be a DoS attack on the network?
staff
Activity: 4284
Merit: 8808
January 11, 2015, 12:32:48 PM
#13
What do you mean with "can never be enforced"? If a replacement is broadcasted long before nLockTime expires, it is unlikely
Thats unsafe. It will cause random, surprise, state divergences; along with attacker triggerable ones. Such a thing needs a consensus system to decide on what the requirements are. This is what we have mining for. Consider an attacker who floods the network concurrently with many different spends all the time. Miners have no idea that other people got different spends (and can even be prevented because the information is simply out of their lightcone). Even if they have some awareness, they have no idea what the majority of the network is accepting. We have mining precisely to resolve this ambiguity in the state of other people's systems.
cjp
full member
Activity: 210
Merit: 124
January 11, 2015, 06:26:55 AM
#12
Transactions don't get replaced in the client based on sequence number any more. More recently, the handling of nLockTime was also changed, so that transactions with an nLockTime in the future can't enter the memory pool. There's some history at the wiki.

I posted an idea for payment channels to the bitcoin-development list yesterday, provoking a discussion of this very topic.
Besides the discussion about what Bitcoin's behavior should be, I'm also interested in what the exact behavior of Bitcoin is, right now.

The way I understand it, the current behavior of non-modified Bitcoin Core is (assuming all else is correct about a transaction):
  • any sequence number is 0xffffffff -> see "transaction OK"
  • all sequence numbers are not 0xffffffff and nLockTime is expired -> see "transaction OK"
  • all sequence numbers are not 0xffffffff and nLockTime is not expired -> see "transaction NOT OK"
  • "transaction OK" -> transaction will be transferred to other nodes and included into blocks. Will mine on top of blocks that include such transactions.
  • "transaction NOT OK" -> transaction will NOT be transferred to other nodes and NOT included into blocks. Will NOT mine on top of blocks that include such transactions.
Is this correct?
cjp
full member
Activity: 210
Merit: 124
January 11, 2015, 06:14:17 AM
#11
Is there any use for sequence at all (other than backwards compatibility)?  It seems whatever Satoshi intended sequence to be used for can never be enforced.
It is useful for making microtransaction channels bidirectional. This is also possible without transaction replacement, but at some cost:
https://bitcointalksearch.org/topic/bi-directional-micro-payment-channels-with-single-party-bitcoin-locking-814770

What do you mean with "can never be enforced"? If a replacement is broadcasted long before nLockTime expires, it is unlikely that any miner doesn't receive it. Once nLockTime expires, each honest miner will include the latest update into its block. Most non-honest miners will do this too, because their only interest in your transaction is to capture its transaction fee. Only non-honest miners who have a higher stake in your transaction might choose to ignore a transaction update.

So, as far as I can see, the only "enforcement" you need is against a certain (typically very small) percentage of miners which might have a special interest in cheating. This "enforcement" could be in the form of other miners who refuse to build upon a block with an outdated version of a transaction. I'm not sure this is a good idea though: you need to be absolutely certain it won't ever break consensus in the long term. IMHO, preventing a long-lived block chain fork is much more important than any feature provided by trying to make transaction replacement 100% secure.
staff
Activity: 4284
Merit: 8808
January 10, 2015, 08:27:46 PM
#10
Is there any use for sequence at all (other than backwards compatibility)?  It seems whatever Satoshi intended sequence to be used for can never be enforced.
It's potentially useful in your own protocol, at least. Not _everything_ that reads a transaction is the blockchain. It could potential gain some productive use (beyond the binary max or not for locking) in a softfork.
donator
Activity: 1218
Merit: 1079
Gerald Davis
January 10, 2015, 06:56:42 PM
#9
Is there any use for sequence at all (other than backwards compatibility)?  It seems whatever Satoshi intended sequence to be used for can never be enforced.
newbie
Activity: 17
Merit: 0
January 10, 2015, 06:14:23 PM
#8
any more.
There was some code stubbed out to do that, but it was never implemented as far as I recall. Do you have a reason to believe they actually were? (if you don't I don't want to waste time spelunking through old code)

That was an inaccuracy on my part, sorry. The commit removing the code indicates that it never worked.

Edit: The wiki was linking to the wrong commit stubbing out transaction replacement. This is the real commit.
staff
Activity: 4284
Merit: 8808
January 10, 2015, 06:00:09 PM
#7
any more.
There was some code stubbed out to do that, but it was never implemented as far as I recall. Do you have a reason to believe they actually were? (if you don't I don't want to waste time spelunking through old code)
newbie
Activity: 17
Merit: 0
January 10, 2015, 05:54:54 PM
#6
How does the current Bitcoin software deal with sequence numbers that are not 0xffffffff? Is every value for the sequence number accepted? If a miner receives double-spends with different sequence numbers (all with zero confirmations), will it choose the one with the highest sequence number for inclusion in a block?

It seems that the "microtransaction channel" implementation in bitcoinj always uses sequence number 0 for to-be-updated transactions. Is this the recommended way of setting the sequence number?

Transactions don't get replaced in the client based on sequence number any more. More recently, the handling of nLockTime was also changed, so that transactions with an nLockTime in the future can't enter the memory pool. There's some history at the wiki.

I posted an idea for payment channels to the bitcoin-development list yesterday, provoking a discussion of this very topic.
cjp
full member
Activity: 210
Merit: 124
January 10, 2015, 06:11:04 AM
#5
How does the current Bitcoin software deal with sequence numbers that are not 0xffffffff? Is every value for the sequence number accepted? If a miner receives double-spends with different sequence numbers (all with zero confirmations), will it choose the one with the highest sequence number for inclusion in a block?

It seems that the "microtransaction channel" implementation in bitcoinj always uses sequence number 0 for to-be-updated transactions. Is this the recommended way of setting the sequence number?
sr. member
Activity: 375
Merit: 255
December 09, 2014, 09:33:55 PM
#4
thanks guys
legendary
Activity: 3472
Merit: 4801
December 09, 2014, 09:25:27 PM
#3
Here's a simple example unsigned transaction created with createrawtransaction. It has only one input and one output:

01000000018a38995bf447db93db0547191c369b7938db2b91fdbd88adcc20858f7574578f00000 00000ffffffff019a50c903000000001976a914fc1e692875788d0ac5d685440feb1358515212f388ac00000000

The bold and underlined "ffffffff" is the 4 byte sequence number for the input.  If you create a transaction with multiple inputs, then each input will have its own sequence number.

The bold and underlined "00000000" is the 4 byte locktime for the transaction.

locktime is ignored if any of the sequence numbers are ffffffff.

Therefore after generating your generic transaction (without a locktime) with createrawtransaction, you'll want to modify the sequence number bytes appropriately.

Then you can modify the locktime bytes at the end of the transaction.  Remember to use the appropriate endian-ness for your bytes.

Once you have modified the transaction for the sequence numbers and locktime that you want, you can then use signrawtransaction to sign it.

For a better understanding of what you are looking at, here's that same transaction broken down into its component parts while keeping all the bytes in the exact same order as above:

Code:
Version Number: 01000000 (version 1 with proper endian-ness)
  Qty of inputs: 01
     Input txid: 8a38995bf447db93db0547191c369b7938db2b91fdbd88adcc20858f7574578f (this is transactionID 8f5774758f8520ccad88bdfd912bdb38799b361c194705db93db47f45b99388a, note the endian-ness)
          Index: 00000000
  Script length: 00
Sequence Number: ffffffff
 Qty of outputs: 01
   Output value: 9a50c90300000000 (63525018 in hex with proper endian-ness)
  Script Length: 19 (25 bytes)
         OP_DUP: 76
     OP_HASH160: a9
  Bytes to push: 14 (20 bytes)
   Data to push: fc1e692875788d0ac5d685440feb1358515212f3 (this is the RIPEMD160 hash with proper endian-ness that the bitcoin address is computed from, it represents address 1Pz5iKVeAAFUh66PBUy5Sozjgeqd2ptuWV)
 OP_EQUALVERIFY: 88
    OP_CHECKSIG: ac
       Locktime: 00000000
administrator
Activity: 5222
Merit: 13032
December 09, 2014, 09:04:34 PM
#2
You can't do it directly in Bitcoin Core, though it isn't too difficult to modify the hex yourself. signrawtransaction will sign modified transactions. Refer to the protocol specification. Keep in mind that you'll also need to modify each input's sequence for your lock time to actually work.
sr. member
Activity: 375
Merit: 255
December 09, 2014, 08:52:29 PM
#1
How can I create a transaction using the command createrawtransaction but specifying a locktime?
Jump to: