1
0
Fork 0
mirror of https://github.com/bitcoin-s/bitcoin-s.git synced 2025-03-26 21:42:48 +01:00

Update last seen value in PeerDb on disconnect ()

This commit is contained in:
Chris Stewart 2024-02-13 16:38:18 -06:00 committed by GitHub
parent 05d03e7da6
commit 536cc26ba5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 12 deletions
node-test/src/test/scala/org/bitcoins/node
node/src/main/scala/org/bitcoins/node

View file

@ -1,5 +1,6 @@
package org.bitcoins.node
import org.bitcoins.node.models.{PeerDAO, PeerDAOHelper}
import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.node.fixture.NeutrinoNodeConnectedWithBitcoind
@ -10,6 +11,7 @@ import org.bitcoins.testkit.node.{
import org.bitcoins.testkit.util.TorUtil
import org.scalatest.{FutureOutcome, Outcome}
import java.time.Instant
import scala.concurrent.Future
class PeerManagerTest extends NodeTestWithCachedBitcoindNewest {
@ -77,6 +79,30 @@ class PeerManagerTest extends NodeTestWithCachedBitcoindNewest {
}
}
it must "update last time a peer was seen on disconnect" in {
nodeConnectedWithBitcoind =>
val node = nodeConnectedWithBitcoind.node
val bitcoind = nodeConnectedWithBitcoind.bitcoind
val peerF = NodeTestUtil.getBitcoindPeer(bitcoind)
for {
_ <- node.start()
peer <- peerF
peerManager = node.peerManager
_ <- NodeTestUtil.awaitSyncAndIBD(node = node, bitcoind = bitcoind)
//disconnect
timestamp = Instant.now()
_ <- peerManager.disconnectPeer(peer)
_ <- NodeTestUtil.awaitConnectionCount(node, 0)
addrBytes = PeerDAOHelper.getAddrBytes(peer)
peerDb <- PeerDAO()(system.dispatcher, node.nodeConfig)
.read(addrBytes)
.map(_.get)
} yield {
assert(timestamp.isBefore(peerDb.lastSeen))
}
}
it must "determine if filters are out of sync" in { _ =>
val blockCount = 804934
val oldFilterHeaderCount = 804934

View file

@ -13,19 +13,17 @@ import org.bitcoins.core.api.chain.db.{
CompactFilterDb,
CompactFilterHeaderDb
}
import NodeState._
import org.bitcoins.core.api.node._
import org.bitcoins.core.p2p._
import org.bitcoins.core.util.{NetworkUtil, StartStopAsync}
import org.bitcoins.core.util.StartStopAsync
import org.bitcoins.crypto.DoubleSha256DigestBE
import org.bitcoins.node.NodeState._
import org.bitcoins.node.NodeStreamMessage._
import org.bitcoins.node.config.NodeAppConfig
import org.bitcoins.node.models.{PeerDAO, PeerDb}
import org.bitcoins.node.models.{PeerDAO, PeerDAOHelper, PeerDb}
import org.bitcoins.node.networking.peer._
import org.bitcoins.node.util.PeerMessageSenderApi
import scodec.bits.ByteVector
import java.net.InetAddress
import java.time.Instant
import java.util.concurrent.atomic.AtomicBoolean
import scala.collection.mutable
@ -126,11 +124,7 @@ case class PeerManager(
peer: Peer,
serviceIdentifier: ServiceIdentifier): Future[PeerDb] = {
logger.debug(s"Adding peer to db $peer")
val addrBytes =
if (peer.socket.getHostString.contains(".onion"))
NetworkUtil.torV3AddressToBytes(peer.socket.getHostString)
else
InetAddress.getByName(peer.socket.getHostString).getAddress
val addrBytes = PeerDAOHelper.getAddrBytes(peer)
val networkByte = addrBytes.length match {
case AddrV2Message.IPV4_ADDR_LENGTH => AddrV2Message.IPV4_NETWORK_BYTE
case AddrV2Message.IPV6_ADDR_LENGTH => AddrV2Message.IPV6_NETWORK_BYTE
@ -140,7 +134,7 @@ case class PeerManager(
s"Unsupported address type of size $unknownSize bytes")
}
PeerDAO()
.upsertPeer(ByteVector(addrBytes),
.upsertPeer(addrBytes,
peer.socket.getPort,
networkByte,
serviceIdentifier)
@ -342,6 +336,8 @@ case class PeerManager(
s"Disconnected peer=$peer peers=$peers state=$state forceReconnect=$forceReconnect peerDataMap=${peerDataMap
.map(_._1)}")
val finder = state.peerFinder
val addrBytes = PeerDAOHelper.getAddrBytes(peer)
val updateLastSeenF = PeerDAO().updateLastSeenTime(addrBytes)
val stateF = {
require(!finder.hasPeer(peer) || !peerDataMap.contains(peer),
s"$peer cannot be both a test and a persistent peer")
@ -406,7 +402,7 @@ case class PeerManager(
}
}
stateF.map {
val replacedPeersStateF = stateF.map {
case s: SyncNodeState =>
if (s.syncPeer == peer) {
//the peer being disconnected is our sync peer
@ -426,6 +422,11 @@ case class PeerManager(
case runningState: NodeRunningState =>
runningState.replacePeers(peerWithServicesDataMap)
}
for {
state <- replacedPeersStateF
_ <- updateLastSeenF
} yield state
}
private def onQueryTimeout(

View file

@ -1,11 +1,15 @@
package org.bitcoins.node.models
import org.bitcoins.core.api.node.Peer
import org.bitcoins.core.p2p.{AddrV2Message, ServiceIdentifier}
import org.bitcoins.core.util.NetworkUtil
import org.bitcoins.db.{CRUD, SlickUtil}
import org.bitcoins.node.config.NodeAppConfig
import scodec.bits.ByteVector
import slick.dbio.DBIOAction
import slick.lifted.ProvenShape
import java.net.InetAddress
import java.time.Instant
import scala.concurrent.{ExecutionContext, Future}
@ -81,6 +85,20 @@ case class PeerDAO()(implicit ec: ExecutionContext, appConfig: NodeAppConfig)
}
}
def updateLastSeenTime(address: ByteVector): Future[Option[PeerDb]] = {
val action = table.filter(_.address === address).result.headOption
val updatedLastSeenA = action.flatMap {
case Some(peerDb) =>
updateAction(peerDb.copy(lastSeen = Instant.now()))
.map(Some(_))
case None => DBIOAction.successful(None)
}
for {
result <- safeDatabase.run(updatedLastSeenA)
} yield result
}
class PeerTable(tag: Tag) extends Table[PeerDb](tag, schemaName, "peers") {
def address: Rep[ByteVector] = column("address")
@ -103,3 +121,15 @@ case class PeerDAO()(implicit ec: ExecutionContext, appConfig: NodeAppConfig)
PeerDb.unapply)
}
}
object PeerDAOHelper {
def getAddrBytes(peer: Peer): ByteVector = {
val addrBytes =
if (peer.socket.getHostString.contains(".onion"))
NetworkUtil.torV3AddressToBytes(peer.socket.getHostString)
else
InetAddress.getByName(peer.socket.getHostString).getAddress
ByteVector(addrBytes)
}
}