Attempt LBCD connection with rpc.Client.

This commit is contained in:
Jonathan Moody 2022-12-14 16:20:37 -06:00
parent 2821fc0ee9
commit efac6ffd56
5 changed files with 90 additions and 12 deletions

View file

@ -3,6 +3,7 @@ package server
import ( import (
"fmt" "fmt"
"log" "log"
"net/url"
"os" "os"
"strconv" "strconv"
"strings" "strings"
@ -25,6 +26,7 @@ type Args struct {
Port int Port int
DBPath string DBPath string
Chain *string Chain *string
DaemonURL *url.URL
EsHost string EsHost string
EsPort int EsPort int
PrometheusPort int PrometheusPort int
@ -203,10 +205,19 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args {
environment := GetEnvironmentStandard() environment := GetEnvironmentStandard()
parser := argparse.NewParser("herald", "herald server and client") parser := argparse.NewParser("herald", "herald server and client")
serveCmd := parser.NewCommand("serve", "start the hub server") serveCmd := parser.NewCommand("serve", "start the herald server")
searchCmd := parser.NewCommand("search", "claim search") searchCmd := parser.NewCommand("search", "claim search")
dbCmd := parser.NewCommand("db", "db testing") dbCmd := parser.NewCommand("db", "db testing")
defaultDaemonURL := "localhost:9245"
if url, ok := environment["DAEMON_URL"]; ok {
defaultDaemonURL = url
}
validateURL := func(arg []string) error {
_, err := url.Parse(arg[0])
return err
}
validatePort := func(arg []string) error { validatePort := func(arg []string) error {
_, err := strconv.ParseUint(arg[0], 10, 16) _, err := strconv.ParseUint(arg[0], 10, 16)
return err return err
@ -218,6 +229,7 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args {
dbPath := parser.String("", "db-path", &argparse.Options{Required: false, Help: "RocksDB path", Default: DefaultDBPath}) dbPath := parser.String("", "db-path", &argparse.Options{Required: false, Help: "RocksDB path", Default: DefaultDBPath})
chain := parser.Selector("", "chain", []string{chaincfg.MainNetParams.Name, chaincfg.TestNet3Params.Name, chaincfg.RegressionNetParams.Name, "testnet"}, chain := parser.Selector("", "chain", []string{chaincfg.MainNetParams.Name, chaincfg.TestNet3Params.Name, chaincfg.RegressionNetParams.Name, "testnet"},
&argparse.Options{Required: false, Help: "Which chain to use, default is 'mainnet'. Values 'regtest' and 'testnet' are for testing", Default: chaincfg.MainNetParams.Name}) &argparse.Options{Required: false, Help: "Which chain to use, default is 'mainnet'. Values 'regtest' and 'testnet' are for testing", Default: chaincfg.MainNetParams.Name})
daemonURLStr := parser.String("", "daemon-url", &argparse.Options{Required: true, Help: "URL for rpc to lbrycrd or lbcd, <rpcuser>:<rpcpassword>@<lbcd rpc ip><lbrcd rpc port>.", Validate: validateURL, Default: defaultDaemonURL})
esHost := parser.String("", "eshost", &argparse.Options{Required: false, Help: "elasticsearch host", Default: DefaultEsHost}) esHost := parser.String("", "eshost", &argparse.Options{Required: false, Help: "elasticsearch host", Default: DefaultEsHost})
esPort := parser.Int("", "esport", &argparse.Options{Required: false, Help: "elasticsearch port", Default: DefaultEsPort}) esPort := parser.Int("", "esport", &argparse.Options{Required: false, Help: "elasticsearch port", Default: DefaultEsPort})
prometheusPort := parser.Int("", "prometheus-port", &argparse.Options{Required: false, Help: "prometheus port", Default: DefaultPrometheusPort}) prometheusPort := parser.Int("", "prometheus-port", &argparse.Options{Required: false, Help: "prometheus port", Default: DefaultPrometheusPort})
@ -277,6 +289,11 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args {
*jsonRPCPort = DefaultJSONRPCPort *jsonRPCPort = DefaultJSONRPCPort
} }
daemonURL, err := url.Parse(*daemonURLStr)
if err != nil {
log.Fatalf("URL parse failed: %v", err)
}
banner := loadBanner(bannerFile, HUB_PROTOCOL_VERSION) banner := loadBanner(bannerFile, HUB_PROTOCOL_VERSION)
args := &Args{ args := &Args{
@ -285,6 +302,7 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args {
Port: *port, Port: *port,
DBPath: *dbPath, DBPath: *dbPath,
Chain: chain, Chain: chain,
DaemonURL: daemonURL,
EsHost: *esHost, EsHost: *esHost,
EsPort: *esPort, EsPort: *esPort,
PrometheusPort: *prometheusPort, PrometheusPort: *prometheusPort,

View file

@ -207,7 +207,7 @@ func TestHeadersSubscribe(t *testing.T) {
return return
} }
sm := newSessionManager(nil, db, args, grp, &chaincfg.RegressionNetParams) sm := newSessionManager(nil, db, args, grp, &chaincfg.RegressionNetParams, nil)
sm.start() sm.start()
defer sm.stop() defer sm.stop()
@ -388,7 +388,7 @@ func TestAddressSubscribe(t *testing.T) {
return return
} }
sm := newSessionManager(nil, db, args, grp, &chaincfg.RegressionNetParams) sm := newSessionManager(nil, db, args, grp, &chaincfg.RegressionNetParams, nil)
sm.start() sm.start()
defer sm.stop() defer sm.stop()

View file

@ -1,15 +1,19 @@
package server package server
import ( import (
"bytes"
"context" "context"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"hash" "hash"
"io"
golog "log" golog "log"
"net" "net"
"net/http" "net/http"
"net/rpc"
"net/rpc/jsonrpc"
"os" "os"
"regexp" "regexp"
"strconv" "strconv"
@ -38,6 +42,7 @@ type Server struct {
WeirdCharsRe *regexp.Regexp WeirdCharsRe *regexp.Regexp
DB *db.ReadOnlyDBColumnFamily DB *db.ReadOnlyDBColumnFamily
Chain *chaincfg.Params Chain *chaincfg.Params
DaemonClient *rpc.Client
EsClient *elastic.Client EsClient *elastic.Client
QueryCache *ttlcache.Cache QueryCache *ttlcache.Cache
S256 *hash.Hash S256 *hash.Hash
@ -237,6 +242,38 @@ func LoadDatabase(args *Args, grp *stop.Group) (*db.ReadOnlyDBColumnFamily, erro
return myDB, nil return myDB, nil
} }
type BasicAuthClientCodec struct {
client http.Client
url string
user string
password string
buff *bytes.Buffer
}
func (c BasicAuthClientCodec) Read(p []byte) (n int, err error) {
return c.buff.Read(p)
}
func (c BasicAuthClientCodec) Write(p []byte) (n int, err error) {
req, err := http.NewRequest("POST", c.url, bytes.NewReader(p))
if err != nil {
return 0, err
}
req.SetBasicAuth(c.user, c.password)
req.Header.Add("Content-Type", "application/json")
resp, err := c.client.Do(req)
if err != nil {
return len(p), err
}
io.Copy(c.buff, resp.Body)
return len(p), err
}
func (c BasicAuthClientCodec) Close() error {
c.client.CloseIdleConnections()
return nil
}
// MakeHubServer takes the arguments given to a hub when it's started and // MakeHubServer takes the arguments given to a hub when it's started and
// initializes everything. It loads information about previously known peers, // initializes everything. It loads information about previously known peers,
// creates needed internal data structures, and initializes goroutines. // creates needed internal data structures, and initializes goroutines.
@ -253,7 +290,24 @@ func MakeHubServer(grp *stop.Group, args *Args) *Server {
log.Fatal(err) log.Fatal(err)
} }
var client *elastic.Client = nil var lbcdClient *rpc.Client = nil
if args.DaemonURL != nil {
log.Warnf("connecting to lbcd daemon at %v...", args.DaemonURL)
password, _ := args.DaemonURL.User.Password()
codec := jsonrpc.NewClientCodec(
&BasicAuthClientCodec{
client: http.Client{
Timeout: 30 * time.Second,
},
url: args.DaemonURL.Host,
user: args.DaemonURL.User.Username(),
password: password,
buff: bytes.NewBuffer(nil),
})
lbcdClient = rpc.NewClientWithCodec(codec)
}
var esClient *elastic.Client = nil
if !args.DisableEs { if !args.DisableEs {
esUrl := args.EsHost + ":" + fmt.Sprintf("%d", args.EsPort) esUrl := args.EsHost + ":" + fmt.Sprintf("%d", args.EsPort)
opts := []elastic.ClientOptionFunc{ opts := []elastic.ClientOptionFunc{
@ -265,7 +319,7 @@ func MakeHubServer(grp *stop.Group, args *Args) *Server {
if args.Debug { if args.Debug {
opts = append(opts, elastic.SetTraceLog(golog.New(os.Stderr, "[[ELASTIC]]", 0))) opts = append(opts, elastic.SetTraceLog(golog.New(os.Stderr, "[[ELASTIC]]", 0)))
} }
client, err = elastic.NewClient(opts...) esClient, err = elastic.NewClient(opts...)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -344,7 +398,8 @@ func MakeHubServer(grp *stop.Group, args *Args) *Server {
WeirdCharsRe: weirdCharsRe, WeirdCharsRe: weirdCharsRe,
DB: myDB, DB: myDB,
Chain: &chain, Chain: &chain,
EsClient: client, DaemonClient: lbcdClient,
EsClient: esClient,
QueryCache: cache, QueryCache: cache,
S256: &s256, S256: &s256,
LastRefreshCheck: time.Now(), LastRefreshCheck: time.Now(),
@ -364,7 +419,7 @@ func MakeHubServer(grp *stop.Group, args *Args) *Server {
sessionManager: nil, sessionManager: nil,
} }
// FIXME: HACK // FIXME: HACK
s.sessionManager = newSessionManager(s, myDB, args, sessionGrp, &chain) s.sessionManager = newSessionManager(s, myDB, args, sessionGrp, &chain, lbcdClient)
// Start up our background services // Start up our background services
if !args.DisableResolve && !args.DisableRocksDBRefresh { if !args.DisableResolve && !args.DisableRocksDBRefresh {

View file

@ -15,5 +15,5 @@ func (s *Server) GetNumPeersExported() func() int64 {
} }
func NewSessionManagerExported(server *Server, db *db.ReadOnlyDBColumnFamily, args *Args, grp *stop.Group, chain *chaincfg.Params) *sessionManager { func NewSessionManagerExported(server *Server, db *db.ReadOnlyDBColumnFamily, args *Args, grp *stop.Group, chain *chaincfg.Params) *sessionManager {
return newSessionManager(server, db, args, grp, chain) return newSessionManager(server, db, args, grp, chain, nil)
} }

View file

@ -140,6 +140,7 @@ type sessionManager struct {
args *Args args *Args
server *Server server *Server
chain *chaincfg.Params chain *chaincfg.Params
lbcd *rpc.Client
// peerSubs are sessions subscribed via 'blockchain.peers.subscribe' // peerSubs are sessions subscribed via 'blockchain.peers.subscribe'
peerSubs sessionMap peerSubs sessionMap
// headerSubs are sessions subscribed via 'blockchain.headers.subscribe' // headerSubs are sessions subscribed via 'blockchain.headers.subscribe'
@ -148,7 +149,7 @@ type sessionManager struct {
hashXSubs map[[HASHX_LEN]byte]sessionMap hashXSubs map[[HASHX_LEN]byte]sessionMap
} }
func newSessionManager(server *Server, db *db.ReadOnlyDBColumnFamily, args *Args, grp *stop.Group, chain *chaincfg.Params) *sessionManager { func newSessionManager(server *Server, db *db.ReadOnlyDBColumnFamily, args *Args, grp *stop.Group, chain *chaincfg.Params, lbcd *rpc.Client) *sessionManager {
return &sessionManager{ return &sessionManager{
sessions: make(sessionMap), sessions: make(sessionMap),
grp: grp, grp: grp,
@ -159,6 +160,7 @@ func newSessionManager(server *Server, db *db.ReadOnlyDBColumnFamily, args *Args
args: args, args: args,
server: server, server: server,
chain: chain, chain: chain,
lbcd: lbcd,
peerSubs: make(sessionMap), peerSubs: make(sessionMap),
headerSubs: make(sessionMap), headerSubs: make(sessionMap),
hashXSubs: make(map[[HASHX_LEN]byte]sessionMap), hashXSubs: make(map[[HASHX_LEN]byte]sessionMap),
@ -306,9 +308,12 @@ func (sm *sessionManager) removeSessionLocked(sess *session) {
} }
func (sm *sessionManager) broadcastTx(rawTx []byte) (*chainhash.Hash, error) { func (sm *sessionManager) broadcastTx(rawTx []byte) (*chainhash.Hash, error) {
// TODO var reply string
panic("not implemented") err := sm.lbcd.Call("sendrawtransaction", hex.EncodeToString(rawTx), reply)
return nil, nil if err != nil {
return nil, err
}
return chainhash.NewHashFromStr(reply)
} }
func (sm *sessionManager) peersSubscribe(sess *session, subscribe bool) { func (sm *sessionManager) peersSubscribe(sess *session, subscribe bool) {