Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate ZmqWatcher to akka-typed #1759

Merged
merged 16 commits into from
May 4, 2021
Merged

Migrate ZmqWatcher to akka-typed #1759

merged 16 commits into from
May 4, 2021

Conversation

t-bast
Copy link
Member

@t-bast t-bast commented Apr 9, 2021

Use akka-typed for the ZmqWatcher actor.
It is probably best reviewed commit by commit.

  • the first commit just moves to akka-typed with minimal changes
  • the second commit adds tests (in particular for the subtle case of confirmed txs never seen in mempool).
  • the third commit adds type constraints on the BitcoinEvent (even though they're actually dropped at runtime because of type erasure, but since the compiler enforces it it's enough). Note that this introduces compiler warnings in ZmqWatcher.scala that I don't know how to get rid of.

I tried to go even further and also constrain the replyTo for each Watch, something like:

  sealed trait WatchEvent[E <: BitcoinEvent] {
    def event: E
  }
  sealed trait Watch[E <: BitcoinEvent, R <: WatchEvent[E]] extends Command {
    def replyTo: ActorRef[R]
    def event: E
  }
  final case class WatchConfirmed[E <: BitcoinEvent](replyTo: ActorRef[WatchEventConfirmed[E]], txId: ByteVector32, minDepth: Long, event: E) extends Watch[E, WatchEventConfirmed[E]]
  final case class WatchEventConfirmed[E <: BitcoinEvent](event: E, blockHeight: Int, txIndex: Int, tx: Transaction) extends WatchEvent[E]

This would let us remove the unsafeUpcast in TxPublisher, but I lost to the compiler on that one...
Another reason I gave up this approach is that these type constraints aren't really enforced, they're basically hidden .asInstanceOf[E] that will only throw at runtime if we guessed wrong, but not at compile-time, so it may not be worth going in that direction...

This is why in the last commits I instead flattened the hierarchy to get rid of generic types as much as possible, which provides much better type safety.

EDIT: these caveats have eventually all been resolved in the last commits. We're now in a good state where we make the most of strong typing without bumping into type erasure!

Use akka typed for the ZmqWatcher actor.
This is a naive port with minimal code changes.
More changes will be added in the next commits to leverage akka typed
more extensively.
Add missing test cases and enrich existing tests.
This ensures WatchEvents use the same concrete BitcoinEvent as their
corresponding Watch.
No functional change, just moving the code at the beginning of the file.
@codecov-commenter
Copy link

codecov-commenter commented Apr 22, 2021

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

Attention: Patch coverage is 89.78102% with 14 lines in your changes missing coverage. Please review.

Project coverage is 89.28%. Comparing base (48c0c4c) to head (60b75c6).
Report is 689 commits behind head on master.

Files with missing lines Patch % Lines
...c/main/scala/fr/acinq/eclair/channel/Channel.scala 67.74% 10 Missing ⚠️
.../acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala 95.83% 4 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1759      +/-   ##
==========================================
+ Coverage   89.17%   89.28%   +0.10%     
==========================================
  Files         144      144              
  Lines       10822    10933     +111     
  Branches      494      455      -39     
==========================================
+ Hits         9651     9762     +111     
  Misses       1171     1171              
Files with missing lines Coverage Δ
...air-core/src/main/scala/fr/acinq/eclair/Logs.scala 89.79% <ø> (ø)
...ir-core/src/main/scala/fr/acinq/eclair/Setup.scala 80.23% <100.00%> (ø)
...lockchain/bitcoind/rpc/ExtendedBitcoinClient.scala 96.42% <ø> (ø)
...n/scala/fr/acinq/eclair/channel/ChannelTypes.scala 97.14% <ø> (ø)
...in/scala/fr/acinq/eclair/channel/TxPublisher.scala 97.02% <100.00%> (-0.02%) ⬇️
...-core/src/main/scala/fr/acinq/eclair/io/Peer.scala 89.89% <ø> (ø)
...src/main/scala/fr/acinq/eclair/router/Router.scala 93.54% <100.00%> (ø)
...main/scala/fr/acinq/eclair/router/Validation.scala 90.76% <100.00%> (ø)
.../acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala 96.80% <95.83%> (-2.30%) ⬇️
...c/main/scala/fr/acinq/eclair/channel/Channel.scala 86.47% <67.74%> (-0.13%) ⬇️

... and 24 files with indirect coverage changes

Instead of encapsulating a `BitcoinEvent`, flatten all watches types used.
It provides better type safety and prevents potential incoherencies with the
type of `BitcoinEvent` encapsulated.
We only keep "real" events that can be sent directly to watchers instead of
being wrapped in watch events.
There was a race condition with block production, where we didn't properly
wait for the right block to be confirmed before setting the watch.
@pm47
Copy link
Member

pm47 commented May 4, 2021

I suggest replacing ebad701 by 611bb80. It's more fool proof, is consistent with checkConfirmed, and makes the actor less cluttered.

Copy link
Member

@pm47 pm47 left a comment

Choose a reason for hiding this comment

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

That's a pretty cool change!

@t-bast
Copy link
Member Author

t-bast commented May 4, 2021

I suggest replacing ebad701 by 611bb80. It's more fool proof, is consistent with checkConfirmed, and makes the actor less cluttered.

Good idea, done in 2a2d8dc

pm47
pm47 previously approved these changes May 4, 2021
@t-bast t-bast merged commit 9e4042f into master May 4, 2021
@t-bast t-bast deleted the typed-watcher branch May 4, 2021 16:22
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.

3 participants