Skip to content

Commit

Permalink
core-serializers2: moved CAnyValue to core
Browse files Browse the repository at this point in the history
  • Loading branch information
aslesarenko committed Sep 20, 2023
1 parent 094beeb commit 3f85433
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 110 deletions.
18 changes: 18 additions & 0 deletions core/shared/src/main/scala/sigma/data/CAnyValue.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package sigma.data

import sigma.AnyValue
import sigma.data.OverloadHack.Overloaded1

import scala.annotation.unused

/** Default implementation of AnyValue interface. */
case class CAnyValue[A](value: A, tVal: RType[Any]) extends AnyValue {
def tA: RType[A] = tVal.asInstanceOf[RType[A]]

override def toString = s"TestValue($value)"
}

object CAnyValue {
def apply[A](value: A)(implicit t: RType[A], @unused o: Overloaded1): CAnyValue[A] =
new CAnyValue(value, t.asInstanceOf[RType[Any]])
}
95 changes: 95 additions & 0 deletions interpreter/shared/src/main/scala/sigmastate/eval/CBox.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package sigmastate.eval

import org.ergoplatform.ErgoBox
import scorex.utils.Ints
import sigma.Evaluation.stypeToRType
import sigma.ast.SCollection.SByteArray
import sigma.ast.{SInt, STuple, SType}
import sigma.data.{CAnyValue, RType, WrapperOf}
import sigma.{AnyValue, Box, Coll, Colls}
import sigmastate.Values.{ConstantNode, EvaluatedValue, SValue}
import sigmastate.eval.CBox.regs
import sigmastate.eval.Extensions.toAnyValue

import java.util.Arrays

/** A default implementation of [[Box]] interface.
*
* @see [[Box]] for detailed descriptions
*/
case class CBox(ebox: ErgoBox) extends Box with WrapperOf[ErgoBox] {
val builder = CSigmaDslBuilder

val value = ebox.value
lazy val id : Coll[Byte] = Colls.fromArray(ebox.id)
lazy val bytes : Coll[Byte] = Colls.fromArray(ebox.bytes)
lazy val bytesWithoutRef : Coll[Byte] = Colls.fromArray(ebox.bytesWithNoRef)
lazy val propositionBytes: Coll[Byte] = Colls.fromArray(ebox.propositionBytes)
lazy val registers : Coll[AnyValue] = regs(ebox)

override def wrappedValue: ErgoBox = ebox

override def getReg[T](i: Int)(implicit tT: RType[T]): Option[T] = {
if (i < 0 || i >= registers.length) return None
val value = registers(i)
if (value != null) {
// once the value is not null it should be of the right type
value match {
case value: CAnyValue[_] if value.value != null && value.tA == tT =>
Some(value.value.asInstanceOf[T])
case _ =>
throw new InvalidType(s"Cannot getReg[${tT.name}]($i): invalid type of value $value at id=$i")
}
} else None
}

override def creationInfo: (Int, Coll[Byte]) = {
this.getReg[(Int, Coll[Byte])](3).get.asInstanceOf[Any] match {
case info: Tuple2[Int, Coll[Byte]]@unchecked => info
case ConstantNode(arr: Array[Any], STuple(IndexedSeq(SInt, SByteArray))) if arr.length == 2 =>
(arr(0).asInstanceOf[Int], builder.Colls.fromArray(arr(1).asInstanceOf[Array[Byte]]))
case v =>
sys.error(s"Invalid value $v of creationInfo register R3")
}
}

override def tokens: Coll[(Coll[Byte], Long)] = {
this.getReg[Coll[(Coll[Byte], Long)]](ErgoBox.R2.asIndex).get
}

override def executeFromRegister[T](regId: Byte)
(implicit cT: RType[T]): T = ??? // TODO implement

override def hashCode(): Int = Ints.fromByteArray(id.toArray)

override def equals(obj: Any): Boolean = (this eq obj.asInstanceOf[AnyRef]) || (obj != null && {
obj match {
case obj: Box => Arrays.equals(id.toArray, obj.id.toArray)
case _ =>
// this case was missing in v4.x, however has never been a problem
// Thus, v5.0 interpreter will not fail (while v4.x would fail here)
false
}
})
}

object CBox {
def regs(ebox: ErgoBox): Coll[AnyValue] = {
val res = new Array[AnyValue](ErgoBox.maxRegisters)

def checkNotYetDefined(id: Int, newValue: SValue) =
require(res(id) == null, s"register $id is defined more then once: previous value ${res(id)}, new value $newValue")

for ( (k, v: EvaluatedValue[t]) <- ebox.additionalRegisters ) {
checkNotYetDefined(k.number, v)
res(k.number) = toAnyValue(v.value)(stypeToRType(v.tpe))
}
for ( r <- ErgoBox.mandatoryRegisters ) {
val regId = r.number
val v = ebox.get(r).get.asInstanceOf[EvaluatedValue[SType]]
checkNotYetDefined(regId, v)
res(regId) = toAnyValue(v.value)(stypeToRType(v.tpe))
}
Colls.fromArray(res)
}
}
97 changes: 0 additions & 97 deletions interpreter/shared/src/main/scala/sigmastate/eval/CContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,103 +60,6 @@ object AvlTreeVerifier {
}
}

/** Default implementation of AnyValue interface. */
case class CAnyValue[A](value: A, tVal: RType[Any]) extends AnyValue {
def tA: RType[A] = tVal.asInstanceOf[RType[A]]
override def toString = s"TestValue($value)"
}

object CAnyValue {
def apply[A](value: A)(implicit t: RType[A], @unused o: Overloaded1): CAnyValue[A] =
new CAnyValue(value, t.asInstanceOf[RType[Any]])
}

import sigmastate.eval.CBox._

/** A default implementation of [[Box]] interface.
* @see [[Box]] for detailed descriptions
*/
case class CBox(ebox: ErgoBox) extends Box with WrapperOf[ErgoBox] {
val builder = CSigmaDslBuilder

val value = ebox.value
lazy val id: Coll[Byte] = Colls.fromArray(ebox.id)
lazy val bytes: Coll[Byte] = Colls.fromArray(ebox.bytes)
lazy val bytesWithoutRef: Coll[Byte] = Colls.fromArray(ebox.bytesWithNoRef)
lazy val propositionBytes: Coll[Byte] = Colls.fromArray(ebox.propositionBytes)
lazy val registers: Coll[AnyValue] = regs(ebox)

override def wrappedValue: ErgoBox = ebox

override def getReg[T](i: Int)(implicit tT: RType[T]): Option[T] = {
if (i < 0 || i >= registers.length) return None
val value = registers(i)
if (value != null ) {
// once the value is not null it should be of the right type
value match {
case value: CAnyValue[_] if value.value != null && value.tA == tT =>
Some(value.value.asInstanceOf[T])
case _ =>
throw new InvalidType(s"Cannot getReg[${tT.name}]($i): invalid type of value $value at id=$i")
}
} else None
}

override def creationInfo: (Int, Coll[Byte]) = {
this.getReg[(Int, Coll[Byte])](3).get.asInstanceOf[Any] match {
case info: Tuple2[Int, Coll[Byte]]@unchecked => info
case ConstantNode(arr: Array[Any], STuple(IndexedSeq(SInt, SByteArray))) if arr.length == 2 =>
(arr(0).asInstanceOf[Int], builder.Colls.fromArray(arr(1).asInstanceOf[Array[Byte]]))
case v =>
sys.error(s"Invalid value $v of creationInfo register R3")
}
}

override def tokens: Coll[(Coll[Byte], Long)] = {
this.getReg[Coll[(Coll[Byte], Long)]](ErgoBox.R2.asIndex).get
}

override def executeFromRegister[T](regId: Byte)(implicit cT: RType[T]): T = ??? // TODO implement

override def hashCode(): Int = Ints.fromByteArray(id.toArray)

override def equals(obj: Any): Boolean = (this eq obj.asInstanceOf[AnyRef]) || (obj != null && {
obj match {
case obj: Box => Arrays.equals(id.toArray, obj.id.toArray)
case _ =>
// this case was missing in v4.x, however has never been a problem
// Thus, v5.0 interpreter will not fail (while v4.x would fail here)
false
}
})
}

object CBox {

import Evaluation._

def regs(ebox: ErgoBox): Coll[AnyValue] = {
val res = new Array[AnyValue](ErgoBox.maxRegisters)

def checkNotYetDefined(id: Int, newValue: SValue) =
require(res(id) == null, s"register $id is defined more then once: previous value ${res(id)}, new value $newValue")

for ((k, v: EvaluatedValue[t]) <- ebox.additionalRegisters) {
checkNotYetDefined(k.number, v)
res(k.number) = toAnyValue(v.value)(stypeToRType(v.tpe))
}

for (r <- ErgoBox.mandatoryRegisters) {
val regId = r.number
val v = ebox.get(r).get.asInstanceOf[EvaluatedValue[SType]]
checkNotYetDefined(regId, v)
res(regId) = toAnyValue(v.value)(stypeToRType(v.tpe))
}
Colls.fromArray(res)
}

}

/** This class represents context variable and register value of a functional type A => B.
* When variable or register is accessed using `getVar[A => B](id).get` or
* `box.getReg[A => B].get an instance of this class is returned.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import scorex.crypto.authds.{ADKey, ADValue}
import scorex.util.encode.Base16
import sigma.ast.SType.AnyOps
import sigma.ast.{SBoolean, SCollection, SCollectionType, SType}
import sigma.data.{Nullable, RType, SigmaBoolean}
import sigma.data.{CAnyValue, Nullable, RType, SigmaBoolean}
import sigma.{Coll, _}
import sigmastate.Platform
import sigmastate.Values.{Constant, ConstantNode, SigmaPropConstant, SigmaPropValue, Value}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package sigmastate.utils
import debox.cfor
import io.circe.Decoder
import org.ergoplatform.settings.ErgoAlgos
import sigma.data.{OverloadHack, RType}
import sigma.data.{CAnyValue, OverloadHack, RType}
import scorex.utils.Ints
import sigma.crypto.EcPointType
import sigma.{Coll, Colls, Environment, GroupElement}
import sigmastate.eval.{CAnyValue, SigmaDsl}
import sigmastate.eval.SigmaDsl

import java.util
import java.util.concurrent.locks.Lock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package sigmastate.lang
import org.scalatest.matchers.should.Matchers
import org.scalatest.propspec.AnyPropSpec
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import sigma.data.{CAvlTree, Nullable, RType}
import sigma.data.{CAnyValue, CAvlTree, Nullable, RType}
import sigma.{Environment, VersionContext}
import sigmastate.Values._
import sigmastate._
import sigma.Extensions.ArrayOps
import sigmastate.eval.{CAnyValue, CBox, SigmaDsl}
import sigmastate.eval.{CBox, SigmaDsl}
import sigmastate.exceptions.ConstraintFailed
import sigmastate.serialization.OpCodes
import sigma.SigmaTestingData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import sigmastate.eval._
import sigmastate.helpers.NegativeTesting
import sigma.Coll
import sigma.ast._
import sigma.data.{ProveDHTuple, ProveDlog, SigmaBoolean}
import sigma.data.{CAnyValue, ProveDHTuple, ProveDlog, SigmaBoolean}
import sigma.util.Extensions.BigIntegerOps

trait LangTests extends Matchers with NegativeTesting {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import sigmastate.interpreter.{CostedProverResult, ProverResult}

import scala.collection.mutable.ArrayBuffer
import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId}
import sigma.data.{AvlTreeData, CSigmaProp, Nullable}
import sigma.data.{AvlTreeData, CAnyValue, CSigmaProp, Nullable}

import scala.util.Try
import org.ergoplatform.{ErgoBox, ErgoLikeContext}
import org.ergoplatform.dsl.ContractSyntax.{ErgoScript, Proposition, Token}
import sigma.ast.SType
import sigmastate.Values.{ErgoTree, EvaluatedValue}
import sigmastate.eval.{CAnyValue, IRContext}
import sigmastate.eval.IRContext
import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter}
import sigmastate.helpers.TestingHelpers._
import sigmastate.lang.Terms.ValueOps
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sigmastate.eval

import scalan.BaseCtxTests
import sigma.data.CAnyValue

trait ExampleContracts extends ErgoScriptTestkit { self: BaseCtxTests =>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import sigma.Extensions.ArrayOps
import sigma.ast.SCollection.SByteArray
import sigma.ast.SType.AnyOps
import sigma.ast._
import sigma.data.AvlTreeData
import sigma.data.{AvlTreeData, CAnyValue}
import sigma.util.StringUtil._
import sigmastate.Values._
import sigmastate._
import sigmastate.crypto.CryptoConstants
import sigmastate.eval.{CAnyValue, InvalidType}
import sigmastate.eval.InvalidType
import sigmastate.helpers.TestingHelpers._
import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter}
import sigmastate.interpreter.ContextExtension.VarBinding
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package sigmastate.utxo

import sigma.ast.SType
import sigma.data.CAnyValue
import sigmastate.Values._
import sigmastate.eval.CAnyValue
import sigmastate.helpers.CompilerTestingCommons
import sigmastate.interpreter.Interpreter.ScriptEnv
import sigmastate.lang.Terms._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.circe.syntax._
import org.ergoplatform.ErgoBox
import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, Token}
import org.ergoplatform.settings.ErgoAlgos
import sigma.data.RType
import sigma.data.{CAnyValue, RType}
import scorex.util._
import sigmastate.Values.{Constant, EvaluatedValue}
import sigmastate.lang.SigmaParser
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package org.ergoplatform.sdk
import java.math.BigInteger
import org.scalacheck.Arbitrary._
import org.scalacheck.Gen
import sigma.data.{RType, SigmaBoolean, TupleColl}
import sigma.data.{CAnyValue, RType, SigmaBoolean, TupleColl}
import sigma.ast._
import sigma.ast.SCollection.SByteArray
import sigma.ast.SType.AnyOps
Expand Down

0 comments on commit 3f85433

Please sign in to comment.