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

Add relayer API #1785

Merged
merged 45 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
eb4c98e
WIP: initial relayer api
dwasse Jan 8, 2024
0129b41
WIP: use ByTxID naming
dwasse Jan 8, 2024
c740fbf
Feat: add GetQuoteRequestStatusByTxHash
dwasse Jan 8, 2024
571e865
WIP: initial impl for PUT /tx/retry
dwasse Jan 8, 2024
521e7fa
Cleanup: comments
dwasse Jan 8, 2024
2e2eba3
Feat: add OriginTxHash to QuoteRequest, RequestForQuote models
dwasse Jan 8, 2024
de99481
Merge branch 'feat/rfq-origin-tx-hash' into feat/rfq-status
dwasse Jan 8, 2024
20123b6
Feat: fetch request by origin tx hash instead of dest
dwasse Jan 8, 2024
29a27d7
WIP: initial relayer api suite
dwasse Jan 8, 2024
90d1f5f
Feat: add /health endpoint
dwasse Jan 8, 2024
8645575
Feat: add TestGetQuoteRequestByTxHash
dwasse Jan 8, 2024
902f4aa
Fix: use /health in TestNewAPIServer
dwasse Jan 8, 2024
86d01e7
Feat: add TestGetQuoteRequestByTxID
dwasse Jan 8, 2024
8689d37
Cleanup: reorder funcs
dwasse Jan 8, 2024
a7a9cf2
WIP: add TestPutTxRetry
dwasse Jan 8, 2024
165f46f
Feat: PutTxRetry -> GetTxRetry, remove auth
dwasse Jan 8, 2024
c352481
WIP: set chain IDs on test request
dwasse Jan 8, 2024
5e3f0a7
Fix: set transaction submitter in suite
dwasse Jan 8, 2024
ee218b2
Feat: check for submitted tx in TestGetTxRetry
dwasse Jan 8, 2024
a5b254f
Cleanup: add SubmitRelay func to deduplicate code
dwasse Jan 8, 2024
b99e4fa
Cleanup: lints
dwasse Jan 9, 2024
27b7998
Cleanup: lints
dwasse Jan 9, 2024
d75654b
Merge branch 'master' into feat/rfq-status update w/ working test [go…
trajan0x Jan 9, 2024
32db813
Fix: bump server start timeout
dwasse Jan 9, 2024
833fca4
Lint: disable depguard
dwasse Jan 9, 2024
acd3f44
Fix: check nil tx in TestListenForEvents
dwasse Jan 9, 2024
aa743d2
Cleanup: use itoa instead of sprintf
dwasse Jan 9, 2024
831c50d
[goreleaser] Bump timeout on server startup
dwasse Jan 9, 2024
1cca179
Fix: server_test
dwasse Jan 9, 2024
5ca7680
Merge branch 'master' into feat/rfq-status
dwasse Jan 9, 2024
f42f2ce
[goreleaser] Cleanup: lint
dwasse Jan 9, 2024
dbed1e3
WIP: add relayer api config
dwasse Jan 9, 2024
2c57477
WIP: add new chain pkg, add APIConfig section for relayer api
dwasse Jan 9, 2024
0d0615c
Cleanup: lint
dwasse Jan 10, 2024
4e4e4d4
Cleanup: APIConfig -> RelayerAPIConfig
dwasse Jan 10, 2024
9abe98c
Cleanup: APIServer -> QuoterAPIServer
dwasse Jan 10, 2024
49b6ce4
Fix: build
dwasse Jan 10, 2024
98dcf6b
Merge branch 'master' into feat/rfq-status
dwasse Jan 10, 2024
83aa7d9
Cleanup: lint
dwasse Jan 10, 2024
51f719d
Fix: build
dwasse Jan 10, 2024
497bdff
Cleanup: lint
dwasse Jan 10, 2024
6a297fb
[goreleaser] Merge branch 'master' into feat/rfq-status
dwasse Jan 10, 2024
5dbd12e
Cleanup: lint
dwasse Jan 10, 2024
5fa3598
[goreleaser] Remove redundant RelayerAPIConfig section
dwasse Jan 10, 2024
6beb0f7
Merge branch 'master' into feat/rfq-status [goreleaser]
trajan0x Jan 11, 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
8 changes: 4 additions & 4 deletions services/rfq/api/client/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type ClientSuite struct {
cfg config.Config
testWallet wallet.Wallet
handler metrics.Handler
APIServer *rest.APIServer
QuoterAPIServer *rest.QuoterAPIServer
port uint16
client client.AuthenticatedClient
}
Expand Down Expand Up @@ -84,12 +84,12 @@ func (c *ClientSuite) SetupTest() {
}
c.cfg = testConfig

APIServer, err := rest.NewAPI(c.GetTestContext(), c.cfg, c.handler, c.omniRPCClient, c.database)
QuoterAPIServer, err := rest.NewAPI(c.GetTestContext(), c.cfg, c.handler, c.omniRPCClient, c.database)
c.Require().NoError(err)
c.APIServer = APIServer
c.QuoterAPIServer = QuoterAPIServer

go func() {
err := c.APIServer.Run(c.GetTestContext())
err := c.QuoterAPIServer.Run(c.GetTestContext())
Comment on lines +87 to +92
Copy link
Contributor

Choose a reason for hiding this comment

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

The SetupTest method correctly initializes the QuoterAPIServer and starts it in a goroutine. The use of time.Sleep to wait for the server to start is not ideal for test reliability. Consider using a more deterministic approach to wait for the server to be ready, such as polling on a health check endpoint.

- time.Sleep(2 * time.Second) // Wait for the server to start.
+ // Implement a more reliable way to wait for the server to start, such as polling a health endpoint.

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.

Suggested change
QuoterAPIServer, err := rest.NewAPI(c.GetTestContext(), c.cfg, c.handler, c.omniRPCClient, c.database)
c.Require().NoError(err)
c.APIServer = APIServer
c.QuoterAPIServer = QuoterAPIServer
go func() {
err := c.APIServer.Run(c.GetTestContext())
err := c.QuoterAPIServer.Run(c.GetTestContext())
QuoterAPIServer, err := rest.NewAPI(c.GetTestContext(), c.cfg, c.handler, c.omniRPCClient, c.database)
c.Require().NoError(err)
c.QuoterAPIServer = QuoterAPIServer
go func() {
err := c.QuoterAPIServer.Run(c.GetTestContext())
// Implement a more reliable way to wait for the server to start, such as polling a health endpoint.

c.Require().NoError(err)
}()
time.Sleep(2 * time.Second) // Wait for the server to start.
Expand Down
14 changes: 7 additions & 7 deletions services/rfq/api/rest/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import (
"github.com/synapsecns/sanguine/services/rfq/contracts/fastbridge"
)

// APIServer is a struct that holds the configuration, database connection, gin engine, RPC client, metrics handler, and fast bridge contracts.
// QuoterAPIServer is a struct that holds the configuration, database connection, gin engine, RPC client, metrics handler, and fast bridge contracts.
// It is used to initialize and run the API server.
type APIServer struct {
type QuoterAPIServer struct {
cfg config.Config
db db.APIDB
engine *gin.Engine
Expand All @@ -42,7 +42,7 @@ func NewAPI(
handler metrics.Handler,
omniRPCClient omniClient.RPCClient,
store db.APIDB,
) (*APIServer, error) {
) (*QuoterAPIServer, error) {
if ctx == nil {
return nil, fmt.Errorf("context is nil")
}
Expand All @@ -68,7 +68,7 @@ func NewAPI(
}
}

return &APIServer{
return &QuoterAPIServer{
cfg: cfg,
db: store,
omnirpcClient: omniRPCClient,
Expand All @@ -84,8 +84,8 @@ const (

var logger = log.Logger("rfq-api")

// Run runs the rest api server.
func (r *APIServer) Run(ctx context.Context) error {
// Run runs the quoter api server.
func (r *QuoterAPIServer) Run(ctx context.Context) error {
// TODO: Use Gin Helper
engine := ginhelper.New(logger)
h := NewHandler(r.db)
Expand All @@ -112,7 +112,7 @@ func (r *APIServer) Run(ctx context.Context) error {
}

// AuthMiddleware is the Gin authentication middleware that authenticates requests using EIP191.
func (r *APIServer) AuthMiddleware() gin.HandlerFunc {
func (r *QuoterAPIServer) AuthMiddleware() gin.HandlerFunc {
Copy link
Contributor

Choose a reason for hiding this comment

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

The AuthMiddleware method correctly implements the EIP191 authentication, but the hardcoded deadline (time.Now().Unix() - 1000) should be replaced with a configurable value from r.cfg.AuthExpiryDelta as indicated by the TODO comment. This is important for security reasons and to allow for easy adjustments without code changes.

return func(c *gin.Context) {
var req model.PutQuoteRequest
if err := c.BindJSON(&req); err != nil {
Comment on lines 112 to 118
Copy link
Contributor

Choose a reason for hiding this comment

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

Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [87-117]

The Run method of QuoterAPIServer has been updated to use the ginhelper.New function to create a new Gin engine. The TODO comment suggests that there is an intention to replace the hardcoded deadline with a configurable value. This should be addressed to avoid potential security issues with stale authentication tokens.

Expand Down
20 changes: 10 additions & 10 deletions services/rfq/api/rest/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import (
"github.com/synapsecns/sanguine/services/rfq/api/model"
)

func (c *ServerSuite) TestNewAPIServer() {
func (c *ServerSuite) TestNewQuoterAPIServer() {
// Start the API server in a separate goroutine and wait for it to initialize.
c.startAPIServer()
c.startQuoterAPIServer()
client := &http.Client{}
req, err := http.NewRequestWithContext(c.GetTestContext(), http.MethodGet, fmt.Sprintf("http://localhost:%d/quotes", c.port), nil)
c.Require().NoError(err)
Expand All @@ -34,7 +34,7 @@ func (c *ServerSuite) TestNewAPIServer() {
// TestEIP191_SuccessfulSignature tests the EIP191 signature process for successful authentication.
func (c *ServerSuite) TestEIP191_SuccessfulSignature() {
// Start the API server in a separate goroutine and wait for it to initialize.
c.startAPIServer()
c.startQuoterAPIServer()

// Prepare the authorization header with a signed timestamp.
header, err := c.prepareAuthHeader(c.testWallet)
Expand Down Expand Up @@ -65,7 +65,7 @@ func (c *ServerSuite) TestEIP191_SuccessfulSignature() {
// TestEIP191_UnsuccessfulSignature tests the EIP191 signature process with an incorrect wallet signature.
func (c *ServerSuite) TestEIP191_UnsuccessfulSignature() {
// Start the API server in a separate goroutine and wait for it to initialize.
c.startAPIServer()
c.startQuoterAPIServer()

// Prepare the authorization header with a signed timestamp using an incorrect wallet.
randomWallet, err := wallet.FromRandom()
Expand Down Expand Up @@ -97,7 +97,7 @@ func (c *ServerSuite) TestEIP191_UnsuccessfulSignature() {
// TestEIP191_SuccessfulPutSubmission tests a successful PUT request submission.
func (c *ServerSuite) TestEIP191_SuccessfulPutSubmission() {
// Start the API server in a separate goroutine and wait for it to initialize.
c.startAPIServer()
c.startQuoterAPIServer()

// Prepare the authorization header with a signed timestamp.
header, err := c.prepareAuthHeader(c.testWallet)
Expand All @@ -120,7 +120,7 @@ func (c *ServerSuite) TestEIP191_SuccessfulPutSubmission() {
}

func (c *ServerSuite) TestPutAndGetQuote() {
c.startAPIServer()
c.startQuoterAPIServer()

header, err := c.prepareAuthHeader(c.testWallet)
c.Require().NoError(err)
Expand Down Expand Up @@ -162,7 +162,7 @@ func (c *ServerSuite) TestPutAndGetQuote() {
}

func (c *ServerSuite) TestPutAndGetQuoteByRelayer() {
c.startAPIServer()
c.startQuoterAPIServer()

header, err := c.prepareAuthHeader(c.testWallet)
c.Require().NoError(err)
Expand Down Expand Up @@ -203,10 +203,10 @@ func (c *ServerSuite) TestPutAndGetQuoteByRelayer() {
c.Assert().True(found, "Newly added quote not found")
}

// startAPIServer starts the API server and waits for it to initialize.
func (c *ServerSuite) startAPIServer() {
// startQuoterAPIServer starts the API server and waits for it to initialize.
func (c *ServerSuite) startQuoterAPIServer() {
go func() {
err := c.APIServer.Run(c.GetTestContext())
err := c.QuoterAPIServer.Run(c.GetTestContext())
Comment on lines +206 to +209
Copy link
Contributor

Choose a reason for hiding this comment

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

The startQuoterAPIServer method starts the QuoterAPIServer in a goroutine. As mentioned earlier, using time.Sleep to wait for the server to start is not ideal. A more deterministic approach should be used to ensure the server is ready before proceeding with tests.

- time.Sleep(2 * time.Second) // Wait for the server to start.
+ // Implement a more reliable way to wait for the server to start, such as polling a health endpoint.

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.

Suggested change
// startQuoterAPIServer starts the API server and waits for it to initialize.
func (c *ServerSuite) startQuoterAPIServer() {
go func() {
err := c.APIServer.Run(c.GetTestContext())
err := c.QuoterAPIServer.Run(c.GetTestContext())
// startQuoterAPIServer starts the API server and waits for it to initialize.
func (c *ServerSuite) startQuoterAPIServer() {
go func() {
err := c.QuoterAPIServer.Run(c.GetTestContext())
// Implement a more reliable way to wait for the server to start, such as polling a health endpoint.

c.Require().NoError(err)
}()
time.Sleep(2 * time.Second) // Wait for the server to start.
Expand Down
8 changes: 4 additions & 4 deletions services/rfq/api/rest/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type ServerSuite struct {
cfg config.Config
testWallet wallet.Wallet
handler metrics.Handler
APIServer *rest.APIServer
QuoterAPIServer *rest.QuoterAPIServer
port uint16
}

Expand Down Expand Up @@ -80,13 +80,13 @@ func (c *ServerSuite) SetupTest() {
}
c.cfg = testConfig

APIServer, err := rest.NewAPI(c.GetTestContext(), c.cfg, c.handler, c.omniRPCClient, c.database)
QuoterAPIServer, err := rest.NewAPI(c.GetTestContext(), c.cfg, c.handler, c.omniRPCClient, c.database)
c.Require().NoError(err)

c.APIServer = APIServer
c.QuoterAPIServer = QuoterAPIServer

// go func() {
// err := c.APIServer.Run(c.GetTestContext())
// err := c.QuoterAPIServer.Run(c.GetTestContext())
// c.Require().NoError(err)
// }()
// time.Sleep(2 * time.Second) // Wait for the server to start.
Expand Down
17 changes: 9 additions & 8 deletions services/rfq/e2e/rfq_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ type IntegrationSuite struct {
originBackend backends.SimulatedTestBackend
destBackend backends.SimulatedTestBackend
//omniserver is the omnirpc server address
omniServer string
omniClient omnirpcClient.RPCClient
metrics metrics.Handler
apiServer string
relayer *service.Relayer
relayerWallet wallet.Wallet
userWallet wallet.Wallet
omniServer string
omniClient omnirpcClient.RPCClient
metrics metrics.Handler
apiServer string
relayerApiServer string
relayer *service.Relayer
relayerWallet wallet.Wallet
userWallet wallet.Wallet
}

func NewIntegrationSuite(tb testing.TB) *IntegrationSuite {
Expand Down Expand Up @@ -68,7 +69,7 @@ func (i *IntegrationSuite) SetupTest() {
i.setupBackends()

// setup the api server
i.setupAPI()
i.setupQuoterAPI()
i.setupRelayer()

}
Expand Down
14 changes: 12 additions & 2 deletions services/rfq/e2e/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import (
"github.com/synapsecns/sanguine/services/rfq/testutil"
)

func (i *IntegrationSuite) setupAPI() {
func (i *IntegrationSuite) setupQuoterAPI() {
dbPath := filet.TmpDir(i.T(), "")
apiPort, err := freeport.GetFreePort()
i.NoError(err)
Expand Down Expand Up @@ -189,6 +189,8 @@ func (i *IntegrationSuite) setupRelayer() {
wg.Wait()

// construct the config
relayerApiPort, err := freeport.GetFreePort()
i.NoError(err)
dsn := filet.TmpDir(i.T(), "")
cfg := relconfig.Config{
// generated ex-post facto
Expand Down Expand Up @@ -229,6 +231,15 @@ func (i *IntegrationSuite) setupRelayer() {
Type: signerConfig.FileType.String(),
File: filet.TmpFile(i.T(), "", i.relayerWallet.PrivateKeyHex()).Name(),
},
RelayerAPIURL: fmt.Sprintf("http://localhost:%d", relayerApiPort),
RelayerAPIConfig: relconfig.RelayerAPIConfig{
Database: relconfig.DatabaseConfig{
Type: dbcommon.Sqlite.String(),
DSN: dsn,
},
OmniRPCURL: i.omniServer,
Port: strconv.Itoa(relayerApiPort),
},
FeePricer: relconfig.FeePricerConfig{
GasPriceCacheTTLSeconds: 60,
TokenPriceCacheTTLSeconds: 60,
Expand Down Expand Up @@ -277,7 +288,6 @@ func (i *IntegrationSuite) setupRelayer() {
}

// TODO: good chance we wanna leave actually starting this up to the indiividual test.
var err error
i.relayer, err = service.NewRelayer(i.GetTestContext(), i.metrics, cfg)
i.NoError(err)
go func() {
Expand Down
91 changes: 91 additions & 0 deletions services/rfq/relayer/chain/chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Package chain defines the interface for interacting with a blockchain.
package chain

import (
"context"
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/synapsecns/sanguine/core"
"github.com/synapsecns/sanguine/ethergo/client"
"github.com/synapsecns/sanguine/ethergo/submitter"
"github.com/synapsecns/sanguine/services/rfq/contracts/fastbridge"
"github.com/synapsecns/sanguine/services/rfq/relayer/listener"
"github.com/synapsecns/sanguine/services/rfq/relayer/reldb"
)

// Chain is a chain helper for relayer.
// lowercase fields are private, uppercase are public.
// the plan is to move this out of relayer which is when this distinction will matter.
type Chain struct {
ChainID uint32
Bridge *fastbridge.FastBridgeRef
Client client.EVM
Confirmations uint64
listener listener.ContractListener
submitter submitter.TransactionSubmitter
}

// NewChain creates a new chain.
func NewChain(ctx context.Context, chainClient client.EVM, addr common.Address, chainListener listener.ContractListener, ts submitter.TransactionSubmitter) (*Chain, error) {
bridge, err := fastbridge.NewFastBridgeRef(addr, chainClient)
if err != nil {
return nil, fmt.Errorf("could not create bridge contract: %w", err)
}
chainID, err := chainClient.ChainID(ctx)
if err != nil {
return nil, fmt.Errorf("could not get chain id: %w", err)
}
return &Chain{
ChainID: uint32(chainID.Int64()),
Bridge: bridge,
Client: chainClient,
// TODO: configure
Confirmations: 1,
listener: chainListener,
submitter: ts,
}, nil
Comment on lines +32 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.

The NewChain function is responsible for creating a new Chain instance. It performs error checking and returns a new Chain object or an error. The error messages are wrapped for better context. The TODO comment on line 46 indicates that the Confirmations field should be configurable in the future.

- // TODO: configure
- Confirmations: 1,
+ // TODO: This value should be made configurable.
+ Confirmations: defaultConfirmations, // Assuming `defaultConfirmations` is a constant defined elsewhere.

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.

Suggested change
// NewChain creates a new chain.
func NewChain(ctx context.Context, chainClient client.EVM, addr common.Address, chainListener listener.ContractListener, ts submitter.TransactionSubmitter) (*Chain, error) {
bridge, err := fastbridge.NewFastBridgeRef(addr, chainClient)
if err != nil {
return nil, fmt.Errorf("could not create bridge contract: %w", err)
}
chainID, err := chainClient.ChainID(ctx)
if err != nil {
return nil, fmt.Errorf("could not get chain id: %w", err)
}
return &Chain{
ChainID: uint32(chainID.Int64()),
Bridge: bridge,
Client: chainClient,
// TODO: configure
Confirmations: 1,
listener: chainListener,
submitter: ts,
}, nil
// NewChain creates a new chain.
func NewChain(ctx context.Context, chainClient client.EVM, addr common.Address, chainListener listener.ContractListener, ts submitter.TransactionSubmitter) (*Chain, error) {
bridge, err := fastbridge.NewFastBridgeRef(addr, chainClient)
if err != nil {
return nil, fmt.Errorf("could not create bridge contract: %w", err)
}
chainID, err := chainClient.ChainID(ctx)
if err != nil {
return nil, fmt.Errorf("could not get chain id: %w", err)
}
return &Chain{
ChainID: uint32(chainID.Int64()),
Bridge: bridge,
Client: chainClient,
// TODO: This value should be made configurable.
Confirmations: defaultConfirmations, // Assuming `defaultConfirmations` is a constant defined elsewhere.
listener: chainListener,
submitter: ts,
}, nil
}

}

// SubmitTransaction submits a transaction to the chain.
func (c Chain) SubmitTransaction(ctx context.Context, call submitter.ContractCallType) (nonce uint64, _ error) {
//nolint: wrapcheck
return c.submitter.SubmitTransaction(ctx, big.NewInt(int64(c.ChainID)), call)
}

// LatestBlock returns the latest block.
func (c Chain) LatestBlock() uint64 {
return c.listener.LatestBlock()
}

// SubmitRelay submits a relay transaction to the destination chain after evaluating gas amount.
func (c Chain) SubmitRelay(ctx context.Context, request reldb.QuoteRequest) (uint64, *big.Int, error) {
gasAmount := big.NewInt(0)
var err error

if request.Transaction.SendChainGas {
gasAmount, err = c.Bridge.ChainGasAmount(&bind.CallOpts{Context: ctx})
if err != nil {
return 0, nil, fmt.Errorf("could not get chain gas amount: %w", err)
}
}

nonce, err := c.SubmitTransaction(ctx, func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) {
transactor.Value = core.CopyBigInt(gasAmount)

tx, err = c.Bridge.Relay(transactor, request.RawRequest)
if err != nil {
return nil, fmt.Errorf("could not relay: %w", err)
}

return tx, nil
})
if err != nil {
return 0, nil, fmt.Errorf("could not submit transaction: %w", err)
}

return nonce, gasAmount, nil
}
9 changes: 6 additions & 3 deletions services/rfq/relayer/listener/listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package listener_test

import (
"context"
"math/big"
"sync"
"time"

"github.com/brianvoe/gofakeit/v6"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/synapsecns/sanguine/services/rfq/contracts/testcontracts/fastbridgemock"
"github.com/synapsecns/sanguine/services/rfq/relayer/listener"
"math/big"
"sync"
"time"
)

func (l *ListenerTestSuite) TestListenForEvents() {
Expand Down Expand Up @@ -40,6 +41,7 @@ func (l *ListenerTestSuite) TestListenForEvents() {
Deadline: new(big.Int).SetUint64(uint64(time.Now().Add(-1 * time.Second * time.Duration(gofakeit.Uint16())).Unix())),
})
l.NoError(err)
l.NotNil(bridgeRequestTX)

l.backend.WaitForConfirmation(l.GetTestContext(), bridgeRequestTX)

Expand All @@ -63,6 +65,7 @@ func (l *ListenerTestSuite) TestListenForEvents() {
// gasAmount
new(big.Int).SetUint64(gofakeit.Uint64()))
l.NoError(err)
l.NotNil(bridgeResponseTX)
l.backend.WaitForConfirmation(l.GetTestContext(), bridgeResponseTX)
}(i)
}
Expand Down
Loading
Loading