From cb00e037d508a415f9a87394b5b2048b26120c4f Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Wed, 16 Oct 2024 17:58:55 +0200 Subject: [PATCH 01/18] add: broadcast logic --- client/v2/go.mod | 11 +- client/v2/go.sum | 6 +- client/v2/internal/broadcast/broadcaster.go | 51 ++++ .../v2/internal/broadcast/broadcaster_test.go | 39 +++ client/v2/internal/broadcast/comet.go | 155 ++++++++++ client/v2/internal/broadcast/comet_test.go | 131 ++++++++ .../internal/broadcast/testutil/comet_mock.go | 284 ++++++++++++++++++ simapp/go.mod | 2 +- simapp/go.sum | 4 +- 9 files changed, 676 insertions(+), 7 deletions(-) create mode 100644 client/v2/internal/broadcast/broadcaster.go create mode 100644 client/v2/internal/broadcast/broadcaster_test.go create mode 100644 client/v2/internal/broadcast/comet.go create mode 100644 client/v2/internal/broadcast/comet_test.go create mode 100644 client/v2/internal/broadcast/testutil/comet_mock.go diff --git a/client/v2/go.mod b/client/v2/go.mod index a55b13e882d0..79f05be494b6 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -6,6 +6,8 @@ require ( cosmossdk.io/api v0.7.6 cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 + cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 + cosmossdk.io/server/v2/cometbft v0.0.0-20241015140036-ee3d320eaa55 cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a cosmossdk.io/x/tx v0.13.3 @@ -13,6 +15,7 @@ require ( github.com/cosmos/cosmos-sdk v0.53.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 + go.uber.org/mock v0.4.0 google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.35.1 gotest.tools/v3 v3.5.1 @@ -27,7 +30,7 @@ require ( cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.4.1 // indirect cosmossdk.io/math v1.3.0 - cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect + cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac // indirect cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -47,7 +50,7 @@ require ( github.com/cockroachdb/pebble v1.1.2 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v1.0.0-rc1.0.20240908111210-ab0be101882f // indirect + github.com/cometbft/cometbft v1.0.0-rc1.0.20240908111210-ab0be101882f github.com/cometbft/cometbft-db v0.15.0 // indirect github.com/cometbft/cometbft/api v1.0.0-rc.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect @@ -175,8 +178,12 @@ replace github.com/cosmos/cosmos-sdk => ./../../ // TODO remove post spinning out all modules replace ( cosmossdk.io/api => ./../../api + cosmossdk.io/server/v2 => ./../../server/v2 + cosmossdk.io/server/v2/cometbft => ./../../server/v2/cometbft cosmossdk.io/store => ./../../store + cosmossdk.io/store/v2 => ./../../store/v2 cosmossdk.io/x/bank => ./../../x/bank + cosmossdk.io/x/consensus => ./../../x/consensus cosmossdk.io/x/gov => ./../../x/gov cosmossdk.io/x/staking => ./../../x/staking cosmossdk.io/x/tx => ./../../x/tx diff --git a/client/v2/go.sum b/client/v2/go.sum index e9b07cd27b81..100300c73e31 100644 --- a/client/v2/go.sum +++ b/client/v2/go.sum @@ -14,12 +14,14 @@ cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= cosmossdk.io/depinject v1.0.0/go.mod h1:zxK/h3HgHoA/eJVtiSsoaRaRA2D5U4cJ5thIG4ssbB8= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= +cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 h1:IQNdY2kB+k+1OM2DvqFG1+UgeU1JzZrWtwuWzI3ZfwA= +cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5/go.mod h1:0CuYKkFHxc1vw2JC+t21THBCALJVROrWVR/3PQ1urpc= cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= -cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac h1:3joNZZWZ3k7fMsrBDL1ktuQ2xQwYLZOaDhkruadDFmc= +cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o= cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190/go.mod h1:7WUGupOvmlHJoIMBz1JbObQxeo6/TDiuDBxmtod8HRg= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= diff --git a/client/v2/internal/broadcast/broadcaster.go b/client/v2/internal/broadcast/broadcaster.go new file mode 100644 index 000000000000..bea2677d1e43 --- /dev/null +++ b/client/v2/internal/broadcast/broadcaster.go @@ -0,0 +1,51 @@ +package broadcast + +import ( + "context" + "fmt" +) + +const ( + // BroadcastSync defines a tx broadcasting mode where the client waits for + // a CheckTx execution response only. + BroadcastSync = "sync" + // BroadcastAsync defines a tx broadcasting mode where the client returns + // immediately. + BroadcastAsync = "async" + + // cometBftConsensus is the identifier for the CometBFT consensus engine. + cometBftConsensus = "comet" +) + +type ( + // Broadcaster defines an interface for broadcasting transactions to the consensus engine. + Broadcaster interface { + // Broadcast sends a transaction to the network and returns the result. + // + // 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) + } + + // factory defines a generic interface for creating a Broadcaster. + factory interface { + // Create creates a new Broadcaster instance of type T. + create(ctx context.Context, consensus, url string, opts ...Option) (Broadcaster, error) + } + + // Option is a function that configures a Broadcaster. + Option func(Broadcaster) +) + +// broadcasterFactory is a factory for creating Broadcaster instances. +type broadcasterFactory struct{} + +// 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: + return nil, fmt.Errorf("invalid consensus type: %s", consensus) + } +} diff --git a/client/v2/internal/broadcast/broadcaster_test.go b/client/v2/internal/broadcast/broadcaster_test.go new file mode 100644 index 000000000000..81e061bc1d47 --- /dev/null +++ b/client/v2/internal/broadcast/broadcaster_test.go @@ -0,0 +1,39 @@ +package broadcast + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_newBroadcaster(t *testing.T) { + tests := []struct { + name string + consensus string + opts []Option + want Broadcaster + wantErr bool + }{ + { + name: "comet", + consensus: "comet", + opts: []Option{ + withMode(BroadcastSync), + }, + want: &CometBftBroadcaster{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := broadcasterFactory{}.create(context.Background(), tt.consensus, "localhost:26657", tt.opts...) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.NotNil(t, got) + require.IsType(t, tt.want, got) + } + }) + } +} diff --git a/client/v2/internal/broadcast/comet.go b/client/v2/internal/broadcast/comet.go new file mode 100644 index 000000000000..c562a697726e --- /dev/null +++ b/client/v2/internal/broadcast/comet.go @@ -0,0 +1,155 @@ +package broadcast + +import ( + "context" + "encoding/json" + "fmt" + "github.com/cometbft/cometbft/mempool" + rpchttp "github.com/cometbft/cometbft/rpc/client/http" + coretypes "github.com/cometbft/cometbft/rpc/core/types" + cmttypes "github.com/cometbft/cometbft/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "strings" + + apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" + serverrpc "cosmossdk.io/server/v2/cometbft/client/rpc" + + "github.com/cosmos/cosmos-sdk/codec" +) + +// CometBftBroadcaster implements the Broadcaster interface for CometBFT consensus engine. +type CometBftBroadcaster struct { + rpcClient serverrpc.CometRPC + mode string + cdc codec.JSONCodec +} + +func withMode(mode string) func(broadcaster Broadcaster) { + return func(b Broadcaster) { + cbc, ok := b.(*CometBftBroadcaster) + if !ok { + return + } + cbc.mode = mode + } +} + +func withJsonCodec(codec codec.JSONCodec) func(broadcaster Broadcaster) { + return func(b Broadcaster) { + cbc, ok := b.(*CometBftBroadcaster) + if !ok { + return + } + cbc.cdc = codec + } +} + +// NewCometBftBroadcaster creates a new CometBftBroadcaster. +func NewCometBftBroadcaster(rpcURL string, opts ...Option) (*CometBftBroadcaster, error) { + rpcClient, err := rpchttp.New(rpcURL) + if err != nil { + return nil, fmt.Errorf("failed to create CometBft RPC client: %w", err) + } + + bc := &CometBftBroadcaster{} + for _, opt := range opts { + opt(bc) + } + + bc.rpcClient = *rpcClient + return bc, nil +} + +// 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) { + var fn func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error) + switch c.mode { + case BroadcastSync: + fn = c.rpcClient.BroadcastTxSync + case BroadcastAsync: + fn = c.rpcClient.BroadcastTxAsync + default: + return []byte{}, fmt.Errorf("unknown broadcast mode: %s", c.mode) + } + + res, err := c.broadcast(ctx, txBytes, fn) + if err != nil { + return []byte{}, err + } + + return c.cdc.MarshalJSON(res) +} + +// broadcast sends a transaction to the CometBFT network using the provided function. +func (c CometBftBroadcaster) broadcast(ctx context.Context, txbytes []byte, + fn func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error)) (*apiacbci.TxResponse, error) { + bResult, err := fn(ctx, txbytes) + if errRes := checkCometError(err, txbytes); err != nil { + return errRes, nil + } + + return newResponseFormatBroadcastTx(bResult), err +} + +// checkCometError checks for errors returned by the CometBFT network and returns an appropriate TxResponse. +// It extracts error information and constructs a TxResponse with the error details. +func checkCometError(err error, tx cmttypes.Tx) *apiacbci.TxResponse { + if err == nil { + return nil + } + + errStr := strings.ToLower(err.Error()) + txHash := fmt.Sprintf("%X", tx.Hash()) + + switch { + case strings.Contains(errStr, strings.ToLower(mempool.ErrTxInCache.Error())): + return &apiacbci.TxResponse{ + Code: sdkerrors.ErrTxInMempoolCache.ABCICode(), + Codespace: sdkerrors.ErrTxInMempoolCache.Codespace(), + Txhash: txHash, + } + + case strings.Contains(errStr, "mempool is full"): + return &apiacbci.TxResponse{ + Code: sdkerrors.ErrMempoolIsFull.ABCICode(), + Codespace: sdkerrors.ErrMempoolIsFull.Codespace(), + Txhash: txHash, + } + + case strings.Contains(errStr, "tx too large"): + return &apiacbci.TxResponse{ + Code: sdkerrors.ErrTxTooLarge.ABCICode(), + Codespace: sdkerrors.ErrTxTooLarge.Codespace(), + Txhash: txHash, + } + + default: + return nil + } +} + +// newResponseFormatBroadcastTx returns a TxResponse given a ResultBroadcastTx from cometbft +func newResponseFormatBroadcastTx(res *coretypes.ResultBroadcastTx) *apiacbci.TxResponse { + if res == nil { + return nil + } + + parsedLogs, _ := parseABCILogs(res.Log) + + return &apiacbci.TxResponse{ + Code: res.Code, + Codespace: res.Codespace, + Data: res.Data.String(), + RawLog: res.Log, + Logs: parsedLogs, + Txhash: res.Hash.String(), + } +} + +// parseABCILogs attempts to parse a stringified ABCI tx log into a slice of +// ABCIMessageLog types. It returns an error upon JSON decoding failure. +func parseABCILogs(logs string) (res []*apiacbci.ABCIMessageLog, err error) { + err = json.Unmarshal([]byte(logs), &res) + return res, err +} diff --git a/client/v2/internal/broadcast/comet_test.go b/client/v2/internal/broadcast/comet_test.go new file mode 100644 index 000000000000..e52aa51a9f29 --- /dev/null +++ b/client/v2/internal/broadcast/comet_test.go @@ -0,0 +1,131 @@ +package broadcast + +import ( + "context" + apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" + "errors" + "github.com/cometbft/cometbft/mempool" + coretypes "github.com/cometbft/cometbft/rpc/core/types" + "github.com/cometbft/cometbft/types" + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + + mockrpc "cosmossdk.io/client/v2/internal/broadcast/testutil" + + "github.com/cosmos/cosmos-sdk/codec/testutil" +) + +var cdc = testutil.CodecOptions{}.NewCodec() + +func TestNewCometBftBroadcaster(t *testing.T) { + tests := []struct { + name string + opts []Option + want *CometBftBroadcaster + wantErr bool + }{ + { + name: "constructor", + opts: []Option{ + withMode(BroadcastSync), + withJsonCodec(cdc), + }, + want: &CometBftBroadcaster{ + mode: BroadcastSync, + cdc: cdc, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewCometBftBroadcaster("localhost:26657", tt.opts...) + if (err != nil) != tt.wantErr { + t.Errorf("NewCometBftBroadcaster() error = %v, wantErr %v", err, tt.wantErr) + return + } + require.Equal(t, got.mode, tt.want.mode) + require.Equal(t, got.cdc, tt.want.cdc) + }) + } +} + +func TestCometBftBroadcaster_Broadcast(t *testing.T) { + ctrl := gomock.NewController(t) + cometMock := mockrpc.NewMockCometRPC(ctrl) + c := CometBftBroadcaster{ + rpcClient: cometMock, + mode: BroadcastSync, + cdc: cdc, + } + tests := []struct { + name string + mode string + want []byte + wantErr bool + }{ + { + name: "sync", + mode: BroadcastSync, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c.mode = tt.mode + cometMock.EXPECT().BroadcastTxSync(context.Background(), gomock.Any()).Return(&coretypes.ResultBroadcastTx{ + Code: 0, + Data: []byte{}, + Log: "", + Codespace: "", + Hash: []byte("%�����\u0010\n�T�\u0017\u0016�N^H[5�\u0006}�n�w�/Vi� "), + }, nil) + got, err := c.Broadcast(context.Background(), []byte{}) + if (err != nil) != tt.wantErr { + t.Errorf("Broadcast() error = %v, wantErr %v", err, tt.wantErr) + return + } + require.NotNil(t, got) + }) + } +} + +func Test_checkCometError(t *testing.T) { + type args struct { + err error + tx types.Tx + } + tests := []struct { + name string + err error + want *apiacbci.TxResponse + }{ + { + name: "error in cache", + err: errors.New("tx already exists in cache"), + want: &apiacbci.TxResponse{ + Code: 19, + }, + }, + { + name: "error in cache", + err: mempool.ErrMempoolIsFull{}, + want: &apiacbci.TxResponse{ + Code: 20, + }, + }, + { + name: "error in cache", + err: mempool.ErrTxTooLarge{10, 11}, + want: &apiacbci.TxResponse{ + Code: 21, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := checkCometError(tt.err, []byte{}) + require.Equal(t, got.Code, tt.want.Code) + }) + } +} diff --git a/client/v2/internal/broadcast/testutil/comet_mock.go b/client/v2/internal/broadcast/testutil/comet_mock.go new file mode 100644 index 000000000000..0442b9a925bc --- /dev/null +++ b/client/v2/internal/broadcast/testutil/comet_mock.go @@ -0,0 +1,284 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: server/v2/cometbft/client/rpc/client.go +// +// Generated by this command: +// +// mockgen -source=server/v2/cometbft/client/rpc/client.go +// + +// Package mock_rpc is a generated GoMock package. +package mock_rpc + +import ( + context "context" + reflect "reflect" + + bytes "github.com/cometbft/cometbft/libs/bytes" + client "github.com/cometbft/cometbft/rpc/client" + types "github.com/cometbft/cometbft/rpc/core/types" + types0 "github.com/cometbft/cometbft/types" + gomock "go.uber.org/mock/gomock" +) + +// MockCometRPC is a mock of CometRPC interface. +type MockCometRPC struct { + ctrl *gomock.Controller + recorder *MockCometRPCMockRecorder +} + +// MockCometRPCMockRecorder is the mock recorder for MockCometRPC. +type MockCometRPCMockRecorder struct { + mock *MockCometRPC +} + +// NewMockCometRPC creates a new mock instance. +func NewMockCometRPC(ctrl *gomock.Controller) *MockCometRPC { + mock := &MockCometRPC{ctrl: ctrl} + mock.recorder = &MockCometRPCMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCometRPC) EXPECT() *MockCometRPCMockRecorder { + return m.recorder +} + +// ABCIInfo mocks base method. +func (m *MockCometRPC) ABCIInfo(ctx context.Context) (*types.ResultABCIInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ABCIInfo", ctx) + ret0, _ := ret[0].(*types.ResultABCIInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ABCIInfo indicates an expected call of ABCIInfo. +func (mr *MockCometRPCMockRecorder) ABCIInfo(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ABCIInfo", reflect.TypeOf((*MockCometRPC)(nil).ABCIInfo), ctx) +} + +// ABCIQuery mocks base method. +func (m *MockCometRPC) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*types.ResultABCIQuery, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ABCIQuery", ctx, path, data) + ret0, _ := ret[0].(*types.ResultABCIQuery) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ABCIQuery indicates an expected call of ABCIQuery. +func (mr *MockCometRPCMockRecorder) ABCIQuery(ctx, path, data any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ABCIQuery", reflect.TypeOf((*MockCometRPC)(nil).ABCIQuery), ctx, path, data) +} + +// ABCIQueryWithOptions mocks base method. +func (m *MockCometRPC) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*types.ResultABCIQuery, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ABCIQueryWithOptions", ctx, path, data, opts) + ret0, _ := ret[0].(*types.ResultABCIQuery) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ABCIQueryWithOptions indicates an expected call of ABCIQueryWithOptions. +func (mr *MockCometRPCMockRecorder) ABCIQueryWithOptions(ctx, path, data, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ABCIQueryWithOptions", reflect.TypeOf((*MockCometRPC)(nil).ABCIQueryWithOptions), ctx, path, data, opts) +} + +// Block mocks base method. +func (m *MockCometRPC) Block(ctx context.Context, height *int64) (*types.ResultBlock, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Block", ctx, height) + ret0, _ := ret[0].(*types.ResultBlock) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Block indicates an expected call of Block. +func (mr *MockCometRPCMockRecorder) Block(ctx, height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Block", reflect.TypeOf((*MockCometRPC)(nil).Block), ctx, height) +} + +// BlockByHash mocks base method. +func (m *MockCometRPC) BlockByHash(ctx context.Context, hash []byte) (*types.ResultBlock, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BlockByHash", ctx, hash) + ret0, _ := ret[0].(*types.ResultBlock) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BlockByHash indicates an expected call of BlockByHash. +func (mr *MockCometRPCMockRecorder) BlockByHash(ctx, hash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByHash", reflect.TypeOf((*MockCometRPC)(nil).BlockByHash), ctx, hash) +} + +// BlockResults mocks base method. +func (m *MockCometRPC) BlockResults(ctx context.Context, height *int64) (*types.ResultBlockResults, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BlockResults", ctx, height) + ret0, _ := ret[0].(*types.ResultBlockResults) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BlockResults indicates an expected call of BlockResults. +func (mr *MockCometRPCMockRecorder) BlockResults(ctx, height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockResults", reflect.TypeOf((*MockCometRPC)(nil).BlockResults), ctx, height) +} + +// BlockSearch mocks base method. +func (m *MockCometRPC) BlockSearch(ctx context.Context, query string, page, perPage *int, orderBy string) (*types.ResultBlockSearch, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BlockSearch", ctx, query, page, perPage, orderBy) + ret0, _ := ret[0].(*types.ResultBlockSearch) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BlockSearch indicates an expected call of BlockSearch. +func (mr *MockCometRPCMockRecorder) BlockSearch(ctx, query, page, perPage, orderBy any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockSearch", reflect.TypeOf((*MockCometRPC)(nil).BlockSearch), ctx, query, page, perPage, orderBy) +} + +// BlockchainInfo mocks base method. +func (m *MockCometRPC) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*types.ResultBlockchainInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BlockchainInfo", ctx, minHeight, maxHeight) + ret0, _ := ret[0].(*types.ResultBlockchainInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BlockchainInfo indicates an expected call of BlockchainInfo. +func (mr *MockCometRPCMockRecorder) BlockchainInfo(ctx, minHeight, maxHeight any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockchainInfo", reflect.TypeOf((*MockCometRPC)(nil).BlockchainInfo), ctx, minHeight, maxHeight) +} + +// BroadcastTxAsync mocks base method. +func (m *MockCometRPC) BroadcastTxAsync(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BroadcastTxAsync", ctx, tx) + ret0, _ := ret[0].(*types.ResultBroadcastTx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BroadcastTxAsync indicates an expected call of BroadcastTxAsync. +func (mr *MockCometRPCMockRecorder) BroadcastTxAsync(ctx, tx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BroadcastTxAsync", reflect.TypeOf((*MockCometRPC)(nil).BroadcastTxAsync), ctx, tx) +} + +// BroadcastTxCommit mocks base method. +func (m *MockCometRPC) BroadcastTxCommit(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTxCommit, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BroadcastTxCommit", ctx, tx) + ret0, _ := ret[0].(*types.ResultBroadcastTxCommit) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BroadcastTxCommit indicates an expected call of BroadcastTxCommit. +func (mr *MockCometRPCMockRecorder) BroadcastTxCommit(ctx, tx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BroadcastTxCommit", reflect.TypeOf((*MockCometRPC)(nil).BroadcastTxCommit), ctx, tx) +} + +// BroadcastTxSync mocks base method. +func (m *MockCometRPC) BroadcastTxSync(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BroadcastTxSync", ctx, tx) + ret0, _ := ret[0].(*types.ResultBroadcastTx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BroadcastTxSync indicates an expected call of BroadcastTxSync. +func (mr *MockCometRPCMockRecorder) BroadcastTxSync(ctx, tx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BroadcastTxSync", reflect.TypeOf((*MockCometRPC)(nil).BroadcastTxSync), ctx, tx) +} + +// Commit mocks base method. +func (m *MockCometRPC) Commit(ctx context.Context, height *int64) (*types.ResultCommit, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Commit", ctx, height) + ret0, _ := ret[0].(*types.ResultCommit) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Commit indicates an expected call of Commit. +func (mr *MockCometRPCMockRecorder) Commit(ctx, height any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockCometRPC)(nil).Commit), ctx, height) +} + +// Status mocks base method. +func (m *MockCometRPC) Status(arg0 context.Context) (*types.ResultStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Status", arg0) + ret0, _ := ret[0].(*types.ResultStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Status indicates an expected call of Status. +func (mr *MockCometRPCMockRecorder) Status(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Status", reflect.TypeOf((*MockCometRPC)(nil).Status), arg0) +} + +// Tx mocks base method. +func (m *MockCometRPC) Tx(ctx context.Context, hash []byte, prove bool) (*types.ResultTx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Tx", ctx, hash, prove) + ret0, _ := ret[0].(*types.ResultTx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Tx indicates an expected call of Tx. +func (mr *MockCometRPCMockRecorder) Tx(ctx, hash, prove any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Tx", reflect.TypeOf((*MockCometRPC)(nil).Tx), ctx, hash, prove) +} + +// TxSearch mocks base method. +func (m *MockCometRPC) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (*types.ResultTxSearch, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TxSearch", ctx, query, prove, page, perPage, orderBy) + ret0, _ := ret[0].(*types.ResultTxSearch) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TxSearch indicates an expected call of TxSearch. +func (mr *MockCometRPCMockRecorder) TxSearch(ctx, query, prove, page, perPage, orderBy any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TxSearch", reflect.TypeOf((*MockCometRPC)(nil).TxSearch), ctx, query, prove, page, perPage, orderBy) +} + +// Validators mocks base method. +func (m *MockCometRPC) Validators(ctx context.Context, height *int64, page, perPage *int) (*types.ResultValidators, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Validators", ctx, height, page, perPage) + ret0, _ := ret[0].(*types.ResultValidators) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Validators indicates an expected call of Validators. +func (mr *MockCometRPCMockRecorder) Validators(ctx, height, page, perPage any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validators", reflect.TypeOf((*MockCometRPC)(nil).Validators), ctx, height, page, perPage) +} diff --git a/simapp/go.mod b/simapp/go.mod index 4885801831da..8e42d6df24dd 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -62,7 +62,7 @@ require ( cloud.google.com/go/iam v1.1.13 // indirect cloud.google.com/go/storage v1.43.0 // indirect cosmossdk.io/errors v1.0.1 // indirect - cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect + cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect diff --git a/simapp/go.sum b/simapp/go.sum index 16288a075bd5..11b262771249 100644 --- a/simapp/go.sum +++ b/simapp/go.sum @@ -204,8 +204,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= -cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac h1:3joNZZWZ3k7fMsrBDL1ktuQ2xQwYLZOaDhkruadDFmc= +cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= From 202598706be3132fdb9c4e13e23f9aff82a50c4a Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Wed, 16 Oct 2024 18:07:27 +0200 Subject: [PATCH 02/18] lint :) --- client/v2/internal/broadcast/broadcaster_test.go | 4 +++- client/v2/internal/broadcast/comet.go | 8 +++++--- client/v2/internal/broadcast/comet_test.go | 13 ++++--------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/client/v2/internal/broadcast/broadcaster_test.go b/client/v2/internal/broadcast/broadcaster_test.go index 81e061bc1d47..16f778fd2d1f 100644 --- a/client/v2/internal/broadcast/broadcaster_test.go +++ b/client/v2/internal/broadcast/broadcaster_test.go @@ -8,6 +8,8 @@ import ( ) func Test_newBroadcaster(t *testing.T) { + var f factory + f = broadcasterFactory{} tests := []struct { name string consensus string @@ -26,7 +28,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 { diff --git a/client/v2/internal/broadcast/comet.go b/client/v2/internal/broadcast/comet.go index c562a697726e..658fbe39e604 100644 --- a/client/v2/internal/broadcast/comet.go +++ b/client/v2/internal/broadcast/comet.go @@ -4,17 +4,18 @@ import ( "context" "encoding/json" "fmt" + "strings" + "github.com/cometbft/cometbft/mempool" rpchttp "github.com/cometbft/cometbft/rpc/client/http" coretypes "github.com/cometbft/cometbft/rpc/core/types" cmttypes "github.com/cometbft/cometbft/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "strings" apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" serverrpc "cosmossdk.io/server/v2/cometbft/client/rpc" "github.com/cosmos/cosmos-sdk/codec" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // CometBftBroadcaster implements the Broadcaster interface for CometBFT consensus engine. @@ -83,7 +84,8 @@ func (c CometBftBroadcaster) Broadcast(ctx context.Context, txBytes []byte) ([]b // broadcast sends a transaction to the CometBFT network using the provided function. func (c CometBftBroadcaster) broadcast(ctx context.Context, txbytes []byte, - fn func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error)) (*apiacbci.TxResponse, error) { + fn func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error), +) (*apiacbci.TxResponse, error) { bResult, err := fn(ctx, txbytes) if errRes := checkCometError(err, txbytes); err != nil { return errRes, nil diff --git a/client/v2/internal/broadcast/comet_test.go b/client/v2/internal/broadcast/comet_test.go index e52aa51a9f29..6b0a5c7ed83a 100644 --- a/client/v2/internal/broadcast/comet_test.go +++ b/client/v2/internal/broadcast/comet_test.go @@ -2,16 +2,15 @@ package broadcast import ( "context" - apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" "errors" - "github.com/cometbft/cometbft/mempool" - coretypes "github.com/cometbft/cometbft/rpc/core/types" - "github.com/cometbft/cometbft/types" "testing" + "github.com/cometbft/cometbft/mempool" + coretypes "github.com/cometbft/cometbft/rpc/core/types" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" + apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" mockrpc "cosmossdk.io/client/v2/internal/broadcast/testutil" "github.com/cosmos/cosmos-sdk/codec/testutil" @@ -91,10 +90,6 @@ func TestCometBftBroadcaster_Broadcast(t *testing.T) { } func Test_checkCometError(t *testing.T) { - type args struct { - err error - tx types.Tx - } tests := []struct { name string err error @@ -116,7 +111,7 @@ func Test_checkCometError(t *testing.T) { }, { name: "error in cache", - err: mempool.ErrTxTooLarge{10, 11}, + err: mempool.ErrTxTooLarge{}, want: &apiacbci.TxResponse{ Code: 21, }, From 39b5126e7a9faee421926dbd1f28cbf1c79db285 Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Wed, 16 Oct 2024 19:02:08 +0200 Subject: [PATCH 03/18] fix: make sure interfaces are implemented --- client/v2/go.mod | 1 - client/v2/go.sum | 2 -- client/v2/internal/broadcast/broadcaster.go | 2 ++ client/v2/internal/broadcast/broadcaster_test.go | 4 +--- client/v2/internal/broadcast/comet.go | 2 ++ simapp/v2/go.mod | 2 +- tests/go.mod | 2 +- tests/go.sum | 4 ++-- 8 files changed, 9 insertions(+), 10 deletions(-) diff --git a/client/v2/go.mod b/client/v2/go.mod index 2ce81f9b852a..1d7828c85c9b 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -6,7 +6,6 @@ require ( cosmossdk.io/api v0.7.6 cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 - cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 cosmossdk.io/server/v2/cometbft v0.0.0-20241015140036-ee3d320eaa55 cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a diff --git a/client/v2/go.sum b/client/v2/go.sum index c3fedbee7333..bdf8a2eaf7b9 100644 --- a/client/v2/go.sum +++ b/client/v2/go.sum @@ -14,8 +14,6 @@ cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= cosmossdk.io/depinject v1.0.0/go.mod h1:zxK/h3HgHoA/eJVtiSsoaRaRA2D5U4cJ5thIG4ssbB8= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= -cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 h1:IQNdY2kB+k+1OM2DvqFG1+UgeU1JzZrWtwuWzI3ZfwA= -cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5/go.mod h1:0CuYKkFHxc1vw2JC+t21THBCALJVROrWVR/3PQ1urpc= cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= diff --git a/client/v2/internal/broadcast/broadcaster.go b/client/v2/internal/broadcast/broadcaster.go index bea2677d1e43..8fd3d5404ff6 100644 --- a/client/v2/internal/broadcast/broadcaster.go +++ b/client/v2/internal/broadcast/broadcaster.go @@ -37,6 +37,8 @@ type ( Option func(Broadcaster) ) +var _ factory = broadcasterFactory{} + // broadcasterFactory is a factory for creating Broadcaster instances. type broadcasterFactory struct{} diff --git a/client/v2/internal/broadcast/broadcaster_test.go b/client/v2/internal/broadcast/broadcaster_test.go index 16f778fd2d1f..81e061bc1d47 100644 --- a/client/v2/internal/broadcast/broadcaster_test.go +++ b/client/v2/internal/broadcast/broadcaster_test.go @@ -8,8 +8,6 @@ import ( ) func Test_newBroadcaster(t *testing.T) { - var f factory - f = broadcasterFactory{} tests := []struct { name string consensus string @@ -28,7 +26,7 @@ func Test_newBroadcaster(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := f.create(context.Background(), tt.consensus, "localhost:26657", tt.opts...) + got, err := broadcasterFactory{}.create(context.Background(), tt.consensus, "localhost:26657", tt.opts...) if tt.wantErr { require.Error(t, err) } else { diff --git a/client/v2/internal/broadcast/comet.go b/client/v2/internal/broadcast/comet.go index 658fbe39e604..09dffa09064f 100644 --- a/client/v2/internal/broadcast/comet.go +++ b/client/v2/internal/broadcast/comet.go @@ -18,6 +18,8 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) +var _ Broadcaster = CometBftBroadcaster{} + // CometBftBroadcaster implements the Broadcaster interface for CometBFT consensus engine. type CometBftBroadcaster struct { rpcClient serverrpc.CometRPC diff --git a/simapp/v2/go.mod b/simapp/v2/go.mod index 457c1e06364c..59fbfd98c719 100644 --- a/simapp/v2/go.mod +++ b/simapp/v2/go.mod @@ -11,7 +11,7 @@ require ( cosmossdk.io/math v1.3.0 cosmossdk.io/runtime/v2 v2.0.0-00010101000000-000000000000 cosmossdk.io/server/v2 v2.0.0-20240718121635-a877e3e8048a - cosmossdk.io/server/v2/cometbft v0.0.0-00010101000000-000000000000 + cosmossdk.io/server/v2/cometbft v0.0.0-20241015140036-ee3d320eaa55 cosmossdk.io/store/v2 v2.0.0 cosmossdk.io/tools/confix v0.0.0-00010101000000-000000000000 cosmossdk.io/x/accounts v0.0.0-20240913065641-0064ccbce64e diff --git a/tests/go.mod b/tests/go.mod index 540cb84fd733..763d14237665 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -65,7 +65,7 @@ require ( cloud.google.com/go/storage v1.43.0 // indirect cosmossdk.io/client/v2 v2.0.0-20230630094428-02b760776860 // indirect cosmossdk.io/errors v1.0.1 // indirect - cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect + cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac // indirect cosmossdk.io/x/circuit v0.0.0-20230613133644-0a778132a60f // indirect cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337 // indirect filippo.io/edwards25519 v1.1.0 // indirect diff --git a/tests/go.sum b/tests/go.sum index 474e0a602b10..ac79fe10e904 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -204,8 +204,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= -cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac h1:3joNZZWZ3k7fMsrBDL1ktuQ2xQwYLZOaDhkruadDFmc= +cosmossdk.io/schema v0.3.1-0.20241010135032-192601639cac/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= From 49598ddec849ffefa511132d3f169b45109184c0 Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Thu, 17 Oct 2024 09:57:02 +0200 Subject: [PATCH 04/18] del: server/v2 dependency --- client/v2/go.mod | 5 -- client/v2/internal/broadcast/broadcaster.go | 8 +- .../v2/internal/broadcast/broadcaster_test.go | 5 ++ client/v2/internal/broadcast/comet.go | 51 ++++++++++--- .../internal/broadcast/testutil/comet_mock.go | 76 +++++++++---------- 5 files changed, 86 insertions(+), 59 deletions(-) diff --git a/client/v2/go.mod b/client/v2/go.mod index 1d7828c85c9b..816073b162bd 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -6,7 +6,6 @@ require ( cosmossdk.io/api v0.7.6 cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 - cosmossdk.io/server/v2/cometbft v0.0.0-20241015140036-ee3d320eaa55 cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a cosmossdk.io/x/tx v0.13.3 @@ -177,12 +176,8 @@ replace github.com/cosmos/cosmos-sdk => ./../../ // TODO remove post spinning out all modules replace ( cosmossdk.io/api => ./../../api - cosmossdk.io/server/v2 => ./../../server/v2 - cosmossdk.io/server/v2/cometbft => ./../../server/v2/cometbft cosmossdk.io/store => ./../../store - cosmossdk.io/store/v2 => ./../../store/v2 cosmossdk.io/x/bank => ./../../x/bank - cosmossdk.io/x/consensus => ./../../x/consensus cosmossdk.io/x/gov => ./../../x/gov cosmossdk.io/x/staking => ./../../x/staking cosmossdk.io/x/tx => ./../../x/tx diff --git a/client/v2/internal/broadcast/broadcaster.go b/client/v2/internal/broadcast/broadcaster.go index 8fd3d5404ff6..36c6f571b8f9 100644 --- a/client/v2/internal/broadcast/broadcaster.go +++ b/client/v2/internal/broadcast/broadcaster.go @@ -14,7 +14,7 @@ const ( BroadcastAsync = "async" // cometBftConsensus is the identifier for the CometBFT consensus engine. - cometBftConsensus = "comet" + cometBFTConsensus = "comet" ) type ( @@ -29,7 +29,7 @@ type ( // factory defines a generic interface for creating a Broadcaster. factory interface { - // Create creates a new Broadcaster instance of type T. + // create creates a new Broadcaster instance based on the consensus type. create(ctx context.Context, consensus, url string, opts ...Option) (Broadcaster, error) } @@ -45,8 +45,8 @@ type broadcasterFactory struct{} // 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...) + case cometBFTConsensus: + return NewCometBFTBroadcaster(url, opts...) default: return nil, fmt.Errorf("invalid consensus type: %s", consensus) } diff --git a/client/v2/internal/broadcast/broadcaster_test.go b/client/v2/internal/broadcast/broadcaster_test.go index 81e061bc1d47..697c35e564ea 100644 --- a/client/v2/internal/broadcast/broadcaster_test.go +++ b/client/v2/internal/broadcast/broadcaster_test.go @@ -23,6 +23,11 @@ func Test_newBroadcaster(t *testing.T) { }, want: &CometBftBroadcaster{}, }, + { + name: "unsupported_consensus", + consensus: "unsupported", + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/client/v2/internal/broadcast/comet.go b/client/v2/internal/broadcast/comet.go index 09dffa09064f..665b8c85f8a7 100644 --- a/client/v2/internal/broadcast/comet.go +++ b/client/v2/internal/broadcast/comet.go @@ -7,29 +7,56 @@ import ( "strings" "github.com/cometbft/cometbft/mempool" + rpcclient "github.com/cometbft/cometbft/rpc/client" rpchttp "github.com/cometbft/cometbft/rpc/client/http" coretypes "github.com/cometbft/cometbft/rpc/core/types" cmttypes "github.com/cometbft/cometbft/types" apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" - serverrpc "cosmossdk.io/server/v2/cometbft/client/rpc" - "github.com/cosmos/cosmos-sdk/codec" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -var _ Broadcaster = CometBftBroadcaster{} +// CometRPC defines the interface of a CometBFT RPC client needed for +// queries and transaction handling. +type CometRPC interface { + rpcclient.ABCIClient + + Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) + Status(context.Context) (*coretypes.ResultStatus, error) + Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) + BlockByHash(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error) + BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) + BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) + Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) + Tx(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) + TxSearch( + ctx context.Context, + query string, + prove bool, + page, perPage *int, + orderBy string, + ) (*coretypes.ResultTxSearch, error) + BlockSearch( + ctx context.Context, + query string, + page, perPage *int, + orderBy string, + ) (*coretypes.ResultBlockSearch, error) +} + +var _ Broadcaster = CometBFTBroadcaster{} // CometBftBroadcaster implements the Broadcaster interface for CometBFT consensus engine. -type CometBftBroadcaster struct { - rpcClient serverrpc.CometRPC +type CometBFTBroadcaster struct { + rpcClient CometRPC mode string cdc codec.JSONCodec } func withMode(mode string) func(broadcaster Broadcaster) { return func(b Broadcaster) { - cbc, ok := b.(*CometBftBroadcaster) + cbc, ok := b.(*CometBFTBroadcaster) if !ok { return } @@ -39,7 +66,7 @@ func withMode(mode string) func(broadcaster Broadcaster) { func withJsonCodec(codec codec.JSONCodec) func(broadcaster Broadcaster) { return func(b Broadcaster) { - cbc, ok := b.(*CometBftBroadcaster) + cbc, ok := b.(*CometBFTBroadcaster) if !ok { return } @@ -47,14 +74,14 @@ func withJsonCodec(codec codec.JSONCodec) func(broadcaster Broadcaster) { } } -// NewCometBftBroadcaster creates a new CometBftBroadcaster. -func NewCometBftBroadcaster(rpcURL string, opts ...Option) (*CometBftBroadcaster, error) { +// NewCometBFTBroadcaster creates a new CometBftBroadcaster. +func NewCometBFTBroadcaster(rpcURL string, opts ...Option) (*CometBFTBroadcaster, error) { rpcClient, err := rpchttp.New(rpcURL) if err != nil { return nil, fmt.Errorf("failed to create CometBft RPC client: %w", err) } - bc := &CometBftBroadcaster{} + bc := &CometBFTBroadcaster{} for _, opt := range opts { opt(bc) } @@ -65,7 +92,7 @@ func NewCometBftBroadcaster(rpcURL string, opts ...Option) (*CometBftBroadcaster // 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) { +func (c CometBFTBroadcaster) Broadcast(ctx context.Context, txBytes []byte) ([]byte, error) { var fn func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error) switch c.mode { case BroadcastSync: @@ -85,7 +112,7 @@ func (c CometBftBroadcaster) Broadcast(ctx context.Context, txBytes []byte) ([]b } // broadcast sends a transaction to the CometBFT network using the provided function. -func (c CometBftBroadcaster) broadcast(ctx context.Context, txbytes []byte, +func (c CometBFTBroadcaster) broadcast(ctx context.Context, txbytes []byte, fn func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error), ) (*apiacbci.TxResponse, error) { bResult, err := fn(ctx, txbytes) diff --git a/client/v2/internal/broadcast/testutil/comet_mock.go b/client/v2/internal/broadcast/testutil/comet_mock.go index 0442b9a925bc..471ed94ab0b3 100644 --- a/client/v2/internal/broadcast/testutil/comet_mock.go +++ b/client/v2/internal/broadcast/testutil/comet_mock.go @@ -1,13 +1,13 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: server/v2/cometbft/client/rpc/client.go +// Source: comet.go // // Generated by this command: // -// mockgen -source=server/v2/cometbft/client/rpc/client.go +// mockgen -source=comet.go // -// Package mock_rpc is a generated GoMock package. -package mock_rpc +// Package mock_broadcast is a generated GoMock package. +package mock_broadcast import ( context "context" @@ -15,8 +15,8 @@ import ( bytes "github.com/cometbft/cometbft/libs/bytes" client "github.com/cometbft/cometbft/rpc/client" - types "github.com/cometbft/cometbft/rpc/core/types" - types0 "github.com/cometbft/cometbft/types" + coretypes "github.com/cometbft/cometbft/rpc/core/types" + types "github.com/cometbft/cometbft/types" gomock "go.uber.org/mock/gomock" ) @@ -44,10 +44,10 @@ func (m *MockCometRPC) EXPECT() *MockCometRPCMockRecorder { } // ABCIInfo mocks base method. -func (m *MockCometRPC) ABCIInfo(ctx context.Context) (*types.ResultABCIInfo, error) { +func (m *MockCometRPC) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ABCIInfo", ctx) - ret0, _ := ret[0].(*types.ResultABCIInfo) + ret0, _ := ret[0].(*coretypes.ResultABCIInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -59,10 +59,10 @@ func (mr *MockCometRPCMockRecorder) ABCIInfo(ctx any) *gomock.Call { } // ABCIQuery mocks base method. -func (m *MockCometRPC) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*types.ResultABCIQuery, error) { +func (m *MockCometRPC) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ABCIQuery", ctx, path, data) - ret0, _ := ret[0].(*types.ResultABCIQuery) + ret0, _ := ret[0].(*coretypes.ResultABCIQuery) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -74,10 +74,10 @@ func (mr *MockCometRPCMockRecorder) ABCIQuery(ctx, path, data any) *gomock.Call } // ABCIQueryWithOptions mocks base method. -func (m *MockCometRPC) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*types.ResultABCIQuery, error) { +func (m *MockCometRPC) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ABCIQueryWithOptions", ctx, path, data, opts) - ret0, _ := ret[0].(*types.ResultABCIQuery) + ret0, _ := ret[0].(*coretypes.ResultABCIQuery) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -89,10 +89,10 @@ func (mr *MockCometRPCMockRecorder) ABCIQueryWithOptions(ctx, path, data, opts a } // Block mocks base method. -func (m *MockCometRPC) Block(ctx context.Context, height *int64) (*types.ResultBlock, error) { +func (m *MockCometRPC) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Block", ctx, height) - ret0, _ := ret[0].(*types.ResultBlock) + ret0, _ := ret[0].(*coretypes.ResultBlock) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -104,10 +104,10 @@ func (mr *MockCometRPCMockRecorder) Block(ctx, height any) *gomock.Call { } // BlockByHash mocks base method. -func (m *MockCometRPC) BlockByHash(ctx context.Context, hash []byte) (*types.ResultBlock, error) { +func (m *MockCometRPC) BlockByHash(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockByHash", ctx, hash) - ret0, _ := ret[0].(*types.ResultBlock) + ret0, _ := ret[0].(*coretypes.ResultBlock) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -119,10 +119,10 @@ func (mr *MockCometRPCMockRecorder) BlockByHash(ctx, hash any) *gomock.Call { } // BlockResults mocks base method. -func (m *MockCometRPC) BlockResults(ctx context.Context, height *int64) (*types.ResultBlockResults, error) { +func (m *MockCometRPC) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockResults", ctx, height) - ret0, _ := ret[0].(*types.ResultBlockResults) + ret0, _ := ret[0].(*coretypes.ResultBlockResults) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -134,10 +134,10 @@ func (mr *MockCometRPCMockRecorder) BlockResults(ctx, height any) *gomock.Call { } // BlockSearch mocks base method. -func (m *MockCometRPC) BlockSearch(ctx context.Context, query string, page, perPage *int, orderBy string) (*types.ResultBlockSearch, error) { +func (m *MockCometRPC) BlockSearch(ctx context.Context, query string, page, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockSearch", ctx, query, page, perPage, orderBy) - ret0, _ := ret[0].(*types.ResultBlockSearch) + ret0, _ := ret[0].(*coretypes.ResultBlockSearch) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -149,10 +149,10 @@ func (mr *MockCometRPCMockRecorder) BlockSearch(ctx, query, page, perPage, order } // BlockchainInfo mocks base method. -func (m *MockCometRPC) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*types.ResultBlockchainInfo, error) { +func (m *MockCometRPC) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockchainInfo", ctx, minHeight, maxHeight) - ret0, _ := ret[0].(*types.ResultBlockchainInfo) + ret0, _ := ret[0].(*coretypes.ResultBlockchainInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -164,10 +164,10 @@ func (mr *MockCometRPCMockRecorder) BlockchainInfo(ctx, minHeight, maxHeight any } // BroadcastTxAsync mocks base method. -func (m *MockCometRPC) BroadcastTxAsync(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTx, error) { +func (m *MockCometRPC) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BroadcastTxAsync", ctx, tx) - ret0, _ := ret[0].(*types.ResultBroadcastTx) + ret0, _ := ret[0].(*coretypes.ResultBroadcastTx) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -179,10 +179,10 @@ func (mr *MockCometRPCMockRecorder) BroadcastTxAsync(ctx, tx any) *gomock.Call { } // BroadcastTxCommit mocks base method. -func (m *MockCometRPC) BroadcastTxCommit(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTxCommit, error) { +func (m *MockCometRPC) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BroadcastTxCommit", ctx, tx) - ret0, _ := ret[0].(*types.ResultBroadcastTxCommit) + ret0, _ := ret[0].(*coretypes.ResultBroadcastTxCommit) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -194,10 +194,10 @@ func (mr *MockCometRPCMockRecorder) BroadcastTxCommit(ctx, tx any) *gomock.Call } // BroadcastTxSync mocks base method. -func (m *MockCometRPC) BroadcastTxSync(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTx, error) { +func (m *MockCometRPC) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BroadcastTxSync", ctx, tx) - ret0, _ := ret[0].(*types.ResultBroadcastTx) + ret0, _ := ret[0].(*coretypes.ResultBroadcastTx) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -209,10 +209,10 @@ func (mr *MockCometRPCMockRecorder) BroadcastTxSync(ctx, tx any) *gomock.Call { } // Commit mocks base method. -func (m *MockCometRPC) Commit(ctx context.Context, height *int64) (*types.ResultCommit, error) { +func (m *MockCometRPC) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Commit", ctx, height) - ret0, _ := ret[0].(*types.ResultCommit) + ret0, _ := ret[0].(*coretypes.ResultCommit) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -224,10 +224,10 @@ func (mr *MockCometRPCMockRecorder) Commit(ctx, height any) *gomock.Call { } // Status mocks base method. -func (m *MockCometRPC) Status(arg0 context.Context) (*types.ResultStatus, error) { +func (m *MockCometRPC) Status(arg0 context.Context) (*coretypes.ResultStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Status", arg0) - ret0, _ := ret[0].(*types.ResultStatus) + ret0, _ := ret[0].(*coretypes.ResultStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -239,10 +239,10 @@ func (mr *MockCometRPCMockRecorder) Status(arg0 any) *gomock.Call { } // Tx mocks base method. -func (m *MockCometRPC) Tx(ctx context.Context, hash []byte, prove bool) (*types.ResultTx, error) { +func (m *MockCometRPC) Tx(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Tx", ctx, hash, prove) - ret0, _ := ret[0].(*types.ResultTx) + ret0, _ := ret[0].(*coretypes.ResultTx) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -254,10 +254,10 @@ func (mr *MockCometRPCMockRecorder) Tx(ctx, hash, prove any) *gomock.Call { } // TxSearch mocks base method. -func (m *MockCometRPC) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (*types.ResultTxSearch, error) { +func (m *MockCometRPC) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "TxSearch", ctx, query, prove, page, perPage, orderBy) - ret0, _ := ret[0].(*types.ResultTxSearch) + ret0, _ := ret[0].(*coretypes.ResultTxSearch) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -269,10 +269,10 @@ func (mr *MockCometRPCMockRecorder) TxSearch(ctx, query, prove, page, perPage, o } // Validators mocks base method. -func (m *MockCometRPC) Validators(ctx context.Context, height *int64, page, perPage *int) (*types.ResultValidators, error) { +func (m *MockCometRPC) Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Validators", ctx, height, page, perPage) - ret0, _ := ret[0].(*types.ResultValidators) + ret0, _ := ret[0].(*coretypes.ResultValidators) ret1, _ := ret[1].(error) return ret0, ret1 } From 8656f1f1b7f79cda499cb93367ad989c54de018a Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Thu, 17 Oct 2024 09:59:49 +0200 Subject: [PATCH 05/18] fix: tests --- client/v2/internal/broadcast/broadcaster_test.go | 2 +- client/v2/internal/broadcast/comet_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/v2/internal/broadcast/broadcaster_test.go b/client/v2/internal/broadcast/broadcaster_test.go index 697c35e564ea..670a3f05481a 100644 --- a/client/v2/internal/broadcast/broadcaster_test.go +++ b/client/v2/internal/broadcast/broadcaster_test.go @@ -21,7 +21,7 @@ func Test_newBroadcaster(t *testing.T) { opts: []Option{ withMode(BroadcastSync), }, - want: &CometBftBroadcaster{}, + want: &CometBFTBroadcaster{}, }, { name: "unsupported_consensus", diff --git a/client/v2/internal/broadcast/comet_test.go b/client/v2/internal/broadcast/comet_test.go index 6b0a5c7ed83a..73b0d8edca37 100644 --- a/client/v2/internal/broadcast/comet_test.go +++ b/client/v2/internal/broadcast/comet_test.go @@ -22,7 +22,7 @@ func TestNewCometBftBroadcaster(t *testing.T) { tests := []struct { name string opts []Option - want *CometBftBroadcaster + want *CometBFTBroadcaster wantErr bool }{ { @@ -31,7 +31,7 @@ func TestNewCometBftBroadcaster(t *testing.T) { withMode(BroadcastSync), withJsonCodec(cdc), }, - want: &CometBftBroadcaster{ + want: &CometBFTBroadcaster{ mode: BroadcastSync, cdc: cdc, }, @@ -39,7 +39,7 @@ func TestNewCometBftBroadcaster(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewCometBftBroadcaster("localhost:26657", tt.opts...) + got, err := NewCometBFTBroadcaster("localhost:26657", tt.opts...) if (err != nil) != tt.wantErr { t.Errorf("NewCometBftBroadcaster() error = %v, wantErr %v", err, tt.wantErr) return @@ -53,7 +53,7 @@ func TestNewCometBftBroadcaster(t *testing.T) { func TestCometBftBroadcaster_Broadcast(t *testing.T) { ctrl := gomock.NewController(t) cometMock := mockrpc.NewMockCometRPC(ctrl) - c := CometBftBroadcaster{ + c := CometBFTBroadcaster{ rpcClient: cometMock, mode: BroadcastSync, cdc: cdc, From b33e5a2e43aefa554fec5d24dda44028692a141f Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Thu, 17 Oct 2024 10:10:34 +0200 Subject: [PATCH 06/18] CHANGELOG --- client/v2/CHANGELOG.md | 1 + client/v2/internal/broadcast/comet.go | 1 + 2 files changed, 2 insertions(+) diff --git a/client/v2/CHANGELOG.md b/client/v2/CHANGELOG.md index 8bd7877b448a..86a5704ed2a8 100644 --- a/client/v2/CHANGELOG.md +++ b/client/v2/CHANGELOG.md @@ -44,6 +44,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#18461](https://github.com/cosmos/cosmos-sdk/pull/18461) Support governance proposals. * [#20623](https://github.com/cosmos/cosmos-sdk/pull/20623) Introduce client/v2 tx factory. * [#20623](https://github.com/cosmos/cosmos-sdk/pull/20623) Extend client/v2 keyring interface with `KeyType` and `KeyInfo`. +* [#22282](https://github.com/cosmos/cosmos-sdk/pull/22282) Added custom broadcast logic. ### Improvements diff --git a/client/v2/internal/broadcast/comet.go b/client/v2/internal/broadcast/comet.go index 665b8c85f8a7..80f9207c84e6 100644 --- a/client/v2/internal/broadcast/comet.go +++ b/client/v2/internal/broadcast/comet.go @@ -13,6 +13,7 @@ import ( cmttypes "github.com/cometbft/cometbft/types" apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" + "github.com/cosmos/cosmos-sdk/codec" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) From c13fe796c5d3db6162ce63d01689516460c7b0df Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Thu, 17 Oct 2024 18:36:26 +0200 Subject: [PATCH 07/18] update: factory register --- client/v2/internal/broadcast/broadcaster.go | 52 ++++++++++++++----- .../v2/internal/broadcast/broadcaster_test.go | 41 ++++++++++++++- client/v2/internal/broadcast/comet.go | 6 ++- 3 files changed, 84 insertions(+), 15 deletions(-) diff --git a/client/v2/internal/broadcast/broadcaster.go b/client/v2/internal/broadcast/broadcaster.go index 36c6f571b8f9..ae88126169a9 100644 --- a/client/v2/internal/broadcast/broadcaster.go +++ b/client/v2/internal/broadcast/broadcaster.go @@ -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...) + }, + }, + } } diff --git a/client/v2/internal/broadcast/broadcaster_test.go b/client/v2/internal/broadcast/broadcaster_test.go index 670a3f05481a..c383512f0508 100644 --- a/client/v2/internal/broadcast/broadcaster_test.go +++ b/client/v2/internal/broadcast/broadcaster_test.go @@ -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 @@ -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 { @@ -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()) + }) + } +} diff --git a/client/v2/internal/broadcast/comet.go b/client/v2/internal/broadcast/comet.go index 80f9207c84e6..e69fddcb649b 100644 --- a/client/v2/internal/broadcast/comet.go +++ b/client/v2/internal/broadcast/comet.go @@ -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 @@ -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) { From 4bd1fbb154a159d4fa39514a83b5a560dd9905b1 Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Tue, 22 Oct 2024 10:52:41 +0200 Subject: [PATCH 08/18] update: factory and types public --- client/v2/broadcast/factory.go | 41 ++++++++++ .../factory_test.go} | 17 ++-- client/v2/broadcast/types/broadcaster.go | 32 ++++++++ client/v2/internal/broadcast/broadcaster.go | 79 ------------------- .../v2/internal/{broadcast => comet}/comet.go | 27 +++++-- .../{broadcast => comet}/comet_test.go | 13 +-- .../testutil/comet_mock.go | 0 7 files changed, 110 insertions(+), 99 deletions(-) create mode 100644 client/v2/broadcast/factory.go rename client/v2/{internal/broadcast/broadcaster_test.go => broadcast/factory_test.go} (79%) create mode 100644 client/v2/broadcast/types/broadcaster.go delete mode 100644 client/v2/internal/broadcast/broadcaster.go rename client/v2/internal/{broadcast => comet}/comet.go (87%) rename client/v2/internal/{broadcast => comet}/comet_test.go (92%) rename client/v2/internal/{broadcast => comet}/testutil/comet_mock.go (100%) diff --git a/client/v2/broadcast/factory.go b/client/v2/broadcast/factory.go new file mode 100644 index 000000000000..82bad2cae5be --- /dev/null +++ b/client/v2/broadcast/factory.go @@ -0,0 +1,41 @@ +package broadcast + +import ( + "context" + "fmt" + + "cosmossdk.io/client/v2/broadcast/types" + "cosmossdk.io/client/v2/internal/comet" +) + +var _ types.BroadcasterFactory = Factory{} + +// Factory is a factory for creating Broadcaster instances. +type Factory struct { + engines map[string]types.NewBroadcasterFn +} + +// Create creates a new Broadcaster based on the given consensus type. +func (f Factory) Create(_ context.Context, consensus, url string, opts ...types.Option) (types.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 types.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]types.NewBroadcasterFn{ + "comet": func(url string, opts ...types.Option) (types.Broadcaster, error) { + return comet.NewCometBFTBroadcaster(url, opts...) + }, + }, + } +} diff --git a/client/v2/internal/broadcast/broadcaster_test.go b/client/v2/broadcast/factory_test.go similarity index 79% rename from client/v2/internal/broadcast/broadcaster_test.go rename to client/v2/broadcast/factory_test.go index c383512f0508..9f4dc8b236cb 100644 --- a/client/v2/internal/broadcast/broadcaster_test.go +++ b/client/v2/broadcast/factory_test.go @@ -5,6 +5,9 @@ import ( "testing" "github.com/stretchr/testify/require" + + "cosmossdk.io/client/v2/broadcast/types" + "cosmossdk.io/client/v2/internal/comet" ) type testBFT struct{} @@ -22,17 +25,17 @@ func Test_newBroadcaster(t *testing.T) { tests := []struct { name string consensus string - opts []Option - want Broadcaster + opts []types.Option + want types.Broadcaster wantErr bool }{ { name: "comet", consensus: "comet", - opts: []Option{ - withMode(BroadcastSync), + opts: []types.Option{ + comet.WithMode(comet.BroadcastSync), }, - want: &CometBFTBroadcaster{}, + want: &comet.CometBFTBroadcaster{}, }, { name: "unsupported_consensus", @@ -58,12 +61,12 @@ func TestFactory_Register(t *testing.T) { tests := []struct { name string consensus string - creator NewBroadcasterFn + creator types.NewBroadcasterFn }{ { name: "register new broadcaster", consensus: "testBFT", - creator: func(url string, opts ...Option) (Broadcaster, error) { + creator: func(url string, opts ...types.Option) (types.Broadcaster, error) { return testBFT{}, nil }, }, diff --git a/client/v2/broadcast/types/broadcaster.go b/client/v2/broadcast/types/broadcaster.go new file mode 100644 index 000000000000..161533ffe1a6 --- /dev/null +++ b/client/v2/broadcast/types/broadcaster.go @@ -0,0 +1,32 @@ +package types + +import "context" + +type ( + // Broadcaster defines an interface for broadcasting transactions to the consensus engine. + Broadcaster interface { + // Broadcast sends a transaction to the network and returns the result. + // + // 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 + } + + // 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) +) diff --git a/client/v2/internal/broadcast/broadcaster.go b/client/v2/internal/broadcast/broadcaster.go deleted file mode 100644 index ae88126169a9..000000000000 --- a/client/v2/internal/broadcast/broadcaster.go +++ /dev/null @@ -1,79 +0,0 @@ -package broadcast - -import ( - "context" - "fmt" -) - -const ( - // BroadcastSync defines a tx broadcasting mode where the client waits for - // a CheckTx execution response only. - BroadcastSync = "sync" - // BroadcastAsync defines a tx broadcasting mode where the client returns - // immediately. - BroadcastAsync = "async" - - // cometBftConsensus is the identifier for the CometBFT consensus engine. - cometBFTConsensus = "comet" -) - -type ( - // Broadcaster defines an interface for broadcasting transactions to the consensus engine. - Broadcaster interface { - // Broadcast sends a transaction to the network and returns the result. - // - // 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 - } - - // 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 _ BroadcasterFactory = Factory{} - -// 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 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...) - }, - }, - } -} diff --git a/client/v2/internal/broadcast/comet.go b/client/v2/internal/comet/comet.go similarity index 87% rename from client/v2/internal/broadcast/comet.go rename to client/v2/internal/comet/comet.go index e69fddcb649b..85b3baab5f0b 100644 --- a/client/v2/internal/broadcast/comet.go +++ b/client/v2/internal/comet/comet.go @@ -1,4 +1,4 @@ -package broadcast +package comet import ( "context" @@ -6,6 +6,7 @@ import ( "fmt" "strings" + "cosmossdk.io/client/v2/broadcast/types" "github.com/cometbft/cometbft/mempool" rpcclient "github.com/cometbft/cometbft/rpc/client" rpchttp "github.com/cometbft/cometbft/rpc/client/http" @@ -18,6 +19,18 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) +const ( + // BroadcastSync defines a tx broadcasting mode where the client waits for + // a CheckTx execution response only. + BroadcastSync = "sync" + // BroadcastAsync defines a tx broadcasting mode where the client returns + // immediately. + BroadcastAsync = "async" + + // cometBftConsensus is the identifier for the CometBFT consensus engine. + cometBFTConsensus = "comet" +) + // CometRPC defines the interface of a CometBFT RPC client needed for // queries and transaction handling. type CometRPC interface { @@ -46,7 +59,7 @@ type CometRPC interface { ) (*coretypes.ResultBlockSearch, error) } -var _ Broadcaster = CometBFTBroadcaster{} +var _ types.Broadcaster = CometBFTBroadcaster{} // CometBFTBroadcaster implements the Broadcaster interface for CometBFT consensus engine. type CometBFTBroadcaster struct { @@ -55,8 +68,8 @@ type CometBFTBroadcaster struct { cdc codec.JSONCodec } -func withMode(mode string) func(broadcaster Broadcaster) { - return func(b Broadcaster) { +func WithMode(mode string) func(broadcaster types.Broadcaster) { + return func(b types.Broadcaster) { cbc, ok := b.(*CometBFTBroadcaster) if !ok { return @@ -65,8 +78,8 @@ func withMode(mode string) func(broadcaster Broadcaster) { } } -func withJsonCodec(codec codec.JSONCodec) func(broadcaster Broadcaster) { - return func(b Broadcaster) { +func WithJsonCodec(codec codec.JSONCodec) func(broadcaster types.Broadcaster) { + return func(b types.Broadcaster) { cbc, ok := b.(*CometBFTBroadcaster) if !ok { return @@ -76,7 +89,7 @@ func withJsonCodec(codec codec.JSONCodec) func(broadcaster Broadcaster) { } // NewCometBFTBroadcaster creates a new CometBftBroadcaster. -func NewCometBFTBroadcaster(rpcURL string, opts ...Option) (*CometBFTBroadcaster, error) { +func NewCometBFTBroadcaster(rpcURL string, opts ...types.Option) (*CometBFTBroadcaster, error) { rpcClient, err := rpchttp.New(rpcURL) if err != nil { return nil, fmt.Errorf("failed to create CometBft RPC client: %w", err) diff --git a/client/v2/internal/broadcast/comet_test.go b/client/v2/internal/comet/comet_test.go similarity index 92% rename from client/v2/internal/broadcast/comet_test.go rename to client/v2/internal/comet/comet_test.go index 73b0d8edca37..5e83a5445442 100644 --- a/client/v2/internal/broadcast/comet_test.go +++ b/client/v2/internal/comet/comet_test.go @@ -1,4 +1,4 @@ -package broadcast +package comet import ( "context" @@ -11,7 +11,8 @@ import ( "go.uber.org/mock/gomock" apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" - mockrpc "cosmossdk.io/client/v2/internal/broadcast/testutil" + "cosmossdk.io/client/v2/broadcast/types" + mockrpc "cosmossdk.io/client/v2/internal/comet/testutil" "github.com/cosmos/cosmos-sdk/codec/testutil" ) @@ -21,15 +22,15 @@ var cdc = testutil.CodecOptions{}.NewCodec() func TestNewCometBftBroadcaster(t *testing.T) { tests := []struct { name string - opts []Option + opts []types.Option want *CometBFTBroadcaster wantErr bool }{ { name: "constructor", - opts: []Option{ - withMode(BroadcastSync), - withJsonCodec(cdc), + opts: []types.Option{ + WithMode(BroadcastSync), + WithJsonCodec(cdc), }, want: &CometBFTBroadcaster{ mode: BroadcastSync, diff --git a/client/v2/internal/broadcast/testutil/comet_mock.go b/client/v2/internal/comet/testutil/comet_mock.go similarity index 100% rename from client/v2/internal/broadcast/testutil/comet_mock.go rename to client/v2/internal/comet/testutil/comet_mock.go From bee57fa3923af859d354243b20aec857930b27cd Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Tue, 22 Oct 2024 10:58:34 +0200 Subject: [PATCH 09/18] update: mock --- client/v2/internal/comet/comet.go | 14 ++-- client/v2/internal/comet/comet_test.go | 6 +- .../v2/internal/comet/testutil/comet_mock.go | 76 +++++++++---------- scripts/mockgen.sh | 1 + 4 files changed, 49 insertions(+), 48 deletions(-) diff --git a/client/v2/internal/comet/comet.go b/client/v2/internal/comet/comet.go index 85b3baab5f0b..597c14d43be6 100644 --- a/client/v2/internal/comet/comet.go +++ b/client/v2/internal/comet/comet.go @@ -6,7 +6,6 @@ import ( "fmt" "strings" - "cosmossdk.io/client/v2/broadcast/types" "github.com/cometbft/cometbft/mempool" rpcclient "github.com/cometbft/cometbft/rpc/client" rpchttp "github.com/cometbft/cometbft/rpc/client/http" @@ -14,6 +13,7 @@ import ( cmttypes "github.com/cometbft/cometbft/types" apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" + broadcasttypes "cosmossdk.io/client/v2/broadcast/types" "github.com/cosmos/cosmos-sdk/codec" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -59,7 +59,7 @@ type CometRPC interface { ) (*coretypes.ResultBlockSearch, error) } -var _ types.Broadcaster = CometBFTBroadcaster{} +var _ broadcasttypes.Broadcaster = CometBFTBroadcaster{} // CometBFTBroadcaster implements the Broadcaster interface for CometBFT consensus engine. type CometBFTBroadcaster struct { @@ -68,8 +68,8 @@ type CometBFTBroadcaster struct { cdc codec.JSONCodec } -func WithMode(mode string) func(broadcaster types.Broadcaster) { - return func(b types.Broadcaster) { +func WithMode(mode string) func(broadcaster broadcasttypes.Broadcaster) { + return func(b broadcasttypes.Broadcaster) { cbc, ok := b.(*CometBFTBroadcaster) if !ok { return @@ -78,8 +78,8 @@ func WithMode(mode string) func(broadcaster types.Broadcaster) { } } -func WithJsonCodec(codec codec.JSONCodec) func(broadcaster types.Broadcaster) { - return func(b types.Broadcaster) { +func WithJsonCodec(codec codec.JSONCodec) func(broadcaster broadcasttypes.Broadcaster) { + return func(b broadcasttypes.Broadcaster) { cbc, ok := b.(*CometBFTBroadcaster) if !ok { return @@ -89,7 +89,7 @@ func WithJsonCodec(codec codec.JSONCodec) func(broadcaster types.Broadcaster) { } // NewCometBFTBroadcaster creates a new CometBftBroadcaster. -func NewCometBFTBroadcaster(rpcURL string, opts ...types.Option) (*CometBFTBroadcaster, error) { +func NewCometBFTBroadcaster(rpcURL string, opts ...broadcasttypes.Option) (*CometBFTBroadcaster, error) { rpcClient, err := rpchttp.New(rpcURL) if err != nil { return nil, fmt.Errorf("failed to create CometBft RPC client: %w", err) diff --git a/client/v2/internal/comet/comet_test.go b/client/v2/internal/comet/comet_test.go index 5e83a5445442..52ae3849c15f 100644 --- a/client/v2/internal/comet/comet_test.go +++ b/client/v2/internal/comet/comet_test.go @@ -11,7 +11,7 @@ import ( "go.uber.org/mock/gomock" apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" - "cosmossdk.io/client/v2/broadcast/types" + broadcasttypes "cosmossdk.io/client/v2/broadcast/types" mockrpc "cosmossdk.io/client/v2/internal/comet/testutil" "github.com/cosmos/cosmos-sdk/codec/testutil" @@ -22,13 +22,13 @@ var cdc = testutil.CodecOptions{}.NewCodec() func TestNewCometBftBroadcaster(t *testing.T) { tests := []struct { name string - opts []types.Option + opts []broadcasttypes.Option want *CometBFTBroadcaster wantErr bool }{ { name: "constructor", - opts: []types.Option{ + opts: []broadcasttypes.Option{ WithMode(BroadcastSync), WithJsonCodec(cdc), }, diff --git a/client/v2/internal/comet/testutil/comet_mock.go b/client/v2/internal/comet/testutil/comet_mock.go index 471ed94ab0b3..97a943a4e170 100644 --- a/client/v2/internal/comet/testutil/comet_mock.go +++ b/client/v2/internal/comet/testutil/comet_mock.go @@ -1,13 +1,13 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: comet.go +// Source: client/v2/internal/comet/comet.go // // Generated by this command: // -// mockgen -source=comet.go +// mockgen -source=client/v2/internal/comet/comet.go -package testutil -destination client/v2/internal/comet/testutil/comet_mock.go // -// Package mock_broadcast is a generated GoMock package. -package mock_broadcast +// Package testutil is a generated GoMock package. +package testutil import ( context "context" @@ -15,8 +15,8 @@ import ( bytes "github.com/cometbft/cometbft/libs/bytes" client "github.com/cometbft/cometbft/rpc/client" - coretypes "github.com/cometbft/cometbft/rpc/core/types" - types "github.com/cometbft/cometbft/types" + types "github.com/cometbft/cometbft/rpc/core/types" + types0 "github.com/cometbft/cometbft/types" gomock "go.uber.org/mock/gomock" ) @@ -44,10 +44,10 @@ func (m *MockCometRPC) EXPECT() *MockCometRPCMockRecorder { } // ABCIInfo mocks base method. -func (m *MockCometRPC) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { +func (m *MockCometRPC) ABCIInfo(ctx context.Context) (*types.ResultABCIInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ABCIInfo", ctx) - ret0, _ := ret[0].(*coretypes.ResultABCIInfo) + ret0, _ := ret[0].(*types.ResultABCIInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -59,10 +59,10 @@ func (mr *MockCometRPCMockRecorder) ABCIInfo(ctx any) *gomock.Call { } // ABCIQuery mocks base method. -func (m *MockCometRPC) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { +func (m *MockCometRPC) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*types.ResultABCIQuery, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ABCIQuery", ctx, path, data) - ret0, _ := ret[0].(*coretypes.ResultABCIQuery) + ret0, _ := ret[0].(*types.ResultABCIQuery) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -74,10 +74,10 @@ func (mr *MockCometRPCMockRecorder) ABCIQuery(ctx, path, data any) *gomock.Call } // ABCIQueryWithOptions mocks base method. -func (m *MockCometRPC) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { +func (m *MockCometRPC) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*types.ResultABCIQuery, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ABCIQueryWithOptions", ctx, path, data, opts) - ret0, _ := ret[0].(*coretypes.ResultABCIQuery) + ret0, _ := ret[0].(*types.ResultABCIQuery) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -89,10 +89,10 @@ func (mr *MockCometRPCMockRecorder) ABCIQueryWithOptions(ctx, path, data, opts a } // Block mocks base method. -func (m *MockCometRPC) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { +func (m *MockCometRPC) Block(ctx context.Context, height *int64) (*types.ResultBlock, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Block", ctx, height) - ret0, _ := ret[0].(*coretypes.ResultBlock) + ret0, _ := ret[0].(*types.ResultBlock) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -104,10 +104,10 @@ func (mr *MockCometRPCMockRecorder) Block(ctx, height any) *gomock.Call { } // BlockByHash mocks base method. -func (m *MockCometRPC) BlockByHash(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error) { +func (m *MockCometRPC) BlockByHash(ctx context.Context, hash []byte) (*types.ResultBlock, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockByHash", ctx, hash) - ret0, _ := ret[0].(*coretypes.ResultBlock) + ret0, _ := ret[0].(*types.ResultBlock) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -119,10 +119,10 @@ func (mr *MockCometRPCMockRecorder) BlockByHash(ctx, hash any) *gomock.Call { } // BlockResults mocks base method. -func (m *MockCometRPC) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) { +func (m *MockCometRPC) BlockResults(ctx context.Context, height *int64) (*types.ResultBlockResults, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockResults", ctx, height) - ret0, _ := ret[0].(*coretypes.ResultBlockResults) + ret0, _ := ret[0].(*types.ResultBlockResults) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -134,10 +134,10 @@ func (mr *MockCometRPCMockRecorder) BlockResults(ctx, height any) *gomock.Call { } // BlockSearch mocks base method. -func (m *MockCometRPC) BlockSearch(ctx context.Context, query string, page, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { +func (m *MockCometRPC) BlockSearch(ctx context.Context, query string, page, perPage *int, orderBy string) (*types.ResultBlockSearch, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockSearch", ctx, query, page, perPage, orderBy) - ret0, _ := ret[0].(*coretypes.ResultBlockSearch) + ret0, _ := ret[0].(*types.ResultBlockSearch) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -149,10 +149,10 @@ func (mr *MockCometRPCMockRecorder) BlockSearch(ctx, query, page, perPage, order } // BlockchainInfo mocks base method. -func (m *MockCometRPC) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { +func (m *MockCometRPC) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*types.ResultBlockchainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockchainInfo", ctx, minHeight, maxHeight) - ret0, _ := ret[0].(*coretypes.ResultBlockchainInfo) + ret0, _ := ret[0].(*types.ResultBlockchainInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -164,10 +164,10 @@ func (mr *MockCometRPCMockRecorder) BlockchainInfo(ctx, minHeight, maxHeight any } // BroadcastTxAsync mocks base method. -func (m *MockCometRPC) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { +func (m *MockCometRPC) BroadcastTxAsync(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTx, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BroadcastTxAsync", ctx, tx) - ret0, _ := ret[0].(*coretypes.ResultBroadcastTx) + ret0, _ := ret[0].(*types.ResultBroadcastTx) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -179,10 +179,10 @@ func (mr *MockCometRPCMockRecorder) BroadcastTxAsync(ctx, tx any) *gomock.Call { } // BroadcastTxCommit mocks base method. -func (m *MockCometRPC) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { +func (m *MockCometRPC) BroadcastTxCommit(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTxCommit, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BroadcastTxCommit", ctx, tx) - ret0, _ := ret[0].(*coretypes.ResultBroadcastTxCommit) + ret0, _ := ret[0].(*types.ResultBroadcastTxCommit) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -194,10 +194,10 @@ func (mr *MockCometRPCMockRecorder) BroadcastTxCommit(ctx, tx any) *gomock.Call } // BroadcastTxSync mocks base method. -func (m *MockCometRPC) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { +func (m *MockCometRPC) BroadcastTxSync(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTx, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BroadcastTxSync", ctx, tx) - ret0, _ := ret[0].(*coretypes.ResultBroadcastTx) + ret0, _ := ret[0].(*types.ResultBroadcastTx) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -209,10 +209,10 @@ func (mr *MockCometRPCMockRecorder) BroadcastTxSync(ctx, tx any) *gomock.Call { } // Commit mocks base method. -func (m *MockCometRPC) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { +func (m *MockCometRPC) Commit(ctx context.Context, height *int64) (*types.ResultCommit, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Commit", ctx, height) - ret0, _ := ret[0].(*coretypes.ResultCommit) + ret0, _ := ret[0].(*types.ResultCommit) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -224,10 +224,10 @@ func (mr *MockCometRPCMockRecorder) Commit(ctx, height any) *gomock.Call { } // Status mocks base method. -func (m *MockCometRPC) Status(arg0 context.Context) (*coretypes.ResultStatus, error) { +func (m *MockCometRPC) Status(arg0 context.Context) (*types.ResultStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Status", arg0) - ret0, _ := ret[0].(*coretypes.ResultStatus) + ret0, _ := ret[0].(*types.ResultStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -239,10 +239,10 @@ func (mr *MockCometRPCMockRecorder) Status(arg0 any) *gomock.Call { } // Tx mocks base method. -func (m *MockCometRPC) Tx(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) { +func (m *MockCometRPC) Tx(ctx context.Context, hash []byte, prove bool) (*types.ResultTx, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Tx", ctx, hash, prove) - ret0, _ := ret[0].(*coretypes.ResultTx) + ret0, _ := ret[0].(*types.ResultTx) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -254,10 +254,10 @@ func (mr *MockCometRPCMockRecorder) Tx(ctx, hash, prove any) *gomock.Call { } // TxSearch mocks base method. -func (m *MockCometRPC) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { +func (m *MockCometRPC) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (*types.ResultTxSearch, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "TxSearch", ctx, query, prove, page, perPage, orderBy) - ret0, _ := ret[0].(*coretypes.ResultTxSearch) + ret0, _ := ret[0].(*types.ResultTxSearch) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -269,10 +269,10 @@ func (mr *MockCometRPCMockRecorder) TxSearch(ctx, query, prove, page, perPage, o } // Validators mocks base method. -func (m *MockCometRPC) Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) { +func (m *MockCometRPC) Validators(ctx context.Context, height *int64, page, perPage *int) (*types.ResultValidators, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Validators", ctx, height, page, perPage) - ret0, _ := ret[0].(*coretypes.ResultValidators) + ret0, _ := ret[0].(*types.ResultValidators) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index 1018534c81bc..09a19a3cc6ea 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -28,3 +28,4 @@ $mockgen_cmd -source=x/auth/vesting/types/expected_keepers.go -package testutil $mockgen_cmd -source=x/protocolpool/types/expected_keepers.go -package testutil -destination x/protocolpool/testutil/expected_keepers_mocks.go $mockgen_cmd -source=x/upgrade/types/expected_keepers.go -package testutil -destination x/upgrade/testutil/expected_keepers_mocks.go $mockgen_cmd -source=core/gas/service.go -package gas -destination core/testing/gas/service_mocks.go +$mockgen_cmd -source=client/v2/internal/comet/comet.go -package testutil -destination client/v2/internal/comet/testutil/comet_mock.go From 71e1c4a44f5adeb346286dd0a24d4868be12c76f Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Tue, 22 Oct 2024 11:06:59 +0200 Subject: [PATCH 10/18] ./scripts/go-mod-tidy-all.sh --- client/v2/go.mod | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/v2/go.mod b/client/v2/go.mod index 9e7fc0cce67b..a5c7f8968c47 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -13,7 +13,7 @@ require ( github.com/cosmos/cosmos-sdk v0.53.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 - go.uber.org/mock v0.4.0 + go.uber.org/mock v0.5.0 google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.35.1 gotest.tools/v3 v3.5.1 @@ -152,7 +152,6 @@ require ( gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect go.opencensus.io v0.24.0 // indirect - go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.28.0 // indirect golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect From dc9e1f4a8a4341a8efcbdb684953a9ab2e302b71 Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Tue, 22 Oct 2024 11:10:07 +0200 Subject: [PATCH 11/18] make mocks --- .../v2/internal/comet/testutil/comet_mock.go | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/client/v2/internal/comet/testutil/comet_mock.go b/client/v2/internal/comet/testutil/comet_mock.go index 97a943a4e170..abf2bcc83244 100644 --- a/client/v2/internal/comet/testutil/comet_mock.go +++ b/client/v2/internal/comet/testutil/comet_mock.go @@ -15,8 +15,8 @@ import ( bytes "github.com/cometbft/cometbft/libs/bytes" client "github.com/cometbft/cometbft/rpc/client" - types "github.com/cometbft/cometbft/rpc/core/types" - types0 "github.com/cometbft/cometbft/types" + coretypes "github.com/cometbft/cometbft/rpc/core/types" + types "github.com/cometbft/cometbft/types" gomock "go.uber.org/mock/gomock" ) @@ -24,6 +24,7 @@ import ( type MockCometRPC struct { ctrl *gomock.Controller recorder *MockCometRPCMockRecorder + isgomock struct{} } // MockCometRPCMockRecorder is the mock recorder for MockCometRPC. @@ -44,10 +45,10 @@ func (m *MockCometRPC) EXPECT() *MockCometRPCMockRecorder { } // ABCIInfo mocks base method. -func (m *MockCometRPC) ABCIInfo(ctx context.Context) (*types.ResultABCIInfo, error) { +func (m *MockCometRPC) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ABCIInfo", ctx) - ret0, _ := ret[0].(*types.ResultABCIInfo) + ret0, _ := ret[0].(*coretypes.ResultABCIInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -59,10 +60,10 @@ func (mr *MockCometRPCMockRecorder) ABCIInfo(ctx any) *gomock.Call { } // ABCIQuery mocks base method. -func (m *MockCometRPC) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*types.ResultABCIQuery, error) { +func (m *MockCometRPC) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ABCIQuery", ctx, path, data) - ret0, _ := ret[0].(*types.ResultABCIQuery) + ret0, _ := ret[0].(*coretypes.ResultABCIQuery) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -74,10 +75,10 @@ func (mr *MockCometRPCMockRecorder) ABCIQuery(ctx, path, data any) *gomock.Call } // ABCIQueryWithOptions mocks base method. -func (m *MockCometRPC) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*types.ResultABCIQuery, error) { +func (m *MockCometRPC) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ABCIQueryWithOptions", ctx, path, data, opts) - ret0, _ := ret[0].(*types.ResultABCIQuery) + ret0, _ := ret[0].(*coretypes.ResultABCIQuery) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -89,10 +90,10 @@ func (mr *MockCometRPCMockRecorder) ABCIQueryWithOptions(ctx, path, data, opts a } // Block mocks base method. -func (m *MockCometRPC) Block(ctx context.Context, height *int64) (*types.ResultBlock, error) { +func (m *MockCometRPC) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Block", ctx, height) - ret0, _ := ret[0].(*types.ResultBlock) + ret0, _ := ret[0].(*coretypes.ResultBlock) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -104,10 +105,10 @@ func (mr *MockCometRPCMockRecorder) Block(ctx, height any) *gomock.Call { } // BlockByHash mocks base method. -func (m *MockCometRPC) BlockByHash(ctx context.Context, hash []byte) (*types.ResultBlock, error) { +func (m *MockCometRPC) BlockByHash(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockByHash", ctx, hash) - ret0, _ := ret[0].(*types.ResultBlock) + ret0, _ := ret[0].(*coretypes.ResultBlock) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -119,10 +120,10 @@ func (mr *MockCometRPCMockRecorder) BlockByHash(ctx, hash any) *gomock.Call { } // BlockResults mocks base method. -func (m *MockCometRPC) BlockResults(ctx context.Context, height *int64) (*types.ResultBlockResults, error) { +func (m *MockCometRPC) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockResults", ctx, height) - ret0, _ := ret[0].(*types.ResultBlockResults) + ret0, _ := ret[0].(*coretypes.ResultBlockResults) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -134,10 +135,10 @@ func (mr *MockCometRPCMockRecorder) BlockResults(ctx, height any) *gomock.Call { } // BlockSearch mocks base method. -func (m *MockCometRPC) BlockSearch(ctx context.Context, query string, page, perPage *int, orderBy string) (*types.ResultBlockSearch, error) { +func (m *MockCometRPC) BlockSearch(ctx context.Context, query string, page, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockSearch", ctx, query, page, perPage, orderBy) - ret0, _ := ret[0].(*types.ResultBlockSearch) + ret0, _ := ret[0].(*coretypes.ResultBlockSearch) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -149,10 +150,10 @@ func (mr *MockCometRPCMockRecorder) BlockSearch(ctx, query, page, perPage, order } // BlockchainInfo mocks base method. -func (m *MockCometRPC) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*types.ResultBlockchainInfo, error) { +func (m *MockCometRPC) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockchainInfo", ctx, minHeight, maxHeight) - ret0, _ := ret[0].(*types.ResultBlockchainInfo) + ret0, _ := ret[0].(*coretypes.ResultBlockchainInfo) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -164,10 +165,10 @@ func (mr *MockCometRPCMockRecorder) BlockchainInfo(ctx, minHeight, maxHeight any } // BroadcastTxAsync mocks base method. -func (m *MockCometRPC) BroadcastTxAsync(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTx, error) { +func (m *MockCometRPC) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BroadcastTxAsync", ctx, tx) - ret0, _ := ret[0].(*types.ResultBroadcastTx) + ret0, _ := ret[0].(*coretypes.ResultBroadcastTx) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -179,10 +180,10 @@ func (mr *MockCometRPCMockRecorder) BroadcastTxAsync(ctx, tx any) *gomock.Call { } // BroadcastTxCommit mocks base method. -func (m *MockCometRPC) BroadcastTxCommit(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTxCommit, error) { +func (m *MockCometRPC) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BroadcastTxCommit", ctx, tx) - ret0, _ := ret[0].(*types.ResultBroadcastTxCommit) + ret0, _ := ret[0].(*coretypes.ResultBroadcastTxCommit) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -194,10 +195,10 @@ func (mr *MockCometRPCMockRecorder) BroadcastTxCommit(ctx, tx any) *gomock.Call } // BroadcastTxSync mocks base method. -func (m *MockCometRPC) BroadcastTxSync(ctx context.Context, tx types0.Tx) (*types.ResultBroadcastTx, error) { +func (m *MockCometRPC) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BroadcastTxSync", ctx, tx) - ret0, _ := ret[0].(*types.ResultBroadcastTx) + ret0, _ := ret[0].(*coretypes.ResultBroadcastTx) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -209,10 +210,10 @@ func (mr *MockCometRPCMockRecorder) BroadcastTxSync(ctx, tx any) *gomock.Call { } // Commit mocks base method. -func (m *MockCometRPC) Commit(ctx context.Context, height *int64) (*types.ResultCommit, error) { +func (m *MockCometRPC) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Commit", ctx, height) - ret0, _ := ret[0].(*types.ResultCommit) + ret0, _ := ret[0].(*coretypes.ResultCommit) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -224,10 +225,10 @@ func (mr *MockCometRPCMockRecorder) Commit(ctx, height any) *gomock.Call { } // Status mocks base method. -func (m *MockCometRPC) Status(arg0 context.Context) (*types.ResultStatus, error) { +func (m *MockCometRPC) Status(arg0 context.Context) (*coretypes.ResultStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Status", arg0) - ret0, _ := ret[0].(*types.ResultStatus) + ret0, _ := ret[0].(*coretypes.ResultStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -239,10 +240,10 @@ func (mr *MockCometRPCMockRecorder) Status(arg0 any) *gomock.Call { } // Tx mocks base method. -func (m *MockCometRPC) Tx(ctx context.Context, hash []byte, prove bool) (*types.ResultTx, error) { +func (m *MockCometRPC) Tx(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Tx", ctx, hash, prove) - ret0, _ := ret[0].(*types.ResultTx) + ret0, _ := ret[0].(*coretypes.ResultTx) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -254,10 +255,10 @@ func (mr *MockCometRPCMockRecorder) Tx(ctx, hash, prove any) *gomock.Call { } // TxSearch mocks base method. -func (m *MockCometRPC) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (*types.ResultTxSearch, error) { +func (m *MockCometRPC) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "TxSearch", ctx, query, prove, page, perPage, orderBy) - ret0, _ := ret[0].(*types.ResultTxSearch) + ret0, _ := ret[0].(*coretypes.ResultTxSearch) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -269,10 +270,10 @@ func (mr *MockCometRPCMockRecorder) TxSearch(ctx, query, prove, page, perPage, o } // Validators mocks base method. -func (m *MockCometRPC) Validators(ctx context.Context, height *int64, page, perPage *int) (*types.ResultValidators, error) { +func (m *MockCometRPC) Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Validators", ctx, height, page, perPage) - ret0, _ := ret[0].(*types.ResultValidators) + ret0, _ := ret[0].(*coretypes.ResultValidators) ret1, _ := ret[1].(error) return ret0, ret1 } From ea3ffb8895245b144838b8e4e5b07b005d88bcde Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Tue, 22 Oct 2024 11:19:57 +0200 Subject: [PATCH 12/18] update: rabbit enablements --- client/v2/broadcast/factory.go | 6 +++--- client/v2/broadcast/factory_test.go | 4 +++- client/v2/internal/comet/comet.go | 12 ++++++++++++ client/v2/internal/comet/comet_test.go | 22 +++++++++++++++++----- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/client/v2/broadcast/factory.go b/client/v2/broadcast/factory.go index 82bad2cae5be..47b79df64126 100644 --- a/client/v2/broadcast/factory.go +++ b/client/v2/broadcast/factory.go @@ -8,7 +8,7 @@ import ( "cosmossdk.io/client/v2/internal/comet" ) -var _ types.BroadcasterFactory = Factory{} +var _ types.BroadcasterFactory = &Factory{} // Factory is a factory for creating Broadcaster instances. type Factory struct { @@ -16,7 +16,7 @@ type Factory struct { } // Create creates a new Broadcaster based on the given consensus type. -func (f Factory) Create(_ context.Context, consensus, url string, opts ...types.Option) (types.Broadcaster, error) { +func (f *Factory) Create(_ context.Context, consensus, url string, opts ...types.Option) (types.Broadcaster, error) { creator, ok := f.engines[consensus] if !ok { return nil, fmt.Errorf("invalid consensus type: %s", consensus) @@ -25,7 +25,7 @@ func (f Factory) Create(_ context.Context, consensus, url string, opts ...types. } // Register adds a new BroadcasterCreator for a given consensus type to the factory. -func (f Factory) Register(consensus string, creator types.NewBroadcasterFn) { +func (f *Factory) Register(consensus string, creator types.NewBroadcasterFn) { f.engines[consensus] = creator } diff --git a/client/v2/broadcast/factory_test.go b/client/v2/broadcast/factory_test.go index 9f4dc8b236cb..ebe1b9459414 100644 --- a/client/v2/broadcast/factory_test.go +++ b/client/v2/broadcast/factory_test.go @@ -8,6 +8,8 @@ import ( "cosmossdk.io/client/v2/broadcast/types" "cosmossdk.io/client/v2/internal/comet" + + "github.com/cosmos/cosmos-sdk/codec/testutil" ) type testBFT struct{} @@ -33,7 +35,7 @@ func Test_newBroadcaster(t *testing.T) { name: "comet", consensus: "comet", opts: []types.Option{ - comet.WithMode(comet.BroadcastSync), + comet.WithJsonCodec(testutil.CodecOptions{}.NewCodec()), }, want: &comet.CometBFTBroadcaster{}, }, diff --git a/client/v2/internal/comet/comet.go b/client/v2/internal/comet/comet.go index 597c14d43be6..b10c3287370b 100644 --- a/client/v2/internal/comet/comet.go +++ b/client/v2/internal/comet/comet.go @@ -100,6 +100,14 @@ func NewCometBFTBroadcaster(rpcURL string, opts ...broadcasttypes.Option) (*Come opt(bc) } + if bc.cdc == nil { + return nil, fmt.Errorf("missing codec, make sure to initialize with 'WithJsonCodec' option") + } + + if bc.mode == "" { + bc.mode = BroadcastSync + } + bc.rpcClient = *rpcClient return bc, nil } @@ -111,6 +119,10 @@ func (c CometBFTBroadcaster) Consensus() string { // 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) { + if c.cdc == nil { + return []byte{}, fmt.Errorf("JSON codec is not initialized") + } + var fn func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error) switch c.mode { case BroadcastSync: diff --git a/client/v2/internal/comet/comet_test.go b/client/v2/internal/comet/comet_test.go index 52ae3849c15f..b8f7bb052f00 100644 --- a/client/v2/internal/comet/comet_test.go +++ b/client/v2/internal/comet/comet_test.go @@ -37,16 +37,28 @@ func TestNewCometBftBroadcaster(t *testing.T) { cdc: cdc, }, }, + { + name: "missing codec", + opts: []broadcasttypes.Option{ + WithMode(BroadcastSync), + }, + want: &CometBFTBroadcaster{ + mode: BroadcastSync, + cdc: cdc, + }, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := NewCometBFTBroadcaster("localhost:26657", tt.opts...) - if (err != nil) != tt.wantErr { - t.Errorf("NewCometBftBroadcaster() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr { + require.Error(t, err) + require.Nil(t, got) + } else { + require.Equal(t, got.mode, tt.want.mode) + require.Equal(t, got.cdc, tt.want.cdc) } - require.Equal(t, got.mode, tt.want.mode) - require.Equal(t, got.cdc, tt.want.cdc) }) } } From cb472db5c4b5b39630b34e499660c8cd1ab80b8e Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Wed, 23 Oct 2024 16:21:32 +0200 Subject: [PATCH 13/18] fix: create makes use of context --- client/v2/broadcast/factory.go | 6 +++--- client/v2/broadcast/factory_test.go | 2 +- client/v2/broadcast/types/broadcaster.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/v2/broadcast/factory.go b/client/v2/broadcast/factory.go index 47b79df64126..5931795ebf80 100644 --- a/client/v2/broadcast/factory.go +++ b/client/v2/broadcast/factory.go @@ -16,12 +16,12 @@ type Factory struct { } // Create creates a new Broadcaster based on the given consensus type. -func (f *Factory) Create(_ context.Context, consensus, url string, opts ...types.Option) (types.Broadcaster, error) { +func (f *Factory) Create(ctx context.Context, consensus, url string, opts ...types.Option) (types.Broadcaster, error) { creator, ok := f.engines[consensus] if !ok { return nil, fmt.Errorf("invalid consensus type: %s", consensus) } - return creator(url, opts...) + return creator(ctx, url, opts...) } // Register adds a new BroadcasterCreator for a given consensus type to the factory. @@ -33,7 +33,7 @@ func (f *Factory) Register(consensus string, creator types.NewBroadcasterFn) { func NewFactory() Factory { return Factory{ engines: map[string]types.NewBroadcasterFn{ - "comet": func(url string, opts ...types.Option) (types.Broadcaster, error) { + "comet": func(_ context.Context, url string, opts ...types.Option) (types.Broadcaster, error) { return comet.NewCometBFTBroadcaster(url, opts...) }, }, diff --git a/client/v2/broadcast/factory_test.go b/client/v2/broadcast/factory_test.go index ebe1b9459414..a219d88faafc 100644 --- a/client/v2/broadcast/factory_test.go +++ b/client/v2/broadcast/factory_test.go @@ -68,7 +68,7 @@ func TestFactory_Register(t *testing.T) { { name: "register new broadcaster", consensus: "testBFT", - creator: func(url string, opts ...types.Option) (types.Broadcaster, error) { + creator: func(_ context.Context, _ string, _ ...types.Option) (types.Broadcaster, error) { return testBFT{}, nil }, }, diff --git a/client/v2/broadcast/types/broadcaster.go b/client/v2/broadcast/types/broadcaster.go index 161533ffe1a6..d8ce135c5991 100644 --- a/client/v2/broadcast/types/broadcaster.go +++ b/client/v2/broadcast/types/broadcaster.go @@ -16,7 +16,7 @@ type ( } // NewBroadcasterFn is a function type for creating Broadcaster instances. - NewBroadcasterFn func(url string, opts ...Option) (Broadcaster, error) + NewBroadcasterFn func(ctx context.Context, url string, opts ...Option) (Broadcaster, error) // BroadcasterFactory defines an interface for creating and registering Broadcasters. BroadcasterFactory interface { From 4ecd77fe75d1bdc42e365295caae3a7a5ac04899 Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Wed, 23 Oct 2024 17:18:59 +0200 Subject: [PATCH 14/18] update: use broadcaster in v2/tx --- client/v2/tx/tx.go | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/client/v2/tx/tx.go b/client/v2/tx/tx.go index 64e0199d8172..611dec6bd1ca 100644 --- a/client/v2/tx/tx.go +++ b/client/v2/tx/tx.go @@ -2,6 +2,7 @@ package tx import ( "bufio" + "context" "errors" "fmt" "os" @@ -10,7 +11,10 @@ import ( "github.com/spf13/pflag" apitxsigning "cosmossdk.io/api/cosmos/tx/signing/v1beta1" + "cosmossdk.io/client/v2/broadcast" + broadcasttypes "cosmossdk.io/client/v2/broadcast/types" "cosmossdk.io/client/v2/internal/account" + "cosmossdk.io/client/v2/internal/comet" "cosmossdk.io/core/transaction" "github.com/cosmos/cosmos-sdk/client" @@ -40,7 +44,19 @@ func GenerateOrBroadcastTxCLI(ctx client.Context, flagSet *pflag.FlagSet, msgs . return dryRun(txf, msgs...) } - return BroadcastTx(ctx, txf, msgs...) + broadcaster, err := getBroadcaster(ctx, flagSet) + if err != nil { + return err + } + + return BroadcastTx(ctx, txf, broadcaster, msgs...) +} + +func getBroadcaster(ctx client.Context, flagSet *pflag.FlagSet) (broadcasttypes.Broadcaster, error) { + url, _ := flagSet.GetString("node") + mode, _ := flagSet.GetString("broadcast-mode") + f := broadcast.NewFactory() + return f.Create(context.Background(), "comet", url, comet.WithMode(mode), comet.WithJsonCodec(ctx.Codec)) } // newFactory creates a new transaction Factory based on the provided context and flag set. @@ -129,7 +145,7 @@ func SimulateTx(ctx client.Context, flagSet *pflag.FlagSet, msgs ...transaction. // BroadcastTx attempts to generate, sign and broadcast a transaction with the // given set of messages. It will also simulate gas requirements if necessary. // It will return an error upon failure. -func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...transaction.Msg) error { +func BroadcastTx(clientCtx client.Context, txf Factory, broadcaster broadcasttypes.Broadcaster, msgs ...transaction.Msg) error { if txf.simulateAndExecute() { err := txf.calculateGas(msgs...) if err != nil { @@ -183,13 +199,12 @@ func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...transaction.Msg) return err } - // broadcast to a CometBFT node - res, err := clientCtx.BroadcastTx(txBytes) + res, err := broadcaster.Broadcast(context.Background(), txBytes) if err != nil { return err } - return clientCtx.PrintProto(res) + return clientCtx.PrintString(string(res)) } // countDirectSigners counts the number of DIRECT signers in a signature data. From 00fe5a3eb10e6a30bf935026bb479f88615f8887 Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Thu, 24 Oct 2024 17:17:36 +0200 Subject: [PATCH 15/18] update: remove factory + public --- client/v2/broadcast/broadcaster.go | 15 ++++ .../v2/{internal => broadcast}/comet/comet.go | 49 +++-------- .../comet/comet_test.go | 27 +++--- .../comet/testutil/comet_mock.go | 4 +- client/v2/broadcast/factory.go | 41 --------- client/v2/broadcast/factory_test.go | 88 ------------------- client/v2/broadcast/types/broadcaster.go | 32 ------- client/v2/tx/tx.go | 39 +++++--- scripts/mockgen.sh | 2 +- 9 files changed, 70 insertions(+), 227 deletions(-) create mode 100644 client/v2/broadcast/broadcaster.go rename client/v2/{internal => broadcast}/comet/comet.go (85%) rename client/v2/{internal => broadcast}/comet/comet_test.go (84%) rename client/v2/{internal => broadcast}/comet/testutil/comet_mock.go (98%) delete mode 100644 client/v2/broadcast/factory.go delete mode 100644 client/v2/broadcast/factory_test.go delete mode 100644 client/v2/broadcast/types/broadcaster.go diff --git a/client/v2/broadcast/broadcaster.go b/client/v2/broadcast/broadcaster.go new file mode 100644 index 000000000000..bcee034be740 --- /dev/null +++ b/client/v2/broadcast/broadcaster.go @@ -0,0 +1,15 @@ +package broadcast + +import "context" + +// Broadcaster defines an interface for broadcasting transactions to the consensus engine. +type Broadcaster interface { + // Broadcast sends a transaction to the network and returns the result. + // + // 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 +} diff --git a/client/v2/internal/comet/comet.go b/client/v2/broadcast/comet/comet.go similarity index 85% rename from client/v2/internal/comet/comet.go rename to client/v2/broadcast/comet/comet.go index b10c3287370b..d1a1ec670be5 100644 --- a/client/v2/internal/comet/comet.go +++ b/client/v2/broadcast/comet/comet.go @@ -3,6 +3,7 @@ package comet import ( "context" "encoding/json" + "errors" "fmt" "strings" @@ -13,7 +14,7 @@ import ( cmttypes "github.com/cometbft/cometbft/types" apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" - broadcasttypes "cosmossdk.io/client/v2/broadcast/types" + "cosmossdk.io/client/v2/broadcast" "github.com/cosmos/cosmos-sdk/codec" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -59,7 +60,7 @@ type CometRPC interface { ) (*coretypes.ResultBlockSearch, error) } -var _ broadcasttypes.Broadcaster = CometBFTBroadcaster{} +var _ broadcast.Broadcaster = CometBFTBroadcaster{} // CometBFTBroadcaster implements the Broadcaster interface for CometBFT consensus engine. type CometBFTBroadcaster struct { @@ -68,48 +69,26 @@ type CometBFTBroadcaster struct { cdc codec.JSONCodec } -func WithMode(mode string) func(broadcaster broadcasttypes.Broadcaster) { - return func(b broadcasttypes.Broadcaster) { - cbc, ok := b.(*CometBFTBroadcaster) - if !ok { - return - } - cbc.mode = mode +// NewCometBFTBroadcaster creates a new CometBftBroadcaster. +func NewCometBFTBroadcaster(rpcURL, mode string, cdc codec.JSONCodec) (*CometBFTBroadcaster, error) { + if cdc == nil { + return nil, errors.New("codec can't be nil") } -} -func WithJsonCodec(codec codec.JSONCodec) func(broadcaster broadcasttypes.Broadcaster) { - return func(b broadcasttypes.Broadcaster) { - cbc, ok := b.(*CometBFTBroadcaster) - if !ok { - return - } - cbc.cdc = codec + if mode == "" { + mode = BroadcastSync } -} -// NewCometBFTBroadcaster creates a new CometBftBroadcaster. -func NewCometBFTBroadcaster(rpcURL string, opts ...broadcasttypes.Option) (*CometBFTBroadcaster, error) { rpcClient, err := rpchttp.New(rpcURL) if err != nil { return nil, fmt.Errorf("failed to create CometBft RPC client: %w", err) } - bc := &CometBFTBroadcaster{} - for _, opt := range opts { - opt(bc) - } - - if bc.cdc == nil { - return nil, fmt.Errorf("missing codec, make sure to initialize with 'WithJsonCodec' option") - } - - if bc.mode == "" { - bc.mode = BroadcastSync - } - - bc.rpcClient = *rpcClient - return bc, nil + return &CometBFTBroadcaster{ + rpcClient: rpcClient, + mode: mode, + cdc: cdc, + }, nil } func (c CometBFTBroadcaster) Consensus() string { diff --git a/client/v2/internal/comet/comet_test.go b/client/v2/broadcast/comet/comet_test.go similarity index 84% rename from client/v2/internal/comet/comet_test.go rename to client/v2/broadcast/comet/comet_test.go index b8f7bb052f00..d7577f0f760f 100644 --- a/client/v2/internal/comet/comet_test.go +++ b/client/v2/broadcast/comet/comet_test.go @@ -2,7 +2,9 @@ package comet import ( "context" + mockrpc "cosmossdk.io/client/v2/broadcast/comet/testutil" "errors" + "github.com/cosmos/cosmos-sdk/codec" "testing" "github.com/cometbft/cometbft/mempool" @@ -11,9 +13,6 @@ import ( "go.uber.org/mock/gomock" apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" - broadcasttypes "cosmossdk.io/client/v2/broadcast/types" - mockrpc "cosmossdk.io/client/v2/internal/comet/testutil" - "github.com/cosmos/cosmos-sdk/codec/testutil" ) @@ -22,36 +21,30 @@ var cdc = testutil.CodecOptions{}.NewCodec() func TestNewCometBftBroadcaster(t *testing.T) { tests := []struct { name string - opts []broadcasttypes.Option + cdc codec.JSONCodec + mode string want *CometBFTBroadcaster wantErr bool }{ { name: "constructor", - opts: []broadcasttypes.Option{ - WithMode(BroadcastSync), - WithJsonCodec(cdc), - }, + mode: BroadcastSync, + cdc: cdc, want: &CometBFTBroadcaster{ mode: BroadcastSync, cdc: cdc, }, }, { - name: "missing codec", - opts: []broadcasttypes.Option{ - WithMode(BroadcastSync), - }, - want: &CometBFTBroadcaster{ - mode: BroadcastSync, - cdc: cdc, - }, + name: "nil codec", + mode: BroadcastSync, + cdc: nil, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewCometBFTBroadcaster("localhost:26657", tt.opts...) + got, err := NewCometBFTBroadcaster("localhost:26657", tt.mode, tt.cdc) if tt.wantErr { require.Error(t, err) require.Nil(t, got) diff --git a/client/v2/internal/comet/testutil/comet_mock.go b/client/v2/broadcast/comet/testutil/comet_mock.go similarity index 98% rename from client/v2/internal/comet/testutil/comet_mock.go rename to client/v2/broadcast/comet/testutil/comet_mock.go index abf2bcc83244..75cdc50af713 100644 --- a/client/v2/internal/comet/testutil/comet_mock.go +++ b/client/v2/broadcast/comet/testutil/comet_mock.go @@ -1,9 +1,9 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: client/v2/internal/comet/comet.go +// Source: client/v2/broadcast/comet/comet.go // // Generated by this command: // -// mockgen -source=client/v2/internal/comet/comet.go -package testutil -destination client/v2/internal/comet/testutil/comet_mock.go +// mockgen -source=client/v2/broadcast/comet/comet.go -package testutil -destination client/v2/broadcast/comet/testutil/comet_mock.go // // Package testutil is a generated GoMock package. diff --git a/client/v2/broadcast/factory.go b/client/v2/broadcast/factory.go deleted file mode 100644 index 5931795ebf80..000000000000 --- a/client/v2/broadcast/factory.go +++ /dev/null @@ -1,41 +0,0 @@ -package broadcast - -import ( - "context" - "fmt" - - "cosmossdk.io/client/v2/broadcast/types" - "cosmossdk.io/client/v2/internal/comet" -) - -var _ types.BroadcasterFactory = &Factory{} - -// Factory is a factory for creating Broadcaster instances. -type Factory struct { - engines map[string]types.NewBroadcasterFn -} - -// Create creates a new Broadcaster based on the given consensus type. -func (f *Factory) Create(ctx context.Context, consensus, url string, opts ...types.Option) (types.Broadcaster, error) { - creator, ok := f.engines[consensus] - if !ok { - return nil, fmt.Errorf("invalid consensus type: %s", consensus) - } - return creator(ctx, url, opts...) -} - -// Register adds a new BroadcasterCreator for a given consensus type to the factory. -func (f *Factory) Register(consensus string, creator types.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]types.NewBroadcasterFn{ - "comet": func(_ context.Context, url string, opts ...types.Option) (types.Broadcaster, error) { - return comet.NewCometBFTBroadcaster(url, opts...) - }, - }, - } -} diff --git a/client/v2/broadcast/factory_test.go b/client/v2/broadcast/factory_test.go deleted file mode 100644 index a219d88faafc..000000000000 --- a/client/v2/broadcast/factory_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package broadcast - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - - "cosmossdk.io/client/v2/broadcast/types" - "cosmossdk.io/client/v2/internal/comet" - - "github.com/cosmos/cosmos-sdk/codec/testutil" -) - -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 - opts []types.Option - want types.Broadcaster - wantErr bool - }{ - { - name: "comet", - consensus: "comet", - opts: []types.Option{ - comet.WithJsonCodec(testutil.CodecOptions{}.NewCodec()), - }, - want: &comet.CometBFTBroadcaster{}, - }, - { - name: "unsupported_consensus", - consensus: "unsupported", - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := f.Create(context.Background(), tt.consensus, "localhost:26657", tt.opts...) - if tt.wantErr { - require.Error(t, err) - } else { - require.NoError(t, err) - require.NotNil(t, got) - require.IsType(t, tt.want, got) - } - }) - } -} - -func TestFactory_Register(t *testing.T) { - tests := []struct { - name string - consensus string - creator types.NewBroadcasterFn - }{ - { - name: "register new broadcaster", - consensus: "testBFT", - creator: func(_ context.Context, _ string, _ ...types.Option) (types.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()) - }) - } -} diff --git a/client/v2/broadcast/types/broadcaster.go b/client/v2/broadcast/types/broadcaster.go deleted file mode 100644 index d8ce135c5991..000000000000 --- a/client/v2/broadcast/types/broadcaster.go +++ /dev/null @@ -1,32 +0,0 @@ -package types - -import "context" - -type ( - // Broadcaster defines an interface for broadcasting transactions to the consensus engine. - Broadcaster interface { - // Broadcast sends a transaction to the network and returns the result. - // - // 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 - } - - // NewBroadcasterFn is a function type for creating Broadcaster instances. - NewBroadcasterFn func(ctx context.Context, 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) -) diff --git a/client/v2/tx/tx.go b/client/v2/tx/tx.go index 611dec6bd1ca..941ac1b07054 100644 --- a/client/v2/tx/tx.go +++ b/client/v2/tx/tx.go @@ -7,14 +7,14 @@ import ( "fmt" "os" + "cosmossdk.io/client/v2/broadcast/comet" + "github.com/cosmos/gogoproto/proto" "github.com/spf13/pflag" apitxsigning "cosmossdk.io/api/cosmos/tx/signing/v1beta1" "cosmossdk.io/client/v2/broadcast" - broadcasttypes "cosmossdk.io/client/v2/broadcast/types" "cosmossdk.io/client/v2/internal/account" - "cosmossdk.io/client/v2/internal/comet" "cosmossdk.io/core/transaction" "github.com/cosmos/cosmos-sdk/client" @@ -22,9 +22,9 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keyring" ) -// GenerateOrBroadcastTxCLI will either generate and print an unsigned transaction -// or sign it and broadcast it returning an error upon failure. -func GenerateOrBroadcastTxCLI(ctx client.Context, flagSet *pflag.FlagSet, msgs ...transaction.Msg) error { +// GenerateOrBroadcastTxCLIWithBroadcaste will either generate and print an unsigned transaction +// or sign it and broadcast it with the specified broadcaster returning an error upon failure. +func GenerateOrBroadcastTxCLIWithBroadcaste(ctx client.Context, flagSet *pflag.FlagSet, broadcaster broadcast.Broadcaster, msgs ...transaction.Msg) error { if err := validateMessages(msgs...); err != nil { return err } @@ -44,19 +44,36 @@ func GenerateOrBroadcastTxCLI(ctx client.Context, flagSet *pflag.FlagSet, msgs . return dryRun(txf, msgs...) } - broadcaster, err := getBroadcaster(ctx, flagSet) + return BroadcastTx(ctx, txf, broadcaster, msgs...) +} + +// GenerateOrBroadcastTxCLI will either generate and print an unsigned transaction +// or sign it and broadcast it using defaults cometBFT broadcaster, returning an error upon failure. +func GenerateOrBroadcastTxCLI(ctx client.Context, flagSet *pflag.FlagSet, msgs ...transaction.Msg) error { + cometBroadcaster, err := getCometBroadcaster(ctx, flagSet) if err != nil { return err } - return BroadcastTx(ctx, txf, broadcaster, msgs...) + return GenerateOrBroadcastTxCLIWithBroadcaste(ctx, flagSet, cometBroadcaster, msgs...) } -func getBroadcaster(ctx client.Context, flagSet *pflag.FlagSet) (broadcasttypes.Broadcaster, error) { +// getCometBroadcaster returns a new CometBFT broadcaster based on the provided context and flag set. +// +// It retrieves the node URL and broadcast mode from the flag set, and uses these along with the +// context's codec to create and return a new CometBFT broadcaster. +// +// Parameters: +// - ctx: The client context containing the codec and other configuration. +// - flagSet: The flag set containing command-line flags. +// +// Returns: +// - broadcast.Broadcaster: A new CometBFT broadcaster. +// - error: An error if the broadcaster creation fails. +func getCometBroadcaster(ctx client.Context, flagSet *pflag.FlagSet) (broadcast.Broadcaster, error) { url, _ := flagSet.GetString("node") mode, _ := flagSet.GetString("broadcast-mode") - f := broadcast.NewFactory() - return f.Create(context.Background(), "comet", url, comet.WithMode(mode), comet.WithJsonCodec(ctx.Codec)) + return comet.NewCometBFTBroadcaster(url, mode, ctx.Codec) } // newFactory creates a new transaction Factory based on the provided context and flag set. @@ -145,7 +162,7 @@ func SimulateTx(ctx client.Context, flagSet *pflag.FlagSet, msgs ...transaction. // BroadcastTx attempts to generate, sign and broadcast a transaction with the // given set of messages. It will also simulate gas requirements if necessary. // It will return an error upon failure. -func BroadcastTx(clientCtx client.Context, txf Factory, broadcaster broadcasttypes.Broadcaster, msgs ...transaction.Msg) error { +func BroadcastTx(clientCtx client.Context, txf Factory, broadcaster broadcast.Broadcaster, msgs ...transaction.Msg) error { if txf.simulateAndExecute() { err := txf.calculateGas(msgs...) if err != nil { diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index 09a19a3cc6ea..4a13745c0f63 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -28,4 +28,4 @@ $mockgen_cmd -source=x/auth/vesting/types/expected_keepers.go -package testutil $mockgen_cmd -source=x/protocolpool/types/expected_keepers.go -package testutil -destination x/protocolpool/testutil/expected_keepers_mocks.go $mockgen_cmd -source=x/upgrade/types/expected_keepers.go -package testutil -destination x/upgrade/testutil/expected_keepers_mocks.go $mockgen_cmd -source=core/gas/service.go -package gas -destination core/testing/gas/service_mocks.go -$mockgen_cmd -source=client/v2/internal/comet/comet.go -package testutil -destination client/v2/internal/comet/testutil/comet_mock.go +$mockgen_cmd -source=client/v2/broadcast/comet/comet.go -package testutil -destination client/v2/broadcast/comet/testutil/comet_mock.go From 86b8d58d71d6c7d8d28a15df8bb866e435f7c9e0 Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Thu, 24 Oct 2024 17:19:24 +0200 Subject: [PATCH 16/18] lint + typo --- client/v2/broadcast/comet/comet_test.go | 5 +++-- client/v2/tx/tx.go | 17 +++-------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/client/v2/broadcast/comet/comet_test.go b/client/v2/broadcast/comet/comet_test.go index d7577f0f760f..62d29f97ecf3 100644 --- a/client/v2/broadcast/comet/comet_test.go +++ b/client/v2/broadcast/comet/comet_test.go @@ -2,9 +2,7 @@ package comet import ( "context" - mockrpc "cosmossdk.io/client/v2/broadcast/comet/testutil" "errors" - "github.com/cosmos/cosmos-sdk/codec" "testing" "github.com/cometbft/cometbft/mempool" @@ -13,6 +11,9 @@ import ( "go.uber.org/mock/gomock" apiacbci "cosmossdk.io/api/cosmos/base/abci/v1beta1" + mockrpc "cosmossdk.io/client/v2/broadcast/comet/testutil" + + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/testutil" ) diff --git a/client/v2/tx/tx.go b/client/v2/tx/tx.go index 941ac1b07054..87e361227794 100644 --- a/client/v2/tx/tx.go +++ b/client/v2/tx/tx.go @@ -22,9 +22,9 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keyring" ) -// GenerateOrBroadcastTxCLIWithBroadcaste will either generate and print an unsigned transaction +// GenerateOrBroadcastTxCLIWithBroadcaster will either generate and print an unsigned transaction // or sign it and broadcast it with the specified broadcaster returning an error upon failure. -func GenerateOrBroadcastTxCLIWithBroadcaste(ctx client.Context, flagSet *pflag.FlagSet, broadcaster broadcast.Broadcaster, msgs ...transaction.Msg) error { +func GenerateOrBroadcastTxCLIWithBroadcaster(ctx client.Context, flagSet *pflag.FlagSet, broadcaster broadcast.Broadcaster, msgs ...transaction.Msg) error { if err := validateMessages(msgs...); err != nil { return err } @@ -55,21 +55,10 @@ func GenerateOrBroadcastTxCLI(ctx client.Context, flagSet *pflag.FlagSet, msgs . return err } - return GenerateOrBroadcastTxCLIWithBroadcaste(ctx, flagSet, cometBroadcaster, msgs...) + return GenerateOrBroadcastTxCLIWithBroadcaster(ctx, flagSet, cometBroadcaster, msgs...) } // getCometBroadcaster returns a new CometBFT broadcaster based on the provided context and flag set. -// -// It retrieves the node URL and broadcast mode from the flag set, and uses these along with the -// context's codec to create and return a new CometBFT broadcaster. -// -// Parameters: -// - ctx: The client context containing the codec and other configuration. -// - flagSet: The flag set containing command-line flags. -// -// Returns: -// - broadcast.Broadcaster: A new CometBFT broadcaster. -// - error: An error if the broadcaster creation fails. func getCometBroadcaster(ctx client.Context, flagSet *pflag.FlagSet) (broadcast.Broadcaster, error) { url, _ := flagSet.GetString("node") mode, _ := flagSet.GetString("broadcast-mode") From c840773e14a817295c4464b27c3d33fba74d66b5 Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Thu, 24 Oct 2024 17:28:24 +0200 Subject: [PATCH 17/18] lint :/ --- client/v2/tx/tx.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/v2/tx/tx.go b/client/v2/tx/tx.go index 87e361227794..765a6837e712 100644 --- a/client/v2/tx/tx.go +++ b/client/v2/tx/tx.go @@ -7,13 +7,12 @@ import ( "fmt" "os" - "cosmossdk.io/client/v2/broadcast/comet" - "github.com/cosmos/gogoproto/proto" "github.com/spf13/pflag" apitxsigning "cosmossdk.io/api/cosmos/tx/signing/v1beta1" "cosmossdk.io/client/v2/broadcast" + "cosmossdk.io/client/v2/broadcast/comet" "cosmossdk.io/client/v2/internal/account" "cosmossdk.io/core/transaction" From 5b3db1e824d0266f64badcfe9c50e555d44f8b95 Mon Sep 17 00:00:00 2001 From: Julian Toledano Date: Thu, 24 Oct 2024 17:57:05 +0200 Subject: [PATCH 18/18] update: rabbit enhancements --- client/v2/broadcast/comet/comet.go | 24 ++++++------ client/v2/broadcast/comet/comet_test.go | 52 ++++++++++++++++--------- client/v2/tx/tx.go | 2 +- 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/client/v2/broadcast/comet/comet.go b/client/v2/broadcast/comet/comet.go index d1a1ec670be5..e0cfc05a8413 100644 --- a/client/v2/broadcast/comet/comet.go +++ b/client/v2/broadcast/comet/comet.go @@ -60,7 +60,7 @@ type CometRPC interface { ) (*coretypes.ResultBlockSearch, error) } -var _ broadcast.Broadcaster = CometBFTBroadcaster{} +var _ broadcast.Broadcaster = &CometBFTBroadcaster{} // CometBFTBroadcaster implements the Broadcaster interface for CometBFT consensus engine. type CometBFTBroadcaster struct { @@ -69,7 +69,7 @@ type CometBFTBroadcaster struct { cdc codec.JSONCodec } -// NewCometBFTBroadcaster creates a new CometBftBroadcaster. +// NewCometBFTBroadcaster creates a new CometBFTBroadcaster. func NewCometBFTBroadcaster(rpcURL, mode string, cdc codec.JSONCodec) (*CometBFTBroadcaster, error) { if cdc == nil { return nil, errors.New("codec can't be nil") @@ -91,28 +91,30 @@ func NewCometBFTBroadcaster(rpcURL, mode string, cdc codec.JSONCodec) (*CometBFT }, nil } -func (c CometBFTBroadcaster) Consensus() string { +// Consensus returns the consensus engine name used by the broadcaster. +// It always returns "comet" for CometBFTBroadcaster. +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) { +func (c *CometBFTBroadcaster) Broadcast(ctx context.Context, txBytes []byte) ([]byte, error) { if c.cdc == nil { return []byte{}, fmt.Errorf("JSON codec is not initialized") } - var fn func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error) + var broadcastFunc func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error) switch c.mode { case BroadcastSync: - fn = c.rpcClient.BroadcastTxSync + broadcastFunc = c.rpcClient.BroadcastTxSync case BroadcastAsync: - fn = c.rpcClient.BroadcastTxAsync + broadcastFunc = c.rpcClient.BroadcastTxAsync default: return []byte{}, fmt.Errorf("unknown broadcast mode: %s", c.mode) } - res, err := c.broadcast(ctx, txBytes, fn) + res, err := c.broadcast(ctx, txBytes, broadcastFunc) if err != nil { return []byte{}, err } @@ -121,11 +123,11 @@ func (c CometBFTBroadcaster) Broadcast(ctx context.Context, txBytes []byte) ([]b } // broadcast sends a transaction to the CometBFT network using the provided function. -func (c CometBFTBroadcaster) broadcast(ctx context.Context, txbytes []byte, +func (c *CometBFTBroadcaster) broadcast(ctx context.Context, txBytes []byte, fn func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error), ) (*apiacbci.TxResponse, error) { - bResult, err := fn(ctx, txbytes) - if errRes := checkCometError(err, txbytes); err != nil { + bResult, err := fn(ctx, txBytes) + if errRes := checkCometError(err, txBytes); err != nil { return errRes, nil } diff --git a/client/v2/broadcast/comet/comet_test.go b/client/v2/broadcast/comet/comet_test.go index 62d29f97ecf3..0eb8b81685ed 100644 --- a/client/v2/broadcast/comet/comet_test.go +++ b/client/v2/broadcast/comet/comet_test.go @@ -66,32 +66,48 @@ func TestCometBftBroadcaster_Broadcast(t *testing.T) { cdc: cdc, } tests := []struct { - name string - mode string - want []byte - wantErr bool + name string + mode string + setupMock func(*mockrpc.MockCometRPC) + wantErr bool }{ { name: "sync", mode: BroadcastSync, + setupMock: func(m *mockrpc.MockCometRPC) { + m.EXPECT().BroadcastTxSync(context.Background(), gomock.Any()).Return(&coretypes.ResultBroadcastTx{ + Code: 0, + Data: []byte{}, + Log: "", + Codespace: "", + Hash: []byte("%�����\u0010\n�T�\u0017\u0016�N^H[5�\u0006}�n�w�/Vi� "), + }, nil) + }, + }, + { + name: "async", + mode: BroadcastAsync, + setupMock: func(m *mockrpc.MockCometRPC) { + m.EXPECT().BroadcastTxAsync(context.Background(), gomock.Any()).Return(&coretypes.ResultBroadcastTx{ + Code: 0, + Data: []byte{}, + Log: "", + Codespace: "", + Hash: []byte("%�����\u0010\n�T�\u0017\u0016�N^H[5�\u0006}�n�w�/Vi� "), + }, nil) + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c.mode = tt.mode - cometMock.EXPECT().BroadcastTxSync(context.Background(), gomock.Any()).Return(&coretypes.ResultBroadcastTx{ - Code: 0, - Data: []byte{}, - Log: "", - Codespace: "", - Hash: []byte("%�����\u0010\n�T�\u0017\u0016�N^H[5�\u0006}�n�w�/Vi� "), - }, nil) + tt.setupMock(cometMock) got, err := c.Broadcast(context.Background(), []byte{}) - if (err != nil) != tt.wantErr { - t.Errorf("Broadcast() error = %v, wantErr %v", err, tt.wantErr) - return + if tt.wantErr { + require.Error(t, err) + } else { + require.NotNil(t, got) } - require.NotNil(t, got) }) } } @@ -103,21 +119,21 @@ func Test_checkCometError(t *testing.T) { want *apiacbci.TxResponse }{ { - name: "error in cache", + name: "tx already in cache", err: errors.New("tx already exists in cache"), want: &apiacbci.TxResponse{ Code: 19, }, }, { - name: "error in cache", + name: "mempool is full", err: mempool.ErrMempoolIsFull{}, want: &apiacbci.TxResponse{ Code: 20, }, }, { - name: "error in cache", + name: "tx too large", err: mempool.ErrTxTooLarge{}, want: &apiacbci.TxResponse{ Code: 21, diff --git a/client/v2/tx/tx.go b/client/v2/tx/tx.go index 765a6837e712..ab82c813ac20 100644 --- a/client/v2/tx/tx.go +++ b/client/v2/tx/tx.go @@ -47,7 +47,7 @@ func GenerateOrBroadcastTxCLIWithBroadcaster(ctx client.Context, flagSet *pflag. } // GenerateOrBroadcastTxCLI will either generate and print an unsigned transaction -// or sign it and broadcast it using defaults cometBFT broadcaster, returning an error upon failure. +// or sign it and broadcast it using default CometBFT broadcaster, returning an error upon failure. func GenerateOrBroadcastTxCLI(ctx client.Context, flagSet *pflag.FlagSet, msgs ...transaction.Msg) error { cometBroadcaster, err := getCometBroadcaster(ctx, flagSet) if err != nil {