github.com/btcsuite/btcd@v0.24.0/rpcadapters.go (about)

     1  // Copyright (c) 2017 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"sync/atomic"
     9  
    10  	"github.com/btcsuite/btcd/blockchain"
    11  	"github.com/btcsuite/btcd/btcutil"
    12  	"github.com/btcsuite/btcd/chaincfg/chainhash"
    13  	"github.com/btcsuite/btcd/mempool"
    14  	"github.com/btcsuite/btcd/netsync"
    15  	"github.com/btcsuite/btcd/peer"
    16  	"github.com/btcsuite/btcd/wire"
    17  )
    18  
    19  // rpcPeer provides a peer for use with the RPC server and implements the
    20  // rpcserverPeer interface.
    21  type rpcPeer serverPeer
    22  
    23  // Ensure rpcPeer implements the rpcserverPeer interface.
    24  var _ rpcserverPeer = (*rpcPeer)(nil)
    25  
    26  // ToPeer returns the underlying peer instance.
    27  //
    28  // This function is safe for concurrent access and is part of the rpcserverPeer
    29  // interface implementation.
    30  func (p *rpcPeer) ToPeer() *peer.Peer {
    31  	if p == nil {
    32  		return nil
    33  	}
    34  	return (*serverPeer)(p).Peer
    35  }
    36  
    37  // IsTxRelayDisabled returns whether or not the peer has disabled transaction
    38  // relay.
    39  //
    40  // This function is safe for concurrent access and is part of the rpcserverPeer
    41  // interface implementation.
    42  func (p *rpcPeer) IsTxRelayDisabled() bool {
    43  	return (*serverPeer)(p).disableRelayTx
    44  }
    45  
    46  // BanScore returns the current integer value that represents how close the peer
    47  // is to being banned.
    48  //
    49  // This function is safe for concurrent access and is part of the rpcserverPeer
    50  // interface implementation.
    51  func (p *rpcPeer) BanScore() uint32 {
    52  	return (*serverPeer)(p).banScore.Int()
    53  }
    54  
    55  // FeeFilter returns the requested current minimum fee rate for which
    56  // transactions should be announced.
    57  //
    58  // This function is safe for concurrent access and is part of the rpcserverPeer
    59  // interface implementation.
    60  func (p *rpcPeer) FeeFilter() int64 {
    61  	return atomic.LoadInt64(&(*serverPeer)(p).feeFilter)
    62  }
    63  
    64  // rpcConnManager provides a connection manager for use with the RPC server and
    65  // implements the rpcserverConnManager interface.
    66  type rpcConnManager struct {
    67  	server *server
    68  }
    69  
    70  // Ensure rpcConnManager implements the rpcserverConnManager interface.
    71  var _ rpcserverConnManager = &rpcConnManager{}
    72  
    73  // Connect adds the provided address as a new outbound peer.  The permanent flag
    74  // indicates whether or not to make the peer persistent and reconnect if the
    75  // connection is lost.  Attempting to connect to an already existing peer will
    76  // return an error.
    77  //
    78  // This function is safe for concurrent access and is part of the
    79  // rpcserverConnManager interface implementation.
    80  func (cm *rpcConnManager) Connect(addr string, permanent bool) error {
    81  	replyChan := make(chan error)
    82  	cm.server.query <- connectNodeMsg{
    83  		addr:      addr,
    84  		permanent: permanent,
    85  		reply:     replyChan,
    86  	}
    87  	return <-replyChan
    88  }
    89  
    90  // RemoveByID removes the peer associated with the provided id from the list of
    91  // persistent peers.  Attempting to remove an id that does not exist will return
    92  // an error.
    93  //
    94  // This function is safe for concurrent access and is part of the
    95  // rpcserverConnManager interface implementation.
    96  func (cm *rpcConnManager) RemoveByID(id int32) error {
    97  	replyChan := make(chan error)
    98  	cm.server.query <- removeNodeMsg{
    99  		cmp:   func(sp *serverPeer) bool { return sp.ID() == id },
   100  		reply: replyChan,
   101  	}
   102  	return <-replyChan
   103  }
   104  
   105  // RemoveByAddr removes the peer associated with the provided address from the
   106  // list of persistent peers.  Attempting to remove an address that does not
   107  // exist will return an error.
   108  //
   109  // This function is safe for concurrent access and is part of the
   110  // rpcserverConnManager interface implementation.
   111  func (cm *rpcConnManager) RemoveByAddr(addr string) error {
   112  	replyChan := make(chan error)
   113  	cm.server.query <- removeNodeMsg{
   114  		cmp:   func(sp *serverPeer) bool { return sp.Addr() == addr },
   115  		reply: replyChan,
   116  	}
   117  	return <-replyChan
   118  }
   119  
   120  // DisconnectByID disconnects the peer associated with the provided id.  This
   121  // applies to both inbound and outbound peers.  Attempting to remove an id that
   122  // does not exist will return an error.
   123  //
   124  // This function is safe for concurrent access and is part of the
   125  // rpcserverConnManager interface implementation.
   126  func (cm *rpcConnManager) DisconnectByID(id int32) error {
   127  	replyChan := make(chan error)
   128  	cm.server.query <- disconnectNodeMsg{
   129  		cmp:   func(sp *serverPeer) bool { return sp.ID() == id },
   130  		reply: replyChan,
   131  	}
   132  	return <-replyChan
   133  }
   134  
   135  // DisconnectByAddr disconnects the peer associated with the provided address.
   136  // This applies to both inbound and outbound peers.  Attempting to remove an
   137  // address that does not exist will return an error.
   138  //
   139  // This function is safe for concurrent access and is part of the
   140  // rpcserverConnManager interface implementation.
   141  func (cm *rpcConnManager) DisconnectByAddr(addr string) error {
   142  	replyChan := make(chan error)
   143  	cm.server.query <- disconnectNodeMsg{
   144  		cmp:   func(sp *serverPeer) bool { return sp.Addr() == addr },
   145  		reply: replyChan,
   146  	}
   147  	return <-replyChan
   148  }
   149  
   150  // ConnectedCount returns the number of currently connected peers.
   151  //
   152  // This function is safe for concurrent access and is part of the
   153  // rpcserverConnManager interface implementation.
   154  func (cm *rpcConnManager) ConnectedCount() int32 {
   155  	return cm.server.ConnectedCount()
   156  }
   157  
   158  // NetTotals returns the sum of all bytes received and sent across the network
   159  // for all peers.
   160  //
   161  // This function is safe for concurrent access and is part of the
   162  // rpcserverConnManager interface implementation.
   163  func (cm *rpcConnManager) NetTotals() (uint64, uint64) {
   164  	return cm.server.NetTotals()
   165  }
   166  
   167  // ConnectedPeers returns an array consisting of all connected peers.
   168  //
   169  // This function is safe for concurrent access and is part of the
   170  // rpcserverConnManager interface implementation.
   171  func (cm *rpcConnManager) ConnectedPeers() []rpcserverPeer {
   172  	replyChan := make(chan []*serverPeer)
   173  	cm.server.query <- getPeersMsg{reply: replyChan}
   174  	serverPeers := <-replyChan
   175  
   176  	// Convert to RPC server peers.
   177  	peers := make([]rpcserverPeer, 0, len(serverPeers))
   178  	for _, sp := range serverPeers {
   179  		peers = append(peers, (*rpcPeer)(sp))
   180  	}
   181  	return peers
   182  }
   183  
   184  // PersistentPeers returns an array consisting of all the added persistent
   185  // peers.
   186  //
   187  // This function is safe for concurrent access and is part of the
   188  // rpcserverConnManager interface implementation.
   189  func (cm *rpcConnManager) PersistentPeers() []rpcserverPeer {
   190  	replyChan := make(chan []*serverPeer)
   191  	cm.server.query <- getAddedNodesMsg{reply: replyChan}
   192  	serverPeers := <-replyChan
   193  
   194  	// Convert to generic peers.
   195  	peers := make([]rpcserverPeer, 0, len(serverPeers))
   196  	for _, sp := range serverPeers {
   197  		peers = append(peers, (*rpcPeer)(sp))
   198  	}
   199  	return peers
   200  }
   201  
   202  // BroadcastMessage sends the provided message to all currently connected peers.
   203  //
   204  // This function is safe for concurrent access and is part of the
   205  // rpcserverConnManager interface implementation.
   206  func (cm *rpcConnManager) BroadcastMessage(msg wire.Message) {
   207  	cm.server.BroadcastMessage(msg)
   208  }
   209  
   210  // AddRebroadcastInventory adds the provided inventory to the list of
   211  // inventories to be rebroadcast at random intervals until they show up in a
   212  // block.
   213  //
   214  // This function is safe for concurrent access and is part of the
   215  // rpcserverConnManager interface implementation.
   216  func (cm *rpcConnManager) AddRebroadcastInventory(iv *wire.InvVect, data interface{}) {
   217  	cm.server.AddRebroadcastInventory(iv, data)
   218  }
   219  
   220  // RelayTransactions generates and relays inventory vectors for all of the
   221  // passed transactions to all connected peers.
   222  func (cm *rpcConnManager) RelayTransactions(txns []*mempool.TxDesc) {
   223  	cm.server.relayTransactions(txns)
   224  }
   225  
   226  // NodeAddresses returns an array consisting node addresses which can
   227  // potentially be used to find new nodes in the network.
   228  //
   229  // This function is safe for concurrent access and is part of the
   230  // rpcserverConnManager interface implementation.
   231  func (cm *rpcConnManager) NodeAddresses() []*wire.NetAddressV2 {
   232  	return cm.server.addrManager.AddressCache()
   233  }
   234  
   235  // rpcSyncMgr provides a block manager for use with the RPC server and
   236  // implements the rpcserverSyncManager interface.
   237  type rpcSyncMgr struct {
   238  	server  *server
   239  	syncMgr *netsync.SyncManager
   240  }
   241  
   242  // Ensure rpcSyncMgr implements the rpcserverSyncManager interface.
   243  var _ rpcserverSyncManager = (*rpcSyncMgr)(nil)
   244  
   245  // IsCurrent returns whether or not the sync manager believes the chain is
   246  // current as compared to the rest of the network.
   247  //
   248  // This function is safe for concurrent access and is part of the
   249  // rpcserverSyncManager interface implementation.
   250  func (b *rpcSyncMgr) IsCurrent() bool {
   251  	return b.syncMgr.IsCurrent()
   252  }
   253  
   254  // SubmitBlock submits the provided block to the network after processing it
   255  // locally.
   256  //
   257  // This function is safe for concurrent access and is part of the
   258  // rpcserverSyncManager interface implementation.
   259  func (b *rpcSyncMgr) SubmitBlock(block *btcutil.Block, flags blockchain.BehaviorFlags) (bool, error) {
   260  	return b.syncMgr.ProcessBlock(block, flags)
   261  }
   262  
   263  // Pause pauses the sync manager until the returned channel is closed.
   264  //
   265  // This function is safe for concurrent access and is part of the
   266  // rpcserverSyncManager interface implementation.
   267  func (b *rpcSyncMgr) Pause() chan<- struct{} {
   268  	return b.syncMgr.Pause()
   269  }
   270  
   271  // SyncPeerID returns the peer that is currently the peer being used to sync
   272  // from.
   273  //
   274  // This function is safe for concurrent access and is part of the
   275  // rpcserverSyncManager interface implementation.
   276  func (b *rpcSyncMgr) SyncPeerID() int32 {
   277  	return b.syncMgr.SyncPeerID()
   278  }
   279  
   280  // LocateBlocks returns the hashes of the blocks after the first known block in
   281  // the provided locators until the provided stop hash or the current tip is
   282  // reached, up to a max of wire.MaxBlockHeadersPerMsg hashes.
   283  //
   284  // This function is safe for concurrent access and is part of the
   285  // rpcserverSyncManager interface implementation.
   286  func (b *rpcSyncMgr) LocateHeaders(locators []*chainhash.Hash, hashStop *chainhash.Hash) []wire.BlockHeader {
   287  	return b.server.chain.LocateHeaders(locators, hashStop)
   288  }