Fix inconsistency of PeerDAO primary key usage (#5398)

* Fix inconsistency of PeerDAO primary key usage

* Add Peer.port helper method
This commit is contained in:
Chris Stewart 2024-02-14 13:31:56 -06:00 committed by GitHub
parent 536cc26ba5
commit fe33c2919c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 19 additions and 16 deletions

View file

@ -15,6 +15,8 @@ case class Peer(
this.copy(id = Some(id))
}
def port: Int = socket.getPort
override def toString(): String =
s"Peer(${socket.getHostString()}:${socket.getPort()})"

View file

@ -96,7 +96,7 @@ class PeerManagerTest extends NodeTestWithCachedBitcoindNewest {
_ <- NodeTestUtil.awaitConnectionCount(node, 0)
addrBytes = PeerDAOHelper.getAddrBytes(peer)
peerDb <- PeerDAO()(system.dispatcher, node.nodeConfig)
.read(addrBytes)
.read((addrBytes, peer.port))
.map(_.get)
} yield {
assert(timestamp.isBefore(peerDb.lastSeen))

View file

@ -24,7 +24,7 @@ class PeerDAOTest extends NodeDAOFixture {
for {
created <- peerDAO.create(peer)
read <- peerDAO.read(peer.address)
read <- peerDAO.read((peer.address, peer.port))
} yield {
assert(
read.get.address == created.address &&

View file

@ -134,10 +134,7 @@ case class PeerManager(
s"Unsupported address type of size $unknownSize bytes")
}
PeerDAO()
.upsertPeer(addrBytes,
peer.socket.getPort,
networkByte,
serviceIdentifier)
.upsertPeer(addrBytes, peer.port, networkByte, serviceIdentifier)
}
private def replacePeer(replacePeer: Peer, withPeer: Peer): Future[Unit] = {
@ -336,8 +333,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 updateLastSeenF = PeerDAO().updateLastSeenTime(peer)
val stateF = {
require(!finder.hasPeer(peer) || !peerDataMap.contains(peer),
s"$peer cannot be both a test and a persistent peer")

View file

@ -23,8 +23,8 @@ case class PeerDb(
)
case class PeerDAO()(implicit ec: ExecutionContext, appConfig: NodeAppConfig)
extends CRUD[PeerDb, ByteVector]
with SlickUtil[PeerDb, ByteVector] {
extends CRUD[PeerDb, (ByteVector, Int)]
with SlickUtil[PeerDb, (ByteVector, Int)] {
import profile.api._
val mappers = new org.bitcoins.db.DbCommonsColumnMappers(profile)
@ -37,13 +37,15 @@ case class PeerDAO()(implicit ec: ExecutionContext, appConfig: NodeAppConfig)
createAllNoAutoInc(ts, safeDatabase)
override protected def findByPrimaryKeys(
ids: Vector[ByteVector]): Query[PeerTable, PeerDb, Seq] = {
table.filter(_.address.inSet(ids))
ids: Vector[(ByteVector, Int)]): Query[PeerTable, PeerDb, Seq] = {
//from: https://stackoverflow.com/questions/26815913/how-to-do-or-filter-in-slick
table.filter(r =>
ids.map(i => r.address === i._1 && r.port === i._2).reduceLeft(_ || _))
}
override protected def findAll(
ts: Vector[PeerDb]): Query[Table[PeerDb], PeerDb, Seq] =
findByPrimaryKeys(ts.map(_.address))
findByPrimaryKeys(ts.map(t => (t.address, t.port)))
def deleteByKey(address: String): Future[Int] = {
val bytes = ByteVector(address.getBytes)
@ -64,7 +66,7 @@ case class PeerDAO()(implicit ec: ExecutionContext, appConfig: NodeAppConfig)
networkId: Byte,
serviceIdentifier: ServiceIdentifier): Future[PeerDb] = {
val lastSeen: Instant = Instant.now
val existingF = read(address)
val existingF = read((address, port))
existingF.flatMap {
case Some(value) =>
upsert(
@ -85,8 +87,10 @@ case class PeerDAO()(implicit ec: ExecutionContext, appConfig: NodeAppConfig)
}
}
def updateLastSeenTime(address: ByteVector): Future[Option[PeerDb]] = {
val action = table.filter(_.address === address).result.headOption
def updateLastSeenTime(peer: Peer): Future[Option[PeerDb]] = {
val address = PeerDAOHelper.getAddrBytes(peer)
val port = peer.port
val action = findByPrimaryKey((address, port)).result.headOption
val updatedLastSeenA = action.flatMap {
case Some(peerDb) =>
updateAction(peerDb.copy(lastSeen = Instant.now()))