9

I've noticed recently that Bitcoin Core is producing transactions with non-zero lock-time and sequence numbers of inputs being 0xFFFFFFFE, even though I didn't instruct it to do so. The lock-time appears to be current block number.

  • What is the reason for this behavior?
  • What is the algorithm for setting sequence number?

(I know that at least one input must have sequence number less than 0xFFFFFFFF. Does the Core set just first input or all inputs? I couldn't check this because I have no transaction with more than one input.)

Thank you for your answers!

1 Answer 1

18

TL;DR: The aim is to discourage reorganizations and increase privacy.

In wallet.cpp, just above where nLockTime gets set, it says:

// Discourage fee sniping.
//
// For a large miner the value of the transactions in the best block and
// the mempool can exceed the cost of deliberately attempting to mine two
// blocks to orphan the current best block. By setting nLockTime such that
// only the next block can include the transaction, we discourage this
// practice as the height restricted and limited blocksize gives miners
// considering fee sniping fewer options for pulling off this attack.
//
// A simple way to think about this is from the wallet's point of view we
// always want the blockchain to move forward. By setting nLockTime this
// way we're basically making the statement that we only want this
// transaction to appear in the next block; we don't want to potentially
// encourage reorgs by allowing transactions to appear at lower heights
// than the next block in forks of the best chain.
//
// Of course, the subsidy is high enough, and transaction volume low
// enough, that fee sniping isn't a problem yet, but by implementing a fix
// now we ensure code won't be written that makes assumptions about
// nLockTime that preclude a fix later.

txNew.nLockTime = chainActive.Height();

// Secondly occasionally randomly pick a nLockTime even further back, so
// that transactions that are delayed after signing for whatever reason,
// e.g. high-latency mix networks and some CoinJoin implementations, have
// better privacy.

if (GetRandInt(10) == 0)
  txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));

As Martin Habovštiak noticed, the sequence number is set to MAX-1 for every input. It's in the code just below the previously mentioned code section.

5
  • 1
    Seems like sequence is set to max()-1 for every input. The code is just bellow of what you mentioned Thank you for your answer! Commented Sep 3, 2016 at 9:04
  • 1
    Do you have a text version of the explanation? The code you posted is really unreadable on mobile, because you need to scroll to the right for every line
    – Ferrybig
    Commented Sep 9, 2016 at 5:53
  • @Ferrybig: I've put the TL;DR at the top.
    – Murch
    Commented Sep 9, 2016 at 12:37
  • is there a reason for that weird sequence number? the reasons stated in this answer only seem to explain the nLockTime, not the sequence number
    – knocte
    Commented Nov 7, 2017 at 8:10
  • 1
    @knocte: nLockTime is only active if the sequence number is below UINT_MAX.
    – Murch
    Commented Nov 9, 2017 at 6:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.