github.com/evdatsion/aphelion-dpos-bft@v0.32.1/lite/proxy/proxy.go (about)

     1  package proxy
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  
     7  	amino "github.com/evdatsion/go-amino"
     8  
     9  	cmn "github.com/evdatsion/aphelion-dpos-bft/libs/common"
    10  	"github.com/evdatsion/aphelion-dpos-bft/libs/log"
    11  	rpcclient "github.com/evdatsion/aphelion-dpos-bft/rpc/client"
    12  	"github.com/evdatsion/aphelion-dpos-bft/rpc/core"
    13  	ctypes "github.com/evdatsion/aphelion-dpos-bft/rpc/core/types"
    14  	rpcserver "github.com/evdatsion/aphelion-dpos-bft/rpc/lib/server"
    15  	rpctypes "github.com/evdatsion/aphelion-dpos-bft/rpc/lib/types"
    16  	"github.com/evdatsion/aphelion-dpos-bft/types"
    17  )
    18  
    19  const (
    20  	wsEndpoint = "/websocket"
    21  )
    22  
    23  // StartProxy will start the websocket manager on the client,
    24  // set up the rpc routes to proxy via the given client,
    25  // and start up an http/rpc server on the location given by bind (eg. :1234)
    26  // NOTE: This function blocks - you may want to call it in a go-routine.
    27  func StartProxy(c rpcclient.Client, listenAddr string, logger log.Logger, maxOpenConnections int) error {
    28  	err := c.Start()
    29  	if err != nil {
    30  		return err
    31  	}
    32  
    33  	cdc := amino.NewCodec()
    34  	ctypes.RegisterAmino(cdc)
    35  	r := RPCRoutes(c)
    36  
    37  	// build the handler...
    38  	mux := http.NewServeMux()
    39  	rpcserver.RegisterRPCFuncs(mux, r, cdc, logger)
    40  
    41  	unsubscribeFromAllEvents := func(remoteAddr string) {
    42  		if err := c.UnsubscribeAll(context.Background(), remoteAddr); err != nil {
    43  			logger.Error("Failed to unsubscribe from events", "err", err)
    44  		}
    45  	}
    46  	wm := rpcserver.NewWebsocketManager(r, cdc, rpcserver.OnDisconnect(unsubscribeFromAllEvents))
    47  	wm.SetLogger(logger)
    48  	core.SetLogger(logger)
    49  	mux.HandleFunc(wsEndpoint, wm.WebsocketHandler)
    50  
    51  	config := rpcserver.DefaultConfig()
    52  	config.MaxOpenConnections = maxOpenConnections
    53  	l, err := rpcserver.Listen(listenAddr, config)
    54  	if err != nil {
    55  		return err
    56  	}
    57  	return rpcserver.StartHTTPServer(l, mux, logger, config)
    58  }
    59  
    60  // RPCRoutes just routes everything to the given client, as if it were
    61  // a tendermint fullnode.
    62  //
    63  // if we want security, the client must implement it as a secure client
    64  func RPCRoutes(c rpcclient.Client) map[string]*rpcserver.RPCFunc {
    65  	return map[string]*rpcserver.RPCFunc{
    66  		// Subscribe/unsubscribe are reserved for websocket events.
    67  		"subscribe":       rpcserver.NewWSRPCFunc(c.(Wrapper).SubscribeWS, "query"),
    68  		"unsubscribe":     rpcserver.NewWSRPCFunc(c.(Wrapper).UnsubscribeWS, "query"),
    69  		"unsubscribe_all": rpcserver.NewWSRPCFunc(c.(Wrapper).UnsubscribeAllWS, ""),
    70  
    71  		// info API
    72  		"status":     rpcserver.NewRPCFunc(makeStatusFunc(c), ""),
    73  		"blockchain": rpcserver.NewRPCFunc(makeBlockchainInfoFunc(c), "minHeight,maxHeight"),
    74  		"genesis":    rpcserver.NewRPCFunc(makeGenesisFunc(c), ""),
    75  		"block":      rpcserver.NewRPCFunc(makeBlockFunc(c), "height"),
    76  		"commit":     rpcserver.NewRPCFunc(makeCommitFunc(c), "height"),
    77  		"tx":         rpcserver.NewRPCFunc(makeTxFunc(c), "hash,prove"),
    78  		"validators": rpcserver.NewRPCFunc(makeValidatorsFunc(c), "height"),
    79  
    80  		// broadcast API
    81  		"broadcast_tx_commit": rpcserver.NewRPCFunc(makeBroadcastTxCommitFunc(c), "tx"),
    82  		"broadcast_tx_sync":   rpcserver.NewRPCFunc(makeBroadcastTxSyncFunc(c), "tx"),
    83  		"broadcast_tx_async":  rpcserver.NewRPCFunc(makeBroadcastTxAsyncFunc(c), "tx"),
    84  
    85  		// abci API
    86  		"abci_query": rpcserver.NewRPCFunc(makeABCIQueryFunc(c), "path,data"),
    87  		"abci_info":  rpcserver.NewRPCFunc(makeABCIInfoFunc(c), ""),
    88  	}
    89  }
    90  
    91  func makeStatusFunc(c rpcclient.Client) func(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) {
    92  	return func(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) {
    93  		return c.Status()
    94  	}
    95  }
    96  
    97  func makeBlockchainInfoFunc(c rpcclient.Client) func(ctx *rpctypes.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
    98  	return func(ctx *rpctypes.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
    99  		return c.BlockchainInfo(minHeight, maxHeight)
   100  	}
   101  }
   102  
   103  func makeGenesisFunc(c rpcclient.Client) func(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) {
   104  	return func(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) {
   105  		return c.Genesis()
   106  	}
   107  }
   108  
   109  func makeBlockFunc(c rpcclient.Client) func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultBlock, error) {
   110  	return func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultBlock, error) {
   111  		return c.Block(height)
   112  	}
   113  }
   114  
   115  func makeCommitFunc(c rpcclient.Client) func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultCommit, error) {
   116  	return func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultCommit, error) {
   117  		return c.Commit(height)
   118  	}
   119  }
   120  
   121  func makeTxFunc(c rpcclient.Client) func(ctx *rpctypes.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) {
   122  	return func(ctx *rpctypes.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) {
   123  		return c.Tx(hash, prove)
   124  	}
   125  }
   126  
   127  func makeValidatorsFunc(c rpcclient.Client) func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultValidators, error) {
   128  	return func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultValidators, error) {
   129  		return c.Validators(height)
   130  	}
   131  }
   132  
   133  func makeBroadcastTxCommitFunc(c rpcclient.Client) func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
   134  	return func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
   135  		return c.BroadcastTxCommit(tx)
   136  	}
   137  }
   138  
   139  func makeBroadcastTxSyncFunc(c rpcclient.Client) func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
   140  	return func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
   141  		return c.BroadcastTxSync(tx)
   142  	}
   143  }
   144  
   145  func makeBroadcastTxAsyncFunc(c rpcclient.Client) func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
   146  	return func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
   147  		return c.BroadcastTxAsync(tx)
   148  	}
   149  }
   150  
   151  func makeABCIQueryFunc(c rpcclient.Client) func(ctx *rpctypes.Context, path string, data cmn.HexBytes) (*ctypes.ResultABCIQuery, error) {
   152  	return func(ctx *rpctypes.Context, path string, data cmn.HexBytes) (*ctypes.ResultABCIQuery, error) {
   153  		return c.ABCIQuery(path, data)
   154  	}
   155  }
   156  
   157  func makeABCIInfoFunc(c rpcclient.Client) func(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error) {
   158  	return func(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error) {
   159  		return c.ABCIInfo()
   160  	}
   161  }