Skip to content

Commit

Permalink
relabeling & using v2 events/parsing for both versions
Browse files Browse the repository at this point in the history
  • Loading branch information
parodime committed Nov 2, 2024
1 parent c664fa8 commit 494e841
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 165 deletions.
22 changes: 11 additions & 11 deletions services/rfq/guard/guardconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ type Config struct {

// ChainConfig represents the configuration for a chain.
type ChainConfig struct {
// RFQAddressV1 is the rfq bridge contract address.
// RFQAddressV1 is the legacy V1 rfq bridge contract address. OPTIONAL. Only populate if also guarding a deprecated V1 contract.
RFQAddressV1 *string `yaml:"rfq_address_v1"`
// RFQAddressV2 is the rfq bridge contract address.
RFQAddressV2 string `yaml:"rfq_address_v2"`
// RFQAddress is the current/latest rfq bridge contract address. REQUIRED.
RFQAddress string `yaml:"rfq_address"`
// Confirmations is the number of required confirmations.
Confirmations uint64 `yaml:"confirmations"`
}
Expand Down Expand Up @@ -70,17 +70,17 @@ func (c Config) Validate() (err error) {
for chainID := range c.Chains {
addrV1, err := c.GetRFQAddressV1(chainID)
if err != nil {
return fmt.Errorf("could not get rfq address: %w", err)
return fmt.Errorf("could not get v1 rfq address: %w", err)
}
if addrV1 != nil && !common.IsHexAddress(*addrV1) {
return fmt.Errorf("invalid rfq address: %s", *addrV1)
return fmt.Errorf("invalid rfq v1 address: %s", *addrV1)
}
addrV2, err := c.GetRFQAddressV2(chainID)
if err != nil {
return fmt.Errorf("could not get rfq address: %w", err)
return fmt.Errorf("could not get v1 rfq address: %w", err)
}
if !common.IsHexAddress(addrV2) {
return fmt.Errorf("invalid rfq address: %s", addrV2)
return fmt.Errorf("invalid rfq v1 address: %s", addrV2)
}
}

Expand All @@ -96,7 +96,7 @@ func (c Config) GetChains() map[int]ChainConfig {
func (c Config) GetRFQAddressV1(chainID int) (*string, error) {
chainCfg, ok := c.Chains[chainID]
if !ok {
return nil, fmt.Errorf("chain config not found for chain %d", chainID)
return nil, fmt.Errorf("v1 chain config not found for chain %d", chainID)
}
return chainCfg.RFQAddressV1, nil
}
Expand All @@ -105,9 +105,9 @@ func (c Config) GetRFQAddressV1(chainID int) (*string, error) {
func (c Config) GetRFQAddressV2(chainID int) (string, error) {
chainCfg, ok := c.Chains[chainID]
if !ok {
return "", fmt.Errorf("chain config not found for chain %d", chainID)
return "", fmt.Errorf("v2 chain config not found for chain %d", chainID)
}
return chainCfg.RFQAddressV2, nil
return chainCfg.RFQAddress, nil
}

const defaultDBSelectorIntervalSeconds = 1
Expand All @@ -134,7 +134,7 @@ func NewGuardConfigFromRelayer(relayerCfg relconfig.Config) Config {
for chainID, chainCfg := range relayerCfg.GetChains() {
cfg.Chains[chainID] = ChainConfig{
RFQAddressV1: chainCfg.RFQAddressV1,
RFQAddressV2: chainCfg.RFQAddress,
RFQAddress: chainCfg.RFQAddress,
Confirmations: chainCfg.FinalityConfirmations,
}
}
Expand Down
97 changes: 9 additions & 88 deletions services/rfq/guard/service/guard.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func NewGuard(ctx context.Context, metricHandler metrics.Handler, cfg guardconfi
if err != nil {
return nil, fmt.Errorf("could not get deploy block: %w", err)
}
chainListener, err := listener.NewChainListener(chainClient, store, common.HexToAddress(*rfqAddrV1), uint64(startBlock.Int64()), metricHandler, listener.WithName("guard"))
chainListener, err := listener.NewChainListener(chainClient, store, common.HexToAddress(*rfqAddrV1), uint64(startBlock.Int64()), metricHandler, listener.WithName("guardListenerLegacy"))
if err != nil {
return nil, fmt.Errorf("could not get chain listener: %w", err)
}
Expand All @@ -107,7 +107,7 @@ func NewGuard(ctx context.Context, metricHandler metrics.Handler, cfg guardconfi
if err != nil {
return nil, fmt.Errorf("could not get deploy block: %w", err)
}
chainListener, err := listener.NewChainListener(chainClient, store, common.HexToAddress(rfqAddrV2), uint64(startBlock.Int64()), metricHandler, listener.WithName("guard"))
chainListener, err := listener.NewChainListener(chainClient, store, common.HexToAddress(rfqAddrV2), uint64(startBlock.Int64()), metricHandler, listener.WithName("guardListener"))
if err != nil {
return nil, fmt.Errorf("could not get chain listener: %w", err)
}
Expand Down Expand Up @@ -210,7 +210,7 @@ func (g *Guard) startChainIndexers(ctx context.Context) (err error) {
}
if v1Addr != nil {
group.Go(func() error {
err := g.runChainIndexerV1(ctx, chainID)
err := g.runChainIndexer(ctx, chainID, g.listenersV1)
if err != nil {
return fmt.Errorf("could not runChainIndexer chain indexer for chain %d [v1]: %w", chainID, err)
}
Expand All @@ -219,7 +219,7 @@ func (g *Guard) startChainIndexers(ctx context.Context) (err error) {
}

group.Go(func() error {
err := g.runChainIndexerV2(ctx, chainID)
err := g.runChainIndexer(ctx, chainID, g.listenersV2)
if err != nil {
return fmt.Errorf("could not runChainIndexer chain indexer for chain %d [v2]: %w", chainID, err)
}
Expand All @@ -236,65 +236,9 @@ func (g *Guard) startChainIndexers(ctx context.Context) (err error) {
}

//nolint:cyclop
func (g Guard) runChainIndexerV1(ctx context.Context, chainID int) (err error) {
chainListener := g.listenersV1[chainID]
func (g Guard) runChainIndexer(ctx context.Context, chainID int, listeners map[int]listener.ContractListener) (err error) {

Check failure on line 239 in services/rfq/guard/service/guard.go

View workflow job for this annotation

GitHub Actions / Lint (services/rfq)

unnecessary leading newline (whitespace)

parser, err := fastbridge.NewParser(chainListener.Address())
if err != nil {
return fmt.Errorf("could not parse: %w", err)
}

err = chainListener.Listen(ctx, func(parentCtx context.Context, log types.Log) (err error) {
et, parsedEvent, ok := parser.ParseEvent(log)
// handle unknown event
if !ok {
if len(log.Topics) != 0 {
logger.Warnf("unknown event %s", log.Topics[0])
}
return nil
}

ctx, span := g.metrics.Tracer().Start(parentCtx, fmt.Sprintf("handleLog-%s", et), trace.WithAttributes(
attribute.String(metrics.TxHash, log.TxHash.String()),
attribute.Int(metrics.Origin, chainID),
attribute.String(metrics.Contract, log.Address.String()),
attribute.String("block_hash", log.BlockHash.String()),
attribute.Int64("block_number", int64(log.BlockNumber)),
))

defer func() {
metrics.EndSpanWithErr(span, err)
}()

switch event := parsedEvent.(type) {
case *fastbridge.FastBridgeBridgeRequested:
err = g.handleBridgeRequestedLog(ctx, event, chainID)
if err != nil {
return fmt.Errorf("could not handle request: %w", err)
}
case *fastbridge.FastBridgeBridgeProofProvided:
err = g.handleProofProvidedLog(ctx, event, chainID)
if err != nil {
return fmt.Errorf("could not handle request: %w", err)
}
case *fastbridge.FastBridgeBridgeProofDisputed:
err = g.handleProofDisputedLog(ctx, event)
if err != nil {
return fmt.Errorf("could not handle request: %w", err)
}
}

return nil
})
if err != nil {
return fmt.Errorf("listener failed: %w", err)
}
return nil
}

//nolint:cyclop,gosec
func (g Guard) runChainIndexerV2(ctx context.Context, chainID int) (err error) {
chainListener := g.listenersV2[chainID]
chainListener := listeners[chainID]

parser, err := fastbridgev2.NewParser(chainListener.Address())
if err != nil {
Expand Down Expand Up @@ -325,40 +269,17 @@ func (g Guard) runChainIndexerV2(ctx context.Context, chainID int) (err error) {

switch event := parsedEvent.(type) {
case *fastbridgev2.FastBridgeV2BridgeRequested:
v1Event := &fastbridge.FastBridgeBridgeRequested{
TransactionId: event.TransactionId,
Sender: event.Sender,
Request: event.Request,
DestChainId: event.DestChainId,
OriginToken: event.OriginToken,
DestToken: event.DestToken,
DestAmount: event.DestAmount,
SendChainGas: event.SendChainGas,
Raw: event.Raw,
}
err = g.handleBridgeRequestedLog(ctx, v1Event, chainID)
err = g.handleBridgeRequestedLog(ctx, event, chainID)
if err != nil {
return fmt.Errorf("could not handle request: %w", err)
}
// following events match ABIs exactly, so no need to differentiate
case *fastbridgev2.FastBridgeV2BridgeProofProvided:
v1Event := &fastbridge.FastBridgeBridgeProofProvided{
TransactionId: event.TransactionId,
Relayer: event.Relayer,
TransactionHash: event.TransactionHash,
Raw: event.Raw,
}
err = g.handleProofProvidedLog(ctx, v1Event, chainID)
err = g.handleProofProvidedLog(ctx, event, chainID)
if err != nil {
return fmt.Errorf("could not handle request: %w", err)
}
case *fastbridgev2.FastBridgeV2BridgeProofDisputed:
v1Event := &fastbridge.FastBridgeBridgeProofDisputed{
TransactionId: event.TransactionId,
Relayer: event.Relayer,
Raw: event.Raw,
}
err = g.handleProofDisputedLog(ctx, v1Event)
err = g.handleProofDisputedLog(ctx, event)
if err != nil {
return fmt.Errorf("could not handle request: %w", err)
}
Expand Down
85 changes: 19 additions & 66 deletions services/rfq/guard/service/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (

var maxRPCRetryTime = 15 * time.Second

func (g *Guard) handleBridgeRequestedLog(parentCtx context.Context, req *fastbridge.FastBridgeBridgeRequested, chainID int) (err error) {
func (g *Guard) handleBridgeRequestedLog(parentCtx context.Context, req *fastbridgev2.FastBridgeV2BridgeRequested, chainID int) (err error) {
ctx, span := g.metrics.Tracer().Start(parentCtx, "handleBridgeRequestedLog-guard", trace.WithAttributes(
attribute.Int(metrics.Origin, chainID),
attribute.String("transaction_id", hexutil.Encode(req.TransactionId[:])),
Expand Down Expand Up @@ -68,7 +68,7 @@ func (g *Guard) handleBridgeRequestedLog(parentCtx context.Context, req *fastbri
}

//nolint:gosec
func (g *Guard) handleProofProvidedLog(parentCtx context.Context, event *fastbridge.FastBridgeBridgeProofProvided, chainID int) (err error) {
func (g *Guard) handleProofProvidedLog(parentCtx context.Context, event *fastbridgev2.FastBridgeV2BridgeProofProvided, chainID int) (err error) {
ctx, span := g.metrics.Tracer().Start(parentCtx, "handleProofProvidedLog-guard", trace.WithAttributes(
attribute.Int(metrics.Origin, chainID),
attribute.String("transaction_id", hexutil.Encode(event.TransactionId[:])),
Expand All @@ -95,7 +95,7 @@ func (g *Guard) handleProofProvidedLog(parentCtx context.Context, event *fastbri
return nil
}

func (g *Guard) handleProofDisputedLog(parentCtx context.Context, event *fastbridge.FastBridgeBridgeProofDisputed) (err error) {
func (g *Guard) handleProofDisputedLog(parentCtx context.Context, event *fastbridgev2.FastBridgeV2BridgeProofDisputed) (err error) {
ctx, span := g.metrics.Tracer().Start(parentCtx, "handleProofDisputedLog-guard", trace.WithAttributes(
attribute.String("transaction_id", hexutil.Encode(event.TransactionId[:])),
))
Expand Down Expand Up @@ -211,6 +211,7 @@ func (g *Guard) disputeV2(ctx context.Context, proven *guarddb.PendingProven, br

//nolint:cyclop
func (g *Guard) isProveValid(ctx context.Context, proven *guarddb.PendingProven, bridgeRequest *guarddb.BridgeRequest) (bool, error) {

// get the receipt for this tx on dest chain
chainClient, err := g.client.GetChainClient(ctx, int(bridgeRequest.Transaction.DestChainId))
if err != nil {
Expand All @@ -225,83 +226,35 @@ func (g *Guard) isProveValid(ctx context.Context, proven *guarddb.PendingProven,
return false, fmt.Errorf("could not get receipt: %w", err)
}

var valid bool
var rfqContractAddr string

if g.isV2Address(int(bridgeRequest.Transaction.OriginChainId), proven.FastBridgeAddress) {
valid, err = g.isProveValidV2(ctx, proven, bridgeRequest, receipt)
rfqContractAddr, err = g.cfg.GetRFQAddressV2(int(bridgeRequest.Transaction.DestChainId))
if err != nil {
return false, fmt.Errorf("could not check prove validity v2: %w", err)
return false, fmt.Errorf("could not get rfq address v2: %w", err)
}
} else {
valid, err = g.isProveValidV1(ctx, proven, bridgeRequest, receipt)
v1addr, err := g.cfg.GetRFQAddressV1(int(bridgeRequest.Transaction.DestChainId))
if err != nil {
return false, fmt.Errorf("could not check prove validity v1: %w", err)
return false, fmt.Errorf("could not get rfq address v1: %w", err)
}
rfqContractAddr = *v1addr
}

return valid, nil
}

func (g *Guard) isProveValidV1(ctx context.Context, proven *guarddb.PendingProven, bridgeRequest *guarddb.BridgeRequest, receipt *types.Receipt) (bool, error) {
span := trace.SpanFromContext(ctx)
var valid bool
valid, err = g.isProveValidParse(ctx, proven, bridgeRequest, receipt, rfqContractAddr)

rfqAddr, err := g.cfg.GetRFQAddressV1(int(bridgeRequest.Transaction.DestChainId))
if err != nil {
return false, fmt.Errorf("could not get rfq address v1: %w", err)
}
if rfqAddr == nil {
return false, errors.New("rfq address v1 is nil")
}
parser, err := fastbridge.NewParser(common.HexToAddress(*rfqAddr))
if err != nil {
return false, fmt.Errorf("could not get parser: %w", err)
}

for _, log := range receipt.Logs {
_, parsedEvent, ok := parser.ParseEvent(*log)
if !ok {
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 {
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
}

details := relayDetails{
TransactionID: event.TransactionId,
OriginAmount: event.OriginAmount,
DestAmount: event.DestAmount,
OriginChainID: event.OriginChainId,
To: event.To,
OriginToken: event.OriginToken,
DestToken: event.DestToken,
}

return relayMatchesBridgeRequest(details, bridgeRequest), nil
return false, fmt.Errorf("could not parse proof for validity: %w", err)
}

return false, nil
return valid, nil
}

func (g *Guard) isProveValidV2(ctx context.Context, proven *guarddb.PendingProven, bridgeRequest *guarddb.BridgeRequest, receipt *types.Receipt) (bool, error) {
func (g *Guard) isProveValidParse(ctx context.Context, proven *guarddb.PendingProven, bridgeRequest *guarddb.BridgeRequest, receipt *types.Receipt, rfqContractAddr string) (bool, error) {
span := trace.SpanFromContext(ctx)

rfqAddr, err := g.cfg.GetRFQAddressV2(int(bridgeRequest.Transaction.DestChainId))
if err != nil {
return false, fmt.Errorf("could not get rfq address v2: %w", err)
}
parser, err := fastbridgev2.NewParser(common.HexToAddress(rfqAddr))
parser, err := fastbridgev2.NewParser(common.HexToAddress(rfqContractAddr))
if err != nil {
return false, fmt.Errorf("could not get parser: %w", err)
}
Expand All @@ -312,8 +265,8 @@ func (g *Guard) isProveValidV2(ctx context.Context, proven *guarddb.PendingProve
continue
}

if log.Address != common.HexToAddress(rfqAddr) {
span.AddEvent(fmt.Sprintf("log address %s does not match rfq address %s", log.Address.Hex(), rfqAddr))
if log.Address != common.HexToAddress(rfqContractAddr) {
span.AddEvent(fmt.Sprintf("log address %s does not match rfq address %s", log.Address.Hex(), rfqContractAddr))
continue
}

Expand Down

0 comments on commit 494e841

Please sign in to comment.