diff --git a/src/net.h b/src/net.h --- a/src/net.h +++ b/src/net.h @@ -674,6 +674,7 @@ int64_t nLastSend; int64_t nLastRecv; int64_t nLastTXTime; + int64_t nLastProofTime; int64_t nLastBlockTime; int64_t nTimeConnected; int64_t nTimeOffset; @@ -1064,6 +1065,14 @@ */ std::atomic nLastTXTime{0}; + /** + * UNIX epoch time of the last proof received from this peer that we + * had not yet seen (e.g. not already received from another peer) and that + * was accepted into our proof pool. Used as an inbound peer eviction + * criterium in CConnman::AttemptToEvictConnection. + */ + std::atomic nLastProofTime{0}; + // Ping time measurement: // The pong reply we're expecting, or 0 if no pong expected. std::atomic nPingNonceSent{0}; diff --git a/src/net.cpp b/src/net.cpp --- a/src/net.cpp +++ b/src/net.cpp @@ -553,6 +553,7 @@ stats.nLastSend = nLastSend; stats.nLastRecv = nLastRecv; stats.nLastTXTime = nLastTXTime; + stats.nLastProofTime = nLastProofTime; stats.nLastBlockTime = nLastBlockTime; stats.nTimeConnected = nTimeConnected; stats.nTimeOffset = nTimeOffset; diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4410,6 +4410,8 @@ WITH_LOCK(cs_proofrequest, m_proofrequest.ForgetInvId(proofid)); RelayProof(proofid, m_connman); + pfrom.nLastProofTime = GetTime(); + LogPrint(BCLog::NET, "New avalanche proof: peer=%d, proofid %s\n", nodeid, proofid.ToString()); } else { diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -4,6 +4,7 @@ #include +#include #include #include #include @@ -231,6 +232,9 @@ obj.pushKV("lastsend", stats.nLastSend); obj.pushKV("lastrecv", stats.nLastRecv); obj.pushKV("last_transaction", stats.nLastTXTime); + if (g_avalanche) { + obj.pushKV("last_proof", stats.nLastProofTime); + } obj.pushKV("last_block", stats.nLastBlockTime); obj.pushKV("bytessent", stats.nSendBytes); obj.pushKV("bytesrecv", stats.nRecvBytes); diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py --- a/test/functional/rpc_net.py +++ b/test/functional/rpc_net.py @@ -11,6 +11,8 @@ from itertools import product import time +from test_framework.avatools import create_coinbase_stakes +from test_framework.key import ECKey from test_framework.p2p import P2PInterface import test_framework.messages from test_framework.messages import ( @@ -49,8 +51,8 @@ def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 - self.extra_args = [["-minrelaytxfee=10"], - ["-minrelaytxfee=5"]] + self.extra_args = [["-enableavalanche=1", "-minrelaytxfee=10"], + ["-enableavalanche=1", "-minrelaytxfee=5"]] self.supports_cli = False def run_test(self): @@ -159,16 +161,27 @@ def test_getpeerinfo(self): self.log.info("Test getpeerinfo") - # Create a few getpeerinfo last_block/last_transaction values. + # Create a few getpeerinfo last_block/last_transaction/last_proof + # values. if self.is_wallet_compiled(): self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1000000) - self.nodes[1].generate(1) + tip = self.nodes[1].generate(1)[0] self.sync_all() + + stake = create_coinbase_stakes( + self.nodes[1], [tip], self.nodes[1].get_deterministic_priv_key().key) + privkey = ECKey() + privkey.generate() + proof = self.nodes[1].buildavalancheproof( + 42, 2000000000, privkey.get_pubkey().get_bytes().hex(), stake) + self.nodes[1].sendavalancheproof(proof) + self.sync_proofs() + time_now = int(time.time()) peer_info = [x.getpeerinfo() for x in self.nodes] - # Verify last_block and last_transaction keys/values. + # Verify last_block, last_transaction and last_proof keys/values. for node, peer, field in product(range(self.num_nodes), range(2), [ - 'last_block', 'last_transaction']): + 'last_block', 'last_transaction', 'last_proof']): assert field in peer_info[node][peer].keys() if peer_info[node][peer][field] != 0: assert_approx(peer_info[node][peer][field], time_now, vspan=60)