-
Notifications
You must be signed in to change notification settings - Fork 268
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
Generate local alias before spawning channel #2316
Conversation
eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala
Outdated
Show resolved
Hide resolved
eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/MigrationMethods.scala
Outdated
Show resolved
Hide resolved
6fc252f
to
3becfb8
Compare
I have an alternative design for alias generation: what about inserting a new temporary channel state to generate it? Whenever we currently call |
Something else that comes to mind: for public channels that aren't using 0-conf (which is going to be the most common flow for most node operators), we probably shouldn't really generate a |
I thought about that, but I'd don't like adding new states because we then need to handle all the other events (remote errors, funding spent, disconnection, etc.) and it quickly becomes bulky.
That's a good point, but I think we don't want to have duplicate aliases, it should be an |
Yes, it's true, after thinking about it more I think we should keep the |
eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/Mutators.scala
Outdated
Show resolved
Hide resolved
* .as[MyClass] | ||
* }}} | ||
*/ | ||
object Mutators { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we put that in a versioned namespace (this one would go in the version3
package since we introduced the need for it in version3
and won't need it for future versions)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, although we sort of adopted the opposite approach for ChannelTypes0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the contrary, we put ChannelTypes0
in the version1
package? But it doesn't matter right now, we can move those mutators to a versioned package when we introduce new ones that are for a different codecs version.
Using the first 7B increases the risk of collision at migration due to how `channel_id` is built. Collisions would happen when multiple channels are funded with the same transaction.
val localAlias_p = Promise[Alias]() | ||
context.system.eventStream.publish(Register.GenerateLocalAlias(localAlias_p)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't very academic, but:
- using the
eventStream
saves us from having to pass a reference toregister
all the way to thepeer
- using a
Promise
saves us from creating an ad-hoc actor (pipeTo
doesn't work with theeventStream
approach)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, only a few comments (and a rebase is needed).
// at block height 1000 LN didn't exist, so all real scids less than that will never be used | ||
val upperBound = RealShortChannelId.apply(BlockHeight(1000),1,0).toLong |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we use such a small range? We can go up to at least block 350 000, can't we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The space is already huge : 1_099_511_627_841_536 (*) and we are checking for duplicates. I figure leaving some values available could prove handy later?
(*) So huge in fact that I believe our previous computation was invalid. If we indeed go up to block height 350 000 it gives us a ceiling of 384_829_069_721_665_536 which is about 2^59. The probability of a collision for 250 000 channels would be 0.000011 %, not 0.8 % ?
def generateLocalAlias(): Alias = { | ||
// at block height 1000 LN didn't exist, so all real scids less than that will never be used | ||
val upperBound = RealShortChannelId.apply(BlockHeight(1000),1,0).toLong | ||
Alias(Random.nextLong(upperBound)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use the randomLong
from package.scala
here.
* .as[MyClass] | ||
* }}} | ||
*/ | ||
object Mutators { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the contrary, we put ChannelTypes0
in the version1
package? But it doesn't matter right now, we can move those mutators to a versioned package when we introduce new ones that are for a different codecs version.
@@ -79,6 +82,13 @@ class Register extends Actor with ActorLogging { | |||
case Some(channel) => channel.tell(msg, compatReplyTo) | |||
case None => compatReplyTo ! ForwardShortIdFailure(fwd) | |||
} | |||
|
|||
case GenerateLocalAlias(promise) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we re-populate the shortIds
map asynchronously as channels are restored and send ShortChannelIdAssigned
, we may receive that message before we've restored all channels and recovered a complete shortIds
map.
I believe it won't be an issue in practice as long as the range we use for ShortChannelId.generateLocalAlias()
is big enough to make collisions unlikely.
system.eventStream.subscribe(generateLocalAliasListener.ref, classOf[GenerateLocalAlias]) | ||
waitEventStreamSynced(system.eventStream) | ||
generateLocalAliasListener.setAutoPilot { | ||
case (_, gen:GenerateLocalAlias) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
case (_, gen:GenerateLocalAlias) => | |
case (_, gen: GenerateLocalAlias) => |
Superseded by #2337. |
As a first step before addressing #2224 (comment), we need to make the alias generation asynchronous.
Peer generates the alias along with the shutdown script, and before spawning the channel.
This approach has several drawbacks:
WAIT_FOR_FUNDING_CONFIRMED
, which is persisted and requires a migration. We can't set it to the real scid because we don't have it yet