Skip to content

Commit

Permalink
fix for #1046: Impossible to use 6.0 types in register and context ex…
Browse files Browse the repository at this point in the history
…tension vars
  • Loading branch information
kushti committed Jan 8, 2025
1 parent d13dd4d commit 08c7f98
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sigma.serialization

import sigma.SigmaException
import sigma.ast.SType

import scala.collection.compat.immutable.ArraySeq

Expand Down Expand Up @@ -37,3 +38,6 @@ final class DeserializeCallDepthExceeded(message: String, cause: Option[Throwabl
/** Thrown by [[org.ergoplatform.validation.ValidationRules.CheckValidOpCode]] validation rule. */
final class InvalidOpCode(message: String, cause: Option[Throwable] = None)
extends SerializerException(message, cause)

final class V6TypeUsedException(tpe: SType, cause: Option[Throwable] = None)
extends SerializerException(s"V6 type used in register or context var extension: $tpe", cause)
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import sigma.{Coll, Colls}
import sigma.ast._
import sigma.ast.syntax._
import sigma.serialization.ErgoTreeSerializer.DefaultSerializer
import sigma.serialization.{SigmaByteReader, SigmaByteWriter, SigmaSerializer}
import sigma.serialization.{SerializerException, SigmaByteReader, SigmaByteWriter, SigmaSerializer, V6TypeUsedException}

import scala.collection.{immutable, mutable}
import scala.runtime.ScalaRunTime
Expand Down Expand Up @@ -228,6 +228,9 @@ object ErgoBoxCandidate {
cfor(0)(_ < nRegs, _ + 1) { iReg =>
val reg = ErgoBox.nonMandatoryRegisters(iReg)
val v = r.getValue().asInstanceOf[EvaluatedValue[SType]] // READ
if (containsV6Types(v)) {
throw new V6TypeUsedException(v.tpe)
}
b += ((reg, v)) // don't use `->` since it incur additional wrapper overhead
}
r.positionLimit = previousPositionLimit
Expand Down
2 changes: 1 addition & 1 deletion data/shared/src/main/scala/sigma/ast/values.scala
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ trait PerItemCostValueCompanion extends ValueCompanion {
*
* @see Constant, ConcreteCollection, Tuple
*/
abstract class EvaluatedValue[+S <: SType] extends Value[S] {
sealed trait EvaluatedValue[+S <: SType] extends Value[S] {
/** The evaluated data value of the corresponding underlying data type. */
val value: S#WrappedType

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package sigma.interpreter

import org.ergoplatform.ErgoBoxCandidate.serializer.containsV6Types
import sigma.ast.{EvaluatedValue, SType}
import sigma.interpreter.ContextExtension.VarBinding
import sigma.serialization.{SigmaByteReader, SigmaByteWriter, SigmaSerializer}
import sigma.serialization.{SerializerException, SigmaByteReader, SigmaByteWriter, SigmaSerializer}

/**
* User-defined variables to be put into context.
Expand Down Expand Up @@ -49,7 +50,14 @@ object ContextExtension {
if (extSize < 0)
error(s"Negative amount of context extension values: $extSize")
val values = (0 until extSize)
.map(_ => (r.getByte(), r.getValue().asInstanceOf[EvaluatedValue[_ <: SType]]))
.map{_ =>
val k = r.getByte()
val v = r.getValue().asInstanceOf[EvaluatedValue[_ <: SType]]
if(containsV6Types(v)){
throw SerializerException("")
}
(k, v)
}
ContextExtension(values.toMap)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sigma.serialization
import java.nio.ByteBuffer
import scorex.util.ByteArrayBuilder
import scorex.util.serialization._
import sigma.ast.{Constant, EvaluatedCollection, EvaluatedValue, GroupGenerator, SHeader, SType, SUnsignedBigInt}
import sigma.data.SigmaConstants
import sigma.serialization.SigmaByteWriter.{FixedCostCallback, PerItemCostCallback}
import sigma.serialization.ValueCodes.OpCode
Expand Down Expand Up @@ -81,6 +82,17 @@ abstract class SigmaSerializer[TFamily, T <: TFamily] extends Serializer[TFamily
final def fromBytes(bytes: Array[Byte]): TFamily = {
parse(SigmaSerializer.startReader(bytes))
}

protected final def containsV6Types(v: EvaluatedValue[_]): Boolean = {
def v6TypeCheck(tpe: SType) = {
tpe.isOption || tpe.typeCode == SHeader.typeCode || tpe.typeCode == SUnsignedBigInt.typeCode
}
v match {
case c: Constant[_] => v6TypeCheck(c.tpe)
case c: EvaluatedCollection[_, _] => v6TypeCheck(c.elementType)
case GroupGenerator => false
}
}
}

trait SigmaSerializerCompanion[TFamily] {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sigma.serialization

import org.ergoplatform.ErgoBoxCandidate
import org.ergoplatform.ErgoBox.R4
import org.ergoplatform.{ErgoBoxCandidate, ErgoTreePredef}
import org.scalacheck.Gen
import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert}
import scorex.crypto.authds.{ADKey, ADValue}
Expand All @@ -11,7 +12,7 @@ import sigma.data.{AvlTreeData, AvlTreeFlags, CAND, SigmaBoolean}
import sigma.util.{BenchmarkUtil, safeNewArray}
import sigma.validation.ValidationException
import sigma.validation.ValidationRules.CheckPositionLimit
import sigma.{Colls, Environment}
import sigma.{Colls, Environment, VersionContext}
import sigma.ast._
import sigma.ast.syntax._
import sigmastate._
Expand All @@ -25,6 +26,7 @@ import sigmastate.helpers.{CompilerTestingCommons, ErgoLikeContextTesting, ErgoL
import sigma.serialization.OpCodes._
import sigmastate.utils.Helpers._

import java.math.BigInteger
import java.nio.ByteBuffer
import scala.collection.immutable.Seq
import scala.collection.mutable
Expand Down Expand Up @@ -425,4 +427,16 @@ class DeserializationResilience extends DeserializationResilienceTesting {
// NOTE, even though performOneOperation fails, some AvlTree$ methods used in Interpreter
// (remove_eval, update_eval, contains_eval) won't throw, while others will.
}


property("impossible to use v6 types in box registers") {
val trueProp = ErgoTreePredef.TrueProp(ErgoTree.defaultHeaderWithVersion(3))
val b = new ErgoBoxCandidate(1L, trueProp, 1,
additionalRegisters = Map(R4 -> UnsignedBigIntConstant(new BigInteger("2"))))
VersionContext.withVersions(3, 3) {
val bs = ErgoBoxCandidate.serializer.toBytes(b)
a[V6TypeUsedException] should be thrownBy ErgoBoxCandidate.serializer.fromBytes(bs)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ class SerializationRoundTripSpec extends AnyPropSpec
}
}

property("ErgoBoxCandidate: Serializer round trip") {

}

property("ContextExtension: Serializer round trip") {
forAll { t: ContextExtension => roundTripTest(t)(ContextExtension.serializer) }
forAll { t: ContextExtension => roundTripTestWithPos(t)(ContextExtension.serializer) }
Expand Down

0 comments on commit 08c7f98

Please sign in to comment.