diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index f46c39e900..b702f64c5a 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -7,19 +7,17 @@ import org.bitbucket.inkytonik.kiama.rewriting.Strategy import org.ergoplatform.ErgoLikeContext import org.ergoplatform.validation.SigmaValidationSettings import org.ergoplatform.validation.ValidationRules._ -import sigmastate.basics.DLogProtocol.ProveDlog import scorex.util.ScorexLogging import sigmastate.SCollection.SByteArray import sigmastate.Values._ -import sigmastate.basics.DLogProtocol.{DLogInteractiveProver, FirstDLogProverMessage} +import sigmastate.basics.DLogProtocol.{ProveDlog, DLogInteractiveProver, FirstDLogProverMessage} import sigmastate.basics._ import sigmastate.interpreter.Interpreter._ import sigmastate.lang.exceptions.InterpreterException import sigmastate.serialization.{SigmaSerializer, ValueSerializer} import sigmastate.utxo.DeserializeContext import sigmastate.{SType, _} -import sigmastate.eval.{Evaluation, IRContext, Profiler} -import scalan.util.BenchmarkUtil +import sigmastate.eval.{Evaluation, Profiler, IRContext} import sigmastate.FiatShamirTree._ import sigmastate.SigSerializer._ import sigmastate.eval.Evaluation.addCostChecked @@ -29,7 +27,7 @@ import sigmastate.utils.Helpers._ import sigmastate.lang.Terms.ValueOps import spire.syntax.all.cfor -import scala.util.{Success, Try} +import scala.util.{Try, Success} /** Base (verifying) interpreter of ErgoTrees. * Can perform: diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala index 81d1825072..cebfc366dc 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala @@ -4,7 +4,7 @@ import fastparse.core.Parsed import fastparse.core.Parsed.Success import org.ergoplatform.ErgoAddressEncoder.NetworkPrefix import sigmastate.SType -import sigmastate.Values.{Value, SValue} +import sigmastate.Values.{SValue, Value} import sigmastate.eval.IRContext import sigmastate.interpreter.Interpreter.ScriptEnv import sigmastate.lang.SigmaPredef.PredefinedFuncRegistry @@ -26,7 +26,11 @@ case class CompilerSettings( lowerMethodCalls: Boolean ) +/** Compiler which compiles ErgoScript source code into ErgoTree. + * @param settings compilation parameters \ + */ class SigmaCompiler(settings: CompilerSettings) { + /** Constructs an instance for the given network type and with default settings. */ def this(networkPrefix: Byte) = this( CompilerSettings(networkPrefix, TransformingSigmaBuilder, lowerMethodCalls = true) ) diff --git a/sigmastate/src/main/scala/sigmastate/lang/exceptions/Exceptions.scala b/sigmastate/src/main/scala/sigmastate/lang/exceptions/Exceptions.scala index a07eab52c8..285baf6c26 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/exceptions/Exceptions.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/exceptions/Exceptions.scala @@ -3,6 +3,7 @@ package sigmastate.lang.exceptions import sigmastate.JitCost import sigmastate.lang.SourceContext +/** Base class of all exceptions thrown from various Sigma components. */ class SigmaException(val message: String, val source: Option[SourceContext] = None, val cause: Option[Throwable] = None) extends Exception(message, cause.orNull) { @@ -13,33 +14,42 @@ class SigmaException(val message: String, val source: Option[SourceContext] = No }.getOrElse(message) } +/** Exception thrown by the [[sigmastate.lang.SigmaBinder]]. */ class BinderException(message: String, source: Option[SourceContext] = None) extends SigmaException(message, source) +/** Exception thrown by the [[sigmastate.lang.SigmaTyper]]. */ class TyperException(message: String, source: Option[SourceContext] = None) extends SigmaException(message, source) +/** Exception thrown by the [[sigmastate.lang.SigmaSpecializer]]. */ class SpecializerException(message: String, source: Option[SourceContext] = None) extends SigmaException(message, source) +/** Exception thrown by the [[sigmastate.serialization.SigmaSerializer]]. */ case class SerializerException( override val message: String, override val source: Option[SourceContext] = None, override val cause: Option[Throwable] = None) extends SigmaException(message, source, cause) +/** Exception thrown by the [[sigmastate.lang.SigmaBuilder]]. */ class BuilderException(message: String, source: Option[SourceContext] = None) extends SigmaException(message, source) +/** Exception thrown by interpreter during cost estimation. */ class CosterException(message: String, source: Option[SourceContext], cause: Option[Throwable] = None) extends SigmaException(message, source, cause) +/** Exception thrown by [[sigmastate.interpreter.Interpreter]]. */ class InterpreterException(message: String, source: Option[SourceContext] = None, cause: Option[Throwable] = None) extends SigmaException(message, source, cause) +/** Exception thrown by [[sigmastate.interpreter.Interpreter]] when cost limit is exceeded. */ class CostLimitException(val estimatedCost: Long, message: String, cause: Option[Throwable] = None) extends SigmaException(message, None, cause) object CostLimitException { + /** Formats the error message with the given parameters. */ def msgCostLimitError(cost: JitCost, limit: JitCost) = s"Estimated execution cost $cost exceeds the limit $limit" } diff --git a/sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala index e061721fd2..a7373b0d53 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala @@ -1,9 +1,9 @@ package sigmastate.serialization -import sigmastate.{ArgInfo, SType} +import sigmastate.{SType, ArgInfo} import sigmastate.Values._ -import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} -import ValueSerializer._ +import sigmastate.utils.{SigmaByteWriter, SigmaByteReader} +import sigmastate.serialization.ValueSerializer._ import sigmastate.util.safeNewArray import sigmastate.utils.SigmaByteWriter.{DataInfo, U} import spire.syntax.all.cfor @@ -25,7 +25,9 @@ case class TupleSerializer(cons: Seq[Value[SType]] => Value[SType]) override def parse(r: SigmaByteReader): Value[SType] = { val size = r.getByte() - val values = safeNewArray[SValue](size) // assume size > 0 so always create a new array + // note, in v4.x, v5.x tuples always has 2 elements, this may change in v6.0 + // in which case allocation can be avoided for empty tuples + val values = safeNewArray[SValue](size) cfor(0)(_ < size, _ + 1) { i => values(i) = r.getValue() } diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala index 447c111eca..40b8d64786 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala @@ -8,7 +8,7 @@ import sigmastate._ import sigmastate.lang.DeserializationSigmaBuilder import sigmastate.serialization.OpCodes._ import sigmastate.serialization.transformers._ -import sigmastate.serialization.trees.{QuadrupleSerializer, Relation2Serializer} +import sigmastate.serialization.trees.{Relation2Serializer, QuadrupleSerializer} import scalan.util.Extensions._ import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils._ @@ -30,6 +30,14 @@ abstract class ValueSerializer[V <: Value[SType]] extends SigmaSerializer[Value[ @inline final def opCode: OpCode = opDesc.opCode } +/** Implements serialization of ErgoTree expressions. Contains global collection of + * serializers for each ErgoTree operation (see `serializers` field). + * + * It also implements optional (see collectSerInfo flag) metadata collection during serialization + * to generate serializer specification tables in LaTeX. + * + * @see GenSerializers + */ object ValueSerializer extends SigmaSerializerCompanion[Value[SType]] { type Tag = OpCode @@ -347,7 +355,7 @@ object ValueSerializer extends SigmaSerializerCompanion[Value[SType]] { } } - // TODO v5.x: control maxTreeDepth same as in deserialize + // TODO v5.x: control maxTreeDepth same as in deserialize (see Reader.level property and SigmaSerializer.MaxTreeDepth) override def serialize(v: Value[SType], w: SigmaByteWriter): Unit = serializable(v) match { case c: Constant[SType] => w.constantExtractionStore match {