From 47ff4bae7a79811e5a1203232d087bb7de550860 Mon Sep 17 00:00:00 2001 From: dwasse Date: Mon, 12 Aug 2024 12:07:57 -0500 Subject: [PATCH] feat(rfq-guard): proof checks (#3002) * Feat: check log address before verifying * Feat: add tracing * [goreleaser] * Feat: add RelayerAddress to PendingProven model * Feat: check relayer address * Cleanup: add tracing * [goreleaser] * Cleanup: lint * Fix: set RelayerAddress * [goreleaser] --- services/rfq/guard/guarddb/base/model.go | 20 ++++++++------ services/rfq/guard/guarddb/db.go | 9 ++++--- services/rfq/guard/service/handlers.go | 33 ++++++++++++++++++------ 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/services/rfq/guard/guarddb/base/model.go b/services/rfq/guard/guarddb/base/model.go index b8dd1795ef..3db6c5f938 100644 --- a/services/rfq/guard/guarddb/base/model.go +++ b/services/rfq/guard/guarddb/base/model.go @@ -34,6 +34,8 @@ type PendingProvenModel struct { UpdatedAt time.Time // Origin is the origin chain id Origin uint32 + // RelayerAddress is the address of the relayer that called prove() + RelayerAddress string // TransactionID is the transaction id of the event TransactionID string `gorm:"column:transaction_id;primaryKey"` // TxHash is the hash of the relay transaction on destination @@ -45,10 +47,11 @@ type PendingProvenModel struct { // FromPendingProven converts a quote request to an object that can be stored in the db. func FromPendingProven(proven guarddb.PendingProven) PendingProvenModel { return PendingProvenModel{ - Origin: proven.Origin, - TransactionID: hexutil.Encode(proven.TransactionID[:]), - TxHash: proven.TxHash.Hex(), - Status: proven.Status, + Origin: proven.Origin, + RelayerAddress: proven.RelayerAddress.Hex(), + TransactionID: hexutil.Encode(proven.TransactionID[:]), + TxHash: proven.TxHash.Hex(), + Status: proven.Status, } } @@ -65,10 +68,11 @@ func (p PendingProvenModel) ToPendingProven() (*guarddb.PendingProven, error) { } return &guarddb.PendingProven{ - Origin: p.Origin, - TransactionID: transactionID, - TxHash: common.HexToHash(p.TxHash), - Status: p.Status, + Origin: p.Origin, + RelayerAddress: common.HexToAddress(p.RelayerAddress), + TransactionID: transactionID, + TxHash: common.HexToHash(p.TxHash), + Status: p.Status, }, nil } diff --git a/services/rfq/guard/guarddb/db.go b/services/rfq/guard/guarddb/db.go index 236a5b7e2c..1f6485d34c 100644 --- a/services/rfq/guard/guarddb/db.go +++ b/services/rfq/guard/guarddb/db.go @@ -59,10 +59,11 @@ type BridgeRequest struct { // PendingProven is the pending proven object. type PendingProven struct { - Origin uint32 - TransactionID [32]byte - TxHash common.Hash - Status PendingProvenStatus + Origin uint32 + RelayerAddress common.Address + TransactionID [32]byte + TxHash common.Hash + Status PendingProvenStatus } // PendingProvenStatus is the status of a quote request in the db. diff --git a/services/rfq/guard/service/handlers.go b/services/rfq/guard/service/handlers.go index 736fd61b5a..b861bc33d2 100644 --- a/services/rfq/guard/service/handlers.go +++ b/services/rfq/guard/service/handlers.go @@ -77,10 +77,11 @@ func (g *Guard) handleProofProvidedLog(parentCtx context.Context, event *fastbri }() proven := guarddb.PendingProven{ - Origin: uint32(chainID), - TransactionID: event.TransactionId, - TxHash: event.TransactionHash, - Status: guarddb.ProveCalled, + Origin: uint32(chainID), + RelayerAddress: event.Relayer, + TransactionID: event.TransactionId, + TxHash: event.TransactionHash, + Status: guarddb.ProveCalled, } err = g.db.StorePendingProven(ctx, proven) if err != nil { @@ -162,7 +163,10 @@ func (g *Guard) handleProveCalled(parentCtx context.Context, proven *guarddb.Pen return nil } +//nolint:cyclop func (g *Guard) isProveValid(ctx context.Context, proven *guarddb.PendingProven, bridgeRequest *guarddb.BridgeRequest) (bool, error) { + span := trace.SpanFromContext(ctx) + // get the receipt for this tx on dest chain chainClient, err := g.client.GetChainClient(ctx, int(bridgeRequest.Transaction.DestChainId)) if err != nil { @@ -176,11 +180,11 @@ func (g *Guard) isProveValid(ctx context.Context, proven *guarddb.PendingProven, if err != nil { return false, fmt.Errorf("could not get receipt: %w", err) } - addr, err := g.cfg.GetRFQAddress(int(bridgeRequest.Transaction.DestChainId)) + rfqAddr, err := g.cfg.GetRFQAddress(int(bridgeRequest.Transaction.DestChainId)) if err != nil { return false, fmt.Errorf("could not get rfq address: %w", err) } - parser, err := fastbridge.NewParser(common.HexToAddress(addr)) + parser, err := fastbridge.NewParser(common.HexToAddress(rfqAddr)) if err != nil { return false, fmt.Errorf("could not get parser: %w", err) } @@ -191,10 +195,23 @@ func (g *Guard) isProveValid(ctx context.Context, proven *guarddb.PendingProven, continue } + if log.Address != common.HexToAddress(rfqAddr) { + span.AddEvent(fmt.Sprintf("log address %s does not match rfq address %s", log.Address.Hex(), rfqAddr)) + continue + } + event, ok := parsedEvent.(*fastbridge.FastBridgeBridgeRelayed) - if ok { - return relayMatchesBridgeRequest(event, bridgeRequest), nil + if !ok { + span.AddEvent("event is not a BridgeRelayed event") + continue } + + if event.Relayer != proven.RelayerAddress { + span.AddEvent(fmt.Sprintf("relayer address %s does not match prover address %s", event.Relayer.Hex(), proven.RelayerAddress.Hex())) + continue + } + + return relayMatchesBridgeRequest(event, bridgeRequest), nil } return false, nil