Add PeerDAO (#3738)

* add PeerDAO

* update DbManagementTest expected migration count
This commit is contained in:
Shreyansh 2021-10-10 18:20:11 +05:30 committed by GitHub
parent 3ffa997cc7
commit 99107b61ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 131 additions and 5 deletions

View file

@ -129,14 +129,14 @@ class DbManagementTest extends BitcoinSAsyncTest with EmbeddedPg {
val result = nodeDbManagement.migrate()
nodeAppConfig.driver match {
case SQLite =>
val expected = 2
val expected = 3
assert(result == expected)
val flywayInfo = nodeDbManagement.info()
assert(flywayInfo.applied().length == expected)
assert(flywayInfo.pending().length == 0)
case PostgreSQL =>
val expected = 2
val expected = 3
assert(result == expected)
val flywayInfo = nodeDbManagement.info()

View file

@ -0,0 +1,35 @@
package org.bitcoins.node.models
import org.bitcoins.core.p2p.AddrV2Message
import org.bitcoins.testkit.fixtures.NodeDAOFixture
import scodec.bits.ByteVector
import java.time.Instant
class PeerDAOTest extends NodeDAOFixture {
behavior of "PeerDAO"
it must "write peer bytes and read it back" in { daos =>
val peerDAO = daos.peerDAO
val bytes = ByteVector(Array[Byte](127, 0, 0, 1))
val peer = PeerDb(address = bytes,
port = 8333,
lastSeen = Instant.now,
firstSeen = Instant.now,
networkId = AddrV2Message.IPV4_NETWORK_BYTE)
for {
created <- peerDAO.create(peer)
read <- peerDAO.read(peer.address)
} yield {
assert(
read.get.address == created.address &&
read.get.port == created.port &&
read.get.lastSeen.getEpochSecond == created.lastSeen.getEpochSecond
&& read.get.firstSeen.getEpochSecond == created.firstSeen.getEpochSecond
&& read.get.networkId == AddrV2Message.IPV4_NETWORK_BYTE
)
}
}
}

View file

@ -0,0 +1 @@
create table if not exists "peers" ("address" VARCHAR NOT NULL PRIMARY KEY UNIQUE,"port" INT NOT NULL,"last_seen" TIMESTAMP,"first_seen" TIMESTAMP, "network_id" INT)

View file

@ -0,0 +1 @@
create table if not exists "peers" ("address" VARCHAR NOT NULL PRIMARY KEY UNIQUE, "port" INT NOT NULL, "last_seen" TIMESTAMP,"first_seen" TIMESTAMP, "network_id" INT)

View file

@ -0,0 +1,88 @@
package org.bitcoins.node.models
import org.bitcoins.db.{CRUD, SlickUtil}
import org.bitcoins.node.config.NodeAppConfig
import scodec.bits.ByteVector
import slick.lifted.ProvenShape
import java.time.Instant
import scala.concurrent.{ExecutionContext, Future}
case class PeerDb(
address: ByteVector,
port: Int,
lastSeen: Instant,
firstSeen: Instant,
networkId: Byte
)
case class PeerDAO()(implicit ec: ExecutionContext, appConfig: NodeAppConfig)
extends CRUD[PeerDb, ByteVector]
with SlickUtil[PeerDb, ByteVector] {
import profile.api._
val mappers = new org.bitcoins.db.DbCommonsColumnMappers(profile)
import mappers._
override val table: TableQuery[PeerTable] =
TableQuery[PeerTable]
override def createAll(ts: Vector[PeerDb]): Future[Vector[PeerDb]] =
createAllNoAutoInc(ts, safeDatabase)
override protected def findByPrimaryKeys(
ids: Vector[ByteVector]): Query[PeerTable, PeerDb, Seq] = {
table.filter(_.address.inSet(ids))
}
override protected def findAll(
ts: Vector[PeerDb]): Query[Table[_], PeerDb, Seq] = findByPrimaryKeys(
ts.map(_.address))
def deleteByKey(address: String): Future[Int] = {
val bytes = ByteVector(address.getBytes)
val q = table.filter(_.address === bytes)
safeDatabase.run(q.delete)
}
def upsertPeer(
address: ByteVector,
port: Int,
networkId: Byte): Future[PeerDb] = {
val lastSeen: Instant = Instant.now
val existingF = read(address)
existingF.flatMap {
case Some(value) =>
upsert(
PeerDb(address,
port,
firstSeen = value.firstSeen,
lastSeen = lastSeen,
networkId = networkId))
case None =>
upsert(
PeerDb(address,
port,
firstSeen = Instant.now,
lastSeen = lastSeen,
networkId = networkId))
}
}
class PeerTable(tag: Tag) extends Table[PeerDb](tag, schemaName, "peers") {
def address: Rep[ByteVector] = column("address", O.PrimaryKey)
def port: Rep[Int] = column("port")
def lastSeen: Rep[Instant] = column("last_seen")
def firstSeen: Rep[Instant] = column("first_seen")
def networkId: Rep[Byte] = column("network_id")
def * : ProvenShape[PeerDb] =
(address, port, lastSeen, firstSeen, networkId).<>(PeerDb.tupled,
PeerDb.unapply)
}
}

View file

@ -2,7 +2,7 @@ package org.bitcoins.testkit.fixtures
import org.bitcoins.chain.config.ChainAppConfig
import org.bitcoins.node.config.NodeAppConfig
import org.bitcoins.node.models.BroadcastAbleTransactionDAO
import org.bitcoins.node.models.{BroadcastAbleTransactionDAO, PeerDAO}
import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.node.{CachedBitcoinSAppConfig, NodeUnitTest}
@ -10,7 +10,7 @@ import org.scalatest._
import scala.concurrent.Future
case class NodeDAOs(txDAO: BroadcastAbleTransactionDAO)
case class NodeDAOs(txDAO: BroadcastAbleTransactionDAO, peerDAO: PeerDAO)
/** Provides a fixture where all DAOs used by the node projects are provided */
trait NodeDAOFixture extends NodeUnitTest with CachedBitcoinSAppConfig {
@ -21,7 +21,8 @@ trait NodeDAOFixture extends NodeUnitTest with CachedBitcoinSAppConfig {
private lazy val daos = {
val tx = BroadcastAbleTransactionDAO()
NodeDAOs(tx)
val peerDao = PeerDAO()
NodeDAOs(tx, peerDao)
}
final override type FixtureParam = NodeDAOs