Skip to content

Commit

Permalink
fix-i778: more detailed message on assertion
Browse files Browse the repository at this point in the history
  • Loading branch information
aslesarenko committed Apr 20, 2022
1 parent af1c323 commit 20a9d63
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
17 changes: 12 additions & 5 deletions sigmastate/src/main/scala/sigmastate/eval/IRContext.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package sigmastate.eval

import java.lang.{Math => JMath}
import sigmastate.SType
import sigmastate.Values.{Value, SValue}
import sigmastate.Values.{SValue, Value}
import sigmastate.interpreter.Interpreter.ScriptEnv
import sigmastate.lang.TransformingSigmaBuilder
import sigmastate.lang.exceptions.CostLimitException
import sigmastate.utils.Helpers
import sigmastate.utxo.CostTable

import java.util.concurrent.locks.ReentrantLock
import scala.util.Try

trait IRContext extends Evaluation with TreeBuilding {

override val builder = TransformingSigmaBuilder

/** Can be used to synchronize access to this IR object from multiple threads. */
val lock = new ReentrantLock()

/** Pass configuration which is used to turn-off constant propagation.
* @see `beginPass(noCostPropagationPass)` */
lazy val noConstPropagationPass = new DefaultPass(
Expand Down Expand Up @@ -125,9 +129,12 @@ trait IRContext extends Evaluation with TreeBuilding {
*/
def checkCostWithContext(ctx: SContext,
costF: Ref[((Context, (Int, Size[Context]))) => Int], maxCost: Long, initCost: Long): Try[Int] = Try {
val costFun = compile[(SContext, (Int, SSize[SContext])), Int, (Context, (Int, Size[Context])), Int](
getDataEnv, costF, Some(maxCost))
val (estimatedCost, accCost) = costFun((ctx, (0, Sized.sizeOf(ctx))))

val (estimatedCost, accCost) = Helpers.withReentrantLock(lock) { // protect mutable access to this IR
val costFun = compile[(SContext, (Int, SSize[SContext])), Int, (Context, (Int, Size[Context])), Int](
getDataEnv, costF, Some(maxCost))
costFun((ctx, (0, Sized.sizeOf(ctx))))
}

if (debugModeSanityChecks) {
if (estimatedCost != accCost)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ package sigmastate.interpreter

import java.util.concurrent.ExecutionException
import java.util.concurrent.atomic.AtomicInteger

import com.google.common.cache.{CacheBuilder, RemovalNotification, RemovalListener, LoadingCache, CacheLoader, CacheStats}
import com.google.common.cache.{CacheBuilder, CacheLoader, CacheStats, LoadingCache, RemovalListener, RemovalNotification}
import org.ergoplatform.settings.ErgoAlgos
import org.ergoplatform.validation.SigmaValidationSettings
import org.ergoplatform.validation.ValidationRules.{CheckCostFunc, CheckCalcFunc, trySoftForkable}
import org.ergoplatform.validation.ValidationRules.{CheckCalcFunc, CheckCostFunc, trySoftForkable}
import scalan.{AVHashMap, Nullable}
import sigmastate.Values
import sigmastate.Values.ErgoTree
import sigmastate.eval.{RuntimeIRContext, IRContext}
import sigmastate.eval.{IRContext, RuntimeIRContext}
import sigmastate.interpreter.Interpreter.{ReductionResult, WhenSoftForkReductionResult}
import sigmastate.serialization.ErgoTreeSerializer
import sigmastate.utils.Helpers
import sigmastate.utils.Helpers._
import spire.syntax.all.cfor

Expand Down Expand Up @@ -84,9 +84,11 @@ case class PrecompiledScriptReducer(scriptBytes: Seq[Byte])(implicit val IR: IRC
val estimatedCost = IR.checkCostWithContext(costingCtx, costF, maxCost, initCost).getOrThrow

// check calc
val calcF = costingRes.calcF
val calcCtx = context.toSigmaContext(isCost = false)
val res = Interpreter.calcResult(IR)(calcCtx, calcF)
val res = Helpers.withReentrantLock(IR.lock) { // protecting mutable access to IR instance
val calcF = costingRes.calcF
Interpreter.calcResult(IR)(calcCtx, calcF)
}
ReductionResult(SigmaDsl.toSigmaBoolean(res), estimatedCost)
}
}
Expand Down
25 changes: 23 additions & 2 deletions sigmastate/src/main/scala/sigmastate/utils/Helpers.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package sigmastate.utils

import java.util

import io.circe.Decoder
import org.ergoplatform.settings.ErgoAlgos
import sigmastate.eval.{Colls, SigmaDsl}
import sigmastate.interpreter.CryptoConstants.EcPointType
import special.collection.Coll
import special.sigma.GroupElement

import java.util.concurrent.locks.{Lock, ReentrantLock}
import scala.reflect.ClassTag
import scala.util.{Failure, Try, Either, Success, Right}
import scala.util.{Either, Failure, Right, Success, Try}

object Helpers {
def xor(ba1: Array[Byte], ba2: Array[Byte]): Array[Byte] = ba1.zip(ba2).map(t => (t._1 ^ t._2).toByte)
Expand Down Expand Up @@ -158,6 +158,27 @@ object Helpers {
val bytes = ErgoAlgos.decodeUnsafe(base16String)
Colls.fromArray(bytes)
}

/**
* Executes the given block with a reentrant mutual exclusion Lock with the same basic
* behavior and semantics as the implicit monitor lock accessed using synchronized
* methods and statements in Java.
*
* Note, using this method has an advantage of having this method in a stack trace in case of
* an exception in the block.
* @param l lock object which should be acquired by the current thread before block can start executing
* @param block block of code which will be executed retaining the lock
* @return the value produced by the block
*/
def withReentrantLock[A](l: Lock)(block: => A): A = {
l.lock()
val res = try
block
finally {
l.unlock()
}
res
}
}

object Overloading {
Expand Down

0 comments on commit 20a9d63

Please sign in to comment.