github.com/devwanda/aphelion-staking@v0.33.9/cmd/tendermint/commands/lite.go (about)

     1  package commands
     2  
     3  import (
     4  	"net/http"
     5  	"os"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/pkg/errors"
    10  	"github.com/spf13/cobra"
    11  
    12  	"github.com/evdatsion/go-amino"
    13  	dbm "github.com/tendermint/tm-db"
    14  
    15  	"github.com/devwanda/aphelion-staking/libs/log"
    16  	tmos "github.com/devwanda/aphelion-staking/libs/os"
    17  	lite "github.com/devwanda/aphelion-staking/lite2"
    18  	lproxy "github.com/devwanda/aphelion-staking/lite2/proxy"
    19  	lrpc "github.com/devwanda/aphelion-staking/lite2/rpc"
    20  	dbs "github.com/devwanda/aphelion-staking/lite2/store/db"
    21  	rpchttp "github.com/devwanda/aphelion-staking/rpc/client/http"
    22  	rpcserver "github.com/devwanda/aphelion-staking/rpc/jsonrpc/server"
    23  )
    24  
    25  // LiteCmd represents the base command when called without any subcommands
    26  var LiteCmd = &cobra.Command{
    27  	Use:   "lite [chainID]",
    28  	Short: "Run a light client proxy server, verifying Tendermint rpc",
    29  	Long: `Run a light client proxy server, verifying Tendermint rpc.
    30  
    31  All calls that can be tracked back to a block header by a proof
    32  will be verified before passing them back to the caller. Other than
    33  that, it will present the same interface as a full Tendermint node.
    34  
    35  Example:
    36  
    37  start a fresh instance:
    38  
    39  lite cosmoshub-3 -p 52.57.29.196:26657 -w public-seed-node.cosmoshub.certus.one:26657
    40  	--height 962118 --hash 28B97BE9F6DE51AC69F70E0B7BFD7E5C9CD1A595B7DC31AFF27C50D4948020CD
    41  
    42  continue from latest state:
    43  
    44  lite cosmoshub-3 -p 52.57.29.196:26657 -w public-seed-node.cosmoshub.certus.one:26657
    45  `,
    46  	RunE: runProxy,
    47  	Args: cobra.ExactArgs(1),
    48  	Example: `lite cosmoshub-3 -p 52.57.29.196:26657 -w public-seed-node.cosmoshub.certus.one:26657
    49  	--height 962118 --hash 28B97BE9F6DE51AC69F70E0B7BFD7E5C9CD1A595B7DC31AFF27C50D4948020CD`,
    50  }
    51  
    52  var (
    53  	listenAddr         string
    54  	primaryAddr        string
    55  	witnessAddrsJoined string
    56  	chainID            string
    57  	home               string
    58  	maxOpenConnections int
    59  
    60  	trustingPeriod time.Duration
    61  	trustedHeight  int64
    62  	trustedHash    []byte
    63  
    64  	verbose bool
    65  )
    66  
    67  func init() {
    68  	LiteCmd.Flags().StringVar(&listenAddr, "laddr", "tcp://localhost:8888",
    69  		"Serve the proxy on the given address")
    70  	LiteCmd.Flags().StringVarP(&primaryAddr, "primary", "p", "",
    71  		"Connect to a Tendermint node at this address")
    72  	LiteCmd.Flags().StringVarP(&witnessAddrsJoined, "witnesses", "w", "",
    73  		"Tendermint nodes to cross-check the primary node, comma-separated")
    74  	LiteCmd.Flags().StringVar(&home, "home-dir", ".tendermint-lite", "Specify the home directory")
    75  	LiteCmd.Flags().IntVar(
    76  		&maxOpenConnections,
    77  		"max-open-connections",
    78  		900,
    79  		"Maximum number of simultaneous connections (including WebSocket).")
    80  	LiteCmd.Flags().DurationVar(&trustingPeriod, "trusting-period", 168*time.Hour,
    81  		"Trusting period. Should be significantly less than the unbonding period")
    82  	LiteCmd.Flags().Int64Var(&trustedHeight, "height", 1, "Trusted header's height")
    83  	LiteCmd.Flags().BytesHexVar(&trustedHash, "hash", []byte{}, "Trusted header's hash")
    84  	LiteCmd.Flags().BoolVar(&verbose, "verbose", false, "Verbose output")
    85  }
    86  
    87  func runProxy(cmd *cobra.Command, args []string) error {
    88  	// Initialise logger.
    89  	logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
    90  	var option log.Option
    91  	if verbose {
    92  		option, _ = log.AllowLevel("debug")
    93  	} else {
    94  		option, _ = log.AllowLevel("info")
    95  	}
    96  	logger = log.NewFilter(logger, option)
    97  
    98  	chainID = args[0]
    99  	logger.Info("Creating client...", "chainID", chainID)
   100  
   101  	witnessesAddrs := strings.Split(witnessAddrsJoined, ",")
   102  
   103  	db, err := dbm.NewGoLevelDB("lite-client-db", home)
   104  	if err != nil {
   105  		return errors.Wrap(err, "new goleveldb")
   106  	}
   107  
   108  	var c *lite.Client
   109  	if trustedHeight > 0 && len(trustedHash) > 0 { // fresh installation
   110  		c, err = lite.NewHTTPClient(
   111  			chainID,
   112  			lite.TrustOptions{
   113  				Period: trustingPeriod,
   114  				Height: trustedHeight,
   115  				Hash:   trustedHash,
   116  			},
   117  			primaryAddr,
   118  			witnessesAddrs,
   119  			dbs.New(db, chainID),
   120  			lite.Logger(logger),
   121  		)
   122  	} else { // continue from latest state
   123  		c, err = lite.NewHTTPClientFromTrustedStore(
   124  			chainID,
   125  			trustingPeriod,
   126  			primaryAddr,
   127  			witnessesAddrs,
   128  			dbs.New(db, chainID),
   129  			lite.Logger(logger),
   130  		)
   131  	}
   132  	if err != nil {
   133  		return err
   134  	}
   135  
   136  	rpcClient, err := rpchttp.New(primaryAddr, "/websocket")
   137  	if err != nil {
   138  		return errors.Wrapf(err, "http client for %s", primaryAddr)
   139  	}
   140  	p := lproxy.Proxy{
   141  		Addr:   listenAddr,
   142  		Config: &rpcserver.Config{MaxOpenConnections: maxOpenConnections},
   143  		Codec:  amino.NewCodec(),
   144  		Client: lrpc.NewClient(rpcClient, c),
   145  		Logger: logger,
   146  	}
   147  	// Stop upon receiving SIGTERM or CTRL-C.
   148  	tmos.TrapSignal(logger, func() {
   149  		p.Listener.Close()
   150  	})
   151  
   152  	logger.Info("Starting proxy...", "laddr", listenAddr)
   153  	if err := p.ListenAndServe(); err != http.ErrServerClosed {
   154  		// Error starting or closing listener:
   155  		logger.Error("proxy ListenAndServe", "err", err)
   156  	}
   157  
   158  	return nil
   159  }