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

RFQ Relayer: concurrent request processing #2739

Merged
merged 73 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
6afae8a
Feat: set max open conns to 50 for relayer mysql
dwasse Jun 12, 2024
817e66c
Feat: process each quote request in parallel
dwasse Jun 12, 2024
2dd5aa6
Feat: add GetDBStats to store and processDB span
dwasse Jun 12, 2024
a500f11
Feat: add backoffs to relayer contract calls
dwasse Jun 12, 2024
2a41ada
[goreleaser]
dwasse Jun 12, 2024
4d38041
Cleanup: lint
dwasse Jun 12, 2024
2c5c82b
[goreleaser]
dwasse Jun 12, 2024
d0a1f0c
Feat: do screener calls in parallel
dwasse Jun 12, 2024
f78f465
[goreleaser]
dwasse Jun 12, 2024
0ea9e94
Feat: add immediate handler forwarding
dwasse Jun 12, 2024
16599cc
[goreleaser]
dwasse Jun 12, 2024
c02428c
Cleanup: tracing
dwasse Jun 12, 2024
d48e53a
[goreleaser]
dwasse Jun 12, 2024
a94fc80
Fix: set should_relay=true if relayer addresses match
dwasse Jun 12, 2024
6e054f3
[goreleaser]
dwasse Jun 12, 2024
9c86df8
Fix: test
dwasse Jun 12, 2024
49b0eca
[goreleaser]
dwasse Jun 12, 2024
a93fd2a
Fix: new goroutine for every reqeuest
dwasse Jun 12, 2024
b7d7841
[goreleaser]
dwasse Jun 12, 2024
5635d61
Fix: immediately call Handle() vs underlying handler
dwasse Jun 13, 2024
381e0db
Feat: add semaphore to limit max requests handled at once
dwasse Jun 13, 2024
5ccebc9
Feat: add relayMtx and mutexMiddleware
dwasse Jun 13, 2024
f540d29
Feat: process pre-relay and post-relay requests separately
dwasse Jun 13, 2024
aacbb3a
[goreleaser]
dwasse Jun 13, 2024
6bee34f
Cleanup: coalesce processDB funcs, run two dbSelectors
dwasse Jun 13, 2024
8f7b96e
Feat: use Lock() instead of TryLock()
dwasse Jun 13, 2024
3bf969e
[goreleaser]
dwasse Jun 13, 2024
530f916
Feat: check shouldProcess() and isProfitable() in parallel
dwasse Jun 13, 2024
7b6b613
[goreleaser]
dwasse Jun 13, 2024
35dae54
Feat: run post-relay requests in serial
dwasse Jun 13, 2024
36f2a9f
[goreleaser]
dwasse Jun 13, 2024
85f7d07
Merge branch 'master' into feat/rfq-speedup
dwasse Jun 13, 2024
73423ac
[goreleaser]
dwasse Jun 13, 2024
5664008
Feat: double wrap db selectors
dwasse Jun 13, 2024
df2f822
Feat: get rid of MaxOpenConns
dwasse Jun 13, 2024
0547917
[goreleaser]
dwasse Jun 13, 2024
912c56f
Feat: bump max concurrent requests
dwasse Jun 13, 2024
0e7114b
Feat: don't use semaphore in serial
dwasse Jun 13, 2024
f9c4613
[goreleaser]
dwasse Jun 13, 2024
bf4e297
Feat: use TryLock() instead of Lock() on sem and mtx
dwasse Jun 13, 2024
3996a65
Fix: don't bubble up errors from forwarding
dwasse Jun 13, 2024
39f9701
[goreleaser]
dwasse Jun 13, 2024
bef4a23
Revert "Feat: check shouldProcess() and isProfitable() in parallel"
dwasse Jun 13, 2024
bcec14f
[goreleaser]
dwasse Jun 13, 2024
60040da
fix middleware [goreleaser]
trajan0x Jun 19, 2024
52cf495
Feat: add tracing
dwasse Jun 17, 2024
58b30ac
[goreleaser]
dwasse Jun 19, 2024
df28e70
lint
trajan0x Jun 19, 2024
852de63
Merge branch 'fix/rfq-head' of https://github.com/synapsecns/sanguine…
trajan0x Jun 19, 2024
b61cc2a
[goreleaser] lock
trajan0x Jun 19, 2024
e59b3d3
[goreleaser] fix races
trajan0x Jun 19, 2024
5fbdfaf
Update services/rfq/relayer/service/handlers.go
trajan0x Jun 19, 2024
e161a8d
Revert "Update services/rfq/relayer/service/handlers.go"
trajan0x Jun 19, 2024
a6a1831
clean up control flow [goreleaser]
trajan0x Jun 19, 2024
5d38963
Fix: handle RelayStarted to get unstuck from DeadlineExceeded edge case
dwasse Jun 17, 2024
6e82d8f
Fix: ctx shadowing
dwasse Jun 19, 2024
aa411ea
[goreleaser]
dwasse Jun 19, 2024
316b9f8
Fix: add deadlineMiddleware to RelayStarted handler
dwasse Jun 19, 2024
85bef07
[goreleaser]
dwasse Jun 19, 2024
e8bd911
Cleanup: lints
dwasse Jun 19, 2024
19921c4
Feat: use waitgroup over errgroup for request processing
dwasse Jun 20, 2024
51aab1c
Fix: store RelayStarted after successful submission
dwasse Jun 20, 2024
97ada76
Feat: add RelayNonce and writer
dwasse Jun 20, 2024
a686322
[goreleaser]
dwasse Jun 20, 2024
13f7897
fix version [goreleaser]
trajan0x Jun 20, 2024
e1c2bc2
Merge branch 'fix/rfq-head' of https://github.com/synapsecns/sanguine…
trajan0x Jun 20, 2024
0363c1c
[goreleaser]
trajan0x Jun 20, 2024
3850c29
cpu bump
trajan0x Jun 20, 2024
857375b
cleanup
trajan0x Jun 20, 2024
9b5bbf8
semconv bug fix [goreleaser]
trajan0x Jun 20, 2024
d20b5f4
[goreleaser] cache fix]
trajan0x Jun 20, 2024
cd33535
bump version to v6 to fix actions/setup-java#543 style issue
trajan0x Jun 20, 2024
7c2e331
cache fix [ci skip]
trajan0x Jun 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion services/rfq/api/rest/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ func (r *QuoterAPIServer) PutRelayAck(c *gin.Context) {
// Otherwise, insert the current relayer's address into the cache.
r.ackMux.Lock()
ack := r.relayAckCache.Get(ackReq.TxID)
shouldRelay := ack == nil
shouldRelay := ack == nil || common.HexToAddress(relayerAddr).Hex() == common.HexToAddress(ack.Value()).Hex()
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor the condition for shouldRelay to improve readability and maintainability.

- shouldRelay := ack == nil || common.HexToAddress(relayerAddr).Hex() == common.HexToAddress(ack.Value()).Hex()
+ isAckNil := ack == nil
+ isAddressMatch := common.HexToAddress(relayerAddr).Hex() == common.HexToAddress(ack.Value()).Hex()
+ shouldRelay := isAckNil || isAddressMatch

This separates the condition into clearer, more manageable parts, making the code easier to understand and maintain.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
shouldRelay := ack == nil || common.HexToAddress(relayerAddr).Hex() == common.HexToAddress(ack.Value()).Hex()
isAckNil := ack == nil
isAddressMatch := common.HexToAddress(relayerAddr).Hex() == common.HexToAddress(ack.Value()).Hex()
shouldRelay := isAckNil || isAddressMatch

if shouldRelay {
r.relayAckCache.Set(ackReq.TxID, relayerAddr, ttlcache.DefaultTTL)
} else {
Expand Down
4 changes: 2 additions & 2 deletions services/rfq/api/rest/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,12 @@ func (c *ServerSuite) TestPutAck() {
c.Require().NoError(err)
c.Equal(http.StatusOK, resp.StatusCode)

// Expect ack with shouldRelay=false
// Expect ack with shouldRelay=true
err = json.NewDecoder(resp.Body).Decode(&result)
c.Require().NoError(err)
expectedResult = relapi.PutRelayAckResponse{
TxID: testTxID,
ShouldRelay: false,
ShouldRelay: true,
RelayerAddress: c.testWallet.Address().Hex(),
}
c.Equal(expectedResult, result)
Expand Down
41 changes: 27 additions & 14 deletions services/rfq/relayer/quoter/quoter.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"github.com/synapsecns/sanguine/services/rfq/relayer/relconfig"
"github.com/synapsecns/sanguine/services/rfq/relayer/reldb"
"golang.org/x/exp/slices"
"golang.org/x/sync/errgroup"

"github.com/ethereum/go-ethereum/common"
"github.com/synapsecns/sanguine/ethergo/signer/signer"
Expand Down Expand Up @@ -149,23 +150,35 @@
}

if m.screener != nil {
blocked, err := m.screener.ScreenAddress(ctx, screenerRuleset, quote.Transaction.OriginSender.String())
if err != nil {
span.RecordError(fmt.Errorf("error screening address: %w", err))
return false, fmt.Errorf("error screening address: %w", err)
}
if blocked {
span.AddEvent(fmt.Sprintf("address %s blocked", quote.Transaction.OriginSender))
return false, nil
}
// screen sender and recipient in parallel

Check warning on line 153 in services/rfq/relayer/quoter/quoter.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/quoter/quoter.go#L153

Added line #L153 was not covered by tests
g, gctx := errgroup.WithContext(ctx)
var senderBlocked, recipientBlocked bool
g.Go(func() error {

Check warning on line 156 in services/rfq/relayer/quoter/quoter.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/quoter/quoter.go#L155-L156

Added lines #L155 - L156 were not covered by tests
senderBlocked, err = m.screener.ScreenAddress(gctx, screenerRuleset, quote.Transaction.OriginSender.String())
if err != nil {
span.RecordError(fmt.Errorf("error screening address: %w", err))
return fmt.Errorf("error screening address: %w", err)
}
return nil

Check warning on line 162 in services/rfq/relayer/quoter/quoter.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/quoter/quoter.go#L158-L162

Added lines #L158 - L162 were not covered by tests
})
g.Go(func() error {

Check warning on line 164 in services/rfq/relayer/quoter/quoter.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/quoter/quoter.go#L164

Added line #L164 was not covered by tests
recipientBlocked, err = m.screener.ScreenAddress(gctx, screenerRuleset, quote.Transaction.DestRecipient.String())
if err != nil {
span.RecordError(fmt.Errorf("error screening address: %w", err))
return fmt.Errorf("error screening address: %w", err)
}
return nil

Check warning on line 170 in services/rfq/relayer/quoter/quoter.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/quoter/quoter.go#L166-L170

Added lines #L166 - L170 were not covered by tests
})

blocked, err = m.screener.ScreenAddress(ctx, screenerRuleset, quote.Transaction.DestRecipient.String())
err = g.Wait()

Check warning on line 173 in services/rfq/relayer/quoter/quoter.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/quoter/quoter.go#L173

Added line #L173 was not covered by tests
if err != nil {
span.RecordError(fmt.Errorf("error screening address: %w", err))
return false, fmt.Errorf("error screening address: %w", err)
return false, fmt.Errorf("error screening addresses: %w", err)

Check warning on line 175 in services/rfq/relayer/quoter/quoter.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/quoter/quoter.go#L175

Added line #L175 was not covered by tests
}
if blocked {
span.AddEvent(fmt.Sprintf("address %s blocked", quote.Transaction.DestRecipient))
if senderBlocked || recipientBlocked {
span.SetAttributes(
attribute.Bool("sender_blocked", senderBlocked),
attribute.Bool("recipient_blocked", recipientBlocked),
)

Check warning on line 181 in services/rfq/relayer/quoter/quoter.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/quoter/quoter.go#L177-L181

Added lines #L177 - L181 were not covered by tests
return false, nil
}
}
Expand Down
12 changes: 12 additions & 0 deletions services/rfq/relayer/reldb/base/rebalance.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"errors"
"fmt"

"database/sql"

"github.com/synapsecns/sanguine/services/rfq/relayer/reldb"
"gorm.io/gorm"
)
Expand Down Expand Up @@ -125,3 +127,13 @@

return rebalance, nil
}

// GetDBStats gets the database stats.
func (s Store) GetDBStats(ctx context.Context) (*sql.DBStats, error) {
sqlDB, err := s.DB().WithContext(ctx).DB()
if err != nil {
return nil, fmt.Errorf("could not get db: %w", err)
}
stats := sqlDB.Stats()
return &stats, nil

Check warning on line 138 in services/rfq/relayer/reldb/base/rebalance.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/reldb/base/rebalance.go#L132-L138

Added lines #L132 - L138 were not covered by tests
Comment on lines +132 to +138
Copy link
Contributor

Choose a reason for hiding this comment

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

Add unit tests for the new GetDBStats method to ensure it behaves as expected.

Tools
GitHub Check: codecov/patch

[warning] 132-138: services/rfq/relayer/reldb/base/rebalance.go#L132-L138
Added lines #L132 - L138 were not covered by tests

}
3 changes: 3 additions & 0 deletions services/rfq/relayer/reldb/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package reldb

import (
"context"
"database/sql"
"database/sql/driver"
"errors"
"fmt"
Expand Down Expand Up @@ -43,6 +44,8 @@ type Reader interface {
GetPendingRebalances(ctx context.Context, chainIDs ...uint64) ([]*Rebalance, error)
// GetRebalance gets a rebalance by ID. Should return ErrNoRebalanceForID if not found.
GetRebalanceByID(ctx context.Context, rebalanceID string) (*Rebalance, error)
// GetDBStats gets the database stats.
GetDBStats(ctx context.Context) (*sql.DBStats, error)
Comment on lines +49 to +50
Copy link
Contributor

Choose a reason for hiding this comment

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

Tip

Codebase Verification

Ensure the Store struct in the mysql and sqlite packages implement the GetDBStats method to adhere to the Reader interface contract.

  • services/rfq/relayer/reldb/mysql
  • services/rfq/relayer/reldb/sqlite
Analysis chain

Ensure the GetDBStats method is implemented consistently across all concrete Reader types to adhere to the interface contract.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify all implementations of `GetDBStats` in `Reader` types.

# Test: Search for the method implementation in all `Reader` types. Expect: Consistent implementation.
rg --type go $'GetDBStats' ./services/rfq/relayer/reldb/

Length of output: 424



Script:

#!/bin/bash
# Description: Identify all concrete types implementing the `Reader` interface.

# Test: Search for all types implementing the `Reader` interface. Expect: Comprehensive list of implementations.
ast-grep --lang go --pattern $'type $_ struct {
  $$$
}
func ($_ $_) GetDBStats($_) ($_ $_, $_) {
  $$$
}' ./services/rfq/relayer/reldb/

Length of output: 634



Script:

#!/bin/bash
# Description: Identify all concrete types implementing the `Reader` interface.

# Test: Search for all types implementing the `Reader` interface. Expect: Comprehensive list of implementations.
ast-grep --lang go --pattern $'type $_ struct {
  $$$
}
func ($_ $_) GetDBStats($_) ($_ $_, $_) {
  $$$
}' ./services/rfq/relayer/reldb/

Length of output: 634



Script:

#!/bin/bash
# Description: Identify all concrete types implementing the `Reader` interface by searching for struct types.

# Test: Search for all struct types in the directory. Expect: Comprehensive list of struct types.
ast-grep --lang go --pattern 'type $_ struct {
  $$$
}' ./services/rfq/relayer/reldb/

Length of output: 7754


Script:

#!/bin/bash
# Description: Identify all concrete types implementing the `Reader` interface by searching for method implementations.

# Test: Search for all method implementations of `GetDBStats`. Expect: Comprehensive list of method implementations.
ast-grep --lang go --pattern 'func ($_ $_) GetDBStats($_) ($_ $_, $_) {
  $$$
}' ./services/rfq/relayer/reldb/

Length of output: 112



Script:

#!/bin/bash
# Description: Check if `Store` struct in `mysql` and `sqlite` packages implement `GetDBStats`.

# Test: Search for `GetDBStats` implementation in `mysql` and `sqlite`. Expect: Implementation found.
rg --type go 'GetDBStats' ./services/rfq/relayer/reldb/mysql ./services/rfq/relayer/reldb/sqlite

Length of output: 96

}

// Service is the interface for the database service.
Expand Down
3 changes: 2 additions & 1 deletion services/rfq/relayer/reldb/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ package mysql
import (
"context"
"fmt"
"time"

"github.com/ipfs/go-log"
"github.com/synapsecns/sanguine/core/dbcommon"
"github.com/synapsecns/sanguine/core/metrics"
"github.com/synapsecns/sanguine/services/rfq/relayer/reldb/base"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/schema"
"time"
)

var logger = log.Logger("mysql-logger")
Expand Down
120 changes: 103 additions & 17 deletions services/rfq/relayer/service/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
"errors"
"fmt"
"strings"
"time"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/synapsecns/sanguine/core/metrics"
"github.com/synapsecns/sanguine/core/retry"
"github.com/synapsecns/sanguine/services/rfq/api/model"
"github.com/synapsecns/sanguine/services/rfq/contracts/fastbridge"
"github.com/synapsecns/sanguine/services/rfq/relayer/inventory"
Expand All @@ -18,6 +20,8 @@
"go.opentelemetry.io/otel/trace"
)

var maxRPCRetryTime = 15 * time.Second

// handleBridgeRequestedLog handles the BridgeRequestedLog event.
// Step 1: Seen
//
Expand All @@ -33,14 +37,26 @@
metrics.EndSpanWithErr(span, err)
}()

// TODO: consider a mapmutex
unlocker, ok := r.relayMtx.TryLock(hexutil.Encode(req.TransactionId[:]))
if !ok {
span.SetAttributes(attribute.Bool("locked", true))
// already processing this request
return nil
}

Check warning on line 45 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L40-L45

Added lines #L40 - L45 were not covered by tests

defer unlocker.Unlock()

Check warning on line 48 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L47-L48

Added lines #L47 - L48 were not covered by tests
_, err = r.db.GetQuoteRequestByID(ctx, req.TransactionId)
// expect no results
if !errors.Is(err, reldb.ErrNoQuoteForID) {
// maybe a db err? if so error out & try again later
if err != nil {
return fmt.Errorf("could not call db: %w", err)
}

span.AddEvent("already known")
// already seen this request
return nil

Check warning on line 59 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L57-L59

Added lines #L57 - L59 were not covered by tests
}

// TODO: these should be premade
Expand All @@ -54,9 +70,17 @@
return fmt.Errorf("could not get correct fast bridge: %w", err)
}

bridgeTx, err := fastBridge.GetBridgeTransaction(&bind.CallOpts{Context: ctx}, req.Request)
var bridgeTx fastbridge.IFastBridgeBridgeTransaction
call := func(ctx context.Context) error {
bridgeTx, err = fastBridge.GetBridgeTransaction(&bind.CallOpts{Context: ctx}, req.Request)
if err != nil {
return fmt.Errorf("could not get bridge transaction: %w", err)
}
return nil

Check warning on line 79 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L73-L79

Added lines #L73 - L79 were not covered by tests
}
err = retry.WithBackoff(ctx, call, retry.WithMaxTotalTime(maxRPCRetryTime))

Check warning on line 81 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L81

Added line #L81 was not covered by tests
if err != nil {
return fmt.Errorf("could not get bridge transaction: %w", err)
return fmt.Errorf("could not make call: %w", err)

Check warning on line 83 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L83

Added line #L83 was not covered by tests
Comment on lines +73 to +83
Copy link
Contributor

Choose a reason for hiding this comment

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

The retry logic for fetching the bridge transaction is crucial. However, this block of code lacks unit tests, which is essential to ensure its reliability under various network conditions.

Would you like help in creating these test cases?

Tools
GitHub Check: codecov/patch

[warning] 73-79: services/rfq/relayer/service/handlers.go#L73-L79
Added lines #L73 - L79 were not covered by tests


[warning] 81-81: services/rfq/relayer/service/handlers.go#L81
Added line #L81 was not covered by tests


[warning] 83-83: services/rfq/relayer/service/handlers.go#L83
Added line #L83 was not covered by tests

}

// TODO: you can just pull these out of inventory. If they don't exist mark as invalid.
Expand All @@ -71,7 +95,7 @@
return fmt.Errorf("could not get decimals: %w", err)
}

err = r.db.StoreQuoteRequest(ctx, reldb.QuoteRequest{
dbReq := reldb.QuoteRequest{

Check warning on line 98 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L98

Added line #L98 was not covered by tests
BlockNumber: req.Raw.BlockNumber,
RawRequest: req.Request,
OriginTokenDecimals: *originDecimals,
Expand All @@ -81,11 +105,25 @@
Transaction: bridgeTx,
Status: reldb.Seen,
OriginTxHash: req.Raw.TxHash,
})
}
err = r.db.StoreQuoteRequest(ctx, dbReq)

Check warning on line 109 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L108-L109

Added lines #L108 - L109 were not covered by tests
if err != nil {
return fmt.Errorf("could not get db: %w", err)
}

// immediately forward the request to handleSeen
span.AddEvent("sending to handleSeen")
qr, err := r.requestToHandler(ctx, dbReq)
if err != nil {
return fmt.Errorf("could not get quote request handler: %w", err)
}

Check warning on line 119 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L115-L119

Added lines #L115 - L119 were not covered by tests
// Forward instead of lock since we called lock above.
fwdErr := qr.Forward(ctx, dbReq)
if fwdErr != nil {
logger.Errorf("could not forward to handle seen: %w", fwdErr)
span.AddEvent("could not forward to handle seen")
}

Check warning on line 125 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L121-L125

Added lines #L121 - L125 were not covered by tests

return nil
}

Expand Down Expand Up @@ -167,10 +205,20 @@
return nil
}

request.Status = reldb.CommittedPending

Check warning on line 208 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L208

Added line #L208 was not covered by tests
err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.CommittedPending)
if err != nil {
return fmt.Errorf("could not update request status: %w", err)
}

// immediately forward the request to handleCommitPending
span.AddEvent("forwarding to handleCommitPending")
fwdErr := q.Forward(ctx, request)
if fwdErr != nil {
logger.Errorf("could not forward to handle commit pending: %w", fwdErr)
span.AddEvent("could not forward to handle commit pending")
}

Check warning on line 220 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L215-L220

Added lines #L215 - L220 were not covered by tests

Comment on lines +208 to +221
Copy link
Contributor

Choose a reason for hiding this comment

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

The logic to update the quote request status and forward it to handleCommitPending is crucial but lacks test coverage.

Would you like help in creating these test cases?

Tools
GitHub Check: codecov/patch

[warning] 208-208: services/rfq/relayer/service/handlers.go#L208
Added line #L208 was not covered by tests


[warning] 215-220: services/rfq/relayer/service/handlers.go#L215-L220
Added lines #L215 - L220 were not covered by tests

return nil
}

Expand Down Expand Up @@ -201,20 +249,40 @@
return nil
}

bs, err := q.Origin.Bridge.BridgeStatuses(&bind.CallOpts{Context: ctx}, request.TransactionID)
var bs uint8
call := func(ctx context.Context) error {
bs, err = q.Origin.Bridge.BridgeStatuses(&bind.CallOpts{Context: ctx}, request.TransactionID)
if err != nil {
return fmt.Errorf("could not get bridge status: %w", err)
}
return nil

Check warning on line 258 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L252-L258

Added lines #L252 - L258 were not covered by tests
}
err = retry.WithBackoff(ctx, call, retry.WithMaxTotalTime(maxRPCRetryTime))

Check warning on line 260 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L260

Added line #L260 was not covered by tests
if err != nil {
return fmt.Errorf("could not get bridge status: %w", err)
return fmt.Errorf("could not make contract call: %w", err)

Check warning on line 262 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L262

Added line #L262 was not covered by tests
}

span.AddEvent("status_check", trace.WithAttributes(attribute.String("chain_bridge_status", fastbridge.BridgeStatus(bs).String())))

// sanity check to make sure it's still requested.
if bs == fastbridge.REQUESTED.Int() {
err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.CommittedConfirmed)
if err != nil {
return fmt.Errorf("could not update request status: %w", err)
}
if bs != fastbridge.REQUESTED.Int() {
return nil

Check warning on line 269 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L268-L269

Added lines #L268 - L269 were not covered by tests
}

request.Status = reldb.CommittedConfirmed
err = q.db.UpdateQuoteRequestStatus(ctx, request.TransactionID, reldb.CommittedConfirmed)
if err != nil {
return fmt.Errorf("could not update request status: %w", err)
}

Check warning on line 276 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L272-L276

Added lines #L272 - L276 were not covered by tests

// immediately forward to handleCommitConfirmed
span.AddEvent("forwarding to handleCommitConfirmed")
fwdErr := q.Forward(ctx, request)
if fwdErr != nil {
logger.Errorf("could not forward to handle commit confirmed: %w", fwdErr)
span.AddEvent("could not forward to handle commit confirmed")
}

Check warning on line 284 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L279-L284

Added lines #L279 - L284 were not covered by tests

return nil
}

Expand Down Expand Up @@ -253,7 +321,9 @@
return fmt.Errorf("could not get quote request: %w", err)
}
// we might've accidentally gotten this later, if so we'll just ignore it
if reqID.Status != reldb.RelayStarted {
// note that in the edge case where we pessimistically marked as DeadlineExceeded
// and the relay was actually succesful, we should continue the proving process

Check failure on line 325 in services/rfq/relayer/service/handlers.go

View workflow job for this annotation

GitHub Actions / Lint (services/rfq)

`succesful` is a misspelling of `successful` (misspell)
if reqID.Status != reldb.RelayStarted && reqID.Status != reldb.DeadlineExceeded {
logger.Warnf("got relay log for request that was not relay started (transaction id: %s, txhash: %s)", hexutil.Encode(reqID.TransactionID[:]), req.Raw.TxHash)
return nil
}
Expand Down Expand Up @@ -321,9 +391,17 @@

// make sure relayer hasn't already proved. This is neeeded in case of an abrupt halt in event sourcing
// note: this assumes caller has already checked the sender is the relayer.
bs, err := q.Origin.Bridge.BridgeStatuses(&bind.CallOpts{Context: ctx}, request.TransactionID)
var bs uint8
call := func(ctx context.Context) error {
bs, err = q.Origin.Bridge.BridgeStatuses(&bind.CallOpts{Context: ctx}, request.TransactionID)
if err != nil {
return fmt.Errorf("could not get bridge status: %w", err)
}
return nil

Check warning on line 400 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L394-L400

Added lines #L394 - L400 were not covered by tests
}
err = retry.WithBackoff(ctx, call, retry.WithMaxTotalTime(maxRPCRetryTime))

Check warning on line 402 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L402

Added line #L402 was not covered by tests
if err != nil {
return fmt.Errorf("could not get bridge status: %w", err)
return fmt.Errorf("could not make contract call: %w", err)

Check warning on line 404 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L404

Added line #L404 was not covered by tests
}

if bs == fastbridge.RelayerClaimed.Int() {
Expand All @@ -334,9 +412,17 @@
return nil
}

canClaim, err := q.Origin.Bridge.CanClaim(&bind.CallOpts{Context: ctx}, request.TransactionID, q.RelayerAddress)
var canClaim bool
claimCall := func(ctx context.Context) error {
canClaim, err = q.Origin.Bridge.CanClaim(&bind.CallOpts{Context: ctx}, request.TransactionID, q.RelayerAddress)
if err != nil {
return fmt.Errorf("could not check if can claim: %w", err)
}
return nil

Check warning on line 421 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L415-L421

Added lines #L415 - L421 were not covered by tests
}
err = retry.WithBackoff(ctx, claimCall, retry.WithMaxTotalTime(maxRPCRetryTime))

Check warning on line 423 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L423

Added line #L423 was not covered by tests
if err != nil {
return fmt.Errorf("could not check if can claim: %w", err)
return fmt.Errorf("could not make call: %w", err)

Check warning on line 425 in services/rfq/relayer/service/handlers.go

View check run for this annotation

Codecov / codecov/patch

services/rfq/relayer/service/handlers.go#L425

Added line #L425 was not covered by tests
}

// can't claim yet. we'll check again later
Expand Down
Loading
Loading