Skip to content

Commit

Permalink
key sources+dsts by chain
Browse files Browse the repository at this point in the history
  • Loading branch information
cam-schultz committed Mar 4, 2024
1 parent 6884e54 commit 2b0017a
Show file tree
Hide file tree
Showing 17 changed files with 96 additions and 96 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ The relayer is configured via a JSON file, the path to which is passed in via th

- The address of the destination account that will receive the Warp message.

`"source-subnets": []SourceSubnets`
`"source-blockchains": []SourceBlockchains`

- The list of source subnets to support. Each `SourceSubnet` has the following configuration:
- The list of source subnets to support. Each `SourceBlockchain` has the following configuration:

`"subnet-id": string`

Expand Down Expand Up @@ -175,9 +175,9 @@ The relayer is configured via a JSON file, the path to which is passed in via th

- The block height at which to back-process transactions from the source subnet. If the database already contains a later block height for the source subnet, then that will be used instead. Must be non-zero.

`"destination-subnets": []DestinationSubnets`
`"destination-blockchains": []DestinationBlockchains`

- The list of destination subnets to support. Each `DestinationSubnet` has the following configuration:
- The list of destination subnets to support. Each `DestinationBlockchain` has the following configuration:

`"subnet-id": string`

Expand Down
60 changes: 30 additions & 30 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ type ManualWarpMessage struct {
destinationAddress common.Address
}

type SourceSubnet struct {
type SourceBlockchain struct {
SubnetID string `mapstructure:"subnet-id" json:"subnet-id"`
BlockchainID string `mapstructure:"blockchain-id" json:"blockchain-id"`
VM string `mapstructure:"vm" json:"vm"`
Expand All @@ -69,7 +69,7 @@ type SourceSubnet struct {
supportedDestinations set.Set[ids.ID]
}

type DestinationSubnet struct {
type DestinationBlockchain struct {
SubnetID string `mapstructure:"subnet-id" json:"subnet-id"`
BlockchainID string `mapstructure:"blockchain-id" json:"blockchain-id"`
VM string `mapstructure:"vm" json:"vm"`
Expand All @@ -86,14 +86,14 @@ type WarpQuorum struct {
}

type Config struct {
LogLevel string `mapstructure:"log-level" json:"log-level"`
PChainAPIURL string `mapstructure:"p-chain-api-url" json:"p-chain-api-url"`
InfoAPIURL string `mapstructure:"info-api-url" json:"info-api-url"`
StorageLocation string `mapstructure:"storage-location" json:"storage-location"`
SourceSubnets []*SourceSubnet `mapstructure:"source-subnets" json:"source-subnets"`
DestinationSubnets []*DestinationSubnet `mapstructure:"destination-subnets" json:"destination-subnets"`
ProcessMissedBlocks bool `mapstructure:"process-missed-blocks" json:"process-missed-blocks"`
ManualWarpMessages []*ManualWarpMessage `mapstructure:"manual-warp-messages" json:"manual-warp-messages"`
LogLevel string `mapstructure:"log-level" json:"log-level"`
PChainAPIURL string `mapstructure:"p-chain-api-url" json:"p-chain-api-url"`
InfoAPIURL string `mapstructure:"info-api-url" json:"info-api-url"`
StorageLocation string `mapstructure:"storage-location" json:"storage-location"`
SourceBlockchains []*SourceBlockchain `mapstructure:"source-blockchains" json:"source-blockchains"`
DestinationBlockchains []*DestinationBlockchain `mapstructure:"destination-blockchains" json:"destination-blockchains"`
ProcessMissedBlocks bool `mapstructure:"process-missed-blocks" json:"process-missed-blocks"`
ManualWarpMessages []*ManualWarpMessage `mapstructure:"manual-warp-messages" json:"manual-warp-messages"`

// convenience fields to access the source subnet and chain IDs after initialization
sourceSubnetIDs []ids.ID
Expand Down Expand Up @@ -136,10 +136,10 @@ func BuildConfig(v *viper.Viper) (Config, bool, error) {
if err := v.UnmarshalKey(ManualWarpMessagesKey, &cfg.ManualWarpMessages); err != nil {
return Config{}, false, fmt.Errorf("failed to unmarshal manual warp messages: %w", err)
}
if err := v.UnmarshalKey(DestinationSubnetsKey, &cfg.DestinationSubnets); err != nil {
if err := v.UnmarshalKey(DestinationBlockchainsKey, &cfg.DestinationBlockchains); err != nil {
return Config{}, false, fmt.Errorf("failed to unmarshal destination subnets: %w", err)
}
if err := v.UnmarshalKey(SourceSubnetsKey, &cfg.SourceSubnets); err != nil {
if err := v.UnmarshalKey(SourceBlockchainsKey, &cfg.SourceBlockchains); err != nil {
return Config{}, false, fmt.Errorf("failed to unmarshal source subnets: %w", err)
}

Expand All @@ -150,19 +150,19 @@ func BuildConfig(v *viper.Viper) (Config, bool, error) {
accountPrivateKey := v.GetString(AccountPrivateKeyKey)
if accountPrivateKey != "" {
optionOverwritten = true
for i := range cfg.DestinationSubnets {
cfg.DestinationSubnets[i].AccountPrivateKey = utils.SanitizeHexString(accountPrivateKey)
for i := range cfg.DestinationBlockchains {
cfg.DestinationBlockchains[i].AccountPrivateKey = utils.SanitizeHexString(accountPrivateKey)
}
} else {
// Otherwise, check for private keys suffixed with the chain ID and set it for that subnet
// Since the key is dynamic, this is only possible through environment variables
for i, subnet := range cfg.DestinationSubnets {
for i, subnet := range cfg.DestinationBlockchains {
subnetAccountPrivateKey := os.Getenv(fmt.Sprintf("%s_%s", accountPrivateKeyEnvVarName, subnet.BlockchainID))
if subnetAccountPrivateKey != "" {
optionOverwritten = true
cfg.DestinationSubnets[i].AccountPrivateKey = utils.SanitizeHexString(subnetAccountPrivateKey)
cfg.DestinationBlockchains[i].AccountPrivateKey = utils.SanitizeHexString(subnetAccountPrivateKey)
} else {
cfg.DestinationSubnets[i].AccountPrivateKey = utils.SanitizeHexString(cfg.DestinationSubnets[i].AccountPrivateKey)
cfg.DestinationBlockchains[i].AccountPrivateKey = utils.SanitizeHexString(cfg.DestinationBlockchains[i].AccountPrivateKey)
}
}
}
Expand All @@ -178,10 +178,10 @@ func BuildConfig(v *viper.Viper) (Config, bool, error) {
// Does not modify the public fields as derived from the configuration passed to the application,
// but does initialize private fields available through getters
func (c *Config) Validate() error {
if len(c.SourceSubnets) == 0 {
if len(c.SourceBlockchains) == 0 {
return errors.New("relayer not configured to relay from any subnets. A list of source subnets must be provided in the configuration file")
}
if len(c.DestinationSubnets) == 0 {
if len(c.DestinationBlockchains) == 0 {
return errors.New("relayer not configured to relay to any subnets. A list of destination subnets must be provided in the configuration file")
}
if _, err := url.ParseRequestURI(c.PChainAPIURL); err != nil {
Expand All @@ -192,8 +192,8 @@ func (c *Config) Validate() error {
}

// Validate the destination chains
destinationChains := set.NewSet[string](len(c.DestinationSubnets))
for _, s := range c.DestinationSubnets {
destinationChains := set.NewSet[string](len(c.DestinationBlockchains))
for _, s := range c.DestinationBlockchains {
if err := s.Validate(); err != nil {
return err
}
Expand All @@ -204,10 +204,10 @@ func (c *Config) Validate() error {
}

// Validate the source chains and store the source subnet and chain IDs for future use
sourceBlockchains := set.NewSet[string](len(c.SourceSubnets))
sourceBlockchains := set.NewSet[string](len(c.SourceBlockchains))
var sourceSubnetIDs []ids.ID
var sourceBlockchainIDs []ids.ID
for _, s := range c.SourceSubnets {
for _, s := range c.SourceBlockchains {
// Validate configuration
if err := s.Validate(&destinationChains); err != nil {
return err
Expand Down Expand Up @@ -359,7 +359,7 @@ func getWarpQuorum(

func (c *Config) InitializeWarpQuorums() error {
// Fetch the Warp quorum values for each destination subnet.
for _, destinationSubnet := range c.DestinationSubnets {
for _, destinationSubnet := range c.DestinationBlockchains {
err := destinationSubnet.initializeWarpQuorum()
if err != nil {
return fmt.Errorf("failed to initialize Warp quorum for destination subnet %s: %w", destinationSubnet.SubnetID, err)
Expand All @@ -369,14 +369,14 @@ func (c *Config) InitializeWarpQuorums() error {
return nil
}

func (s *SourceSubnet) GetSupportedDestinations() set.Set[ids.ID] {
func (s *SourceBlockchain) GetSupportedDestinations() set.Set[ids.ID] {
return s.supportedDestinations
}

// Validates the source subnet configuration, including verifying that the supported destinations are present in destinationBlockchainIDs
// Does not modify the public fields as derived from the configuration passed to the application,
// but does initialize private fields available through getters
func (s *SourceSubnet) Validate(destinationBlockchainIDs *set.Set[string]) error {
func (s *SourceBlockchain) Validate(destinationBlockchainIDs *set.Set[string]) error {
if _, err := ids.FromString(s.SubnetID); err != nil {
return fmt.Errorf("invalid subnetID in source subnet configuration. Provided ID: %s", s.SubnetID)
}
Expand Down Expand Up @@ -441,7 +441,7 @@ func (s *SourceSubnet) Validate(destinationBlockchainIDs *set.Set[string]) error
}

// Validatees the destination subnet configuration
func (s *DestinationSubnet) Validate() error {
func (s *DestinationBlockchain) Validate() error {
if _, err := ids.FromString(s.SubnetID); err != nil {
return fmt.Errorf("invalid subnetID in source subnet configuration. Provided ID: %s", s.SubnetID)
}
Expand Down Expand Up @@ -469,7 +469,7 @@ func (s *DestinationSubnet) Validate() error {
return nil
}

func (s *DestinationSubnet) initializeWarpQuorum() error {
func (s *DestinationBlockchain) initializeWarpQuorum() error {
blockchainID, err := ids.FromString(s.BlockchainID)
if err != nil {
return fmt.Errorf("invalid blockchainID in configuration. error: %w", err)
Expand All @@ -494,7 +494,7 @@ func (s *DestinationSubnet) initializeWarpQuorum() error {
}

// Get the private key and derive the wallet address from a relayer's configured private key for a given destination subnet.
func (s *DestinationSubnet) GetRelayerAccountInfo() (*ecdsa.PrivateKey, common.Address, error) {
func (s *DestinationBlockchain) GetRelayerAccountInfo() (*ecdsa.PrivateKey, common.Address, error) {
pk, err := crypto.HexToECDSA(s.AccountPrivateKey)
if err != nil {
return nil, common.Address{}, err
Expand All @@ -513,7 +513,7 @@ func (c *Config) GetSourceIDs() ([]ids.ID, []ids.ID) {
}

func (c *Config) GetWarpQuorum(blockchainID ids.ID) (WarpQuorum, error) {
for _, s := range c.DestinationSubnets {
for _, s := range c.DestinationBlockchains {
if blockchainID.String() == s.BlockchainID {
return s.warpQuorum, nil
}
Expand Down
54 changes: 27 additions & 27 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var (
LogLevel: "info",
PChainAPIURL: "http://test.avax.network",
InfoAPIURL: "http://test.avax.network",
SourceSubnets: []*SourceSubnet{
SourceBlockchains: []*SourceBlockchain{
{
RPCEndpoint: fmt.Sprintf("http://test.avax.network/ext/bc/%s/rpc", testBlockchainID),
WSEndpoint: fmt.Sprintf("ws://test.avax.network/ext/bc/%s/ws", testBlockchainID),
Expand All @@ -47,7 +47,7 @@ var (
},
},
},
DestinationSubnets: []*DestinationSubnet{
DestinationBlockchains: []*DestinationBlockchain{
{
RPCEndpoint: fmt.Sprintf("http://test.avax.network/ext/bc/%s/rpc", testBlockchainID),
BlockchainID: testBlockchainID,
Expand All @@ -70,12 +70,12 @@ func TestGetRelayerAccountInfo(t *testing.T) {

testCases := []struct {
name string
s DestinationSubnet
s DestinationBlockchain
expectedResult retStruct
}{
{
name: "valid",
s: DestinationSubnet{
s: DestinationBlockchain{
AccountPrivateKey: "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027",
},
expectedResult: retStruct{
Expand All @@ -88,7 +88,7 @@ func TestGetRelayerAccountInfo(t *testing.T) {
},
{
name: "invalid 0x prefix",
s: DestinationSubnet{
s: DestinationBlockchain{
AccountPrivateKey: "0x56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027",
},
expectedResult: retStruct{
Expand All @@ -101,7 +101,7 @@ func TestGetRelayerAccountInfo(t *testing.T) {
},
{
name: "invalid private key",
s: DestinationSubnet{
s: DestinationBlockchain{
AccountPrivateKey: "invalid56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027",
},
expectedResult: retStruct{
Expand Down Expand Up @@ -168,9 +168,9 @@ func TestGetRelayerAccountPrivateKey_set_pk_in_config(t *testing.T) {
expectedOverwritten: false,
resultVerifier: func(c Config) bool {
// All destination subnets should have the default private key
for i, subnet := range c.DestinationSubnets {
if subnet.AccountPrivateKey != utils.SanitizeHexString(testValidConfig.DestinationSubnets[i].AccountPrivateKey) {
fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testValidConfig.DestinationSubnets[i].AccountPrivateKey), subnet.AccountPrivateKey)
for i, subnet := range c.DestinationBlockchains {
if subnet.AccountPrivateKey != utils.SanitizeHexString(testValidConfig.DestinationBlockchains[i].AccountPrivateKey) {
fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testValidConfig.DestinationBlockchains[i].AccountPrivateKey), subnet.AccountPrivateKey)
return false
}
}
Expand All @@ -185,26 +185,26 @@ func TestGetRelayerAccountPrivateKey_set_pk_with_subnet_env(t *testing.T) {
baseConfig: testValidConfig,
configModifier: func(c Config) Config {
// Add a second destination subnet. This PK should NOT be overwritten
newSubnet := *c.DestinationSubnets[0]
newSubnet := *c.DestinationBlockchains[0]
newSubnet.BlockchainID = testBlockchainID2
newSubnet.AccountPrivateKey = testPk1
c.DestinationSubnets = append(c.DestinationSubnets, &newSubnet)
c.DestinationBlockchains = append(c.DestinationBlockchains, &newSubnet)
return c
},
envSetter: func() {
// Overwrite the PK for the first subnet using an env var
varName := fmt.Sprintf("%s_%s", accountPrivateKeyEnvVarName, testValidConfig.DestinationSubnets[0].BlockchainID)
varName := fmt.Sprintf("%s_%s", accountPrivateKeyEnvVarName, testValidConfig.DestinationBlockchains[0].BlockchainID)
t.Setenv(varName, testPk2)
},
expectedOverwritten: true,
resultVerifier: func(c Config) bool {
// All destination subnets should have testPk1
if c.DestinationSubnets[0].AccountPrivateKey != utils.SanitizeHexString(testPk2) {
fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testPk2), c.DestinationSubnets[0].AccountPrivateKey)
if c.DestinationBlockchains[0].AccountPrivateKey != utils.SanitizeHexString(testPk2) {
fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testPk2), c.DestinationBlockchains[0].AccountPrivateKey)
return false
}
if c.DestinationSubnets[1].AccountPrivateKey != utils.SanitizeHexString(testPk1) {
fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testPk1), c.DestinationSubnets[1].AccountPrivateKey)
if c.DestinationBlockchains[1].AccountPrivateKey != utils.SanitizeHexString(testPk1) {
fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testPk1), c.DestinationBlockchains[1].AccountPrivateKey)
return false
}
return true
Expand All @@ -217,10 +217,10 @@ func TestGetRelayerAccountPrivateKey_set_pk_with_global_env(t *testing.T) {
baseConfig: testValidConfig,
configModifier: func(c Config) Config {
// Add a second destination subnet. This PK SHOULD be overwritten
newSubnet := *c.DestinationSubnets[0]
newSubnet := *c.DestinationBlockchains[0]
newSubnet.BlockchainID = testBlockchainID2
newSubnet.AccountPrivateKey = testPk1
c.DestinationSubnets = append(c.DestinationSubnets, &newSubnet)
c.DestinationBlockchains = append(c.DestinationBlockchains, &newSubnet)
return c
},
envSetter: func() {
Expand All @@ -230,7 +230,7 @@ func TestGetRelayerAccountPrivateKey_set_pk_with_global_env(t *testing.T) {
expectedOverwritten: true,
resultVerifier: func(c Config) bool {
// All destination subnets should have testPk2
for _, subnet := range c.DestinationSubnets {
for _, subnet := range c.DestinationBlockchains {
if subnet.AccountPrivateKey != utils.SanitizeHexString(testPk2) {
fmt.Printf("expected: %s, got: %s\n", utils.SanitizeHexString(testPk2), subnet.AccountPrivateKey)
return false
Expand All @@ -253,7 +253,7 @@ func TestGetRelayerAccountInfoSkipChainConfigCheckCompatible(t *testing.T) {
accountPrivateKey := "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027"
expectedAddress := "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"

info := DestinationSubnet{
info := DestinationBlockchain{
AccountPrivateKey: accountPrivateKey,
}
_, address, err := info.GetRelayerAccountInfo()
Expand Down Expand Up @@ -388,8 +388,8 @@ func TestGetWarpQuorum(t *testing.T) {
}
}

func TestValidateSourceSubnet(t *testing.T) {
validSourceCfg := SourceSubnet{
func TestValidateSourceBlockchain(t *testing.T) {
validSourceCfg := SourceBlockchain{
BlockchainID: testBlockchainID,
RPCEndpoint: fmt.Sprintf("http://test.avax.network/ext/bc/%s/rpc", testBlockchainID),
WSEndpoint: fmt.Sprintf("ws://test.avax.network/ext/bc/%s/ws", testBlockchainID),
Expand All @@ -404,21 +404,21 @@ func TestValidateSourceSubnet(t *testing.T) {
}
testCases := []struct {
name string
sourceSubnet func() SourceSubnet
sourceSubnet func() SourceBlockchain
destinationBlockchainIDs []string
expectError bool
expectedSupportedDestinations []string
}{
{
name: "valid source subnet; explicitly supported destination",
sourceSubnet: func() SourceSubnet { return validSourceCfg },
sourceSubnet: func() SourceBlockchain { return validSourceCfg },
destinationBlockchainIDs: []string{testBlockchainID},
expectError: false,
expectedSupportedDestinations: []string{testBlockchainID},
},
{
name: "valid source subnet; implicitly supported destination",
sourceSubnet: func() SourceSubnet {
sourceSubnet: func() SourceBlockchain {
cfg := validSourceCfg
cfg.SupportedDestinations = nil
return cfg
Expand All @@ -429,14 +429,14 @@ func TestValidateSourceSubnet(t *testing.T) {
},
{
name: "valid source subnet; partially supported destinations",
sourceSubnet: func() SourceSubnet { return validSourceCfg },
sourceSubnet: func() SourceBlockchain { return validSourceCfg },
destinationBlockchainIDs: []string{testBlockchainID, testBlockchainID2},
expectError: false,
expectedSupportedDestinations: []string{testBlockchainID},
},
{
name: "valid source subnet; unsupported destinations",
sourceSubnet: func() SourceSubnet { return validSourceCfg },
sourceSubnet: func() SourceBlockchain { return validSourceCfg },
destinationBlockchainIDs: []string{testBlockchainID2},
expectError: true,
expectedSupportedDestinations: []string{},
Expand Down
Loading

0 comments on commit 2b0017a

Please sign in to comment.