-
Notifications
You must be signed in to change notification settings - Fork 81
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
multi: Autopilot session linking #621
Conversation
ca48d39
to
f6fa1e3
Compare
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.
First round done, it's a very impressive PR 🥇, nice commit structure! Will also do manual tests in the next round.
9f6b95b
to
b289546
Compare
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.
First round of code review looks good 🔥 🚀!! Really nice PR.
Will also do more deep manual testing for next round :)!
session_rpcserver.go
Outdated
return nil, err | ||
} | ||
|
||
if prevSess.State != session.StateRevoked && |
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.
Shouldn't we check here that there's no active session for whole group, and not just that the session for the prevPub
isn't active? Else this will allow people to set the PrevLocalPub
to an old session in the group that has already been replaced by a new session, and this will instead fail in on the AutoPilot
server side. I think we should have checks on both the client + server side?
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.
really good point.
The only thing stopping me from adding this is that currently, to do this, we would need to iterate through and load all of our sessions into memory to figure out which ones belong to the group. We currently dont even store the session ID in the session DB. So it could potentially be a very slow query if we have 100s of sessions.
So
- option 1 is: we leave it like this and rely on autopilot to return an error (not ideal since we already persisted some things before calling autopilot)
- option 2: we build an index from session pubkey to session ID.
- option 3: we bite the bullet and migrate Lit to use a sqlite db
I gueeeesss the best thing to do for now is option 2
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.
ok i've added option 2 in the commit before this one 🤓
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.
Awesome, thanks! Agree that this is the best option for now :)!
I guess the only case this can happen now is if a user tries to link a session to a group where all sessions are expired, but then doesn't link the latest session in the group, but a previous one. That will succeed here, but fail on the AutoPilot
server side. Though I think that's a fair tradeoff to not add checks for that in LiT and instead just error on the AutoPilot
server side.
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.
cool - this should no longer be an issue with the latest update and I think we no longer need to check the whole group. Let me know if you agree.
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.
Really like the last update 🔥!
Though as we send the request to register the session to the Autopilot server before we store the session, we need to also need to add a check before this, that checks the linkedSessionIndex
to see that no other session has linked a session using that id, so that that check fails before we send a request to the autopilot server.
I think we should keep this linkedSessionIndex
check on LiT even if we change how the Autopilot server checks if a session can be linked corresponding to my other comment :)! I think the linkedSessionIndex
way of checking it is really neat for LiT
and I don't think that should any cause any issues similar to the ones I've described in my other comment 🚀!
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.
Nice, this looks very close 🚀. Tested out the migration manually, also tried to go back to an older code version, which was prevented as expected.
firewall/rule_enforcer.go
Outdated
@@ -30,6 +30,7 @@ var _ mid.RequestInterceptor = (*RuleEnforcer)(nil) | |||
type RuleEnforcer struct { | |||
ruleDB firewalldb.RulesDB | |||
actionsDB firewalldb.ActionReadDBGetter | |||
sessionIDIndexDB firewalldb.SessionIDIndex |
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.
suggestion: I feel like the previous commit may be easier to understand if squashed with this one
b289546
to
b355746
Compare
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.
thanks for the review so far @ViktorTigerstrom & @bitromortac !!
I've updated accordingly.
I've added one new commit called session: add session ID to Key index
session_rpcserver.go
Outdated
return nil, err | ||
} | ||
|
||
if prevSess.State != session.StateRevoked && |
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.
really good point.
The only thing stopping me from adding this is that currently, to do this, we would need to iterate through and load all of our sessions into memory to figure out which ones belong to the group. We currently dont even store the session ID in the session DB. So it could potentially be a very slow query if we have 100s of sessions.
So
- option 1 is: we leave it like this and rely on autopilot to return an error (not ideal since we already persisted some things before calling autopilot)
- option 2: we build an index from session pubkey to session ID.
- option 3: we bite the bullet and migrate Lit to use a sqlite db
I gueeeesss the best thing to do for now is option 2
session_rpcserver.go
Outdated
return nil, err | ||
} | ||
|
||
if prevSess.State != session.StateRevoked && |
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.
ok i've added option 2 in the commit before this one 🤓
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.
New changes looks great! Still manually not done with second round of reviewing, but reviewing the changes first :)
Leaving one comment regarding an issue introduced with the latest push.
session_rpcserver.go
Outdated
prevSess, err := s.db.GetSessionByID(id) | ||
if err != nil { | ||
return nil, err | ||
} |
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.
Sorry now we just introduced a case of the issue I comment about before 😅:
#621 (comment)
If we can't find the session in the db, we should just move on to the next id of the prevSessionIDs
:).
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.
ah! yeah true 😂 good catch! will update tomorrow.
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.
think this is now fine with latest updates :)
b355746
to
4972e85
Compare
gonna add something else shortly 🤓 |
4972e85
to
1b47fae
Compare
Ok ya'll! thanks for your patience! The PR has been updated quite a bit. Here are the changes:
|
d9622b8
to
2b4006b
Compare
ok I tacked on a temporary commit here now labeled |
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.
Really nice updates!! Thinks became so much cleaner once the indexes are stored in the same file as the sessions 🚀 🔥 🚀 !!
Unfortunately though, I realised an issue that exists that'll likely require some redesigning... Sorry to find this one out so late in the review cycle. I've explained the issue in my first comment of this review.
session_rpcserver.go
Outdated
return nil, err | ||
} | ||
|
||
if prevSess.State != session.StateRevoked && |
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.
Really like the last update 🔥!
Though as we send the request to register the session to the Autopilot server before we store the session, we need to also need to add a check before this, that checks the linkedSessionIndex
to see that no other session has linked a session using that id, so that that check fails before we send a request to the autopilot server.
I think we should keep this linkedSessionIndex
check on LiT even if we change how the Autopilot server checks if a session can be linked corresponding to my other comment :)! I think the linkedSessionIndex
way of checking it is really neat for LiT
and I don't think that should any cause any issues similar to the ones I've described in my other comment 🚀!
200790f
to
296c281
Compare
This commit does a few things: 1. Instead of deriving IDs using the first 4 bytes of the session's serialised local pub key, we instead use bytes [1:5] in order to skip the first byte which is either 0x02 or 0x03. This results in a greater entropy set. 2. We also add a new index from ID to key and we write to this index each time a new session is added. 3. We add a `ReserveNewSessionID` method to the session store which will grind through private keys until it finds one that does not clash with the current ID set. 4. A migration is added to back-fill the ID-to-key index. If any old sessions are found that _do_ have a colliding ID, they are sorted by created time and all but the newest session is revoked. Only an entry for the newest session will be added to the ID-to-key index.
Update the autopilot rpc protos to include the new fields that will allow the client to link autopilot sessions.
Update the autopilot server client to send the new session linking fields if they are provided. Currently, they are not yet provided.
Add the new `GroupID1` field to the `Session` struct and ensure that the new fields are properly serialised and deserialised. The `GroupID` is the ID of the first Session in a set of linked sessions.
cb54bb0
to
8284d97
Compare
8284d97
to
b87c625
Compare
Update the Autopilot service AddAutopilotSessionRequest message to include a new `group_id` field. Users may set this field to the ID of a sessino group in order to link the new session to the older ones. The Session message is also updated with new `group_id` field which will be populated by the group a session.
Marshal the new Session fields into the proto Session struct.
This commit adds two new indexes to the session store. One from session ID to group ID and one from groupID to a set of session IDs. This commit only adds the new logic and starts writing the the new indexes from the `StoreSession` method. The next commit will add a migration to back-fill the new indexes.
This commit adds a migration to the session store to back-fill the new session ID to group ID and group ID to session IDs indexes.
This commit adds new getters: `GetGroupID` and `GetSessionIDs` to the session store which can be used to query the newly added indexes to get the associated group ID for a session ID or the associated set of session IDs for a group ID.
Change all comments and variable names mentioning "session ID" to "group ID" instead. As of this commit, session linking is not yet possible and so what ever session IDs are passed in are also group IDs.
This method can be used to list actions in a session Group. Note that actions are still stored under session IDs.
This method can be used to check that each session in a group passes for a given predicate.
This commit adds logic to the CreateSession method that checks that a all the past sessions in a linked set are no longer active.
b87c625
to
3b5007c
Compare
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.
aACK, things around the session ID collision look good, very nice work 💯
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.
tACK 🚀🚀 strong work 💪!
With this PR, we add the ability for a client to link a new autopilot session with
a previous set of revoked ones. If this is done, then the same privacy mapper is used
for the linked sessions & the actions and rules db is also shared across sessions.
PR Flow:
2.. Add a new session ID to session local pub key index to the session store. This makes possible to fetch session by ID. A migration to backfill this index is also added.
autopilotserver.proto
to have the new fields required to link sessions.These include the session group key along with a sig to prove ownership of the linked
session.
initially we do not provide them.
GroupID
to theSession
store. The group ID is the ID of the very firstsession in the group of linked sessions.
litrpc
sSession
andAddAutopilotSessionRequest
messages to includea
linked group ID
.to session IDs.
one-to-one both ways. Only after this PR will the group-to-session index be one-to-many.
ListGroupActions
method to the firewall DB that allows us to query the DBfor all actions of a specific group.
TODO: