diff --git a/da/registry/registry.go b/da/registry/registry.go index 0279f316e26..4e9a1a92e9e 100644 --- a/da/registry/registry.go +++ b/da/registry/registry.go @@ -1,12 +1,23 @@ package registry import ( + "fmt" + "github.com/rollkit/rollkit/da" "github.com/rollkit/rollkit/da/celestia" "github.com/rollkit/rollkit/da/grpc" "github.com/rollkit/rollkit/da/mock" ) +// ErrAlreadyRegistered is used when user tries to register DA using a name already used in registry. +type ErrAlreadyRegistered struct { + name string +} + +func (e *ErrAlreadyRegistered) Error() string { + return fmt.Sprintf("Data Availability Layer '%s' already registered", e.name) +} + // this is a central registry for all Data Availability Layer Clients var clients = map[string]func() da.DataAvailabilityLayerClient{ "mock": func() da.DataAvailabilityLayerClient { return &mock.DataAvailabilityLayerClient{} }, @@ -23,6 +34,17 @@ func GetClient(name string) da.DataAvailabilityLayerClient { return f() } +// Register adds a Data Availability Layer Client to registry. +// +// If name was previously used in the registry, error is returned. +func Register(name string, constructor func() da.DataAvailabilityLayerClient) error { + if _, found := clients[name]; !found { + clients[name] = constructor + return nil + } + return &ErrAlreadyRegistered{name: name} +} + // RegisteredClients returns names of all DA clients in registry. func RegisteredClients() []string { registered := make([]string, 0, len(clients)) diff --git a/da/registry/registry_test.go b/da/registry/registry_test.go index 0eb8d00cfeb..a5f6f3ce77e 100644 --- a/da/registry/registry_test.go +++ b/da/registry/registry_test.go @@ -4,6 +4,9 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "github.com/rollkit/rollkit/da" + "github.com/rollkit/rollkit/da/mock" ) func TestRegistery(t *testing.T) { @@ -14,7 +17,21 @@ func TestRegistery(t *testing.T) { assert.ElementsMatch(expected, actual) - for _, e := range expected { + constructor := func() da.DataAvailabilityLayerClient { + return &mock.DataAvailabilityLayerClient{} // cheating, only for tests :D + } + err := Register("testDA", constructor) + assert.NoError(err) + + // re-registration should fail + err = Register("celestia", constructor) + regErr := &ErrAlreadyRegistered{} + assert.ErrorAs(err, ®Err) + assert.Equal("celestia", regErr.name) + + assert.Contains(RegisteredClients(), "testDA") + + for _, e := range RegisteredClients() { dalc := GetClient(e) assert.NotNil(dalc) }