-
Notifications
You must be signed in to change notification settings - Fork 42
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
New evaluation and costing #639
Conversation
…ByteArray, ByteArrayToLong, ByteArrayToBigInt, CalcBlake2b256, CalcSha256, SubstConstants
…NoRef, ExtractCreationInfo
…nd, SigmaOr, OR, AND, AtLeast, BinOr, BinAnd, If
val argsV = args.map(a => a.evalTo[Any](E, env)) | ||
f(argsV) | ||
} | ||
// TODO JITC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TO REVIEWER: I added a separate issue #662 to implement all TODO JITC in a separate PR
import sigmastate.lang.SigmaParser | ||
import sigmastate.lang.Terms.OperationId | ||
|
||
case class JitCostTable(operCosts: Map[OperationId, Int]) extends (OperationId => Int) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To reviewer:
This is version is mostly the same as the old CostTable, but the plan is to make completely new Cost Model which better reflect JIT costs.
The main invariant which will be guaranteed is that always JIT cost < AOT cost for all non spam scripts.
This shouldn't be hard to do since existing op costs are very conservative and new costs may be reduced proportional to new JIT interpreter speedup. (e.g. 2-3x)
import sigmastate.utxo.CostTable._ | ||
import special.sigma.{SigmaTestingData, AvlTree} | ||
|
||
class JitCostingSpecification extends SigmaTestingData { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To reviewer:
This spec will be further updated (in separate PR as part of implementing #665)
The old CostingSpecification remains unchanged since the AOT version should remain unchanged.
@@ -3,9 +3,12 @@ package org.ergoplatform | |||
import sigmastate.SCollection.SByteArray | |||
import sigmastate.Values._ | |||
import sigmastate.eval.IRContext | |||
import sigmastate.interpreter.Interpreter | |||
import sigmastate.interpreter.{Interpreter, ErgoTreeEvaluator} | |||
import sigmastate.interpreter.Interpreter.{ScriptEnv, ReductionResult} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused imports added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
import sigmastate.utxo._ | ||
|
||
import scala.util.Try |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused import added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
trait BigIntIsIntegral extends Integral[BigInt] { | ||
def quot(x: BigInt, y: BigInt): BigInt = x.divide(y) | ||
def rem(x: BigInt, y: BigInt): BigInt = x.remainder(y) | ||
def rem(x: BigInt, y: BigInt): BigInt = x.mod(y) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like consensus-breaking change (however, mod is more proper operation, so should be added to 4.0).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added comment
exp.evalTo[Any](this, env) | ||
} | ||
|
||
def addCostOf(opName: String, opType: SFunc) = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please do ScalaDoc for all the public methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -97,10 +118,21 @@ trait Interpreter extends ScorexLogging { | |||
(res, currContext.value) | |||
} | |||
|
|||
// TODO after HF: merge with old version (`applyDeserializeContext`) | |||
def applyDeserializeContextJITC(context: CTX, exp: Value[SType]): (SigmaPropValue, CTX) = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ScalaDoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -83,6 +97,13 @@ trait Interpreter extends ScorexLogging { | |||
case x => throw new Error(s"Context-dependent pre-processing should produce tree of type Boolean or SigmaProp but was $x") | |||
} | |||
|
|||
// TODO after HF: merge with old version (`toValidScriptType`) | |||
def toValidScriptTypeJITC(exp: SValue): SigmaPropValue = exp match { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ScalaDoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is helper, made it private.
import sigmastate.lang.SigmaParser | ||
import sigmastate.lang.Terms.OperationId | ||
|
||
case class JitCostTable(operCosts: Map[OperationId, Int]) extends (OperationId => Int) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ScalaDoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class removed
|
||
import sigmastate.utxo.JitCostTable | ||
|
||
def costOf(opName: String, opType: SFunc): Int = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do ScalaDoc for all the public methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
methods removed
# Conflicts: # build.sbt # sigma-api/src/main/scala/special/sigma/SigmaDsl.scala # sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala # sigmastate/src/main/scala/sigmastate/Values.scala # sigmastate/src/main/scala/sigmastate/eval/BigIntegerOps.scala # sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala # sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala # sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala # sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala # sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala # sigmastate/src/main/scala/sigmastate/lang/Terms.scala # sigmastate/src/main/scala/sigmastate/serialization/ConstantPlaceholderSerializer.scala # sigmastate/src/main/scala/sigmastate/trees.scala # sigmastate/src/main/scala/sigmastate/types.scala # sigmastate/src/main/scala/sigmastate/utxo/transformers.scala # sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala # sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala # sigmastate/src/test/scala/special/sigma/SigmaDslTest.scala
The work continues in #699, as the approach to costing will be slightly different. |
Motivation
ErgoTree is simple declarative intermediate representation for Ergo contracts.
It is designed to be compact in serialized form and directly executable, i.e. no additional transformation is necessary before it can be efficiently executed.
This PR implements big-step recursive ErgoTreeEvaluator that works directly with ErgoTree.
Because of this the evaluator is very simple and follows denotational semantics of ErgoTree.
Or, the other way around, this implementation of ErgoTreeEvaluator is purely functional with immutable data structures and can be used as definition of ErgoTree's semantics.
Implementation
ErgoTreeEvaluator takes ErgoTree directly as it is deserialized as part of a transaction.
No additional transformations is performed.
ErgoTree is interpreted directly and all intermediate data are stored in runtime types.
Runtime types are such types as Coll, SigmaProp, AvlTree, BigInt, etc.
It also use immutable Map to keep current DataEnv of computed ValDefs, as a result only the addition operation is used from the map, and the deletion is essentially done by the garbage collection.
Performance
Since this interpreter directly works with SigmaDsl types (Coll, BigInt, SigmaProp etc), it turns out to be fast.
Since it also does JIT style costing instead of AOT style, it is 5-6x faster then existing implementation.
Milestone
New evaluation of ErgoTree required changes in how isProven handled.
In particular isProven is not supported in ErgoTree that is passed to prove/verify methods.
This required changes in tests and also in the coverage report.
Unfortunately those changes may break the consensus, because isProven can be serialized and present in ErgoTree.
This prevents ErgoTreeEvaluator to be used in v3.x