-
Notifications
You must be signed in to change notification settings - Fork 33
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
feat(opbot): add additional relay check [SLT-359] #3312
Changes from all commits
c5659ed
109e2c1
a2d6461
d537d66
077bc51
134cbf5
ffe3179
b5c8bd3
15a282a
692228f
3bc3966
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ | |
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"log" | ||
"math/big" | ||
|
@@ -20,8 +19,8 @@ | |
"github.com/hako/durafmt" | ||
"github.com/slack-go/slack" | ||
"github.com/slack-io/slacker" | ||
"github.com/synapsecns/sanguine/contrib/opbot/internal" | ||
"github.com/synapsecns/sanguine/contrib/opbot/signoz" | ||
"github.com/synapsecns/sanguine/core" | ||
"github.com/synapsecns/sanguine/core/retry" | ||
"github.com/synapsecns/sanguine/ethergo/chaindata" | ||
"github.com/synapsecns/sanguine/ethergo/submitter" | ||
|
@@ -250,7 +249,8 @@ | |
return | ||
} | ||
|
||
fastBridgeContract, err := b.makeFastBridge(ctx.Context(), rawRequest) | ||
//nolint: gosec | ||
fastBridgeContractOrigin, err := b.makeFastBridge(ctx.Context(), uint32(rawRequest.Bridge.OriginChainID)) | ||
if err != nil { | ||
_, err := ctx.Response().Reply(err.Error()) | ||
if err != nil { | ||
|
@@ -275,11 +275,44 @@ | |
return | ||
} | ||
|
||
//nolint:gosec | ||
fastBridgeContractDest, err := b.makeFastBridge(ctx.Context(), uint32(rawRequest.Bridge.DestChainID)) | ||
if err != nil { | ||
_, err := ctx.Response().Reply(err.Error()) | ||
if err != nil { | ||
log.Println(err) | ||
} | ||
return | ||
} | ||
txBz, err := core.BytesToArray(common.Hex2Bytes(rawRequest.Bridge.TransactionID[2:])) | ||
if err != nil { | ||
_, err := ctx.Response().Reply("error converting tx id") | ||
if err != nil { | ||
log.Println(err) | ||
} | ||
return | ||
} | ||
isRelayed, err := fastBridgeContractDest.BridgeRelays(nil, txBz) | ||
if err != nil { | ||
_, err := ctx.Response().Reply("error fetching bridge relays") | ||
if err != nil { | ||
log.Println(err) | ||
} | ||
return | ||
} | ||
if isRelayed { | ||
_, err := ctx.Response().Reply("transaction has already been relayed") | ||
if err != nil { | ||
log.Println(err) | ||
} | ||
return | ||
} | ||
Comment on lines
+280
to
+309
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add test coverage for the relay check functionality. The newly added relay check is a critical validation that prevents duplicate processing. However, this code path lacks test coverage. Please add test cases covering:
Would you like me to help create comprehensive test cases for these scenarios? 🧰 Tools🪛 GitHub Check: codecov/patch[warning] 278-283: contrib/opbot/botmd/commands.go#L278-L283 [warning] 286-291: contrib/opbot/botmd/commands.go#L286-L291 [warning] 293-299: contrib/opbot/botmd/commands.go#L293-L299 [warning] 301-306: contrib/opbot/botmd/commands.go#L301-L306 |
||
|
||
nonce, err := b.submitter.SubmitTransaction( | ||
ctx.Context(), | ||
big.NewInt(int64(rawRequest.Bridge.OriginChainID)), | ||
func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) { | ||
tx, err = fastBridgeContract.Refund(transactor, common.Hex2Bytes(rawRequest.Bridge.Request[2:])) | ||
tx, err = fastBridgeContractOrigin.Refund(transactor, common.Hex2Bytes(rawRequest.Bridge.Request[2:])) | ||
if err != nil { | ||
return nil, fmt.Errorf("error submitting refund: %w", err) | ||
} | ||
|
@@ -322,7 +355,7 @@ | |
} | ||
} | ||
|
||
func (b *Bot) makeFastBridge(ctx context.Context, req *internal.GetRFQByTxIDResponse) (*fastbridge.FastBridge, error) { | ||
func (b *Bot) makeFastBridge(ctx context.Context, chainID uint32) (*fastbridge.FastBridge, error) { | ||
client, err := rfqClient.NewUnauthenticatedClient(b.handler, b.cfg.RFQApiURL) | ||
if err != nil { | ||
return nil, fmt.Errorf("error creating rfq client: %w", err) | ||
|
@@ -333,22 +366,23 @@ | |
return nil, fmt.Errorf("error fetching rfq contracts: %w", err) | ||
} | ||
|
||
chainClient, err := b.rpcClient.GetChainClient(ctx, req.Bridge.OriginChainID) | ||
chainClient, err := b.rpcClient.GetChainClient(ctx, int(chainID)) | ||
if err != nil { | ||
return nil, fmt.Errorf("error getting chain client: %w", err) | ||
return nil, fmt.Errorf("error getting chain client for chain ID %d: %w", chainID, err) | ||
} | ||
|
||
//nolint: gosec | ||
contractAddress, ok := contracts.Contracts[uint32(req.Bridge.OriginChainID)] | ||
contractAddress, ok := contracts.Contracts[chainID] | ||
if !ok { | ||
return nil, errors.New("contract address not found") | ||
return nil, fmt.Errorf("no contract address for chain ID") | ||
} | ||
|
||
fastBridgeHandle, err := fastbridge.NewFastBridge(common.HexToAddress(contractAddress), chainClient) | ||
if err != nil { | ||
return nil, fmt.Errorf("error creating fast bridge: %w", err) | ||
return nil, fmt.Errorf("error creating fast bridge for chain ID %d: %w", chainID, err) | ||
} | ||
|
||
return fastBridgeHandle, nil | ||
|
||
} | ||
|
||
func toExplorerSlackLink(ogHash string) string { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,3 +25,13 @@ | |
|
||
return string(formattedJSON), nil | ||
} | ||
|
||
// BytesToArray converts a slice to a 32 length byte array. | ||
func BytesToArray(bz []byte) ([32]byte, error) { | ||
golangisfun123 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
var bytes [32]byte | ||
if len(bz) != 32 { | ||
return bytes, fmt.Errorf("invalid length of bytes: %d", len(bz)) | ||
} | ||
copy(bytes[:], bz) | ||
return bytes, nil | ||
} | ||
Comment on lines
+30
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add unit tests for BytesToArray function The function lacks test coverage according to codecov report. As this is a core utility function, comprehensive testing is essential to ensure reliable behavior across different scenarios. Would you like me to help generate unit tests covering:
🧰 Tools🪛 GitHub Check: codecov/patch[warning] 30-36: core/bytes.go#L30-L36 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add bounds checking for chain ID conversions.
The conversions from
int
touint32
for both origin and destination chain IDs could lead to integer overflow. Add validation to ensure the values are within uint32 range.Apply this diff:
Also applies to: 277-277
🧰 Tools
🪛 GitHub Check: Lint (contrib/opbot)
[failure] 252-252:
G115: integer overflow conversion int -> uint32 (gosec)