cosmos-sdk/server/rosetta/config.go

205 lines
5.8 KiB
Go

package rosetta
import (
"fmt"
"strings"
"time"
"github.com/coinbase/rosetta-sdk-go/types"
"github.com/spf13/pflag"
crg "github.com/cosmos/cosmos-sdk/server/rosetta/lib/server"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
)
// configuration defaults constants
const (
// DefaultBlockchain defines the default blockchain identifier name
DefaultBlockchain = "app"
// DefaultAddr defines the default rosetta binding address
DefaultAddr = ":8080"
// DefaultRetries is the default number of retries
DefaultRetries = 5
// DefaultTendermintEndpoint is the default value for the tendermint endpoint
DefaultTendermintEndpoint = "localhost:26657"
// DefaultGRPCEndpoint is the default value for the gRPC endpoint
DefaultGRPCEndpoint = "localhost:9090"
// DefaultNetwork defines the default network name
DefaultNetwork = "network"
// DefaultOffline defines the default offline value
DefaultOffline = false
)
// configuration flags
const (
FlagBlockchain = "blockchain"
FlagNetwork = "network"
FlagTendermintEndpoint = "tendermint"
FlagGRPCEndpoint = "grpc"
FlagAddr = "addr"
FlagRetries = "retries"
FlagOffline = "offline"
)
// Config defines the configuration of the rosetta server
type Config struct {
// Blockchain defines the blockchain name
// defaults to DefaultBlockchain
Blockchain string
// Network defines the network name
Network string
// TendermintRPC defines the endpoint to connect to
// tendermint RPC, specifying 'tcp://' before is not
// required, usually it's at port 26657 of the
TendermintRPC string
// GRPCEndpoint defines the cosmos application gRPC endpoint
// usually it is located at 9090 port
GRPCEndpoint string
// Addr defines the default address to bind the rosetta server to
// defaults to DefaultAddr
Addr string
// Retries defines the maximum number of retries
// rosetta will do before quitting
Retries int
// Offline defines if the server must be run in offline mode
Offline bool
// Codec overrides the default data and construction api client codecs
Codec *codec.ProtoCodec
// InterfaceRegistry overrides the default data and construction api interface registry
InterfaceRegistry codectypes.InterfaceRegistry
}
// NetworkIdentifier returns the network identifier given the configuration
func (c *Config) NetworkIdentifier() *types.NetworkIdentifier {
return &types.NetworkIdentifier{
Blockchain: c.Blockchain,
Network: c.Network,
}
}
// validate validates a configuration and sets
// its defaults in case they were not provided
func (c *Config) validate() error {
if (c.Codec == nil) != (c.InterfaceRegistry == nil) {
return fmt.Errorf("codec and interface registry must be both different from nil or nil")
}
if c.Addr == "" {
c.Addr = DefaultAddr
}
if c.Blockchain == "" {
c.Blockchain = DefaultBlockchain
}
if c.Retries == 0 {
c.Retries = DefaultRetries
}
// these are must
if c.Network == "" {
return fmt.Errorf("network not provided")
}
if c.Offline {
return fmt.Errorf("offline mode is not supported for stargate implementation due to how sigv2 works")
}
// these are optional but it must be online
if c.GRPCEndpoint == "" {
return fmt.Errorf("grpc endpoint not provided")
}
if c.TendermintRPC == "" {
return fmt.Errorf("tendermint rpc not provided")
}
if !strings.HasPrefix(c.TendermintRPC, "tcp://") {
c.TendermintRPC = fmt.Sprintf("tcp://%s", c.TendermintRPC)
}
return nil
}
// WithCodec extends the configuration with a predefined Codec
func (c *Config) WithCodec(ir codectypes.InterfaceRegistry, cdc *codec.ProtoCodec) {
c.Codec = cdc
c.InterfaceRegistry = ir
}
// FromFlags gets the configuration from flags
func FromFlags(flags *pflag.FlagSet) (*Config, error) {
blockchain, err := flags.GetString(FlagBlockchain)
if err != nil {
return nil, err
}
network, err := flags.GetString(FlagNetwork)
if err != nil {
return nil, err
}
tendermintRPC, err := flags.GetString(FlagTendermintEndpoint)
if err != nil {
return nil, err
}
gRPCEndpoint, err := flags.GetString(FlagGRPCEndpoint)
if err != nil {
return nil, err
}
addr, err := flags.GetString(FlagAddr)
if err != nil {
return nil, err
}
retries, err := flags.GetInt(FlagRetries)
if err != nil {
return nil, err
}
offline, err := flags.GetBool(FlagOffline)
if err != nil {
return nil, err
}
conf := &Config{
Blockchain: blockchain,
Network: network,
TendermintRPC: tendermintRPC,
GRPCEndpoint: gRPCEndpoint,
Addr: addr,
Retries: retries,
Offline: offline,
}
err = conf.validate()
if err != nil {
return nil, err
}
return conf, nil
}
func ServerFromConfig(conf *Config) (crg.Server, error) {
err := conf.validate()
if err != nil {
return crg.Server{}, err
}
client, err := NewClient(conf)
if err != nil {
return crg.Server{}, err
}
return crg.NewServer(
crg.Settings{
Network: &types.NetworkIdentifier{
Blockchain: conf.Blockchain,
Network: conf.Network,
},
Client: client,
Listen: conf.Addr,
Offline: conf.Offline,
Retries: conf.Retries,
RetryWait: 15 * time.Second,
})
}
// SetFlags sets the configuration flags to the given flagset
func SetFlags(flags *pflag.FlagSet) {
flags.String(FlagBlockchain, DefaultBlockchain, "the blockchain type")
flags.String(FlagNetwork, DefaultNetwork, "the network name")
flags.String(FlagTendermintEndpoint, DefaultTendermintEndpoint, "the tendermint rpc endpoint, without tcp://")
flags.String(FlagGRPCEndpoint, DefaultGRPCEndpoint, "the app gRPC endpoint")
flags.String(FlagAddr, DefaultAddr, "the address rosetta will bind to")
flags.Int(FlagRetries, DefaultRetries, "the number of retries that will be done before quitting")
flags.Bool(FlagOffline, DefaultOffline, "run rosetta only with construction API")
}