-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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
[fastx adapter] making move execution work end-to-end #88
Conversation
2e70390
to
68f99f8
Compare
24b17d1
to
0b46af2
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.
This looks pretty darn amazing to me, but I'm a bit of a Move noob, so I'll just comment.
This introduces 8 new TODOs not covered by a subsequent PR: should we introduce an umbrella issue to track them? "Leftovers in adapter logic", perhaps?
for (mut obj, new_contents) in mutable_refs { | ||
match &mut obj.data { | ||
Data::Move(m) => m.contents = new_contents, | ||
_ => unreachable!(), |
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.
Is this unreachable or is this an API invariant violation? Should a panic here involve a message?
Also, consider using pre
, perhaps.
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.
- It is unreachable--we checked earlier than
mutable_refs
only had Move objects. Will change topanic
with an appropriate message. pre
looks very interesting/useful. But I am trying to weigh the risk/reward of adding this as a dep in a system that's currently pretty dependency-minimal--thoughts on that?
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.
pre
is:
- pretty darn safe, because it's itself small, it disappears at release and is dependency-minimal,
- really useful when you're committed to using a specific set of preconditions that should be enforced by callers, rather than a one-off.
So it may be just early (in this PR), if you do have a battery invariants in mind, or pre may not be for you if you don't.
} | ||
// any object left in `by_value_objects` is an input passed by value that was not transferred or frozen. | ||
// this means that either the object was (1) deleted from the FastX system altogether, or | ||
// (2) wrapped inside another object that is in the FastX object pool |
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.
Remind me: what's the logic for deleting wrapped objects in this case?
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.
A wrapped object was either:
- Passed in via
by_value_objects
and not subsequently transferred - Created by the transaction and subsequently transferred or deleted
- In case (1), the wrapped object will be present in
by_value_objects
and thus deleted from the object pool here. - In case (2), the wrapped object was never in the object pool, so there's no need to delete it.
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.
Got it, thanks!
} | ||
} | ||
debug_assert!( | ||
by_value_objects.len() + mutable_ref_objects.len() + num_immutable_objects == num_objects |
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.
👍
@@ -0,0 +1,30 @@ | |||
/// Test CTURD object basics (create, transfer, update, read, delete) |
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 : consider a different acronym)
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.
Lol, this was the most memorable one I could think of
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.
CRUD is a well-known acronym in databases, so that CRUDT, TCRUD would ring a bell.
@@ -118,6 +142,11 @@ impl TransactionDigest { | |||
SequenceNumber::new(), | |||
) | |||
} | |||
|
|||
// for testing |
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: #[cfg(test)]
?
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.
Would do this, but then it can't be used outside of the base_types
crate (unless there is a way to allow this?)
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.
True, the only way to allow this is with a feature, which dependent crates would have to activate when appropriate. Sigh.
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.
Probably makes sense for us to do this eventually because we have several functions that look like this... but in a future PR
Good call + will do! |
2a2e158
to
84b86b0
Compare
Using the new VM API in diem/diem@346301f to make the Move-powered execution work as intended. At a high level: - The adapter takes some FastX objects, some pure values (e.g., addresses), and a Move function to call as input as input - It takes extracts a Move value from each object and type-checks the objects against the function signature - It invokes the function on the Move values and pure values - It processes the effects produced from executing the function to update the input objects, as well as updating the store with freshly created and deleted objects. This is intricate logic that will need much more testing in time. But wanted to get this functionality out as early as possible to unblock the client workstream, which will need to send `MoveCall` orders and observe their effects.
84b86b0
to
1d83bd5
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.
One Q: where (would|does)a the sequence number management that happens during the creation of an object from an unwrap live?
old_object.next_sequence_number = sequence_number; | ||
old_object | ||
} else { | ||
Object::new_move(move_obj, recipient, SequenceNumber::new()) |
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.
One Q: where (would|does)a the sequence number management that happens during the creation of an object from an unwrap live?
@huitseeker : this is it--same code path as object creation.
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.
Worth noting that this is (as @gdanezis pointed out in the preso this morning) completely unsafe if sequence numbers are used for replay prevention (as they are today ...).
But it is fine in the (future, proposed world) where keys in the order_lock
map are (ObjectId
, TxDigest
) (or a commitment to this pair).
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.
#98 for much more detail on this.
I'm going to go ahead and land this because there are a few outstanding PR's that are tough to review by virtue of being based on it. Happy to address any/all other comments async! |
Using the new VM API in diem/diem@346301f to make the Move-powered execution work as intended. At a high level:
This is intricate logic that will need much more testing in time. But wanted to get this functionality out as early as possible to unblock the client workstream, which will need to send
MoveCall
orders and observe their effects.