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 (#5397)
This commit is contained in:
parent
05d03e7da6
commit
536cc26ba5
3 changed files with 69 additions and 12 deletions
node-test/src/test/scala/org/bitcoins/node
node/src/main/scala/org/bitcoins/node
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue