package frontend import ( "net" "time" "git.hush.is/hush/lightwalletd/zrpc" "github.com/pkg/errors" ini "gopkg.in/ini.v1" ) // DefaultRPCTimeout bounds a single JSON-RPC round trip to dragonxd. // // Why 120s and not something tighter: the slowest legitimate call this daemon // makes is `coinsupply`, measured at 48s on first call and 3s afterwards. // hush_coinsupply walks the block index back to genesis loading each block from // disk, memoising newcoins/zfunds into the CBlockIndex as it goes, so the first // call pays for the whole chain and later ones are nearly free. A timeout below // that first-call cost would turn a slow-but-working call into a hard failure. // 120s leaves ~2.5x headroom while still bounding a hang that is otherwise // unbounded -- calls were seen running past five minutes. const DefaultRPCTimeout = 120 * time.Second // DefaultRPCMaxConcurrent matches dragonxd's DEFAULT_HTTP_THREADS. Asking for // more in-flight calls than the node has worker threads only adds queueing. const DefaultRPCMaxConcurrent = 8 func NewZRPCFromConf(confPath string, timeout time.Duration, maxConcurrent int) (*zrpc.Client, error) { cfg, err := ini.Load(confPath) if err != nil { return nil, errors.Wrap(err, "failed to read config file") } rpcaddr := cfg.Section("").Key("rpcbind").String() rpcport := cfg.Section("").Key("rpcport").String() username := cfg.Section("").Key("rpcuser").String() password := cfg.Section("").Key("rpcpassword").String() return NewZRPCFromCreds(net.JoinHostPort(rpcaddr, rpcport), username, password, timeout, maxConcurrent) } func NewZRPCFromCreds(addr, username, password string, timeout time.Duration, maxConcurrent int) (*zrpc.Client, error) { // DragonX only supports HTTP POST mode and does not provide TLS by default. return zrpc.New(addr, username, password, timeout, maxConcurrent), nil }