[lbry] rpc: import getnetworkinfo from bchd

This commit is contained in:
Brannon King 2021-10-28 14:02:44 -04:00 committed by Roy Lee
parent 5116f45617
commit 81862c664e
6 changed files with 257 additions and 46 deletions

View file

@ -45,7 +45,7 @@ type AddrManager struct {
nTried int nTried int
nNew int nNew int
lamtx sync.Mutex lamtx sync.Mutex
localAddresses map[string]*localAddress localAddresses map[string]*LocalAddress
version int version int
} }
@ -69,9 +69,9 @@ type serializedAddrManager struct {
TriedBuckets [triedBucketCount][]string TriedBuckets [triedBucketCount][]string
} }
type localAddress struct { type LocalAddress struct {
na *wire.NetAddress NA *wire.NetAddress
score AddressPriority Score AddressPriority
} }
// AddressPriority type is used to describe the hierarchy of local address // AddressPriority type is used to describe the hierarchy of local address
@ -178,7 +178,7 @@ func (a *AddrManager) updateAddress(netAddr, srcAddr *wire.NetAddress) {
// note that to prevent causing excess garbage on getaddr // note that to prevent causing excess garbage on getaddr
// messages the netaddresses in addrmanager are *immutable*, // messages the netaddresses in addrmanager are *immutable*,
// if we need to change them then we replace the pointer with a // if we need to change them then we replace the pointer with a
// new copy so that we don't have to copy every na for getaddr. // new copy so that we don't have to copy every NA for getaddr.
if netAddr.Timestamp.After(ka.na.Timestamp) || if netAddr.Timestamp.After(ka.na.Timestamp) ||
(ka.na.Services&netAddr.Services) != (ka.na.Services&netAddr.Services) !=
netAddr.Services { netAddr.Services {
@ -755,7 +755,7 @@ func (a *AddrManager) HostToNetAddress(host string, port uint16, services wire.S
// the relevant .onion address. // the relevant .onion address.
func ipString(na *wire.NetAddress) string { func ipString(na *wire.NetAddress) string {
if IsOnionCatTor(na) { if IsOnionCatTor(na) {
// We know now that na.IP is long enough. // We know now that NA.IP is long enough.
base32 := base32.StdEncoding.EncodeToString(na.IP[6:]) base32 := base32.StdEncoding.EncodeToString(na.IP[6:])
return strings.ToLower(base32) + ".onion" return strings.ToLower(base32) + ".onion"
} }
@ -882,7 +882,7 @@ func (a *AddrManager) Connected(addr *wire.NetAddress) {
// so. // so.
now := time.Now() now := time.Now()
if now.After(ka.na.Timestamp.Add(time.Minute * 20)) { if now.After(ka.na.Timestamp.Add(time.Minute * 20)) {
// ka.na is immutable, so replace it. // ka.NA is immutable, so replace it.
naCopy := *ka.na naCopy := *ka.na
naCopy.Timestamp = time.Now() naCopy.Timestamp = time.Now()
ka.mtx.Lock() ka.mtx.Lock()
@ -994,7 +994,7 @@ func (a *AddrManager) SetServices(addr *wire.NetAddress, services wire.ServiceFl
// Update the services if needed. // Update the services if needed.
if ka.na.Services != services { if ka.na.Services != services {
// ka.na is immutable, so replace it. // ka.NA is immutable, so replace it.
naCopy := *ka.na naCopy := *ka.na
naCopy.Services = services naCopy.Services = services
ka.mtx.Lock() ka.mtx.Lock()
@ -1003,7 +1003,7 @@ func (a *AddrManager) SetServices(addr *wire.NetAddress, services wire.ServiceFl
} }
} }
// AddLocalAddress adds na to the list of known local addresses to advertise // AddLocalAddress adds NA to the list of known local addresses to advertise
// with the given priority. // with the given priority.
func (a *AddrManager) AddLocalAddress(na *wire.NetAddress, priority AddressPriority) error { func (a *AddrManager) AddLocalAddress(na *wire.NetAddress, priority AddressPriority) error {
if !IsRoutable(na) { if !IsRoutable(na) {
@ -1015,13 +1015,13 @@ func (a *AddrManager) AddLocalAddress(na *wire.NetAddress, priority AddressPrior
key := NetAddressKey(na) key := NetAddressKey(na)
la, ok := a.localAddresses[key] la, ok := a.localAddresses[key]
if !ok || la.score < priority { if !ok || la.Score < priority {
if ok { if ok {
la.score = priority + 1 la.Score = priority + 1
} else { } else {
a.localAddresses[key] = &localAddress{ a.localAddresses[key] = &LocalAddress{
na: na, NA: na,
score: priority, Score: priority,
} }
} }
} }
@ -1117,12 +1117,12 @@ func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.Net
var bestscore AddressPriority var bestscore AddressPriority
var bestAddress *wire.NetAddress var bestAddress *wire.NetAddress
for _, la := range a.localAddresses { for _, la := range a.localAddresses {
reach := getReachabilityFrom(la.na, remoteAddr) reach := getReachabilityFrom(la.NA, remoteAddr)
if reach > bestreach || if reach > bestreach ||
(reach == bestreach && la.score > bestscore) { (reach == bestreach && la.Score > bestscore) {
bestreach = reach bestreach = reach
bestscore = la.score bestscore = la.Score
bestAddress = la.na bestAddress = la.NA
} }
} }
if bestAddress != nil { if bestAddress != nil {
@ -1146,6 +1146,15 @@ func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.Net
return bestAddress return bestAddress
} }
// LocalAddresses returns the list of local addresses for our node.
func (a *AddrManager) LocalAddresses() []*LocalAddress {
var addrs []*LocalAddress
for _, addr := range a.localAddresses {
addrs = append(addrs, addr)
}
return addrs
}
// New returns a new bitcoin address manager. // New returns a new bitcoin address manager.
// Use Start to begin processing asynchronous address updates. // Use Start to begin processing asynchronous address updates.
func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager { func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager {
@ -1154,7 +1163,7 @@ func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager
lookupFunc: lookupFunc, lookupFunc: lookupFunc,
rand: rand.New(rand.NewSource(time.Now().UnixNano())), rand: rand.New(rand.NewSource(time.Now().UnixNano())),
quit: make(chan struct{}), quit: make(chan struct{}),
localAddresses: make(map[string]*localAddress), localAddresses: make(map[string]*LocalAddress),
version: serialisationVersion, version: serialisationVersion,
} }
am.reset() am.reset()

View file

@ -199,6 +199,15 @@ func (b *BlockChain) HaveBlock(hash *chainhash.Hash) (bool, error) {
return exists || b.IsKnownOrphan(hash), nil return exists || b.IsKnownOrphan(hash), nil
} }
// GetWarnings returns a bool for whether unknownRules
// has been warned.
func (b *BlockChain) GetWarnings() bool {
b.chainLock.RLock()
defer b.chainLock.RUnlock()
return b.unknownRulesWarned
}
// IsKnownOrphan returns whether the passed hash is currently a known orphan. // IsKnownOrphan returns whether the passed hash is currently a known orphan.
// Keep in mind that only a limited number of orphans are held onto for a // Keep in mind that only a limited number of orphans are held onto for a
// limited amount of time, so this function must not be used as an absolute // limited amount of time, so this function must not be used as an absolute

View file

@ -27,21 +27,22 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/blockchain/indexers"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/database"
"github.com/btcsuite/btcd/mempool"
"github.com/btcsuite/btcd/mining"
"github.com/btcsuite/btcd/mining/cpuminer"
"github.com/btcsuite/btcd/peer"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/btcsuite/websocket" "github.com/btcsuite/websocket"
"github.com/lbryio/lbcd/addrmgr"
"github.com/lbryio/lbcd/blockchain"
"github.com/lbryio/lbcd/blockchain/indexers"
"github.com/lbryio/lbcd/btcec"
"github.com/lbryio/lbcd/btcjson"
"github.com/lbryio/lbcd/chaincfg"
"github.com/lbryio/lbcd/chaincfg/chainhash"
"github.com/lbryio/lbcd/database"
"github.com/lbryio/lbcd/mempool"
"github.com/lbryio/lbcd/mining"
"github.com/lbryio/lbcd/mining/cpuminer"
"github.com/lbryio/lbcd/peer"
"github.com/lbryio/lbcd/txscript"
"github.com/lbryio/lbcd/wire"
btcutil "github.com/lbryio/lbcutil"
) )
// API version constants // API version constants
@ -137,6 +138,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
"decodescript": handleDecodeScript, "decodescript": handleDecodeScript,
"estimatefee": handleEstimateFee, "estimatefee": handleEstimateFee,
"generate": handleGenerate, "generate": handleGenerate,
"generatetoaddress": handleGenerateToAddress,
"getaddednodeinfo": handleGetAddedNodeInfo, "getaddednodeinfo": handleGetAddedNodeInfo,
"getbestblock": handleGetBestBlock, "getbestblock": handleGetBestBlock,
"getbestblockhash": handleGetBestBlockHash, "getbestblockhash": handleGetBestBlockHash,
@ -159,6 +161,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
"getmininginfo": handleGetMiningInfo, "getmininginfo": handleGetMiningInfo,
"getnettotals": handleGetNetTotals, "getnettotals": handleGetNetTotals,
"getnetworkhashps": handleGetNetworkHashPS, "getnetworkhashps": handleGetNetworkHashPS,
"getnetworkinfo": handleGetNetworkInfo,
"getnodeaddresses": handleGetNodeAddresses, "getnodeaddresses": handleGetNodeAddresses,
"getpeerinfo": handleGetPeerInfo, "getpeerinfo": handleGetPeerInfo,
"getrawmempool": handleGetRawMempool, "getrawmempool": handleGetRawMempool,
@ -233,7 +236,6 @@ var rpcUnimplemented = map[string]struct{}{
"estimatepriority": {}, "estimatepriority": {},
"getchaintips": {}, "getchaintips": {},
"getmempoolentry": {}, "getmempoolentry": {},
"getnetworkinfo": {},
"getwork": {}, "getwork": {},
"invalidateblock": {}, "invalidateblock": {},
"preciousblock": {}, "preciousblock": {},
@ -573,7 +575,7 @@ func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan
default: default:
return nil, &btcjson.RPCError{ return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidAddressOrKey, Code: btcjson.ErrRPCInvalidAddressOrKey,
Message: "Invalid address or key", Message: "Invalid address or key: " + addr.String(),
} }
} }
if !addr.IsForNet(params) { if !addr.IsForNet(params) {
@ -701,11 +703,12 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap
// script doesn't fully parse, so ignore the error here. // script doesn't fully parse, so ignore the error here.
disbuf, _ := txscript.DisasmString(v.PkScript) disbuf, _ := txscript.DisasmString(v.PkScript)
script := txscript.StripClaimScriptPrefix(v.PkScript)
// Ignore the error here since an error means the script // Ignore the error here since an error means the script
// couldn't parse and there is no additional information about // couldn't parse and there is no additional information about
// it anyways. // it anyways.
scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs( scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script, chainParams)
v.PkScript, chainParams)
// Encode the addresses while checking if the address passes the // Encode the addresses while checking if the address passes the
// filter when needed. // filter when needed.
@ -735,9 +738,19 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap
vout.ScriptPubKey.Addresses = encodedAddrs vout.ScriptPubKey.Addresses = encodedAddrs
vout.ScriptPubKey.Asm = disbuf vout.ScriptPubKey.Asm = disbuf
vout.ScriptPubKey.Hex = hex.EncodeToString(v.PkScript) vout.ScriptPubKey.Hex = hex.EncodeToString(v.PkScript)
vout.ScriptPubKey.Type = scriptClass.String()
vout.ScriptPubKey.ReqSigs = int32(reqSigs) vout.ScriptPubKey.ReqSigs = int32(reqSigs)
if len(script) < len(v.PkScript) {
vout.ScriptPubKey.IsClaim = v.PkScript[0] == txscript.OP_CLAIMNAME || v.PkScript[0] == txscript.OP_UPDATECLAIM
vout.ScriptPubKey.IsSupport = v.PkScript[0] == txscript.OP_SUPPORTCLAIM
vout.ScriptPubKey.SubType = scriptClass.String()
vout.ScriptPubKey.Type = txscript.ScriptClass.String(0)
} else {
vout.ScriptPubKey.Type = scriptClass.String()
}
// TODO here: isclaim, issupport, subtype,
voutList = append(voutList, vout) voutList = append(voutList, vout)
} }
@ -882,7 +895,6 @@ func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
return float64(feeRate), nil return float64(feeRate), nil
} }
// handleGenerate handles generate commands.
func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
// Respond with an error if there are no addresses to pay the // Respond with an error if there are no addresses to pay the
// created blocks to. // created blocks to.
@ -919,7 +931,62 @@ func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
// Create a reply // Create a reply
reply := make([]string, c.NumBlocks) reply := make([]string, c.NumBlocks)
blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(c.NumBlocks) blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(c.NumBlocks, nil)
if err != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInternal.Code,
Message: err.Error(),
}
}
// Mine the correct number of blocks, assigning the hex representation of the
// hash of each one to its place in the reply.
for i, hash := range blockHashes {
reply[i] = hash.String()
}
return reply, nil
}
// handleGenerateToAddress handles generate commands.
func handleGenerateToAddress(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.GenerateToAddressCmd)
payToAddr, err := btcutil.DecodeAddress(c.Address, s.cfg.ChainParams)
// Respond with an error if there are no addresses to pay the
// created blocks to.
if err != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidParameter,
Message: "No payment addresses specified ",
}
}
// cfg.miningAddrs = append(cfg.miningAddrs, maddr)
// Respond with an error if there's virtually 0 chance of mining a block
// with the CPU.
if !s.cfg.ChainParams.GenerateSupported {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCDifficulty,
Message: fmt.Sprintf("No support for `generatetoaddress` on "+
"the current network, %s, as it's unlikely to "+
"be possible to mine a block with the CPU.",
s.cfg.ChainParams.Net),
}
}
// Respond with an error if the client is requesting 0 blocks to be generated.
if c.NumBlocks == 0 {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInternal.Code,
Message: "Please request a nonzero number of blocks to generate.",
}
}
// Create a reply
reply := make([]string, c.NumBlocks)
blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(uint32(c.NumBlocks), payToAddr)
if err != nil { if err != nil {
return nil, &btcjson.RPCError{ return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInternal.Code, Code: btcjson.ErrRPCInternal.Code,
@ -2537,6 +2604,84 @@ func handleGetNodeAddresses(s *rpcServer, cmd interface{}, closeChan <-chan stru
return addresses, nil return addresses, nil
} }
// handleGetNetworkInfo implements the getnetworkinfo command.
func handleGetNetworkInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
ver := wire.MsgVersion{}
_ = ver.AddUserAgent(userAgentName, userAgentVersion, cfg.UserAgentComments...)
var localAddrs []btcjson.LocalAddressesResult
var ipv4Reachable, ipv6Reachable bool
for _, addr := range s.cfg.AddrMgr.LocalAddresses() {
localAddrs = append(localAddrs, btcjson.LocalAddressesResult{
Address: addr.NA.IP.String(),
Port: addr.NA.Port,
Score: int32(addr.Score),
})
if addr.NA.IP.To4() != nil {
ipv4Reachable = true
} else {
ipv6Reachable = true
}
}
onionProxy := cfg.Proxy
if cfg.OnionProxy != "" {
onionProxy = cfg.OnionProxy
}
var warnings string
unknownRulesWarned := s.cfg.Chain.GetWarnings()
if unknownRulesWarned {
warnings = "Warning: Unknown new rules activated! "
}
var timeOffset int64
if !s.cfg.SyncMgr.IsCurrent() {
ss := s.cfg.Chain.BestSnapshot()
bestHeader, err := s.cfg.Chain.HeaderByHash(&ss.Hash)
if err != nil {
return nil, err
}
timeOffset = int64(time.Since(bestHeader.Timestamp).Seconds())
}
reply := &btcjson.GetNetworkInfoResult{
ProtocolVersion: int32(wire.ProtocolVersion),
Version: versionNumeric(),
Connections: s.cfg.ConnMgr.ConnectedCount(),
IncrementalFee: cfg.MinRelayTxFee,
LocalAddresses: localAddrs,
LocalRelay: !cfg.BlocksOnly,
LocalServices: s.cfg.Services.String(),
NetworkActive: true,
Networks: []btcjson.NetworksResult{
{
Name: "ipv4",
Reachable: ipv4Reachable,
Proxy: cfg.Proxy,
},
{
Name: "ipv6",
Reachable: ipv6Reachable,
Proxy: cfg.Proxy,
},
{
Name: "onion",
ProxyRandomizeCredentials: cfg.TorIsolation,
Proxy: onionProxy,
Reachable: cfg.Proxy != "" || cfg.OnionProxy != "",
},
},
RelayFee: cfg.MinRelayTxFee,
SubVersion: ver.UserAgent,
TimeOffset: timeOffset,
Warnings: warnings,
}
return reply, nil
}
// handleGetPeerInfo implements the getpeerinfo command. // handleGetPeerInfo implements the getpeerinfo command.
func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
peers := s.cfg.ConnMgr.ConnectedPeers() peers := s.cfg.ConnMgr.ConnectedPeers()
@ -2795,10 +2940,12 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
// doesn't fully parse, so ignore the error here. // doesn't fully parse, so ignore the error here.
disbuf, _ := txscript.DisasmString(pkScript) disbuf, _ := txscript.DisasmString(pkScript)
script := txscript.StripClaimScriptPrefix(pkScript)
// Get further info about the script. // Get further info about the script.
// Ignore the error here since an error means the script couldn't parse // Ignore the error here since an error means the script couldn't parse
// and there is no additional information about it anyways. // and there is no additional information about it anyways.
scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(pkScript, scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script,
s.cfg.ChainParams) s.cfg.ChainParams)
addresses := make([]string, len(addrs)) addresses := make([]string, len(addrs))
for i, addr := range addrs { for i, addr := range addrs {
@ -2813,11 +2960,20 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
Asm: disbuf, Asm: disbuf,
Hex: hex.EncodeToString(pkScript), Hex: hex.EncodeToString(pkScript),
ReqSigs: int32(reqSigs), ReqSigs: int32(reqSigs),
Type: scriptClass.String(),
Addresses: addresses, Addresses: addresses,
}, },
Coinbase: isCoinbase, Coinbase: isCoinbase,
} }
if len(script) < len(pkScript) {
txOutReply.ScriptPubKey.IsClaim = pkScript[0] == txscript.OP_CLAIMNAME || pkScript[0] == txscript.OP_UPDATECLAIM
txOutReply.ScriptPubKey.IsSupport = pkScript[0] == txscript.OP_SUPPORTCLAIM
txOutReply.ScriptPubKey.SubType = scriptClass.String()
txOutReply.ScriptPubKey.Type = txscript.ScriptClass.String(0)
} else {
txOutReply.ScriptPubKey.Type = scriptClass.String()
}
return txOutReply, nil return txOutReply, nil
} }
@ -3066,6 +3222,8 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P
vinListEntry.PrevOut = &btcjson.PrevOut{ vinListEntry.PrevOut = &btcjson.PrevOut{
Addresses: encodedAddrs, Addresses: encodedAddrs,
Value: btcutil.Amount(originTxOut.Value).ToBTC(), Value: btcutil.Amount(originTxOut.Value).ToBTC(),
IsClaim: originTxOut.PkScript[0] == txscript.OP_CLAIMNAME || originTxOut.PkScript[0] == txscript.OP_UPDATECLAIM,
IsSupport: originTxOut.PkScript[0] == txscript.OP_SUPPORTCLAIM,
} }
} }
} }
@ -3548,7 +3706,7 @@ func handleStop(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter
case s.requestProcessShutdown <- struct{}{}: case s.requestProcessShutdown <- struct{}{}:
default: default:
} }
return "btcd stopping.", nil return "lbcd stopping.", nil
} }
// handleSubmitBlock implements the submitblock command. // handleSubmitBlock implements the submitblock command.
@ -3756,7 +3914,7 @@ func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{
// NOTE: This is a btcsuite extension ported from github.com/decred/dcrd. // NOTE: This is a btcsuite extension ported from github.com/decred/dcrd.
func handleVersion(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { func handleVersion(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
result := map[string]btcjson.VersionResult{ result := map[string]btcjson.VersionResult{
"btcdjsonrpcapi": { "lbcdjsonrpcapi": {
VersionString: jsonrpcSemverString, VersionString: jsonrpcSemverString,
Major: jsonrpcSemverMajor, Major: jsonrpcSemverMajor,
Minor: jsonrpcSemverMinor, Minor: jsonrpcSemverMinor,
@ -4350,7 +4508,7 @@ func (s *rpcServer) jsonRPCRead(w http.ResponseWriter, r *http.Request, isAdmin
// jsonAuthFail sends a message back to the client if the http auth is rejected. // jsonAuthFail sends a message back to the client if the http auth is rejected.
func jsonAuthFail(w http.ResponseWriter) { func jsonAuthFail(w http.ResponseWriter) {
w.Header().Add("WWW-Authenticate", `Basic realm="btcd RPC"`) w.Header().Add("WWW-Authenticate", `Basic realm="lbcd RPC"`)
http.Error(w, "401 Unauthorized.", http.StatusUnauthorized) http.Error(w, "401 Unauthorized.", http.StatusUnauthorized)
} }
@ -4431,7 +4589,7 @@ func (s *rpcServer) Start() {
func genCertPair(certFile, keyFile string) error { func genCertPair(certFile, keyFile string) error {
rpcsLog.Infof("Generating TLS certificates...") rpcsLog.Infof("Generating TLS certificates...")
org := "btcd autogenerated cert" org := "lbcd autogenerated cert"
validUntil := time.Now().Add(10 * 365 * 24 * time.Hour) validUntil := time.Now().Add(10 * 365 * 24 * time.Hour)
cert, key, err := btcutil.NewTLSCertPair(org, validUntil, nil) cert, key, err := btcutil.NewTLSCertPair(org, validUntil, nil)
if err != nil { if err != nil {
@ -4582,6 +4740,9 @@ type rpcserverConfig struct {
// connection-related data and tasks. // connection-related data and tasks.
ConnMgr rpcserverConnManager ConnMgr rpcserverConnManager
// AddrMgr is the server's instance of the AddressManager.
AddrMgr *addrmgr.AddrManager
// SyncMgr defines the sync manager for the RPC server to use. // SyncMgr defines the sync manager for the RPC server to use.
SyncMgr rpcserverSyncManager SyncMgr rpcserverSyncManager
@ -4612,6 +4773,9 @@ type rpcserverConfig struct {
// The fee estimator keeps track of how long transactions are left in // The fee estimator keeps track of how long transactions are left in
// the mempool before they are mined into blocks. // the mempool before they are mined into blocks.
FeeEstimator *mempool.FeeEstimator FeeEstimator *mempool.FeeEstimator
// Services represents the services supported by this node.
Services wire.ServiceFlag
} }
// newRPCServer returns a new instance of the rpcServer struct. // newRPCServer returns a new instance of the rpcServer struct.

View file

@ -454,6 +454,27 @@ var helpDescsEnUS = map[string]string{
"getnetworkhashps-height": "Perform estimate ending with this height or -1 for current best chain block height", "getnetworkhashps-height": "Perform estimate ending with this height or -1 for current best chain block height",
"getnetworkhashps--result0": "Estimated hashes per second", "getnetworkhashps--result0": "Estimated hashes per second",
// GetNetworkInfo help.
"getnetworkinfo--synopsis": "Returns an object containing various state info regarding P2P networking.",
"getnetworkinfo--result0--desc": "GetNetworkInfo object",
"getnetworkinfo--result0--key": "Field name",
"getnetworkinfo--result0--value": "Object containing the network info",
// GetNetworkInfoResult help.
"getnetworkinforesult-version": "The server version",
"getnetworkinforesult-subversion": "The server subversion string",
"getnetworkinforesult-protocolversion": "The protocol version",
"getnetworkinforesult-localservices": "The services we offer to the network",
"getnetworkinforesult-localrelay": "True if transaction relay is requested from peers",
"getnetworkinforesult-timeoffset": "The time offset",
"getnetworkinforesult-connections": "The number of connections",
"getnetworkinforesult-networkactive": "Whether p2p networking is enabled",
"getnetworkinforesult-networks": "Information per network",
"getnetworkinforesult-relayfee": "Minimum relay fee for transactions in BTC/kB",
"getnetworkinforesult-incrementalfee": "Minimum fee increment for mempool limiting or BIP 125 replacement in BTC/kB",
"getnetworkinforesult-localaddresses": "List of local addresses",
"getnetworkinforesult-warnings": "Any network and blockchain warnings",
// GetNetTotalsCmd help. // GetNetTotalsCmd help.
"getnettotals--synopsis": "Returns a JSON object containing network traffic statistics.", "getnettotals--synopsis": "Returns a JSON object containing network traffic statistics.",
@ -819,6 +840,7 @@ var rpcResultTypes = map[string][]interface{}{
"getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)}, "getmininginfo": {(*btcjson.GetMiningInfoResult)(nil)},
"getnettotals": {(*btcjson.GetNetTotalsResult)(nil)}, "getnettotals": {(*btcjson.GetNetTotalsResult)(nil)},
"getnetworkhashps": {(*int64)(nil)}, "getnetworkhashps": {(*int64)(nil)},
"getnetworkinfo": {(*map[string]btcjson.GetNetworkInfoResult)(nil)},
"getnodeaddresses": {(*[]btcjson.GetNodeAddressesResult)(nil)}, "getnodeaddresses": {(*[]btcjson.GetNodeAddressesResult)(nil)},
"getpeerinfo": {(*[]btcjson.GetPeerInfoResult)(nil)}, "getpeerinfo": {(*[]btcjson.GetPeerInfoResult)(nil)},
"getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)}, "getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)},

View file

@ -2950,6 +2950,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string,
Listeners: rpcListeners, Listeners: rpcListeners,
StartupTime: startupTime.Unix(), StartupTime: startupTime.Unix(),
ConnMgr: &rpcConnManager{&s}, ConnMgr: &rpcConnManager{&s},
AddrMgr: amgr,
SyncMgr: &rpcSyncMgr{&s, s.syncManager}, SyncMgr: &rpcSyncMgr{&s, s.syncManager},
TimeSource: s.timeSource, TimeSource: s.timeSource,
Chain: s.chain, Chain: s.chain,
@ -2962,6 +2963,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string,
AddrIndex: s.addrIndex, AddrIndex: s.addrIndex,
CfIndex: s.cfIndex, CfIndex: s.cfIndex,
FeeEstimator: s.feeEstimator, FeeEstimator: s.feeEstimator,
Services: s.services,
}) })
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -57,6 +57,11 @@ func version() string {
return version return version
} }
// Numeric returns the application version as an integer.
func versionNumeric() int32 {
return int32(2 ^ appMajor*3 ^ appMinor*5 ^ appPatch)
}
// normalizeVerString returns the passed string stripped of all characters which // normalizeVerString returns the passed string stripped of all characters which
// are not valid according to the semantic versioning guidelines for pre-release // are not valid according to the semantic versioning guidelines for pre-release
// version and build metadata strings. In particular they MUST only contain // version and build metadata strings. In particular they MUST only contain