Skip to content

Use 48-bit commitment transaction numbers#93

Merged
Roasbeef merged 8 commits into
lightningnetwork:masterfrom
cjamthagen:statehints
Feb 22, 2017
Merged

Use 48-bit commitment transaction numbers#93
Roasbeef merged 8 commits into
lightningnetwork:masterfrom
cjamthagen:statehints

Conversation

@cjamthagen
Copy link
Copy Markdown
Contributor

TODO: fix deriveStateHintObsfucator to set correct obsfucator for the channel. According to the spec the payment-basepoints from open_channel and accept_channel are needed, and they don't seem to be implemented yet.

Since I am pretty new to writing Go, please let me know if I have done something wrong.

Copy link
Copy Markdown
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I was literally just thinking about making this change the other day.

This looks pretty good so far, however the build is currently failing since the change as it stands is incomplete:

  • The lnwire.SingleFundingComplete message needs to be altered to accept a 6-byte obfuscator rather than a 4-byte one.

With that change the Travis should be able to successfully build this PR and run all the tests.

You're correct that the current funding workflow in the daemon doesn't yet match the workflow as outlined within the spec. A few pieces are currently being assembled towards adherence in that area which is why I added the StateHintObsfucator field to hold us over until our funding workflow was fully compliant.

One final thing that would be great would be to modify the add an additional set of tests which we can use to generate test-vectors for the spec. The additional set of tests would be in the form of table driven tests. Such a form will allow us to easily add more cases in the future and also easily translate our set of tests to test vectors which the rest of the implementers can use.

Comment thread lnwallet/script_utils.go Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can avoid a heap allocation here by declaring the slice as a fixed-sized array like so:

var obfs [8]byte

Comment thread lnwallet/script_utils.go Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here as above about using a fixed-sized array instead of a dynamically allocated slice.

@cjamthagen
Copy link
Copy Markdown
Contributor Author

Fixed.

Question: Is there a specific way to rebase to master that is preferred?

Will work on the tests next.

@Roasbeef
Copy link
Copy Markdown
Member

Roasbeef commented Jan 6, 2017

Great, thanks!

I've answered your question about rebasing in this comment on your other PR.

@cjamthagen cjamthagen force-pushed the statehints branch 2 times, most recently from f08a1c3 to 7ce0857 Compare January 9, 2017 09:04
@cjamthagen
Copy link
Copy Markdown
Contributor Author

Table driven tests added.

@cjamthagen cjamthagen force-pushed the statehints branch 2 times, most recently from 1a3e5f2 to d978a32 Compare January 11, 2017 06:53
@cjamthagen
Copy link
Copy Markdown
Contributor Author

cjamthagen commented Jan 13, 2017

It seems like the locktime is the culprit for not passing the 'channel force closure' integration test.

The lower 24 bits of the locktime represents the lower 24 bits of the obscured commitment transaction number. If the high byte of locktime is always zero, then the locktime value can only assume a maximum value of 16,777,215, which is below 500,000,000, meaning the locktime will always be compared to blockheight and not MTP, if enabled. Similarly the sequence number will never take the value maxInt (0xFFFFFFFF) because the high byte will always be 0x80. This means that the locktime will not be disabled for the commit transaction, and the commit transaction will not be eligible for inclusion in a block until it has the proper height as constrained by its locktime.

If this is the case, then the locktime cannot be used as defined in the specification to hold the obscured commitment transaction number, because it would risk rendering the commitment transaction unspendable in many cases, only passing as spendable in 2-3% of the time on the mainchain.

Let me know I got anything wrong.

Edit: Although, shouldn't transactions which can not be included due to locktime be rejected from the mempool? During the 'channel force closure' test, the commitment transaction is in the mempool.

Edit2: Looks like SimNetParams sets RelayNonStdTxs to true, so the commitment transaction can be included in the mempool. Right?

Edit3: Changing RelayNonStdTxs to false will still include the commitment transaction.

@cjamthagen
Copy link
Copy Markdown
Contributor Author

Alright, setting the 30th bit (1<<29) of the locktime fixes the problem and allows the test to pass. I'll await some comments and then propose an update to BOLT 3.

Copy link
Copy Markdown
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! I've completed a final pass of the code and have also done a bit of testing locally. Thanks for expanding the unit tests to exercise those additional cases I missed the first time around when.

There's a set of test vectors pending within the spec that should take care of ensuring the precise algorithm to encoding/decoding the state hints are detailed within the spec.

LGTM!

Two things are currently blocking me merging this PR:

  1. These two commits should be squashed together:
    • 5f42ff94c30f7801d93a896e37c19313abddd66e and f6bced9a94e51584abfe2a116de3a1164c35c0ec
  2. I'll need to first merge in the PR which adds the init message. If I merge this one first, then nodes will on either side of the latest commits (in master) won't be able to create channels with each other as the initial commitment sigs will fail validation.
    • Temporarily, I'll modify the local feature bits to abort channel creation if bit for "48-bit state hints" isn't set. Within an upcoming major version the temporary local feature bits we add will be eliminated and instead aligned with the bits as specified within the spec.

Comment thread lnwire/lnwire.go Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit (175112af510ca5888684c68b760bb6fdbf7e66e1) should also be amended to remove the case for in readElement/writeElement for a [4]byte as it was only used for the 24-bit state hints which have been deprecated by this PR.

Comment thread lnwallet/script_utils_test.go Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit: there should be a space before the comment here and the comment should be expanded to a complete sentence.

@cjamthagen
Copy link
Copy Markdown
Contributor Author

Fixed. I'll take a look at the test vectors in the spec and make sure they get added.

@Roasbeef Roasbeef force-pushed the master branch 2 times, most recently from d86107c to a34df2f Compare February 8, 2017 04:54
Copy link
Copy Markdown
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! This PR inches us a bit closer to having full compatibility with the current specification draft.

This PR now conflicts with master, I think if you remove the last commit all together, then the conflict will go away. The change itself is incomplete, as it doesn't modify the ChannelDelta usage within the database.

Will take another run through after the last commit is removed, likely stamping this with an "LGTM" and getting it merged finally :)

Fix SetStateNumHint and GetStateNumHint to properly
set and get the stateNumHints using the lower 24 bits
of the locktime of the commitment transaction as the
lower 24 bits of the obfuscated state number and the
lower 24 bits of the sequence field as the higher 24
bits.
and remove serialization for type [4]byte.
Add tests to assert maximum state can be used. Also test
that more than one input in the commitment transaction
will fail and that having state number larger than
maxStateHint will fail.
Add table-driven tests for testing GetStateHint and SetStateHint in package lnwallet.
Introduce TimelockShift which is used to make sure the commitment
transaction is spendable by setting the locktime with it so that
it is larger than 500,000,000, thus interpreting it as Unix epoch
timestamp and not a block height. It is also smaller than the current
timestamp which has bit (1 << 30) set, so there is no risk of having
the commitment transaction be rejected. This way we can safely use
the lower 24 bits of the locktime field for part of the obscured
commitment transaction number.
@cjamthagen
Copy link
Copy Markdown
Contributor Author

Done. What ChannelDelta usage needed modification?

@Roasbeef
Copy link
Copy Markdown
Member

@cjamthagen this modification: db8c6d4

Copy link
Copy Markdown
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🎉

@Roasbeef Roasbeef merged commit cf30609 into lightningnetwork:master Feb 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants