Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scala3 support #108

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
scala: [2.13.8, 2.12.15, 2.11.12]
scala: [3.3.1, 2.13.12, 2.12.18, 2.11.12]
java: [[email protected]]
runs-on: ${{ matrix.os }}
steps:
Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
scala: [2.13.8, 2.12.15]
scala: [3.3.1, 2.13.12]
java: [[email protected]]
node-version: [16.x]
runs-on: ${{ matrix.os }}
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@ target
# logs
scorex-errors.log
*.log

# js
node_modules
.bsp
.DS_Store
yarn.lock
package-lock.json
65 changes: 39 additions & 26 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ name := "scrypto"
description := "Cryptographic primitives for Scala"
organization := "org.scorexfoundation"

lazy val scala213 = "2.13.8"
lazy val scala212 = "2.12.15"
lazy val scala213 = "2.13.12"
lazy val scala212 = "2.12.18"
lazy val scala211 = "2.11.12"
lazy val scala3 = "3.3.1"
ccellado marked this conversation as resolved.
Show resolved Hide resolved

javacOptions ++=
"-source" :: "1.8" ::
Expand All @@ -15,32 +16,44 @@ javacOptions ++=

lazy val commonSettings = Seq(
organization := "org.scorexfoundation",
resolvers += Resolver.sonatypeRepo("public"),
resolvers ++= Resolver.sonatypeOssRepos("snapshots"),
licenses := Seq("CC0" -> url("https://creativecommons.org/publicdomain/zero/1.0/legalcode")),
homepage := Some(url("https://github.com/input-output-hk/scrypto")),
pomExtra :=
<developers>
<developer>
<id>kushti</id>
<name>Alexander Chepurnoy</name>
<url>http://chepurnoy.org/</url>
</developer>
</developers>,
<developers>
<developer>
<id>kushti</id>
<name>Alexander Chepurnoy</name>
<url>http://chepurnoy.org/</url>
</developer>
</developers>,
scmInfo := Some(
ScmInfo(
url("https://github.com/input-output-hk/scrypto"),
"scm:[email protected]:input-output-hk/scrypto.git"
)
),
libraryDependencies ++= Seq(
"org.rudogma" %%% "supertagged" % "2.0-RC2",
"org.scorexfoundation" %%% "scorex-util" % "0.2.0",
"org.scalatest" %%% "scalatest" % "3.3.0-SNAP3" % Test,
"org.scalatest" %%% "scalatest-propspec" % "3.3.0-SNAP3" % Test,
"org.scalatest" %%% "scalatest-shouldmatchers" % "3.3.0-SNAP3" % Test,
"org.scalatestplus" %%% "scalacheck-1-15" % "3.3.0.0-SNAP3" % Test,
"org.scalacheck" %%% "scalacheck" % "1.15.2" % Test
ScmInfo(
url("https://github.com/input-output-hk/scrypto"),
"scm:[email protected]:input-output-hk/scrypto.git"
)
),
libraryDependencies ++= {
if (scalaVersion.value == scala3)
Seq(
("org.scorexfoundation" %%% "scorex-util" % "0.2.1").cross(CrossVersion.for3Use2_13),
"org.scalatest" %%% "scalatest" % "3.3.0-alpha.1" % Test,
"org.scalatest" %%% "scalatest-propspec" % "3.3.0-alpha.1" % Test,
"org.scalatest" %%% "scalatest-shouldmatchers" % "3.3.0-alpha.1" % Test,
"org.scalacheck" %%% "scalacheck" % "1.15.3" % Test,
"org.scalatestplus" %%% "scalacheck-1-17" % "3.3.0.0-alpha.1" % Test
)
else // use last versions with Scala 2.11 support
Seq(
"org.rudogma" %%% "supertagged" % "2.0-RC2",
"org.scorexfoundation" %%% "scorex-util" % "0.2.1",
"org.scalatest" %%% "scalatest" % "3.3.0-SNAP3" % Test,
"org.scalatest" %%% "scalatest-propspec" % "3.3.0-SNAP3" % Test,
"org.scalatest" %%% "scalatest-shouldmatchers" % "3.3.0-SNAP3" % Test,
"org.scalacheck" %%% "scalacheck" % "1.15.2" % Test,
"org.scalatestplus" %%% "scalacheck-1-15" % "3.3.0.0-SNAP3" % Test
)
},
javacOptions ++= javacReleaseOption,
publishMavenStyle := true,
publishTo := sonatypePublishToBundle.value
Expand All @@ -66,15 +79,15 @@ lazy val scrypto = crossProject(JVMPlatform, JSPlatform)
"org.bouncycastle" % "bcprov-jdk15to18" % "1.66"
),
scalaVersion := scala213,
crossScalaVersions := Seq(scala211, scala212, scala213)
crossScalaVersions := Seq(scala211, scala212, scala213, scala3)
)

lazy val scryptoJS = scrypto.js
.enablePlugins(ScalaJSBundlerPlugin)
.enablePlugins(ScalablyTypedConverterExternalNpmPlugin)
.settings(
scalaVersion := scala213,
crossScalaVersions := Seq(scala212, scala213),
crossScalaVersions := Seq(scala212, scala213, scala3),
libraryDependencies ++= Seq(
"org.scala-js" %%% "scala-js-macrotask-executor" % "1.0.0",
("org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13)
Expand All @@ -93,7 +106,7 @@ lazy val benchmarks = project
.dependsOn(scrypto.jvm)
.settings(
moduleName := "scrypto-benchmarks",
crossScalaVersions := Seq(scala211, scala212, scala213),
crossScalaVersions := Seq(scala211, scala212, scala213, scala3),
scalaVersion := scala213,
)
.enablePlugins(JmhPlugin)
Expand Down
2 changes: 1 addition & 1 deletion js/src/main/scala/scorex/crypto/hash/Platform.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package scorex.crypto.hash

import typings.nobleHashes.blake2Mod.BlakeOpts
import typings.nobleHashes.mod.blake2b
import typings.nobleHashes.blake2bMod.blake2b
import typings.nobleHashes.sha256Mod.sha256
import typings.nobleHashes.utilsMod

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import scala.util.{Random, Try, Success, Failure}
class AVLBatchStatefulSpecification extends AnyPropSpec {

property("BatchAVLProver: prove and verify") {
AVLCommands.property().check
AVLCommands.property().check()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ with Matchers {
val unsafeHash = new Blake2b256Unsafe

property("Unsafe should produce the same result") {
forAll { message: Array[Byte] =>
forAll { (message: Array[Byte]) =>
unsafeHash.hash(message) shouldEqual Blake2b256(message)
}
}
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
sbt.version=1.5.4
sbt.version=1.9.1

4 changes: 2 additions & 2 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ logLevel := Level.Warn

addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0")

addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0")
//addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0")

//addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.3.5")

Expand All @@ -18,4 +18,4 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1")
addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.20.0")
addSbtPlugin("org.scalablytyped.converter" % "sbt-converter" % "1.0.0-beta37")
addSbtPlugin("org.scalablytyped.converter" % "sbt-converter" % "1.0.0-beta43")
29 changes: 29 additions & 0 deletions shared/src/main/scala-3/scorex/crypto/authds/authds.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package scorex.crypto

import scorex.crypto.utils.{NewByte, NewArrayByte}

package object authds:
object LeafData extends NewArrayByte
type LeafData = LeafData.Type

object Side extends NewByte
type Side = Side.Type

object ADKey extends NewArrayByte
type ADKey = ADKey.Type

object ADValue extends NewArrayByte
type ADValue = ADValue.Type

object ADDigest extends NewArrayByte
type ADDigest = ADDigest.Type

object SerializedAdProof extends NewArrayByte
type SerializedAdProof = SerializedAdProof.Type

object Balance extends NewByte
type Balance = Balance.Type

/** Immutable empty array which can be used in many places to avoid allocations. */
val EmptyByteArray = Array.empty[Byte]
end authds
30 changes: 30 additions & 0 deletions shared/src/main/scala-3/scorex/crypto/hash/hash.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package scorex.crypto

import scorex.crypto.utils.NewArrayByte
import scorex.crypto.utils.NewDigest

package object hash {

trait BaseDigest extends NewDigest
type Digest = BaseDigest#Type
object Digest32 extends BaseDigest
object Digest64 extends BaseDigest

type Digest32 = Digest32.Type
type Digest64 = Digest64.Type

object NonStandardDigest extends NewDigest
type NonStandardDigest = NonStandardDigest.Type

type ExtendedDigest = Platform.Digest

def createBlake2bDigest(bitSize: Int): ExtendedDigest = Platform.createBlake2bDigest(bitSize)

def createSha256Digest(): ExtendedDigest = Platform.createSha256Digest()

def updateDigest(digest: ExtendedDigest, b: Byte) = Platform.updateDigest(digest, b)

def updateDigest(digest: ExtendedDigest, in: Array[Byte], inOff: Int, inLen: Int) = Platform.updateDigest(digest, in, inOff, inLen)

def doFinalDigest(digest: ExtendedDigest): Array[Byte] = Platform.doFinalDigest(digest)
}
21 changes: 21 additions & 0 deletions shared/src/main/scala-3/scorex/crypto/utils/utils.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package scorex.crypto

object utils:

trait NewDigest:
opaque type Type <: Array[Byte] = Array[Byte] with this.type
inline def @@(a: Array[Byte]): this.Type = a.asInstanceOf[this.Type]
inline def @@@[B <: Array[Byte]](b: B): this.Type = b.asInstanceOf[this.Type]
end NewDigest

trait NewArrayByte:
opaque type Type <: Array[Byte] = Array[Byte]
inline def @@(a: Array[Byte]): this.Type = a
inline def @@@[B <: Array[Byte]](b: B): this.Type = b
end NewArrayByte

trait NewByte:
opaque type Type <: Byte = Byte
inline def @@(a: Byte): this.Type = a
inline def @@@[B <: Byte](b: B): this.Type = b
end NewByte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package scorex.crypto.authds.avltree.batch

import scorex.crypto.authds.{ADKey, ADValue, Balance}
import scorex.crypto.authds._
import scorex.crypto.hash._

sealed trait Node[D <: Digest] extends ToStringHelper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ object PersistentBatchAVLProver {
): Try[PersistentBatchAVLProver[D, HF]] = Try {

new PersistentBatchAVLProver[D, HF] {
override var avlProver: BatchAVLProver[D, HF] = avlBatchProver
var avlProver: BatchAVLProver[D, HF] = avlBatchProver
ccellado marked this conversation as resolved.
Show resolved Hide resolved
override val storage: VersionedAVLStorage[D] = versionedStorage

(storage.version match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ case class AVLModifyProof(key: ADKey, proofSeq: Seq[AVLProofElement])

val pathLength = if (keyFound) proofSeq.length - 3 else proofSeq.length - 4
val inBytes = pathLength.toByte +: key
val pathProofsBytes: Array[Byte] = (0 until pathLength / 3).toArray.flatMap { i: Int =>
val pathProofsBytes: Array[Byte] = (0 until pathLength / 3).toArray.flatMap { (i: Int) =>
val label = proofSeq(3 * i + 1)
val directionLabelByte = AVLModifyProof.directionBalanceByte(proofSeq(3 * i).asInstanceOf[ProofDirection],
proofSeq(3 * i + 2).asInstanceOf[ProofBalance])
Expand All @@ -251,7 +251,7 @@ object AVLModifyProof {
val pathLength: Int = bytes.head.ensuring(_ % 3 == 0)

val key = ADKey @@ bytes.slice(1, 1 + keyLength)
val pathProofs: Seq[AVLProofElement] = (0 until pathLength / 3) flatMap { i: Int =>
val pathProofs: Seq[AVLProofElement] = (0 until pathLength / 3) flatMap { (i: Int) =>
val start = 1 + keyLength + i * (1 + 32)
val (direction, balance) = parseDirectionBalance(bytes.slice(start, start + 1).head)
val labelBytes = bytes.slice(start + 1, start + 1 + digestSize)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class AVLTree[HF <: CryptographicHash[_ <: Digest]](keyLength: Int,
val proofStream = new scala.collection.mutable.Queue[AVLProofElement]

val updateFn: Option[ADValue] => Try[Option[ADValue]] = operation match {
case _: Lookup => x: Option[ADValue] => Success(x)
case _: Lookup => (x: Option[ADValue]) => Success(x)

case m: Modification => m.updateFn
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ sealed trait Node extends ToStringHelper {

trait InternalNode {
val hf: CryptographicHash[_ <: Digest]
val level: Level
def level: Level

def leftLabel: Digest

Expand All @@ -44,7 +44,7 @@ case class ProverNode(key: ADKey, private var _left: ProverNodes, private var _r
(implicit val hf: CryptographicHash[_ <: Digest], levelFunc: LevelFunction)
extends ProverNodes with InternalNode {

lazy val level: Level = levelFunc(key)
def level: Level = levelFunc(key)

def left: ProverNodes = _left

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Treap[HF <: CryptographicHash[_ <: Digest]](rootOpt: Option[Leaf] = None)

//todo: unify types AVLValue/TreapValue and then generalize 4 LoCs below which are the same for Treap & AVLTree
val updateFn: Option[ADValue] => Try[Option[ADValue]] = operation match {
case _: Lookup => x: Option[ADValue] => Success(x)
case _: Lookup => (x: Option[ADValue]) => Success(x)
case m: Modification => m.updateFn
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ case class MerkleTree[D <: Digest](topNode: Node[D],
val dif = b_flat diff a
var m = dif.map(i => {
val side = if (i % 2 == 0) MerkleProof.LeftSide else MerkleProof.RightSide
(l.lift(i).getOrElse(EmptyNode[D].hash), side)
(l.lift(i).getOrElse(EmptyNode[D]().hash), side)
})

// Take all the even numbers from B_pruned, and divide them by two
Expand All @@ -85,7 +85,7 @@ case class MerkleTree[D <: Digest](topNode: Node[D],
// Go up one layer in the tree
val l_new = l.grouped(2).map(lr => {
hf.prefixedHash(InternalNodePrefix,
lr.head, if (lr.lengthCompare(2) == 0) lr.last else EmptyNode[D].hash)
lr.head, if (lr.lengthCompare(2) == 0) lr.last else EmptyNode[D]().hash)
}).toSeq

// Repeat until the root of the tree is reached
Expand Down Expand Up @@ -156,10 +156,10 @@ object MerkleTree {
@tailrec
def calcTopNode[D <: Digest](nodes: Seq[Node[D]])(implicit hf: CryptographicHash[D]): Node[D] = {
if (nodes.isEmpty) {
EmptyRootNode[D]
EmptyRootNode[D]()
} else {
val nextNodes = nodes.grouped(2)
.map(lr => InternalNode[D](lr.head, if (lr.lengthCompare(2) == 0) lr.last else EmptyNode[D])).toSeq
.map(lr => InternalNode[D](lr.head, if (lr.lengthCompare(2) == 0) lr.last else EmptyNode[D]())).toSeq
if (nextNodes.lengthCompare(1) == 0) nextNodes.head else calcTopNode(nextNodes)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ trait TwoPartyTests extends TestingCommons {

case class Append(key: ADKey, value: ADValue) extends Modification {
override def updateFn: UpdateFunction = {
oldOpt: Option[ADValue] => Success(Some(ADValue @@ oldOpt.map(_ ++ value).getOrElse(value)))
(oldOpt: Option[ADValue]) => Success(Some(ADValue @@ oldOpt.map(_ ++ value).getOrElse(value)))
}: UpdateFunction
}

case class TransactionUpdate(key: ADKey, amount: Long) extends Modification {
override def updateFn: UpdateFunction = {
oldOpt: Option[ADValue] =>
(oldOpt: Option[ADValue]) =>
Success(Some(ADValue @@ Longs.toByteArray(oldOpt.map(v => Longs.fromByteArray(v) + amount).getOrElse(amount))))
}: UpdateFunction
}
Expand Down
Loading
Loading