BIP-68: Mempool-only sequence number constraint verification #6312

pull maaku wants to merge 12 commits into bitcoin:master from maaku:sequencenumbers changing 15 files +308 −117
  1. maaku commented at 0:55 am on June 20, 2015: contributor

    Essentially enforces sequence numbers as a relative lock-time as an IsStandard() rule to make it easy to test applications using it; blocks containing transactions with invalid sequence numbers given the age of their inputs per BIP 68 are still accepted.

    This pull-req is not a soft-fork nor does it contain any code to start that process.

    This pull request builds on top of #6177.

    Background: BIP 68, Consensus-enforced transaction replacement signalled via sequence numbers

  2. petertodd commented at 6:28 pm on June 21, 2015: contributor
    Mind fixing that BIP link? 404
  3. maaku commented at 6:39 pm on June 21, 2015: contributor

    Fixed.

    On Sun, Jun 21, 2015 at 11:28 AM, Peter Todd notifications@github.com wrote:

    Mind fixing that BIP link? 404

    — Reply to this email directly or view it on GitHub #6312 (comment).

  4. petertodd commented at 0:05 am on June 22, 2015: contributor

    Now again, could you please do up a quick demo example app that actually uses this? e.g. like my https://github.com/petertodd/checklocktimeverify-demos/blob/master/micropayment-channel.py

    Doesn’t have to be much, but we really need a worked out example here… Notably, see how without a way to fix tx mutability the nSequence proposal really isn’t any different in practice than just signing increasingly decreasing nLockTime’s? Because if you could safely sign the transaction it’d already be mined and thus you don’t need a relative nSequence - an absolute nLockTime calculated from the height/time of the tx you know already is in the chain is fine.

    IMO there’s no reason to merge this until it has a safe use-case that provides a concrete benefit over the existing status quo; a simple change in what exact number is being signed isn’t a concrete benefit.

  5. laanwj added the label Feature on Jun 22, 2015
  6. laanwj added the label Mempool on Jun 22, 2015
  7. btcdrak commented at 8:19 pm on June 23, 2015: contributor
    Why doesn’ this patch include the code for OP_CHECKSEQUENCEVERIFY?
  8. maaku commented at 8:38 pm on June 23, 2015: contributor

    @btcdrak that code is here:

    https://github.com/maaku/bitcoin/tree/checksequenceverify

    It is entirely separate from what this pull request accomplishes. For example, it is possible to do simple transaction replacement without CHECKSEQUENCEVERIFY, as explained in the BIP. Likewise the source code of the CSV branch does not in fact depend on this pull request – all CSV does is verify a constraint on the sequence number of the input, it does not depend on that sequence number having consensus-enforced semantics.

  9. btcdrak commented at 10:13 pm on June 23, 2015: contributor

    @maaku I think the value of this PR in isolation is limited. You really need the opcode as well. It would be wonderful if you could publish a separate PR+BIP for CSV if you dont wish to combine them.

    CSV is a very useful feature and one I think we clearly need to help address scalability. I see no profit in not getting it on the table now especially since it’s been deployed in Elements already and is clearly working.

  10. maaku commented at 10:21 pm on June 23, 2015: contributor

    I’m working on it. Things take time. On Jun 23, 2015 15:14, “฿tcDrak” notifications@github.com wrote:

    @maaku https://github.com/maaku I think the value of this PR in isolation is limited. You really need the opcode as well. It would be wonderful if you could publish a separate PR+BIP for CSV if you dont wish to combine them.

    CSV is a very useful feature and one I think we clearly need to help address scalability. I see no profit in not getting it on the table now especially since it’s been deployed in Elements already and is clearly working.

    — Reply to this email directly or view it on GitHub #6312 (comment).

  11. in src/consensus/consensus.h: in 856081c2b6 outdated
    13@@ -14,5 +14,7 @@ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
    14 static const int COINBASE_MATURITY = 100;
    15 /** Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. */
    16 static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov  5 00:53:20 1985 UTC
    17+/** Threshold for inverted CTxIn::nSequence: below this value it is interpreted as a relative lock-time, otherwise ignored. */
    18+static const uint32_t SEQUENCE_THRESHOLD = (1 << 31);
    


    luke-jr commented at 11:59 pm on June 24, 2015:
    Probably should call this something other than sequence?
  12. in src/main.cpp: in 856081c2b6 outdated
    672@@ -673,22 +673,110 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
    673     return true;
    674 }
    675 
    676-bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
    677+int64_t LockTime(const CTransaction &tx, int flags, const CCoinsView* pCoinsView, int nBlockHeight, int64_t nBlockTime)
    


    luke-jr commented at 11:59 pm on June 24, 2015:
    IsFinalTx was a better name IMO.
  13. in src/main.cpp: in 856081c2b6 outdated
    1049@@ -969,6 +1050,19 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
    1050         view.SetBackend(dummy);
    1051         }
    1052 
    1053+        // Enforce sequnce numbers as relative lock-time
    1054+        // only for tx.nVersion >= 2.
    1055+        int nLockTimeFlags = 0;
    1056+        if (tx.nVersion >= 2)
    1057+            nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
    


    luke-jr commented at 1:31 am on June 26, 2015:
    The version check is in LockTime already, so redundant here…
  14. in src/main.cpp: in 856081c2b6 outdated
    1057+            nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
    1058+
    1059+        // Only accept nLockTime-using transactions that can be mined in the next
    1060+        // block; we don't want our mempool filled up with transactions that can't
    1061+        // be mined yet.
    1062+        if (LockTime(tx, nLockTimeFlags, &view, chainActive.Height() + 1, GetAdjustedTime()))
    


    luke-jr commented at 1:32 am on June 26, 2015:
    Perhaps STANDARD_LOCKTIME_VERIFY_FLAGS instead of nLockTimeFlags?

    maaku commented at 1:34 am on August 18, 2015:
    Took me a while to see what you’re suggestion, but I agree. I’ll rework it to be a policy.h option.
  15. in src/miner.cpp: in 856081c2b6 outdated
    163+
    164+            // Enforce sequnce numbers as relative lock-time
    165+            // only for tx.nVersion >= 2.
    166+            int nLockTimeFlags = 0;
    167+            if (tx.nVersion >= 2)
    168+                nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
    


    luke-jr commented at 1:32 am on June 26, 2015:
    The version check is in LockTime already, so redundant here…
  16. btcdrak commented at 10:50 pm on August 4, 2015: contributor
    needs rebase
  17. maaku force-pushed on Aug 12, 2015
  18. maaku commented at 6:39 am on August 12, 2015: contributor
    Rebased.
  19. in src/main.cpp: in b011af6c55 outdated
    941@@ -860,6 +942,18 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
    942         view.SetBackend(dummy);
    943         }
    944 
    945+        // Enforce sequnce numbers as relative lock-time
    


    dcousens commented at 10:10 pm on August 13, 2015:
    s/sequnce/sequence
  20. dcousens commented at 10:14 pm on August 13, 2015: contributor
    concept ACK
  21. btcdrak commented at 7:28 pm on August 17, 2015: contributor
    Refs #6564
  22. rustyrussell commented at 0:18 am on August 18, 2015: contributor

    Agreed with @petertodd that this is fairly pointless without BIP-62 (malleability), but I do want both for lightning.

    (I also note that we should in future detach the locktime field from requiring non-FFFFFFFF nSequence; they’re completely orthogonal AFAICT. But that’s a minor soft-fork.)

  23. dcousens commented at 0:28 am on August 18, 2015: contributor
    @petertodd isn’t the point of this that it is relative? That is, I don’t need to know what block the first transaction is in, nor the follow up transactions? But I know that they will be (at least) no less than nSequence apart?
  24. maaku force-pushed on Aug 18, 2015
  25. maaku commented at 1:42 am on August 18, 2015: contributor
    @rustyrussell @petertodd : what relative lock-time gives you is a committed response window to a proof-of-publication. With CHECKSEQUENCEVERIFY (#6564) there is indeed some features you can get that in some situations aren’t just replicatable with CHECKLOCKTIMEVERIFY. However the most exciting use cases also require something additional still. In the case of lightning, not just BIP 62, but some sort of normative txid. @dcousens I believe @petertodd’s point is that since all the inputs are already on the block chain, you can just set nLockTime to the confirmed age of the input + the relative lock-time. And if the inputs are not all confirmed, then you are building chains of transactions that aren’t safe due to malleability. So really this is a feature that becomes most useful when we have a definitive fix for malleability, which we will in the not so distant future.
  26. petertodd commented at 1:57 am on August 18, 2015: contributor

    Yup, my objection was a somewhat pedantic point of process; now that CSV has been proposed it’s moot objection.

    Will review all this stuff soon FWIW, travelling right now… Per usual. :/

    On 17 August 2015 18:43:33 GMT-07:00, Mark Friedenbach notifications@github.com wrote:

    @rustyrussell @petertodd : what relative lock-time gives you is a committed response window to a proof-of-publication. With CHECKSEQUENCEVERIFY (#6564) there is indeed some features you can get that in some situations aren’t just replicatable with CHECKLOCKTIMEVERIFY. However the most exciting use cases also require something additional still. In the case of lightning, not just BIP 62, but some sort of normative txid.

    @dcousens I believe @petertodd’s point is that since all the inputs are already on the block chain, you can just set nLockTime to the confirmed age of the input + the relative lock-time. And if the inputs are not all confirmed, then you are building chains of transactions that aren’t safe due to malleability. So really this is a feature that becomes most useful when we have a definitive fix for malleability, which we will in the not so distant future.


    Reply to this email directly or view it on GitHub: #6312 (comment)

  27. dcousens commented at 2:23 am on August 18, 2015: contributor

    And if the inputs are not all confirmed, then you are building chains of transactions that aren’t safe due to malleability.

    Right, thanks for clearing that up @maaku :)

  28. rustyrussell commented at 4:22 am on August 18, 2015: contributor

    @maaku Just to clarify (though a bit OT):

    Lightning wants normalized txid for simpler dual-input anchors, but doesn’t need it (the escape tx design seems to work).

    Lightning needs normalized txid for outsourcing of revocation enforcement.

  29. maaku force-pushed on Aug 19, 2015
  30. maaku commented at 1:16 am on August 19, 2015: contributor
    Fixed @luke-jr’s nits.
  31. in src/consensus/consensus.h: in 246d456476 outdated
    14 /** The maximum allowed number of signature check operations in a block (network rule) */
    15 static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
    16 /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
    17 static const int COINBASE_MATURITY = 100;
    18+/** Threshold for inverted CTxIn::nSequence: below this value it is interpreted as a relative lock-time, otherwise ignored. */
    19+static const uint32_t SEQUENCE_THRESHOLD = (1 << 31);
    


    luke-jr commented at 2:22 am on August 19, 2015:
    Probably should call this something other than sequence?

    dcousens commented at 4:11 am on August 19, 2015:
    RELATIVE_LOCKTIME_THRESHOLD?
  32. in src/main.cpp: in 246d456476 outdated
    637@@ -638,22 +638,110 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRE
    638     return nEvicted;
    639 }
    640 
    641-bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
    642+int64_t LockTime(const CTransaction &tx, int flags, const CCoinsView* pCoinsView, int nBlockHeight, int64_t nBlockTime)
    


    luke-jr commented at 2:23 am on August 19, 2015:
    IsFinalTx was a better name IMO.

    maaku commented at 2:33 am on August 19, 2015:

    Luke, did you notice that the semantics changed? That’s why the name changed. On Aug 18, 2015 7:23 PM, “Luke-Jr” notifications@github.com wrote:

    In src/main.cpp #6312 (review):

    @@ -638,22 +638,110 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRE return nEvicted; }

    -bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) +int64_t LockTime(const CTransaction &tx, int flags, const CCoinsView* pCoinsView, int nBlockHeight, int64_t nBlockTime)

    IsFinalTx was a better name IMO.

    — Reply to this email directly or view it on GitHub https://github.com/bitcoin/bitcoin/pull/6312/files#r37374581.


    luke-jr commented at 3:23 am on August 19, 2015:
    You mean because it returns int64_t instead of bool? But unless I missed a spot, the return value is only ever used as a bool in the same sense…

    maaku commented at 3:42 am on August 19, 2015:

    No it switches to opposite meaning – zero indicates tx is final, nonzero indicates when it will become final. On Aug 18, 2015 8:24 PM, “Luke-Jr” notifications@github.com wrote:

    In src/main.cpp #6312 (review):

    @@ -638,22 +638,110 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRE return nEvicted; }

    -bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) +int64_t LockTime(const CTransaction &tx, int flags, const CCoinsView* pCoinsView, int nBlockHeight, int64_t nBlockTime)

    You mean because it returns int64_t instead of bool? But unless I missed a spot, the return value is only ever used as a bool in the same sense…

    — Reply to this email directly or view it on GitHub https://github.com/bitcoin/bitcoin/pull/6312/files#r37376960.


    maaku commented at 4:02 am on August 19, 2015:
    To expand, the change in semantics is required because it is no longer a simple matter to introspect the transaction to see how long it will remain non-final. You will see in some parts of the GUI code for example its return value is saved and used to calculate how long the transaction will remain locked, which is then displayed to the user.
  33. rustyrussell commented at 6:57 am on August 21, 2015: contributor

    OK, I tested with with the lightning cli tools. Passed and failed transactions using nSequence as expected. That was for git rev 246d456476119d464adfb8fa2e938b6def13ad50.

    Acked-by: Rusty Russell rusty@rustcorp.com.au

  34. maaku force-pushed on Aug 21, 2015
  35. maaku force-pushed on Aug 22, 2015
  36. maaku force-pushed on Aug 24, 2015
  37. maaku commented at 0:57 am on August 28, 2015: contributor

    I have pushed two separate repos which provide an alternative to BIP 68 as specified, based on feedback received. I would appreciate review of these alternatives:

    https://github.com/maaku/bitcoin/tree/sequencenumbers2

    This repo removes the inversion of the sequence number, such that the relative lock-time value is used directly as the sequence number.

    https://github.com/maaku/bitcoin/tree/sequencenumbers3

    This repo also inverts the sequence number, as well as interprets it as a fixed-point number. This allows up to 5 year relative lock times using blocks as units, and saves 12 low-order bits for future use. Or, up to about 2 year relative lock times using seconds as units, and saves 4 bits for future use without second-level granularity. More bits could be recovered from time-based locktimes by choosing a higher granularity (a soft-fork change if done correctly).

  38. maaku renamed this:
    Mempool-only sequence number constraint verification (BIP 68)
    BIP-68: Mempool-only sequence number constraint verification
    on Aug 28, 2015
  39. rustyrussell commented at 0:34 am on August 31, 2015: contributor

    Mark Friedenbach notifications@github.com writes:

    I have pushed two separate repos which provide an alternative to BIP 68 as specified, based on feedback received. I would appreciate review of these alternatives:

    https://github.com/maaku/bitcoin/tree/sequencenumbers2

    This repo removes the inversion of the sequence number, such that the relative lock-time value is used directly as the sequence number.

    OK, I like this.

    https://github.com/maaku/bitcoin/tree/sequencenumbers3

    This repo also inverts the sequence number, as well as interprets it as a fixed-point number. This allows up to 5 year relative lock times using blocks as units, and saves 12 low-order bits for future use. Or, up to about 2 year relative lock times using seconds as units, and saves 4 bits for future use without second-level granularity. More bits could be recovered from time-based locktimes by choosing a higher granularity (a soft-fork change if done correctly).

    I think that’s overkill. We already have the high bit to say “ignore it” for future soft forks.

    BTW, you need to fix the commit messages, as they still talk about inversion.

    Cheers, Rusty.

  40. btcdrak commented at 6:08 pm on September 17, 2015: contributor
    @maaku I like https://github.com/maaku/bitcoin/tree/sequencenumbers3 which leaves the door open for future expansion.
  41. maaku force-pushed on Sep 23, 2015
  42. maaku commented at 2:07 am on September 23, 2015: contributor

    Since posting the two alternatives 26 days ago, I have had conversations with many stakeholders via the mailing list, IRC, direct messaging, and in-person at the Scaling Bitcoin workshop in Montreal. Not all of these conversations were explicitly on the public record, so I will obey Chatham House rules in presenting a summary of these conversations in aggregate without identities attached. I hope that those who disagree with the summary or the outcome speak up in response.

    • There seems to be consensus in favor of BIP 68: I was unable to find anyone willing to argue that BIP 68 is on the whole a bad idea, so long as half of the sequence space keeps the original pre-BIP 68 (non consensus) semantics. The present pull request respects this constraint.
    • There is universal consensus that the bit-inversion step should be dropped. I have updated this pull request accordingly.
    • There is mixed views on whether the range of allowed relative lock-times should be constrained to set aside future bits for soft-fork changes (see: sequencenumbers2 and sequencenumbers3 discussed above). One developer argued strongly against this on the basis of favoring simplicity. Three developers argued to varying degrees in favor of setting bits aside for future soft-fork changes. The rest who were asked were explicitly indifferent. Nobody, of the developers who were asked, has said that they would retract their support for this pull request if the consensus were to be against them on this issue.

    With this in mind I have decided to update this pull request to the sequencenumbers3 branch. This branch restricts maximum relative lock-times to approximately 1 year, and in doing so sets aside 5 bits for future expansion when using time-based relative lock-time (granularity: 1 second), and 14 bits for future expansion when using height-based relative lock-time (granularity: 1 block). Further bits could be set aside by decreasing granularity in a soft-fork compatible way.

    All of the presently imagined use cases for BIP 68 and the related CHECKSEQUENCEVERIFY opcode (#6564) use relative lock-times much less than one year, so it is expected that this constraint on the maximum range does not restrict usability in any meaningful way.

    BIP 68 will be updated to reflect this new scheme.

  43. in src/main.cpp: in c11fa72951 outdated
    682+            continue;
    683+
    684+        // Skip this input if it is not in the UTXO set. This should
    685+        // only ever happen in non-consensus code.
    686+        if (!pCoinsView->GetCoins(txin.prevout.hash, coins))
    687+            continue;
    


    btcdrak commented at 12:55 pm on September 23, 2015:
    “I believe this is incorrect, as LockTime() is called for the coinbase transaction by ContextualCheckBlock()” - @petertodd from other branch
  44. maaku force-pushed on Sep 23, 2015
  45. maaku commented at 1:57 pm on September 23, 2015: contributor
    For some reason I was not email notified of Peter’s nits. They have now been fixed, at least those on the commit you linked to.
  46. in src/main.cpp: in 5624be42cb outdated
    647-        return true;
    648-    BOOST_FOREACH(const CTxIn& txin, tx.vin)
    649-        if (!txin.IsFinal())
    650-            return false;
    651-    return true;
    652+    CCoins coins;
    


    sipa commented at 2:15 pm on September 23, 2015:
    Would it be possible to retain the old IsFinalTx function, including its code, but replace its “return true;” statements by “return LockTime(…) == 0”, and use that in consensus code? That would make it trivial to see this is a softfork.

    maaku commented at 5:40 pm on September 23, 2015:

    Yep that would have been better. However I wonder if this is necessary or desirable now that this PR has received many full reviews, including verification that the change is a soft-fork.

    If you or others are having trouble verifying this, I recommend looking at the individual commits. There are two preparatory commits that contain no consensus changes, only rearrangement of the logic for IsFinalTx() into what will become LockTime(). The BIP 68 changes then affect only specific portions of the IsFinalTx / LockTime code.


    maaku commented at 9:28 pm on September 23, 2015:
    I have broken out another commit in order to make review easier.
  47. maaku force-pushed on Sep 23, 2015
  48. maaku commented at 5:04 pm on September 23, 2015: contributor

    Just pushed a relatively minor consensus change to BIP 68 functionality, based on something that was observed while editing the BIP 68 and BIP 112 drafts.

    Previously, it was possible to have a “zero” relative lock-time that allowed child and parent to be in the same block, but only if block-height was used. The smallest allowed relative lock-height using block-time required at least one block separation between child and parent. The reason for this asymmetry was a legacy of bit inversion where SEQUENCE_FINAL overlapped in meaning with 0-height relative lock-time.

    There is no longer justification for treating these two units separately. Conceivably there could be an obscure use case where the CHECKSEQUENCEVERIFY parameter is calculated on the stack and yet the check itself needs to be disabled under some circumstances – passing though a zero in this case could save a few bytes over wrapping the CSV in an IF/ELSE block. So I have opted for making the behavior symmetric in that both 0x00000000 (0 blocks) and 0x40000000 (0 seconds) allow child and parent to appear in the same block. The tests have been updated accordingly.

  49. maaku force-pushed on Sep 23, 2015
  50. maaku commented at 5:40 pm on September 23, 2015: contributor

    All nits have been addressed except @sipa’s (see my comment there). @rustyrussell for your convenience I have extracted the patch from the tree you ACK’d to the present state of the pull request. Here is the 0bin:

    http://0bin.net/paste/R7x6LS+2bZ588OLs#2yvQPDe36d0PxI8ImqRhhie4-DS5l4wb0OcpDJIgWw1

  51. maaku force-pushed on Sep 23, 2015
  52. maaku force-pushed on Sep 23, 2015
  53. btcdrak commented at 7:48 pm on September 23, 2015: contributor
    needs rebase
  54. maaku commented at 8:01 pm on September 23, 2015: contributor

    Does not need rebase… anyone know how to get github to reload a PR? My branch is updated but the PR is not updating.

    EDIT: yay fixed

  55. maaku force-pushed on Sep 23, 2015
  56. maaku force-pushed on Sep 23, 2015
  57. btcdrak commented at 7:03 pm on September 25, 2015: contributor

    So to summarise this latest iteration now frees up some nSequence bits for future expansion as follows:

    The first two bits signal whether relative lock-time is used, and which units (0 = height, 1 = seconds for bit 30), then either 16 bits of relative height, or 25 bits of relative time.

    The remaining low order bits (5 or 14) are unused, reserved for future expansion: if you don’t want relative lock-time, there’s 31 bits to use for whatever purpose (by setting the MSB) and if you do want relative lock-time, then there are 5 or 14 bits based on which units you use. More bits are reclaimable if you decrease granularity (in a soft-fork compatible way), e.g. round up the second based relative lock-time to the next multiple of 512, and you now have 14 bits for both units (512s is less than the expected time between blocks, so it’s barely any a change anyway).

  58. maaku force-pushed on Sep 25, 2015
  59. maaku commented at 10:31 pm on September 25, 2015: contributor
    Rebase to fix merge.
  60. maaku force-pushed on Sep 26, 2015
  61. maaku force-pushed on Sep 26, 2015
  62. maaku force-pushed on Sep 27, 2015
  63. maaku commented at 9:02 pm on September 27, 2015: contributor
    I believe all nits have been addressed. Can we get some ACKs?
  64. maaku force-pushed on Sep 29, 2015
  65. rustyrussell commented at 7:18 am on September 29, 2015: contributor

    This failed my test script.

    In particular, I generate tx A, and tx B which spends A and has nSequence indicating +60 seconds. I sendrawtransaction A, generate 11 blocks, sleep 61, generate 11 blocks, then try to spend B. It fails as nonfinal. This worked with previous versions. I suspect in some places we’re using median time and in other places block time.

    Immediately after spending A, we try to spend B (and expect it to fail): in LockTime() nBlockTime is 1443510877, but pindexBestHeader->GetAncestor(coins.nHeight-1)->GetMedianTimePast() is 1443510890. That extra 13 seconds is just weird.

    This is -regtest, BTW.

  66. maaku commented at 4:29 pm on September 29, 2015: contributor

    Rusty, I believe that is due to the normal behavior of regtest. It is a consensus rule that the median time past increase in each block, and in regtest mode you are creating blocks faster than 1 second. The consensus rule probably should have been checking that nTime >= GetMedianTimePast() rather than strictly greater, but c’est la vie. Add that to the list of trivial hard forks.

    So given that there were 13 seconds of discrepency, you’ve given us insight into how long it took on your machine to generate 100 blocks, submit a transaction, and generate 22 more blocks.

  67. rustyrussell commented at 1:16 am on September 30, 2015: contributor

    @maaku thanks, indeed: the block times were being pushed forward about 13 seconds (block generation bumps the time if it would be <= GetMedianPast()). Taking that into account, my tests all pass!

    Tested-by: Rusty Russell rusty@rustcorp.com.au

  68. maaku force-pushed on Oct 1, 2015
  69. sipa commented at 8:51 pm on October 1, 2015: member
    @maaku What I wanted to say earlier is that I think that CheckLockTime is being called in the wallet for not-new transactions, which would make it fail for locktimed transactions in the wallet, even long after they are in the chain.
  70. morcos commented at 9:19 pm on October 2, 2015: member
    Can you fix the link in the original pull message, it sends you to an outdated BIP now.
  71. btcdrak commented at 9:22 pm on October 2, 2015: contributor
  72. maaku force-pushed on Oct 5, 2015
  73. maaku force-pushed on Oct 5, 2015
  74. maaku force-pushed on Oct 6, 2015
  75. CodeShark commented at 12:28 pm on October 6, 2015: contributor

    We’re permanently sacrificing a bit from nSequence - and possibly sacrificing a few more longer term. But the immediate utility of CSV seems to outweigh the sacrifice, and we can eventually recover 31 bits back if we end up deprecating this mechanism in the future.

    I still have some reservations on the implementation. Did not test with wallet. But I would like to see some form of this merged soon. .

  76. in src/main.cpp: in 0f8a3c420c outdated
    692+            // be certain about whether lock-time constraints have
    693+            // been satisfied. Note that it should only ever be
    694+            // possible for this to happen with wallet transactions
    695+            // that have unknown inputs.
    696+            else
    697+                return std::numeric_limits<int64_t>::max();
    


    petertodd commented at 4:44 pm on October 8, 2015:
    This is kinda scary… I’d much rather see the UTXO not found, yet it should be there, case fail hard (by an assertion?) than introduce new consensus behavior in the case of bugs.

    sipa commented at 5:45 pm on October 13, 2015:

    (summarizing earlier discussion about this) The problem is that that would be the case whenever the wallet check finality on an transaction whose inputs are already spent.

    IMHO the clean solution is to pass in the heights/times of all inputs to this function, which could have a different implementation for mempool/wallet/blockchain behaviour. Another - but probably more invasive change - would be to extend the CCoinsView interface to be able to request height/time data for inputs, and implement a CCoinsView for the wallet too.


    sipa commented at 5:48 pm on October 13, 2015:
    @maaku Did you test this in conjunction with a wallet? My guess is that it will start hiding all old transactions whose inputs are completely spent, because they are treated as non-final.

    maaku commented at 9:10 pm on October 19, 2015:
    Reverted to prior behavior of continuing to the next input if the UTXO doesn’t exist in the view.
  77. in src/main.cpp: in 0f8a3c420c outdated
    685+        // Fetch the UTXO corresponding to this input.
    686+        if (!pCoinsView->GetCoins(txin.prevout.hash, coins)) {
    687+            // It is fully expected that coinbases inputs are not
    688+            // found in the UTXO set. Proceed to the next intput...
    689+            if (txin.prevout.IsNull())
    690+                continue;
    


    petertodd commented at 5:11 pm on October 8, 2015:
    Is this case tested anywhere?
  78. maaku force-pushed on Oct 8, 2015
  79. maaku force-pushed on Oct 14, 2015
  80. josephpoon commented at 6:47 pm on October 15, 2015: none

    Looks good. Having 1 year of relative time for nSequence is more than sufficient for multisigature revocation scripts used in systems such as Lightning Network. These systems have the particular use case of revoking multisignature double-spends via lower relative locktimes. In effect, the 1 year relative time becomes a dispute period for observing activity on-chain and is therefore well more than sufficient, as that presumes a maximum programmable length of onece per year when one watches the blockchain.

    Additionally, the per-input use of consuming a bit in nSequence makes a lot of sense, as there may be inputs with different behavior – applying it to all inputs with nVersion would significantly increase complexity and reduce use, as maaku explained. It’s also good to have similar functionality for blockheight and relative timestamp to match nLockTime.

    Enabling/disabling relative locks permanently consumes a single bit in nSequence seems to make a lot of sense, as there may be different uses of relative timestamps (e.g. timestops in the future) or more exotic uses. Stellar has something which uses the phrase “sequence number”[1] but appears that functionality in Bitcoin can be used without some sequence flag via sending to different Bitcoin addresses per transaction.

    [1] https://www.stellar.org/blog/multisig-and-simple-contracts-stellar/

  81. instagibbs commented at 9:14 pm on October 15, 2015: member

    utACK

    Gave a close read-over. I think the extra flexibility is a good idea at the expense of total relative lock time span.

  82. maaku force-pushed on Oct 19, 2015
  83. dcousens commented at 10:41 am on October 20, 2015: contributor
    Whats with all the univalue files?
  84. maaku force-pushed on Oct 20, 2015
  85. maaku commented at 4:14 pm on October 20, 2015: contributor
    Build files that should be masked off by .gitignore but weren’t. I’ve removed them.
  86. in src/main.cpp: in 5f7a3587bd outdated
    709+            //
    710+            // Note that it is not guaranteed that indexBestBlock will
    711+            // be consistent with the passed in view. The proper thing
    712+            // to do is to have the view return time information about
    713+            // UTXOs.
    714+            const CBlockIndex& indexBestBlock = *chainActive.Tip();
    


    sdaftuar commented at 7:13 pm on October 21, 2015:
    We need to hold cs_main for this, though I think the callers already do. So perhaps an AssertLockHeld(cs_main) would be appropriate at the top of this function?

    btcdrak commented at 11:03 pm on October 23, 2015:
    It is worth noting that this function was IsFinalTx() which does not currently have an AssertLockHeld(cs_main) in the main tree. I don’t think it does any harm adding an assert though.

    btcdrak commented at 6:58 am on October 24, 2015:
    Ok, I have added AssertLockHeld(cs_main).
  87. dcousens commented at 10:13 pm on October 21, 2015: contributor
    concept ACK, will code review soon
  88. afk11 commented at 3:41 pm on October 22, 2015: contributor
    utACK
  89. jmcorgan commented at 7:14 pm on October 23, 2015: contributor
    FYI the stray univalue files were fixed upstream with an updated .gitignore in libunivalue. Not sure if/when that gets updated in-tree.
  90. btcdrak commented at 7:40 pm on October 23, 2015: contributor
    @jmcorgan it was rebased out.
  91. btcdrak force-pushed on Oct 24, 2015
  92. rubensayshi commented at 9:49 am on October 26, 2015: contributor
    concept ACK
  93. in src/main.cpp: in dd817d2cd1 outdated
    718+            // The only time the negative branch of this conditional
    719+            // is executed is when the prior output was taken from the
    720+            // mempool, in which case we assume it makes it into the
    721+            // same block (see above).
    722+            int64_t nCoinTime = (nCoinHeight <= (indexBestBlock.nHeight+1))
    723+                              ? indexBestBlock.GetAncestor(nCoinHeight-1)->GetMedianTimePast()
    


    NicolasDorier commented at 4:28 pm on October 26, 2015:
    By mistake I commented on the commit not PR, but here it seems it should be GetBlockTime() instead of GetMedianTimePast() or am I missing something ?

    afk11 commented at 5:03 pm on October 26, 2015:

    NicolasDorier commented at 5:05 pm on October 26, 2015:

    Pasting @maaku ’s response on the commit :

    No, GetMedianTimePast is preferred because it is not a free choice by the miner who included the transaction being spent. BIP 113 changes the other end of the interval for both nLockTime and nSequence to be GetMedianTimePast, which is a soft-fork change, but changing the start of the interval in that way would be a hard-fork change. So we start from the very beginning using GetMedianTimePast.

    Ok it is clear thanks !

  94. btcdrak force-pushed on Oct 27, 2015
  95. btcdrak commented at 0:35 am on October 27, 2015: contributor
    This branch has been rebased with the recently merged “median past locktime” #6566
  96. sipa commented at 8:09 pm on October 29, 2015: member
    To reiterate a comment I’ve made before on the commits but which may have been lost: I dislike the fact that the LockTime function skips non-existing inputs in the CCoinsView. I believe that’s a dangerous mix of non-consensus logic in consensus code, and ideally it would be a pure logic functions which just takes a list of input heights/times and makes decisions. Different call sites can then pass that data by pulling it out of chainstate, mempool or wallet as wanted.
  97. petertodd commented at 8:11 pm on October 29, 2015: contributor
    @sipa ACK, and I like the idea of explicitly providing a list to work on.
  98. CodeShark commented at 9:58 pm on October 29, 2015: contributor
    @sipa @petertodd I fully agree that skipping nonexisting inputs is ugly. But in the interest of expedient deployment I would suggest sticking a prominent TODO in there and reworking the calls in a separate PR.
  99. NicolasDorier commented at 7:10 am on October 30, 2015: contributor

    I agree that IsFinalTx should be a pure logic function.

    I think a compromise can be made by having two overload of the IsFinalTx : One with the CCoinsView and the pure logic one.

    The one with CCoinsView would pull out the list of input heights/times and then call the pure function. This would not break the code which already depends on the current IsFinalTx, while still allowing to call the IsFinalTx pure function for other part which need to decide by themselves how to deal with missing inputs.

    If the PR needs to be expedient, the clients of IsFinalTx may be modified in a separate PR, but at least IsFinalTx will be easier to review and test.

  100. NicolasDorier commented at 11:22 am on November 5, 2015: contributor

    I tried to implement the purely logical way of doing it in C#: (code very similar to C) ChainedBlock correspond to CBlockIndex, also this is a non static method, so “Input” and “LockTime” refer to the currently evaluated transaction.

    Basically, I pass an array of CBlockIndex which is expected to have the same size as the number of input in the transaction. If an element is null, I assume that the transaction in the mempool. “confirmedBlocks[i]” corresponds to the CBlockIndex of the i’th input of the transaction.

    https://github.com/MetacoSA/NBitcoin/commit/874a21c240b2da2ab9310d4e5962336cfea4efbb

    Now, for being expedient on this PR, it would be possible to make a LockTime function which have the same parameter as now but which search the “confirmedBlocks” in the CCoinView directly, take the tip of th activeChain, and call the pure logic overload.

  101. NicolasDorier commented at 7:57 am on November 6, 2015: contributor

    Since I am assuming null element of the input’s block array are spent output from the mempool, if you can keep the exact same semantic than now in the case the CCoinView does not have the coin, then you can feel with the array with the genesis CBlockIndex if CCoinView does not find the coin.

    This would have the same effect as:

    0if (!pCoinsView->GetCoins(txin.prevout.hash, coins))
    1            continue;
    

    Because nMinTime and nMinHeight would not be modified.

    I can implement it in C if it helps, but since I can’t really compile it would certainly need some fixes.

  102. NicolasDorier commented at 6:01 am on November 7, 2015: contributor

    I gave it a try : 5f24b6603407c78ae112ae82fd293ac24fbefb52

    I have not compiled it, but it explains my point.

  103. btcdrak commented at 6:56 am on November 7, 2015: contributor

    @NicolasDorier Oh that’s great. I can cherry-pick this into the PR after testing.

    edit: doesn’t compile.

  104. NicolasDorier commented at 8:03 am on November 7, 2015: contributor

    I fix that for tonight, thanks, will setup travis on my branch as well as you advised.

    EDIT : fixed on 6a9495392f0f89ed9ce46ff2bc3460ce443f407a you can try, if it does not work I’ll try to setup travis on my branch to debug myself.

  105. NicolasDorier commented at 2:00 pm on November 10, 2015: contributor

    Just sent a new commit which make LockTime independant from the tip, but also responsible for calculating the blocktime correctly based on MTP flag. With that I could remove several code duplication.

    65506413367f09d34b942a3b1256066e4346eccf

  106. NicolasDorier commented at 4:29 pm on November 10, 2015: contributor

    I’m thinking about changing this line, so the CCoinView is not queried twice. (once in HaveInputs, the other in LockTime to fetch previous coins)

    Also, it would make the consensus code dependent only the purely logical LockTime function instead of the other.

    Thoughts ?

  107. btcdrak force-pushed on Nov 10, 2015
  108. btcdrak commented at 7:30 pm on November 10, 2015: contributor
    rebased.
  109. btcdrak force-pushed on Nov 11, 2015
  110. jtimon commented at 4:23 pm on November 11, 2015: contributor

    @NicolasDorier

    I’m thinking about changing this line, so the CCoinView is not queried twice. (once in HaveInputs, the other in LockTime to fetch previous coins) Thoughts ?

    It reminds me of #6445 (which I’m happy to rebase at any time if/when/after “we merge the mempool limiting code” (sorry, I’m not sure which PR to point you to) ).

  111. jtimon commented at 4:42 pm on November 11, 2015: contributor
    utACK
  112. NicolasDorier commented at 6:19 pm on November 11, 2015: contributor

    The scope of #6445 seems to do way more optimization. So I think that all of these optimization should be done at the same time with another PR. (calling the logical function LockTime included) I also don’t know if it is worth since the CCoinView is already caching coins.

    The PR seems complete to me right now, I’ll start making more tests by running a node.

    Last question I have : I’m not used to dev in C, so I don’t really know the best practice out here, as you can see here there is a std::vector<CCoins> parameter. This works fine, but does a std::vector<CCoin*> would be preferable to avoid copies ?

  113. instagibbs commented at 6:42 pm on November 11, 2015: member
    @NicolasDorier it is passing a reference to the vector. Not a C pro myself either but that shouldn’t copy
  114. sipa commented at 6:44 pm on November 11, 2015: member
    @instagibbs @NicolasDorier Indeed, it’s being passed by reference.
  115. NicolasDorier commented at 4:51 am on November 12, 2015: contributor
    The vector is not copied, but when I access coins with .at (write or read) there is a copy of the item.
  116. sipa commented at 4:54 am on November 12, 2015: member
    No there isn’t. Using the at method also returns a reference.
  117. in src/main.cpp: in 949f8b63c1 outdated
    648-    BOOST_FOREACH(const CTxIn& txin, tx.vin)
    649-        if (!txin.IsFinal())
    650-            return false;
    651-    return true;
    652+    int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
    653+                                    ? block.pprev->GetMedianTimePast()
    


    maaku commented at 5:16 am on November 12, 2015:
    This will access uninitialized memory beyond the stack on the genesis block.

    NicolasDorier commented at 6:39 am on November 12, 2015:

    Good catch, I just fixed it on https://github.com/NicolasDorier/bitcoin/commit/eb2696281bd9bd13d0fca5c25e7c96969b5ef518

    If you want to update this PR.


    btcdrak commented at 11:14 am on November 12, 2015:
    This has been updated.
  118. NicolasDorier commented at 12:01 pm on November 12, 2015: contributor
    @btcdrak you should squash the two last commit together.
  119. btcdrak force-pushed on Nov 12, 2015
  120. sipa commented at 8:43 pm on November 12, 2015: member
    @NicolasDorier So you’ve abstracted out a pure function for locktime calculations, but you’re keeping a single wrapper for everything. Ideally, there would be different wrappers for mempool, chainstate(consensus), and wallet. Perhaps mempool and wallet can use the same one.
  121. NicolasDorier commented at 6:08 am on November 13, 2015: contributor
    @sipa I addressed your nits on 95ea71b3f84f4c630470e2f85f0fb7ee5154b84b, thanks for reviewing, my C skills are a bit rusty. (Except the point about a coin not being found in the CCoinView) I planned to use the pure function on this line but @jtimon pointed out that a bigger optimization is on the way (#6445) so I think it is better to use the pure one on a separate PR which make the optimizations. @btcdrak can you add my commit ? (travis running but it should be good)
  122. btcdrak commented at 7:33 am on November 13, 2015: contributor
    @NicolasDorier Cherry picked in f45f136, this should address the bulk of @sipa’s nits, the optimisations will be done in a separate PR after this is merged.
  123. jgarzik commented at 8:00 am on November 13, 2015: contributor

    concept ACK + it-works test

    Reviewed downstream payment channel code and specifications - no apparent conflicting uses in the field widely deployed AFAICS, which was my main concern with BIP 68.

  124. jonasschnelli commented at 8:37 am on November 16, 2015: contributor

    Concept ACK.

    I really miss some RPC tests. A RPC test/playground-script could be used to demo the new functionality, allow modification for testers and would prove that it actually works. For testing/verification purposes its far more useful than the internal unit tests (not saying the unit tests would then be superfluous!).

  125. NicolasDorier commented at 6:48 am on November 17, 2015: contributor

    @jonasschnelli I can provide that, but it would be in C#, so I’m not sure if it will be useful for people here.

    Maybe a website where you can create your own script and point it to your node ?

  126. jonasschnelli commented at 8:10 am on November 17, 2015: contributor

    @NicolasDorier: I think it should be in line with our qa/rpc-tests. They are written in Python, a language that everyone can lear within 5-10mins. :) You might check the bip65 test scripts: https://github.com/bitcoin/bitcoin/blob/master/qa/rpc-tests/bip65-cltv-p2p.py

    Would be awesome to see some bip68 rpc tests that demonstrate and test real-world examples.

  127. btcdrak commented at 8:43 am on November 17, 2015: contributor

    @jonasschnelli those are tests for the softfork and were added to CLTV after the mempool only PR was merged. They were added as part of the CLTV softfork implementation in #6351.

    So for this reason, we’ll add RPC tests when it’s time to activate the softfork.

    This PR is 5 months old now and we’ve accommodated everyone’s nits. I believe it’s refined enough now to be merged. It is currently mempool-only behaviour so does not pose any risks.

    I don’t want this PR to end up in “rebase-hell”, especially because we know there are more refactoring coming up that will affect this patch. Better merge now, and refactor/optimise afterwards.

  128. btcdrak force-pushed on Nov 17, 2015
  129. btcdrak commented at 10:45 am on November 17, 2015: contributor
    Had to rebase again due to changes in master.
  130. btcdrak force-pushed on Nov 17, 2015
  131. btcdrak commented at 8:00 pm on November 17, 2015: contributor
    Rebase again due to divergence with master.
  132. CodeShark commented at 11:50 am on November 19, 2015: contributor
    Builds and syncs without incident here - and the miner tests pass. I have not tested it with custom transactions yet, but I’ve given the code itself a once over and the logic seems to be correct (I could have missed something, I’ll have another look). @NicolasDorier @btcdrak I think the commits could be restructured a bit, and in particular, the commits creating two different LockTime functions could probably be squashed.
  133. greenaddress commented at 12:04 pm on November 19, 2015: contributor
    utACK
  134. sipa commented at 12:07 pm on November 19, 2015: member
    This is still using the “if not found in chainstate, skip” logic I was hoping to avoid in consensus logic…
  135. CodeShark commented at 12:12 pm on November 19, 2015: contributor
    @sipa I agree we should get rid of that logic, but we really need to get something merged soon and perhaps it would be better to fix that issue in a separate PR.
  136. sipa commented at 12:16 pm on November 19, 2015: member
    @CodeShark But the logic to avoid it is there! It’s just still using the wrapper inside consensus!
  137. sipa commented at 2:03 pm on November 19, 2015: member

    @btcdrak Please have a look at https://github.com/sipa/bitcoin/commits/sequencenumbers. I added a commit that turns LockTime into a function that only takes in a height map of inputs, and CheckLockTime contain all mempool-specific logic (no intermediate-level LockTime function either).

    It also avoids calling the inefficient GetCoins method on pcoinsTip in block validation, which would make a full copy of all UTXO data of transactions being spent.

  138. NicolasDorier commented at 3:53 pm on November 19, 2015: contributor

    Reviewed d6ed8e6 this is good to me, I prefer the height map as well. Although, I think not having the wrapper make it less readable. What difference between GetCoins and AccessCoins ? if the problem was about performance, we could have used AccessCoins in the wrapper, it would spare us some code. @CodeShark I’m not against squashing anything, I just thought it was better for review to keep them separate:

    • 3a3687d introduced the wrapper class and was not breaking client code of LockTime.
    • d2ca485 broke clients and was done to simplify the call to LockTime.
    • 31ebf4a fixed a bug in the previous implementation which happened on spending of unconf coins.
    • 86061f6 could be squashed though

    I think they should be reviewed separately to understand how we’ve been from @maaku implementation to the modified one.

  139. sipa commented at 4:01 pm on November 19, 2015: member

    @NicolasDorier Yes, performance. GetCoins copies. AccessCoins returns a reference. But you can only use AccessCoins on caches (so not on the mempoolview, for example).

    I’m not against leaving the wrapper, though I think it’s better this way.

  140. NicolasDorier commented at 4:10 pm on November 19, 2015: contributor
    I see, so it needs to be different at both places, if so, the wrapper does not help much so better keeping it this way.
  141. btcdrak force-pushed on Nov 19, 2015
  142. btcdrak commented at 5:06 pm on November 19, 2015: contributor
    Okay, I’ve fixed up and squashed commits a bit according to @CodeShark and added @sipa commit. Is there anything else?
  143. jtimon commented at 6:55 pm on November 19, 2015: contributor
    @sipa what about https://github.com/jtimon/bitcoin/commit/071bc1cf615c0528d4f7e2fe33dc80186da447d3 ? Is using size() == 0 instead of pointer == NULL to signal the special case.
  144. NicolasDorier commented at 4:51 am on November 20, 2015: contributor

    @jtimon I’m not sure but I think there are blocks in the past without input for the coinbase ? In such case they would be size() == 0, but this would have different semantic as point==NULL.

    Also, I think expressing missing parameter with NULL is more common.

  145. sipa commented at 10:24 am on November 20, 2015: member

    @Nicolas there is a consensus rule that all transactions (including coinbases) have at least one input and one output.

    No opinion otherwise.

  146. jtimon commented at 12:10 pm on November 20, 2015: contributor
    Well, == NULL may be more common than .size.() == 0, but using a pointer instead of a reference unnecessarily complicates things for no good reason. Look at how many & from the callers we could remove if using a ref, for example. Any drawback that I’m missing?
  147. btcdrak commented at 5:42 pm on November 20, 2015: contributor
    @jtimon Thank you for taking time to consider options. After some discussions on IRC I have decided I not to merge jtimon@071bc1c in this PR because it appears contentious and unnecessary.
  148. in src/primitives/transaction.h: in 3497aabf83 outdated
    69+     * sequence number disabled relative lock-time. */
    70+    static const uint32_t SEQUENCE_LOCKTIME_DISABLED_FLAG = (1 << 31);
    71+    /* If CTxIn::nSequence encodes a relative lock-time and this flag
    72+     * is set, the relative lock-time has units of 512 seconds,
    73+     * otherwise it specifies blocks with a granularity of 1. */
    74+    static const uint32_t SEQUENCE_LOCKTIME_SECONDS_FLAG = (1 << 22);
    


    btcdrak commented at 7:37 pm on November 20, 2015:
    Bikeshedding myself but I think SEQUENCE_LOCKTIME_SECONDS_FLAG is not a good name because this flag determines the type of relative lock-time, i.e. timebased or block based. I wonder if SEQUENCE_LOCKTIME_TYPE_FLAG would be better.

    NicolasDorier commented at 7:50 am on November 21, 2015:
    I agree on that, this got me confused as well

    CodeShark commented at 7:55 am on November 21, 2015:
    I also agree.
  149. btcdrak force-pushed on Nov 21, 2015
  150. btcdrak force-pushed on Nov 21, 2015
  151. btcdrak force-pushed on Nov 22, 2015
  152. btcdrak commented at 5:26 am on November 22, 2015: contributor
    Rebased due to conflicting changes in master.
  153. instagibbs commented at 2:28 am on November 24, 2015: member
    Carefully went through the latest draft of the BIP, and checked the related sections in this pull, especially LockTime(). Description and code lines up.
  154. jtimon commented at 6:51 pm on November 30, 2015: contributor
    re-utACK with the latest changes. Is there still anything holding this back?
  155. in src/main.cpp: in 0efb962e2e outdated
    652+    assert(prevHeights == NULL || prevHeights->size() == tx.vin.size());
    653+    int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
    654+                                    ? block.GetAncestor(std::max(block.nHeight-1, 0))->GetMedianTimePast()
    655+                                    : block.GetBlockTime();
    656+
    657+    bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2
    


    jtimon commented at 8:33 pm on November 30, 2015:
    why is this cast needed?

    maaku commented at 0:07 am on December 1, 2015:

    Because otherwise you’d be doing a signed comparison and there’d be half the range of nVersion that wouldn’t support BIP 68.

    On Tue, Dec 1, 2015 at 4:33 AM, Jorge Timón notifications@github.com wrote:

    In src/main.cpp #6312 (review):

    {

    • if (tx.nLockTime == 0)
    •    return true;
      
    • if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
    •    return true;
      
    • BOOST_FOREACH(const CTxIn& txin, tx.vin)
    •    if (!txin.IsFinal())
      
    •        return false;
      
    • return true;
    • assert(prevHeights == NULL || prevHeights->size() == tx.vin.size());
    • int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
    •                                ? block.GetAncestor(std::max(block.nHeight-1, 0))->GetMedianTimePast()
      
    •                                : block.GetBlockTime();
      
    • bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2

    why is this cast needed?

    — Reply to this email directly or view it on GitHub https://github.com/bitcoin/bitcoin/pull/6312/files#r46199226.


    jtimon commented at 7:21 pm on December 1, 2015:
    Mhmm, I believe I have asked this before…maybe a comment here would be useful (although of course it can be added later).

    sipa commented at 7:22 pm on December 1, 2015:
    Agree with @jtimon. This is not obvious.

    btcdrak commented at 6:57 pm on December 2, 2015:
    I added a comment to explain the casting.
  156. NicolasDorier commented at 3:46 pm on December 1, 2015: contributor
  157. afk11 commented at 5:16 am on December 2, 2015: contributor
    Needs rebase
  158. btcdrak force-pushed on Dec 2, 2015
  159. btcdrak force-pushed on Dec 2, 2015
  160. btcdrak force-pushed on Dec 2, 2015
  161. Reverse structure of IsFinalTx()
    Instead of checking if the transaction is in a category of cases to return true and failing otherwise, we return false if the tx is a failure case and otherwise return true. This removes an early-exit opportunity which will no longer be possible once sequence numbers are re-enabled, but has no change in behaviour.
    30392955af
  162. Get rid of CTxIn::IsFinal(), which is only used in one location and whose semantics will not survive revival of sequence numbers, and introduce CTxIn::SEQUENCE_FINAL constant instead. 998230b446
  163. Expand IsFinalTx() to the structure it will have when it becomes LockTime()
    Breaks up the modifications to IsFinalTx() / LockTime() for easier review. This commit does not change the logic of IsFinalTx().
    bf45b9fa5a
  164. Add rules--presently disabled--for using sequence numbers as a relative lock time
    In summary, the sequence number of each input in a transaction can be used to store a relative locktime: a delta value which is added to the height or time of the block which included the output being spent to generate a per-input lock time from the sequence number. If enforced, this would make consensus-enforced transaction replacement possible as replacing an input with a lower sequence number / relative lock time would allow the new transaction to make it on the chain before previous versions of the transaction become valid.
    
    This commit does not implement the transaction replacement logic. Nor does this commit make the relative lock time rules as consensus or policy rules. It merely adds new, but disabled functionality and unit tests of that functionality.
    deedf00b96
  165. Enable policy enforcing sequence numbers as a relative lock time in the mempool and transaction selection code, for the purpose of later supporting consensus-enforced transaction replacement
    Transactions that fail relative lock time checks will be rejected from the mempool and not included in generated blocks, making it easy to test the feature. However blocks including transactions containing "invalid" relative lock times will still be accepted; this is *not* the soft-fork required to actually enable relative lock times for production use.
    8110e73112
  166. Add AssertLockHeld(cs_main) to LockTime() function. 33ec593aa1
  167. Transform LockTime to a pure logic function, while not breaking existing code fc4bfb40bd
  168. btcdrak force-pushed on Dec 2, 2015
  169. NicolasDorier commented at 3:21 pm on December 2, 2015: contributor
    @sipa a rewrite has been done by #6898 makes it impossible to call LockTime by passing the prevHeights. (because all calls to the CCoinsView have been remove) I have the feeling that fetching the prevHeights by using the view to fix the problem will kill the perf improvement made by #6898, making it irrrelevant. @morcos can you advise ? The problem is that we call LockTime (which was IsFinalTx before), but for BIP68 we need parent’s height. If we need parent’s height, then we’ll query the view, which would kill your perf improvement #6898. Do you see a solution to the problem ?
  170. sipa commented at 3:25 pm on December 2, 2015: member
    We’ll need to store the input’s heights inside the mempool entries. I don’t think that’s hard.
  171. NicolasDorier commented at 3:31 pm on December 2, 2015: contributor
    ok sorry, it seems to be stored already… trying that out.
  172. Make LockTime function easier to use by not requiring the tip, and by making it responsible to calculate the right blockTime from flags
    LockTime() : the nCoinTime of a confirmed coin does not depend on MTP
    flag, so the nCoinTime of an unconfirmed also should not be.
    
    Addressing sipa's nits
    aa83819cac
  173. morcos commented at 4:12 pm on December 2, 2015: member

    @NicolasDorier Ah, I hadn’t realized that we wouldn’t be able to merge #6312 until we worked on the efficient way of doing that. @sipa Why not just make the mempool be consistent with finality of txs so we don’t have to check that any more in CreateNewBlock. This is what we discussed in #6915, we only need to store one height, which is the max of the height the tx is viable for coinbase maturity and for BIP68 sequence numbers. Then on a reorg we revaluate if the reorg dropped below this height.

    So that’s necessary before #6312 can be merged? I or @sdaftuar can do it.

  174. NicolasDorier commented at 4:34 pm on December 2, 2015: contributor

    I tried to modify sipa’s commit to adapt on https://github.com/NicolasDorier/bitcoin/commit/33254c779baa365f15af74074e66f620388a5e5e#diff-4a59b408ad3778278c3aeffa7da33c3cL142 but it is not good it fails

    0test_bitcoin: main.cpp:666: int64_t LockTime(const CTransaction&, int, const std::__debug::vector<int>*, const CBlockIndex&): Assertion `prevHeights == __null || prevHeights->size() == tx.vin.size()' failed.
    1unknown location(0): fatal error in "CreateNewBlock_validity": signal: SIGABRT (application abort requested)
    2test/miner_tests.cpp(139): last checkpoint
    

    This is the only point that need to be fixed for rebasing, I needed to fix conflict and modify lots of commits which took into account recent commits on master, https://github.com/NicolasDorier/bitcoin/commits/sequencenumbers .

    I don’t understand why what I did for CreateBlocks does not work though (GetMempoolParent only get parents which are in mempool and not conf ?)… I would appreciate some help, this really seems the last problem. :(

  175. NicolasDorier commented at 4:45 pm on December 2, 2015: contributor

    @morcos AFAIK a transaction is not accepted into mempool if finality does not pass. Link

    So maybe preheights are not needed at all and we can just pass NULL to LockTime() or even not checking at all. Someone can confirm ?

  176. sipa commented at 4:48 pm on December 2, 2015: member
    Right now I believe that during a reorg the finality of transactions can theoretically get violated (because the chain height can go down, though this is very unlikely). So we’d need to evaluate finality upon disconnect if we want to remove finality checking from CNB.
  177. NicolasDorier commented at 4:52 pm on December 2, 2015: contributor
    How can a reorg can make the chain height go down ? I thought the only way a reorg could happen was if a longest chain was discovered.
  178. instagibbs commented at 4:54 pm on December 2, 2015: member
    @NicolasDorier more total work not height
  179. morcos commented at 4:58 pm on December 2, 2015: member
    @NicolasDorier It’s also whether the height went below the height that each of the previous inputs was confirmed at, because they may have changed height, even if the reorg finished at a higher height.
  180. morcos commented at 5:02 pm on December 2, 2015: member
    @NicolasDorier Looking briefly at your branch, you seem to be looking at the heights of the mempool parents. Thats not the same thing as looking at all the parents.
  181. NicolasDorier commented at 5:04 pm on December 2, 2015: contributor

    Ok, I understand. Checking finality during reorg is better done in a separate PR, or can we try to squeeze it into this one ?

    Seems like best to do that than trying to fetch heights in CNB like I tried.

  182. morcos commented at 5:17 pm on December 2, 2015: member
    I think probably the right thing to do is fetch heights in CNB the slow and correct way for this pull. And then have a separate pull that properly calculates finality in a reorg and we can then remove that code from CNB. We should make sure to do the 2nd step before releasing 0.12.1 though, otherwise we’ll have a serious regression in CNB performance.
  183. Make LockTime use a height map of inputs 6bf228e4c3
  184. Rename flags
    _SECONDS_FLAG to _TYPE_FLAG
    _DISABLED_FLAG to _DISABLE_FLAG
    bd5a760e69
  185. btcdrak force-pushed on Dec 2, 2015
  186. btcdrak commented at 6:42 pm on December 2, 2015: contributor
    This has been rebase (by @NicolasDorier)
  187. NicolasDorier commented at 6:44 pm on December 2, 2015: contributor

    I did as @morcos advised. It will be easy to get rid off once finality is enforced in mempool.

    Also I had to adapt CheckLockTime here because of 2d8860e820e2ca73000f558eb9686206bec2652a. I fixed some comments which had IsFinalTx references.

    This is about all I remember now.

  188. Explain the reason for unsigned cast of tx.nVersion ae5d345a62
  189. maaku commented at 0:52 am on December 3, 2015: contributor

    @NicolasDorier longest-chain means most-work, not most-blocks. Think about a reorg that crosses drastically different difficulty adjustments.

    But while such edge cases should be properly handled, I wouldn’t want you to waste your time trying to get the checks in CNB removed. Such a change will be nack’d. Those checks exist because we’ve had mempool inconsistencies in the past, and we will have mempool inconsistencies in the future. This is other people’s money we’re talking about in CNB, so it’s really not a terrible thing to double-check ourselves.

  190. NicolasDorier commented at 3:20 am on December 3, 2015: contributor

    @maaku I understand for the chain, I indeed thought longest chain was “more blocks”. It is a bit a shame that it breaks the perf improvement that @morcos spent time to fix though.

    What I propose to keep CNB while having perf improvement, is to save in mempool entry the highest blockid at the time of AcceptToMempool after the finality check. In CNB if the blockid of the mempool entry is not in current chain, then we do the CNB test, else we can skip it. How does it sound ? Easy to implement, and not lots of room for mistake. (I think people will not like the +32bytes per entry ;( )

  191. morcos commented at 4:04 am on December 3, 2015: member
    @maaku The evolution of CreateNewBlock has been to not do any checks. It now depends on the mempool’s consistency for everything other than finality of txs. Adding finality of txs is next. @NicolasDorier What @sdaftuar and I are already working on is a variation of what you are proposing. Our idea is to keep the mempool consistent so CNB never has to do any finality checks, so on a reorg you will recheck everything that may no longer be final. You will do this by storing the height and time at which the entry is final, and only recalculating if the reorg dropped below that height (or for added efficiency if the reorg dropped below the height necessary to calculate those heights). There is some nuance if we ever decide to allow non-final txs in the mempool (which seems like something we might want to do at some point). In any case, I think we merge #6312 without that performance improvement and just bring the performance back in line before release.
  192. btcdrak commented at 4:08 am on December 3, 2015: contributor
    There was some conversation about CNB today here
  193. NicolasDorier commented at 4:56 am on December 3, 2015: contributor

    You will do this by storing the height and time at which the entry is final, and only recalculating if the reorg dropped below that height (or for added efficiency if the reorg dropped below the height necessary to calculate those heights).

    Doing such thing would be a bug. Because even if the reorg does not drop below the height, the FinalTx may be invalidated. (the “blocktime” in LockTime() may have changed) This is why we would need to store the hash of the evaluated block in the mempool entry, not only the height.

  194. morcos commented at 1:45 pm on December 3, 2015: member
    @NicolasDorier yes I was just describing the basic idea, you still have to recheck the locktime (height or time) and the sequence (height and time) for every tx in the mempool. what you want to do is make those checks quick. locktime is always quick, if we only recalculate the sequence validity height and time only when necessary then we’ll achieve our goal.
  195. jtimon commented at 6:18 pm on December 3, 2015: contributor

    or can we try to squeeze it into this one ?

    At some point we will hopefully stop improving this PR and finally merge it. It was my belief that the plan was to do it before 0.12, but 6 months after the functionality was first implemented and more than 5 months after the PR was created (now) seems as good of a time as any other. That doesn’t mean we can’t keep improving the code later, but it would be nice to finally get this functionality in. We use this “that improvement can be added later” argument with many other PRs, in fact, I’m pretty confused about what’s the criterion on when to stop adding improvements to a given PR, it seems very inconsistent from PR to PR (this PR being a good example of a perpetually-changing PR).

  196. sipa commented at 6:20 pm on December 3, 2015: member
    As discussed in the weekly meetings several times, several people are not confortable that the BIP has had sufficient review. We can’t merge unless it won’t change anymore.
  197. jtimon commented at 6:29 pm on December 3, 2015: contributor
    I thought the mismatch between the BIP and the code had been solved. But I completely agree on it stop changing so that it can be merged. I like @NicolasDorier and @sipa ’s included changes but in my opinion the PR already had too many ACKs when they were added and that’s what I mean with improvements that could have been done later.
  198. NicolasDorier commented at 9:17 pm on December 3, 2015: contributor
    Ok let’s freeze it now so people can review and ACK. Btw, I am tempted to make LockTime() returns 0 for the coinbase transaction explicitly. In ConnectBlock, finality is not tested for the coinbase, but for some reason it is tested in CNB since #6898 Link. Returning 0 explicitly if we pass coinbase to LockTime() will disable the finality check if we pass by mistake a coinbase elsewhere to LockTime. Thoughts ?
  199. jtimon commented at 9:59 pm on December 3, 2015: contributor
    @NicolasDorier I’ll happily review any further improvements once this is merged.
  200. NicolasDorier commented at 10:22 pm on December 3, 2015: contributor
    Woops sorry… reflex. Review time ! :)
  201. jtimon commented at 10:59 pm on December 3, 2015: contributor
    @NicolasDorier In the meantime…there’s another function that could benefit from the kind of work that has been put in this PR lately that could use some of the same ideas: Consensus::CheckTxInputs in main.cpp currently has a const CCoinsViewCache& parameter and I would happily review any attempt to change that fact. Just saying…
  202. morcos commented at 4:40 am on December 4, 2015: member

    This is what I had in mind: https://github.com/maaku/bitcoin/compare/sequencenumbers...morcos:refactorb

    It’s still missing commits to properly recalculate the LockPoints after a reorg and to remove the checking of LockTime in CreateNewBlock. However I wanted to see if this is the direction people want to go?

  203. NicolasDorier commented at 8:11 am on December 4, 2015: contributor
    It is a good idea I think, but it should better be done in a separate PR. This one is already a monster shaky PR, every time someone commit into master, I need to rebase. Would like to flush the PR. :(
  204. btcdrak commented at 10:30 am on December 4, 2015: contributor
    @NicolasDorier I think @morcos idea should be added to this PR. I’m happy to cherry-pick. This was also echoed in the IRC meeting yesterday.
  205. jtimon commented at 1:03 pm on December 4, 2015: contributor
    It would be nice if the people who are in favor to keep changing this would voice it here for those of us who missed the meeting. I think the meeting should be a complement but not a replacement to discussion in github for obvious traceability reasons. Personally, I won’t have time to re-utACK this if we cherry pick more things in. And many of the earlier acks haven’t been repeated after the latest changes anyway. But I’m sure others reviewers won’t mind to keep reviewing changes to this PR and hopefully it will be finally merged after one or 2 more iterations even if I don’t participate in the review anymore. Hopefully not 6 months more!
  206. morcos commented at 1:35 pm on December 4, 2015: member

    @NicolasDorier The only thing that I’d argue should be added to this PR is the change to the consensus functions. The first commit from my branch and maybe the change to CheckLockTime from the second. The other changes should be in a separate PR that is backported only to 0.12 (but before the point release that contains this PR)

    I wanted to show the version that has the fewest changes from this PR first, but I do think its a good question as to whether thats the right goal. This is unreleased consensus code still, so it might make sense to make a bit more substantial refactor. Open questions:

    • After breaking up the function in two two parts, is it necessary to maintain the original LockTime interface?
    • Do we want to retain the semantics of returning an int64_t now that we’re populating a bit more information in the LockPoints?
    • Should I return LockPoints instead of using an output argument?
    • Should maxInputHeight instead be a block hash or even BlockIndex*?
    • Obviously LockPoints shouldn’t be in txmempool.h, but where should it go?
    • Reach goal: I’m not a super big fan of prevheights being NULL. Do we still need the check in ContextualCheckBlock?

    These changes would be very small additional changes to the consensus code, but would require changing all the tests, so it would be more to review.

  207. jtimon commented at 1:49 pm on December 4, 2015: contributor
    @morcos can you summarize what is the problem that your proposed changes are supposed to solve again?
  208. sipa commented at 1:59 pm on December 4, 2015: member
    This patch makes CNB fetch data from the UTXO set again, nullifying the performance improvement we got from the rewrite.
  209. jtimon commented at 2:14 pm on December 4, 2015: contributor
    Then maybe it would have been a good idea to have merged this first before merging the CNB optimization rewrite(much newer code than this, btw), but anyway, too late for that. I fail to see how https://github.com/maaku/bitcoin/compare/sequencenumbers...morcos:refactorb solves the issue without touching miner.cpp, but that may be because I haven’t reviewed the CNB in much detail. Thank you for the explanations but as said I won’t have time to review the CNB rewrite to be able to re-utACK this. I won’t distract those who want to introduce and review more changes to this PR with more comments. Keep up the good work (just please don’t keep it up for 6 more months).
  210. NicolasDorier commented at 5:09 pm on December 4, 2015: contributor

    @morcos, on my side, I’m just getting tired of rebasing every time something change on master. I’ll do anything to get that merged. I’ll pay ACKs in beers for those coming in HK… And make them drink until they give the ACK. :p

    I quickly reviewed your commits : I don’t understand the purpose of the structure update_lock_points. I fear also that we will again need to update the BIPs explaining why there is a new structure and why it is broken in two function before this PR can be pushed. And pushing your two commits in this PR without the one calling updatePoint during reorg is like doing the job mid way spread onto 2 different PR.

    This is a good idea, but the monstruosity of this PR make it already hard to review, which is why it never get ACKed. A sort of psychological blocks happen when one see 11 commits with 174 messages in discussion. Anyway, I’m not against having your commits in this PR if it accelerate the reviews, but I doubt it.

  211. morcos commented at 8:30 pm on December 4, 2015: member

    (EDITED) OK I updated https://github.com/maaku/bitcoin/compare/sequencenumbers...morcos:refactorb to be a slightly different refactoring.

    The first two commits are bug fixes for the unit tests. The third commit is a minor refactor of LockTime to get access to the critical variables. The fourth commit uses that refactor to store LockPoints in CTxMemPoolEntries. The fifth commit keeps LockPoints valid during a reorg. The sixth commit removes LockTime calculations from CreateNewBlock

    Probably the miner_tests need to be completely rewritten now that mempool consistency is depended on. A lot of the tests are designed to make sure invalid blocks won’t be created if the mempool isn’t consistent.

    If this is the direction of refactor we want to achieve our goal, then I think we should only cherry-pick at most the first three commits into this pull (and for backporting to 0.11). The third commit which is the change to consensus code should be trivial for people to review.

  212. jtimon commented at 10:33 pm on December 4, 2015: contributor

    @morcos what is exactly the problem with leaving all your commits for the next PR instead of putting “half of the change” here? Now I see why I wasn’t able to understand how your code fixes cnb (the goal of the changes), it doesn’t yet!

    I think it’s better to put the preparation commits in the same PR when the preparations are actually going to be used when possible (ie when this doesn’t result in a 20 commit PR). Otherwise ww may change our mind on how to fix the problem but the preparations remain there.

  213. morcos commented at 10:35 pm on December 4, 2015: member
    @NicolasDorier OK I think I’m done. I edited the above message to reflect the final branch.
  214. morcos commented at 10:37 pm on December 4, 2015: member
    @jtimon Yeah that actually might be fine. I think the question is how much are we going to refactor the consensus code. This turns out to be a relatively minor refactor, but we might decide to do a more significant one instead. Since this is all new consensus code, it makes sense to get it right the first time so that we don’t have to change it again in the future, and so that the backported to 0.11 code is as similar to 0.12 and master as possible. Anyway, I’m done with my proposed branch now.
  215. NicolasDorier commented at 11:02 am on December 5, 2015: contributor

    I prefered your previous commits CalculateLocks should returns information direclty into LockPoint datastructure, so we don’t have to make the mapping. Also I think it is hard to review right now and I guess, @maaku was not so eager to remove locktime check in CNB.

    How about a simpler change : We store a bool called “LockTimeChecked” in the mempool entry, then when there is a reorg (which is the only case where the lock can be invalidated) we set the bool do false.

    CNB, would check LockTime only if the bool is false, and once checked, it can put it back to “true” so next call to CNB will be fast.

    I am not comfortable with your changes, it change lots of stuff that was reviewed and tested. Not mentioning the fact we would need to update the BIP again. My change would achieve the same thing as you but with minimal changes. I will try to propose a commit.

  216. jtimon commented at 11:41 am on December 5, 2015: contributor

    @NicolasDorier sounds like a nice and easy way to solve the CNB performance problem without having to touch the consensus code further and without having it depend on new structures.

    Let’s have a thought experiment. Let’s say this was merged with morcos’ preparations for his solution but without the actual solution for CNB. Let’s say @NicolasDorier had had the odea only after merging morcos’ preparations. Now what? Do we revert morcos’ changes? That’s why I don’t like including more things here. Regarding bakports, the same commits can be backported regarlesss of them being in a single PR or 2 separate ones. Please let’s leave this as it is and solve the CNB performance issue later, even if we all like Nicolas’ solution. We may rhink of another even better solution later.

  217. sipa commented at 11:46 am on December 5, 2015: member
    I think there’s a good argument for trying to get the code to a point where it’s easily merged both in 0.12 and older branches.
  218. morcos commented at 12:40 pm on December 5, 2015: member
    @NicolasDorier By all means please try another approach. @sdaftuar was also working on a slight variation, that I originally thought might be better than this, although now I think this is better. I’m not sure which code changes you aren’t comfortable with though. I believe the changes to #6312 are very minimal, again its only the 3rd commit that changes consensus code. The original commits were worse in that they introduced LockPoints to consensus and it was not easy to do the reorg testing with only a height. @jtimon Your concern about the prep commits changing if the final solution changes is exactly why I’m working on trying to get the final solution right now. @NicolasDorier do you want to at least go ahead and take the two bug fix commits (you can squash them, not sure why I left them as 2).
  219. btcdrak commented at 12:41 pm on December 5, 2015: contributor

    For the record, @ajtowns has been working on some exotic HTLC functional demos using my #6312+#6564 branch which will help allay fears about the lack of tested ACKs (which is the real reason for delay). It will also help protect against regression if we need to change anything.

    This PR has to be backported to 0.11 and 0.12, so we need to take that into consideration. So long as we have good functional tests we should be able to add commits to cater for CNB() optimisations that can be removed for 0.11.

    With regards to updating the BIP, we’re not changing any of the specification, only parts of the code implementation which is simple copy paste, so I don’t think it will present a problem.

    tl;dr - while I appreciate reluctance for too much change, that is not the obstacle to getting this merged.

  220. btcdrak commented at 12:42 pm on December 5, 2015: contributor

    @morcos I’ve cherry-picked the bug fixes as a first step.

    EDIT: squashed morcos/bitcoin@71922fb and morcos/bitcoin@0bc5b84 into 4a01034

  221. Fix minor bugs in miner_tests
    There was an extraneous tx being added to the mempool which spent the same inputs.  This only didn't cause a problem because locktimes stopped it from being selected for the template.
    
    In addition, since the merger of MedianTimePast, locked txs that were time based were not being correctly tested in the unit test.
    4a010348d8
  222. btcdrak force-pushed on Dec 5, 2015
  223. jtimon commented at 3:08 pm on December 5, 2015: contributor
    @morcos yeah, my point is that with either add the final solution or nothing at all. My preference would be nothing at all and doing the “final solution” in another PR (and also backport that, at least to 0.12 which has the rewritten CNB), but if everybody else prefers to do the 2 different things in this one PR, I won’t say anything else on the subject. I just don’t see the backport advantage of doing it all in one PR (while I see how more changes invalidate previous reviews and delay the merging further and that this PR is becoming harder and harder to read, not just for current reviewers, but also for future readers once it is merged]).
  224. NicolasDorier commented at 4:04 pm on December 5, 2015: contributor
    @morcos not for this PR, but what would you say about another PR after this one for : https://github.com/NicolasDorier/bitcoin/commit/b13f47535cc24304176dfb9cd3f12511cf095055
  225. jtimon referenced this in commit b13f47535c on Dec 5, 2015
  226. NicolasDorier commented at 1:15 am on December 6, 2015: contributor
    Just created an issue so we can debate without polluting here #7176
  227. NicolasDorier commented at 7:39 am on December 6, 2015: contributor
    Let me apologize if I seem to have put pressure or lost my nerves, about getting tired of rebasing and wanting csv, it is not the case. Lots of you had way more pressure than me, and I’ve not been really conscious about it, I’ll rebase when there is a need to.
  228. morcos referenced this in commit d08dfced59 on Dec 7, 2015
  229. morcos referenced this in commit 5635e5b5ab on Dec 8, 2015
  230. morcos referenced this in commit ba957d5407 on Dec 8, 2015
  231. morcos referenced this in commit bd5d29f870 on Dec 8, 2015
  232. morcos referenced this in commit b6ba13472a on Dec 8, 2015
  233. morcos referenced this in commit ce229b5ca8 on Dec 9, 2015
  234. morcos referenced this in commit 50ce92f985 on Dec 9, 2015
  235. morcos commented at 3:10 am on December 9, 2015: member
    @NicolasDorier Is there a reason you calculated the prevheights directly in CreateNewBlock instead of just calling CheckLockTime there? I’m just thinking about the best way to back port this to 0.11, which will have no choice but to be slow in CreateNewBlock.
  236. NicolasDorier commented at 3:49 am on December 9, 2015: contributor

    Yes, CheckLockTime assumes that if a parent is not in CCoinView, then the locktime is correct. I don’t want this behavior in CNB, what I want is : if it is not in CCoinView, assume it is in the mempool.

    But this will likely be completely deleted because I managed to keep mempool consistent with finality while not having to call CheckLockTime on every tx in the mempool during reorg (which was a big performance problem, regardless of CNB, as you noted), we will not have to call CheckLockTime in CNB now. Can you check https://github.com/NicolasDorier/bitcoin/compare/67646e099c13...b2a27a71823b to see if it makes sense ? I’ve fixed the failing test. Travis running, but it should work.

  237. NicolasDorier commented at 3:57 pm on December 10, 2015: contributor
    Is there any concern about assuming MTP only in LockTime() so we can get rid of the MTP flag ? (and get rid off the enum by the same occasion)
  238. morcos commented at 4:03 pm on December 10, 2015: member

    @NicolasDorier We need MTP and BIP 113 and the enum all for the purposes of nLockTime locks because nLockTime is already consensus and we want to soft fork its semantics to be MTP.

    However in the case of sequence locks and BIP 68, there is no reason for us to not just redefine BIP 68 to have MTP semantics from the outset, because there is no policy or consensus meaning to sequence locks yet.

  239. NicolasDorier commented at 4:23 pm on December 10, 2015: contributor
    Ok thanks. So we can’t change anything in this PR relative to the MTP flags.
  240. NicolasDorier commented at 10:55 am on December 14, 2015: contributor

    This change to BIP68 (https://github.com/bitcoin/bips/pull/260) while making a clearer specification just broke completely this PR. Basically this PR assumed similar blocktime calculation (MTP or not) policy for both nLockTime and sequence lock time. But the change of specification makes MTP mandatory for sequence locktime while nLockTime is still depends on MTP activation.

    This PR, if preferred over alternatives, will need to be updated. (or the change to specification reverted) I expect the changes to tests code and logic to be significant though to be worth the trouble.

    I think the best choices are either to move to Morcos’ PR (https://github.com/bitcoin/bitcoin/pull/7184) which is very different from this implementation. Or, reverting https://github.com/bitcoin/bips/pull/260 if people wants to stick with this well reviewed PR.

  241. btcdrak commented at 2:27 pm on December 14, 2015: contributor

    The assumption of MTP only was discussed at the IRC meeting and that BIP68 and BIP113 need to be softforked together.

    I am in favour of #7184. However, the assumption was if this PR is chosen over #7184 then this PR would be updated accordingly to the new specification. It’s just #7184 already made the assumption. It’s a lot cleaner to assume MTP and really, there is no situation where it would not be MTP because we are deploying 68 and 113 together.

  242. morcos commented at 2:35 pm on December 14, 2015: member

    Yeah sorry about that, I guess it is a bit tough to try to keep BIP spec in line with code. But honestly I think this confusion shows why I like the code organization of #7184 better. The consensus code for sequence and nLockTime is too intermingled here.

    One of the hesitations with switching to #7184 has been that this PR is already heavily reviewed and tested. I think this is wrong. It had a lot of preliminary review, but then the code changed, and I think its had only minimal testing. An example is the checking of sequence locks that is throughout the wallet and GUI code in this PR. I believe those would lead to unacceptable performance for any node with a half way decent size wallet. They would slow down a lot of operations and also make the utxo cache worthless.

  243. btcdrak commented at 2:52 pm on December 14, 2015: contributor
    @morcos I absolutely agree, we cannot claim this PR is well reviewed because each reviewer, reviewed it in a different state. Regardless, this has been beneficial in refining the specification and implementation.
  244. NicolasDorier commented at 3:09 pm on December 14, 2015: contributor
    Understood, I have no particular feeling about it, just worried #7184 would delay CSV adoption for months.
  245. jtimon commented at 7:21 am on December 20, 2015: contributor

    I think this is wrong. It had a lot of preliminary review, but then the code changed, and I think its had only minimal testing.

    It is true that the code changed after most of the reviews were done. Fortunately @btcdrak kept the commits separated so that concern has an easy solution: remove the latest changes. I have to say that this has also been tested as part of the elements/alpha testchain (still in operation) for more than 6 months. @rustyrussell may be able to tell us more about tests in the context of lighting development (my apologies if that’s not the case).

  246. NicolasDorier commented at 10:18 am on December 20, 2015: contributor

    @jtimon one of my change is actually a bug fix… sadly it was squashed. Regardless of what happen, this should be kept.

    The problem was that the birth time of an unconfirmed coin was set to blockTime which depended on MTP activation. Whereas confirmed coins always used MTP time.

  247. maaku commented at 10:28 am on December 20, 2015: contributor
    I have to say it was bad form that #7184 merged everything into one commit as it makes the review significantly harder (and less critically, credit assignment less clear). I think it was also bad form to split off a separate PR for the exact same feature, rather than discuss the alternative implementation pathway in the same thread, but I digress…
  248. jtimon commented at 10:56 am on December 20, 2015: contributor

    @NicolasDorier Well, if it was a bugfix then it’s not sad that it was squashed, is it? I mean more the later changes to make the function a pure function, which is, I assume the less reviewed changes @morcos is concerned with.

    In my opinion no optimization had been needed in the mining code this could have been merged before 0.12 with no backporting problems. If the optimizations hadn’t been urgent they could have been later during 0.13.99. But now it’s too late for that, thus the need for #7176 . All the possible fixes could be built on top of the same branch (this one, for example) to compare them more easily, but seems not everybody agrees that a common base makes branches easier because I have already say this without the different proponents agreeing on a common base, and @maaku seems to be the only other person that thinks #7187 should be based on this PR instead of #7184 so I shouldn’t insist on this.

  249. NicolasDorier commented at 11:03 am on December 20, 2015: contributor
    By “sad being squashed”, I mean that if you want to revert recent changes I made, at least you should keep the bug fix commit. Extracting it would have been simpler without squash. (but well, the bug is not a big deal to fix again)
  250. maaku commented at 11:14 am on December 20, 2015: contributor

    Which is why it is better not to squash until the very end before merge. On Dec 20, 2015 7:04 PM, “Nicolas Dorier” notifications@github.com wrote:

    By “sad being squashed”, I mean that if you want to revert recent changes I made, at least you should keep the bug fix commit. Extracting it would have been simpler without squash. (but well, the bug is not a big deal to fix again)

    — Reply to this email directly or view it on GitHub #6312 (comment).

  251. btcdrak commented at 11:55 am on December 20, 2015: contributor
    @maaku I think #7184 can be redone with commit history. @morcos
  252. morcos commented at 1:02 pm on December 20, 2015: member

    As already posted on #7184

    https://github.com/maaku/bitcoin/compare/sequencenumbers...morcos:7184onorig6312

    Feel free to incorporate that here if that is preferred.

  253. rustyrussell commented at 4:23 am on January 7, 2016: contributor

    Tested-by: Rusty Russell rusty@rustcorp.com.au

    (I merged both this and #6564 for the test, with only a trivial conflict to resolve).

  254. btcdrak commented at 7:57 pm on January 14, 2016: contributor
    Closing in favour of #7184
  255. morcos referenced this in commit 1d4310627b on Jan 14, 2016
  256. laanwj closed this on Jan 16, 2016

  257. morcos referenced this in commit c6c2f0fd78 on Feb 10, 2016
  258. NicolasDorier referenced this in commit adec2a2bf9 on Feb 13, 2016
  259. NicolasDorier referenced this in commit a3b783f462 on Feb 13, 2016
  260. NicolasDorier referenced this in commit 59fbfea951 on Feb 13, 2016
  261. NicolasDorier referenced this in commit 91e5fee499 on Feb 13, 2016
  262. jtimon referenced this in commit caf6ba1015 on Feb 14, 2016
  263. btcdrak referenced this in commit 5cc159f3cb on Feb 16, 2016
  264. instagibbs referenced this in commit bcef61083c on Feb 25, 2016
  265. GamerSg referenced this in commit 99a0128a1f on Feb 27, 2016
  266. btcdrak referenced this in commit 21b2a6d733 on Mar 18, 2016
  267. btcdrak referenced this in commit 15ba08c3b5 on Mar 18, 2016
  268. rebroad referenced this in commit 9c07c6bed7 on Dec 7, 2016
  269. fanquake locked this on Jan 9, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-11-17 03:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me