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

Enhance/cleanup unconfirmed execution #375

Merged
merged 9 commits into from
Feb 8, 2022

Conversation

oxade
Copy link
Contributor

@oxade oxade commented Feb 6, 2022

This PR converts this to work with the new refactoring.

Removed the ability to execute transactions without confirmation and instead all executions go through the same function execute_transaction
This allows us consolidate the critical areas where we might have to lock/unlock orders.
Additionally propagated the OrderInfoResponse for executions which was being discarded.
Updated test cases to use pending-orders
Also ported multi-insert and multi-remove over to Mysten infra, so no need to have them here.

How it works:

An order ord's objects can be locked or unlocked by the order if all of ord's input objects are already locked by ord or by no other order.

There are two phases to completing a transaction:
TX Order without confirmation: this locks the objects owned by ord if they are available for locking. However in case of an authority error the objects are unlocked.
If the order is successfully executed, the objects remain locked until confirmation.

Confirmation of TX order:
Here the objects are unlocked if tx is successful or if tx fails with errors having no side effects.
If the objects remain locked after this step, there is a critical error.

Next steps:

  1. Clarify which errors from authorities should or should not lead to unlocking orders
  2. Make pending_order table test & + test & unlock thread-safe

@oxade oxade requested a review from lxfind February 6, 2022 02:30
@oxade
Copy link
Contributor Author

oxade commented Feb 6, 2022

@lxfind please take a look to make sure this PR fits in the refactor flow.

// Which errors should be unlock on?
// TODO: define which errors we must not unlock from
// https://github.com/MystenLabs/fastnft/issues/346
if result.is_err() || with_confirmation {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I feel there are situations where an authority operation fails and we would rather keep the order locked.
How can we for sure determine which errors should unlock orders?

Copy link
Contributor

Choose a reason for hiding this comment

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

I have two questions about this:

  1. If we keep the order locked, when would we unlock them?
  2. Could you also write down a concrete scenario where things could go wrong if we always unlock here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. Up to the caller. They can re-submit and order. Or can call try_complete_pending
  2. Situations where the true state of the order is not defined. Example quorum logic failure, network/comms failure, set_order_lock failure here https://github.com/MystenLabs/fastnft/blob/main/fastpay_core/src/authority/authority_store.rs#L289

These are just guesses of course. I could be wrong.

@lxfind
Copy link
Contributor

lxfind commented Feb 7, 2022

Thanks for putting up the PR.
I did give this flag idea a thought, and I chose to not add this flag to merge the two code paths for the following reasons:

  1. We don't know if transfer_to_fastx_unsafe_unconfirmed is actually useful/needed.
  2. Even if (1) is necessary, so far, there is only one caller that's calling execute_transaction_without_confirmation_unsafe. I am not aware of any new callers being added.
    So we could say that execute_transaction_without_confirmation_unsafe is an edge case at best. Adding a flag like this makes the code a lot more complex. Such complexity is not worth it for an edge case (this PR vs 2 lines of code in the original impl).
    Of course, if we are convinced that this is not an edge case and we will be adding more callers to execute_transaction_without_confirmation_unsafe, I would totally agree that a unification of the code paths would be a good idea.

Let me what you think.

Also, @gdanezis Could you confirm how transfer_to_fastx_unsafe_unconfirmed would be used? And whether it would be a common need for the client to call into execute_transaction_without_confirmation_unsafe?

fastpay_core/src/authority_aggregator.rs Show resolved Hide resolved
fastpay_core/src/authority_aggregator.rs Show resolved Hide resolved
// Which errors should be unlock on?
// TODO: define which errors we must not unlock from
// https://github.com/MystenLabs/fastnft/issues/346
if result.is_err() || with_confirmation {
Copy link
Contributor

Choose a reason for hiding this comment

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

I have two questions about this:

  1. If we keep the order locked, when would we unlock them?
  2. Could you also write down a concrete scenario where things could go wrong if we always unlock here?

Comment on lines 498 to 500
if !self.can_lock_or_unlock(order)? {
return Err(FastPayError::ConcurrentTransactionError);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Duplicates?

&self.store.pending_orders,
order.input_objects().iter().map(|e| e.object_id()),
)
if !self.can_lock_or_unlock(order)? {
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious, what happens if we fail to unlock here due to can_lock_or_unlock returns Err? Could the objects be locked forever?

Copy link
Contributor

Choose a reason for hiding this comment

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

May want to add a TODO here. I think we need to handle the failure of can_lock_or_unlock eventually.

@oxade
Copy link
Contributor Author

oxade commented Feb 7, 2022

Thanks for putting up the PR. I did give this flag idea a thought, and I chose to not add this flag to merge the two code paths for the following reasons:

  1. We don't know if transfer_to_fastx_unsafe_unconfirmed is actually useful/needed.
  2. Even if (1) is necessary, so far, there is only one caller that's calling execute_transaction_without_confirmation_unsafe. I am not aware of any new callers being added.
    So we could say that execute_transaction_without_confirmation_unsafe is an edge case at best. Adding a flag like this makes the code a lot more complex. Such complexity is not worth it for an edge case (this PR vs 2 lines of code in the original impl).
    Of course, if we are convinced that this is not an edge case and we will be adding more callers to execute_transaction_without_confirmation_unsafe, I would totally agree that a unification of the code paths would be a good idea.

Let me what you think.

Also, @gdanezis Could you confirm how transfer_to_fastx_unsafe_unconfirmed would be used? And whether it would be a common need for the client to call into execute_transaction_without_confirmation_unsafe?

Right. I want to get rid of the unconfirmed path too for the reasons you mentioned, and more. But while we have it, I'm striving to reduce ways it can be misused.

fastpay_core/src/authority_aggregator.rs Outdated Show resolved Hide resolved
fastpay_core/src/client.rs Outdated Show resolved Hide resolved
&self.store.pending_orders,
order.input_objects().iter().map(|e| e.object_id()),
)
if !self.can_lock_or_unlock(order)? {
Copy link
Contributor

Choose a reason for hiding this comment

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

May want to add a TODO here. I think we need to handle the failure of can_lock_or_unlock eventually.

fastpay_core/src/client.rs Outdated Show resolved Hide resolved
Comment on lines +873 to +882
.iter()
.map(|vote| {
(
vote.signed_order.as_ref().unwrap().authority,
vote.signed_order.as_ref().unwrap().signature,
)
})
.collect::<Vec<_>>();

let certificate = CertifiedOrder { order, signatures };
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious why do we have to do this here instead of keeping the old logic (match returns the pairs)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The responses from the old code will always be empty because it's the output of the catch-up confirmation steps, which tx_order does not do anymore. It's a bit misleading.

Copy link
Contributor

@lxfind lxfind left a comment

Choose a reason for hiding this comment

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

Approving but some of the code will go away in latter PRs from @gdanezis (may want to take a look at his PR to make sure we are porting changes from this PR)

@oxade
Copy link
Contributor Author

oxade commented Feb 8, 2022

Approving but some of the code will go away in latter PRs from @gdanezis (may want to take a look at his PR to make sure we are porting changes from this PR)

Agreed. Many of the concepts here are based on logic that will go away soon, however I'm not sure of the timelines, so I'm hoping these incremental steps can keep us moving at least.

mwtian pushed a commit that referenced this pull request Sep 12, 2022
9f662f1f6d7711c6545519c8b85996d515d3f104 removed a proptest non-regression file that exercises #375. We reinstate it and un-ignore the test.
mwtian pushed a commit that referenced this pull request Sep 12, 2022
mwtian pushed a commit to mwtian/sui that referenced this pull request Sep 29, 2022
9f662f1f6d7711c6545519c8b85996d515d3f104 removed a proptest non-regression file that exercises MystenLabs#375. We reinstate it and un-ignore the test.
mwtian pushed a commit to mwtian/sui that referenced this pull request Sep 29, 2022
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.

None yet

2 participants