diff --git a/be2-scala/build.sbt b/be2-scala/build.sbt index 617a323b1b..767b16c0e7 100644 --- a/be2-scala/build.sbt +++ b/be2-scala/build.sbt @@ -3,7 +3,7 @@ import sbtsonar.SonarPlugin.autoImport.sonarProperties name := "pop" -scalaVersion := "3.1.2" +scalaVersion := "3.2.0-RC1" // Recommended 2.13 Scala flags (https://nathankleyn.com/2019/05/13/recommended-scalac-flags-for-2-13) slightly adapted for PoP scalacOptions ++= Seq( diff --git a/be2-scala/src/main/scala/ch/epfl/pop/Server.scala b/be2-scala/src/main/scala/ch/epfl/pop/Server.scala index 677b02e93d..04921213b0 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/Server.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/Server.scala @@ -55,7 +55,7 @@ object Server { val bindingFuture = Http().newServerAt(config.interface, config.port).bindFlow(publishSubscribeRoute) bindingFuture.onComplete { - case Success(_) => println(f"ch.epfl.pop.Server online at ws://${config.interface}:${config.port}/${config.path}") + case Success(_) => println(s"ch.epfl.pop.Server online at ws://${config.interface}:${config.port}/${config.path}") case Failure(_) => logger.error( "ch.epfl.pop.Server failed to start. Terminating actor system" diff --git a/be2-scala/src/main/scala/ch/epfl/pop/model/objects/ElectionChannel.scala b/be2-scala/src/main/scala/ch/epfl/pop/model/objects/ElectionChannel.scala index ce5c4cbc56..bab7090d41 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/model/objects/ElectionChannel.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/model/objects/ElectionChannel.scala @@ -22,7 +22,7 @@ object ElectionChannel { */ def extractMessages[T: reflect.ClassTag](dbActor: AskableActorRef = DbActor.getInstance): Future[List[(Message, T)]] = { for { - DbActor.DbActorCatchupAck(messages) <- dbActor ? DbActor.Catchup(channel) + case DbActor.DbActorCatchupAck(messages) <- dbActor ? DbActor.Catchup(channel) result <- Future.traverse(messages.flatMap(message => message.decodedData match { case Some(t: T) => Some((message, t)) diff --git a/be2-scala/src/main/scala/ch/epfl/pop/model/objects/Transaction.scala b/be2-scala/src/main/scala/ch/epfl/pop/model/objects/Transaction.scala index c8c81e1145..1f0d7e76f2 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/model/objects/Transaction.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/model/objects/Transaction.scala @@ -41,8 +41,8 @@ final case class Transaction( } private def signaturePayload = - Base64Data.encode(inputs.map { txin => f"${txin.txOutHash}${txin.txOutIndex}" }.reduce(_+_) + - outputs.map { txout => f"${txout.value}${txout.script.`type`}${txout.script.pubkeyHash.base64Data}" }.reduce(_+_)) + Base64Data.encode(inputs.map { txin => s"${txin.txOutHash}${txin.txOutIndex}" }.reduce(_+_) + + outputs.map { txout => s"${txout.value}${txout.script.`type`}${txout.script.pubkeyHash.base64Data}" }.reduce(_+_)) /** * This ensures the validity of the signatures, not that the funds are unspent. diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ElectionHandler.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ElectionHandler.scala index b3adf5f9bc..eded8fce5c 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ElectionHandler.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/ElectionHandler.scala @@ -131,7 +131,7 @@ class ElectionHandler(dbRef: => AskableActorRef) extends MessageHandler { castsVotesElections <- electionChannel.getLastVotes(dbActor) setupMessage <- electionChannel.getSetupMessage(dbActor) questionToBallots = setupMessage.questions.map(question => question.id -> question.ballot_options).toMap - DbActorReadElectionDataAck(electionData) <- dbActor ? DbActor.ReadElectionData(setupMessage.id) + case DbActorReadElectionDataAck(electionData) <- dbActor ? DbActor.ReadElectionData(setupMessage.id) } yield { val resultsTable = mutable.HashMap.from(for { (question, ballots) <- questionToBallots diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/LaoHandler.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/LaoHandler.scala index 96971700f2..b5caa41197 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/LaoHandler.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/LaoHandler.scala @@ -31,7 +31,7 @@ case object LaoHandler extends MessageHandler { val reactionChannel: Channel = Channel(s"$laoChannel${Channel.REACTIONS_CHANNEL_PREFIX}") //we get access to the canonical address of the server val config = ServerConf(appConf) - val address: Option[String] = Some(f"ws://${config.interface}:${config.port}/${config.path}") + val address: Option[String] = Some(s"ws://${config.interface}:${config.port}/${config.path}") val combined = for { // check whether the lao already exists in db diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/MessageHandler.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/MessageHandler.scala index da4e2c8303..13b18d2fe2 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/MessageHandler.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/MessageHandler.scala @@ -27,16 +27,17 @@ trait MessageHandler extends AskPatternConstants { * @return the database answer wrapped in a [[scala.concurrent.Future]] */ def dbAskWrite(rpcRequest: JsonRpcRequest): Future[GraphMessage] = { - val m: Message = rpcRequest.getParamsMessage.getOrElse( - return Future { + rpcRequest.getParamsMessage match { + case None => + Future { Right(PipelineError(ErrorCodes.SERVER_ERROR.id, s"dbAskWrite failed : retrieve empty rpcRequest message", rpcRequest.id)) } - ) - - val askWrite = dbActor ? DbActor.Write(rpcRequest.getParamsChannel, m) - askWrite.transformWith { - case Success(_) => Future(Left(rpcRequest)) - case _ => Future(Right(PipelineError(ErrorCodes.SERVER_ERROR.id, s"dbAskWrite failed : could not write message $m", rpcRequest.id))) + case Some(m) => + val askWrite = dbActor ? DbActor.Write(rpcRequest.getParamsChannel, m) + askWrite.transformWith { + case Success(_) => Future(Left(rpcRequest)) + case _ => Future(Right(PipelineError(ErrorCodes.SERVER_ERROR.id, s"dbAskWrite failed : could not write message $m", rpcRequest.id))) + } } } @@ -48,16 +49,17 @@ trait MessageHandler extends AskPatternConstants { * @return the database answer wrapped in a [[scala.concurrent.Future]] */ def dbAskWritePropagate(rpcRequest: JsonRpcRequest): Future[GraphMessage] = { - val m: Message = rpcRequest.getParamsMessage.getOrElse( - return Future { + rpcRequest.getParamsMessage match { + case None => + Future { Right(PipelineError(ErrorCodes.SERVER_ERROR.id, s"dbAskWritePropagate failed : retrieve empty rpcRequest message", rpcRequest.id)) } - ) - - val askWritePropagate = dbActor ? DbActor.WriteAndPropagate(rpcRequest.getParamsChannel, m) - askWritePropagate.transformWith { - case Success(_) => Future(Left(rpcRequest)) - case _ => Future(Right(PipelineError(ErrorCodes.SERVER_ERROR.id, s"dbAskWritePropagate failed : could not write & propagate message $m", rpcRequest.id))) + case Some(m) => + val askWritePropagate = dbActor ? DbActor.WriteAndPropagate(rpcRequest.getParamsChannel, m) + askWritePropagate.transformWith { + case Success(_) => Future(Left(rpcRequest)) + case _ => Future(Right(PipelineError(ErrorCodes.SERVER_ERROR.id, s"dbAskWritePropagate failed : could not write & propagate message $m", rpcRequest.id))) + } } } @@ -71,23 +73,24 @@ trait MessageHandler extends AskPatternConstants { * @return the database answer wrapped in a [[scala.concurrent.Future]] */ def dbBroadcast(rpcMessage: JsonRpcRequest, channel: Channel, broadcastData: Base64Data, broadcastChannel: Channel): Future[GraphMessage] = { - val m: Message = rpcMessage.getParamsMessage.getOrElse( - return Future { + rpcMessage.getParamsMessage match { + case None => + Future { Right(PipelineError(ErrorCodes.SERVER_ERROR.id, s"dbAskWritePropagate failed : retrieve empty rpcRequest message", rpcMessage.id)) } - ) - - val combined = for { - DbActorReadLaoDataAck(laoData) <- dbActor ? DbActor.ReadLaoData(channel) - broadcastSignature: Signature = laoData.privateKey.signData(broadcastData) - broadcastId: Hash = Hash.fromStrings(broadcastData.toString, broadcastSignature.toString) - broadcastMessage: Message = Message(broadcastData, laoData.publicKey, broadcastSignature, broadcastId, List.empty) - _ <- dbActor ? DbActor.WriteAndPropagate(broadcastChannel, broadcastMessage) - } yield () + case Some(m) => + val combined = for { + case DbActorReadLaoDataAck(laoData) <- dbActor ? DbActor.ReadLaoData(channel) + broadcastSignature: Signature = laoData.privateKey.signData(broadcastData) + broadcastId: Hash = Hash.fromStrings(broadcastData.toString, broadcastSignature.toString) + broadcastMessage: Message = Message(broadcastData, laoData.publicKey, broadcastSignature, broadcastId, List.empty) + _ <- dbActor ? DbActor.WriteAndPropagate(broadcastChannel, broadcastMessage) + } yield () - combined.transformWith { - case Success(_) => Future(Left(rpcMessage)) - case _ => Future(Right(PipelineError(ErrorCodes.SERVER_ERROR.id, s"dbBroadcast failed : could not read and broadcast message $m", rpcMessage.id))) + combined.transformWith { + case Success(_) => Future(Left(rpcMessage)) + case _ => Future(Right(PipelineError(ErrorCodes.SERVER_ERROR.id, s"dbBroadcast failed : could not read and broadcast message $m", rpcMessage.id))) + } } } } diff --git a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/WitnessHandler.scala b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/WitnessHandler.scala index 0140f52436..be56396010 100644 --- a/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/WitnessHandler.scala +++ b/be2-scala/src/main/scala/ch/epfl/pop/pubsub/graph/handlers/WitnessHandler.scala @@ -39,7 +39,7 @@ class WitnessHandler(dbRef: => AskableActorRef) extends MessageHandler { case Some(_) => val combined = for { // add new witness signature to existing ones - DbActorAddWitnessSignatureAck(witnessMessage) <- dbActor ? DbActor.AddWitnessSignature(channel, messageId, signature) + case DbActorAddWitnessSignatureAck(witnessMessage) <- dbActor ? DbActor.AddWitnessSignature(channel, messageId, signature) //overwrites the message containing now the witness signature in the db _ <- dbActor ? DbActor.WriteAndPropagate(channel, witnessMessage) } yield () diff --git a/be2-scala/src/test/scala/ch/epfl/pop/model/objects/PublicKeySuite.scala b/be2-scala/src/test/scala/ch/epfl/pop/model/objects/PublicKeySuite.scala index 9d82e602d1..4558b8ba52 100644 --- a/be2-scala/src/test/scala/ch/epfl/pop/model/objects/PublicKeySuite.scala +++ b/be2-scala/src/test/scala/ch/epfl/pop/model/objects/PublicKeySuite.scala @@ -15,7 +15,7 @@ class PublicKeySuite extends AnyFunSuite with should.Matchers { test("pubkey hash matches example data") { for (suffix <- Seq("", "2")) { - val Seq(JsString(pubkeyData), JsString(pubkeyHash)) = data.asJsObject.getFields(s"publicKey$suffix", s"publicKeyHash$suffix") + val Seq(JsString(pubkeyData), JsString(pubkeyHash)) = data.asJsObject.getFields(s"publicKey$suffix", s"publicKeyHash$suffix"): @unchecked val pubkey = PublicKey(Base64Data(pubkeyData)) pubkey.hash.base64Data should equal(Base64Data(pubkeyHash)) } diff --git a/be2-scala/src/test/scala/util/examples/data/TestKeyPairs.scala b/be2-scala/src/test/scala/util/examples/data/TestKeyPairs.scala index d86897528e..383b8251a9 100644 --- a/be2-scala/src/test/scala/util/examples/data/TestKeyPairs.scala +++ b/be2-scala/src/test/scala/util/examples/data/TestKeyPairs.scala @@ -16,7 +16,7 @@ object TestKeyPairs { val keypairs: Vector[KeyPairWithHash] = for (suffix <- Vector("", "2")) yield { val Seq(JsString(privkeyData), JsString(pubkeyData), JsString(pubkeyHash)) = - raw.getFields(s"privateKey$suffix", s"publicKey$suffix", s"publicKeyHash$suffix") + raw.getFields(s"privateKey$suffix", s"publicKey$suffix", s"publicKeyHash$suffix"): @unchecked val fixedPrivkeyData = Base64Data(privkeyData).decode().take(32) KeyPairWithHash(KeyPair(PrivateKey(Base64Data.encode(fixedPrivkeyData)), PublicKey(Base64Data(pubkeyData))), Base64Data(pubkeyHash)) }