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

Merge solutions not settlements #2471

Merged
merged 11 commits into from
Mar 27, 2024
Merged

Merge solutions not settlements #2471

merged 11 commits into from
Mar 27, 2024

Conversation

fleupold
Copy link
Contributor

@fleupold fleupold commented Mar 5, 2024

Description

Currently merging multiple solutions into a larger one happens in the Settlement type and reuses the legacy settlement encoder. As part of our initiative to fully transition away from the legacy code base this PR moves solution merging logic into our solution domain model.

This means we will now merge solutions before simulating and encoding them. This can potentially lead to a lot more solution candidates being generated and requiring simulation. I don't expect this to be an issue in practice as encoding is already part of a stream which will yield the best solution candidate found so far as soon as we approach the solving deadline (thought may have to go into in which order solution candidate should be attempted to be simulated).

Changes

  • Implement merge method on Solution
  • Change the Id type on Solution to be able to represent when a solution was generated from multiple sub-solutions.
  • Replace settlement.merge with solution.merge (this means merging now happens before first simulation)
  • Change the way merge candidates are generated
  • Sort stream of to encode settlements by "simples" ie least merged solution (might want to use score instead once Rank by surplus driver V3 #2448 is merged)

Depending on how risky we think this change is, we can also keep the existing merging logic and have a feature flag guard the two codepaths.

How to test

Existing unit test

Related Issues

Fixes #1478

@fleupold fleupold requested a review from a team as a code owner March 5, 2024 12:55
@fleupold fleupold mentioned this pull request Mar 5, 2024
2 tasks
crates/driver/src/domain/competition/mod.rs Outdated Show resolved Hide resolved
merged.extend(extension);
}
// Sort by "simplest", ie least merged solution.
// Maybe we should sort by score instead?
Copy link
Contributor

Choose a reason for hiding this comment

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

@harisang brought up at some point that we have no way of knowing the score of a merged solution so using that for determining a sort order is probably not wise.
Prioritizing solutions that are the closest to what the solver originally intended seems like the most reasonable choice here.
But since we now have reth nodes we might not have to sweat it anyway. ;)

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 reason we only knew the score for settlements (not solutions) was that they required simulation to get the gas costs. Thanks to CiP38 (rank by surplus) this goes away and so we can now actually compute the score from the solution (cf. #2448).

So I think we could still debate if we want to start with the highest scored solution (even if it's more risky to fail because it'll likely consist of many merged settlements.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, right. With CIP 38 things change. Then I'd say let's be greedy (highest score first). That way we could stop at the first solution that doesn't revert.

crates/driver/src/domain/competition/solution/mod.rs Outdated Show resolved Hide resolved
crates/driver/src/domain/competition/solution/mod.rs Outdated Show resolved Hide resolved
crates/driver/src/domain/competition/solution/mod.rs Outdated Show resolved Hide resolved
// Solution prices need to congruent, i.e. there needs to be a unique factor to
// scale all common tokens from one solution into the other.
let scaling_factors = scaling_factors(&self.prices, &other.prices);
let factor = match scaling_factors.len() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic seems pretty awkward. I think calling the function common_scaling_factor() -> Result<BigRational> or sth like that and moving that check into the function would be easier to understand.

I would also move if factor < 1 there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wasn't able to get the if factor < 1 logic abstracted but I think this is much simpler to read now.

Comment on lines 205 to 250
if *entry.get() != scaled {
return Err(MergeError::IncongruentPrices);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Since the single common scaling factor is already chosen to satisfy this condition I assume this is supposed to detect rounding errors when converting back to U256?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I just don't want to override values that don't match and be on the safe side, but you are right this shouldn't really happen.

crates/driver/src/domain/competition/solution/mod.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@MartinquaXD MartinquaXD left a comment

Choose a reason for hiding this comment

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

Looks alright to me.

Copy link
Contributor

@sunce86 sunce86 left a comment

Choose a reason for hiding this comment

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

Since this is now possible, and since some solvers raised the question of skipping merging, and since we discussed it before, have you considered completely moving the merging to solvers?

}
// Sort by "simplest", ie least merged solution.
// Maybe we should sort by score instead?
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should capture issue to change sorting (by score) once the CIP38 is live.

@sunce86 sunce86 mentioned this pull request Mar 8, 2024
Copy link

This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed.

@github-actions github-actions bot added the stale label Mar 15, 2024
@fleupold
Copy link
Contributor Author

still planning to merge this (next week hopefully)

@github-actions github-actions bot removed the stale label Mar 16, 2024
Copy link

This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed.

@github-actions github-actions bot added the stale label Mar 25, 2024
@fleupold fleupold enabled auto-merge (squash) March 27, 2024 17:03
@fleupold fleupold merged commit 9e1eb58 into main Mar 27, 2024
9 checks passed
@fleupold fleupold deleted the merge_solutions branch March 27, 2024 17:17
@github-actions github-actions bot locked and limited conversation to collaborators Mar 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Don't rely on legacy code for solution merging in driver
4 participants