Skip to content

Commit

Permalink
Merge pull request #706 from ScorexFoundation/develop
Browse files Browse the repository at this point in the history
Release v3.3.3
  • Loading branch information
aslesarenko authored Nov 30, 2020
2 parents 5f6770a + e16203d commit a116e37
Show file tree
Hide file tree
Showing 55 changed files with 2,046 additions and 833 deletions.
27 changes: 19 additions & 8 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ version in ThisBuild := {
git.gitUncommittedChanges in ThisBuild := true

val bouncycastleBcprov = "org.bouncycastle" % "bcprov-jdk15on" % "1.64"
val scrypto = "org.scorexfoundation" %% "scrypto" % "2.1.9"
val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.6"
val scrypto = "org.scorexfoundation" %% "scrypto" % "2.1.10"
val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.8"
val macroCompat = "org.typelevel" %% "macro-compat" % "1.1.1"
val paradise = "org.scalamacros" %% "paradise" % "2.1.0" cross CrossVersion.full
val debox = "org.spire-math" %% "debox" % "0.8.0"
Expand Down Expand Up @@ -118,12 +118,19 @@ libraryDependencies ++= Seq(
kiama, fastparse, debox
) ++ testingDependencies

val circeVersion = "0.10.0"
val circeCore = "io.circe" %% "circe-core" % circeVersion
val circeGeneric = "io.circe" %% "circe-generic" % circeVersion
val circeParser = "io.circe" %% "circe-parser" % circeVersion
lazy val circeCore211 = "io.circe" %% "circe-core" % "0.10.0"
lazy val circeGeneric211 = "io.circe" %% "circe-generic" % "0.10.0"
lazy val circeParser211 = "io.circe" %% "circe-parser" % "0.10.0"

libraryDependencies ++= Seq( circeCore, circeGeneric, circeParser )
lazy val circeCore = "io.circe" %% "circe-core" % "0.13.0"
lazy val circeGeneric = "io.circe" %% "circe-generic" % "0.13.0"
lazy val circeParser = "io.circe" %% "circe-parser" % "0.13.0"

libraryDependencies ++= Seq(
if (scalaVersion.value == scala211) circeCore211 else circeCore,
if (scalaVersion.value == scala211) circeGeneric211 else circeGeneric,
if (scalaVersion.value == scala211) circeParser211 else circeParser
)

scalacOptions ++= Seq("-feature", "-deprecation")

Expand Down Expand Up @@ -274,7 +281,11 @@ lazy val sigmastate = (project in file("sigmastate"))
.dependsOn(sigmaimpl % allConfigDependency, sigmalibrary % allConfigDependency)
.settings(libraryDefSettings)
.settings(libraryDependencies ++= Seq(
scorexUtil, kiama, fastparse, circeCore, circeGeneric, circeParser))
scorexUtil, kiama, fastparse,
if (scalaVersion.value == scala211) circeCore211 else circeCore,
if (scalaVersion.value == scala211) circeGeneric211 else circeGeneric,
if (scalaVersion.value == scala211) circeParser211 else circeParser
))
.settings(publish / skip := true)

lazy val sigma = (project in file("."))
Expand Down
2 changes: 2 additions & 0 deletions common/src/main/scala/scalan/util/Extensions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ object Extensions {
res
}
def getBytes(size: Int): Array[Byte] = {
if (size > buf.remaining)
throw new IllegalArgumentException(s"Not enough bytes in the ByteBuffer: $size")
val res = new Array[Byte](size)
buf.get(res)
res
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class CollOverArrayBuilder extends CollBuilder {
override def Monoids: MonoidBuilder = new MonoidBuilderInst

@inline override def pairColl[@specialized A, @specialized B](as: Coll[A], bs: Coll[B]): PairColl[A, B] = {
// TODO HF: use minimal length and slice longer collection
// TODO HF (2h): use minimal length and slice longer collection
// The current implementation doesn't check the case when `as` and `bs` have different lengths.
// in which case the implementation of `PairOfCols` has inconsistent semantics of `map`, `exists` etc methods.
// To fix the problem, the longer collection have to be truncated (which is consistent
Expand Down
16 changes: 16 additions & 0 deletions library/src/test/scala/special/collections/BasicBenchmarks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ import org.scalameter.api._
import spire.syntax.all.cfor

trait BasicBenchmarkCases extends BenchmarkGens { suite: Bench[Double] =>

performance of "allocation" in {
measure method "new" in {
using(sizes) in { case n =>
val arr = new Array[Integer](n)
cfor(0)(_ < n, _ + 1) { i =>
arr(i) = Integer.valueOf(i)
}
var s = 0
cfor(0)(_ < n, _ + 1) { i =>
s += arr(i).intValue()
}
}
}
}

performance of "Seq" in {
var res: Seq[Int] = null
measure method "Nil" in {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.scalameter.KeyValue
import org.scalameter.api.{Gen, Bench, _}

trait BenchmarkGens extends CollGens { suite: Bench[Double] =>
val maxSize = 100000
def maxSize = 100000

val sizes = Gen.exponential("size")(10, maxSize, 10)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class TestSigmaDslBuilder extends SigmaDslBuilder {

@NeverInline
override def xorOf(conditions: Coll[Boolean]): Boolean = {
// TODO HF: see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/640
// TODO HF (2h): see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/640
conditions.toArray.distinct.length == 2
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ class ErgoLikeInterpreter(implicit val IR: IRContext) extends Interpreter {
else
Some(outVal)
case _ =>
// TODO HF: this case is not possible because `ErgoBox.get`
// TODO HF (1h): this case is not possible because `ErgoBox.get`
// returns lookups values from `additionalRegisters` Map with values
// of type EvaluatedValue, which are always Constant nodes in practice.
// Also, this branch is never executed so can be safely removed
// (better as part of as part of HF)
// (better as part of the HF)
None
}
}.orElse(d.default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,18 @@ object ValidationRules {
map
})

/** Executes the given `block` catching [[ValidationException]] and checking possible
* soft-fork condition in the context of the given [[SigmaValidationSettings]].
* If soft-fork condition is recognized the `whenSoftFork` is executed and its result
* is returned.
*
* @param whenSoftFork executed when soft-fork condition is detected
* @param block block of code, which may throw [[ValidationException]]
* @param vs set of [[SigmaValidationSettings]] which can be used to recognize soft-fork conditions.
* @return result of `block` if no ValidationException was thrown, or the result of
* `whenSoftFork` if soft-fork condition is detected.
* @throws ValidationException if soft-fork condition is not recognized by the given `vs`
*/
def trySoftForkable[T](whenSoftFork: => T)(block: => T)(implicit vs: SigmaValidationSettings): T = {
try block
catch {
Expand Down
2 changes: 1 addition & 1 deletion sigmastate/src/main/scala/sigmastate/UnprovenTree.scala
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ case class UnprovenDiffieHellmanTuple(override val proposition: ProveDHTuple,
* and should not contain challenges, responses, or the real/simulated flag for any node.
*
*/
// TODO coverage: write a test that restores the tree from this string and check that the result is equal,
// TODO coverage (8h): write a test that restores the tree from this string and check that the result is equal,
// in order to make sure this conversion is unambiguous
object FiatShamirTree {
val internalNodePrefix = 0: Byte
Expand Down
2 changes: 1 addition & 1 deletion sigmastate/src/main/scala/sigmastate/Values.scala
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ object Values {
trait OptionValue[T <: SType] extends Value[SOption[T]] {
}

// TODO HF: SomeValue and NoneValue are not used in ErgoTree and can be
// TODO HF (4h): SomeValue and NoneValue are not used in ErgoTree and can be
// either removed or implemented in v4.x
case class SomeValue[T <: SType](x: Value[T]) extends OptionValue[T] {
override def companion = SomeValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ class EvalSizeBox(
val foundSize = varSize.asInstanceOf[SizeOption[AnyValue]].sizeOpt
val regSize = foundSize match {
case Some(varSize: SizeAnyValue) =>
assert(varSize.tVal == tT, s"Unexpected register type found at register #$id: ${varSize.tVal}, expected $tT")
require(varSize.tVal == tT, s"Unexpected register type found at register #$id: ${varSize.tVal}, expected $tT")
val regSize = varSize.valueSize.asInstanceOf[Size[T]]
regSize
case _ =>
Expand Down
3 changes: 0 additions & 3 deletions sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,6 @@ trait Evaluation extends RuntimeCosting { IR: IRContext =>
val loopCost = if (_loopStack.isEmpty) 0 else _loopStack.head.accumulatedCost
val accumulatedCost = java.lang.Math.addExact(cost, loopCost)
if (accumulatedCost > limit) {
// if (cost < limit)
// println(s"FAIL FAST in loop: $accumulatedCost > $limit")
// TODO cover with tests
throw new CostLimitException(accumulatedCost, Evaluation.msgCostLimitError(accumulatedCost, limit), None)
}
}
Expand Down
2 changes: 0 additions & 2 deletions sigmastate/src/main/scala/sigmastate/eval/IRContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ trait IRContext extends Evaluation with TreeBuilding {
val costFun = compile[SSize[SContext], Int, Size[Context], Int](getDataEnv, costF, Some(maxCost))
val (_, estimatedCost) = costFun(Sized.sizeOf(ctx))
if (estimatedCost > maxCost) {
// TODO cover with tests
throw new CostLimitException(estimatedCost, s"Estimated execution cost $estimatedCost exceeds the limit $maxCost in $exp")
}
estimatedCost
Expand Down Expand Up @@ -130,7 +129,6 @@ trait IRContext extends Evaluation with TreeBuilding {
val scaledCost = JMath.multiplyExact(estimatedCost.toLong, CostTable.costFactorIncrease.toLong) / CostTable.costFactorDecrease
val totalCost = JMath.addExact(initCost, scaledCost)
if (totalCost > maxCost) {
// TODO cover with tests
throw new CostLimitException(totalCost, Evaluation.msgCostLimitError(totalCost, maxCost), None)
}
totalCost.toInt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -989,11 +989,11 @@ trait RuntimeCosting extends CostingRules { IR: IRContext =>
implicit val tA = ct.tItem
implicit val sizedA = Sized.typeToSized(tA)
liftConst(Sized.sizeOf(x.asInstanceOf[special.collection.Coll[a]]))
case ct: OptionType[a] => // TODO cover with tests
case ct: OptionType[a] => // TODO cover with tests (1h)
implicit val tA = ct.tA
implicit val sizedA = Sized.typeToSized(tA)
liftConst(Sized.sizeOf(x.asInstanceOf[Option[a]]))
case ct: PairType[a, b] => // TODO cover with tests
case ct: PairType[a, b] => // TODO cover with tests (1h)
implicit val tA = ct.tFst
implicit val tB = ct.tSnd
implicit val sizedA = Sized.typeToSized(tA)
Expand Down
4 changes: 2 additions & 2 deletions sigmastate/src/main/scala/sigmastate/eval/Zero.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ object Zero extends ZeroLowPriority {
case AvlTreeRType => Zero[AvlTree]
case SigmaPropRType => sigmaPropIsZero
case ct: CollType[a] => collIsZero(typeToZero(ct.tItem), ct.tItem)
case ct: OptionType[a] => optionIsZero(typeToZero(ct.tA)) // TODO cover with tests
case ct: PairType[a, b] => pairIsZero(typeToZero(ct.tFst), typeToZero(ct.tSnd)) // TODO cover with tests
case ct: OptionType[a] => optionIsZero(typeToZero(ct.tA)) // TODO cover with tests (2h)
case ct: PairType[a, b] => pairIsZero(typeToZero(ct.tFst), typeToZero(ct.tSnd)) // TODO cover with tests (1h)
case _ => sys.error(s"Don't know how to compute Zero for type $t")
}).asInstanceOf[Zero[T]]

Expand Down
24 changes: 14 additions & 10 deletions sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ trait Interpreter extends ScorexLogging {

val currCost = JMath.addExact(context.initCost, scriptComplexity)
val remainingLimit = context.costLimit - currCost
if (remainingLimit <= 0)
throw new CostLimitException(currCost, Evaluation.msgCostLimitError(currCost, context.costLimit), None) // TODO cover with tests

if (remainingLimit <= 0) {
throw new CostLimitException(currCost, Evaluation.msgCostLimitError(currCost, context.costLimit), None)
}
val ctx1 = context.withInitCost(currCost).asInstanceOf[CTX]
(ctx1, script)
}
Expand All @@ -71,17 +71,20 @@ trait Interpreter extends ScorexLogging {

CheckDeserializedScriptType(d, script)
Some(script)
case _ => None // TODO cover with tests
case _ =>
None
}
else
None // TODO cover with tests
None
case _ => None
}

def toValidScriptType(exp: SValue): BoolValue = exp match {
case v: Value[SBoolean.type]@unchecked if v.tpe == SBoolean => v
case p: SValue if p.tpe == SSigmaProp => p.asSigmaProp.isProven
case x => // TODO cover with tests
case x =>
// This case is not possible, due to exp is always of Boolean/SigmaProp type.
// In case it will ever change, leave it here to throw an explaining message.
throw new Error(s"Context-dependent pre-processing should produce tree of type Boolean or SigmaProp but was $x")
}

Expand All @@ -96,7 +99,7 @@ trait Interpreter extends ScorexLogging {
ergoTree.toProposition(ergoTree.isConstantSegregation)
case Left(UnparsedErgoTree(_, error)) if validationSettings.isSoftFork(error) =>
TrueSigmaProp
case Left(UnparsedErgoTree(_, error)) => // TODO cover with tests
case Left(UnparsedErgoTree(_, error)) =>
throw new InterpreterException(
"Script has not been recognized due to ValidationException, and it cannot be accepted as soft-fork.", None, Some(error))
}
Expand Down Expand Up @@ -231,9 +234,10 @@ trait Interpreter extends ScorexLogging {

val initCost = JMath.addExact(ergoTree.complexity.toLong, context.initCost)
val remainingLimit = context.costLimit - initCost
if (remainingLimit <= 0)
throw new CostLimitException(initCost, Evaluation.msgCostLimitError(initCost, context.costLimit), None) // TODO cover with tests

if (remainingLimit <= 0) {
// TODO cover with tests (2h)
throw new CostLimitException(initCost, Evaluation.msgCostLimitError(initCost, context.costLimit), None)
}
val contextWithCost = context.withInitCost(initCost).asInstanceOf[CTX]

val (cProp, cost) = fullReduction(ergoTree, contextWithCost, env)
Expand Down
2 changes: 1 addition & 1 deletion sigmastate/src/main/scala/sigmastate/lang/Terms.scala
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ object Terms {
def apply(name: String): Ident = Ident(name, NoType)
}

// TODO HF: move to sigmastate.Values
// TODO refactor: move to sigmastate.Values
/** ErgoTree node which represents application of function `func` to the given arguments.
* @param func expression which evaluates to a function
* @param args arguments of the function application
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ case class ConcreteCollectionBooleanConstantSerializer(cons: (IndexedSeq[Value[S
val bits = new Array[Boolean](len)
cfor(0)(_ < len, _ + 1) { i =>
bits(i) = items(i) match {
case v: BooleanConstant => v.value
case v => error(s"Expected collection of BooleanConstant values, got: $v") // TODO cover with tests
case v: BooleanConstant if v.tpe == SBoolean =>
v.value
case v =>
error(s"Expected collection of BooleanConstant values, got: $v")
}
}
w.putBits(bits, bitsInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ case class ConstantPlaceholderSerializer(cons: (Int, SType) => Value[SType])

override def parse(r: SigmaByteReader): Value[SType] = {
val id = r.getUInt().toInt
val constant = r.constantStore.get(id) // TODO HF move this under if branch
val constant = r.constantStore.get(id)
if (r.resolvePlaceholdersToConstants)
constant
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter}

/** This works in tandem with DataSerializer, if you change one make sure to check the other.*/
case class ConstantSerializer(builder: SigmaBuilder)
extends ByteBufferSerializer[Constant[SType]] with ValueSerializer[Constant[SType]] {
extends ValueSerializer[Constant[SType]] {
override def opDesc = Constant

override def parse(r: SigmaByteReader): Value[SType] = deserialize(r)
Expand All @@ -17,7 +17,7 @@ case class ConstantSerializer(builder: SigmaBuilder)
DataSerializer.serialize(c.value, c.tpe, w)
}

override def deserialize(r: SigmaByteReader): Constant[SType] = {
def deserialize(r: SigmaByteReader): Constant[SType] = {
val tpe = r.getType()
val obj = DataSerializer.deserialize(tpe, r)
builder.mkConstant(obj, tpe)
Expand Down
Loading

0 comments on commit a116e37

Please sign in to comment.