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

I1039 Finishes executeFromSelfReg #1055

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 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
13 changes: 11 additions & 2 deletions data/shared/src/main/scala/sigma/ast/SigmaPredef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sigma.ast

import org.ergoplatform.ErgoAddressEncoder.NetworkPrefix
import org.ergoplatform.{ErgoAddressEncoder, P2PKAddress}
import org.ergoplatform.ErgoBox.RegisterId
import scorex.util.encode.{Base16, Base58, Base64}
import sigma.ast.SCollection.{SByteArray, SIntArray}
import sigma.ast.SOption.SIntOption
Expand Down Expand Up @@ -386,10 +387,18 @@ object SigmaPredef {
val ExecuteFromSelfRegFunc = PredefinedFunc("executeFromSelfReg",
Lambda(
Seq(paramT),
Array("id" -> SByte, "default" -> SOption(tT)),
Array("id" -> SInt, "default" -> SOption(tT)),
tT, None
),
PredefFuncInfo(undefined),
PredefFuncInfo(
{
case (Ident(_, SFunc(_, rtpe, _)), Seq(id: Constant[SNumericType]@unchecked, default)) =>
val r: RegisterId = org.ergoplatform.ErgoBox.registerByIndex(SByte.downcast(id.value.asInstanceOf[AnyVal]))
mkDeserializeRegister(
r, rtpe,
Some(default.asValue[rtpe.type])
)
}),
OperationInfo(DeserializeRegister,
"""Extracts SELF register as \lst{Coll[Byte]}, deserializes it to script
| and then executes this script in the current context.
Expand Down
2 changes: 1 addition & 1 deletion data/shared/src/main/scala/sigma/ast/transformers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ object DeserializeContext extends ValueCompanion {
}

/** Extract register of SELF box as Coll[Byte], deserialize it into Value and inline into executing script.
* NOTE: it only applicable to SELF box
* NOTE: it's only applicable to SELF box
*/
case class DeserializeRegister[V <: SType](reg: RegisterId, tpe: V, default: Option[Value[V]] = None) extends Deserialize[V] {
override def companion = DeserializeRegister
Expand Down
9 changes: 8 additions & 1 deletion sc/shared/src/main/scala/sigma/compiler/ir/Base.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package sigma.compiler.ir

import debox.{cfor, Buffer => DBuffer}
import sigma.compiler.ir.core.MutableLazy
import sigma.ast.{DeserializeContext, SType}
import sigma.ast.{DeserializeContext, DeserializeRegister, SType}
import sigma.data.{AVHashMap, Nullable, RType}
import sigma.data.OverloadHack.Overloaded1
import sigma.reflection.RConstructor
Expand Down Expand Up @@ -211,6 +211,13 @@ abstract class Base { thisIR: IRContext =>
override def resultType: Elem[V#WrappedType] = e
}

/**
* Def done in order to carry on DeserializeRegister through stages of compilation intact
*/
case class DeserializeRegisterDef[V <: SType](d: DeserializeRegister[V], t: Elem[V#WrappedType], e: Elem[V#WrappedType]) extends Def[V#WrappedType] {
override def resultType: Elem[V#WrappedType] = t
}

/** Base class for virtualized instances of type companions.
* Each virtualized entity type (trait or class) may have virtualized companion class. */
abstract class CompanionDef[T] extends Def[T] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,10 @@ trait GraphBuilding extends Base with DefRewriting { IR: IRContext =>
val e = stypeToElem(d.tpe)
DeserializeContextDef(d, e)

case d: DeserializeRegister[T] =>
val e = stypeToElem(d.tpe)
DeserializeRegisterDef[T](d, e, e)

case ValUse(valId, _) =>
env.getOrElse(valId, !!!(s"ValUse $valId not found in environment $env"))

Expand Down
3 changes: 3 additions & 0 deletions sc/shared/src/main/scala/sigma/compiler/ir/TreeBuilding.scala
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ trait TreeBuilding extends Base { IR: IRContext =>
case Def(DeserializeContextDef(d, _)) =>
d

case Def(DeserializeRegisterDef(d, _, _)) =>
d

case Def(IsContextProperty(v)) => v
case s if s == sigmaDslBuilder => Global

Expand Down
110 changes: 109 additions & 1 deletion sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package sigmastate.utxo

import org.ergoplatform.ErgoBox.{AdditionalRegisters, R6, R8}
import org.ergoplatform.ErgoBox.{AdditionalRegisters, R4, R6, R8}
import org.ergoplatform._
import sigma.Colls
import sigma.Extensions.ArrayOps
import sigma.ast.SCollection.SByteArray
import sigma.ast.SOption
import sigma.ast.SOption.{OptionTypeConstrId, SIntOption}
import sigma.ast.SType.AnyOps
import sigma.data.{AvlTreeData, CAnyValue, CSigmaDslBuilder}
import sigma.util.StringUtil._
Expand Down Expand Up @@ -203,6 +205,112 @@ class BasicOpsSpecification extends CompilerTestingCommons
)
}

property("executeFromSelfReg - SigmaProp") {
val script = GT(Height, IntConstant(-1)).toSigmaProp
val scriptBytes = ValueSerializer.serialize(script)

val defScript = EQ(Plus(IntConstant(1), IntConstant(5)), 7).toSigmaProp
val defBytes = ValueSerializer.serialize(defScript)

val customExt = Seq(21.toByte -> ByteArrayConstant(defBytes))
val customEnv = Map(
"defaultVal" -> CAnyValue(21.toByte)
)

test("executeFromSelfReg", customEnv, customExt,
"executeFromSelfReg[SigmaProp](4, getVar[SigmaProp](defaultVal))",
null,
true,
additionalRegistersOpt = Some(Map(
reg1 -> ByteArrayConstant(scriptBytes)
))
)
}

property("executeFromSelfReg - Coll[Byte]") {
val bytes = Slice(ByteArrayConstant(Colls.fromArray(Array.fill(5)(1.toByte))), IntConstant(1), IntConstant(3))
val scriptBytes = ValueSerializer.serialize(bytes)

val dval = ByteArrayConstant(Colls.fromArray(Array.fill(3)(1.toByte)))
val defaultBytes = ValueSerializer.serialize(dval)

val customExt = Seq(21.toByte -> ByteArrayConstant(defaultBytes))
val customEnv = Map(
"defaultVal" -> CAnyValue(21.toByte)
)

test("executeFromSelfReg", customEnv, customExt,
"{val ba = executeFromSelfReg[Coll[Byte]](4, getVar[Coll[Byte]](defaultVal)); ba.size == 2 }",
null,
true,
additionalRegistersOpt = Some(Map(
reg1 -> ByteArrayConstant(scriptBytes)
))
)
}

property("executeFromSelfReg - Int") {
val bytes = Plus(IntConstant(2), IntConstant(3))
val scriptBytes = ValueSerializer.serialize(bytes)

test("executeFromSelfReg", env, ext,
"{ executeFromSelfReg[Int](4, getVar[Int](1)) == 5 }",
null,
true,
additionalRegistersOpt = Some(Map(
reg1 -> ByteArrayConstant(scriptBytes)
))
)
}


// executeFromSelfReg failure tests - Most fail the same way as these
// Coll[Bytes] doesn't and attempts to get the default value but fails

property("executeFromSelfReg - IReduct") {
val bytes = Plus(IntConstant(2), IntConstant(3))
val scriptBytes = ValueSerializer.serialize(bytes)

test("executeFromSelfReg", env, ext,
"{ executeFromSelfReg[Int](4, getVar[Int](1)) == 5 }",
null,
true,
additionalRegistersOpt = Some(Map())
)
}

property("executeFromSelfReg - IThrows") {
val bytes = Plus(IntConstant(2), IntConstant(3))
val scriptBytes = ValueSerializer.serialize(bytes)

test("executeFromSelfReg", env, ext,
"{ executeFromSelfReg[Int](4, getVar[Int](1)) == 5 }",
null,
true
)
}

property("executeFromSelfReg - CCorner") {
val bytes = Slice(ByteArrayConstant(Colls.fromArray(Array.fill(5)(1.toByte))), IntConstant(1), IntConstant(3))
val scriptBytes = ValueSerializer.serialize(bytes)

val dval = ByteArrayConstant(Colls.fromArray(Array.fill(3)(1.toByte)))
val defaultBytes = ValueSerializer.serialize(dval)

val customExt = Seq(21.toByte -> ByteArrayConstant(defaultBytes))
val customEnv = Map(
"defaultVal" -> CAnyValue(21.toByte)
)

test("executeFromSelfReg", customEnv, customExt,
"{val ba = executeFromSelfReg[Coll[Byte]](4, getVar[Coll[Byte]](defaultVal)); ba.size == 2 }",
null,
true,
additionalRegistersOpt = Some(Map())
)
}
// end executeFromSelfReg failure tests

property("Relation operations") {
test("R1", env, ext,
"{ allOf(Coll(getVar[Boolean](trueVar).get, true, true)) }",
Expand Down
Loading