-
Notifications
You must be signed in to change notification settings - Fork 57
Conversation
I need to investigate something that's happening here: The example is not completing consistently, for some reason it looks like a user that is not supposed to be able to read a signed packet is retrieving, need to look into it to see where the bug is |
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 feedback, that focuses on 2 aspects that I think need to be discussed before continuing with the review:
- Root branch provided as input in
User::create_stream()
instead of having aBASE_BRANCH
constant Topic
being backed by aString
instead of a byte array
…hStore::remove_from_all()`
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.
Reviewed key_store.rs
. I've found an important bug in remove_from_all()
(and similar methods that use the fold
pattern). I've written a test that replicates the bug, give it a look!
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 main issues that needs resolving first are:
- Topic internal and the
Copy
inHDF
- The fold bug that may be responsible for intermittent false removal of subscribers
… v2.0/test-topics
…nto v2.0/test-topics
… v2.0/test-topics
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.
Fresh round of changes in response to the reviews. Still need to do the Option
/upserting for BranchStore
but most of the rest has been addressed.
spongos/src/ddml/types/bytes.rs
Outdated
self.0.resize(new_size, 0) | ||
// Return an error if size exceeds u32 max size to avoid panic | ||
// TODO: Remove anyhow error and replace with no_std compatible error handling | ||
pub(crate) fn resize(&mut self, new_size: usize) -> anyhow::Result<()> { |
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.
When recovering a user we end up unmasking the stream of wrapped topics/cursors, but if you use the wrong password (as we do in the examples) it mixes up the unmasked Size
value for number of topics, and the Size
within the topic Byte
unwrap gets messed up as well. This results in an attempt to create a Vec
with a size that exceeds its max allocation availability (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.reserve), resulting in a panic that we have no way to catch.
One thing that threw me off was I tried to use isize::MAX
and it still resulted in panics on occassion when the new size exceeded u32::MAX
, so I made that the default max length. From a Streams
perspective, we have no instance where Bytes
should exceed 32Kb let alone u32::MAX
so I thought that was an appropriate value to use.
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, here goes some more comments. I did not had time to finish reviewing user.rs
, but I'm confident the big chunk is done. There are some clone()
here and there that I think can be spared but didn't comment on it. We'll clean them up along the way.
The most important discussions I'm opening are:
- branch announcement as a separate message type
- keyloads linked to tip of branch, and joining the stream announcement spongos
// Prepare HDF and PCF | ||
let header = HDF::new(message_types::ANNOUNCEMENT, ANN_MESSAGE_NUM, self.identifier())?; | ||
let header = HDF::new( | ||
message_types::ANNOUNCEMENT, |
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.
(I have the feeling to had already raised this concern somewhere, but can't remember where nor if it got any answer, so I'm raising it again from scratch 😆 )
Are we sure we want to reuse the announcement message for both stream announcement and branch announcement? In my opinion that's not a very good idea, mainly for 2 reasons:
- the announcement message is a fundamentally different entity than the branch announcement, as proven by the fact that it includes the author's identifier, which is not necessary for the branch announcement. Instead, if we want to support a tree structure branching from other branches, branch announcements will need the topic they are branching from. Also haven't really thought about it, but are we sure it's ok that branch announcements are not linked to any message?
- the previous fact forces us to introduce the
is_base_branch
if-branching in the announcement-related methods. Now it seems harmless, but it will become uglier once we introduce admin permissions (admin subscribers can send branch announcements, but not stream announcements)
We can agree on an iterative approach as long as we are aligned on the design.
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.
I wouldn't be opposed to having branch announcement be its own thing, although I'd prefer to make that a focused PR of its own. This one is already undergoing a pretty significant number of changes/reviews as is
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.
more than fair.
lets/src/address.rs
Outdated
@@ -229,10 +231,11 @@ impl MsgId { | |||
Self(bytes) | |||
} | |||
|
|||
pub fn gen(appaddr: AppAddr, identifier: Identifier, seq_num: usize) -> MsgId { | |||
pub fn gen(appaddr: AppAddr, identifier: Identifier, topic: Topic, seq_num: usize) -> MsgId { |
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.
Topic does not need to be taken by value, and it is not Copy
now so it should be taken by ref
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 not do this for Identifier
as well despite the Copy
? It's an extra allocation without it being necessary.
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.
As long as something is Copy
, you can be certain it does not incur in a heap allocation (basically because that's a hard condition for types to be able to implement Copy
). Generally speaking, Copy
is a marker that says that "cloning" the type is essentially the same as moving the type (a memcpy
). For this reason, Copy
types can keep using the old variable, even after a move to another variable (aka the copy semantics). Types that don't implement Copy
have a more complex cloning (for example, because they handle resources, like the pointer to some heap allocated memory that tneeds to be freed when dropping the value), therefore move != clone anymore.
For the types that don't implement Copy
, it's important not to take ownership in function parameters if it's not needed, cause you are forcing a potentially costly clone unnecessarily. For Copy
types, this clone is as cheap as a move, and the extra cost of the move vs reference, even if arguable, I'd say is under the ream of "profile before assuming anything" and definitely negligible in our case. So in this case ergonomics prevail.
TL;DR: performance is not a factor in this decision. But still passing Identifier
by reference would be valid if you prefer it (for coherence, or any other reason)
Co-authored-by: Arnau Orriols <[email protected]>
…into v2.0/test-topics
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.
From my side, this can be merged. I'll create the issue to discuss and track the comments that have been postponed (keyload linking, branch announcement message type)
@kwek20 any further comments/change requests before we merge? |
Hmm only thing is maybe the name of cursor_store. SHouldnt it be branch_store now? Or maybe just state_store? (Im assuming you guys dont want to call it just store :D) |
Probalby reasonable to change the module name, but I don't think it matters all that much, the only purpose of |
Even if it's not part of the public API, we should view this naming decision from a new contributor perspective, and what name would be most intuitive for her when trying to make sense of the code structure. In my opinion, the only meaningful name is But I really don't think it's that important, you both have equally valid arguments, I'm fine with any decision as long as this beast gets merged! |
Description of change
Introduce
Topic
type and splitKeyStore
intoBranchStore
.Changes:
Topic
's inBranchStore
Topic
's will be sent inside theHDF
of messagesKeyload
messages tolink_to
addressnew_branch
function to allow users to announce (and retrieve) branches and store them beforeKeyload
messages are parsedType of change
How the change has been tested
link_to
from send functions