Skip to content

htlcswitch: batch preimage writes/consistency fix#2501

Merged
Roasbeef merged 8 commits into
lightningnetwork:masterfrom
cfromknecht:batch-preimage-writes
Feb 22, 2019
Merged

htlcswitch: batch preimage writes/consistency fix#2501
Roasbeef merged 8 commits into
lightningnetwork:masterfrom
cfromknecht:batch-preimage-writes

Conversation

@cfromknecht
Copy link
Copy Markdown
Contributor

This PR adds batched writes for witnesses discovered in HTLC forwarding. At the same time, we correct a nuanced consistency issue related to a lack of synchronization with the channel state machine. Forcing the individual preimage writes to be synchronized with the link incurs a heavy performance penalty (about 80% from my measurements). Batching these allows us to minimize the number of db transactions required to write the preimages, allowing us to reinsert the batched write into the link's critical path and resolve the possible inconsistency. In fact, the benchmarks actually showed a slight performance improvement, even with the extra write in the critical path.

See commit messages for more details.

Comment thread htlcswitch/link.go Outdated
Comment thread htlcswitch/link.go Outdated
Comment thread channeldb/witness_cache_test.go Outdated
Comment thread witness_beacon.go Outdated
Comment thread contractcourt/channel_arbitrator.go Outdated
Comment thread htlcswitch/link.go Outdated
Comment thread htlcswitch/link.go Outdated
Copy link
Copy Markdown
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

Very nice fix 👍 🦊

Comment thread channeldb/witness_cache.go Outdated
Comment thread channeldb/witness_cache_test.go Outdated
Comment thread contractcourt/channel_arbitrator.go Outdated
Comment thread contractcourt/htlc_outgoing_contest_resolver.go Outdated
Comment thread witness_beacon.go Outdated
@cfromknecht cfromknecht force-pushed the batch-preimage-writes branch 3 times, most recently from 70f2c6d to c173aa0 Compare February 13, 2019 06:40
@cfromknecht
Copy link
Copy Markdown
Contributor Author

cfromknecht commented Feb 13, 2019

@joostjager @halseth ready for another round of review. the changes sprawled quite a bit as you'll see.

I plan to consolidate bc01a41 (the move to lntypes) and a5fc555 (first commit), but wanted to get your feedback on the additional commits before doing so.

Along the way:

  • lnmock is born, avoiding the same mockPreimageCache implementation in 4 places in the code base.
  • lntypes is moved to lnhash
  • channeldb.WitnessCache gained the AddSHA256Witnesses helper, to avoid the extra copied in the preimageBeacon
  • modfiied the channeldb/witness_cache_test to test batch insertion
  • added a link-level test to assert that the changes in htlcswitch/link.go behave as expected.

ptal

Copy link
Copy Markdown
Contributor

@joostjager joostjager left a comment

Choose a reason for hiding this comment

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

I think having those Hash and Preimage types is proving good (thanks @halseth). I like the strictness it introduces.

Comment thread htlcswitch/link_test.go Outdated
Comment thread lntypes/preimage.go Outdated
Comment thread lnwallet/channel.go Outdated
Comment thread lnmock/preimage_cache.go Outdated
Comment thread channeldb/invoices.go Outdated
Comment thread channeldb/witness_cache.go Outdated
Comment thread witness_beacon.go Outdated
@cfromknecht cfromknecht force-pushed the batch-preimage-writes branch 3 times, most recently from 08a4cf0 to f921e0a Compare February 13, 2019 19:27
@cfromknecht
Copy link
Copy Markdown
Contributor Author

@joostjager @halseth comments addressed and commits restructured, ptal

@cfromknecht cfromknecht force-pushed the batch-preimage-writes branch from f921e0a to 5f62111 Compare February 13, 2019 19:32
Comment thread contractcourt/htlc_success_resolver.go Outdated
Comment thread contractcourt/htlc_incoming_contest_resolver.go Outdated
Comment thread lnwallet/channel.go Outdated
Comment thread channeldb/witness_cache.go Outdated
Comment thread lnwallet/channel.go Outdated
@cfromknecht cfromknecht force-pushed the batch-preimage-writes branch from 5f62111 to 981eaac Compare February 16, 2019 01:26
@cfromknecht cfromknecht added this to the 0.6 milestone Feb 16, 2019
@cfromknecht
Copy link
Copy Markdown
Contributor Author

@joostjager revamped the witness cache to only expose the specific interface, makes everything much cleaner imo, ptal

@cfromknecht cfromknecht force-pushed the batch-preimage-writes branch 2 times, most recently from e8f02a9 to 73a041a Compare February 16, 2019 01:39
@cfromknecht
Copy link
Copy Markdown
Contributor Author

cfromknecht commented Feb 16, 2019

note: planning to squash channeldb+witness_beacon: use sha256 lookup+delete witness (46c6c96) down into channeldb/witness_cache: create AddSHA256Witnesses helper + test (e3766be)

Copy link
Copy Markdown
Contributor

@joostjager joostjager left a comment

Choose a reason for hiding this comment

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

Yes, could use some squashing indeed. PR is looking good.

Comment thread contractcourt/htlc_outgoing_contest_resolver.go Outdated
Comment thread contractcourt/htlc_success_resolver.go Outdated
Comment thread htlcswitch/link_test.go Outdated
Copy link
Copy Markdown
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

Most changes look good in general, but I think this PR has sprawled a bit, which can be a bit dangerous when we are dealing with important stuff s.a. preimages 🙊

Would prefer splitting changes unrelated to the original change out 😄

re: squashing commits "bc01a41 (the move to lntypes) and a5fc555 (first commit)", I don't think that is necessary, as it is nice to separate commits that just moves/refactors code, from commits that actually changes behavior.

Comment thread lntypes/preimage.go Outdated
Comment thread contractcourt/channel_arbitrator.go Outdated
Comment thread contractcourt/htlc_outgoing_contest_resolver.go Outdated
Comment thread contractcourt/htlc_success_resolver.go Outdated
Comment thread witness_beacon.go Outdated
Comment thread lnmock/preimage_cache.go Outdated
Comment thread contractcourt/htlc_success_resolver.go Outdated
Comment thread lnwallet/channel.go Outdated
Comment thread channeldb/witness_cache.go Outdated
Comment thread contractcourt/htlc_incoming_contest_resolver.go Outdated
@cfromknecht cfromknecht force-pushed the batch-preimage-writes branch from 73a041a to d062cbc Compare February 20, 2019 00:06
In this commit, we modify the WitnessCache's
AddPreimage method to accept a variadic number
of preimages. This enables callers to batch
preimage writes in performance critical areas
of the codebase, e.g. the htlcswitch.

Additionally, we lift the computation of the
witnesses' keys outside of the db transaction.
This saves us from having to do hashing inside
and blocking other callers, and limits extraneous
blocking at the call site.
This commit makes use of the batched AddWitness
method of the WitnessCache, in order to avoid
performing one write for each accepted preimage.

Additionally, this fixes an existing hole in the
consistency guarantees since the batched writes
are now guaranteed to take place before accepting
the next CommitSig. Previously, these writes were
processed in an unsynchronized go routine that
could be delayed arbitrarily long before being
executed.

With this change, the async_payments_benchmarks
actually shows a slight improvement in
performance, presumably because we no longer do
an individual write per preimage, even though
the execution is now explicitly in the critical
path. There is likely also a marginal performance
improvement from the reduction in goroutine
overhead.
@cfromknecht cfromknecht force-pushed the batch-preimage-writes branch from d062cbc to 0a3e1cf Compare February 20, 2019 01:06
@cfromknecht
Copy link
Copy Markdown
Contributor Author

@halseth @joostjager i took out the commits that removed the preimage cache from lnwallet, should be a little more contained now. it still includes the commits that make the switch to lntypes as requested, ptal

Copy link
Copy Markdown
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

Thanks, I'm much more comfortable with the current scope of the PR!

Gave it a thorough review, the commit structure made it a breeze. LGTM! 🥇

Comment thread channeldb/witness_cache.go
Comment thread contractcourt/channel_arbitrator.go Outdated
@Roasbeef Roasbeef merged commit cbe0bf6 into lightningnetwork:master Feb 22, 2019
@cfromknecht cfromknecht deleted the batch-preimage-writes branch February 22, 2019 01:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants