feat(client/v2): broadcast logic (#22282)
This commit is contained in:
parent
31f97e934e
commit
78cfc68c83
@ -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
|
||||
|
||||
|
||||
15
client/v2/broadcast/broadcaster.go
Normal file
15
client/v2/broadcast/broadcaster.go
Normal file
@ -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
|
||||
}
|
||||
197
client/v2/broadcast/comet/comet.go
Normal file
197
client/v2/broadcast/comet/comet.go
Normal file
@ -0,0 +1,197 @@
|
||||
package comet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"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"
|
||||
"cosmossdk.io/client/v2/broadcast"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
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 {
|
||||
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 _ broadcast.Broadcaster = &CometBFTBroadcaster{}
|
||||
|
||||
// CometBFTBroadcaster implements the Broadcaster interface for CometBFT consensus engine.
|
||||
type CometBFTBroadcaster struct {
|
||||
rpcClient CometRPC
|
||||
mode string
|
||||
cdc codec.JSONCodec
|
||||
}
|
||||
|
||||
// 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")
|
||||
}
|
||||
|
||||
if mode == "" {
|
||||
mode = BroadcastSync
|
||||
}
|
||||
|
||||
rpcClient, err := rpchttp.New(rpcURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create CometBft RPC client: %w", err)
|
||||
}
|
||||
|
||||
return &CometBFTBroadcaster{
|
||||
rpcClient: rpcClient,
|
||||
mode: mode,
|
||||
cdc: cdc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if c.cdc == nil {
|
||||
return []byte{}, fmt.Errorf("JSON codec is not initialized")
|
||||
}
|
||||
|
||||
var broadcastFunc func(ctx context.Context, tx cmttypes.Tx) (*coretypes.ResultBroadcastTx, error)
|
||||
switch c.mode {
|
||||
case BroadcastSync:
|
||||
broadcastFunc = c.rpcClient.BroadcastTxSync
|
||||
case BroadcastAsync:
|
||||
broadcastFunc = c.rpcClient.BroadcastTxAsync
|
||||
default:
|
||||
return []byte{}, fmt.Errorf("unknown broadcast mode: %s", c.mode)
|
||||
}
|
||||
|
||||
res, err := c.broadcast(ctx, txBytes, broadcastFunc)
|
||||
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); errRes != 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
|
||||
}
|
||||
149
client/v2/broadcast/comet/comet_test.go
Normal file
149
client/v2/broadcast/comet/comet_test.go
Normal file
@ -0,0 +1,149 @@
|
||||
package comet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"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/broadcast/comet/testutil"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
)
|
||||
|
||||
var cdc = testutil.CodecOptions{}.NewCodec()
|
||||
|
||||
func TestNewCometBftBroadcaster(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cdc codec.JSONCodec
|
||||
mode string
|
||||
want *CometBFTBroadcaster
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "constructor",
|
||||
mode: BroadcastSync,
|
||||
cdc: cdc,
|
||||
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.mode, tt.cdc)
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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("%<25><><EFBFBD><EFBFBD><EFBFBD>\u0010\n<>T<EFBFBD>\u0017\u0016<31>N^H[5<>\u0006}<7D>n<EFBFBD>w<EFBFBD>/Vi<56> "),
|
||||
}, 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("%<25><><EFBFBD><EFBFBD><EFBFBD>\u0010\n<>T<EFBFBD>\u0017\u0016<31>N^H[5<>\u0006}<7D>n<EFBFBD>w<EFBFBD>/Vi<56> "),
|
||||
}, nil)
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c.mode = tt.mode
|
||||
tt.setupMock(cometMock)
|
||||
got, err := c.Broadcast(context.Background(), []byte{})
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NotNil(t, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_checkCometError(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
err error
|
||||
want *apiacbci.TxResponse
|
||||
}{
|
||||
{
|
||||
name: "tx already in cache",
|
||||
err: errors.New("tx already exists in cache"),
|
||||
want: &apiacbci.TxResponse{
|
||||
Code: 19,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "mempool is full",
|
||||
err: mempool.ErrMempoolIsFull{},
|
||||
want: &apiacbci.TxResponse{
|
||||
Code: 20,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tx too large",
|
||||
err: mempool.ErrTxTooLarge{},
|
||||
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)
|
||||
})
|
||||
}
|
||||
}
|
||||
285
client/v2/broadcast/comet/testutil/comet_mock.go
Normal file
285
client/v2/broadcast/comet/testutil/comet_mock.go
Normal file
@ -0,0 +1,285 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: client/v2/broadcast/comet/comet.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// 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.
|
||||
package testutil
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
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"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockCometRPC is a mock of CometRPC interface.
|
||||
type MockCometRPC struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockCometRPCMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// 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) (*coretypes.ResultABCIInfo, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ABCIInfo", ctx)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultABCIQuery, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ABCIQuery", ctx, path, data)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultABCIQuery, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ABCIQueryWithOptions", ctx, path, data, opts)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultBlock, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Block", ctx, height)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultBlock, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockByHash", ctx, hash)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultBlockResults, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockResults", ctx, height)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultBlockSearch, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockSearch", ctx, query, page, perPage, orderBy)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultBlockchainInfo, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockchainInfo", ctx, minHeight, maxHeight)
|
||||
ret0, _ := ret[0].(*coretypes.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 types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BroadcastTxAsync", ctx, tx)
|
||||
ret0, _ := ret[0].(*coretypes.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 types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BroadcastTxCommit", ctx, tx)
|
||||
ret0, _ := ret[0].(*coretypes.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 types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BroadcastTxSync", ctx, tx)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultCommit, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Commit", ctx, height)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Status", arg0)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultTx, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Tx", ctx, hash, prove)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultTxSearch, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TxSearch", ctx, query, prove, page, perPage, orderBy)
|
||||
ret0, _ := ret[0].(*coretypes.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) (*coretypes.ResultValidators, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Validators", ctx, height, page, perPage)
|
||||
ret0, _ := ret[0].(*coretypes.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)
|
||||
}
|
||||
@ -13,6 +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.5.0
|
||||
google.golang.org/grpc v1.67.1
|
||||
google.golang.org/protobuf v1.35.1
|
||||
gotest.tools/v3 v3.5.1
|
||||
@ -27,7 +28,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 +48,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
|
||||
@ -150,7 +151,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
|
||||
|
||||
@ -18,8 +18,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=
|
||||
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=
|
||||
|
||||
@ -2,6 +2,7 @@ package tx
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -10,6 +11,8 @@ import (
|
||||
"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"
|
||||
|
||||
@ -18,9 +21,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 {
|
||||
// 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 GenerateOrBroadcastTxCLIWithBroadcaster(ctx client.Context, flagSet *pflag.FlagSet, broadcaster broadcast.Broadcaster, msgs ...transaction.Msg) error {
|
||||
if err := validateMessages(msgs...); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -40,7 +43,25 @@ func GenerateOrBroadcastTxCLI(ctx client.Context, flagSet *pflag.FlagSet, msgs .
|
||||
return dryRun(txf, msgs...)
|
||||
}
|
||||
|
||||
return BroadcastTx(ctx, txf, msgs...)
|
||||
return BroadcastTx(ctx, txf, broadcaster, msgs...)
|
||||
}
|
||||
|
||||
// GenerateOrBroadcastTxCLI will either generate and print an unsigned transaction
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
|
||||
return GenerateOrBroadcastTxCLIWithBroadcaster(ctx, flagSet, cometBroadcaster, msgs...)
|
||||
}
|
||||
|
||||
// getCometBroadcaster returns a new CometBFT broadcaster based on the provided context and flag set.
|
||||
func getCometBroadcaster(ctx client.Context, flagSet *pflag.FlagSet) (broadcast.Broadcaster, error) {
|
||||
url, _ := flagSet.GetString("node")
|
||||
mode, _ := flagSet.GetString("broadcast-mode")
|
||||
return comet.NewCometBFTBroadcaster(url, mode, ctx.Codec)
|
||||
}
|
||||
|
||||
// newFactory creates a new transaction Factory based on the provided context and flag set.
|
||||
@ -129,7 +150,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 broadcast.Broadcaster, msgs ...transaction.Msg) error {
|
||||
if txf.simulateAndExecute() {
|
||||
err := txf.calculateGas(msgs...)
|
||||
if err != nil {
|
||||
@ -183,13 +204,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.
|
||||
|
||||
@ -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/broadcast/comet/comet.go -package testutil -destination client/v2/broadcast/comet/testutil/comet_mock.go
|
||||
|
||||
@ -59,7 +59,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
|
||||
|
||||
@ -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=
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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=
|
||||
|
||||
Loading…
Reference in New Issue
Block a user