mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-06 13:26:23 +00:00
lite2: fix tendermint lite sub command (#4505)
* lite2: fix tendermint lite sub command - better logging - chainID as an argument - more examples * one more log msg * lite2: fire update right away after start * turn off auto update in verification tests Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
@@ -2,6 +2,7 @@ package commands
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
amino "github.com/tendermint/go-amino"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmos "github.com/tendermint/tendermint/libs/os"
|
||||
lite "github.com/tendermint/tendermint/lite2"
|
||||
"github.com/tendermint/tendermint/lite2/provider"
|
||||
@@ -24,15 +26,29 @@ import (
|
||||
|
||||
// LiteCmd represents the base command when called without any subcommands
|
||||
var LiteCmd = &cobra.Command{
|
||||
Use: "lite",
|
||||
Use: "lite [chainID]",
|
||||
Short: "Run a light client proxy server, verifying Tendermint rpc",
|
||||
Long: `Run a light client proxy server, verifying Tendermint rpc.
|
||||
|
||||
All calls that can be tracked back to a block header by a proof
|
||||
will be verified before passing them back to the caller. Other than
|
||||
that, it will present the same interface as a full Tendermint node.`,
|
||||
that, it will present the same interface as a full Tendermint node.
|
||||
|
||||
Example:
|
||||
|
||||
start a fresh instance:
|
||||
|
||||
lite cosmoshub-3 -p 52.57.29.196:26657 -w public-seed-node.cosmoshub.certus.one:26657
|
||||
--height 962118 --hash 28B97BE9F6DE51AC69F70E0B7BFD7E5C9CD1A595B7DC31AFF27C50D4948020CD
|
||||
|
||||
continue from latest state:
|
||||
|
||||
lite cosmoshub-3 -p 52.57.29.196:26657 -w public-seed-node.cosmoshub.certus.one:26657
|
||||
`,
|
||||
RunE: runProxy,
|
||||
SilenceUsage: true,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Example: `lite cosmoshub-3 -p 52.57.29.196:26657 -w public-seed-node.cosmoshub.certus.one:26657
|
||||
--height 962118 --hash 28B97BE9F6DE51AC69F70E0B7BFD7E5C9CD1A595B7DC31AFF27C50D4948020CD`,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -46,15 +62,16 @@ var (
|
||||
trustingPeriod time.Duration
|
||||
trustedHeight int64
|
||||
trustedHash []byte
|
||||
|
||||
verbose bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
LiteCmd.Flags().StringVar(&listenAddr, "laddr", "tcp://localhost:8888",
|
||||
"Serve the proxy on the given address")
|
||||
LiteCmd.Flags().StringVar(&chainID, "chain-id", "tendermint", "Specify the Tendermint chain ID")
|
||||
LiteCmd.Flags().StringVar(&primaryAddr, "primary", "tcp://localhost:26657",
|
||||
LiteCmd.Flags().StringVarP(&primaryAddr, "primary", "p", "",
|
||||
"Connect to a Tendermint node at this address")
|
||||
LiteCmd.Flags().StringVar(&witnessesAddrs, "witnesses", "",
|
||||
LiteCmd.Flags().StringVarP(&witnessesAddrs, "witnesses", "w", "",
|
||||
"Tendermint nodes to cross-check the primary node, comma-separated")
|
||||
LiteCmd.Flags().StringVar(&home, "home-dir", ".tendermint-lite", "Specify the home directory")
|
||||
LiteCmd.Flags().IntVar(
|
||||
@@ -64,21 +81,32 @@ func init() {
|
||||
"Maximum number of simultaneous connections (including WebSocket).")
|
||||
LiteCmd.Flags().DurationVar(&trustingPeriod, "trusting-period", 168*time.Hour,
|
||||
"Trusting period. Should be significantly less than the unbonding period")
|
||||
LiteCmd.Flags().Int64Var(&trustedHeight, "trusted-height", 1, "Trusted header's height")
|
||||
LiteCmd.Flags().BytesHexVar(&trustedHash, "trusted-hash", []byte{}, "Trusted header's hash")
|
||||
LiteCmd.Flags().Int64Var(&trustedHeight, "height", 1, "Trusted header's height")
|
||||
LiteCmd.Flags().BytesHexVar(&trustedHash, "hash", []byte{}, "Trusted header's hash")
|
||||
LiteCmd.Flags().BoolVar(&verbose, "verbose", false, "Verbose output")
|
||||
}
|
||||
|
||||
func runProxy(cmd *cobra.Command, args []string) error {
|
||||
liteLogger := logger.With("module", "lite")
|
||||
// Initialise logger.
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
||||
var option log.Option
|
||||
if verbose {
|
||||
option, _ = log.AllowLevel("debug")
|
||||
} else {
|
||||
option, _ = log.AllowLevel("info")
|
||||
}
|
||||
logger = log.NewFilter(logger, option)
|
||||
|
||||
logger.Info("Connecting to the primary node...")
|
||||
rpcClient, err := rpcclient.NewHTTP(chainID, primaryAddr)
|
||||
chainID = args[0]
|
||||
|
||||
logger.Info("Creating HTTP client for primary...", "addr", primaryAddr)
|
||||
rpcClient, err := rpcclient.NewHTTP(primaryAddr, "/websocket")
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "http client for %s", primaryAddr)
|
||||
}
|
||||
primary := httpp.NewWithClient(chainID, rpcClient)
|
||||
|
||||
logger.Info("Connecting to the witness nodes...")
|
||||
// TODO: use NewNetClient once we have it
|
||||
addrs := strings.Split(witnessesAddrs, ",")
|
||||
witnesses := make([]provider.Provider, len(addrs))
|
||||
for i, addr := range addrs {
|
||||
@@ -89,12 +117,15 @@ func runProxy(cmd *cobra.Command, args []string) error {
|
||||
witnesses[i] = p
|
||||
}
|
||||
|
||||
logger.Info("Creating client...")
|
||||
logger.Info("Creating client...", "chainID", chainID)
|
||||
db, err := dbm.NewGoLevelDB("lite-client-db", home)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, err := lite.NewClient(
|
||||
|
||||
var c *lite.Client
|
||||
if trustedHeight > 0 && len(trustedHash) > 0 { // fresh installation
|
||||
c, err = lite.NewClient(
|
||||
chainID,
|
||||
lite.TrustOptions{
|
||||
Period: trustingPeriod,
|
||||
@@ -104,25 +135,42 @@ func runProxy(cmd *cobra.Command, args []string) error {
|
||||
primary,
|
||||
witnesses,
|
||||
dbs.New(db, chainID),
|
||||
lite.Logger(liteLogger),
|
||||
lite.Logger(logger),
|
||||
)
|
||||
} else { // continue from latest state
|
||||
c, err = lite.NewClientFromTrustedStore(
|
||||
chainID,
|
||||
trustingPeriod,
|
||||
primary,
|
||||
witnesses,
|
||||
dbs.New(db, chainID),
|
||||
lite.Logger(logger),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create")
|
||||
}
|
||||
logger.Info("Starting client...")
|
||||
err = c.Start()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to start")
|
||||
}
|
||||
defer c.Stop()
|
||||
|
||||
p := lproxy.Proxy{
|
||||
Addr: listenAddr,
|
||||
Config: &rpcserver.Config{MaxOpenConnections: maxOpenConnections},
|
||||
Codec: amino.NewCodec(),
|
||||
Client: lrpc.NewClient(rpcClient, c),
|
||||
Logger: liteLogger,
|
||||
Logger: logger,
|
||||
}
|
||||
// Stop upon receiving SIGTERM or CTRL-C.
|
||||
tmos.TrapSignal(liteLogger, func() {
|
||||
tmos.TrapSignal(logger, func() {
|
||||
p.Listener.Close()
|
||||
})
|
||||
|
||||
logger.Info("Starting proxy...")
|
||||
logger.Info("Starting proxy...", "laddr", listenAddr)
|
||||
if err := p.ListenAndServe(); err != http.ErrServerClosed {
|
||||
// Error starting or closing listener:
|
||||
logger.Error("proxy ListenAndServe", "err", err)
|
||||
|
||||
@@ -55,9 +55,9 @@ passing them back to the caller. Other than that, it will present the same
|
||||
interface as a full Tendermint node.
|
||||
|
||||
```sh
|
||||
$ tendermint lite --chain-id=supernova --primary=tcp://233.123.0.140:26657 \
|
||||
--witnesses=tcp://179.63.29.15:26657,tcp://144.165.223.135:26657 \
|
||||
--trusted-height=10 --trusted-hash=37E9A6DD3FA25E83B22C18835401E8E56088D0D7ABC6FD99FCDC920DD76C1C57
|
||||
$ tendermint lite supernova -p tcp://233.123.0.140:26657 \
|
||||
-w tcp://179.63.29.15:26657,tcp://144.165.223.135:26657 \
|
||||
--height=10 --hash=37E9A6DD3FA25E83B22C18835401E8E56088D0D7ABC6FD99FCDC920DD76C1C57
|
||||
```
|
||||
|
||||
For additional options, run `tendermint lite --help`.
|
||||
|
||||
@@ -166,12 +166,14 @@ func NewClient(
|
||||
}
|
||||
|
||||
if c.latestTrustedHeader != nil {
|
||||
c.logger.Info("Checking trusted header using options")
|
||||
if err := c.checkTrustedHeaderUsingOptions(trustOptions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if c.latestTrustedHeader == nil || c.latestTrustedHeader.Height < trustOptions.Height {
|
||||
c.logger.Info("Downloading trusted header using options")
|
||||
if err := c.initializeWithTrustOptions(trustOptions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -258,7 +260,7 @@ func (c *Client) restoreTrustedHeaderAndVals() error {
|
||||
c.latestTrustedHeader = trustedHeader
|
||||
c.latestTrustedVals = trustedVals
|
||||
|
||||
c.logger.Debug("Restored trusted header and vals", "height", lastHeight)
|
||||
c.logger.Info("Restored trusted header and vals", "height", lastHeight)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -930,6 +932,11 @@ func (c *Client) removeWitness(idx int) {
|
||||
func (c *Client) autoUpdateRoutine() {
|
||||
defer c.routinesWaitGroup.Done()
|
||||
|
||||
err := c.Update(time.Now())
|
||||
if err != nil {
|
||||
c.logger.Error("Error during auto update", "err", err)
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(c.updatePeriod)
|
||||
defer ticker.Stop()
|
||||
|
||||
@@ -1013,6 +1020,7 @@ func (c *Client) signedHeaderFromPrimary(height int64) (*types.SignedHeader, err
|
||||
if err == provider.ErrSignedHeaderNotFound {
|
||||
return nil, err
|
||||
}
|
||||
c.logger.Error("Failed to get signed header from primary", "attempt", attempt, "err", err)
|
||||
time.Sleep(backoffTimeout(attempt))
|
||||
}
|
||||
|
||||
@@ -1036,6 +1044,7 @@ func (c *Client) validatorSetFromPrimary(height int64) (*types.ValidatorSet, err
|
||||
if err == nil || err == provider.ErrValidatorSetNotFound {
|
||||
return vals, err
|
||||
}
|
||||
c.logger.Error("Failed to get validator set from primary", "attempt", attempt, "err", err)
|
||||
time.Sleep(backoffTimeout(attempt))
|
||||
}
|
||||
|
||||
|
||||
@@ -154,6 +154,7 @@ func TestClient_SequentialVerification(t *testing.T) {
|
||||
)},
|
||||
dbs.New(dbm.NewMemDB(), chainID),
|
||||
SequentialVerification(),
|
||||
UpdatePeriod(0),
|
||||
)
|
||||
|
||||
if tc.initErr {
|
||||
@@ -280,6 +281,7 @@ func TestClient_SkippingVerification(t *testing.T) {
|
||||
)},
|
||||
dbs.New(dbm.NewMemDB(), chainID),
|
||||
SkippingVerification(DefaultTrustLevel),
|
||||
UpdatePeriod(0),
|
||||
)
|
||||
if tc.initErr {
|
||||
require.Error(t, err)
|
||||
|
||||
Reference in New Issue
Block a user