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

Test builder transaction submission via public mempool #2011

Merged
merged 12 commits into from
Oct 14, 2024

Conversation

shenkeyao
Copy link
Member

@shenkeyao shenkeyao commented Sep 13, 2024

Closes #1968. Closes #1969.

This PR:

  • Add tests for transaction submissions via public mempool with reserve and fallback builders.
  • Combine and refactor tests for public and private mempools.

This PR does not:

  • Test complicated scenarios, which will be added later.

Key places to review:

  • Whether the retries make sense.
  • Whether sleep is needed put in the right places.
  • Whether the submission and bundle fetching are properly done.

How to test this PR:

  • Run the four test_marketplace_{reserve/fallback}_builder_with_{public/private}_mempool tests.

Copy link
Contributor

@QuentinI QuentinI left a comment

Choose a reason for hiding this comment

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

LGTM with minor comments

marketplace-builder/src/builder.rs Outdated Show resolved Hide resolved
marketplace-builder/src/builder.rs Outdated Show resolved Hide resolved
Comment on lines 520 to 531
if let Ok(bundle) = builder_client
.get::<Bundle<SeqTypes>>(
format!(
"bundle_info/bundle/{parent_view_number}/{parent_commitment}/{}",
parent_view_number + 1
)
.as_str(),
)
.send()
.await
{
return Some(bundle);
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure whether it's correct to return Some without checking if bundle.transactions is empty. The public mempool tests now fail pretty consistently after I changed it to this way.

Copy link
Member

Choose a reason for hiding this comment

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

I think one potential cause of this comes from assumping that the next event we get from the Network is a proposal. I think we should be waiting for a Transaction event before we wait for this Quorum Proposal in order to see the transactions.

We might not actually want to wait for the Quorum Proposal either in these cases. As receiving the Transaction event will cause any requests for subsequent Quorum Proposals to return the transaction list until they are included.

Copy link
Member Author

Choose a reason for hiding this comment

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

Looks like we can't use a Transaction event directly here, because we need the parent commitment to fetch the bundle. But I agree we shouldn't wait for the QuorumProposal. I'll think about what might be a good alternative.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, maybe I misunderstood your point. Do you mean we just do transaction comparison so there's no need to fetch the bundle?

Copy link
Member

@Ayiga Ayiga Oct 1, 2024

Choose a reason for hiding this comment

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

Oh... No I don't think that works, because then we wouldn't be testing the Builder.

My point was to point out that we cannot guarantee that the next proposal would be after the Transactions were submitted to consensus. So we'd really need to use the proposal that preceeds the Transactions message. Since the Transactions message is essentially informing the Builder that these transactions need to be included, we can consider them as not being a part of the public mempool until that message is seen.

But even then, this isn't a guarantee that the Builder will have received this message yet. I think if we don't wait for the Transactions message, then the Bundles that the Builder will hand out will be empty Bundles which will not contain the vec of transactions anyway.

We don't have this issue with the private mempool, as the transactions are being handed directly to the Builder rather than coming in through the Events Service.

Copy link
Member

Choose a reason for hiding this comment

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

I should add that I tried adding this yesterday, but it didn't seem to result in a pass... instead I received errors about not being able to receive a bundle.

Copy link
Member Author

Choose a reason for hiding this comment

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

As discussed I moved the quorum proposal handling earlier, so it corresponds to the parent view now, and the tests pass!

}

#[async_std::test]
async fn test_marketplace_fallback_builder() {
async fn test_marketplace_fallback_builder(public_mempool: bool) {
Copy link
Member

Choose a reason for hiding this comment

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

I think it would be better to rewrite this test to replace the bool in this test with an enum that can add clarity to each of these cases. Since both forks end with an Event stream in either case, it would also be a natural place for the conditional to exist instead of within the body of this function.

Copy link
Member Author

Choose a reason for hiding this comment

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

Since both forks end with an Event stream in either case, it would also be a natural place for the conditional to exist instead of within the body of this function.

Could you clarify this? Besides replacing the bool with an enum, are you suggesting some other change?

Copy link
Member

@Ayiga Ayiga Oct 1, 2024

Choose a reason for hiding this comment

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

I suppose this is more of a nit, and it's likely a personal preference thing. I don't really care for passing a raw bool into a function / method call, as it doesn't convey any context of what it signifies in isolation. It's only with the function signature, which would require manual inspection, that you would get the relevant context.

With the enum you could convey part of the context at the call site.

test_marketplace_fallback_builder(true);

versus

test_marketplace_fallback_builder(Mempool::Public)

The other piece relates to the conditional inspection of the replaced variable within the test_marketplace_fallback_builder itself. With the enum, you could replace the conditional of:

if public_mempool {
  ...
} else {
  ...
}

With a method call, so that this conditional is not required / evaluated within the body of the test itself. It helps the branch logic look cleaner in the test, as we end up just focusing on the result that we are inspecting rather than worrying about what action to perform based on a conditional branch.

mempool_behavior.submit_transactions(txs).await;
let bundle = mempool_behavior.get_next_bundle().await;

Copy link
Member Author

Choose a reason for hiding this comment

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

All make sense! I replaced bool with enum and reorganized functions. There are some parts that can't be combined or extracted easily, e.g., due to the public and private mempools using different event streams, but I added some helper functions to simplify things.

@shenkeyao
Copy link
Member Author

shenkeyao commented Oct 1, 2024

The latest commit is just to sync with main.

Tests have been fixed.

@shenkeyao shenkeyao marked this pull request as ready for review October 3, 2024 21:06
@shenkeyao shenkeyao merged commit a57b811 into main Oct 14, 2024
15 checks passed
@shenkeyao shenkeyao deleted the keyao/test-public-mempool branch October 14, 2024 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants