Skip to content

Commit

Permalink
update: factory register
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianToledano committed Oct 17, 2024
1 parent b33e5a2 commit c13fe79
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 15 deletions.
52 changes: 39 additions & 13 deletions client/v2/internal/broadcast/broadcaster.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,55 @@ type (
// It returns a byte slice containing the formatted result that will be
// passed to the output writer, and an error if the broadcast failed.
Broadcast(ctx context.Context, txBytes []byte) ([]byte, error)

// Consensus returns the consensus engine identifier for this Broadcaster.
Consensus() string
}

// factory defines a generic interface for creating a Broadcaster.
factory interface {
// create creates a new Broadcaster instance based on the consensus type.
create(ctx context.Context, consensus, url string, opts ...Option) (Broadcaster, error)
// NewBroadcasterFn is a function type for creating Broadcaster instances.
NewBroadcasterFn func(url string, opts ...Option) (Broadcaster, error)

// BroadcasterFactory defines an interface for creating and registering Broadcasters.
BroadcasterFactory interface {
// Register adds a new BroadcasterCreator for a given consensus type to the factory.
Register(consensus string, creator NewBroadcasterFn)
// Create instantiates a new Broadcaster based on the given consensus type, URL, and options.
// It returns the created Broadcaster and any error encountered during creation.
Create(ctx context.Context, consensus, url string, opts ...Option) (Broadcaster, error)
}

// Option is a function that configures a Broadcaster.
Option func(Broadcaster)
)

var _ factory = broadcasterFactory{}
var _ BroadcasterFactory = Factory{}

// broadcasterFactory is a factory for creating Broadcaster instances.
type broadcasterFactory struct{}
// Factory is a factory for creating Broadcaster instances.
type Factory struct {
engines map[string]NewBroadcasterFn
}

// create creates a new Broadcaster based on the given consensus type.
func (f broadcasterFactory) create(_ context.Context, consensus, url string, opts ...Option) (Broadcaster, error) {
switch consensus {
case cometBFTConsensus:
return NewCometBFTBroadcaster(url, opts...)
default:
// Create creates a new Broadcaster based on the given consensus type.
func (f Factory) Create(_ context.Context, consensus, url string, opts ...Option) (Broadcaster, error) {
creator, ok := f.engines[consensus]
if !ok {
return nil, fmt.Errorf("invalid consensus type: %s", consensus)
}
return creator(url, opts...)
}

// Register adds a new BroadcasterCreator for a given consensus type to the factory.
func (f Factory) Register(consensus string, creator NewBroadcasterFn) {
f.engines[consensus] = creator
}

// NewFactory creates and returns a new Factory instance with a default CometBFT broadcaster.
func NewFactory() Factory {
return Factory{
engines: map[string]NewBroadcasterFn{
cometBFTConsensus: func(url string, opts ...Option) (Broadcaster, error) {
return NewCometBFTBroadcaster(url, opts...)
},
},
}
}
41 changes: 40 additions & 1 deletion client/v2/internal/broadcast/broadcaster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,18 @@ import (
"github.com/stretchr/testify/require"
)

type testBFT struct{}

func (t testBFT) Broadcast(_ context.Context, _ []byte) ([]byte, error) {
return nil, nil
}

func (t testBFT) Consensus() string {
return "testBFT"
}

func Test_newBroadcaster(t *testing.T) {
f := NewFactory()
tests := []struct {
name string
consensus string
Expand All @@ -31,7 +42,7 @@ func Test_newBroadcaster(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := broadcasterFactory{}.create(context.Background(), tt.consensus, "localhost:26657", tt.opts...)
got, err := f.Create(context.Background(), tt.consensus, "localhost:26657", tt.opts...)
if tt.wantErr {
require.Error(t, err)
} else {
Expand All @@ -42,3 +53,31 @@ func Test_newBroadcaster(t *testing.T) {
})
}
}

func TestFactory_Register(t *testing.T) {
tests := []struct {
name string
consensus string
creator NewBroadcasterFn
}{
{
name: "register new broadcaster",
consensus: "testBFT",
creator: func(url string, opts ...Option) (Broadcaster, error) {
return testBFT{}, nil
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := NewFactory()
f.Register(tt.consensus, tt.creator)

b, err := f.Create(context.Background(), tt.consensus, "localhost:26657")
require.NoError(t, err)
require.NotNil(t, b)

require.Equal(t, tt.consensus, b.Consensus())
})
}
}
6 changes: 5 additions & 1 deletion client/v2/internal/broadcast/comet.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type CometRPC interface {

var _ Broadcaster = CometBFTBroadcaster{}

// CometBftBroadcaster implements the Broadcaster interface for CometBFT consensus engine.
// CometBFTBroadcaster implements the Broadcaster interface for CometBFT consensus engine.
type CometBFTBroadcaster struct {
rpcClient CometRPC
mode string
Expand Down Expand Up @@ -91,6 +91,10 @@ func NewCometBFTBroadcaster(rpcURL string, opts ...Option) (*CometBFTBroadcaster
return bc, nil
}

func (c CometBFTBroadcaster) Consensus() string {
return cometBFTConsensus
}

// Broadcast sends a transaction to the network and returns the result.
// returns a byte slice containing the JSON-encoded result and an error if the broadcast failed.
func (c CometBFTBroadcaster) Broadcast(ctx context.Context, txBytes []byte) ([]byte, error) {
Expand Down

0 comments on commit c13fe79

Please sign in to comment.