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 }