| 1809 | } |
| 1810 | |
| 1811 | bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const |
| 1812 | { |
| 1813 | { |
| 1814 | LOCK(cs_main); |
| 1815 | const CNodeState* state = State(nodeid); |
| 1816 | if (state == nullptr) |
| 1817 | return false; |
| 1818 | stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1; |
| 1819 | stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1; |
| 1820 | for (const QueuedBlock& queue : state->vBlocksInFlight) { |
| 1821 | if (queue.pindex) |
| 1822 | stats.vHeightInFlight.push_back(queue.pindex->nHeight); |
| 1823 | } |
| 1824 | } |
| 1825 | |
| 1826 | PeerRef peer = GetPeerRef(nodeid); |
| 1827 | if (peer == nullptr) return false; |
| 1828 | stats.their_services = peer->m_their_services; |
| 1829 | // It is common for nodes with good ping times to suddenly become lagged, |
| 1830 | // due to a new block arriving or other large transfer. |
| 1831 | // Merely reporting pingtime might fool the caller into thinking the node was still responsive, |
| 1832 | // since pingtime does not update until the ping is complete, which might take a while. |
| 1833 | // So, if a ping is taking an unusually long time in flight, |
| 1834 | // the caller can immediately detect that this is happening. |
| 1835 | NodeClock::duration ping_wait{0us}; |
| 1836 | if ((0 != peer->m_ping_nonce_sent) && (peer->m_ping_start.load() > NodeClock::epoch)) { |
| 1837 | ping_wait = NodeClock::now() - peer->m_ping_start.load(); |
| 1838 | } |
| 1839 | |
| 1840 | if (auto tx_relay = peer->GetTxRelay(); tx_relay != nullptr) { |
| 1841 | stats.m_relay_txs = WITH_LOCK(tx_relay->m_bloom_filter_mutex, return tx_relay->m_relay_txs); |
| 1842 | stats.m_fee_filter_received = tx_relay->m_fee_filter_received.load(); |
| 1843 | LOCK(tx_relay->m_tx_inventory_mutex); |
| 1844 | stats.m_last_inv_seq = tx_relay->m_last_inv_sequence; |
| 1845 | stats.m_inv_to_send = tx_relay->m_tx_inventory_to_send.size(); |
| 1846 | } else { |
| 1847 | stats.m_relay_txs = false; |
| 1848 | stats.m_fee_filter_received = 0; |
| 1849 | stats.m_inv_to_send = 0; |
| 1850 | } |
| 1851 | |
| 1852 | stats.m_ping_wait = ping_wait; |
| 1853 | stats.m_addr_processed = peer->m_addr_processed.load(); |
| 1854 | stats.m_addr_rate_limited = peer->m_addr_rate_limited.load(); |
| 1855 | stats.m_addr_relay_enabled = peer->m_addr_relay_enabled.load(); |
| 1856 | { |
| 1857 | LOCK(peer->m_headers_sync_mutex); |
| 1858 | if (peer->m_headers_sync) { |
| 1859 | stats.presync_height = peer->m_headers_sync->GetPresyncHeight(); |
| 1860 | } |
| 1861 | } |
| 1862 | stats.time_offset = peer->m_time_offset; |
| 1863 | |
| 1864 | return true; |
| 1865 | } |
| 1866 | |
| 1867 | std::vector<node::TxOrphanage::OrphanInfo> PeerManagerImpl::GetOrphanTransactions() |
| 1868 | { |