Skip to content

Commit

Permalink
Merge branch 'v6.0.0' of github.com:ScorexFoundation/sigmastate-inter…
Browse files Browse the repository at this point in the history
…preter into i906
  • Loading branch information
kushti committed Jul 30, 2024
2 parents aaef77e + 271ec30 commit 8f9b549
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 30 deletions.
30 changes: 17 additions & 13 deletions core/shared/src/main/scala/sigma/ast/SType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import sigma.data.OverloadHack.Overloaded1
import sigma.data.{CBigInt, Nullable, SigmaConstants}
import sigma.reflection.{RClass, RMethod, ReflectionData}
import sigma.util.Extensions.{IntOps, LongOps, ShortOps}
import sigma.{AvlTree, BigInt, Box, Coll, Context, Evaluation, GroupElement, Header, PreHeader, SigmaDslBuilder, SigmaProp}
import sigma.{AvlTree, BigInt, Box, Coll, Context, Evaluation, GroupElement, Header, PreHeader, SigmaDslBuilder, SigmaProp, VersionContext}

import java.math.BigInteger

Expand Down Expand Up @@ -375,6 +375,7 @@ case object SByte extends SPrimType with SEmbeddable with SNumericType with SMon
case s: Short => s.toByteExact
case i: Int => i.toByteExact
case l: Long => l.toByteExact
case bi: BigInt if VersionContext.current.isV6SoftForkActivated => bi.toByte // toByteExact from int is called under the hood
case _ => sys.error(s"Cannot downcast value $v to the type $this")
}
}
Expand All @@ -396,6 +397,7 @@ case object SShort extends SPrimType with SEmbeddable with SNumericType with SMo
case s: Short => s
case i: Int => i.toShortExact
case l: Long => l.toShortExact
case bi: BigInt if VersionContext.current.isV6SoftForkActivated => bi.toShort // toShortExact from int is called under the hood
case _ => sys.error(s"Cannot downcast value $v to the type $this")
}
}
Expand All @@ -419,6 +421,7 @@ case object SInt extends SPrimType with SEmbeddable with SNumericType with SMono
case s: Short => s.toInt
case i: Int => i
case l: Long => l.toIntExact
case bi: BigInt if VersionContext.current.isV6SoftForkActivated => bi.toInt
case _ => sys.error(s"Cannot downcast value $v to the type $this")
}
}
Expand All @@ -444,6 +447,7 @@ case object SLong extends SPrimType with SEmbeddable with SNumericType with SMon
case s: Short => s.toLong
case i: Int => i.toLong
case l: Long => l
case bi: BigInt if VersionContext.current.isV6SoftForkActivated => bi.toLong
case _ => sys.error(s"Cannot downcast value $v to the type $this")
}
}
Expand All @@ -465,24 +469,24 @@ case object SBigInt extends SPrimType with SEmbeddable with SNumericType with SM
override def numericTypeIndex: Int = 4

override def upcast(v: AnyVal): BigInt = {
val bi = v match {
case x: Byte => BigInteger.valueOf(x.toLong)
case x: Short => BigInteger.valueOf(x.toLong)
case x: Int => BigInteger.valueOf(x.toLong)
case x: Long => BigInteger.valueOf(x)
v match {
case x: Byte => CBigInt(BigInteger.valueOf(x.toLong))
case x: Short => CBigInt(BigInteger.valueOf(x.toLong))
case x: Int => CBigInt(BigInteger.valueOf(x.toLong))
case x: Long => CBigInt(BigInteger.valueOf(x))
case x: BigInt if VersionContext.current.isV6SoftForkActivated => x
case _ => sys.error(s"Cannot upcast value $v to the type $this")
}
CBigInt(bi)
}
override def downcast(v: AnyVal): BigInt = {
val bi = v match {
case x: Byte => BigInteger.valueOf(x.toLong)
case x: Short => BigInteger.valueOf(x.toLong)
case x: Int => BigInteger.valueOf(x.toLong)
case x: Long => BigInteger.valueOf(x)
v match {
case x: Byte => CBigInt(BigInteger.valueOf(x.toLong))
case x: Short => CBigInt(BigInteger.valueOf(x.toLong))
case x: Int => CBigInt(BigInteger.valueOf(x.toLong))
case x: Long => CBigInt(BigInteger.valueOf(x))
case x: BigInt if VersionContext.current.isV6SoftForkActivated => x
case _ => sys.error(s"Cannot downcast value $v to the type $this")
}
CBigInt(bi)
}
}

Expand Down
77 changes: 60 additions & 17 deletions sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package sigma

import sigma.ast.{Apply, Downcast, FixedCost, FixedCostItem, FuncValue, GetVar, Global, JitCost, MethodCall, NamedDesc, OptionGet, SBigInt, SByte, SGlobalMethods, SInt, SLong, SShort, STypeVar, ValUse}
import sigma.data.{CBigInt, ExactNumeric, RType}
import sigma.eval.{SigmaDsl, TracedCost}
import sigma.ast.{Apply, Downcast, FixedCost, FixedCostItem, FuncValue, GetVar, JitCost, OptionGet, SBigInt, SByte, SInt, SLong, SShort, ValUse}
import sigma.data.{CBigInt, ExactNumeric}
import sigma.eval.SigmaDsl
import sigma.util.Extensions.{BooleanOps, ByteOps, IntOps, LongOps}
import sigmastate.exceptions.MethodNotFound

Expand Down Expand Up @@ -172,21 +172,26 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite =>
}

property("BigInt methods equivalence (new features)") {
// TODO v6.0: the behavior of `upcast` for BigInt is different from all other Numeric types (see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/877)
// The `Upcast(bigInt, SBigInt)` node is never produced by ErgoScript compiler, but is still valid ErgoTree.
// It makes sense to fix this inconsistency as part of upcoming forks
assertExceptionThrown(
SBigInt.upcast(CBigInt(new BigInteger("0", 16)).asInstanceOf[AnyVal]),
_.getMessage.contains("Cannot upcast value")
)
if (activatedVersionInTests < VersionContext.V6SoftForkVersion) {
// The `Upcast(bigInt, SBigInt)` node is never produced by ErgoScript compiler, but is still valid ErgoTree.
// Fixed in 6.0
assertExceptionThrown(
SBigInt.upcast(CBigInt(new BigInteger("0", 16)).asInstanceOf[AnyVal]),
_.getMessage.contains("Cannot upcast value")
)

// TODO v6.0: the behavior of `downcast` for BigInt is different from all other Numeric types (see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/877)
// The `Downcast(bigInt, SBigInt)` node is never produced by ErgoScript compiler, but is still valid ErgoTree.
// It makes sense to fix this inconsistency as part of HF
assertExceptionThrown(
SBigInt.downcast(CBigInt(new BigInteger("0", 16)).asInstanceOf[AnyVal]),
_.getMessage.contains("Cannot downcast value")
)
// The `Downcast(bigInt, SBigInt)` node is never produced by ErgoScript compiler, but is still valid ErgoTree.
// Fixed in 6.0
assertExceptionThrown(
SBigInt.downcast(CBigInt(new BigInteger("0", 16)).asInstanceOf[AnyVal]),
_.getMessage.contains("Cannot downcast value")
)
} else {
forAll { x: BigInteger =>
SBigInt.upcast(CBigInt(x).asInstanceOf[AnyVal]) shouldBe CBigInt(x)
SBigInt.downcast(CBigInt(x).asInstanceOf[AnyVal]) shouldBe CBigInt(x)
}
}

if (activatedVersionInTests < VersionContext.V6SoftForkVersion) {
// NOTE, for such versions the new features are not supported
Expand Down Expand Up @@ -225,6 +230,44 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite =>
forAll { x: (BigInt, BigInt) =>
Seq(compareTo, bitOr, bitAnd).foreach(_.checkEquality(x))
}

forAll { x: Long =>
assertExceptionThrown(
SLong.downcast(CBigInt(new BigInteger(x.toString)).asInstanceOf[AnyVal]),
_.getMessage.contains("Cannot downcast value")
)
}
forAll { x: Int =>
assertExceptionThrown(
SInt.downcast(CBigInt(new BigInteger(x.toString)).asInstanceOf[AnyVal]),
_.getMessage.contains("Cannot downcast value")
)
}
forAll { x: Byte =>
assertExceptionThrown(
SByte.downcast(CBigInt(new BigInteger(x.toString)).asInstanceOf[AnyVal]),
_.getMessage.contains("Cannot downcast value")
)
}
forAll { x: Short =>
assertExceptionThrown(
SShort.downcast(CBigInt(new BigInteger(x.toString)).asInstanceOf[AnyVal]),
_.getMessage.contains("Cannot downcast value")
)
}
} else {
forAll { x: Long =>
SLong.downcast(CBigInt(new BigInteger(x.toString)).asInstanceOf[AnyVal]) shouldBe x
}
forAll { x: Int =>
SInt.downcast(CBigInt(new BigInteger(x.toString)).asInstanceOf[AnyVal]) shouldBe x
}
forAll { x: Byte =>
SByte.downcast(CBigInt(new BigInteger(x.toString)).asInstanceOf[AnyVal]) shouldBe x
}
forAll { x: Short =>
SShort.downcast(CBigInt(new BigInteger(x.toString)).asInstanceOf[AnyVal]) shouldBe x
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import sigma.ast.syntax._
import org.ergoplatform._
import org.scalatest.BeforeAndAfterAll
import scorex.util.encode.Base58
import sigma.VersionContext
import sigma.crypto.CryptoConstants
import sigma.data.{AvlTreeData, CAND, ProveDlog, SigmaBoolean, TrivialProp}
import sigma.util.Extensions.IntOps
Expand Down Expand Up @@ -215,6 +216,46 @@ class TestingInterpreterSpecification extends CompilerTestingCommons
testWithCasting("toBigInt")
}

property("BigInt downcasting to byte") {
def test() = testEval("{ sigmaProp(0L.toBigInt.toByte <= CONTEXT.preHeader.version) }")
if(VersionContext.current.isV6SoftForkActivated) {
test()
} else {
an[Exception] shouldBe thrownBy(test())
}
}

property("BigInt downcasting to short") {
def test() = testEval("{ sigmaProp(0L.toBigInt.toShort <= CONTEXT.preHeader.version.toShort) }")
if(VersionContext.current.isV6SoftForkActivated) {
test()
} else {
an[Exception] shouldBe thrownBy(test())
}
}

property("BigInt downcasting to int") {
def test() = testEval("{ sigmaProp(1L.toBigInt.toInt < CONTEXT.preHeader.timestamp.toInt) }")
if(VersionContext.current.isV6SoftForkActivated) {
test()
} else {
an[Exception] shouldBe thrownBy(test())
}
}

property("BigInt downcasting to long") {
def test() = testEval("{ sigmaProp(1L.toBigInt.toLong < CONTEXT.preHeader.timestamp) }")
if(VersionContext.current.isV6SoftForkActivated) {
test()
} else {
an[Exception] shouldBe thrownBy(test())
}
}

property("upcasting to bigint") {
testEval("{ sigmaProp(1L.toBigInt < bigInt(\"2\")) }")
}

property("Evaluate arithmetic ops") {
def testWithCasting(castSuffix: String): Unit = {
testEval(s"1.$castSuffix + 2.$castSuffix == 3.$castSuffix")
Expand Down

0 comments on commit 8f9b549

Please sign in to comment.