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

Remove auction_transaction #2283

Merged
merged 26 commits into from
Jan 26, 2024
Merged

Remove auction_transaction #2283

merged 26 commits into from
Jan 26, 2024

Conversation

sunce86
Copy link
Contributor

@sunce86 sunce86 commented Jan 15, 2024

Description

Part of #2282 & #2275

Exchanges tx_from/tx_nonce for auction_id which can be directly encoded from the settlement transaction since we shipped colocation. This allows us to remove an entire database table and a bunch of other complicated code.

I'm not yet removing the old columns in case something goes bad with this change.

Changes

  • Removed auction_transaction table.
  • Redesigned settlements table to contain auction id

How to test

  1. db tests and e2e tests cover the new functionality.
  2. Locally I've tested the db migration file like this:
  • First comment out the V_58 migration file and apply old schema.
  • Insert 10 settlements, of which first 5 have auction_transaction record (except one settlement (block_number 3), to simulate the existence of settlement from other environment staging/prod)
  • Then, manually apply migration script V_58
  • Observed the settlements table,auction_id were populated as expected.

@sunce86 sunce86 changed the title DRAFT: Remove auction_transaction Remove auction_transaction Jan 19, 2024
@sunce86 sunce86 marked this pull request as ready for review January 19, 2024 12:40
@sunce86 sunce86 requested a review from a team as a code owner January 19, 2024 12:40
Copy link
Contributor

@fleupold fleupold left a comment

Choose a reason for hiding this comment

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

I like the change of the table turning Option<from/nonce> to an Option<AuctionID>. In fact this could probably be its own PR.

However, I think we should explore populating the auction id field already in the event handler that inserts the original settlement (it should have access to all required information). This way we don't need to create the extra "auction_kind" column which I find quite confusing (as the db values don't match the values on the struct) and don't run into the issue of first requiring one event handler to run before the other one does.

I'm not sure what this means for transitioning, but we could for a while have both systems run in parallel (and assert that the upsert doesn't really change any values other than at the moment of the release when it may be catching up with old auctions).

Comment on lines 106 to 110

// Wait a bit more to not race with the event indexer.
// Otherwise we might miss event and have to wait for next block to retrigger
// loop.
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
Copy link
Contributor

Choose a reason for hiding this comment

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

Relying on a fixed time sleep here is super hacky. I think having one block delay wouldn't be so bad, but if it's a must I think we should combine the two event updater (which one is the other one?) and make sure they are processing events in the order we want them to.

Ok(None)
Some(score) => {
if score.winner.0 != tx_from.0 {
tracing::warn!(
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this and not being able to recover auction_id from calldata be error logs now (or even return an error)?

CREATE TYPE AuctionKind AS ENUM ('valid', 'invalid', 'unprocessed');

ALTER TABLE settlements
ADD COLUMN auction_kind AuctionKind NOT NULL DEFAULT 'unprocessed',
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we relying on this default anywhere? If not, can we drop it (I'd rather us use as little fancy SQL features as possible and set all values explicitly in code)

sqlx::PgConnection,
web3::types::Transaction,
};

#[derive(Debug, Copy, Clone)]
pub enum AuctionKind {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not a fan of this type. It has the same entropy as an Option<AuctionId> with the added complication that in the database it exists in three flavours (including unprocessed)

@sunce86
Copy link
Contributor Author

sunce86 commented Jan 22, 2024

However, I think we should explore populating the auction id field already in the event handler that inserts the original settlement (it should have access to all required information).

I did a detailed exploration of this before starting to work on this issue and it can't be done without extra web3 call to get the transaction and decode the auction_id. The best solution would be to add the auction_id to the settlement event data when the new version of GPv2Settlement contract is deployed.

@fleupold
Copy link
Contributor

I did a detailed exploration of this before starting to work on this issue and it can't be done without extra web3 call to get the transaction and decode the auction_id

We are doing this in OnSettlementEventUpdater updater anyways and event processing is already async so I don't think it changes much honestly. In fact we could probably call OnSettlementEventUpdater.update(tx_hash).await with minimal code changes from the existing event processing code today (although the dependency injection would be quite weird).

My suggested plan of action would be:

  1. Change nonce/from for auction ID but keep the current delay (this get rid of a lot of code and is a strict improvement)
  2. Create a new domain component that has the required dependencies (persistence, Ethereum) and implements EventStoring for all events that we care about. Event processing should be domain logic imo.
  3. Move the current "OnSettlementEventUpdater" logic in this component also
  4. Remove 64 block delay and instead invoke update logic when the settlement event is being processed.

Wdyt?

@sunce86
Copy link
Contributor Author

sunce86 commented Jan 23, 2024

You can do (1) but you still need to keep the auction_transaction table if you don't want to introduce auction_kind. I mean, you would still need a mechanism to know which settlement you want to process in OnSettlementEventUpdater.

Your plan sounds good but it's more involving and I don't we will make it for zero fee launch.

I personally see benefit in separating settlement event insertion from the rest of the code, since the rest of the code can take additional time, fail, require reindexing in case of bugs etc. But your plan would probably simplify handling events and competition data.

@fleupold
Copy link
Contributor

I removed the auction_kind enum and involved migration logic (meaning we still fetch 64 block old auctions without an auction id and amend their information). I plan to tackle those in another PR (first moving event handling into a domain component and then combining the two handlers).

Could I get a review please.

@fleupold fleupold requested a review from a team January 24, 2024 16:21
Copy link
Contributor Author

@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.

Once merged, I think the OnSettlementEventUpdater will try to process the first settlement without auction_id which will be some pre-colocation settlement for which the recovery of auction_id from calldata will fail and it will be stuck.

.await
}

pub async fn data_exists(ex: &mut PgConnection, auction_id: i64) -> Result<bool, sqlx::Error> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this now means already_processed instead of data_exists, I guess

@fleupold
Copy link
Contributor

fleupold commented Jan 24, 2024

Once merged, I think the OnSettlementEventUpdater will try to process the first settlement without auction_id which will be some pre-colocation settlement for which the recovery of auction_id from calldata will fail and it will

You are right! Pre-colocation production transactions would fail on staging and vice versa. Do you think hardcoding a min block (past colocation launch) would be an ok workaround for this?

Edit: this would require a different block per chain which is a bit annoying :-(

@sunce86
Copy link
Contributor Author

sunce86 commented Jan 24, 2024

this

I think that's ok and we can remove it at a later stage of refactoring.

@fleupold
Copy link
Contributor

Would there be an issue with populating a fake auction ID (e.g. -1) for items that are far in the past and cannot be matched?

@sunce86
Copy link
Contributor Author

sunce86 commented Jan 24, 2024

Would there be an issue with populating a fake auction ID (e.g. -1) for items that are far in the past and cannot be matched?

I think theoretically this could also happen when solvers start running their own driver (until we have a new smart contract version that enforces the existence of auction_id) so we definitely want to overcome this error and continue processing other settlements.

From the top of my head, I don't think -1 would cause something bad (would have to go through the codebase and double check all JOINs though)

Copy link
Contributor Author

@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.

Approving with comment (since I cant approve my own PR 😄 )

The only thing I noticed is that we changed the way we handle InvalidSelector error on decoding the transaction, but I think this can't happen after colocation (it could happen before colocation because we saved auction_transaction entry during competition time).

@fleupold fleupold merged commit 0213ec8 into main Jan 26, 2024
7 of 8 checks passed
@fleupold fleupold deleted the auction-transaction branch January 26, 2024 09:33
@github-actions github-actions bot locked and limited conversation to collaborators Jan 26, 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.

2 participants