synapsecns / sanguine

Synapse Monorepo
MIT License
35 stars 25 forks source link

RFQ Potential Speed Ups #2743

Open trajan0x opened 2 weeks ago

trajan0x commented 2 weeks ago

Additional speed ups:

image

Commitable quotes calculated on db side (less data sent over the wire)

image

Paralellize HasSufficientGasOrigin and Dest

greptile-apps[bot] commented 2 weeks ago

To speed up the RFQ process, follow these steps:

  1. Parallelize HasSufficientGasOrigin and HasSufficientGasDest in gasMiddleware:

    func (r *Relayer) gasMiddleware(next func(ctx context.Context, span trace.Span, req reldb.QuoteRequest) error) func(ctx context.Context, span trace.Span, req reldb.QuoteRequest) error {
       return func(ctx context.Context, span trace.Span, req reldb.QuoteRequest) (err error) {
           var sufficientGasOrigin, sufficientGasDest bool
           g, gctx := errgroup.WithContext(ctx)
    
           g.Go(func() error {
               sufficientGasOrigin, err = r.inventory.HasSufficientGas(gctx, int(req.Transaction.OriginChainId), nil)
               return err
           })
    
           g.Go(func() error {
               var destGasValue *big.Int
               if req.Transaction.DestToken == chain.EthAddress && !isInFlight {
                   destGasValue = req.Transaction.DestAmount
                   span.SetAttributes(attribute.String("dest_gas_value", destGasValue.String()))
               }
               sufficientGasDest, err = r.inventory.HasSufficientGas(gctx, int(req.Transaction.DestChainId), destGasValue)
               return err
           })
    
           if err := g.Wait(); err != nil {
               return fmt.Errorf("could not check gas: %w", err)
           }
    
           if !sufficientGasOrigin || !sufficientGasDest {
               return nil
           }
    
           return next(ctx, span, req)
       }
    }
  2. Parallelize HasSufficientGas, IsProfitable, and ShouldProcess in handleSeen:

    func (q *QuoteRequestHandler) handleSeen(ctx context.Context, span trace.Span, request reldb.QuoteRequest) (err error) {
       g, gctx := errgroup.WithContext(ctx)
       var shouldProcess, isProfitable bool
    
       g.Go(func() error {
           shouldProcess, err = q.Quoter.ShouldProcess(gctx, request)
           return err
       })
    
       g.Go(func() error {
           isProfitable, err = q.Quoter.IsProfitable(gctx, request)
           return err
       })
    
       if err := g.Wait(); err != nil {
           return fmt.Errorf("could not determine if should process or is profitable: %w", err)
       }
    
       if !shouldProcess {
           err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.WillNotProcess)
           if err != nil {
               return fmt.Errorf("could not update request status: %w", err)
           }
           return nil
       }
    
       if !isProfitable {
           span.AddEvent("quote is not profitable")
           return nil
       }
    
       // existing code...
    }
  3. Calculate committable quotes on the database side:

    Modify the database query to calculate committable quotes directly in the database and return the results. This will reduce the amount of data sent over the wire and improve performance.

    // Example: Modify the query in reldb/service.go
    func (db *Service) GetCommittableBalances(ctx context.Context) (map[int]map[common.Address]*big.Int, error) {
       // Modify the query to calculate committable balances directly in the database
       query := `SELECT chain_id, token_address, SUM(balance) as committable_balance FROM balances WHERE status = 'committable' GROUP BY chain_id, token_address`
       // Execute the query and process the results
       // ...
    }
  4. Update tests in quoter_test.go to reflect these changes:

    func (s *QuoterSuite) TestParallelizedFunctions() {
       // Add tests for parallelized functions
       // ...
    }

References

/services/rfq/relayer/quoter/quoter.go /services/rfq/relayer/service/statushandler.go /services/rfq/relayer/service/handlers.go /services/rfq/relayer/quoter/quoter_test.go /services/rfq/relayer/reldb/base/model.go /services/rfq/api/docs/swagger.yaml /services/rfq/relayer/README.md

Ask Greptile