From 8fb2f3f24a2f462c7982fc9c5a907bde7e423b4d Mon Sep 17 00:00:00 2001 From: Samdish Date: Tue, 7 Nov 2023 19:30:58 +0530 Subject: [PATCH 1/5] Add flag isUsingBlockchainContext to ErgoTree --- .../src/main/scala/sigma/ast/ErgoTree.scala | 14 +++ .../src/main/scala/sigma/ast/values.scala | 25 +++++ .../sigmastate/ErgoTreeSpecification.scala | 98 +++++++++++++++++++ 3 files changed, 137 insertions(+) diff --git a/data/shared/src/main/scala/sigma/ast/ErgoTree.scala b/data/shared/src/main/scala/sigma/ast/ErgoTree.scala index 1340ca4128..3210cb1ec6 100644 --- a/data/shared/src/main/scala/sigma/ast/ErgoTree.scala +++ b/data/shared/src/main/scala/sigma/ast/ErgoTree.scala @@ -163,6 +163,20 @@ case class ErgoTree private[sigma]( _hasDeserialize.get } + private[sigma] var _isUsingBlockchainContext: Option[Boolean] = None + + /** Returns true if the tree depends on the blockchain context. + */ + lazy val isUsingBlockchainContext: Boolean = { + if (_isUsingBlockchainContext.isEmpty) { + _isUsingBlockchainContext = Some(root match { + case Right(p) => Value.isUsingBlockchainContext(p) + case _ => false + }) + } + _isUsingBlockchainContext.get + } + /** Serialized proposition expression of SigmaProp type with * ConstantPlaceholder nodes not replaced by Constant nodes. */ diff --git a/data/shared/src/main/scala/sigma/ast/values.scala b/data/shared/src/main/scala/sigma/ast/values.scala index 1ded9d6b5c..4618ccaf9d 100644 --- a/data/shared/src/main/scala/sigma/ast/values.scala +++ b/data/shared/src/main/scala/sigma/ast/values.scala @@ -210,6 +210,31 @@ object Value { c > 0 } + /** Traverses the given expression tree and counts the number of operations + * which read the blockchain context. If it is non-zero, returns true. */ + def isUsingBlockchainContext(exp: SValue): Boolean = { + val blockchainContextNode: PartialFunction[Any, Int] = { + case Height => 1 + case LastBlockUtxoRootHash => 1 + case MinerPubkey => 1 + case MethodCall(obj, method, _, _) => + (obj, method.objType) match { + case (_, SContextMethods) => method.name match { + case SContextMethods.headersMethod.name => 1 + case SContextMethods.preHeaderMethod.name => 1 + case SContextMethods.preHeaderMethod.name => 1 + case SContextMethods.heightMethod.name => 1 + case SContextMethods.lastBlockUtxoRootHashMethod.name => 1 + case SContextMethods.minerPubKeyMethod.name => 1 + case _ => 0 + } + case _ => 0 + } + } + val c = count(blockchainContextNode)(exp) + c > 0 + } + def typeError(node: SValue, evalResult: Any) = { val tpe = node.tpe throw new InterpreterException( diff --git a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala index 938de5d836..b0b6273fad 100644 --- a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala @@ -140,6 +140,104 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { } } + property("ErgoTree.isUsingBlockchainContext") { + { + val t = new ErgoTree( + HeaderType @@ 0.toByte, + Array[Constant[SType]](), + Right(TrueSigmaProp)) + t._isUsingBlockchainContext shouldBe None + t.isUsingBlockchainContext shouldBe false + } + + { + val t = new ErgoTree( + HeaderType @@ 16.toByte, + Array(IntConstant(1)), + Right(BoolToSigmaProp(GT(Height, ConstantPlaceholder(0, SInt)))) + ) + t._isUsingBlockchainContext shouldBe None + t.isUsingBlockchainContext shouldBe true + } + + { + val t = new ErgoTree( + HeaderType @@ 16.toByte, + Vector(), + Right(OptionIsDefined(IR.builder.mkMethodCall( + LastBlockUtxoRootHash, SAvlTreeMethods.getMethod, + IndexedSeq(ExtractId(GetVarBox(22: Byte).get), GetVarByteArray(23: Byte).get)).asOption[SByteArray])) + ) + t._isUsingBlockchainContext shouldBe None + t.isUsingBlockchainContext shouldBe true + } + + { + val t = new ErgoTree( + HeaderType @@ 16.toByte, + Vector(), + Right(BoolToSigmaProp(EQ(MinerPubkey, ErgoLikeContextTesting.dummyPubkey))) + ) + t._isUsingBlockchainContext shouldBe None + t.isUsingBlockchainContext shouldBe true + } + + { + val t = new ErgoTree( + HeaderType @@ 16.toByte, + Vector(), + Right(OptionIsDefined(IR.builder.mkMethodCall( + Context, SContextMethods.headersMethod, Vector()).asOption[SByteArray])) + ) + t._isUsingBlockchainContext shouldBe None + t.isUsingBlockchainContext shouldBe true + } + + { + val t = new ErgoTree( + HeaderType @@ 16.toByte, + Vector(), + Right(OptionIsDefined(IR.builder.mkMethodCall( + Context, SContextMethods.preHeaderMethod, Vector()).asOption[SByteArray])) + ) + t._isUsingBlockchainContext shouldBe None + t.isUsingBlockchainContext shouldBe true + } + + { + val t = new ErgoTree( + HeaderType @@ 16.toByte, + Vector(), + Right(OptionIsDefined(IR.builder.mkMethodCall( + Context, SContextMethods.heightMethod, Vector()).asOption[SByteArray])) + ) + t._isUsingBlockchainContext shouldBe None + t.isUsingBlockchainContext shouldBe true + } + + { + val t = new ErgoTree( + HeaderType @@ 16.toByte, + Vector(), + Right(OptionIsDefined(IR.builder.mkMethodCall( + Context, SContextMethods.lastBlockUtxoRootHashMethod, Vector()).asOption[SByteArray])) + ) + t._isUsingBlockchainContext shouldBe None + t.isUsingBlockchainContext shouldBe true + } + + { + val t = new ErgoTree( + HeaderType @@ 16.toByte, + Vector(), + Right(OptionIsDefined(IR.builder.mkMethodCall( + Context, SContextMethods.minerPubKeyMethod, Vector()).asOption[SByteArray])) + ) + t._isUsingBlockchainContext shouldBe None + t.isUsingBlockchainContext shouldBe true + } + } + property("ErgoTree equality") { val t1 = new ErgoTree( HeaderType @@ 16.toByte, From 44844ac15a528fb8afbf132f469468a25237d5dd Mon Sep 17 00:00:00 2001 From: Samdish Date: Tue, 7 Nov 2023 21:36:23 +0530 Subject: [PATCH 2/5] Populate isUsingBlockchainContext during parsing --- .../scala/sigma/serialization/CoreByteReader.scala | 8 ++++++++ data/shared/src/main/scala/sigma/ast/ErgoTree.scala | 10 ++++++---- data/shared/src/main/scala/sigma/ast/values.scala | 1 - .../serialization/CaseObjectSerialization.scala | 13 ++++++++++--- .../sigma/serialization/ErgoTreeSerializer.scala | 10 ++++++++-- .../sigma/serialization/MethodCallSerializer.scala | 13 +++++++++++-- .../scala/sigmastate/ErgoTreeSpecification.scala | 6 +++--- .../ErgoTreeSerializerSpecification.scala | 2 +- 8 files changed, 47 insertions(+), 16 deletions(-) diff --git a/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala b/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala index e5c2e574ca..d89015c82d 100644 --- a/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala +++ b/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala @@ -157,4 +157,12 @@ class CoreByteReader(val r: Reader, val maxTreeDepth: Int = CoreSerializer.MaxTr @inline final def wasDeserialize_=(v: Boolean): Unit = { _wasDeserialize = v } + + private var _wasUsingBlockchainContext: Boolean = false + /** Helper property which is used to track operations using the blockchain context during parsing. */ + @inline final def wasUsingBlockchainContext: Boolean = _wasUsingBlockchainContext + + @inline final def wasUsingBlockchainContext_=(v: Boolean): Unit = { + wasUsingBlockchainContext = v + } } diff --git a/data/shared/src/main/scala/sigma/ast/ErgoTree.scala b/data/shared/src/main/scala/sigma/ast/ErgoTree.scala index 3210cb1ec6..1108fede2d 100644 --- a/data/shared/src/main/scala/sigma/ast/ErgoTree.scala +++ b/data/shared/src/main/scala/sigma/ast/ErgoTree.scala @@ -90,7 +90,8 @@ case class ErgoTree private[sigma]( root: Either[UnparsedErgoTree, SigmaPropValue], private val givenComplexity: Int, private val propositionBytes: Array[Byte], - private val givenDeserialize: Option[Boolean] + private val givenDeserialize: Option[Boolean], + private val givenIsUsingBlockchainContext: Option[Boolean] ) { def this( header: HeaderType, @@ -99,9 +100,10 @@ case class ErgoTree private[sigma]( this( header, constants, root, 0, propositionBytes = DefaultSerializer.serializeErgoTree( - ErgoTree(header, constants, root, 0, null, None) + ErgoTree(header, constants, root, 0, null, None, None) ), - givenDeserialize = None + givenDeserialize = None, + givenIsUsingBlockchainContext = None ) require(isConstantSegregation || constants.isEmpty) @@ -163,7 +165,7 @@ case class ErgoTree private[sigma]( _hasDeserialize.get } - private[sigma] var _isUsingBlockchainContext: Option[Boolean] = None + private[sigma] var _isUsingBlockchainContext: Option[Boolean] = givenIsUsingBlockchainContext /** Returns true if the tree depends on the blockchain context. */ diff --git a/data/shared/src/main/scala/sigma/ast/values.scala b/data/shared/src/main/scala/sigma/ast/values.scala index 4618ccaf9d..0a2b8a3d43 100644 --- a/data/shared/src/main/scala/sigma/ast/values.scala +++ b/data/shared/src/main/scala/sigma/ast/values.scala @@ -222,7 +222,6 @@ object Value { case (_, SContextMethods) => method.name match { case SContextMethods.headersMethod.name => 1 case SContextMethods.preHeaderMethod.name => 1 - case SContextMethods.preHeaderMethod.name => 1 case SContextMethods.heightMethod.name => 1 case SContextMethods.lastBlockUtxoRootHashMethod.name => 1 case SContextMethods.minerPubKeyMethod.name => 1 diff --git a/data/shared/src/main/scala/sigma/serialization/CaseObjectSerialization.scala b/data/shared/src/main/scala/sigma/serialization/CaseObjectSerialization.scala index 56efa0bd52..b3b968af1c 100644 --- a/data/shared/src/main/scala/sigma/serialization/CaseObjectSerialization.scala +++ b/data/shared/src/main/scala/sigma/serialization/CaseObjectSerialization.scala @@ -1,12 +1,19 @@ package sigma.serialization -import sigma.ast.SType -import sigma.ast.{Value, ValueCompanion} +import sigma.ast.{Height, LastBlockUtxoRootHash, MinerPubkey, SType, Value, ValueCompanion} case class CaseObjectSerialization[V <: Value[SType]](override val opDesc: ValueCompanion, obj: V) extends ValueSerializer[V] { override def serialize(obj: V, w: SigmaByteWriter): Unit = () - override def parse(r: SigmaByteReader): V = obj + override def parse(r: SigmaByteReader): V = { + opDesc match { + case Height => r.wasUsingBlockchainContext = true + case LastBlockUtxoRootHash => r.wasUsingBlockchainContext = true + case MinerPubkey => r.wasUsingBlockchainContext = true + } + + obj + } } diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 820c3a70a5..df9a288257 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -150,10 +150,16 @@ class ErgoTreeSerializer { val wasDeserialize_saved = r.wasDeserialize r.wasDeserialize = false + val wasUsingBlockchainContext_saved = r.wasUsingBlockchainContext + r.wasUsingBlockchainContext = false + val root = ValueSerializer.deserialize(r) val hasDeserialize = r.wasDeserialize // == true if there was deserialization node r.wasDeserialize = wasDeserialize_saved + val isUsingBlockchainContext = r.wasUsingBlockchainContext // == true if there was a node using the blockchain context + r.wasUsingBlockchainContext = wasUsingBlockchainContext_saved + if (checkType) { CheckDeserializedScriptIsSigmaProp(root) } @@ -168,7 +174,7 @@ class ErgoTreeSerializer { new ErgoTree( h, cs, Right(root.asSigmaProp), complexity, - propositionBytes, Some(hasDeserialize)) + propositionBytes, Some(hasDeserialize), Some(isUsingBlockchainContext)) } catch { case e: ReaderPositionLimitExceeded => @@ -183,7 +189,7 @@ class ErgoTreeSerializer { r.position = startPos val bytes = r.getBytes(numBytes) val complexity = ComplexityTable.OpCodeComplexity(Constant.opCode) - new ErgoTree(ErgoTree.DefaultHeader, EmptyConstants, Left(UnparsedErgoTree(bytes, ve)), complexity, bytes, None) + new ErgoTree(ErgoTree.DefaultHeader, EmptyConstants, Left(UnparsedErgoTree(bytes, ve)), complexity, bytes, None, None) case None => throw new SerializerException( s"Cannot handle ValidationException, ErgoTree serialized without size bit.", Some(ve)) diff --git a/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala b/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala index 49ea712e80..17028ffa0b 100644 --- a/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala @@ -1,11 +1,10 @@ package sigma.serialization import sigma.ast.syntax._ -import sigma.ast.MethodCall +import sigma.ast.{ComplexityTable, MethodCall, SContextMethods, SMethod, SType, STypeSubst, Value, ValueCompanion} import sigma.util.safeNewArray import SigmaByteWriter._ import debox.cfor -import sigma.ast.{ComplexityTable, SMethod, SType, STypeSubst, Value, ValueCompanion} import sigma.serialization.CoreByteWriter.{ArgInfo, DataInfo} case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[SType]], STypeSubst) => Value[SType]) @@ -60,6 +59,16 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S } val specMethod = method.specializeFor(obj.tpe, types) + + var isUsingBlockchainContext = specMethod.objType == SContextMethods && ( + method.name == SContextMethods.headersMethod.name || + method.name == SContextMethods.preHeaderMethod.name || + method.name == SContextMethods.heightMethod.name || + method.name == SContextMethods.lastBlockUtxoRootHashMethod.name || + method.name == SContextMethods.minerPubKeyMethod.name + ) + r.wasUsingBlockchainContext ||= isUsingBlockchainContext + cons(obj, specMethod, args, Map.empty) } } diff --git a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala index b0b6273fad..ae7f4a3656 100644 --- a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala @@ -826,7 +826,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { val addr = ErgoAddressEncoder.Mainnet.fromString("3ehvg9kjzVt2ep6VkYbsNZBXVoFjQA3b26LTmCwvE9vTUEU2TG1uKdqh7sb1a23G1HLkXa6rv4NUcR5Ucghp8CTuBnUxJB4qYq61GYNDFmCHdoZJq32vUVJ7Jsq4cFE7zp9ddFnchb8EN2Qkaa9rqzmruj4iKjLu8MMJ3V8ns1tpRF8eSp2KSjPuMYt6ZHysFNGoMt4dQ2P45YoCXbgiJtzcADgjMnr5bkpqKMx2ZEaAUWoZfHN8DUwvNawSCr2yHieHKbWujxeGuPUuGPAdJHQRcC47xpBj7rKExxGE6T117vAAzSwc98UG3CC8Lb8UeoE7WWi9LCTdXqJpJFrwb8Zqc9HnqSVRvAxeaKgcueX36absXAxpqpAGUcH8YwYoeVmSYLsQKQbUAVrFe73eJyRtgxpcVEqrs4rBZ3KeDJUe5J2NJTNYKoUFcruqqu4N1XUFCECWXANsE9TLoQNyqDgNRcnHE4t8nw6THPJXQWCTBHK6mHvkVcj6SvGinvVGfMpeuA8MF1FFtZJTMnM31cuMBexK3m5mDxsbamJngQiPrcyVqK4smDpdiqhds7APGJbwKTHgst2u1P6").getOrThrow val tree = addr.script tree match { - case ErgoTree(_, _, Right(BlockValueWithInvalidBoolToSigmaProp(_)), _, _, _) => + case ErgoTree(_, _, Right(BlockValueWithInvalidBoolToSigmaProp(_)), _, _, _, _) => } } @@ -839,7 +839,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { val addr = ErgoAddressEncoder.Mainnet.fromString("bpn7HXccD8wzY3x8XbymfBCh71aeci1FyM7JJgVx6mVY3vxznf2Pom7gtEgQBxr9UZb8cn9Z6GiXEjV7mB7ypRfH9Qpf3eCsd8qoEGmvsFqW2GyEvxgYWnJGd8QYTYZLBgGkSFcAeerLLDZwS1bos5oV4atMLnPDUJ6bH2EFFwVRdTAQKxaVMAhNtNYZxAcYtWhaYBJqYZM8ne3hGFrkWNTgNy7NxEDQ5LpBEM3rq6EqUENAGhH6THDL7RyU8AMkpr2vhosqEeqp4yXJmK887vU4qbnGGrMLX4w5GrgL9zLk41Vm6vzEUVLvp8XQJ8CULwkHNiKkNHRLeTk6BG4hwJsFoUSJJNWgsfputm8pEbaTuKfNG5u4NFmZ3YLfGsrqpr62c95QuNuD3g3FaoBUhxigkfNhKwFFtpKKsYerJvvp2Suh2eVRptFsCN15pjdkveUakhFsAo9j9YwhYVjjPpCWZgB8Wme8iZLRVfopSuDVdiqGsnmpJcuccmPsebgXPz3XvyjQazYE7WnR3Jrr1mRWHVEnJb3UU89JVPDpJPP1jUaSqmkKCkrPj3WMMQTDg17WW2DkhGKsb").getOrThrow val tree = addr.script tree match { - case ErgoTree(_, _, Right(BlockValueWithInvalidBoolToSigmaProp(_)), _, _, _) => + case ErgoTree(_, _, Right(BlockValueWithInvalidBoolToSigmaProp(_)), _, _, _, _) => } } @@ -863,7 +863,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { val addr = ErgoAddressEncoder.Mainnet.fromString("9drgw9DeDxHwdwYWT11yrYD3qCN3fzgnjA3eS5ZXEkR2Rrpd2x58R3HFViGAs93hYFqroBGShW5DG6h2tU7PqDURegny88hEhNKfLpWKBHpLMmfDwZwTM75MuYKXkmtyUmiMRAfGAVVjaSqThddra5ykZ4UrG8kgqkHSBTxtibVPmNff8Fx7Fy5q82xsZ95RFpjGkAX1QgtirHc3JP6QDZfHUFPx2gnyT9pDpYrKWEhjK8Ake779PoYqGzrL5gtuHyLqsC3WtLFMvP3QNfVtwPaqeCLEmjFmWYU6MV1A8fTJxGWDByiCMnva9wDgZgLh8wrSwttEGE9XHiZaWxWNWqVM8Ypn8aW8x8mKSjxQjF1BNxV41JTeGEMFDvY2HaNYgGbQhBbrTXFq9cvxuzPgXHtfwcbb2kiytr3YBCz8eNmbzp73LSKzRk4AFaTiTdFSSWJe72uLAurQTQBTzAzVgPptGWfrhMWmHCkN5qXQMpUQWNsCzwqRHeZzpSMVtWTyrBCGsbyuPitbukdLHZ8Wee7DtCy8j4Gkhewrwn23jVQu1ApN4uGAFEa29AL26bsMGD7tdu1StE9CKRVzbfEknaReqv6").getOrThrow val tree = addr.script tree match { - case ErgoTree(_, _, Right(BlockValueWithInvalidBoolToSigmaProp(_)), _, _, _) => + case ErgoTree(_, _, Right(BlockValueWithInvalidBoolToSigmaProp(_)), _, _, _, _) => } val lines = SigmaPPrint.tokenize(tree, 150, 300) if (printDebugInfo) { diff --git a/sc/shared/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala b/sc/shared/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala index fff1d40c61..e439b1a89d 100644 --- a/sc/shared/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala @@ -217,7 +217,7 @@ class ErgoTreeSerializerSpecification extends SerializationSpecification property("SigmaProp.propBytes vs ErgoTree.serializer equivalence") { forAll(MinSuccessful(100)) { sp: SigmaProp => val propBytes = sp.propBytes - val ergoTree = new ErgoTree(ErgoTree.DefaultHeader, EmptyConstants, Right(sp.toSigmaBoolean.toSigmaPropValue), 0, null, None) + val ergoTree = new ErgoTree(ErgoTree.DefaultHeader, EmptyConstants, Right(sp.toSigmaBoolean.toSigmaPropValue), 0, null, None, None) val treeBytes = DefaultSerializer.serializeErgoTree(ergoTree) treeBytes shouldBe propBytes.toArray } From 22f058625a15767926d53b23ce5812a0e78a7845 Mon Sep 17 00:00:00 2001 From: Samdish Date: Tue, 14 Nov 2023 17:08:16 +0530 Subject: [PATCH 3/5] Cache and use the method names --- .../shared/src/main/scala/sigma/ast/methods.scala | 7 +++++++ data/shared/src/main/scala/sigma/ast/values.scala | 15 +++++---------- .../serialization/MethodCallSerializer.scala | 10 +++------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index 2173438fd5..b637acf792 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -1408,6 +1408,13 @@ case object SContextMethods extends MonoTypeMethods { dataInputsMethod, headersMethod, preHeaderMethod, inputsMethod, outputsMethod, heightMethod, selfMethod, selfBoxIndexMethod, lastBlockUtxoRootHashMethod, minerPubKeyMethod, getVarMethod ) + + /** Names of methods which provide blockchain context. + * This value can be reused where necessary to avoid allocations. */ + val BlockchainContextMethodNames: IndexedSeq[String] = Array( + headersMethod.name, preHeaderMethod.name, heightMethod.name, + lastBlockUtxoRootHashMethod.name, minerPubKeyMethod.name + ) } /** Type descriptor of `Header` type of ErgoTree. */ diff --git a/data/shared/src/main/scala/sigma/ast/values.scala b/data/shared/src/main/scala/sigma/ast/values.scala index 0a2b8a3d43..87c661a00a 100644 --- a/data/shared/src/main/scala/sigma/ast/values.scala +++ b/data/shared/src/main/scala/sigma/ast/values.scala @@ -217,18 +217,13 @@ object Value { case Height => 1 case LastBlockUtxoRootHash => 1 case MinerPubkey => 1 - case MethodCall(obj, method, _, _) => - (obj, method.objType) match { - case (_, SContextMethods) => method.name match { - case SContextMethods.headersMethod.name => 1 - case SContextMethods.preHeaderMethod.name => 1 - case SContextMethods.heightMethod.name => 1 - case SContextMethods.lastBlockUtxoRootHashMethod.name => 1 - case SContextMethods.minerPubKeyMethod.name => 1 - case _ => 0 - } + case MethodCall(_, method, _, _) => + method.objType match { + case SContextMethods => + if (SContextMethods.BlockchainContextMethodNames.contains(method.name)) 1 else 0 case _ => 0 } + case _ => 0 } val c = count(blockchainContextNode)(exp) c > 0 diff --git a/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala b/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala index 17028ffa0b..be368743a1 100644 --- a/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala @@ -5,6 +5,7 @@ import sigma.ast.{ComplexityTable, MethodCall, SContextMethods, SMethod, SType, import sigma.util.safeNewArray import SigmaByteWriter._ import debox.cfor +import sigma.ast.SContextMethods.BlockchainContextMethodNames import sigma.serialization.CoreByteWriter.{ArgInfo, DataInfo} case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[SType]], STypeSubst) => Value[SType]) @@ -60,13 +61,8 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S val specMethod = method.specializeFor(obj.tpe, types) - var isUsingBlockchainContext = specMethod.objType == SContextMethods && ( - method.name == SContextMethods.headersMethod.name || - method.name == SContextMethods.preHeaderMethod.name || - method.name == SContextMethods.heightMethod.name || - method.name == SContextMethods.lastBlockUtxoRootHashMethod.name || - method.name == SContextMethods.minerPubKeyMethod.name - ) + var isUsingBlockchainContext = specMethod.objType == SContextMethods && + BlockchainContextMethodNames.contains(method.name) r.wasUsingBlockchainContext ||= isUsingBlockchainContext cons(obj, specMethod, args, Map.empty) From 0aeede75eb28f26a12d1d371b59e6dcb207b09dc Mon Sep 17 00:00:00 2001 From: Samdish Date: Fri, 24 Nov 2023 19:57:13 +0530 Subject: [PATCH 4/5] Add a handle-all in match case --- .../main/scala/sigma/serialization/CaseObjectSerialization.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/data/shared/src/main/scala/sigma/serialization/CaseObjectSerialization.scala b/data/shared/src/main/scala/sigma/serialization/CaseObjectSerialization.scala index b3b968af1c..f1a8047922 100644 --- a/data/shared/src/main/scala/sigma/serialization/CaseObjectSerialization.scala +++ b/data/shared/src/main/scala/sigma/serialization/CaseObjectSerialization.scala @@ -12,6 +12,7 @@ case class CaseObjectSerialization[V <: Value[SType]](override val opDesc: Value case Height => r.wasUsingBlockchainContext = true case LastBlockUtxoRootHash => r.wasUsingBlockchainContext = true case MinerPubkey => r.wasUsingBlockchainContext = true + case _ => } obj From 0a2390d37d0c4b486ea3d7093107e6c7a8a8b7c6 Mon Sep 17 00:00:00 2001 From: Samdish Date: Sun, 10 Dec 2023 00:02:08 +0530 Subject: [PATCH 5/5] Assign to _wasUsingBlockchainContext instead of wasUsingBlockchainContext --- .../src/main/scala/sigma/serialization/CoreByteReader.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala b/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala index d89015c82d..f7e1924db5 100644 --- a/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala +++ b/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala @@ -163,6 +163,6 @@ class CoreByteReader(val r: Reader, val maxTreeDepth: Int = CoreSerializer.MaxTr @inline final def wasUsingBlockchainContext: Boolean = _wasUsingBlockchainContext @inline final def wasUsingBlockchainContext_=(v: Boolean): Unit = { - wasUsingBlockchainContext = v + _wasUsingBlockchainContext = v } }