Skip to content

Commit

Permalink
Merge pull request #182 from ava-labs/check-supported-destination
Browse files Browse the repository at this point in the history
Check cfg for supported destination
  • Loading branch information
cam-schultz authored Feb 14, 2024
2 parents 86e5faf + 4a36ff5 commit fee580c
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 23 deletions.
12 changes: 12 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,18 @@ func (s *SourceSubnet) Validate(destinationBlockchainIDs *set.Set[string]) error

// Validate and store the allowed destinations for future use
s.supportedDestinations = set.Set[ids.ID]{}

// If the list of supported destinations is empty, populate with all of the configured destinations
if len(s.SupportedDestinations) == 0 {
for _, blockchainIDStr := range destinationBlockchainIDs.List() {
blockchainID, err := ids.FromString(blockchainIDStr)
if err != nil {
return fmt.Errorf("invalid blockchainID in configuration. error: %w", err)
}
s.supportedDestinations.Add(blockchainID)
}
}

for _, blockchainIDStr := range s.SupportedDestinations {
blockchainID, err := ids.FromString(blockchainIDStr)
if err != nil {
Expand Down
80 changes: 80 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"testing"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/set"
"github.com/ava-labs/awm-relayer/utils"
mock_ethclient "github.com/ava-labs/awm-relayer/vms/evm/mocks"
"github.com/ava-labs/subnet-evm/params"
Expand Down Expand Up @@ -542,3 +543,82 @@ func TestGetWarpQuorum(t *testing.T) {
})
}
}

func TestValidateSourceSubnet(t *testing.T) {
validSourceCfg := SourceSubnet{
APINodeHost: "http://test.avax.network",
APINodePort: 0,
BlockchainID: testBlockchainID,
SubnetID: testSubnetID,
VM: "evm",
EncryptConnection: false,
SupportedDestinations: []string{testBlockchainID},
MessageContracts: map[string]MessageProtocolConfig{
testAddress: {
MessageFormat: TELEPORTER.String(),
},
},
}
testCases := []struct {
name string
sourceSubnet func() SourceSubnet
destinationBlockchainIDs []string
expectError bool
expectedSupportedDestinations []string
}{
{
name: "valid source subnet; explicitly supported destination",
sourceSubnet: func() SourceSubnet { return validSourceCfg },
destinationBlockchainIDs: []string{testBlockchainID},
expectError: false,
expectedSupportedDestinations: []string{testBlockchainID},
},
{
name: "valid source subnet; implicitly supported destination",
sourceSubnet: func() SourceSubnet {
cfg := validSourceCfg
cfg.SupportedDestinations = nil
return cfg
},
destinationBlockchainIDs: []string{testBlockchainID},
expectError: false,
expectedSupportedDestinations: []string{testBlockchainID},
},
{
name: "valid source subnet; partially supported destinations",
sourceSubnet: func() SourceSubnet { return validSourceCfg },
destinationBlockchainIDs: []string{testBlockchainID, testBlockchainID2},
expectError: false,
expectedSupportedDestinations: []string{testBlockchainID},
},
{
name: "valid source subnet; unsupported destinations",
sourceSubnet: func() SourceSubnet { return validSourceCfg },
destinationBlockchainIDs: []string{testBlockchainID2},
expectError: true,
expectedSupportedDestinations: []string{},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
blockchainIDs := set.NewSet[string](len(testCase.destinationBlockchainIDs))
for _, id := range testCase.destinationBlockchainIDs {
blockchainIDs.Add(id)
}

sourceSubnet := testCase.sourceSubnet()
res := sourceSubnet.Validate(&blockchainIDs)
if testCase.expectError {
require.Error(t, res)
} else {
require.NoError(t, res)
}
// check the supported destinations
for _, idStr := range testCase.expectedSupportedDestinations {
id, err := ids.FromString(idStr)
require.NoError(t, err)
require.True(t, sourceSubnet.supportedDestinations.Contains(id))
}
})
}
}
1 change: 1 addition & 0 deletions messages/teleporter/message_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ func (m *messageManager) ShouldSendMessage(unsignedMessage *warp.UnsignedMessage
// Get the correct destination client from the global map
destinationClient, ok := m.destinationClients[destinationBlockchainID]
if !ok {
// This shouldn't occur, since we already check this in Relayer.CheckSupportedDestination. Return an error in this case.
return false, fmt.Errorf("relayer not configured to deliver to destination. destinationBlockchainID=%s", destinationBlockchainID.String())
}

Expand Down
4 changes: 2 additions & 2 deletions relayer/message_relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ func newMessageRelayer(
quorum, err := relayer.globalConfig.GetWarpQuorum(destinationBlockchainID)
if err != nil {
relayer.logger.Error(
"Failed to get warp quorum",
zap.Error(err),
"Failed to get warp quorum from config. Relayer may not be configured to deliver to the destination chain.",
zap.String("destinationBlockchainID", destinationBlockchainID.String()),
zap.Error(err),
)
return nil, err
}
Expand Down
18 changes: 3 additions & 15 deletions relayer/relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,22 +99,11 @@ func NewRelayer(
return nil, err
}

var filteredDestinationClients map[ids.ID]vms.DestinationClient
supportedDestinationsBlockchainIDs := sourceSubnetInfo.GetSupportedDestinations()
if len(supportedDestinationsBlockchainIDs) > 0 {
filteredDestinationClients := make(map[ids.ID]vms.DestinationClient)
for id := range supportedDestinationsBlockchainIDs {
filteredDestinationClients[id] = destinationClients[id]
}
} else {
filteredDestinationClients = destinationClients
}

// Create message managers for each supported message protocol
messageManagers := make(map[common.Address]messages.MessageManager)
for addressStr, config := range sourceSubnetInfo.MessageContracts {
address := common.HexToAddress(addressStr)
messageManager, err := messages.NewMessageManager(logger, address, config, filteredDestinationClients)
messageManager, err := messages.NewMessageManager(logger, address, config, destinationClients)
if err != nil {
logger.Error(
"Failed to create message manager",
Expand Down Expand Up @@ -157,7 +146,7 @@ func NewRelayer(
logger: logger,
metrics: metrics,
db: db,
supportedDestinations: supportedDestinationsBlockchainIDs,
supportedDestinations: sourceSubnetInfo.GetSupportedDestinations(),
rpcEndpoint: rpcEndpoint,
apiNodeURI: uri,
messageCreator: messageCreator,
Expand Down Expand Up @@ -464,9 +453,8 @@ func (r *Relayer) RelayMessage(warpLogInfo *vmtypes.WarpLogInfo, storeProcessedH
}

// Returns whether destinationBlockchainID is a supported destination.
// If supportedDestinations is empty, then all destination chain IDs are supported.
func (r *Relayer) CheckSupportedDestination(destinationBlockchainID ids.ID) bool {
return len(r.supportedDestinations) == 0 || r.supportedDestinations.Contains(destinationBlockchainID)
return r.supportedDestinations.Contains(destinationBlockchainID)
}

// Get the latest processed block height from the database.
Expand Down
6 changes: 0 additions & 6 deletions relayer/relayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,6 @@ func TestCheckSupportedDestination(t *testing.T) {
destinationBlockchainID: id1,
expectedResult: true,
},
{
name: "implicitly supported destination",
relayer: Relayer{},
destinationBlockchainID: id1,
expectedResult: true,
},
{
name: "unsupported destination",
relayer: Relayer{
Expand Down

0 comments on commit fee580c

Please sign in to comment.