From dd1b323d774e52538d73a35587a308af3e4789da Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 1 Aug 2019 10:58:25 +0300 Subject: [PATCH 01/64] switch ergo tests branch to master; --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index fedb83ec0a..41142d18b2 100644 --- a/build.sbt +++ b/build.sbt @@ -201,7 +201,7 @@ lazy val sigma = (project in file(".")) .settings(commonSettings: _*) def runErgoTask(task: String, sigmastateVersion: String, log: Logger): Unit = { - val ergoBranch = "ergobox-opt" + val ergoBranch = "master" val sbtEnvVars = Seq("BUILD_ENV" -> "test", "SIGMASTATE_VERSION" -> sigmastateVersion) log.info(s"Testing current build in Ergo (branch $ergoBranch):") From 9e19e421240328fcc668264431fd87de2254b860 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Wed, 24 Jul 2019 13:11:05 +0300 Subject: [PATCH 02/64] add circe 0.10.0 (version used in ergo); --- build.sbt | 7 +++++++ src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/build.sbt b/build.sbt index 41142d18b2..2501cc819d 100644 --- a/build.sbt +++ b/build.sbt @@ -118,6 +118,13 @@ libraryDependencies ++= Seq( "org.spire-math" %% "debox" % "0.8.0" ) ++ testingDependencies +val circeVersion = "0.10.0" + +libraryDependencies ++= Seq( + "io.circe" %% "circe-core", + "io.circe" %% "circe-generic", + "io.circe" %% "circe-parser" +).map(_ % circeVersion) scalacOptions ++= Seq("-feature", "-deprecation") diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 84a0e9b53e..48ed7b18b1 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -1,5 +1,7 @@ package org.ergoplatform +import io.circe._ +import io.circe.syntax._ import org.ergoplatform.ErgoLikeContext.Height import scalan.RType import sigmastate.Values._ @@ -197,6 +199,14 @@ object ErgoLikeContext { new CostingBox(isCost, ebox) } } + + implicit val encoder: Encoder[ErgoLikeContext] = { ctx => + Json.obj( + "currentHeight" -> ctx.currentHeight.asJson, +// "lastBlockUtxoRoot" -> ctx.lastBlockUtxoRoot.asJson, + "minerPubkey" -> ctx.minerPubkey.asJson + ) + } } /** When interpreted evaluates to a ByteArrayConstant built from Context.minerPubkey */ From 150954409b8206306a841049b80baadb88c49b47 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Wed, 24 Jul 2019 18:15:21 +0300 Subject: [PATCH 03/64] add Algos from ergo; implement Header json encoder; implement AvlTreeData json encoder; --- .../org/ergoplatform/ErgoLikeContext.scala | 24 +++++++++--- .../scala/org/ergoplatform/JsonCodecs.scala | 37 +++++++++++++++++++ .../org/ergoplatform/settings/Algos.scala | 30 +++++++++++++++ src/main/scala/sigmastate/AvlTreeData.scala | 15 +++++++- 4 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 src/main/scala/org/ergoplatform/JsonCodecs.scala create mode 100644 src/main/scala/org/ergoplatform/settings/Algos.scala diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 48ed7b18b1..9f6a1bc12a 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -13,11 +13,12 @@ import sigmastate.serialization.OpCodes import sigmastate.serialization.OpCodes.OpCode import special.collection.Coll import special.sigma -import special.sigma.{AnyValue, Box, PreHeader, Header} +import special.sigma.{AnyValue, Box, Header, PreHeader} import SType._ import RType._ import org.ergoplatform.ErgoConstants.ScriptCostLimit -import org.ergoplatform.validation.{ValidationRules, SigmaValidationSettings} +import org.ergoplatform.settings.Algos +import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} import spire.syntax.all.cfor import scala.util.Try @@ -117,7 +118,7 @@ class ErgoLikeContext(val currentHeight: Height, } -object ErgoLikeContext { +object ErgoLikeContext extends JsonCodecs { type Height = Int val dummyPubkey: Array[Byte] = Array.fill(32)(0: Byte) @@ -200,11 +201,22 @@ object ErgoLikeContext { } } - implicit val encoder: Encoder[ErgoLikeContext] = { ctx => + implicit val jsonEncoder: Encoder[ErgoLikeContext] = { ctx => Json.obj( "currentHeight" -> ctx.currentHeight.asJson, -// "lastBlockUtxoRoot" -> ctx.lastBlockUtxoRoot.asJson, - "minerPubkey" -> ctx.minerPubkey.asJson + "lastBlockUtxoRoot" -> ctx.lastBlockUtxoRoot.asJson, + "minerPubkey" -> Algos.encode(ctx.minerPubkey).asJson, + "headers" -> ctx.headers.toArray.toSeq.asJson, + // TODO: implement the rest +// "preHeader" -> ctx.preHeader.asJson, +// "dataBoxes" -> ctx.dataBoxes.asJson, +// "boxesToSpend" -> ctx.boxesToSpend.asJson, +// "spendingTransaction" -> ctx.spendingTransaction.asJson, +// "self" -> ctx.self.asJson, +// "extension" -> ctx.extension.asJson, +// "validationSettings" -> ctx.validationSettings.asJson, + "costLimit" -> ctx.costLimit.asJson, + "initCost" -> ctx.initCost.asJson ) } } diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala new file mode 100644 index 0000000000..707ce27517 --- /dev/null +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -0,0 +1,37 @@ +package org.ergoplatform + +import io.circe._ +import io.circe.syntax._ +import org.ergoplatform.settings.Algos +import sigmastate.AvlTreeData +import sigmastate.eval.{CAvlTree, WrapperOf} +import special.sigma.Header + +trait JsonCodecs { + + implicit val sigmaBigIntEncoder: Encoder[special.sigma.BigInt] = { bigInt => + JsonNumber.fromDecimalStringUnsafe(bigInt.toString).asJson + } + + implicit val headerEncoder: Encoder[Header] = { h: Header => + Map( + "id" -> Algos.encode(h.id).asJson, + "version" -> h.version.asJson, + "parentId" -> Algos.encode(h.parentId).asJson, + "adProofsRoot" -> Algos.encode(h.ADProofsRoot).asJson, + // TODO: fix + "stateRoot" -> h.stateRoot.asInstanceOf[WrapperOf[AvlTreeData]].wrappedValue.asJson, + "transactionsRoot" -> Algos.encode(h.transactionsRoot).asJson, + "timestamp" -> h.timestamp.asJson, + "nBits" -> h.nBits.asJson, + "height" -> h.height.asJson, + "extensionRoot" -> Algos.encode(h.extensionRoot).asJson, + "minerPk" -> Algos.encode(h.minerPk.getEncoded).asJson, + "powOnetimePk" -> Algos.encode(h.powOnetimePk.getEncoded).asJson, + "powNonce" -> Algos.encode(h.powNonce).asJson, + "powDistance" -> h.powDistance.asJson, + "votes" -> Algos.encode(h.votes).asJson + ).asJson + } + +} diff --git a/src/main/scala/org/ergoplatform/settings/Algos.scala b/src/main/scala/org/ergoplatform/settings/Algos.scala new file mode 100644 index 0000000000..0e47bb09a5 --- /dev/null +++ b/src/main/scala/org/ergoplatform/settings/Algos.scala @@ -0,0 +1,30 @@ +package org.ergoplatform.settings + +import scorex.crypto.authds.LeafData +import scorex.crypto.authds.merkle.MerkleTree +import scorex.crypto.hash.{Blake2b256, Digest32} +import scorex.util._ +import special.collection.Coll + +import scala.util.Try + +// TODO: use it in ergo (delete ergo's own) +object Algos extends ScorexEncoding { + + type HF = Blake2b256.type + + val hash: HF = Blake2b256 + + lazy val emptyMerkleTreeRoot: Digest32 = Algos.hash(LeafData @@ Array[Byte]()) + + @inline def encode(bytes: Array[Byte]): String = encoder.encode(bytes) + + @inline def encode(bytes: Coll[Byte]): String = encoder.encode(bytes.toArray) + + @inline def decode(str: String): Try[Array[Byte]] = encoder.decode(str) + + @inline def decodeUnsafe(str: String): Array[Byte] = decode(str).get + + def merkleTreeRoot(elements: Seq[LeafData]): Digest32 = + if (elements.isEmpty) emptyMerkleTreeRoot else MerkleTree(elements)(hash).rootHash +} diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index ac89c070f2..28a9f7c4bb 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -1,7 +1,11 @@ package sigmastate import java.util -import java.util.{Objects, Arrays} +import java.util.{Arrays, Objects} + +import io.circe._ +import io.circe.syntax._ +import org.ergoplatform.settings.Algos import scorex.crypto.authds.ADDigest import sigmastate.interpreter.CryptoConstants import sigmastate.serialization.SigmaSerializer @@ -98,4 +102,13 @@ object AvlTreeData { } } + implicit val jsonEncoder: Encoder[AvlTreeData] = { v => + Json.obj( + "digest" -> Algos.encode(v.digest).asJson, + "treeFlags" -> v.treeFlags.serializeToByte.asJson, + "keyLength" -> v.keyLength.asJson, + "valueLength" -> v.valueLengthOpt.asJson + ) + } + } From 6aa16a31b1f4b3372f61693787950f738b9845e5 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 25 Jul 2019 11:55:02 +0300 Subject: [PATCH 04/64] implment ErgoBox and ErgoTransactionLike json encoders; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 24 +++++++-- .../org/ergoplatform/ErgoLikeContext.scala | 13 ++--- .../ergoplatform/ErgoLikeTransaction.scala | 12 ++++- src/main/scala/org/ergoplatform/Input.scala | 20 ++++++- .../scala/org/ergoplatform/JsonCodecs.scala | 54 +++++++++++++++---- .../interpreter/InterpreterContext.scala | 10 +++- .../interpreter/ProverInterpreter.scala | 11 +++- 7 files changed, 119 insertions(+), 25 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index d41a01c092..be0cbc2bbf 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -1,17 +1,19 @@ package org.ergoplatform +import io.circe._ +import io.circe.syntax._ import com.google.common.primitives.Shorts import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} import scorex.crypto.authds.ADKey import scorex.util.encode.Base16 -import scorex.crypto.hash.{Digest32, Blake2b256} +import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util._ import sigmastate.Values._ import sigmastate.SType.AnyOps import sigmastate._ -import sigmastate.serialization.SigmaSerializer +import sigmastate.serialization.{ErgoTreeSerializer, SigmaSerializer} import sigmastate.SCollection.SByteArray -import sigmastate.utils.{SigmaByteReader, SigmaByteWriter, Helpers} +import sigmastate.utils.{Helpers, SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.ExtractCreationInfo import special.collection._ import sigmastate.eval._ @@ -89,7 +91,7 @@ class ErgoBox( s"$index, $additionalRegisters, $creationHeight)" } -object ErgoBox { +object ErgoBox extends JsonCodecs { type BoxId = ADKey object BoxId { val size: Short = 32 @@ -198,4 +200,18 @@ object ErgoBox { } } + // TODO remove in ergo + implicit val jsonEncoder: Encoder[ErgoBox] = { box => + Json.obj( + "boxId" -> box.id.asJson, + "value" -> box.value.asJson, + "ergoTree" -> ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(box.ergoTree).asJson, + "assets" -> box.additionalTokens.toArray.toSeq.asJson, + "creationHeight" -> box.creationHeight.asJson, + "additionalRegisters" -> box.additionalRegisters.map { case (key, value) => + s"R${key.number}" -> evaluatedValueEncoder(value) + }.asJson + ) + } + } diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 9f6a1bc12a..cea6fb737b 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -207,13 +207,14 @@ object ErgoLikeContext extends JsonCodecs { "lastBlockUtxoRoot" -> ctx.lastBlockUtxoRoot.asJson, "minerPubkey" -> Algos.encode(ctx.minerPubkey).asJson, "headers" -> ctx.headers.toArray.toSeq.asJson, + "preHeader" -> ctx.preHeader.asJson, + "dataBoxes" -> ctx.dataBoxes.asJson, + "boxesToSpend" -> ctx.boxesToSpend.asJson, + // TODO: fix + "spendingTransaction" -> ctx.spendingTransaction.asInstanceOf[ErgoLikeTransaction].asJson, + "self" -> ctx.self.asJson, + "extension" -> ctx.extension.asJson, // TODO: implement the rest -// "preHeader" -> ctx.preHeader.asJson, -// "dataBoxes" -> ctx.dataBoxes.asJson, -// "boxesToSpend" -> ctx.boxesToSpend.asJson, -// "spendingTransaction" -> ctx.spendingTransaction.asJson, -// "self" -> ctx.self.asJson, -// "extension" -> ctx.extension.asJson, // "validationSettings" -> ctx.validationSettings.asJson, "costLimit" -> ctx.costLimit.asJson, "initCost" -> ctx.initCost.asJson diff --git a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index 2c1bb71edf..04b1c85563 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -2,6 +2,8 @@ package org.ergoplatform import java.util +import io.circe._ +import io.circe.syntax._ import org.ergoplatform.ErgoBox.TokenId import scorex.crypto.authds.ADKey import scorex.crypto.hash.{Blake2b256, Digest32} @@ -165,7 +167,7 @@ object ErgoLikeTransactionSerializer extends SigmaSerializer[ErgoLikeTransaction } -object ErgoLikeTransaction { +object ErgoLikeTransaction extends JsonCodecs { val TransactionIdBytesSize: Short = 32 @@ -190,4 +192,12 @@ object ErgoLikeTransaction { // TODO unify serialization approach in Ergo/sigma with BytesSerializable val serializer: SigmaSerializer[ErgoLikeTransaction, ErgoLikeTransaction] = ErgoLikeTransactionSerializer + implicit val jsonEncoder: Encoder[ErgoLikeTransaction] = { tx => + Json.obj( + "id" -> tx.id.asJson, + "inputs" -> tx.inputs.asJson, + "dataInputs" -> tx.dataInputs.asJson, + "outputs" -> tx.outputs.asJson + ) + } } diff --git a/src/main/scala/org/ergoplatform/Input.scala b/src/main/scala/org/ergoplatform/Input.scala index 6d76934855..3457058de3 100644 --- a/src/main/scala/org/ergoplatform/Input.scala +++ b/src/main/scala/org/ergoplatform/Input.scala @@ -2,6 +2,8 @@ package org.ergoplatform import java.util +import io.circe._ +import io.circe.syntax._ import org.ergoplatform.ErgoBox.BoxId import scorex.crypto.authds.ADKey import scorex.util.encode.Base16 @@ -16,6 +18,15 @@ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} */ case class DataInput(boxId: BoxId) +object DataInput extends JsonCodecs { + + implicit val jsonEncoder: Encoder[DataInput] = { input => + Json.obj( + "boxId" -> input.boxId.asJson, + ) + } +} + /** * Inputs of formed, but unsigned transaction * @@ -52,7 +63,7 @@ case class Input(override val boxId: BoxId, spendingProof: ProverResult) override def toString: String = s"Input(${Base16.encode(boxId)},$spendingProof)" } -object Input { +object Input extends JsonCodecs { object serializer extends SigmaSerializer[Input, Input] { @@ -68,4 +79,11 @@ object Input { } } + implicit val jsonEncoder: Encoder[Input] = { input => + Json.obj( + "boxId" -> input.boxId.asJson, + "spendingProof" -> input.spendingProof.asJson + ) + } + } diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index 707ce27517..bff5f6763a 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -3,35 +3,67 @@ package org.ergoplatform import io.circe._ import io.circe.syntax._ import org.ergoplatform.settings.Algos -import sigmastate.AvlTreeData +import scorex.crypto.authds.ADKey +import scorex.crypto.hash.Digest32 +import scorex.util.ModifierId +import sigmastate.{AvlTreeData, SType} +import sigmastate.Values.EvaluatedValue import sigmastate.eval.{CAvlTree, WrapperOf} -import special.sigma.Header +import sigmastate.serialization.ValueSerializer +import special.collection.Coll +import special.sigma.{Header, PreHeader} trait JsonCodecs { + //TODO: remove in ergo implicit val sigmaBigIntEncoder: Encoder[special.sigma.BigInt] = { bigInt => JsonNumber.fromDecimalStringUnsafe(bigInt.toString).asJson } + implicit val arrayBytesEncoder: Encoder[Array[Byte]] = Algos.encode(_).asJson + implicit val collBytesEncoder: Encoder[Coll[Byte]] = Algos.encode(_).asJson +// implicit val byteSeqEncoder: Encoder[IndexedSeq[Byte]] = { in => Algos.encode(in.toArray).asJson } + + implicit val adKeyEncoder: Encoder[ADKey] = _.array.asJson + + implicit val digest32Encoder: Encoder[Digest32] = _.array.asJson + + implicit val modifierIdEncoder: Encoder[ModifierId] = _.asJson + implicit val headerEncoder: Encoder[Header] = { h: Header => Map( - "id" -> Algos.encode(h.id).asJson, + "id" -> h.id.asJson, "version" -> h.version.asJson, - "parentId" -> Algos.encode(h.parentId).asJson, - "adProofsRoot" -> Algos.encode(h.ADProofsRoot).asJson, + "parentId" -> h.parentId.asJson, + "adProofsRoot" -> h.ADProofsRoot.asJson, // TODO: fix "stateRoot" -> h.stateRoot.asInstanceOf[WrapperOf[AvlTreeData]].wrappedValue.asJson, - "transactionsRoot" -> Algos.encode(h.transactionsRoot).asJson, + "transactionsRoot" -> h.transactionsRoot.asJson, "timestamp" -> h.timestamp.asJson, "nBits" -> h.nBits.asJson, "height" -> h.height.asJson, - "extensionRoot" -> Algos.encode(h.extensionRoot).asJson, - "minerPk" -> Algos.encode(h.minerPk.getEncoded).asJson, - "powOnetimePk" -> Algos.encode(h.powOnetimePk.getEncoded).asJson, - "powNonce" -> Algos.encode(h.powNonce).asJson, + "extensionRoot" -> h.extensionRoot.asJson, + "minerPk" -> h.minerPk.getEncoded.asJson, + "powOnetimePk" -> h.powOnetimePk.getEncoded.asJson, + "powNonce" -> h.powNonce.asJson, "powDistance" -> h.powDistance.asJson, - "votes" -> Algos.encode(h.votes).asJson + "votes" -> h.votes.asJson ).asJson } + implicit val preHeaderEncoder: Encoder[PreHeader] = { v: PreHeader => + Map( + "version" -> v.version.asJson, + "parentId" -> v.parentId.asJson, + "timestamp" -> v.timestamp.asJson, + "nBits" -> v.nBits.asJson, + "height" -> v.height.asJson, + "minerPk" -> v.minerPk.getEncoded.asJson, + "votes" -> v.votes.asJson + ).asJson + } + + implicit val evaluatedValueEncoder: Encoder[EvaluatedValue[SType]] = { value => + ValueSerializer.serialize(value).asJson + } } diff --git a/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index 1cee748e6c..b473d85014 100644 --- a/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -1,5 +1,8 @@ package sigmastate.interpreter +import io.circe._ +import io.circe.syntax._ +import org.ergoplatform.JsonCodecs import org.ergoplatform.validation.SigmaValidationSettings import sigmastate.SType import sigmastate.Values.EvaluatedValue @@ -19,7 +22,7 @@ case class ContextExtension(values: Map[Byte, EvaluatedValue[_ <: SType]]) { ContextExtension(values ++ bindings) } -object ContextExtension { +object ContextExtension extends JsonCodecs { val empty = ContextExtension(Map()) object serializer extends SigmaSerializer[ContextExtension, ContextExtension] { @@ -38,6 +41,11 @@ object ContextExtension { } } + implicit val jsonEncoder: Encoder[ContextExtension] = { extension => + extension.values.map { case (key, value) => + key -> evaluatedValueEncoder(value) + }.asJson + } } diff --git a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index 557d2083a4..f54acb4007 100644 --- a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -2,10 +2,13 @@ package sigmastate.interpreter import java.util +import io.circe._ +import io.circe.syntax._ import gf2t.{GF2_192, GF2_192_Poly} import org.bitbucket.inkytonik.kiama.attribution.AttributionCore import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{everywherebu, everywheretd, rule} import org.bitbucket.inkytonik.kiama.rewriting.Strategy +import org.ergoplatform.JsonCodecs import scalan.util.CollectionUtil._ import scorex.util.encode.Base16 import sigmastate.Values._ @@ -37,7 +40,7 @@ class ProverResult(val proof: Array[Byte], val extension: ContextExtension) { override def toString: Idn = s"ProverResult(${Base16.encode(proof)},$extension)" } -object ProverResult { +object ProverResult extends JsonCodecs { val empty: ProverResult = ProverResult(Array[Byte](), ContextExtension.empty) def apply(proof: Array[Byte], extension: ContextExtension): ProverResult = @@ -59,6 +62,12 @@ object ProverResult { } } + implicit val jsonEncoder: Encoder[ProverResult] = { v => + Json.obj( + "proofBytes" -> v.proof.asJson, + "extension" -> v.extension.asJson + ) + } } case class CostedProverResult(override val proof: Array[Byte], From 63a025549340952002231668d479bb1d04a1896c Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 25 Jul 2019 15:39:36 +0300 Subject: [PATCH 05/64] implment validation settings json encoders; --- .../org/ergoplatform/ErgoLikeContext.scala | 5 ++--- .../validation/SigmaValidationSettings.scala | 16 ++++++++++++++++ .../validation/ValidationRules.scala | 19 ++++++++++++++++--- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index cea6fb737b..20c5d0379f 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -205,7 +205,7 @@ object ErgoLikeContext extends JsonCodecs { Json.obj( "currentHeight" -> ctx.currentHeight.asJson, "lastBlockUtxoRoot" -> ctx.lastBlockUtxoRoot.asJson, - "minerPubkey" -> Algos.encode(ctx.minerPubkey).asJson, + "minerPubkey" -> ctx.minerPubkey.asJson, "headers" -> ctx.headers.toArray.toSeq.asJson, "preHeader" -> ctx.preHeader.asJson, "dataBoxes" -> ctx.dataBoxes.asJson, @@ -214,8 +214,7 @@ object ErgoLikeContext extends JsonCodecs { "spendingTransaction" -> ctx.spendingTransaction.asInstanceOf[ErgoLikeTransaction].asJson, "self" -> ctx.self.asJson, "extension" -> ctx.extension.asJson, - // TODO: implement the rest -// "validationSettings" -> ctx.validationSettings.asJson, + "validationSettings" -> ctx.validationSettings.asJson, "costLimit" -> ctx.costLimit.asJson, "initCost" -> ctx.initCost.asJson ) diff --git a/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala b/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala index bb9a3508cd..6e2fa2c3da 100644 --- a/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala +++ b/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala @@ -1,5 +1,9 @@ package org.ergoplatform.validation +import io.circe._ +import io.circe.syntax._ +import org.ergoplatform.JsonCodecs + /** * Configuration of validation. Each `ValidationRule` instance should be * implemented as an `object` to facilitate type-safe usage. It then should be @@ -37,6 +41,7 @@ package org.ergoplatform.validation * when isSoftFork returns true), for example when a new opCode is added in the * newer version of the protocol, and this fact can be recognized by the old * code. + * * @see SoftForkWhenCodeAdded */ abstract class SigmaValidationSettings extends Iterable[(Short, (ValidationRule, RuleStatus))] { @@ -54,6 +59,17 @@ abstract class SigmaValidationSettings extends Iterable[(Short, (ValidationRule, } } +object SigmaValidationSettings extends JsonCodecs { + implicit val jsonEncoder: Encoder[SigmaValidationSettings] = { v => + Json.fromValues(v.toSeq.map { case (_, (rule, status)) => + Json.obj( + "rule" -> rule.asJson, + "status" -> status.statusCode.asJson + ) + }) + } +} + /** Default representation of validation settings. */ sealed class MapSigmaValidationSettings(private val map: Map[Short, (ValidationRule, RuleStatus)]) extends SigmaValidationSettings { override def iterator: Iterator[(Short, (ValidationRule, RuleStatus))] = map.iterator diff --git a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index 3378d87194..a85055cc49 100644 --- a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -4,19 +4,22 @@ import java.nio.ByteBuffer import java.util import org.ergoplatform.ErgoConstants.MaxLoopLevelInCostFunction +import org.ergoplatform.JsonCodecs import scorex.util.ByteArrayBuilder import scorex.util.serialization.{VLQByteBufferReader, VLQByteBufferWriter} import sigma.util.Extensions.toUByte import sigmastate.eval.IRContext -import sigmastate.serialization.OpCodes.{OpCodeExtra, OpCode} -import sigmastate.Values.{Value, ErgoTree, SValue, IntValue} -import sigmastate.serialization.{ValueSerializer, OpCodes} +import sigmastate.serialization.OpCodes.{OpCode, OpCodeExtra} +import sigmastate.Values.{ErgoTree, IntValue, SValue, Value} +import sigmastate.serialization.{OpCodes, ValueSerializer} import sigmastate.utxo.DeserializeContext import sigmastate.lang.exceptions._ import sigmastate.serialization.TypeSerializer.embeddableIdToType import sigmastate._ import scala.collection.mutable +import io.circe._ +import io.circe.syntax._ /** Base class for different validation rules registered in ValidationRules.currentSettings. * Each rule is identified by `id` and have a description. @@ -59,6 +62,16 @@ case class ValidationRule( } +object ValidationRule extends JsonCodecs { + + implicit val jsonEncoder: Encoder[ValidationRule] = { v => + Json.obj( + "id" -> v.id.asJson, + "description" -> v.description.asJson + ) + } +} + /** Base class for all exceptions which may be thrown by validation rules. * Instances of this class are used as messages to communicate soft-fork information, * from the context where the soft-fork condition is detected (such as in ValidationRules), From 0f362059eb195a490ffbb59c9e58d10de7274ec9 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 25 Jul 2019 19:18:17 +0300 Subject: [PATCH 06/64] clean up nulls in ErgoLikeContext.preHeader and spendingTransaction; --- .../org/ergoplatform/ErgoLikeContext.scala | 39 +++++++++++-------- .../ergoplatform/ErgoLikeTransaction.scala | 2 + .../scala/org/ergoplatform/JsonCodecs.scala | 2 +- .../ergoplatform/dsl/TestContractSpec.scala | 2 +- .../helpers/SigmaTestingCommons.scala | 2 +- .../SigSerializerSpecification.scala | 6 +-- .../utxo/ComplexSigSpecification.scala | 38 +++++++++--------- .../ErgoLikeInterpreterSpecification.scala | 6 +-- .../utxo/ThresholdSpecification.scala | 10 ++--- .../AtomicSwapExampleSpecification.scala | 10 ++--- 10 files changed, 62 insertions(+), 55 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 20c5d0379f..875214f873 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -8,12 +8,12 @@ import sigmastate.Values._ import sigmastate._ import sigmastate.eval._ import sigmastate.eval.Extensions._ -import sigmastate.interpreter.{ContextExtension, InterpreterContext} -import sigmastate.serialization.OpCodes +import sigmastate.interpreter.{ContextExtension, CryptoConstants, InterpreterContext} +import sigmastate.serialization.{GroupElementSerializer, OpCodes, SigmaSerializer} import sigmastate.serialization.OpCodes.OpCode import special.collection.Coll import special.sigma -import special.sigma.{AnyValue, Box, Header, PreHeader} +import special.sigma.{AnyValue, Box, GroupElement, Header, PreHeader} import SType._ import RType._ import org.ergoplatform.ErgoConstants.ScriptCostLimit @@ -58,14 +58,16 @@ class ErgoLikeContext(val currentHeight: Height, val initCost: Long ) extends InterpreterContext { - assert(self == null || boxesToSpend.exists(box => box.id == self.id), s"Self box if defined should be among boxesToSpend") - assert(preHeader == null || preHeader.height == currentHeight, "Incorrect preHeader height") - assert(preHeader == null || java.util.Arrays.equals(minerPubkey, preHeader.minerPk.getEncoded.toArray), "Incorrect preHeader minerPubkey") + assert(preHeader != null) + assert(spendingTransaction != null) + assert(boxesToSpend.exists(box => box.id == self.id), s"Self box if defined should be among boxesToSpend") + assert(preHeader.height == currentHeight, "Incorrect preHeader height") + assert(java.util.Arrays.equals(minerPubkey, preHeader.minerPk.getEncoded.toArray), "Incorrect preHeader minerPubkey") assert(headers.toArray.headOption.forall(h => java.util.Arrays.equals(h.stateRoot.digest.toArray, lastBlockUtxoRoot.digest)), "Incorrect lastBlockUtxoRoot") cfor(0)(_ < headers.length, _ + 1) { i => if (i > 0) assert(headers(i - 1).parentId == headers(i).id, s"Incorrect chain: ${headers(i - 1).parentId},${headers(i).id}") } - assert(preHeader == null || headers.toArray.headOption.forall(_.id == preHeader.parentId), s"preHeader.parentId should be id of the best header") + assert(headers.toArray.headOption.forall(_.id == preHeader.parentId), s"preHeader.parentId should be id of the best header") override def withCostLimit(newCostLimit: Long): ErgoLikeContext = new ErgoLikeContext( @@ -99,10 +101,7 @@ class ErgoLikeContext(val currentHeight: Height, implicit val IRForBox: Evaluation = IR val dataInputs = this.dataBoxes.toArray.map(_.toTestBox(isCost)).toColl val inputs = boxesToSpend.toArray.map(_.toTestBox(isCost)).toColl - val outputs = if (spendingTransaction == null) - noOutputs.toColl - else - spendingTransaction.outputs.toArray.map(_.toTestBox(isCost)).toColl + val outputs = spendingTransaction.outputs.toArray.map(_.toTestBox(isCost)).toColl val varMap = extension.values.mapValues { case v: EvaluatedValue[_] => val tVal = stypeToRType[SType](v.tpe) toAnyValue(v.value.asWrappedType)(tVal) @@ -121,11 +120,18 @@ class ErgoLikeContext(val currentHeight: Height, object ErgoLikeContext extends JsonCodecs { type Height = Int - val dummyPubkey: Array[Byte] = Array.fill(32)(0: Byte) + val dummyPubkey: Array[Byte] = Array.fill(CryptoConstants.groupSize + 1)(0: Byte) val noBoxes = IndexedSeq.empty[ErgoBox] val noHeaders = CostingSigmaDslBuilder.Colls.emptyColl[Header] - val dummyPreHeader: PreHeader = null + def dummyPreHeader(currentHeight: Height, minerPk: Array[Byte]): PreHeader = CPreHeader(0, + parentId = Colls.emptyColl[Byte], + timestamp = 3, + nBits = 0, + height = currentHeight, + minerPk = GroupElementSerializer.parse(SigmaSerializer.startReader(minerPk)), + votes = Colls.emptyColl[Byte] + ) /** Maximimum number of headers in `headers` collection of the context. */ val MaxHeaders = ErgoConstants.MaxHeaders.value @@ -140,7 +146,7 @@ object ErgoLikeContext extends JsonCodecs { vs: SigmaValidationSettings = ValidationRules.currentSettings) = new ErgoLikeContext(currentHeight, lastBlockUtxoRoot, minerPubkey, noHeaders, - dummyPreHeader, + dummyPreHeader(currentHeight, minerPubkey), noBoxes, boxesToSpend, spendingTransaction, self, extension, vs, ScriptCostLimit.value, 0L) @@ -153,13 +159,13 @@ object ErgoLikeContext extends JsonCodecs { self: ErgoBox) = new ErgoLikeContext(currentHeight, lastBlockUtxoRoot, minerPubkey, noHeaders, - dummyPreHeader, + dummyPreHeader(currentHeight, minerPubkey), dataBoxes, boxesToSpend, spendingTransaction, self, ContextExtension.empty, ValidationRules.currentSettings, ScriptCostLimit.value, 0L) def dummy(selfDesc: ErgoBox) = ErgoLikeContext(currentHeight = 0, lastBlockUtxoRoot = AvlTreeData.dummy, dummyPubkey, boxesToSpend = IndexedSeq(selfDesc), - spendingTransaction = null, self = selfDesc) + spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), self = selfDesc) def fromTransaction(tx: ErgoLikeTransaction, blockchainState: BlockchainState, @@ -196,7 +202,6 @@ object ErgoLikeContext extends JsonCodecs { implicit class ErgoBoxOps(val ebox: ErgoBox) extends AnyVal { def toTestBox(isCost: Boolean): Box = { - if (ebox == null) return null new CostingBox(isCost, ebox) } } diff --git a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index 04b1c85563..7e5e3ab499 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -171,6 +171,8 @@ object ErgoLikeTransaction extends JsonCodecs { val TransactionIdBytesSize: Short = 32 + val dummy = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()) + /** * Bytes that should be signed by provers. * Contains all the transaction bytes except of signatures diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index bff5f6763a..aab9720634 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -28,7 +28,7 @@ trait JsonCodecs { implicit val digest32Encoder: Encoder[Digest32] = _.array.asJson - implicit val modifierIdEncoder: Encoder[ModifierId] = _.asJson + implicit val modifierIdEncoder: Encoder[ModifierId] = _.asInstanceOf[String].asJson implicit val headerEncoder: Encoder[Header] = { h: Header => Map( diff --git a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index 4141f54901..20b9b56e3b 100644 --- a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -84,7 +84,7 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, headers = noHeaders, - preHeader = dummyPreHeader, + preHeader = dummyPreHeader(tx.block.height, ErgoLikeContext.dummyPubkey), dataBoxes = tx.dataInputs.map(_.utxoBox.ergoBox).toIndexedSeq, boxesToSpend = tx.inputs.map(_.utxoBox.ergoBox).toIndexedSeq, spendingTransaction = testSuite.createTransaction(tx.outputs.map(_.ergoBox).toIndexedSeq), diff --git a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala b/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala index 862b15ae91..5978cc3004 100644 --- a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala +++ b/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala @@ -171,7 +171,7 @@ trait SigmaTestingCommons extends PropSpec catch { case e: Throwable => if (!assertion(e)) - fail(s"exception check failed on $e (root cause: ${rootCause(e)})") + fail(s"exception check failed on $e (root cause: ${rootCause(e)}) \n trace:\n${e.getStackTrace.mkString("\n")}}") } } diff --git a/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala b/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala index cabade8e82..26dcc3edae 100644 --- a/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala +++ b/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala @@ -2,10 +2,10 @@ package sigmastate.serialization import java.util -import org.ergoplatform.ErgoLikeContext +import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction} import org.scalacheck.{Arbitrary, Gen} import org.scalatest.Assertion -import sigmastate.Values.{Value, SigmaPropConstant, SigmaBoolean, SigmaPropValue} +import sigmastate.Values.{SigmaBoolean, SigmaPropConstant, SigmaPropValue, Value} import sigmastate._ import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.ProveDHTuple @@ -77,7 +77,7 @@ class SigSerializerSpecification extends SigmaTestingCommons with ObjectGenerato lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) // get sigma conjectures out of transformers diff --git a/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala b/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala index c9259858e8..3993391914 100644 --- a/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala @@ -1,6 +1,6 @@ package sigmastate.utxo -import org.ergoplatform.{ErgoLikeContext, Height} +import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction, Height} import org.scalacheck.Gen import sigmastate.Values.IntConstant import sigmastate._ @@ -41,7 +41,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -74,7 +74,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -108,7 +108,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -143,7 +143,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -174,7 +174,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -215,7 +215,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -252,7 +252,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -285,7 +285,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -325,7 +325,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -366,7 +366,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -410,7 +410,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -448,7 +448,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx1, fakeMessage).get verifier.verify(compiledProp, ctx1, prA, fakeMessage).get._1 shouldBe true @@ -461,7 +461,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prC = proverC.prove(compiledProp, ctx2, fakeMessage).get verifier.verify(compiledProp, ctx2, prC, fakeMessage).get._1 shouldBe true @@ -490,7 +490,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx1, fakeMessage).get @@ -505,7 +505,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA2 = proverA.prove(compiledProp, ctx2, fakeMessage).get @@ -538,7 +538,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx1, fakeMessage).get @@ -553,7 +553,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA2 = proverA.prove(compiledProp, ctx2, fakeMessage).get @@ -588,7 +588,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) // any prover alone (no added secrets) should fail diff --git a/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala index 3788ed3d66..4b6b75adca 100644 --- a/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala @@ -74,7 +74,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val pr = prover.prove(prop, ctx, fakeMessage).get @@ -104,7 +104,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -131,7 +131,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get diff --git a/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala b/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala index 9ba01a676a..ebcf49a52a 100644 --- a/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala @@ -1,6 +1,6 @@ package sigmastate.utxo -import org.ergoplatform.ErgoLikeContext +import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction} import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog} import sigmastate.Values.{ConcreteCollection, FalseLeaf, IntConstant, SigmaPropConstant, SigmaPropValue, TrueLeaf} import sigmastate._ @@ -39,7 +39,7 @@ class ThresholdSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val env = Map("pubkeyA" -> pubkeyA, "pubkeyB" -> pubkeyB, "pubkeyC" -> pubkeyC) @@ -118,7 +118,7 @@ class ThresholdSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) case class TestCase(numTrue: Int, vector: Seq[SigmaPropValue], dlogOnlyVector: DlogOnlyVector) @@ -288,7 +288,7 @@ class ThresholdSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val verifier = new ErgoLikeTestInterpreter @@ -335,7 +335,7 @@ class ThresholdSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val verifier = new ErgoLikeTestInterpreter diff --git a/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala index fb8f846b3a..74e9319ede 100644 --- a/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala @@ -1,6 +1,6 @@ package sigmastate.utxo.examples -import org.ergoplatform.{ErgoLikeContext, Height} +import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction, Height} import scorex.crypto.hash.Blake2b256 import scorex.utils.Random import sigmastate.Values._ @@ -102,7 +102,7 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) proverB.prove(env, prop1, ctxf1, fakeMessage).isSuccess shouldBe false @@ -114,7 +114,7 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { currentHeight = height2 + 1, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, - boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = null, self = fakeSelf) + boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) proverB.prove(env, prop2, ctxf2, fakeMessage).isSuccess shouldBe false //Successful run below: @@ -125,7 +125,7 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val pr = proverA.prove(env, prop2, ctx1, fakeMessage).get verifier.verify(env, prop2, ctx1, pr, fakeMessage).get._1 shouldBe true @@ -140,7 +140,7 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContext.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = null, + spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) val pr2 = proverB2.prove(env, prop1, ctx2, fakeMessage).get verifier.verify(env, prop1, ctx2, pr2, fakeMessage).get._1 shouldBe true From b8b1397848b21f73b8c0f62be97e6578d26590ad Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Sun, 28 Jul 2019 10:39:54 +0300 Subject: [PATCH 07/64] generate proper dummy key in ctx; --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 875214f873..0248429fa4 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -120,7 +120,7 @@ class ErgoLikeContext(val currentHeight: Height, object ErgoLikeContext extends JsonCodecs { type Height = Int - val dummyPubkey: Array[Byte] = Array.fill(CryptoConstants.groupSize + 1)(0: Byte) + val dummyPubkey: Array[Byte] = GroupElementSerializer.toBytes(CryptoConstants.dlogGroup.generator ) val noBoxes = IndexedSeq.empty[ErgoBox] val noHeaders = CostingSigmaDslBuilder.Colls.emptyColl[Header] From 0b210fe5f626a712ce91fe7c59ae79b73868a6ba Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 29 Jul 2019 11:02:04 +0300 Subject: [PATCH 08/64] fix showECPoint to handle infinity; remove unused duplicate CryptoFunctions.showECPoint; --- .../src/main/scala/special/sigma/Extensions.scala | 13 +++++++++---- .../scala/org/ergoplatform/ErgoLikeContext.scala | 2 +- .../sigmastate/interpreter/CryptoFunctions.scala | 6 ------ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/sigma-impl/src/main/scala/special/sigma/Extensions.scala b/sigma-impl/src/main/scala/special/sigma/Extensions.scala index 20465ccb54..e07c0127ce 100644 --- a/sigma-impl/src/main/scala/special/sigma/Extensions.scala +++ b/sigma-impl/src/main/scala/special/sigma/Extensions.scala @@ -16,10 +16,15 @@ class DslSyntaxExtensions(dsl: SigmaDslBuilder) { object Extensions { - def showECPoint(p: ECPoint) = { - val rawX = p.getRawXCoord.toString.substring(0, 6) - val rawY = p.getRawYCoord.toString.substring(0, 6) - s"ECPoint($rawX,$rawY,...)" + def showECPoint(p: ECPoint): String = { + if (p.isInfinity) { + "INF" + } + else { + val rawX = p.getRawXCoord.toString.substring(0, 6) + val rawY = p.getRawYCoord.toString.substring(0, 6) + s"ECPoint($rawX,$rawY,...)" + } } implicit class GroupElementOps(val source: GroupElement) extends AnyVal { diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 0248429fa4..a27a8cd86e 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -120,7 +120,7 @@ class ErgoLikeContext(val currentHeight: Height, object ErgoLikeContext extends JsonCodecs { type Height = Int - val dummyPubkey: Array[Byte] = GroupElementSerializer.toBytes(CryptoConstants.dlogGroup.generator ) + val dummyPubkey: Array[Byte] = GroupElementSerializer.toBytes(CryptoConstants.dlogGroup.generator) val noBoxes = IndexedSeq.empty[ErgoBox] val noHeaders = CostingSigmaDslBuilder.Colls.emptyColl[Header] diff --git a/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala b/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala index 0aa16f2480..db04394754 100644 --- a/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala +++ b/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala @@ -10,10 +10,4 @@ object CryptoFunctions { Blake2b256.hash(input).take(soundnessBytes) } - def showECPoint(p: ECPoint): String = { - val rawX = p.getRawXCoord.toString.substring(0, 6) - val rawY = p.getRawYCoord.toString.substring(0, 6) - s"ECPoint($rawX,$rawY,...)" - } - } From c0d622f69c24ca76c6c12236d546d2552a7e4ffe Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 29 Jul 2019 12:26:20 +0300 Subject: [PATCH 09/64] encode ErgoLikeContext.self as index of boxesToSpend; --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index a27a8cd86e..40e3aa9e45 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -215,9 +215,9 @@ object ErgoLikeContext extends JsonCodecs { "preHeader" -> ctx.preHeader.asJson, "dataBoxes" -> ctx.dataBoxes.asJson, "boxesToSpend" -> ctx.boxesToSpend.asJson, - // TODO: fix + // TODO: handle unsigned tx "spendingTransaction" -> ctx.spendingTransaction.asInstanceOf[ErgoLikeTransaction].asJson, - "self" -> ctx.self.asJson, + "selfIndex" -> ctx.boxesToSpend.indexOf(ctx.self).asJson, "extension" -> ctx.extension.asJson, "validationSettings" -> ctx.validationSettings.asJson, "costLimit" -> ctx.costLimit.asJson, From 07dcb44ec0a3661c142dc1906cb1b806ec7f75cf Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 29 Jul 2019 12:46:00 +0300 Subject: [PATCH 10/64] convert ErgoLikeContext.self to selfIndex (of boxesToSpend); --- .../org/ergoplatform/ErgoLikeContext.scala | 28 ++++++++++--------- .../ergoplatform/dsl/TestContractSpec.scala | 5 ++-- .../sigmastate/CostingSpecification.scala | 2 +- .../utxo/examples/LetsSpecification.scala | 2 +- .../special/sigma/SigmaTestingData.scala | 2 +- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 40e3aa9e45..00ecbeccf3 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -28,7 +28,7 @@ case class BlockchainState(currentHeight: Height, lastBlockUtxoRoot: AvlTreeData * TODO currentHeight and minerPubkey should be calculated from PreHeader * TODO lastBlockUtxoRoot should be calculated from headers if it is nonEmpty * - * @param self - box that contains the script we're evaluating + * @param selfIndex - index of the box in `boxesToSpend` that contains the script we're evaluating * @param currentHeight - height of a block with the current `spendingTransaction` * @param lastBlockUtxoRoot - state root before current block application * @param minerPubkey - public key of a miner of the block with the current `spendingTransaction` @@ -51,7 +51,7 @@ class ErgoLikeContext(val currentHeight: Height, val dataBoxes: IndexedSeq[ErgoBox], val boxesToSpend: IndexedSeq[ErgoBox], val spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], - val self: ErgoBox, + val selfIndex: Int, val extension: ContextExtension, val validationSettings: SigmaValidationSettings, val costLimit: Long, @@ -60,7 +60,7 @@ class ErgoLikeContext(val currentHeight: Height, assert(preHeader != null) assert(spendingTransaction != null) - assert(boxesToSpend.exists(box => box.id == self.id), s"Self box if defined should be among boxesToSpend") + assert(boxesToSpend.isDefinedAt(selfIndex), s"Self box if defined should be among boxesToSpend") assert(preHeader.height == currentHeight, "Incorrect preHeader height") assert(java.util.Arrays.equals(minerPubkey, preHeader.minerPk.getEncoded.toArray), "Incorrect preHeader minerPubkey") assert(headers.toArray.headOption.forall(h => java.util.Arrays.equals(h.stateRoot.digest.toArray, lastBlockUtxoRoot.digest)), "Incorrect lastBlockUtxoRoot") @@ -69,30 +69,32 @@ class ErgoLikeContext(val currentHeight: Height, } assert(headers.toArray.headOption.forall(_.id == preHeader.parentId), s"preHeader.parentId should be id of the best header") + val self: ErgoBox = boxesToSpend(selfIndex) + override def withCostLimit(newCostLimit: Long): ErgoLikeContext = new ErgoLikeContext( currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, - dataBoxes, boxesToSpend, spendingTransaction, self, extension, validationSettings, newCostLimit, initCost) + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, newCostLimit, initCost) override def withInitCost(newCost: Long): ErgoLikeContext = new ErgoLikeContext( currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, - dataBoxes, boxesToSpend, spendingTransaction, self, extension, validationSettings, costLimit, newCost) + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, newCost) override def withValidationSettings(newVs: SigmaValidationSettings): ErgoLikeContext = new ErgoLikeContext( currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, - dataBoxes, boxesToSpend, spendingTransaction, self, extension, newVs, costLimit, initCost) + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, newVs, costLimit, initCost) override def withExtension(newExtension: ContextExtension): ErgoLikeContext = new ErgoLikeContext( currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, - dataBoxes, boxesToSpend, spendingTransaction, self, newExtension, validationSettings, costLimit, initCost) + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, newExtension, validationSettings, costLimit, initCost) def withTransaction(newSpendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput]): ErgoLikeContext = new ErgoLikeContext( currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, - dataBoxes, boxesToSpend, newSpendingTransaction, self, extension, validationSettings, costLimit, initCost) + dataBoxes, boxesToSpend, newSpendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) import ErgoLikeContext._ import Evaluation._ @@ -148,7 +150,7 @@ object ErgoLikeContext extends JsonCodecs { noHeaders, dummyPreHeader(currentHeight, minerPubkey), noBoxes, - boxesToSpend, spendingTransaction, self, extension, vs, ScriptCostLimit.value, 0L) + boxesToSpend, spendingTransaction, boxesToSpend.indexOf(self), extension, vs, ScriptCostLimit.value, 0L) def apply(currentHeight: Height, lastBlockUtxoRoot: AvlTreeData, @@ -156,11 +158,11 @@ object ErgoLikeContext extends JsonCodecs { dataBoxes: IndexedSeq[ErgoBox], boxesToSpend: IndexedSeq[ErgoBox], spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], - self: ErgoBox) = + selfIndex: Int) = new ErgoLikeContext(currentHeight, lastBlockUtxoRoot, minerPubkey, noHeaders, dummyPreHeader(currentHeight, minerPubkey), - dataBoxes, boxesToSpend, spendingTransaction, self, ContextExtension.empty, ValidationRules.currentSettings, ScriptCostLimit.value, 0L) + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, ContextExtension.empty, ValidationRules.currentSettings, ScriptCostLimit.value, 0L) def dummy(selfDesc: ErgoBox) = ErgoLikeContext(currentHeight = 0, @@ -217,7 +219,7 @@ object ErgoLikeContext extends JsonCodecs { "boxesToSpend" -> ctx.boxesToSpend.asJson, // TODO: handle unsigned tx "spendingTransaction" -> ctx.spendingTransaction.asInstanceOf[ErgoLikeTransaction].asJson, - "selfIndex" -> ctx.boxesToSpend.indexOf(ctx.self).asJson, + "selfIndex" -> ctx.selfIndex.asJson, "extension" -> ctx.extension.asJson, "validationSettings" -> ctx.validationSettings.asJson, "costLimit" -> ctx.costLimit.asJson, @@ -264,7 +266,7 @@ case object LastBlockUtxoRootHash extends NotReadyValueAvlTree with ValueCompani } -/** When interpreted evaluates to a BoxConstant built from Context.self */ +/** When interpreted evaluates to a BoxConstant built from Context.selfIndex */ case object Self extends NotReadyValueBox with ValueCompanion { override def companion = this override def opCode: OpCode = OpCodes.SelfCode diff --git a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index 20b9b56e3b..ab5b6464f4 100644 --- a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -79,6 +79,7 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC case class TestInputBox(tx: TransactionCandidate, utxoBox: OutBox) extends InputBox { private [dsl] def toErgoContext: ErgoLikeContext = { val propSpec = utxoBox.propSpec + val boxesToSpend = tx.inputs.map(_.utxoBox.ergoBox).toIndexedSeq val ctx = new ErgoLikeContext( currentHeight = tx.block.height, lastBlockUtxoRoot = AvlTreeData.dummy, @@ -86,9 +87,9 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC headers = noHeaders, preHeader = dummyPreHeader(tx.block.height, ErgoLikeContext.dummyPubkey), dataBoxes = tx.dataInputs.map(_.utxoBox.ergoBox).toIndexedSeq, - boxesToSpend = tx.inputs.map(_.utxoBox.ergoBox).toIndexedSeq, + boxesToSpend = boxesToSpend, spendingTransaction = testSuite.createTransaction(tx.outputs.map(_.ergoBox).toIndexedSeq), - self = utxoBox.ergoBox, + selfIndex = boxesToSpend.indexOf(utxoBox.ergoBox), extension = ContextExtension.empty, validationSettings = ValidationRules.currentSettings, costLimit = ScriptCostLimit.value, diff --git a/src/test/scala/sigmastate/CostingSpecification.scala b/src/test/scala/sigmastate/CostingSpecification.scala index a053be663a..9d8a8df6bb 100644 --- a/src/test/scala/sigmastate/CostingSpecification.scala +++ b/src/test/scala/sigmastate/CostingSpecification.scala @@ -69,7 +69,7 @@ class CostingSpecification extends SigmaTestingData { headers = headers, preHeader = preHeader, dataBoxes = IndexedSeq(dataBox), boxesToSpend = IndexedSeq(selfBox), - spendingTransaction = tx, self = selfBox, extension, ValidationRules.currentSettings, ScriptCostLimit.value, CostTable.interpreterInitCost) + spendingTransaction = tx, selfIndex = 0, extension, ValidationRules.currentSettings, ScriptCostLimit.value, CostTable.interpreterInitCost) def cost(script: String)(expCost: Int): Unit = { val ergoTree = compiler.compile(env, script) diff --git a/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala b/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala index 9da3ba7d2d..01b6d063c8 100644 --- a/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala @@ -356,7 +356,7 @@ class LetsSpecification extends SigmaTestingCommons { dataBoxes = IndexedSeq(directoryBox), boxesToSpend = IndexedSeq(userBoxBefore0, userBoxBefore1), spendingTransaction = issuanceTx, - self = userBoxBefore0) + selfIndex = 0) val managementProver = new ContextEnrichingTestProvingInterpreter() .withContextExtender(1, ByteArrayConstant(proof)) diff --git a/src/test/scala/special/sigma/SigmaTestingData.scala b/src/test/scala/special/sigma/SigmaTestingData.scala index e5b9bb6f1e..d9ec62e7f8 100644 --- a/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/src/test/scala/special/sigma/SigmaTestingData.scala @@ -96,7 +96,7 @@ trait SigmaTestingData extends SigmaTestingCommons with SigmaTypeGens { preHeader.minerPk.getEncoded.toArray, boxesToSpend = IndexedSeq(inBox), spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(outBox)), - self = inBox, headers = headers, preHeader = preHeader, dataBoxes = IndexedSeq(dataBox), + selfIndex = 0, headers = headers, preHeader = preHeader, dataBoxes = IndexedSeq(dataBox), extension = ContextExtension.empty, validationSettings = ValidationRules.currentSettings, costLimit = ScriptCostLimit.value, initCost = 0L) From 7f16deb1f5569421aed42433f52a73605633d638 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 29 Jul 2019 13:41:21 +0300 Subject: [PATCH 11/64] remove get ErgoLikeContext.currentHeight and minerPubkey from ErgoLikeContext.preHeader; --- .../org/ergoplatform/ErgoLikeContext.scala | 40 ++++++++----------- .../ergoplatform/dsl/TestContractSpec.scala | 2 - .../sigmastate/CostingSpecification.scala | 2 - .../special/sigma/SigmaTestingData.scala | 2 - 4 files changed, 17 insertions(+), 29 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 00ecbeccf3..9c0bbf9142 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -25,13 +25,10 @@ import scala.util.Try case class BlockchainState(currentHeight: Height, lastBlockUtxoRoot: AvlTreeData) /** - * TODO currentHeight and minerPubkey should be calculated from PreHeader * TODO lastBlockUtxoRoot should be calculated from headers if it is nonEmpty * * @param selfIndex - index of the box in `boxesToSpend` that contains the script we're evaluating - * @param currentHeight - height of a block with the current `spendingTransaction` * @param lastBlockUtxoRoot - state root before current block application - * @param minerPubkey - public key of a miner of the block with the current `spendingTransaction` * @param headers - fixed number of last block headers in descending order (first header is the newest one) * @param preHeader - fields of block header with the current `spendingTransaction`, that can be predicted * by a miner before it's formation @@ -43,9 +40,7 @@ case class BlockchainState(currentHeight: Height, lastBlockUtxoRoot: AvlTreeData * @param costLimit hard limit on accumulated execution cost, if exceeded lead to CostLimitException to be thrown * @param initCost initial value of execution cost already accumulated before Interpreter.verify is called */ -class ErgoLikeContext(val currentHeight: Height, - val lastBlockUtxoRoot: AvlTreeData, - val minerPubkey: Array[Byte], +class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val headers: Coll[Header], val preHeader: PreHeader, val dataBoxes: IndexedSeq[ErgoBox], @@ -61,39 +56,43 @@ class ErgoLikeContext(val currentHeight: Height, assert(preHeader != null) assert(spendingTransaction != null) assert(boxesToSpend.isDefinedAt(selfIndex), s"Self box if defined should be among boxesToSpend") - assert(preHeader.height == currentHeight, "Incorrect preHeader height") - assert(java.util.Arrays.equals(minerPubkey, preHeader.minerPk.getEncoded.toArray), "Incorrect preHeader minerPubkey") assert(headers.toArray.headOption.forall(h => java.util.Arrays.equals(h.stateRoot.digest.toArray, lastBlockUtxoRoot.digest)), "Incorrect lastBlockUtxoRoot") cfor(0)(_ < headers.length, _ + 1) { i => if (i > 0) assert(headers(i - 1).parentId == headers(i).id, s"Incorrect chain: ${headers(i - 1).parentId},${headers(i).id}") } assert(headers.toArray.headOption.forall(_.id == preHeader.parentId), s"preHeader.parentId should be id of the best header") + // height of a block with the current `spendingTransaction` + val currentHeight: Height = preHeader.height + + // public key of a miner of the block with the current `spendingTransaction` + val minerPubkey: GroupElement = preHeader.minerPk + val self: ErgoBox = boxesToSpend(selfIndex) override def withCostLimit(newCostLimit: Long): ErgoLikeContext = new ErgoLikeContext( - currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, + lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, newCostLimit, initCost) override def withInitCost(newCost: Long): ErgoLikeContext = new ErgoLikeContext( - currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, + lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, newCost) override def withValidationSettings(newVs: SigmaValidationSettings): ErgoLikeContext = new ErgoLikeContext( - currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, + lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, newVs, costLimit, initCost) override def withExtension(newExtension: ContextExtension): ErgoLikeContext = new ErgoLikeContext( - currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, + lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, newExtension, validationSettings, costLimit, initCost) def withTransaction(newSpendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput]): ErgoLikeContext = new ErgoLikeContext( - currentHeight, lastBlockUtxoRoot, minerPubkey, headers, preHeader, + lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, newSpendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) import ErgoLikeContext._ @@ -110,9 +109,9 @@ class ErgoLikeContext(val currentHeight: Height, } val vars = contextVars(varMap ++ extensions) val avlTree = CAvlTree(lastBlockUtxoRoot) - new CostingDataContext( + CostingDataContext( dataInputs, headers, preHeader, inputs, outputs, currentHeight, self.toTestBox(isCost), avlTree, - minerPubkey.toColl, + minerPubkey.getEncoded, vars, isCost) } @@ -146,10 +145,7 @@ object ErgoLikeContext extends JsonCodecs { self: ErgoBox, extension: ContextExtension = ContextExtension.empty, vs: SigmaValidationSettings = ValidationRules.currentSettings) = - new ErgoLikeContext(currentHeight, lastBlockUtxoRoot, minerPubkey, - noHeaders, - dummyPreHeader(currentHeight, minerPubkey), - noBoxes, + new ErgoLikeContext(lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), noBoxes, boxesToSpend, spendingTransaction, boxesToSpend.indexOf(self), extension, vs, ScriptCostLimit.value, 0L) def apply(currentHeight: Height, @@ -159,9 +155,7 @@ object ErgoLikeContext extends JsonCodecs { boxesToSpend: IndexedSeq[ErgoBox], spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], selfIndex: Int) = - new ErgoLikeContext(currentHeight, lastBlockUtxoRoot, minerPubkey, - noHeaders, - dummyPreHeader(currentHeight, minerPubkey), + new ErgoLikeContext(lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), dataBoxes, boxesToSpend, spendingTransaction, selfIndex, ContextExtension.empty, ValidationRules.currentSettings, ScriptCostLimit.value, 0L) @@ -212,7 +206,7 @@ object ErgoLikeContext extends JsonCodecs { Json.obj( "currentHeight" -> ctx.currentHeight.asJson, "lastBlockUtxoRoot" -> ctx.lastBlockUtxoRoot.asJson, - "minerPubkey" -> ctx.minerPubkey.asJson, + "minerPubkey" -> ctx.minerPubkey.getEncoded.asJson, "headers" -> ctx.headers.toArray.toSeq.asJson, "preHeader" -> ctx.preHeader.asJson, "dataBoxes" -> ctx.dataBoxes.asJson, diff --git a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index ab5b6464f4..2c679f2a7a 100644 --- a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -81,9 +81,7 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC val propSpec = utxoBox.propSpec val boxesToSpend = tx.inputs.map(_.utxoBox.ergoBox).toIndexedSeq val ctx = new ErgoLikeContext( - currentHeight = tx.block.height, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, headers = noHeaders, preHeader = dummyPreHeader(tx.block.height, ErgoLikeContext.dummyPubkey), dataBoxes = tx.dataInputs.map(_.utxoBox.ergoBox).toIndexedSeq, diff --git a/src/test/scala/sigmastate/CostingSpecification.scala b/src/test/scala/sigmastate/CostingSpecification.scala index 9d8a8df6bb..4c1580d1df 100644 --- a/src/test/scala/sigmastate/CostingSpecification.scala +++ b/src/test/scala/sigmastate/CostingSpecification.scala @@ -63,9 +63,7 @@ class CostingSpecification extends SigmaTestingData { lazy val tx = createTransaction(IndexedSeq(outBoxA, outBoxB)) lazy val context = new ErgoLikeContext( - currentHeight = preHeader.height, lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, - minerPubkey = preHeader.minerPk.getEncoded.toArray, headers = headers, preHeader = preHeader, dataBoxes = IndexedSeq(dataBox), boxesToSpend = IndexedSeq(selfBox), diff --git a/src/test/scala/special/sigma/SigmaTestingData.scala b/src/test/scala/special/sigma/SigmaTestingData.scala index d9ec62e7f8..f24e95788e 100644 --- a/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/src/test/scala/special/sigma/SigmaTestingData.scala @@ -91,9 +91,7 @@ trait SigmaTestingData extends SigmaTestingCommons with SigmaTypeGens { votes = Colls.emptyColl[Byte] ) val ergoCtx = new ErgoLikeContext( - currentHeight = preHeader.height, lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, - preHeader.minerPk.getEncoded.toArray, boxesToSpend = IndexedSeq(inBox), spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(outBox)), selfIndex = 0, headers = headers, preHeader = preHeader, dataBoxes = IndexedSeq(dataBox), From 1dc362f1c89aedc10e2d2a3bd2d2e26e4cc4a280 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 29 Jul 2019 13:53:02 +0300 Subject: [PATCH 12/64] remove ErgoLikeContext.currentHeight and minerPubkey from json repr; --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 9c0bbf9142..8e7dadbac4 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -204,9 +204,7 @@ object ErgoLikeContext extends JsonCodecs { implicit val jsonEncoder: Encoder[ErgoLikeContext] = { ctx => Json.obj( - "currentHeight" -> ctx.currentHeight.asJson, "lastBlockUtxoRoot" -> ctx.lastBlockUtxoRoot.asJson, - "minerPubkey" -> ctx.minerPubkey.getEncoded.asJson, "headers" -> ctx.headers.toArray.toSeq.asJson, "preHeader" -> ctx.preHeader.asJson, "dataBoxes" -> ctx.dataBoxes.asJson, From 282313ebcbefa183a2b7e997e4f7cfc9164a805d Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 29 Jul 2019 17:37:47 +0300 Subject: [PATCH 13/64] draft ErgoLikeContext json decoder; implement AvlTreeData PreHeader, Header json decoders; draft ErgoBox json decoder; draft JsonSerializationSpec; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 11 +++ .../org/ergoplatform/ErgoLikeContext.scala | 17 +++++ .../scala/org/ergoplatform/JsonCodecs.scala | 69 +++++++++++++++++-- src/main/scala/sigmastate/AvlTreeData.scala | 8 +++ .../sigmastate/eval/CostingDataContext.scala | 4 ++ .../GroupElementSerializer.scala | 2 + .../ergoplatform/JsonSerializationSpec.scala | 21 ++++++ 7 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 src/test/scala/org/ergoplatform/JsonSerializationSpec.scala diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index be0cbc2bbf..5bf5163bef 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -214,4 +214,15 @@ object ErgoBox extends JsonCodecs { ) } + implicit val jsonDecoder: Decoder[ErgoBox] = { cursor => + for { + value <- cursor.downField("value").as[Long] + ergoTreeBytes <- cursor.downField("ergoTree").as[Array[Byte]] + additionalTokens <- cursor.downField("assets").as[Seq[(TokenId, Long)]] + creationHeight <- cursor.downField("creationHeight").as[Int] + // TODO: decode + additionalRegisters <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, _ <: EvaluatedValue[_ <: SType]]] + } yield ErgoBox(value, ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(ergoTreeBytes), creationHeight, additionalTokens) + } + } diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 8e7dadbac4..ed04191a8e 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -218,6 +218,23 @@ object ErgoLikeContext extends JsonCodecs { "initCost" -> ctx.initCost.asJson ) } + + implicit val jsonDecoder: Decoder[ErgoLikeContext] = { cursor => + for { + lastBlockUtxoRoot <- cursor.downField("lastBlockUtxoRoot").as[AvlTreeData] + headers <- cursor.downField("headers").as[Seq[Header]] + preHeader <- cursor.downField("preHeader").as[PreHeader] + dataBoxes <- cursor.downField("dataBoxes").as[IndexedSeq[ErgoBox]] + boxesToSpend <- cursor.downField("boxesToSpend").as[IndexedSeq[ErgoBox]] + spendingTransaction <- cursor.downField("spendingTransaction").as[ErgoLikeTransaction] + selfIndex <- cursor.downField("selfIndex").as[Int] + extension <- cursor.downField("extension").as[ContextExtension] + validationSettings <- cursor.downField("validationSettings").as[SigmaValidationSettings] + costLimit <- cursor.downField("costLimit").as[Long] + initCost <- cursor.downField("initCost").as[Long] + } yield new ErgoLikeContext(lastBlockUtxoRoot, Colls.fromArray(headers.toArray), preHeader, + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) + } } /** When interpreted evaluates to a ByteArrayConstant built from Context.minerPubkey */ diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index aab9720634..d115ede4df 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -6,23 +6,49 @@ import org.ergoplatform.settings.Algos import scorex.crypto.authds.ADKey import scorex.crypto.hash.Digest32 import scorex.util.ModifierId -import sigmastate.{AvlTreeData, SType} import sigmastate.Values.EvaluatedValue -import sigmastate.eval.{CAvlTree, WrapperOf} -import sigmastate.serialization.ValueSerializer +import sigmastate.eval.{CGroupElement, CPreHeader, WrapperOf, _} +import sigmastate.serialization.{GroupElementSerializer, ValueSerializer} +import sigmastate.{AvlTreeData, SType} import special.collection.Coll import special.sigma.{Header, PreHeader} +import scala.util.Try + trait JsonCodecs { //TODO: remove in ergo + def fromTry[T](tryResult: Try[T])(implicit cursor: ACursor): Either[DecodingFailure, T] = { + tryResult.fold(e => Left(DecodingFailure(e.toString, cursor.history)), Right.apply) + } + + def fromOption[T](maybeResult: Option[T])(implicit cursor: ACursor): Either[DecodingFailure, T] = { + maybeResult.fold[Either[DecodingFailure, T]](Left(DecodingFailure("No value found", cursor.history)))(Right.apply) + } + + private def bytesDecoder[T](transform: Array[Byte] => T): Decoder[T] = { implicit cursor => + for { + str <- cursor.as[String] + bytes <- fromTry(Algos.decode(str)) + } yield transform(bytes) + } + implicit val sigmaBigIntEncoder: Encoder[special.sigma.BigInt] = { bigInt => - JsonNumber.fromDecimalStringUnsafe(bigInt.toString).asJson + JsonNumber.fromDecimalStringUnsafe(bigInt.asInstanceOf[WrapperOf[BigInt]].wrappedValue.toString).asJson + } + + implicit val sigmaBigIntDecoder: Decoder[special.sigma.BigInt] = { implicit cursor => + for { + str <- cursor.as[String] + bigInt <- fromOption(JsonNumber.fromString(str).flatMap(_.toBigInt)) + } yield CBigInt(bigInt.bigInteger) } implicit val arrayBytesEncoder: Encoder[Array[Byte]] = Algos.encode(_).asJson + implicit val arrayBytesDecoder: Decoder[Array[Byte]] = bytesDecoder(x => x) + implicit val collBytesEncoder: Encoder[Coll[Byte]] = Algos.encode(_).asJson -// implicit val byteSeqEncoder: Encoder[IndexedSeq[Byte]] = { in => Algos.encode(in.toArray).asJson } + implicit val collBytesDecoder: Decoder[Coll[Byte]] = bytesDecoder(x => Colls.fromArray(x)) implicit val adKeyEncoder: Encoder[ADKey] = _.array.asJson @@ -51,6 +77,27 @@ trait JsonCodecs { ).asJson } + implicit val headerDecoder: Decoder[Header] = { cursor => + for { + id <- cursor.downField("id").as[Coll[Byte]] + version <- cursor.downField("version").as[Byte] + parentId <- cursor.downField("parentId").as[Coll[Byte]] + adProofsRoot <- cursor.downField("adProofsRoot").as[Coll[Byte]] + stateRoot <- cursor.downField("stateRoot").as[AvlTreeData] + transactionsRoot <- cursor.downField("transactionsRoot").as[Coll[Byte]] + timestamp <- cursor.downField("timestamp").as[Long] + nBits <- cursor.downField("nBits").as[Long] + height <- cursor.downField("height").as[Int] + extensionRoot <- cursor.downField("extensionRoot").as[Coll[Byte]] + minerPk <- cursor.downField("minerPk").as[Coll[Byte]] + powOnetimePk <- cursor.downField("powOnetimePk").as[Coll[Byte]] + powNonce <- cursor.downField("powNonce").as[Coll[Byte]] + powDistance <- cursor.downField("powDistance").as[special.sigma.BigInt] + votes <- cursor.downField("votes").as[Coll[Byte]] + } yield new CHeader(id, version, parentId, adProofsRoot, stateRoot, transactionsRoot, timestamp, nBits, + height, extensionRoot, CGroupElement.decode(minerPk), CGroupElement.decode(powOnetimePk), powNonce, powDistance, votes) + } + implicit val preHeaderEncoder: Encoder[PreHeader] = { v: PreHeader => Map( "version" -> v.version.asJson, @@ -63,6 +110,18 @@ trait JsonCodecs { ).asJson } + implicit val preHeaderDecoder: Decoder[PreHeader] = { cursor => + for { + versionId <- cursor.downField("versionId").as[Byte] + parentId <- cursor.downField("parentId").as[Coll[Byte]] + timeStamp <- cursor.downField("timeStamp").as[Long] + nBits <- cursor.downField("nBits").as[Long] + height <- cursor.downField("height").as[Int] + minerPk <- cursor.downField("minerPk").as[Coll[Byte]] + votes <- cursor.downField("votes").as[Coll[Byte]] + } yield CPreHeader(versionId, parentId, timeStamp, nBits, height, CGroupElement.decode(minerPk), votes) + } + implicit val evaluatedValueEncoder: Encoder[EvaluatedValue[SType]] = { value => ValueSerializer.serialize(value).asJson } diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index 28a9f7c4bb..bc0c945204 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -111,4 +111,12 @@ object AvlTreeData { ) } + implicit val jsonDecoder: Decoder[AvlTreeData] = { cursor => + for { + digest <- cursor.downField("digest").as[Array[Byte]] + treeFlagsByte <- cursor.downField("treeFlags").as[Byte] + keyLength <- cursor.downField("keyLength").as[Int] + valueLength <- cursor.downField("valueLength").as[Option[Int]] + } yield new AvlTreeData(ADDigest @@ digest, AvlTreeFlags(treeFlagsByte), keyLength, valueLength) + } } diff --git a/src/main/scala/sigmastate/eval/CostingDataContext.scala b/src/main/scala/sigmastate/eval/CostingDataContext.scala index 4e5641af19..f81805b707 100644 --- a/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -44,6 +44,10 @@ case class CGroupElement(override val wrappedValue: EcPointType) extends TestGro } +object CGroupElement { + def decode(bytes: Coll[Byte]): CGroupElement = CGroupElement(GroupElementSerializer.parse(bytes.toArray)) +} + case class CSigmaProp(sigmaTree: SigmaBoolean) extends SigmaProp with WrapperOf[SigmaBoolean] { override def wrappedValue: SigmaBoolean = sigmaTree diff --git a/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala b/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala index cb8adb79aa..4305e899c5 100644 --- a/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala +++ b/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala @@ -43,4 +43,6 @@ object GroupElementSerializer extends SigmaSerializer[EcPointType, EcPointType] } } + def parse(bytes: Array[Byte]): EcPointType = parse(SigmaSerializer.startReader(bytes)) + } diff --git a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala new file mode 100644 index 0000000000..83625b44a6 --- /dev/null +++ b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala @@ -0,0 +1,21 @@ +package org.ergoplatform + +import io.circe._ +import io.circe.syntax._ +import sigmastate.helpers.SigmaTestingCommons + +class JsonSerializationSpec extends SigmaTestingCommons { + + property("ErgoFullBlock should be encoded into JSON and decoded back correctly") { + + // TODO: implement ErgoLikeContext generator + val ctx: ErgoLikeContext = ??? + + val ctxJson: Json = ctx.asJson + val ctxDecoded: ErgoLikeContext = ctxJson.as[ErgoLikeContext].toTry.get + + // TODO: implement ErgoLikeContext.equals + ctxDecoded shouldEqual ctx + } + +} From fbec6d038f582af96a7a065d02644047adcdaf3c Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 30 Jul 2019 13:13:41 +0300 Subject: [PATCH 14/64] implement ErgoBox.additionalRegisters json encoder/decoder; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 9 +++------ .../scala/org/ergoplatform/JsonCodecs.scala | 20 ++++++++++++++++++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index 5bf5163bef..645a5ef9bf 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -208,9 +208,7 @@ object ErgoBox extends JsonCodecs { "ergoTree" -> ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(box.ergoTree).asJson, "assets" -> box.additionalTokens.toArray.toSeq.asJson, "creationHeight" -> box.creationHeight.asJson, - "additionalRegisters" -> box.additionalRegisters.map { case (key, value) => - s"R${key.number}" -> evaluatedValueEncoder(value) - }.asJson + "additionalRegisters" -> box.additionalRegisters.asJson ) } @@ -220,9 +218,8 @@ object ErgoBox extends JsonCodecs { ergoTreeBytes <- cursor.downField("ergoTree").as[Array[Byte]] additionalTokens <- cursor.downField("assets").as[Seq[(TokenId, Long)]] creationHeight <- cursor.downField("creationHeight").as[Int] - // TODO: decode - additionalRegisters <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, _ <: EvaluatedValue[_ <: SType]]] - } yield ErgoBox(value, ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(ergoTreeBytes), creationHeight, additionalTokens) + additionalRegisters <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] + } yield ErgoBox(value, ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(ergoTreeBytes), creationHeight, additionalTokens, additionalRegisters) } } diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index d115ede4df..695ba37c98 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -2,13 +2,14 @@ package org.ergoplatform import io.circe._ import io.circe.syntax._ +import org.ergoplatform.ErgoBox.NonMandatoryRegisterId import org.ergoplatform.settings.Algos import scorex.crypto.authds.ADKey import scorex.crypto.hash.Digest32 import scorex.util.ModifierId import sigmastate.Values.EvaluatedValue import sigmastate.eval.{CGroupElement, CPreHeader, WrapperOf, _} -import sigmastate.serialization.{GroupElementSerializer, ValueSerializer} +import sigmastate.serialization.ValueSerializer import sigmastate.{AvlTreeData, SType} import special.collection.Coll import special.sigma.{Header, PreHeader} @@ -56,6 +57,16 @@ trait JsonCodecs { implicit val modifierIdEncoder: Encoder[ModifierId] = _.asInstanceOf[String].asJson + implicit val registerIdEncoder: KeyEncoder[NonMandatoryRegisterId] = { regId => + s"R${regId.number}" + } + + implicit val registerIdDecoder: KeyDecoder[NonMandatoryRegisterId] = { key => + ErgoBox.registerByName.get(key).collect { + case nonMandatoryId: NonMandatoryRegisterId => nonMandatoryId + } + } + implicit val headerEncoder: Encoder[Header] = { h: Header => Map( "id" -> h.id.asJson, @@ -125,4 +136,11 @@ trait JsonCodecs { implicit val evaluatedValueEncoder: Encoder[EvaluatedValue[SType]] = { value => ValueSerializer.serialize(value).asJson } + + implicit val evaluatedValueDecoder: Decoder[EvaluatedValue[SType]] = Decoder.decodeString.emap { str => + Algos.decode(str).flatMap { bytes => + Try { ValueSerializer.deserialize(bytes).asInstanceOf[EvaluatedValue[SType]] } + }.toEither.left.map(_.getMessage) + } + } From 66e4ed31700b29ba3515b90b9e60432ea43a3cf9 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 30 Jul 2019 13:35:51 +0300 Subject: [PATCH 15/64] fix ErgoBox json codec; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 7 ++++--- src/main/scala/org/ergoplatform/JsonCodecs.scala | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index 645a5ef9bf..742651573c 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -206,9 +206,10 @@ object ErgoBox extends JsonCodecs { "boxId" -> box.id.asJson, "value" -> box.value.asJson, "ergoTree" -> ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(box.ergoTree).asJson, - "assets" -> box.additionalTokens.toArray.toSeq.asJson, + "assets" -> box.additionalTokens.toArray.toSeq + .asJson(Encoder.encodeSeq(Encoder.encodeTuple2(digest32Encoder, Encoder.encodeLong))), "creationHeight" -> box.creationHeight.asJson, - "additionalRegisters" -> box.additionalRegisters.asJson + "additionalRegisters" -> box.additionalRegisters.asInstanceOf[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]].asJson ) } @@ -216,7 +217,7 @@ object ErgoBox extends JsonCodecs { for { value <- cursor.downField("value").as[Long] ergoTreeBytes <- cursor.downField("ergoTree").as[Array[Byte]] - additionalTokens <- cursor.downField("assets").as[Seq[(TokenId, Long)]] + additionalTokens <- cursor.downField("assets").as(Decoder.decodeSeq(Decoder.decodeTuple2(digest32Decoder, Decoder.decodeLong))) creationHeight <- cursor.downField("creationHeight").as[Int] additionalRegisters <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] } yield ErgoBox(value, ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(ergoTreeBytes), creationHeight, additionalTokens, additionalRegisters) diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index 695ba37c98..e002d26c43 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -54,6 +54,7 @@ trait JsonCodecs { implicit val adKeyEncoder: Encoder[ADKey] = _.array.asJson implicit val digest32Encoder: Encoder[Digest32] = _.array.asJson + implicit val digest32Decoder: Decoder[Digest32] = bytesDecoder(x => Digest32 @@ x) implicit val modifierIdEncoder: Encoder[ModifierId] = _.asInstanceOf[String].asJson From b474368fb6730f0c518cead04c7ceb6783cea49e Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 30 Jul 2019 16:16:12 +0300 Subject: [PATCH 16/64] add ErgoLikeTransaction json decoder; --- .../ergoplatform/ErgoLikeTransaction.scala | 24 +++++++++++- src/main/scala/org/ergoplatform/Input.scala | 14 +++++++ .../scala/org/ergoplatform/JsonCodecs.scala | 39 +++++++++++++++---- .../interpreter/ProverInterpreter.scala | 8 ++++ 4 files changed, 76 insertions(+), 9 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index 7e5e3ab499..41ccfcdede 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -4,19 +4,22 @@ import java.util import io.circe._ import io.circe.syntax._ -import org.ergoplatform.ErgoBox.TokenId +import org.ergoplatform.ErgoBox.{BoxId, NonMandatoryRegisterId, TokenId} import scorex.crypto.authds.ADKey import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util._ +import sigmastate.SType import sigmastate.interpreter.ProverResult import sigmastate.serialization.SigmaSerializer import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import special.collection.ExtensionMethods._ import sigmastate.eval.Extensions._ import spire.syntax.all.cfor + import scala.collection.mutable import scala.util.Try import sigmastate.SType._ +import sigmastate.Values.{ErgoTree, EvaluatedValue} import sigmastate.eval._ trait ErgoBoxReader { @@ -202,4 +205,23 @@ object ErgoLikeTransaction extends JsonCodecs { "outputs" -> tx.outputs.asJson ) } + + private implicit val outputDecoder: Decoder[(ErgoBoxCandidate, Option[BoxId])] = { cursor => + for { + maybeId <- cursor.downField("boxId").as[Option[BoxId]] + value <- cursor.downField("value").as[Long] + creationHeight <- cursor.downField("creationHeight").as[Int] + ergoTree <- cursor.downField("ergoTree").as[ErgoTree] + assets <- cursor.downField("assets").as[Seq[(ErgoBox.TokenId, Long)]] // TODO optimize: encode directly into Coll avoiding allocation of Tuple2 for each element + registers <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] + } yield (new ErgoBoxCandidate(value, ergoTree, creationHeight, assets.toColl, registers), maybeId) + } + + implicit val jsonDecoder: Decoder[ErgoLikeTransaction] = { implicit cursor => + for { + inputs <- cursor.downField("inputs").as[IndexedSeq[Input]] + dataInputs <- cursor.downField("dataInputs").as[IndexedSeq[DataInput]] + outputsWithIndex <- cursor.downField("outputs").as[IndexedSeq[(ErgoBoxCandidate, Option[BoxId])]] + } yield new ErgoLikeTransaction(inputs, dataInputs, outputsWithIndex.map(_._1)) + } } diff --git a/src/main/scala/org/ergoplatform/Input.scala b/src/main/scala/org/ergoplatform/Input.scala index 3457058de3..a0c9cc9bb6 100644 --- a/src/main/scala/org/ergoplatform/Input.scala +++ b/src/main/scala/org/ergoplatform/Input.scala @@ -25,6 +25,13 @@ object DataInput extends JsonCodecs { "boxId" -> input.boxId.asJson, ) } + + implicit val jsonDecoder: Decoder[DataInput] = { cursor => + for { + boxId <- cursor.downField("boxId").as[ADKey] + } yield DataInput(boxId) + } + } /** @@ -86,4 +93,11 @@ object Input extends JsonCodecs { ) } + implicit val jsonDecoder: Decoder[Input] = { cursor => + for { + boxId <- cursor.downField("boxId").as[ADKey] + proof <- cursor.downField("spendingProof").as[ProverResult] + } yield Input(boxId, proof) + } + } diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index e002d26c43..cad8058ac0 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -1,5 +1,6 @@ package org.ergoplatform +import cats.syntax.either._ import io.circe._ import io.circe.syntax._ import org.ergoplatform.ErgoBox.NonMandatoryRegisterId @@ -7,9 +8,9 @@ import org.ergoplatform.settings.Algos import scorex.crypto.authds.ADKey import scorex.crypto.hash.Digest32 import scorex.util.ModifierId -import sigmastate.Values.EvaluatedValue +import sigmastate.Values.{ErgoTree, EvaluatedValue} import sigmastate.eval.{CGroupElement, CPreHeader, WrapperOf, _} -import sigmastate.serialization.ValueSerializer +import sigmastate.serialization.{ErgoTreeSerializer, ValueSerializer} import sigmastate.{AvlTreeData, SType} import special.collection.Coll import special.sigma.{Header, PreHeader} @@ -27,6 +28,10 @@ trait JsonCodecs { maybeResult.fold[Either[DecodingFailure, T]](Left(DecodingFailure("No value found", cursor.history)))(Right.apply) } + def fromThrows[T](throwsBlock: => T)(implicit cursor: ACursor): Either[DecodingFailure, T] = { + Either.catchNonFatal(throwsBlock).leftMap(e => DecodingFailure(e.toString, cursor.history)) + } + private def bytesDecoder[T](transform: Array[Byte] => T): Decoder[T] = { implicit cursor => for { str <- cursor.as[String] @@ -49,12 +54,13 @@ trait JsonCodecs { implicit val arrayBytesDecoder: Decoder[Array[Byte]] = bytesDecoder(x => x) implicit val collBytesEncoder: Encoder[Coll[Byte]] = Algos.encode(_).asJson - implicit val collBytesDecoder: Decoder[Coll[Byte]] = bytesDecoder(x => Colls.fromArray(x)) + implicit val collBytesDecoder: Decoder[Coll[Byte]] = bytesDecoder(Colls.fromArray(_)) implicit val adKeyEncoder: Encoder[ADKey] = _.array.asJson + implicit val adKeyDecoder: Decoder[ADKey] = bytesDecoder(ADKey @@ _) implicit val digest32Encoder: Encoder[Digest32] = _.array.asJson - implicit val digest32Decoder: Decoder[Digest32] = bytesDecoder(x => Digest32 @@ x) + implicit val digest32Decoder: Decoder[Digest32] = bytesDecoder(Digest32 @@ _) implicit val modifierIdEncoder: Encoder[ModifierId] = _.asInstanceOf[String].asJson @@ -138,10 +144,27 @@ trait JsonCodecs { ValueSerializer.serialize(value).asJson } - implicit val evaluatedValueDecoder: Decoder[EvaluatedValue[SType]] = Decoder.decodeString.emap { str => - Algos.decode(str).flatMap { bytes => - Try { ValueSerializer.deserialize(bytes).asInstanceOf[EvaluatedValue[SType]] } - }.toEither.left.map(_.getMessage) + implicit val evaluatedValueDecoder: Decoder[EvaluatedValue[SType]] = { + decodeEvaluatedValue(_.asInstanceOf[EvaluatedValue[SType]]) + } + + def decodeEvaluatedValue[T](transform: EvaluatedValue[SType] => T): Decoder[T] = { implicit cursor: ACursor => + cursor.as[Array[Byte]] flatMap { bytes => + fromThrows(transform(ValueSerializer.deserialize(bytes).asInstanceOf[EvaluatedValue[SType]])) + } } + implicit val ergoTreeEncoder: Encoder[ErgoTree] = { value => + ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(value).asJson + } + + def decodeErgoTree[T](transform: ErgoTree => T): Decoder[T] = { implicit cursor: ACursor => + cursor.as[Array[Byte]] flatMap { bytes => + fromThrows(transform(ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes))) + } + } + + implicit val ergoTreeDecoder: Decoder[ErgoTree] = { + decodeErgoTree(_.asInstanceOf[ErgoTree]) + } } diff --git a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index f54acb4007..fb56e5ff81 100644 --- a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -68,6 +68,14 @@ object ProverResult extends JsonCodecs { "extension" -> v.extension.asJson ) } + + implicit val jsonDecoder: Decoder[ProverResult] = { cursor => + for { + proofBytes <- cursor.downField("proofBytes").as[Array[Byte]] + extMap <- cursor.downField("extension").as[Map[Byte, EvaluatedValue[SType]]] + } yield ProverResult(proofBytes, ContextExtension(extMap)) + } + } case class CostedProverResult(override val proof: Array[Byte], From 4b8d5cff800abd3b05499594c6dfa7fb1d9c2d6f Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 30 Jul 2019 17:19:49 +0300 Subject: [PATCH 17/64] add ContextExtension and SigmaValidationSettings json decoders; --- .../validation/SigmaValidationSettings.scala | 14 ++++++++------ .../ergoplatform/validation/ValidationRules.scala | 10 ---------- .../interpreter/InterpreterContext.scala | 6 ++++++ .../sigmastate/serialization/SigmaSerializer.scala | 4 ++++ .../org/ergoplatform/JsonSerializationSpec.scala | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala b/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala index 6e2fa2c3da..f2a7e5bd6c 100644 --- a/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala +++ b/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala @@ -60,13 +60,15 @@ abstract class SigmaValidationSettings extends Iterable[(Short, (ValidationRule, } object SigmaValidationSettings extends JsonCodecs { + implicit val jsonEncoder: Encoder[SigmaValidationSettings] = { v => - Json.fromValues(v.toSeq.map { case (_, (rule, status)) => - Json.obj( - "rule" -> rule.asJson, - "status" -> status.statusCode.asJson - ) - }) + SigmaValidationSettingsSerializer.toBytes(v).asJson + } + + implicit val jsonDecoder: Decoder[SigmaValidationSettings] = { implicit cursor: ACursor => + cursor.as[Array[Byte]] flatMap { bytes => + fromThrows(SigmaValidationSettingsSerializer.fromBytes(bytes)) + } } } diff --git a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index a85055cc49..5255f7857e 100644 --- a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -62,16 +62,6 @@ case class ValidationRule( } -object ValidationRule extends JsonCodecs { - - implicit val jsonEncoder: Encoder[ValidationRule] = { v => - Json.obj( - "id" -> v.id.asJson, - "description" -> v.description.asJson - ) - } -} - /** Base class for all exceptions which may be thrown by validation rules. * Instances of this class are used as messages to communicate soft-fork information, * from the context where the soft-fork condition is detected (such as in ValidationRules), diff --git a/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index b473d85014..2a335c64d3 100644 --- a/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -46,6 +46,12 @@ object ContextExtension extends JsonCodecs { key -> evaluatedValueEncoder(value) }.asJson } + + implicit val jsonDecoder: Decoder[ContextExtension] = { cursor => + for { + values <- cursor.as[Map[Byte, EvaluatedValue[SType]]] + } yield ContextExtension(values) + } } diff --git a/src/main/scala/sigmastate/serialization/SigmaSerializer.scala b/src/main/scala/sigmastate/serialization/SigmaSerializer.scala index 38dfe22c0d..fc6e0c4b56 100644 --- a/src/main/scala/sigmastate/serialization/SigmaSerializer.scala +++ b/src/main/scala/sigmastate/serialization/SigmaSerializer.scala @@ -84,6 +84,10 @@ trait SigmaSerializer[TFamily, T <: TFamily] extends Serializer[TFamily, T, Sigm serialize(obj, w) w.toBytes } + + final def fromBytes(bytes: Array[Byte]): TFamily = { + parse(SigmaSerializer.startReader(bytes)) + } } trait SigmaSerializerCompanion[TFamily] { diff --git a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala index 83625b44a6..bc5382ca2e 100644 --- a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala +++ b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala @@ -6,7 +6,7 @@ import sigmastate.helpers.SigmaTestingCommons class JsonSerializationSpec extends SigmaTestingCommons { - property("ErgoFullBlock should be encoded into JSON and decoded back correctly") { + property("ErgoLikeContext should be encoded into JSON and decoded back correctly") { // TODO: implement ErgoLikeContext generator val ctx: ErgoLikeContext = ??? From 7a700d02d61b7c4e001ef4ff7c1869d80fdbfefd Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 30 Jul 2019 17:47:51 +0300 Subject: [PATCH 18/64] draft ErgoLikeContext generator; --- .../org/ergoplatform/ErgoLikeContext.scala | 2 + .../ergoplatform/JsonSerializationSpec.scala | 16 +++--- .../generators/ObjectGenerators.scala | 51 ++++++++++++++++--- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index ed04191a8e..72984758a2 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -53,6 +53,8 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val initCost: Long ) extends InterpreterContext { + // TODO assert dataBoxes correspond to spendingTransaction.dataInputs + // TODO assert boxesToSpend correspond to spendingTransaction.inputs assert(preHeader != null) assert(spendingTransaction != null) assert(boxesToSpend.isDefinedAt(selfIndex), s"Self box if defined should be among boxesToSpend") diff --git a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala index bc5382ca2e..45b33a58b7 100644 --- a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala +++ b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala @@ -3,19 +3,19 @@ package org.ergoplatform import io.circe._ import io.circe.syntax._ import sigmastate.helpers.SigmaTestingCommons +import sigmastate.serialization.SerializationSpecification -class JsonSerializationSpec extends SigmaTestingCommons { +class JsonSerializationSpec extends SigmaTestingCommons with SerializationSpecification { property("ErgoLikeContext should be encoded into JSON and decoded back correctly") { + forAll(ergoLikeContextGen) { ctx => - // TODO: implement ErgoLikeContext generator - val ctx: ErgoLikeContext = ??? + val ctxJson: Json = ctx.asJson + val ctxDecoded: ErgoLikeContext = ctxJson.as[ErgoLikeContext].toTry.get - val ctxJson: Json = ctx.asJson - val ctxDecoded: ErgoLikeContext = ctxJson.as[ErgoLikeContext].toTry.get - - // TODO: implement ErgoLikeContext.equals - ctxDecoded shouldEqual ctx + // TODO: implement ErgoLikeContext.equals + ctxDecoded shouldEqual ctx + } } } diff --git a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 08561784f6..a0b6c1c0c5 100644 --- a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -5,23 +5,23 @@ import org.ergoplatform.ErgoConstants.MaxPropositionBytes import org.ergoplatform.ErgoScriptPredef.{FalseProp, TrueProp} import org.ergoplatform.validation._ import org.ergoplatform._ -import org.scalacheck.Arbitrary.{arbOption, arbAnyVal, arbShort, arbitrary, arbUnit, arbString, arbInt, arbLong, arbBool, arbByte} +import org.scalacheck.Arbitrary.{arbAnyVal, arbBool, arbByte, arbInt, arbLong, arbOption, arbShort, arbString, arbUnit, arbitrary} import org.scalacheck.{Arbitrary, Gen} import scorex.crypto.authds.{ADDigest, ADKey} import scorex.crypto.hash.Digest32 -import scorex.util.encode.{Base64, Base58} -import scorex.util.{bytesToId, ModifierId} -import sigmastate.Values.{ShortConstant, LongConstant, StringConstant, BoxConstant, FuncValue, FalseLeaf, EvaluatedValue, TrueLeaf, TaggedAvlTree, TaggedLong, BigIntConstant, BlockValue, AvlTreeConstant, GetVarInt, SigmaPropConstant, CollectionConstant, ConstantPlaceholder, Value, SigmaPropValue, Tuple, IntConstant, ErgoTree, SigmaBoolean, TaggedBox, ByteConstant, TaggedInt, ValDef, GroupElementConstant, ValUse, TaggedVariable} +import scorex.util.encode.{Base58, Base64} +import scorex.util.{ModifierId, bytesToId} +import sigmastate.Values.{AvlTreeConstant, BigIntConstant, BlockValue, BoxConstant, ByteConstant, CollectionConstant, ConstantPlaceholder, ErgoTree, EvaluatedValue, FalseLeaf, FuncValue, GetVarInt, GroupElementConstant, IntConstant, LongConstant, ShortConstant, SigmaBoolean, SigmaPropConstant, SigmaPropValue, StringConstant, TaggedAvlTree, TaggedBox, TaggedInt, TaggedLong, TaggedVariable, TrueLeaf, Tuple, ValDef, ValUse, Value} import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.ProveDHTuple import sigmastate.eval.Extensions._ import sigmastate.eval.{CostingBox, SigmaDsl, _} import sigmastate.interpreter.CryptoConstants.EcPointType -import sigmastate.interpreter.{ProverResult, ContextExtension, CryptoConstants} -import sigmastate.lang.TransformingSigmaBuilder.{mkModulo, mkExtractCreationInfo, mkExtractScriptBytes, mkFilter, mkPlus, mkTaggedVariable, mkSlice, mkFold, mkAtLeast, mkExtractBytesWithNoRef, mkExists, mkByteArrayToBigInt, mkForAll, mkDivide, mkSigmaOr, mkSigmaAnd, mkGT, mkGE, mkMapCollection, mkDeserializeRegister, mkExtractBytes, mkBoolToSigmaProp, mkNEQ, mkExtractAmount, mkMultiply, mkByteArrayToLong, mkConstant, mkExtractId, mkTuple, mkMax, mkLT, mkLE, mkDowncast, mkSizeOf, mkCollectionConstant, mkMin, mkDeserializeContext, mkEQ, mkAppend, mkMinus} +import sigmastate.interpreter.{ContextExtension, CryptoConstants, ProverResult} +import sigmastate.lang.TransformingSigmaBuilder.{mkAppend, mkAtLeast, mkBoolToSigmaProp, mkByteArrayToBigInt, mkByteArrayToLong, mkCollectionConstant, mkConstant, mkDeserializeContext, mkDeserializeRegister, mkDivide, mkDowncast, mkEQ, mkExists, mkExtractAmount, mkExtractBytes, mkExtractBytesWithNoRef, mkExtractCreationInfo, mkExtractId, mkExtractScriptBytes, mkFilter, mkFold, mkForAll, mkGE, mkGT, mkLE, mkLT, mkMapCollection, mkMax, mkMin, mkMinus, mkModulo, mkMultiply, mkNEQ, mkPlus, mkSigmaAnd, mkSigmaOr, mkSizeOf, mkSlice, mkTaggedVariable, mkTuple} import sigmastate._ -import sigmastate.utxo.{ExtractBytesWithNoRef, OptionGet, ExtractRegisterAs, Append, ExtractScriptBytes, ExtractCreationInfo, GetVar, ExtractId, MapCollection, ExtractAmount, ForAll, ByIndex, OptionGetOrElse, OptionIsDefined, DeserializeContext, Exists, DeserializeRegister, Transformer, Fold, Slice, SizeOf, Filter, ExtractBytes} -import special.sigma.{AvlTree, SigmaProp} +import sigmastate.utxo.{Append, ByIndex, DeserializeContext, DeserializeRegister, Exists, ExtractAmount, ExtractBytes, ExtractBytesWithNoRef, ExtractCreationInfo, ExtractId, ExtractRegisterAs, ExtractScriptBytes, Filter, Fold, ForAll, GetVar, MapCollection, OptionGet, OptionGetOrElse, OptionIsDefined, SizeOf, Slice, Transformer} +import special.sigma.{AvlTree, Header, PreHeader, SigmaProp} import scala.collection.JavaConverters._ import scala.collection.mutable.ListBuffer @@ -625,4 +625,39 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with treeBuilder <- Gen.oneOf(Seq[SigmaPropValue => ErgoTree](ErgoTree.withSegregation, ErgoTree.withoutSegregation)) } yield treeBuilder(prop) + + val headerGen: Gen[Header] = ??? + val preHeaderGen: Gen[PreHeader] = ??? + val validationSettingsGen: Gen[SigmaValidationSettings] = ??? + + val ergoLikeContextGen: Gen[ErgoLikeContext] = for { + avlTreeData <- avlTreeDataGen + headers <- Gen.nonEmptyListOf(headerGen) + preHeader <- preHeaderGen + tokens <- tokensGen + dataBoxes <- Gen.nonEmptyListOf(ergoBoxGen) + boxesToSpend <- Gen.nonEmptyListOf(ergoBoxGen) + extension <- contextExtensionGen + outputsCount <- Gen.chooseNum(50, 200) + outputCandidates <- Gen.listOfN(outputsCount, ergoBoxCandidateGen(tokens)) + validationSettings <- validationSettingsGen + costLimit <- arbLong.arbitrary + initCost <- arbLong.arbitrary + } yield new ErgoLikeContext( + lastBlockUtxoRoot = avlTreeData, + headers = headers.toColl, + preHeader = preHeader, + dataBoxes = dataBoxes.toIndexedSeq, + boxesToSpend = boxesToSpend.toIndexedSeq, + spendingTransaction = new ErgoLikeTransaction( + boxesToSpend.map(b => Input(b.id, serializedProverResultGen.sample.get)).toIndexedSeq, + dataBoxes.map(b => DataInput(b.id)).toIndexedSeq, + outputCandidates.toIndexedSeq), + selfIndex = 0, + extension = extension, + validationSettings = validationSettings, + costLimit = costLimit, + initCost = initCost + ) + } From ef5f2c2c1a3c34dcf5e797d2526c7d3b38d52596 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Wed, 31 Jul 2019 16:22:24 +0300 Subject: [PATCH 19/64] fixes headersGen to have generate parentIds; add ErgoBox.transactionId and index to json codec; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 16 +++- .../org/ergoplatform/ErgoLikeContext.scala | 26 ++++++ .../scala/org/ergoplatform/JsonCodecs.scala | 3 +- .../generators/ObjectGenerators.scala | 84 +++++++++++++++---- 4 files changed, 110 insertions(+), 19 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index 742651573c..414b0d026a 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -209,7 +209,9 @@ object ErgoBox extends JsonCodecs { "assets" -> box.additionalTokens.toArray.toSeq .asJson(Encoder.encodeSeq(Encoder.encodeTuple2(digest32Encoder, Encoder.encodeLong))), "creationHeight" -> box.creationHeight.asJson, - "additionalRegisters" -> box.additionalRegisters.asInstanceOf[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]].asJson + "additionalRegisters" -> box.additionalRegisters.asInstanceOf[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]].asJson, + "transactionId" -> box.transactionId.asJson, + "index" -> box.index.asJson ) } @@ -220,7 +222,17 @@ object ErgoBox extends JsonCodecs { additionalTokens <- cursor.downField("assets").as(Decoder.decodeSeq(Decoder.decodeTuple2(digest32Decoder, Decoder.decodeLong))) creationHeight <- cursor.downField("creationHeight").as[Int] additionalRegisters <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] - } yield ErgoBox(value, ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(ergoTreeBytes), creationHeight, additionalTokens, additionalRegisters) + transactionId <- cursor.downField("transactionId").as[ModifierId] + index <- cursor.downField("index").as[Short] + } yield new ErgoBox( + value = value, + ergoTree = ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(ergoTreeBytes), + additionalTokens = additionalTokens.toColl, + additionalRegisters = additionalRegisters, + transactionId = transactionId, + index = index, + creationHeight = creationHeight + ) } } diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 72984758a2..0f58cb4492 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -118,6 +118,32 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, isCost) } + + def canEqual(other: Any): Boolean = other.isInstanceOf[ErgoLikeContext] + + override def equals(other: Any): Boolean = other match { + case that: ErgoLikeContext => + (that canEqual this) && + lastBlockUtxoRoot == that.lastBlockUtxoRoot && + headers == that.headers && + preHeader == that.preHeader && + dataBoxes == that.dataBoxes && + boxesToSpend == that.boxesToSpend && + spendingTransaction == that.spendingTransaction && + selfIndex == that.selfIndex && + extension == that.extension && + validationSettings == that.validationSettings && + costLimit == that.costLimit && + initCost == that.initCost + case _ => false + } + + override def hashCode(): Int = { + val state = Seq(lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) + state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) + } + + override def toString = s"ErgoLikeContext(lastBlockUtxoRoot=$lastBlockUtxoRoot, headers=$headers, preHeader=$preHeader, dataBoxes=$dataBoxes, boxesToSpend=$boxesToSpend, spendingTransaction=$spendingTransaction, selfIndex=$selfIndex, extension=$extension, validationSettings=$validationSettings, costLimit=$costLimit, initCost=$initCost)" } object ErgoLikeContext extends JsonCodecs { diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index cad8058ac0..61a304bd74 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -3,7 +3,7 @@ package org.ergoplatform import cats.syntax.either._ import io.circe._ import io.circe.syntax._ -import org.ergoplatform.ErgoBox.NonMandatoryRegisterId +import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} import org.ergoplatform.settings.Algos import scorex.crypto.authds.ADKey import scorex.crypto.hash.Digest32 @@ -63,6 +63,7 @@ trait JsonCodecs { implicit val digest32Decoder: Decoder[Digest32] = bytesDecoder(Digest32 @@ _) implicit val modifierIdEncoder: Encoder[ModifierId] = _.asInstanceOf[String].asJson + implicit val modifierIdDecoder: Decoder[ModifierId] = ModifierId @@ _.as[String] implicit val registerIdEncoder: KeyEncoder[NonMandatoryRegisterId] = { regId => s"R${regId.number}" diff --git a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index a0b6c1c0c5..30a4728144 100644 --- a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -21,7 +21,8 @@ import sigmastate.interpreter.{ContextExtension, CryptoConstants, ProverResult} import sigmastate.lang.TransformingSigmaBuilder.{mkAppend, mkAtLeast, mkBoolToSigmaProp, mkByteArrayToBigInt, mkByteArrayToLong, mkCollectionConstant, mkConstant, mkDeserializeContext, mkDeserializeRegister, mkDivide, mkDowncast, mkEQ, mkExists, mkExtractAmount, mkExtractBytes, mkExtractBytesWithNoRef, mkExtractCreationInfo, mkExtractId, mkExtractScriptBytes, mkFilter, mkFold, mkForAll, mkGE, mkGT, mkLE, mkLT, mkMapCollection, mkMax, mkMin, mkMinus, mkModulo, mkMultiply, mkNEQ, mkPlus, mkSigmaAnd, mkSigmaOr, mkSizeOf, mkSlice, mkTaggedVariable, mkTuple} import sigmastate._ import sigmastate.utxo.{Append, ByIndex, DeserializeContext, DeserializeRegister, Exists, ExtractAmount, ExtractBytes, ExtractBytesWithNoRef, ExtractCreationInfo, ExtractId, ExtractRegisterAs, ExtractScriptBytes, Filter, Fold, ForAll, GetVar, MapCollection, OptionGet, OptionGetOrElse, OptionIsDefined, SizeOf, Slice, Transformer} -import special.sigma.{AvlTree, Header, PreHeader, SigmaProp} +import special.collection.Coll +import special.sigma._ import scala.collection.JavaConverters._ import scala.collection.mutable.ListBuffer @@ -110,6 +111,8 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with ints <- Gen.listOfN(length, arbInt.arbitrary) } yield mkCollectionConstant[SInt.type](ints.toArray, SInt) + val heightGen: Gen[Int] = Gen.chooseNum(0, 1000000) + val groupElementGen: Gen[EcPointType] = for { _ <- Gen.const(1) } yield CryptoConstants.dlogGroup.createRandomElement() @@ -237,8 +240,10 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with remove <- arbBool.arbitrary } yield AvlTreeFlags(insert, update, remove) + val aDDigestGen: Gen[ADDigest] = Gen.listOfN(AvlTreeData.DigestSize, arbByte.arbitrary).map(ADDigest @@ _.toArray) + def avlTreeDataGen: Gen[AvlTreeData] = for { - digest <- Gen.listOfN(AvlTreeData.DigestSize, arbByte.arbitrary).map(_.toArray) + digest <- aDDigestGen flags <- avlTreeFlagsGen keyLength <- unsignedIntGen vl <- arbOption[Int](Arbitrary(unsignedIntGen)).arbitrary @@ -289,6 +294,9 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with lazy val modifierIdGen: Gen[ModifierId] = Gen.listOfN(32, arbByte.arbitrary) .map(id => bytesToId(id.toArray)) + lazy val modifierIdBytesGen: Gen[ModifierIdBytes] = Gen.listOfN(32, arbByte.arbitrary) + .map(id => ModifierIdBytes @@ bytesToId(id.toArray).toBytes.toColl) + val ergoBoxGen: Gen[ErgoBox] = for { tId <- modifierIdGen boxId <- unsignedShortGen @@ -309,20 +317,24 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with Gen.oneOf(Seq(List[Digest32]())) } tokenAmounts <- Gen.listOfN(tokensCount, Gen.oneOf(1, 500, 20000, 10000000, Long.MaxValue)) - creationHeight <- Gen.chooseNum(0, 100000) + creationHeight <- heightGen } yield new ErgoBoxCandidate(l, b, creationHeight, tokens.toColl.zip(tokenAmounts.toColl), ar.asScala.toMap) val boxConstantGen: Gen[BoxConstant] = ergoBoxGen.map { v => BoxConstant(CostingBox(false, v)) } - val tokenIdGen: Gen[Digest32] = for { + val digest32Gen: Gen[Digest32] = for { bytes <- Gen.listOfN(TokenId.size, arbByte.arbitrary).map(_.toArray) } yield Digest32 @@ bytes + val tokenIdGen: Gen[Digest32] = digest32Gen + val tokensGen: Gen[Seq[Digest32]] = for { count <- Gen.chooseNum(10, 50) tokens <- Gen.listOfN(count, tokenIdGen) } yield tokens + val digest32CollGen: Gen[Digest32Coll] = digest32Gen.map(Digest32Coll @@ _.toColl) + val ergoTransactionGen: Gen[ErgoLikeTransaction] = for { inputs <- Gen.nonEmptyListOf(inputGen) tokens <- tokensGen @@ -352,11 +364,21 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with } } - val byteArrayGen: Gen[Array[Byte]] = for { - length <- Gen.chooseNum(1, 10) + def byteArrayGen(length: Int): Gen[Array[Byte]] = for { + bytes <- Gen.listOfN(length, arbByte.arbitrary) + } yield bytes.toArray + + def byteArrayGen(minLength: Int, maxLength: Int): Gen[Array[Byte]] = for { + length <- Gen.chooseNum(minLength, maxLength) bytes <- Gen.listOfN(length, arbByte.arbitrary) } yield bytes.toArray + def byteCollGen(length: Int): Gen[Coll[Byte]] = byteArrayGen(length).map(_.toColl) + + val minerVotesGen: Gen[MinerVotes] = byteCollGen(MinerVotes.size).map(MinerVotes @@ _) + + val nonceBytesGen: Gen[NonceBytes] = byteCollGen(NonceBytes.size).map(NonceBytes @@ _) + import ValidationRules._ val numRules = currentSettings.size @@ -368,7 +390,7 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with val statusGen: Gen[RuleStatus] = Gen.oneOf( Gen.oneOf(EnabledRule, DisabledRule), replacedRuleIdGen.map(id => ReplacedRule(id)), - byteArrayGen.map(xs => ChangedRule(xs)) + byteArrayGen(1, 10).map(xs => ChangedRule(xs)) ) val mapCollectionGen: Gen[MapCollection[SInt.type, SInt.type]] = for { @@ -626,25 +648,55 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with ErgoTree.withoutSegregation)) } yield treeBuilder(prop) - val headerGen: Gen[Header] = ??? - val preHeaderGen: Gen[PreHeader] = ??? - val validationSettingsGen: Gen[SigmaValidationSettings] = ??? + def headerGen(stateRoot: AvlTree, parentId: ModifierIdBytes): Gen[Header] = for { + id <- modifierIdBytesGen + version <- arbByte.arbitrary + adProofsRoot <- digest32CollGen + transactionRoot <- digest32CollGen + timestamp <- arbLong.arbitrary + nBits <- arbLong.arbitrary + height <- heightGen + extensionRoot <- digest32CollGen + minerPk <- groupElementGen + powOnetimePk <- groupElementGen + powNonce <- nonceBytesGen + powDistance <- arbBigInt.arbitrary + votes <- minerVotesGen + } yield CHeader(id, version, parentId, adProofsRoot, stateRoot, transactionRoot, timestamp, nBits, + height, extensionRoot, minerPk, powOnetimePk, powNonce, powDistance, votes) + + def headersGen(stateRoot: AvlTree): Gen[Seq[Header]] = for { + size <- Gen.chooseNum(1, 10) + } yield (0 to size) + .foldLeft(List[Header](headerGen(stateRoot, modifierIdBytesGen.sample.get).sample.get)) { (h, _) => + h :+ headerGen(stateRoot, h.last.id).sample.get + }.reverse + + def preHeaderGen(parentId: ModifierIdBytes): Gen[PreHeader] = for { + version <- arbByte.arbitrary + timestamp <- arbLong.arbitrary + nBits <- arbLong.arbitrary + height <- heightGen + minerPk <- groupElementGen + votes <- minerVotesGen + } yield CPreHeader(version, parentId, timestamp, nBits, height, minerPk, votes) + val ergoLikeContextGen: Gen[ErgoLikeContext] = for { - avlTreeData <- avlTreeDataGen - headers <- Gen.nonEmptyListOf(headerGen) - preHeader <- preHeaderGen + stateRoot <- avlTreeGen + headers <- headersGen(stateRoot) + preHeader <- preHeaderGen(headers.head.id) tokens <- tokensGen dataBoxes <- Gen.nonEmptyListOf(ergoBoxGen) boxesToSpend <- Gen.nonEmptyListOf(ergoBoxGen) extension <- contextExtensionGen outputsCount <- Gen.chooseNum(50, 200) outputCandidates <- Gen.listOfN(outputsCount, ergoBoxCandidateGen(tokens)) - validationSettings <- validationSettingsGen costLimit <- arbLong.arbitrary initCost <- arbLong.arbitrary + avlTreeFlags <- avlTreeFlagsGen } yield new ErgoLikeContext( - lastBlockUtxoRoot = avlTreeData, + lastBlockUtxoRoot = AvlTreeData(ADDigest @@ stateRoot.digest.toArray, avlTreeFlags, unsignedIntGen.sample.get), headers = headers.toColl, preHeader = preHeader, dataBoxes = dataBoxes.toIndexedSeq, @@ -655,7 +707,7 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with outputCandidates.toIndexedSeq), selfIndex = 0, extension = extension, - validationSettings = validationSettings, + validationSettings = ValidationRules.currentSettings, costLimit = costLimit, initCost = initCost ) From 7018780837c02396feb9817b5b65062e6df6e5b3 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Wed, 31 Jul 2019 17:33:40 +0300 Subject: [PATCH 20/64] add assertion to ErgoLikeContext that dataBoxes should correspond to spendingTransaction.dataInputs; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 6 +++--- src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala | 4 ++-- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 9 +++++++-- .../scala/org/ergoplatform/ErgoLikeTransaction.scala | 2 ++ src/main/scala/org/ergoplatform/Input.scala | 8 +++++--- .../scala/sigmastate/interpreter/ProverInterpreter.scala | 4 ++-- .../scala/org/ergoplatform/dsl/TestContractSpec.scala | 5 +++-- src/test/scala/sigmastate/CostingSpecification.scala | 4 ++-- .../scala/sigmastate/helpers/SigmaTestingCommons.scala | 4 ++++ src/test/scala/special/sigma/SigmaTestingData.scala | 6 +++--- 10 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index 414b0d026a..04f9a33a55 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -4,8 +4,8 @@ import io.circe._ import io.circe.syntax._ import com.google.common.primitives.Shorts import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} +import org.ergoplatform.settings.Algos import scorex.crypto.authds.ADKey -import scorex.util.encode.Base16 import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util._ import sigmastate.Values._ @@ -86,8 +86,8 @@ class ErgoBox( def toCandidate: ErgoBoxCandidate = new ErgoBoxCandidate(value, ergoTree, creationHeight, additionalTokens, additionalRegisters) - override def toString: Idn = s"ErgoBox(${Base16.encode(id)},$value,$ergoTree," + - s"tokens: (${additionalTokens.map(t => Base16.encode(t._1) + ":" + t._2)}), $transactionId, " + + override def toString: String = s"ErgoBox(${Algos.encode(id)},$value,$ergoTree," + + s"tokens: (${additionalTokens.map(t => Algos.encode(t._1) + ":" + t._2)}), $transactionId, " + s"$index, $additionalRegisters, $creationHeight)" } diff --git a/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala b/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala index 9d83860f47..2b72d348d7 100644 --- a/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala +++ b/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala @@ -3,8 +3,8 @@ package org.ergoplatform import java.util import org.ergoplatform.ErgoBox._ +import org.ergoplatform.settings.Algos import scorex.crypto.hash.Digest32 -import scorex.util.encode.Base16 import scorex.util.ModifierId import sigmastate.Values._ import sigmastate._ @@ -75,7 +75,7 @@ class ErgoBoxCandidate(val value: Long, ScalaRunTime._hashCode((value, ergoTree, additionalTokens, additionalRegisters, creationHeight)) override def toString: Idn = s"ErgoBoxCandidate($value, $ergoTree," + - s"tokens: (${additionalTokens.map(t => Base16.encode(t._1) + ":" + t._2).toArray.mkString(", ")}), " + + s"tokens: (${additionalTokens.map(t => Algos.encode(t._1) + ":" + t._2).toArray.mkString(", ")}), " + s"$additionalRegisters, creationHeight: $creationHeight)" } diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 0f58cb4492..f5289adc64 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -1,5 +1,7 @@ package org.ergoplatform +import java.util + import io.circe._ import io.circe.syntax._ import org.ergoplatform.ErgoLikeContext.Height @@ -53,8 +55,6 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val initCost: Long ) extends InterpreterContext { - // TODO assert dataBoxes correspond to spendingTransaction.dataInputs - // TODO assert boxesToSpend correspond to spendingTransaction.inputs assert(preHeader != null) assert(spendingTransaction != null) assert(boxesToSpend.isDefinedAt(selfIndex), s"Self box if defined should be among boxesToSpend") @@ -63,6 +63,11 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, if (i > 0) assert(headers(i - 1).parentId == headers(i).id, s"Incorrect chain: ${headers(i - 1).parentId},${headers(i).id}") } assert(headers.toArray.headOption.forall(_.id == preHeader.parentId), s"preHeader.parentId should be id of the best header") + assert(spendingTransaction.dataInputs.length == dataBoxes.length && + spendingTransaction.dataInputs.forall(dataInput => dataBoxes.exists(b => util.Arrays.equals(b.id, dataInput.boxId))), + "dataBoxes do not correspond to spendingTransaction.dataInputs") + + // TODO assert boxesToSpend correspond to spendingTransaction.inputs // height of a block with the current `spendingTransaction` val currentHeight: Height = preHeader.height diff --git a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index 41ccfcdede..b55a8911c0 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -55,6 +55,8 @@ trait ErgoLikeTransactionTemplate[IT <: UnsignedInput] { lazy val messageToSign: Array[Byte] = ErgoLikeTransaction.bytesToSign(this) lazy val inputIds: IndexedSeq[ADKey] = inputs.map(_.boxId) + + override def toString = s"ErgoLikeTransactionTemplate(dataInputs=$dataInputs, inputs=$inputs, outputCandidates=$outputCandidates)" } diff --git a/src/main/scala/org/ergoplatform/Input.scala b/src/main/scala/org/ergoplatform/Input.scala index a0c9cc9bb6..4198e5cfc8 100644 --- a/src/main/scala/org/ergoplatform/Input.scala +++ b/src/main/scala/org/ergoplatform/Input.scala @@ -5,8 +5,8 @@ import java.util import io.circe._ import io.circe.syntax._ import org.ergoplatform.ErgoBox.BoxId +import org.ergoplatform.settings.Algos import scorex.crypto.authds.ADKey -import scorex.util.encode.Base16 import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.serialization.SigmaSerializer import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} @@ -16,7 +16,9 @@ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} * * @param boxId - id of a box to add into context (should be in UTXO) */ -case class DataInput(boxId: BoxId) +case class DataInput(boxId: BoxId) { + override def toString: String = s"DataInput(${Algos.encode(boxId)})" +} object DataInput extends JsonCodecs { @@ -67,7 +69,7 @@ class UnsignedInput(val boxId: BoxId, val extension: ContextExtension) { */ case class Input(override val boxId: BoxId, spendingProof: ProverResult) extends UnsignedInput(boxId, spendingProof.extension) { - override def toString: String = s"Input(${Base16.encode(boxId)},$spendingProof)" + override def toString: String = s"Input(${Algos.encode(boxId)},$spendingProof)" } object Input extends JsonCodecs { diff --git a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index fb56e5ff81..bb04daaa48 100644 --- a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -9,8 +9,8 @@ import org.bitbucket.inkytonik.kiama.attribution.AttributionCore import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{everywherebu, everywheretd, rule} import org.bitbucket.inkytonik.kiama.rewriting.Strategy import org.ergoplatform.JsonCodecs +import org.ergoplatform.settings.Algos import scalan.util.CollectionUtil._ -import scorex.util.encode.Base16 import sigmastate.Values._ import sigmastate._ import sigmastate.basics.DLogProtocol._ @@ -37,7 +37,7 @@ class ProverResult(val proof: Array[Byte], val extension: ContextExtension) { case _ => false } - override def toString: Idn = s"ProverResult(${Base16.encode(proof)},$extension)" + override def toString: Idn = s"ProverResult(${Algos.encode(proof)},$extension)" } object ProverResult extends JsonCodecs { diff --git a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index 2c679f2a7a..d07acf79d0 100644 --- a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -80,13 +80,14 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC private [dsl] def toErgoContext: ErgoLikeContext = { val propSpec = utxoBox.propSpec val boxesToSpend = tx.inputs.map(_.utxoBox.ergoBox).toIndexedSeq + val dataBoxes = tx.dataInputs.map(_.utxoBox.ergoBox).toIndexedSeq val ctx = new ErgoLikeContext( lastBlockUtxoRoot = AvlTreeData.dummy, headers = noHeaders, preHeader = dummyPreHeader(tx.block.height, ErgoLikeContext.dummyPubkey), - dataBoxes = tx.dataInputs.map(_.utxoBox.ergoBox).toIndexedSeq, + dataBoxes = dataBoxes, boxesToSpend = boxesToSpend, - spendingTransaction = testSuite.createTransaction(tx.outputs.map(_.ergoBox).toIndexedSeq), + spendingTransaction = testSuite.createTransaction(dataBoxes, tx.outputs.map(_.ergoBox).toIndexedSeq), selfIndex = boxesToSpend.indexOf(utxoBox.ergoBox), extension = ContextExtension.empty, validationSettings = ValidationRules.currentSettings, diff --git a/src/test/scala/sigmastate/CostingSpecification.scala b/src/test/scala/sigmastate/CostingSpecification.scala index 4c1580d1df..fa168d30d3 100644 --- a/src/test/scala/sigmastate/CostingSpecification.scala +++ b/src/test/scala/sigmastate/CostingSpecification.scala @@ -3,7 +3,7 @@ package sigmastate import org.ergoplatform.ErgoConstants.ScriptCostLimit import org.ergoplatform.ErgoScriptPredef.TrueProp import org.ergoplatform.validation.ValidationRules -import org.ergoplatform.{ErgoBox, ErgoLikeContext} +import org.ergoplatform.{ErgoBox, ErgoLikeContext, ErgoLikeTransaction} import scorex.crypto.authds.avltree.batch.Lookup import scorex.crypto.authds.{ADDigest, ADKey} import scorex.crypto.hash.Blake2b256 @@ -60,7 +60,7 @@ class CostingSpecification extends SigmaTestingData { ErgoBox.R6 -> AvlTreeConstant(avlTree))) lazy val outBoxA = ErgoBox(10, pkA, 0) lazy val outBoxB = ErgoBox(20, pkB, 0) - lazy val tx = createTransaction(IndexedSeq(outBoxA, outBoxB)) + lazy val tx = createTransaction(IndexedSeq(dataBox), IndexedSeq(outBoxA, outBoxB)) lazy val context = new ErgoLikeContext( lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, diff --git a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala b/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala index 5978cc3004..1f923d879b 100644 --- a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala +++ b/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala @@ -83,6 +83,10 @@ trait SigmaTestingCommons extends PropSpec def createTransaction(box: ErgoBoxCandidate): ErgoLikeTransaction = createTransaction(IndexedSeq(box)) + def createTransaction(dataInputs: IndexedSeq[ErgoBox], + outputCandidates: IndexedSeq[ErgoBoxCandidate]): ErgoLikeTransaction = + new ErgoLikeTransaction(IndexedSeq(), dataInputs.map(b => DataInput(b.id)), outputCandidates) + class TestingIRContext extends TestContext with IRContext with CompiletimeCosting { override def onCostingResult[T](env: ScriptEnv, tree: SValue, res: RCostingResultEx[T]): Unit = { env.get(ScriptNameProp) match { diff --git a/src/test/scala/special/sigma/SigmaTestingData.scala b/src/test/scala/special/sigma/SigmaTestingData.scala index f24e95788e..25f1668efc 100644 --- a/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/src/test/scala/special/sigma/SigmaTestingData.scala @@ -10,8 +10,8 @@ import org.scalacheck.{Arbitrary, Gen} import sigmastate.helpers.SigmaTestingCommons import sigmastate.eval._ import sigmastate.eval.Extensions._ -import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction, ErgoBox} -import scorex.crypto.hash.{Digest32, Blake2b256} +import org.ergoplatform.{DataInput, ErgoBox, ErgoLikeContext, ErgoLikeTransaction} +import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.crypto.authds.{ADKey, ADValue} trait SigmaTestingData extends SigmaTestingCommons with SigmaTypeGens { @@ -93,7 +93,7 @@ trait SigmaTestingData extends SigmaTestingCommons with SigmaTypeGens { val ergoCtx = new ErgoLikeContext( lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, boxesToSpend = IndexedSeq(inBox), - spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(outBox)), + spendingTransaction = new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(DataInput(dataBox.id)), IndexedSeq(outBox)), selfIndex = 0, headers = headers, preHeader = preHeader, dataBoxes = IndexedSeq(dataBox), extension = ContextExtension.empty, validationSettings = ValidationRules.currentSettings, From 8f49d57e2df36789ec8a5b57ea7e0b444300e1ce Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Wed, 31 Jul 2019 19:27:40 +0300 Subject: [PATCH 21/64] make ErgoLikeContext gen to include empty headers; --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 4 ++-- .../serialization/generators/ObjectGenerators.scala | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index f5289adc64..661ced402c 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -55,8 +55,8 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val initCost: Long ) extends InterpreterContext { - assert(preHeader != null) - assert(spendingTransaction != null) + assert(preHeader != null, "preHeader cannot be null") + assert(spendingTransaction != null, "spendingTransaction cannot be null") assert(boxesToSpend.isDefinedAt(selfIndex), s"Self box if defined should be among boxesToSpend") assert(headers.toArray.headOption.forall(h => java.util.Arrays.equals(h.stateRoot.digest.toArray, lastBlockUtxoRoot.digest)), "Incorrect lastBlockUtxoRoot") cfor(0)(_ < headers.length, _ + 1) { i => diff --git a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 30a4728144..2a66d4c60a 100644 --- a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -666,8 +666,9 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with height, extensionRoot, minerPk, powOnetimePk, powNonce, powDistance, votes) def headersGen(stateRoot: AvlTree): Gen[Seq[Header]] = for { - size <- Gen.chooseNum(1, 10) - } yield (0 to size) + size <- Gen.chooseNum(0, 10) + } yield if (size == 0) Seq() else + (0 to size) .foldLeft(List[Header](headerGen(stateRoot, modifierIdBytesGen.sample.get).sample.get)) { (h, _) => h :+ headerGen(stateRoot, h.last.id).sample.get }.reverse @@ -685,7 +686,7 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with val ergoLikeContextGen: Gen[ErgoLikeContext] = for { stateRoot <- avlTreeGen headers <- headersGen(stateRoot) - preHeader <- preHeaderGen(headers.head.id) + preHeader <- preHeaderGen(headers.headOption.map(_.id).getOrElse(modifierIdBytesGen.sample.get)) tokens <- tokensGen dataBoxes <- Gen.nonEmptyListOf(ergoBoxGen) boxesToSpend <- Gen.nonEmptyListOf(ergoBoxGen) From b9528563cb176ffe847484885dc70ab8e13536c6 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 1 Aug 2019 11:33:56 +0300 Subject: [PATCH 22/64] fix removed tagged types in generators; --- .../scala/sigmastate/eval/CostingDataContext.scala | 5 +++++ .../serialization/generators/ObjectGenerators.scala | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/scala/sigmastate/eval/CostingDataContext.scala b/src/main/scala/sigmastate/eval/CostingDataContext.scala index f81805b707..76c9d4a700 100644 --- a/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -433,6 +433,11 @@ case class CHeader( ) extends Header { } +object CHeader { + val VotesSize = 3 + val NonceSize = 8 +} + class CCostModel extends CostModel { private def costOf(opName: String, opType: SFunc): Int = { val operId = OperationId(opName, opType) diff --git a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 2a66d4c60a..8741c85a98 100644 --- a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -294,8 +294,8 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with lazy val modifierIdGen: Gen[ModifierId] = Gen.listOfN(32, arbByte.arbitrary) .map(id => bytesToId(id.toArray)) - lazy val modifierIdBytesGen: Gen[ModifierIdBytes] = Gen.listOfN(32, arbByte.arbitrary) - .map(id => ModifierIdBytes @@ bytesToId(id.toArray).toBytes.toColl) + lazy val modifierIdBytesGen: Gen[Coll[Byte]] = Gen.listOfN(32, arbByte.arbitrary) + .map(id => bytesToId(id.toArray).toBytes.toColl) val ergoBoxGen: Gen[ErgoBox] = for { tId <- modifierIdGen @@ -375,9 +375,9 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with def byteCollGen(length: Int): Gen[Coll[Byte]] = byteArrayGen(length).map(_.toColl) - val minerVotesGen: Gen[MinerVotes] = byteCollGen(MinerVotes.size).map(MinerVotes @@ _) + val minerVotesGen: Gen[Coll[Byte]] = byteCollGen(CHeader.VotesSize) - val nonceBytesGen: Gen[NonceBytes] = byteCollGen(NonceBytes.size).map(NonceBytes @@ _) + val nonceBytesGen: Gen[Coll[Byte]] = byteCollGen(CHeader.NonceSize) import ValidationRules._ @@ -648,7 +648,7 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with ErgoTree.withoutSegregation)) } yield treeBuilder(prop) - def headerGen(stateRoot: AvlTree, parentId: ModifierIdBytes): Gen[Header] = for { + def headerGen(stateRoot: AvlTree, parentId: Coll[Byte]): Gen[Header] = for { id <- modifierIdBytesGen version <- arbByte.arbitrary adProofsRoot <- digest32CollGen @@ -673,7 +673,7 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with h :+ headerGen(stateRoot, h.last.id).sample.get }.reverse - def preHeaderGen(parentId: ModifierIdBytes): Gen[PreHeader] = for { + def preHeaderGen(parentId: Coll[Byte]): Gen[PreHeader] = for { version <- arbByte.arbitrary timestamp <- arbLong.arbitrary nBits <- arbLong.arbitrary From dcb3a5135016cbe2eecb66bb9148409f5cdf7ad9 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 1 Aug 2019 12:09:46 +0300 Subject: [PATCH 23/64] add NOFH comment for ErgoLikeContext.dummyPubKey; --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 661ced402c..5e1e680ff0 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -154,6 +154,13 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, object ErgoLikeContext extends JsonCodecs { type Height = Int + /* NO HF PROOF: + Changed: val dummyPubkey from `Array[Byte] = Array.fill(32)(0: Byte)` to `GroupElementSerializer.toBytes(CryptoConstants.dlogGroup.generator)` + Motivation: to avoid exception on deserialization(wrong size, needs to be 33 bytes) and later in GroupElement.toString (infinity was not handled) and to provide more practical value in tests. + Safety: + Used only in tests and not used in ergo. + Examined ergo code: all (with IDE's "find usages" action). +*/ val dummyPubkey: Array[Byte] = GroupElementSerializer.toBytes(CryptoConstants.dlogGroup.generator) val noBoxes = IndexedSeq.empty[ErgoBox] From 47a88e4e9b945facedb36851bbc80eff552e1990 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 1 Aug 2019 12:26:04 +0300 Subject: [PATCH 24/64] fix json codecs; --- .../scala/org/ergoplatform/JsonCodecs.scala | 19 ++++++++++++------- src/main/scala/sigmastate/AvlTreeData.scala | 9 +++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index 61a304bd74..f24fda8c9d 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -1,11 +1,13 @@ package org.ergoplatform +import java.math.BigInteger + import cats.syntax.either._ import io.circe._ import io.circe.syntax._ import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} import org.ergoplatform.settings.Algos -import scorex.crypto.authds.ADKey +import scorex.crypto.authds.{ADDigest, ADKey} import scorex.crypto.hash.Digest32 import scorex.util.ModifierId import sigmastate.Values.{ErgoTree, EvaluatedValue} @@ -40,13 +42,13 @@ trait JsonCodecs { } implicit val sigmaBigIntEncoder: Encoder[special.sigma.BigInt] = { bigInt => - JsonNumber.fromDecimalStringUnsafe(bigInt.asInstanceOf[WrapperOf[BigInt]].wrappedValue.toString).asJson + JsonNumber.fromDecimalStringUnsafe(bigInt.asInstanceOf[WrapperOf[BigInteger]].wrappedValue.toString).asJson } implicit val sigmaBigIntDecoder: Decoder[special.sigma.BigInt] = { implicit cursor => for { - str <- cursor.as[String] - bigInt <- fromOption(JsonNumber.fromString(str).flatMap(_.toBigInt)) + jsonNumber <- cursor.as[JsonNumber] + bigInt <- fromOption(jsonNumber.toBigInt) } yield CBigInt(bigInt.bigInteger) } @@ -59,6 +61,9 @@ trait JsonCodecs { implicit val adKeyEncoder: Encoder[ADKey] = _.array.asJson implicit val adKeyDecoder: Decoder[ADKey] = bytesDecoder(ADKey @@ _) + implicit val adDigestEncoder: Encoder[ADDigest] = _.array.asJson + implicit val adDigestDecoder: Decoder[ADDigest] = bytesDecoder(ADDigest @@ _) + implicit val digest32Encoder: Encoder[Digest32] = _.array.asJson implicit val digest32Decoder: Decoder[Digest32] = bytesDecoder(Digest32 @@ _) @@ -131,14 +136,14 @@ trait JsonCodecs { implicit val preHeaderDecoder: Decoder[PreHeader] = { cursor => for { - versionId <- cursor.downField("versionId").as[Byte] + version <- cursor.downField("version").as[Byte] parentId <- cursor.downField("parentId").as[Coll[Byte]] - timeStamp <- cursor.downField("timeStamp").as[Long] + timestamp <- cursor.downField("timestamp").as[Long] nBits <- cursor.downField("nBits").as[Long] height <- cursor.downField("height").as[Int] minerPk <- cursor.downField("minerPk").as[Coll[Byte]] votes <- cursor.downField("votes").as[Coll[Byte]] - } yield CPreHeader(versionId, parentId, timeStamp, nBits, height, CGroupElement.decode(minerPk), votes) + } yield CPreHeader(version, parentId, timestamp, nBits, height, CGroupElement.decode(minerPk), votes) } implicit val evaluatedValueEncoder: Encoder[EvaluatedValue[SType]] = { value => diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index bc0c945204..18e70a5b00 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -5,6 +5,7 @@ import java.util.{Arrays, Objects} import io.circe._ import io.circe.syntax._ +import org.ergoplatform.JsonCodecs import org.ergoplatform.settings.Algos import scorex.crypto.authds.ADDigest import sigmastate.interpreter.CryptoConstants @@ -74,7 +75,7 @@ case class AvlTreeData(digest: ADDigest, keyLength.hashCode()) * 31 + Objects.hash(valueLengthOpt, treeFlags) } -object AvlTreeData { +object AvlTreeData extends JsonCodecs { val DigestSize: Int = CryptoConstants.hashLength + 1 //please read class comments above for details val TreeDataSize = DigestSize + 3 + 4 + 4 @@ -104,7 +105,7 @@ object AvlTreeData { implicit val jsonEncoder: Encoder[AvlTreeData] = { v => Json.obj( - "digest" -> Algos.encode(v.digest).asJson, + "digest" -> v.digest.asJson, "treeFlags" -> v.treeFlags.serializeToByte.asJson, "keyLength" -> v.keyLength.asJson, "valueLength" -> v.valueLengthOpt.asJson @@ -113,10 +114,10 @@ object AvlTreeData { implicit val jsonDecoder: Decoder[AvlTreeData] = { cursor => for { - digest <- cursor.downField("digest").as[Array[Byte]] + digest <- cursor.downField("digest").as[ADDigest] treeFlagsByte <- cursor.downField("treeFlags").as[Byte] keyLength <- cursor.downField("keyLength").as[Int] valueLength <- cursor.downField("valueLength").as[Option[Int]] - } yield new AvlTreeData(ADDigest @@ digest, AvlTreeFlags(treeFlagsByte), keyLength, valueLength) + } yield new AvlTreeData(digest, AvlTreeFlags(treeFlagsByte), keyLength, valueLength) } } From 5f113c678ec9f402e7703b668949a029910e7a7c Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 1 Aug 2019 13:51:08 +0300 Subject: [PATCH 25/64] update branch for ergo test to ergolikectx-json; --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 2501cc819d..821f27969f 100644 --- a/build.sbt +++ b/build.sbt @@ -208,7 +208,7 @@ lazy val sigma = (project in file(".")) .settings(commonSettings: _*) def runErgoTask(task: String, sigmastateVersion: String, log: Logger): Unit = { - val ergoBranch = "master" + val ergoBranch = "ergolikectx-json" val sbtEnvVars = Seq("BUILD_ENV" -> "test", "SIGMASTATE_VERSION" -> sigmastateVersion) log.info(s"Testing current build in Ergo (branch $ergoBranch):") From 2d0ce4a92715368a4f70a1eed59e05f2a9af6bb0 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 1 Aug 2019 14:02:47 +0300 Subject: [PATCH 26/64] rename Algos to SigmaAlgos; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 6 +++--- src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala | 4 ++-- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 2 +- src/main/scala/org/ergoplatform/Input.scala | 6 +++--- src/main/scala/org/ergoplatform/JsonCodecs.scala | 8 ++++---- .../settings/{Algos.scala => SigmaAlgos.scala} | 7 +------ src/main/scala/sigmastate/AvlTreeData.scala | 2 +- .../scala/sigmastate/interpreter/ProverInterpreter.scala | 4 ++-- 8 files changed, 17 insertions(+), 22 deletions(-) rename src/main/scala/org/ergoplatform/settings/{Algos.scala => SigmaAlgos.scala} (70%) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index 04f9a33a55..4425c2820f 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -4,7 +4,7 @@ import io.circe._ import io.circe.syntax._ import com.google.common.primitives.Shorts import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} -import org.ergoplatform.settings.Algos +import org.ergoplatform.settings.SigmaAlgos import scorex.crypto.authds.ADKey import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util._ @@ -86,8 +86,8 @@ class ErgoBox( def toCandidate: ErgoBoxCandidate = new ErgoBoxCandidate(value, ergoTree, creationHeight, additionalTokens, additionalRegisters) - override def toString: String = s"ErgoBox(${Algos.encode(id)},$value,$ergoTree," + - s"tokens: (${additionalTokens.map(t => Algos.encode(t._1) + ":" + t._2)}), $transactionId, " + + override def toString: String = s"ErgoBox(${SigmaAlgos.encode(id)},$value,$ergoTree," + + s"tokens: (${additionalTokens.map(t => SigmaAlgos.encode(t._1) + ":" + t._2)}), $transactionId, " + s"$index, $additionalRegisters, $creationHeight)" } diff --git a/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala b/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala index 2b72d348d7..0ba1572da7 100644 --- a/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala +++ b/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala @@ -3,7 +3,7 @@ package org.ergoplatform import java.util import org.ergoplatform.ErgoBox._ -import org.ergoplatform.settings.Algos +import org.ergoplatform.settings.SigmaAlgos import scorex.crypto.hash.Digest32 import scorex.util.ModifierId import sigmastate.Values._ @@ -75,7 +75,7 @@ class ErgoBoxCandidate(val value: Long, ScalaRunTime._hashCode((value, ergoTree, additionalTokens, additionalRegisters, creationHeight)) override def toString: Idn = s"ErgoBoxCandidate($value, $ergoTree," + - s"tokens: (${additionalTokens.map(t => Algos.encode(t._1) + ":" + t._2).toArray.mkString(", ")}), " + + s"tokens: (${additionalTokens.map(t => SigmaAlgos.encode(t._1) + ":" + t._2).toArray.mkString(", ")}), " + s"$additionalRegisters, creationHeight: $creationHeight)" } diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 5e1e680ff0..01c8e86532 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -19,7 +19,7 @@ import special.sigma.{AnyValue, Box, GroupElement, Header, PreHeader} import SType._ import RType._ import org.ergoplatform.ErgoConstants.ScriptCostLimit -import org.ergoplatform.settings.Algos +import org.ergoplatform.settings.SigmaAlgos import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} import spire.syntax.all.cfor import scala.util.Try diff --git a/src/main/scala/org/ergoplatform/Input.scala b/src/main/scala/org/ergoplatform/Input.scala index 4198e5cfc8..d20c9b4095 100644 --- a/src/main/scala/org/ergoplatform/Input.scala +++ b/src/main/scala/org/ergoplatform/Input.scala @@ -5,7 +5,7 @@ import java.util import io.circe._ import io.circe.syntax._ import org.ergoplatform.ErgoBox.BoxId -import org.ergoplatform.settings.Algos +import org.ergoplatform.settings.SigmaAlgos import scorex.crypto.authds.ADKey import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.serialization.SigmaSerializer @@ -17,7 +17,7 @@ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} * @param boxId - id of a box to add into context (should be in UTXO) */ case class DataInput(boxId: BoxId) { - override def toString: String = s"DataInput(${Algos.encode(boxId)})" + override def toString: String = s"DataInput(${SigmaAlgos.encode(boxId)})" } object DataInput extends JsonCodecs { @@ -69,7 +69,7 @@ class UnsignedInput(val boxId: BoxId, val extension: ContextExtension) { */ case class Input(override val boxId: BoxId, spendingProof: ProverResult) extends UnsignedInput(boxId, spendingProof.extension) { - override def toString: String = s"Input(${Algos.encode(boxId)},$spendingProof)" + override def toString: String = s"Input(${SigmaAlgos.encode(boxId)},$spendingProof)" } object Input extends JsonCodecs { diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index f24fda8c9d..63ddd13df3 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -6,7 +6,7 @@ import cats.syntax.either._ import io.circe._ import io.circe.syntax._ import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} -import org.ergoplatform.settings.Algos +import org.ergoplatform.settings.SigmaAlgos import scorex.crypto.authds.{ADDigest, ADKey} import scorex.crypto.hash.Digest32 import scorex.util.ModifierId @@ -37,7 +37,7 @@ trait JsonCodecs { private def bytesDecoder[T](transform: Array[Byte] => T): Decoder[T] = { implicit cursor => for { str <- cursor.as[String] - bytes <- fromTry(Algos.decode(str)) + bytes <- fromTry(SigmaAlgos.decode(str)) } yield transform(bytes) } @@ -52,10 +52,10 @@ trait JsonCodecs { } yield CBigInt(bigInt.bigInteger) } - implicit val arrayBytesEncoder: Encoder[Array[Byte]] = Algos.encode(_).asJson + implicit val arrayBytesEncoder: Encoder[Array[Byte]] = SigmaAlgos.encode(_).asJson implicit val arrayBytesDecoder: Decoder[Array[Byte]] = bytesDecoder(x => x) - implicit val collBytesEncoder: Encoder[Coll[Byte]] = Algos.encode(_).asJson + implicit val collBytesEncoder: Encoder[Coll[Byte]] = SigmaAlgos.encode(_).asJson implicit val collBytesDecoder: Decoder[Coll[Byte]] = bytesDecoder(Colls.fromArray(_)) implicit val adKeyEncoder: Encoder[ADKey] = _.array.asJson diff --git a/src/main/scala/org/ergoplatform/settings/Algos.scala b/src/main/scala/org/ergoplatform/settings/SigmaAlgos.scala similarity index 70% rename from src/main/scala/org/ergoplatform/settings/Algos.scala rename to src/main/scala/org/ergoplatform/settings/SigmaAlgos.scala index 0e47bb09a5..461fcdb82f 100644 --- a/src/main/scala/org/ergoplatform/settings/Algos.scala +++ b/src/main/scala/org/ergoplatform/settings/SigmaAlgos.scala @@ -9,14 +9,12 @@ import special.collection.Coll import scala.util.Try // TODO: use it in ergo (delete ergo's own) -object Algos extends ScorexEncoding { +object SigmaAlgos extends ScorexEncoding { type HF = Blake2b256.type val hash: HF = Blake2b256 - lazy val emptyMerkleTreeRoot: Digest32 = Algos.hash(LeafData @@ Array[Byte]()) - @inline def encode(bytes: Array[Byte]): String = encoder.encode(bytes) @inline def encode(bytes: Coll[Byte]): String = encoder.encode(bytes.toArray) @@ -24,7 +22,4 @@ object Algos extends ScorexEncoding { @inline def decode(str: String): Try[Array[Byte]] = encoder.decode(str) @inline def decodeUnsafe(str: String): Array[Byte] = decode(str).get - - def merkleTreeRoot(elements: Seq[LeafData]): Digest32 = - if (elements.isEmpty) emptyMerkleTreeRoot else MerkleTree(elements)(hash).rootHash } diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index 18e70a5b00..706834d87f 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -6,7 +6,7 @@ import java.util.{Arrays, Objects} import io.circe._ import io.circe.syntax._ import org.ergoplatform.JsonCodecs -import org.ergoplatform.settings.Algos +import org.ergoplatform.settings.SigmaAlgos import scorex.crypto.authds.ADDigest import sigmastate.interpreter.CryptoConstants import sigmastate.serialization.SigmaSerializer diff --git a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index bb04daaa48..2a0049cac4 100644 --- a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -9,7 +9,7 @@ import org.bitbucket.inkytonik.kiama.attribution.AttributionCore import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{everywherebu, everywheretd, rule} import org.bitbucket.inkytonik.kiama.rewriting.Strategy import org.ergoplatform.JsonCodecs -import org.ergoplatform.settings.Algos +import org.ergoplatform.settings.SigmaAlgos import scalan.util.CollectionUtil._ import sigmastate.Values._ import sigmastate._ @@ -37,7 +37,7 @@ class ProverResult(val proof: Array[Byte], val extension: ContextExtension) { case _ => false } - override def toString: Idn = s"ProverResult(${Algos.encode(proof)},$extension)" + override def toString: Idn = s"ProverResult(${SigmaAlgos.encode(proof)},$extension)" } object ProverResult extends JsonCodecs { From 92e497add2d73a2d5db0bfeb2cffd5832c25eb68 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 1 Aug 2019 15:02:32 +0300 Subject: [PATCH 27/64] make Algo into a trait and rename to ErgoAlgos; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 6 +++--- src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala | 4 ++-- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 2 +- src/main/scala/org/ergoplatform/Input.scala | 6 +++--- src/main/scala/org/ergoplatform/JsonCodecs.scala | 8 ++++---- .../settings/{SigmaAlgos.scala => ErgoAlgos.scala} | 4 +++- src/main/scala/sigmastate/AvlTreeData.scala | 2 +- .../scala/sigmastate/interpreter/ProverInterpreter.scala | 4 ++-- 8 files changed, 19 insertions(+), 17 deletions(-) rename src/main/scala/org/ergoplatform/settings/{SigmaAlgos.scala => ErgoAlgos.scala} (89%) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index 4425c2820f..05ba919e2e 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -4,7 +4,7 @@ import io.circe._ import io.circe.syntax._ import com.google.common.primitives.Shorts import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} -import org.ergoplatform.settings.SigmaAlgos +import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.ADKey import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util._ @@ -86,8 +86,8 @@ class ErgoBox( def toCandidate: ErgoBoxCandidate = new ErgoBoxCandidate(value, ergoTree, creationHeight, additionalTokens, additionalRegisters) - override def toString: String = s"ErgoBox(${SigmaAlgos.encode(id)},$value,$ergoTree," + - s"tokens: (${additionalTokens.map(t => SigmaAlgos.encode(t._1) + ":" + t._2)}), $transactionId, " + + override def toString: String = s"ErgoBox(${ErgoAlgos.encode(id)},$value,$ergoTree," + + s"tokens: (${additionalTokens.map(t => ErgoAlgos.encode(t._1) + ":" + t._2)}), $transactionId, " + s"$index, $additionalRegisters, $creationHeight)" } diff --git a/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala b/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala index 0ba1572da7..332c2ac533 100644 --- a/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala +++ b/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala @@ -3,7 +3,7 @@ package org.ergoplatform import java.util import org.ergoplatform.ErgoBox._ -import org.ergoplatform.settings.SigmaAlgos +import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.hash.Digest32 import scorex.util.ModifierId import sigmastate.Values._ @@ -75,7 +75,7 @@ class ErgoBoxCandidate(val value: Long, ScalaRunTime._hashCode((value, ergoTree, additionalTokens, additionalRegisters, creationHeight)) override def toString: Idn = s"ErgoBoxCandidate($value, $ergoTree," + - s"tokens: (${additionalTokens.map(t => SigmaAlgos.encode(t._1) + ":" + t._2).toArray.mkString(", ")}), " + + s"tokens: (${additionalTokens.map(t => ErgoAlgos.encode(t._1) + ":" + t._2).toArray.mkString(", ")}), " + s"$additionalRegisters, creationHeight: $creationHeight)" } diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 01c8e86532..1e9cb192d3 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -19,7 +19,7 @@ import special.sigma.{AnyValue, Box, GroupElement, Header, PreHeader} import SType._ import RType._ import org.ergoplatform.ErgoConstants.ScriptCostLimit -import org.ergoplatform.settings.SigmaAlgos +import org.ergoplatform.settings.ErgoAlgos import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} import spire.syntax.all.cfor import scala.util.Try diff --git a/src/main/scala/org/ergoplatform/Input.scala b/src/main/scala/org/ergoplatform/Input.scala index d20c9b4095..8e0c286fb7 100644 --- a/src/main/scala/org/ergoplatform/Input.scala +++ b/src/main/scala/org/ergoplatform/Input.scala @@ -5,7 +5,7 @@ import java.util import io.circe._ import io.circe.syntax._ import org.ergoplatform.ErgoBox.BoxId -import org.ergoplatform.settings.SigmaAlgos +import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.ADKey import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.serialization.SigmaSerializer @@ -17,7 +17,7 @@ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} * @param boxId - id of a box to add into context (should be in UTXO) */ case class DataInput(boxId: BoxId) { - override def toString: String = s"DataInput(${SigmaAlgos.encode(boxId)})" + override def toString: String = s"DataInput(${ErgoAlgos.encode(boxId)})" } object DataInput extends JsonCodecs { @@ -69,7 +69,7 @@ class UnsignedInput(val boxId: BoxId, val extension: ContextExtension) { */ case class Input(override val boxId: BoxId, spendingProof: ProverResult) extends UnsignedInput(boxId, spendingProof.extension) { - override def toString: String = s"Input(${SigmaAlgos.encode(boxId)},$spendingProof)" + override def toString: String = s"Input(${ErgoAlgos.encode(boxId)},$spendingProof)" } object Input extends JsonCodecs { diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index 63ddd13df3..ea085fc9ec 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -6,7 +6,7 @@ import cats.syntax.either._ import io.circe._ import io.circe.syntax._ import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} -import org.ergoplatform.settings.SigmaAlgos +import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.{ADDigest, ADKey} import scorex.crypto.hash.Digest32 import scorex.util.ModifierId @@ -37,7 +37,7 @@ trait JsonCodecs { private def bytesDecoder[T](transform: Array[Byte] => T): Decoder[T] = { implicit cursor => for { str <- cursor.as[String] - bytes <- fromTry(SigmaAlgos.decode(str)) + bytes <- fromTry(ErgoAlgos.decode(str)) } yield transform(bytes) } @@ -52,10 +52,10 @@ trait JsonCodecs { } yield CBigInt(bigInt.bigInteger) } - implicit val arrayBytesEncoder: Encoder[Array[Byte]] = SigmaAlgos.encode(_).asJson + implicit val arrayBytesEncoder: Encoder[Array[Byte]] = ErgoAlgos.encode(_).asJson implicit val arrayBytesDecoder: Decoder[Array[Byte]] = bytesDecoder(x => x) - implicit val collBytesEncoder: Encoder[Coll[Byte]] = SigmaAlgos.encode(_).asJson + implicit val collBytesEncoder: Encoder[Coll[Byte]] = ErgoAlgos.encode(_).asJson implicit val collBytesDecoder: Decoder[Coll[Byte]] = bytesDecoder(Colls.fromArray(_)) implicit val adKeyEncoder: Encoder[ADKey] = _.array.asJson diff --git a/src/main/scala/org/ergoplatform/settings/SigmaAlgos.scala b/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala similarity index 89% rename from src/main/scala/org/ergoplatform/settings/SigmaAlgos.scala rename to src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala index 461fcdb82f..61743fc0b8 100644 --- a/src/main/scala/org/ergoplatform/settings/SigmaAlgos.scala +++ b/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala @@ -9,7 +9,7 @@ import special.collection.Coll import scala.util.Try // TODO: use it in ergo (delete ergo's own) -object SigmaAlgos extends ScorexEncoding { +trait ErgoAlgos extends ScorexEncoding { type HF = Blake2b256.type @@ -23,3 +23,5 @@ object SigmaAlgos extends ScorexEncoding { @inline def decodeUnsafe(str: String): Array[Byte] = decode(str).get } + +object ErgoAlgos extends ErgoAlgos diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index 706834d87f..251a202906 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -6,7 +6,7 @@ import java.util.{Arrays, Objects} import io.circe._ import io.circe.syntax._ import org.ergoplatform.JsonCodecs -import org.ergoplatform.settings.SigmaAlgos +import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.ADDigest import sigmastate.interpreter.CryptoConstants import sigmastate.serialization.SigmaSerializer diff --git a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index 2a0049cac4..5f18b05af6 100644 --- a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -9,7 +9,7 @@ import org.bitbucket.inkytonik.kiama.attribution.AttributionCore import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{everywherebu, everywheretd, rule} import org.bitbucket.inkytonik.kiama.rewriting.Strategy import org.ergoplatform.JsonCodecs -import org.ergoplatform.settings.SigmaAlgos +import org.ergoplatform.settings.ErgoAlgos import scalan.util.CollectionUtil._ import sigmastate.Values._ import sigmastate._ @@ -37,7 +37,7 @@ class ProverResult(val proof: Array[Byte], val extension: ContextExtension) { case _ => false } - override def toString: Idn = s"ProverResult(${SigmaAlgos.encode(proof)},$extension)" + override def toString: Idn = s"ProverResult(${ErgoAlgos.encode(proof)},$extension)" } object ProverResult extends JsonCodecs { From 18d94e72a61b31f91ece2bc4ed475424c6dd5351 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Sun, 4 Aug 2019 15:53:11 +0300 Subject: [PATCH 28/64] relax type for evaluatedValueDecoder; --- src/main/scala/org/ergoplatform/JsonCodecs.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index ea085fc9ec..b82976ee83 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -146,11 +146,11 @@ trait JsonCodecs { } yield CPreHeader(version, parentId, timestamp, nBits, height, CGroupElement.decode(minerPk), votes) } - implicit val evaluatedValueEncoder: Encoder[EvaluatedValue[SType]] = { value => + implicit val evaluatedValueEncoder: Encoder[EvaluatedValue[_ <: SType]] = { value => ValueSerializer.serialize(value).asJson } - implicit val evaluatedValueDecoder: Decoder[EvaluatedValue[SType]] = { + implicit val evaluatedValueDecoder: Decoder[EvaluatedValue[_ <: SType]] = { decodeEvaluatedValue(_.asInstanceOf[EvaluatedValue[SType]]) } From 3429e5282fcb32a461e91a78c226e6ea66c9a96e Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Sun, 4 Aug 2019 16:20:28 +0300 Subject: [PATCH 29/64] remove box.transactionId and index from ErgoBox json; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index 05ba919e2e..21bd8d6648 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -210,8 +210,6 @@ object ErgoBox extends JsonCodecs { .asJson(Encoder.encodeSeq(Encoder.encodeTuple2(digest32Encoder, Encoder.encodeLong))), "creationHeight" -> box.creationHeight.asJson, "additionalRegisters" -> box.additionalRegisters.asInstanceOf[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]].asJson, - "transactionId" -> box.transactionId.asJson, - "index" -> box.index.asJson ) } From 209435b031b3103a3b376e77df4fc14e43d09d73 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Sun, 4 Aug 2019 16:22:41 +0300 Subject: [PATCH 30/64] fix build; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index 21bd8d6648..cd6d827feb 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -209,7 +209,7 @@ object ErgoBox extends JsonCodecs { "assets" -> box.additionalTokens.toArray.toSeq .asJson(Encoder.encodeSeq(Encoder.encodeTuple2(digest32Encoder, Encoder.encodeLong))), "creationHeight" -> box.creationHeight.asJson, - "additionalRegisters" -> box.additionalRegisters.asInstanceOf[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]].asJson, + "additionalRegisters" -> box.additionalRegisters.asInstanceOf[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]].asJson ) } From 6ec935e58f2b75f9e180612cb87989e5973b6f3a Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Sun, 4 Aug 2019 19:56:42 +0300 Subject: [PATCH 31/64] move all json codecs under JsonCodecs trait; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 48 +---- .../org/ergoplatform/ErgoLikeContext.scala | 52 +---- .../ergoplatform/ErgoLikeTransaction.scala | 44 +--- src/main/scala/org/ergoplatform/Input.scala | 34 +-- .../scala/org/ergoplatform/JsonCodecs.scala | 199 +++++++++++++++++- .../validation/SigmaValidationSettings.scala | 17 -- .../validation/ValidationRules.scala | 11 +- src/main/scala/sigmastate/AvlTreeData.scala | 24 +-- .../interpreter/InterpreterContext.scala | 17 +- .../interpreter/ProverInterpreter.scala | 20 +- .../ergoplatform/JsonSerializationSpec.scala | 5 +- 11 files changed, 225 insertions(+), 246 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index cd6d827feb..2dc508a564 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -1,23 +1,21 @@ package org.ergoplatform -import io.circe._ -import io.circe.syntax._ import com.google.common.primitives.Shorts import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.ADKey import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util._ -import sigmastate.Values._ +import sigmastate.SCollection.SByteArray import sigmastate.SType.AnyOps +import sigmastate.Values._ import sigmastate._ -import sigmastate.serialization.{ErgoTreeSerializer, SigmaSerializer} -import sigmastate.SCollection.SByteArray +import sigmastate.eval.Extensions._ +import sigmastate.eval._ +import sigmastate.serialization.SigmaSerializer import sigmastate.utils.{Helpers, SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.ExtractCreationInfo import special.collection._ -import sigmastate.eval._ -import sigmastate.eval.Extensions._ import scala.runtime.ScalaRunTime @@ -91,7 +89,7 @@ class ErgoBox( s"$index, $additionalRegisters, $creationHeight)" } -object ErgoBox extends JsonCodecs { +object ErgoBox { type BoxId = ADKey object BoxId { val size: Short = 32 @@ -199,38 +197,4 @@ object ErgoBox extends JsonCodecs { ergoBoxCandidate.toBox(transactionId, index.toShort) } } - - // TODO remove in ergo - implicit val jsonEncoder: Encoder[ErgoBox] = { box => - Json.obj( - "boxId" -> box.id.asJson, - "value" -> box.value.asJson, - "ergoTree" -> ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(box.ergoTree).asJson, - "assets" -> box.additionalTokens.toArray.toSeq - .asJson(Encoder.encodeSeq(Encoder.encodeTuple2(digest32Encoder, Encoder.encodeLong))), - "creationHeight" -> box.creationHeight.asJson, - "additionalRegisters" -> box.additionalRegisters.asInstanceOf[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]].asJson - ) - } - - implicit val jsonDecoder: Decoder[ErgoBox] = { cursor => - for { - value <- cursor.downField("value").as[Long] - ergoTreeBytes <- cursor.downField("ergoTree").as[Array[Byte]] - additionalTokens <- cursor.downField("assets").as(Decoder.decodeSeq(Decoder.decodeTuple2(digest32Decoder, Decoder.decodeLong))) - creationHeight <- cursor.downField("creationHeight").as[Int] - additionalRegisters <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] - transactionId <- cursor.downField("transactionId").as[ModifierId] - index <- cursor.downField("index").as[Short] - } yield new ErgoBox( - value = value, - ergoTree = ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(ergoTreeBytes), - additionalTokens = additionalTokens.toColl, - additionalRegisters = additionalRegisters, - transactionId = transactionId, - index = index, - creationHeight = creationHeight - ) - } - } diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 1e9cb192d3..b8d04bc499 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -2,26 +2,24 @@ package org.ergoplatform import java.util -import io.circe._ -import io.circe.syntax._ +import org.ergoplatform.ErgoConstants.ScriptCostLimit import org.ergoplatform.ErgoLikeContext.Height +import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} import scalan.RType +import scalan.RType._ +import sigmastate.SType._ import sigmastate.Values._ import sigmastate._ -import sigmastate.eval._ import sigmastate.eval.Extensions._ +import sigmastate.eval._ import sigmastate.interpreter.{ContextExtension, CryptoConstants, InterpreterContext} -import sigmastate.serialization.{GroupElementSerializer, OpCodes, SigmaSerializer} import sigmastate.serialization.OpCodes.OpCode +import sigmastate.serialization.{GroupElementSerializer, OpCodes, SigmaSerializer} import special.collection.Coll import special.sigma import special.sigma.{AnyValue, Box, GroupElement, Header, PreHeader} -import SType._ -import RType._ -import org.ergoplatform.ErgoConstants.ScriptCostLimit -import org.ergoplatform.settings.ErgoAlgos -import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} import spire.syntax.all.cfor + import scala.util.Try case class BlockchainState(currentHeight: Height, lastBlockUtxoRoot: AvlTreeData) @@ -151,7 +149,7 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, override def toString = s"ErgoLikeContext(lastBlockUtxoRoot=$lastBlockUtxoRoot, headers=$headers, preHeader=$preHeader, dataBoxes=$dataBoxes, boxesToSpend=$boxesToSpend, spendingTransaction=$spendingTransaction, selfIndex=$selfIndex, extension=$extension, validationSettings=$validationSettings, costLimit=$costLimit, initCost=$initCost)" } -object ErgoLikeContext extends JsonCodecs { +object ErgoLikeContext { type Height = Int /* NO HF PROOF: @@ -241,40 +239,6 @@ object ErgoLikeContext extends JsonCodecs { new CostingBox(isCost, ebox) } } - - implicit val jsonEncoder: Encoder[ErgoLikeContext] = { ctx => - Json.obj( - "lastBlockUtxoRoot" -> ctx.lastBlockUtxoRoot.asJson, - "headers" -> ctx.headers.toArray.toSeq.asJson, - "preHeader" -> ctx.preHeader.asJson, - "dataBoxes" -> ctx.dataBoxes.asJson, - "boxesToSpend" -> ctx.boxesToSpend.asJson, - // TODO: handle unsigned tx - "spendingTransaction" -> ctx.spendingTransaction.asInstanceOf[ErgoLikeTransaction].asJson, - "selfIndex" -> ctx.selfIndex.asJson, - "extension" -> ctx.extension.asJson, - "validationSettings" -> ctx.validationSettings.asJson, - "costLimit" -> ctx.costLimit.asJson, - "initCost" -> ctx.initCost.asJson - ) - } - - implicit val jsonDecoder: Decoder[ErgoLikeContext] = { cursor => - for { - lastBlockUtxoRoot <- cursor.downField("lastBlockUtxoRoot").as[AvlTreeData] - headers <- cursor.downField("headers").as[Seq[Header]] - preHeader <- cursor.downField("preHeader").as[PreHeader] - dataBoxes <- cursor.downField("dataBoxes").as[IndexedSeq[ErgoBox]] - boxesToSpend <- cursor.downField("boxesToSpend").as[IndexedSeq[ErgoBox]] - spendingTransaction <- cursor.downField("spendingTransaction").as[ErgoLikeTransaction] - selfIndex <- cursor.downField("selfIndex").as[Int] - extension <- cursor.downField("extension").as[ContextExtension] - validationSettings <- cursor.downField("validationSettings").as[SigmaValidationSettings] - costLimit <- cursor.downField("costLimit").as[Long] - initCost <- cursor.downField("initCost").as[Long] - } yield new ErgoLikeContext(lastBlockUtxoRoot, Colls.fromArray(headers.toArray), preHeader, - dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) - } } /** When interpreted evaluates to a ByteArrayConstant built from Context.minerPubkey */ diff --git a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index b55a8911c0..d0fc5cc941 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -1,26 +1,20 @@ package org.ergoplatform -import java.util - -import io.circe._ -import io.circe.syntax._ -import org.ergoplatform.ErgoBox.{BoxId, NonMandatoryRegisterId, TokenId} +import org.ergoplatform.ErgoBox.TokenId import scorex.crypto.authds.ADKey import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util._ -import sigmastate.SType +import sigmastate.SType._ +import sigmastate.eval.Extensions._ +import sigmastate.eval._ import sigmastate.interpreter.ProverResult import sigmastate.serialization.SigmaSerializer import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import special.collection.ExtensionMethods._ -import sigmastate.eval.Extensions._ import spire.syntax.all.cfor import scala.collection.mutable import scala.util.Try -import sigmastate.SType._ -import sigmastate.Values.{ErgoTree, EvaluatedValue} -import sigmastate.eval._ trait ErgoBoxReader { def byId(boxId: ADKey): Try[ErgoBox] @@ -172,7 +166,7 @@ object ErgoLikeTransactionSerializer extends SigmaSerializer[ErgoLikeTransaction } -object ErgoLikeTransaction extends JsonCodecs { +object ErgoLikeTransaction { val TransactionIdBytesSize: Short = 32 @@ -198,32 +192,4 @@ object ErgoLikeTransaction extends JsonCodecs { // TODO unify serialization approach in Ergo/sigma with BytesSerializable val serializer: SigmaSerializer[ErgoLikeTransaction, ErgoLikeTransaction] = ErgoLikeTransactionSerializer - - implicit val jsonEncoder: Encoder[ErgoLikeTransaction] = { tx => - Json.obj( - "id" -> tx.id.asJson, - "inputs" -> tx.inputs.asJson, - "dataInputs" -> tx.dataInputs.asJson, - "outputs" -> tx.outputs.asJson - ) - } - - private implicit val outputDecoder: Decoder[(ErgoBoxCandidate, Option[BoxId])] = { cursor => - for { - maybeId <- cursor.downField("boxId").as[Option[BoxId]] - value <- cursor.downField("value").as[Long] - creationHeight <- cursor.downField("creationHeight").as[Int] - ergoTree <- cursor.downField("ergoTree").as[ErgoTree] - assets <- cursor.downField("assets").as[Seq[(ErgoBox.TokenId, Long)]] // TODO optimize: encode directly into Coll avoiding allocation of Tuple2 for each element - registers <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] - } yield (new ErgoBoxCandidate(value, ergoTree, creationHeight, assets.toColl, registers), maybeId) - } - - implicit val jsonDecoder: Decoder[ErgoLikeTransaction] = { implicit cursor => - for { - inputs <- cursor.downField("inputs").as[IndexedSeq[Input]] - dataInputs <- cursor.downField("dataInputs").as[IndexedSeq[DataInput]] - outputsWithIndex <- cursor.downField("outputs").as[IndexedSeq[(ErgoBoxCandidate, Option[BoxId])]] - } yield new ErgoLikeTransaction(inputs, dataInputs, outputsWithIndex.map(_._1)) - } } diff --git a/src/main/scala/org/ergoplatform/Input.scala b/src/main/scala/org/ergoplatform/Input.scala index 8e0c286fb7..94fc16643a 100644 --- a/src/main/scala/org/ergoplatform/Input.scala +++ b/src/main/scala/org/ergoplatform/Input.scala @@ -2,8 +2,6 @@ package org.ergoplatform import java.util -import io.circe._ -import io.circe.syntax._ import org.ergoplatform.ErgoBox.BoxId import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.ADKey @@ -20,22 +18,6 @@ case class DataInput(boxId: BoxId) { override def toString: String = s"DataInput(${ErgoAlgos.encode(boxId)})" } -object DataInput extends JsonCodecs { - - implicit val jsonEncoder: Encoder[DataInput] = { input => - Json.obj( - "boxId" -> input.boxId.asJson, - ) - } - - implicit val jsonDecoder: Decoder[DataInput] = { cursor => - for { - boxId <- cursor.downField("boxId").as[ADKey] - } yield DataInput(boxId) - } - -} - /** * Inputs of formed, but unsigned transaction * @@ -72,7 +54,7 @@ case class Input(override val boxId: BoxId, spendingProof: ProverResult) override def toString: String = s"Input(${ErgoAlgos.encode(boxId)},$spendingProof)" } -object Input extends JsonCodecs { +object Input { object serializer extends SigmaSerializer[Input, Input] { @@ -88,18 +70,4 @@ object Input extends JsonCodecs { } } - implicit val jsonEncoder: Encoder[Input] = { input => - Json.obj( - "boxId" -> input.boxId.asJson, - "spendingProof" -> input.spendingProof.asJson - ) - } - - implicit val jsonDecoder: Decoder[Input] = { cursor => - for { - boxId <- cursor.downField("boxId").as[ADKey] - proof <- cursor.downField("spendingProof").as[ProverResult] - } yield Input(boxId, proof) - } - } diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index b82976ee83..8573d7d01d 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -5,15 +5,18 @@ import java.math.BigInteger import cats.syntax.either._ import io.circe._ import io.circe.syntax._ -import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} +import org.ergoplatform.ErgoBox.{BoxId, NonMandatoryRegisterId, TokenId} import org.ergoplatform.settings.ErgoAlgos +import org.ergoplatform.validation.{SigmaValidationSettings, SigmaValidationSettingsSerializer} import scorex.crypto.authds.{ADDigest, ADKey} import scorex.crypto.hash.Digest32 import scorex.util.ModifierId import sigmastate.Values.{ErgoTree, EvaluatedValue} +import sigmastate.eval.Extensions._ import sigmastate.eval.{CGroupElement, CPreHeader, WrapperOf, _} +import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.serialization.{ErgoTreeSerializer, ValueSerializer} -import sigmastate.{AvlTreeData, SType} +import sigmastate.{AvlTreeData, AvlTreeFlags, SType} import special.collection.Coll import special.sigma.{Header, PreHeader} @@ -67,6 +70,20 @@ trait JsonCodecs { implicit val digest32Encoder: Encoder[Digest32] = _.array.asJson implicit val digest32Decoder: Decoder[Digest32] = bytesDecoder(Digest32 @@ _) + implicit val assetEncoder: Encoder[(TokenId, Long)] = { asset => + Json.obj( + "tokenId" -> asset._1.asJson, + "amount" -> asset._2.asJson + ) + } + + implicit val assetDecoder: Decoder[(TokenId, Long)] = { cursor => + for { + tokenId <- cursor.downField("tokenId").as[TokenId] + amount <- cursor.downField("amount").as[Long] + } yield (tokenId, amount) + } + implicit val modifierIdEncoder: Encoder[ModifierId] = _.asInstanceOf[String].asJson implicit val modifierIdDecoder: Decoder[ModifierId] = ModifierId @@ _.as[String] @@ -160,6 +177,78 @@ trait JsonCodecs { } } + implicit val dataInputEncoder: Encoder[DataInput] = { input => + Json.obj( + "boxId" -> input.boxId.asJson, + ) + } + + implicit val dataInputDecoder: Decoder[DataInput] = { cursor => + for { + boxId <- cursor.downField("boxId").as[ADKey] + } yield DataInput(boxId) + } + + implicit val inputEncoder: Encoder[Input] = { input => + Json.obj( + "boxId" -> input.boxId.asJson, + "spendingProof" -> input.spendingProof.asJson + ) + } + + implicit val inputDecoder: Decoder[Input] = { cursor => + for { + boxId <- cursor.downField("boxId").as[ADKey] + proof <- cursor.downField("spendingProof").as[ProverResult] + } yield Input(boxId, proof) + } + + + implicit val contextExtensionEncoder: Encoder[ContextExtension] = { extension => + extension.values.map { case (key, value) => + key -> evaluatedValueEncoder(value) + }.asJson + } + + implicit val contextExtensionDecoder: Decoder[ContextExtension] = { cursor => + for { + values <- cursor.as[Map[Byte, EvaluatedValue[SType]]] + } yield ContextExtension(values) + } + + implicit val proverResultEncoder: Encoder[ProverResult] = { v => + Json.obj( + "proofBytes" -> v.proof.asJson, + "extension" -> v.extension.asJson + ) + } + + implicit val proverResultDecoder: Decoder[ProverResult] = { cursor => + for { + proofBytes <- cursor.downField("proofBytes").as[Array[Byte]] + extMap <- cursor.downField("extension").as[Map[Byte, EvaluatedValue[SType]]] + } yield ProverResult(proofBytes, ContextExtension(extMap)) + } + + + implicit val avlTreeDataEncoder: Encoder[AvlTreeData] = { v => + Json.obj( + "digest" -> v.digest.asJson, + "treeFlags" -> v.treeFlags.serializeToByte.asJson, + "keyLength" -> v.keyLength.asJson, + "valueLength" -> v.valueLengthOpt.asJson + ) + } + + implicit val avlTreeDataDecoder: Decoder[AvlTreeData] = { cursor => + for { + digest <- cursor.downField("digest").as[ADDigest] + treeFlagsByte <- cursor.downField("treeFlags").as[Byte] + keyLength <- cursor.downField("keyLength").as[Int] + valueLength <- cursor.downField("valueLength").as[Option[Int]] + } yield new AvlTreeData(digest, AvlTreeFlags(treeFlagsByte), keyLength, valueLength) + } + implicit val ergoTreeEncoder: Encoder[ErgoTree] = { value => ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(value).asJson } @@ -173,4 +262,110 @@ trait JsonCodecs { implicit val ergoTreeDecoder: Decoder[ErgoTree] = { decodeErgoTree(_.asInstanceOf[ErgoTree]) } + + implicit val ergoBoxEncoder: Encoder[ErgoBox] = { box => + Json.obj( + "boxId" -> box.id.asJson, + "value" -> box.value.asJson, + "ergoTree" -> ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(box.ergoTree).asJson, + "assets" -> box.additionalTokens.toArray.toSeq + .asJson, //(Encoder.encodeSeq(Encoder.encodeTuple2(digest32Encoder, Encoder.encodeLong))), + "creationHeight" -> box.creationHeight.asJson, + "additionalRegisters" -> box.additionalRegisters.asInstanceOf[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]].asJson, + "transactionId" -> box.transactionId.asJson, + "index" -> box.index.asJson + ) + } + + implicit val ergoBoxDecoder: Decoder[ErgoBox] = { cursor => + for { + value <- cursor.downField("value").as[Long] + ergoTreeBytes <- cursor.downField("ergoTree").as[Array[Byte]] + additionalTokens <- cursor.downField("assets").as(Decoder.decodeSeq(assetDecoder)) + creationHeight <- cursor.downField("creationHeight").as[Int] + additionalRegisters <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] + transactionId <- cursor.downField("transactionId").as[ModifierId] + index <- cursor.downField("index").as[Short] + } yield new ErgoBox( + value = value, + ergoTree = ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(ergoTreeBytes), + additionalTokens = additionalTokens.toColl, + additionalRegisters = additionalRegisters, + transactionId = transactionId, + index = index, + creationHeight = creationHeight + ) + } + + implicit val ergoLikeTransactionEncoder: Encoder[ErgoLikeTransaction] = { tx => + Json.obj( + "id" -> tx.id.asJson, + "inputs" -> tx.inputs.asJson, + "dataInputs" -> tx.dataInputs.asJson, + "outputs" -> tx.outputs.asJson + ) + } + + implicit val transactionOutputsDecoder: Decoder[(ErgoBoxCandidate, Option[BoxId])] = { cursor => + for { + maybeId <- cursor.downField("boxId").as[Option[BoxId]] + value <- cursor.downField("value").as[Long] + creationHeight <- cursor.downField("creationHeight").as[Int] + ergoTree <- cursor.downField("ergoTree").as[ErgoTree] + assets <- cursor.downField("assets").as[Seq[(ErgoBox.TokenId, Long)]] // TODO optimize: encode directly into Coll avoiding allocation of Tuple2 for each element + registers <- cursor.downField("additionalRegisters").as[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] + } yield (new ErgoBoxCandidate(value, ergoTree, creationHeight, assets.toColl, registers), maybeId) + } + + implicit val ergoLikeTransactionDecoder: Decoder[ErgoLikeTransaction] = { implicit cursor => + for { + inputs <- cursor.downField("inputs").as[IndexedSeq[Input]] + dataInputs <- cursor.downField("dataInputs").as[IndexedSeq[DataInput]] + outputsWithIndex <- cursor.downField("outputs").as[IndexedSeq[(ErgoBoxCandidate, Option[BoxId])]] + } yield new ErgoLikeTransaction(inputs, dataInputs, outputsWithIndex.map(_._1)) + } + + implicit val sigmaValidationSettingsEncoder: Encoder[SigmaValidationSettings] = { v => + SigmaValidationSettingsSerializer.toBytes(v).asJson + } + + implicit val sigmaValidationSettingsDecoder: Decoder[SigmaValidationSettings] = { implicit cursor: ACursor => + cursor.as[Array[Byte]] flatMap { bytes => + fromThrows(SigmaValidationSettingsSerializer.fromBytes(bytes)) + } + } + + implicit val ergoLikeContextEncoder: Encoder[ErgoLikeContext] = { ctx => + Json.obj( + "lastBlockUtxoRoot" -> ctx.lastBlockUtxoRoot.asJson, + "headers" -> ctx.headers.toArray.toSeq.asJson, + "preHeader" -> ctx.preHeader.asJson, + "dataBoxes" -> ctx.dataBoxes.asJson, + "boxesToSpend" -> ctx.boxesToSpend.asJson, + // TODO: handle unsigned tx + "spendingTransaction" -> ctx.spendingTransaction.asInstanceOf[ErgoLikeTransaction].asJson, + "selfIndex" -> ctx.selfIndex.asJson, + "extension" -> ctx.extension.asJson, + "validationSettings" -> ctx.validationSettings.asJson, + "costLimit" -> ctx.costLimit.asJson, + "initCost" -> ctx.initCost.asJson + ) + } + + implicit val ergoLikeContextDecoder: Decoder[ErgoLikeContext] = { cursor => + for { + lastBlockUtxoRoot <- cursor.downField("lastBlockUtxoRoot").as[AvlTreeData] + headers <- cursor.downField("headers").as[Seq[Header]] + preHeader <- cursor.downField("preHeader").as[PreHeader] + dataBoxes <- cursor.downField("dataBoxes").as[IndexedSeq[ErgoBox]] + boxesToSpend <- cursor.downField("boxesToSpend").as[IndexedSeq[ErgoBox]] + spendingTransaction <- cursor.downField("spendingTransaction").as[ErgoLikeTransaction] + selfIndex <- cursor.downField("selfIndex").as[Int] + extension <- cursor.downField("extension").as[ContextExtension] + validationSettings <- cursor.downField("validationSettings").as[SigmaValidationSettings] + costLimit <- cursor.downField("costLimit").as[Long] + initCost <- cursor.downField("initCost").as[Long] + } yield new ErgoLikeContext(lastBlockUtxoRoot, Colls.fromArray(headers.toArray), preHeader, + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) + } } diff --git a/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala b/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala index f2a7e5bd6c..e74e41c8c1 100644 --- a/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala +++ b/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala @@ -1,9 +1,5 @@ package org.ergoplatform.validation -import io.circe._ -import io.circe.syntax._ -import org.ergoplatform.JsonCodecs - /** * Configuration of validation. Each `ValidationRule` instance should be * implemented as an `object` to facilitate type-safe usage. It then should be @@ -59,19 +55,6 @@ abstract class SigmaValidationSettings extends Iterable[(Short, (ValidationRule, } } -object SigmaValidationSettings extends JsonCodecs { - - implicit val jsonEncoder: Encoder[SigmaValidationSettings] = { v => - SigmaValidationSettingsSerializer.toBytes(v).asJson - } - - implicit val jsonDecoder: Decoder[SigmaValidationSettings] = { implicit cursor: ACursor => - cursor.as[Array[Byte]] flatMap { bytes => - fromThrows(SigmaValidationSettingsSerializer.fromBytes(bytes)) - } - } -} - /** Default representation of validation settings. */ sealed class MapSigmaValidationSettings(private val map: Map[Short, (ValidationRule, RuleStatus)]) extends SigmaValidationSettings { override def iterator: Iterator[(Short, (ValidationRule, RuleStatus))] = map.iterator diff --git a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index 5255f7857e..3466c28433 100644 --- a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -4,22 +4,19 @@ import java.nio.ByteBuffer import java.util import org.ergoplatform.ErgoConstants.MaxLoopLevelInCostFunction -import org.ergoplatform.JsonCodecs import scorex.util.ByteArrayBuilder import scorex.util.serialization.{VLQByteBufferReader, VLQByteBufferWriter} import sigma.util.Extensions.toUByte +import sigmastate.Values.{ErgoTree, IntValue, SValue, Value} +import sigmastate._ import sigmastate.eval.IRContext +import sigmastate.lang.exceptions._ import sigmastate.serialization.OpCodes.{OpCode, OpCodeExtra} -import sigmastate.Values.{ErgoTree, IntValue, SValue, Value} +import sigmastate.serialization.TypeSerializer.embeddableIdToType import sigmastate.serialization.{OpCodes, ValueSerializer} import sigmastate.utxo.DeserializeContext -import sigmastate.lang.exceptions._ -import sigmastate.serialization.TypeSerializer.embeddableIdToType -import sigmastate._ import scala.collection.mutable -import io.circe._ -import io.circe.syntax._ /** Base class for different validation rules registered in ValidationRules.currentSettings. * Each rule is identified by `id` and have a description. diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index 251a202906..87adf2fb2a 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -3,10 +3,6 @@ package sigmastate import java.util import java.util.{Arrays, Objects} -import io.circe._ -import io.circe.syntax._ -import org.ergoplatform.JsonCodecs -import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.ADDigest import sigmastate.interpreter.CryptoConstants import sigmastate.serialization.SigmaSerializer @@ -75,7 +71,7 @@ case class AvlTreeData(digest: ADDigest, keyLength.hashCode()) * 31 + Objects.hash(valueLengthOpt, treeFlags) } -object AvlTreeData extends JsonCodecs { +object AvlTreeData { val DigestSize: Int = CryptoConstants.hashLength + 1 //please read class comments above for details val TreeDataSize = DigestSize + 3 + 4 + 4 @@ -102,22 +98,4 @@ object AvlTreeData extends JsonCodecs { AvlTreeData(ADDigest @@ digest, tf, keyLength, valueLengthOpt) } } - - implicit val jsonEncoder: Encoder[AvlTreeData] = { v => - Json.obj( - "digest" -> v.digest.asJson, - "treeFlags" -> v.treeFlags.serializeToByte.asJson, - "keyLength" -> v.keyLength.asJson, - "valueLength" -> v.valueLengthOpt.asJson - ) - } - - implicit val jsonDecoder: Decoder[AvlTreeData] = { cursor => - for { - digest <- cursor.downField("digest").as[ADDigest] - treeFlagsByte <- cursor.downField("treeFlags").as[Byte] - keyLength <- cursor.downField("keyLength").as[Int] - valueLength <- cursor.downField("valueLength").as[Option[Int]] - } yield new AvlTreeData(digest, AvlTreeFlags(treeFlagsByte), keyLength, valueLength) - } } diff --git a/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index 2a335c64d3..ea2470c0e7 100644 --- a/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -1,8 +1,5 @@ package sigmastate.interpreter -import io.circe._ -import io.circe.syntax._ -import org.ergoplatform.JsonCodecs import org.ergoplatform.validation.SigmaValidationSettings import sigmastate.SType import sigmastate.Values.EvaluatedValue @@ -22,7 +19,7 @@ case class ContextExtension(values: Map[Byte, EvaluatedValue[_ <: SType]]) { ContextExtension(values ++ bindings) } -object ContextExtension extends JsonCodecs { +object ContextExtension { val empty = ContextExtension(Map()) object serializer extends SigmaSerializer[ContextExtension, ContextExtension] { @@ -40,18 +37,6 @@ object ContextExtension extends JsonCodecs { ContextExtension(ext) } } - - implicit val jsonEncoder: Encoder[ContextExtension] = { extension => - extension.values.map { case (key, value) => - key -> evaluatedValueEncoder(value) - }.asJson - } - - implicit val jsonDecoder: Decoder[ContextExtension] = { cursor => - for { - values <- cursor.as[Map[Byte, EvaluatedValue[SType]]] - } yield ContextExtension(values) - } } diff --git a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index 5f18b05af6..99b2f94903 100644 --- a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -2,13 +2,10 @@ package sigmastate.interpreter import java.util -import io.circe._ -import io.circe.syntax._ import gf2t.{GF2_192, GF2_192_Poly} import org.bitbucket.inkytonik.kiama.attribution.AttributionCore import org.bitbucket.inkytonik.kiama.rewriting.Rewriter.{everywherebu, everywheretd, rule} import org.bitbucket.inkytonik.kiama.rewriting.Strategy -import org.ergoplatform.JsonCodecs import org.ergoplatform.settings.ErgoAlgos import scalan.util.CollectionUtil._ import sigmastate.Values._ @@ -40,7 +37,7 @@ class ProverResult(val proof: Array[Byte], val extension: ContextExtension) { override def toString: Idn = s"ProverResult(${ErgoAlgos.encode(proof)},$extension)" } -object ProverResult extends JsonCodecs { +object ProverResult { val empty: ProverResult = ProverResult(Array[Byte](), ContextExtension.empty) def apply(proof: Array[Byte], extension: ContextExtension): ProverResult = @@ -61,21 +58,6 @@ object ProverResult extends JsonCodecs { ProverResult(proofBytes, ce) } } - - implicit val jsonEncoder: Encoder[ProverResult] = { v => - Json.obj( - "proofBytes" -> v.proof.asJson, - "extension" -> v.extension.asJson - ) - } - - implicit val jsonDecoder: Decoder[ProverResult] = { cursor => - for { - proofBytes <- cursor.downField("proofBytes").as[Array[Byte]] - extMap <- cursor.downField("extension").as[Map[Byte, EvaluatedValue[SType]]] - } yield ProverResult(proofBytes, ContextExtension(extMap)) - } - } case class CostedProverResult(override val proof: Array[Byte], diff --git a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala index 45b33a58b7..8a8941a369 100644 --- a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala +++ b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala @@ -5,15 +5,12 @@ import io.circe.syntax._ import sigmastate.helpers.SigmaTestingCommons import sigmastate.serialization.SerializationSpecification -class JsonSerializationSpec extends SigmaTestingCommons with SerializationSpecification { +class JsonSerializationSpec extends SigmaTestingCommons with SerializationSpecification with JsonCodecs { property("ErgoLikeContext should be encoded into JSON and decoded back correctly") { forAll(ergoLikeContextGen) { ctx => - val ctxJson: Json = ctx.asJson val ctxDecoded: ErgoLikeContext = ctxJson.as[ErgoLikeContext].toTry.get - - // TODO: implement ErgoLikeContext.equals ctxDecoded shouldEqual ctx } } From 29f00626a5a327e52559a4c0affb9d089be585a6 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 5 Aug 2019 16:59:32 +0300 Subject: [PATCH 32/64] clean up todos; --- src/main/scala/org/ergoplatform/JsonCodecs.scala | 1 - src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index 8573d7d01d..d681db6fd2 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -23,7 +23,6 @@ import special.sigma.{Header, PreHeader} import scala.util.Try trait JsonCodecs { - //TODO: remove in ergo def fromTry[T](tryResult: Try[T])(implicit cursor: ACursor): Either[DecodingFailure, T] = { tryResult.fold(e => Left(DecodingFailure(e.toString, cursor.history)), Right.apply) diff --git a/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala b/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala index 61743fc0b8..36e311c86d 100644 --- a/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala +++ b/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala @@ -8,7 +8,6 @@ import special.collection.Coll import scala.util.Try -// TODO: use it in ergo (delete ergo's own) trait ErgoAlgos extends ScorexEncoding { type HF = Blake2b256.type From 231fce288d32fd39ea3dd6f0a3c55f8214d1bdf9 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 5 Aug 2019 17:05:07 +0300 Subject: [PATCH 33/64] construct AvlTreeData from AvlTree; --- src/main/scala/org/ergoplatform/JsonCodecs.scala | 3 +-- src/main/scala/sigmastate/AvlTreeData.scala | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index d681db6fd2..51ef04ba1d 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -102,8 +102,7 @@ trait JsonCodecs { "version" -> h.version.asJson, "parentId" -> h.parentId.asJson, "adProofsRoot" -> h.ADProofsRoot.asJson, - // TODO: fix - "stateRoot" -> h.stateRoot.asInstanceOf[WrapperOf[AvlTreeData]].wrappedValue.asJson, + "stateRoot" -> AvlTreeData(h.stateRoot).asJson, "transactionsRoot" -> h.transactionsRoot.asJson, "timestamp" -> h.timestamp.asJson, "nBits" -> h.nBits.asJson, diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index 87adf2fb2a..f12f5aa0c2 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -7,6 +7,7 @@ import scorex.crypto.authds.ADDigest import sigmastate.interpreter.CryptoConstants import sigmastate.serialization.SigmaSerializer import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} +import special.sigma.AvlTree case class AvlTreeFlags(insertAllowed: Boolean, updateAllowed: Boolean, removeAllowed: Boolean) { @@ -80,6 +81,9 @@ object AvlTreeData { AvlTreeFlags.AllOperationsAllowed, keyLength = 32) + def apply(avlTree: AvlTree): AvlTreeData = new AvlTreeData(ADDigest @@ avlTree.digest.toArray, + AvlTreeFlags.apply(avlTree.enabledOperations), avlTree.keyLength, avlTree.valueLengthOpt) + object serializer extends SigmaSerializer[AvlTreeData, AvlTreeData] { override def serialize(data: AvlTreeData, w: SigmaByteWriter): Unit = { From 98b9fc112ff3fb2c3649408479fe6d170ccadcde Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 6 Aug 2019 11:18:25 +0300 Subject: [PATCH 34/64] update tx json codecs to support UnsignedErgoLikeTransaction; --- .../ergoplatform/ErgoLikeTransaction.scala | 5 ++ .../scala/org/ergoplatform/JsonCodecs.scala | 48 +++++++++++++++++-- .../generators/ObjectGenerators.scala | 43 ++++++++++++----- 3 files changed, 80 insertions(+), 16 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index d0fc5cc941..df5e836686 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -69,6 +69,11 @@ class UnsignedErgoLikeTransaction(override val inputs: IndexedSeq[UnsignedInput] val ins = inputs.zip(proofs).map { case (ui, proof) => Input(ui.boxId, proof) } new ErgoLikeTransaction(ins, dataInputs, outputCandidates) } + + override def equals(obj: Any): Boolean = obj match { + case tx: UnsignedErgoLikeTransaction => this.id == tx.id + case _ => false + } } object UnsignedErgoLikeTransaction { diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index 51ef04ba1d..474648d4b0 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -15,6 +15,7 @@ import sigmastate.Values.{ErgoTree, EvaluatedValue} import sigmastate.eval.Extensions._ import sigmastate.eval.{CGroupElement, CPreHeader, WrapperOf, _} import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigmastate.lang.exceptions.SigmaException import sigmastate.serialization.{ErgoTreeSerializer, ValueSerializer} import sigmastate.{AvlTreeData, AvlTreeFlags, SType} import special.collection.Coll @@ -194,6 +195,7 @@ trait JsonCodecs { ) } + implicit val inputDecoder: Decoder[Input] = { cursor => for { boxId <- cursor.downField("boxId").as[ADKey] @@ -201,6 +203,19 @@ trait JsonCodecs { } yield Input(boxId, proof) } + implicit val unsignedInputEncoder: Encoder[UnsignedInput] = { input => + Json.obj( + "boxId" -> input.boxId.asJson, + "extension" -> input.extension.asJson + ) + } + + implicit val unsignedInputDecoder: Decoder[UnsignedInput] = { cursor => + for { + boxId <- cursor.downField("boxId").as[ADKey] + extension <- cursor.downField("extension").as[ContextExtension] + } yield new UnsignedInput(boxId, extension) + } implicit val contextExtensionEncoder: Encoder[ContextExtension] = { extension => extension.values.map { case (key, value) => @@ -304,6 +319,21 @@ trait JsonCodecs { ) } + implicit val unsignedErgoLikeTransactionEncoder: Encoder[UnsignedErgoLikeTransaction] = { tx => + Json.obj( + "id" -> tx.id.asJson, + "inputs" -> tx.inputs.asJson, + "dataInputs" -> tx.dataInputs.asJson, + "outputs" -> tx.outputs.asJson + ) + } + + implicit def ergoLikeTransactionTemplateEncoder[T <: UnsignedInput]: Encoder[ErgoLikeTransactionTemplate[T]] = { + case transaction: ErgoLikeTransaction => ergoLikeTransactionEncoder(transaction) + case transaction: UnsignedErgoLikeTransaction => unsignedErgoLikeTransactionEncoder(transaction) + case t => throw new SigmaException(s"Don't know how to encode transaction $t") + } + implicit val transactionOutputsDecoder: Decoder[(ErgoBoxCandidate, Option[BoxId])] = { cursor => for { maybeId <- cursor.downField("boxId").as[Option[BoxId]] @@ -323,6 +353,19 @@ trait JsonCodecs { } yield new ErgoLikeTransaction(inputs, dataInputs, outputsWithIndex.map(_._1)) } + implicit val unsignedErgoLikeTransactionDecoder: Decoder[UnsignedErgoLikeTransaction] = { implicit cursor => + for { + inputs <- cursor.downField("inputs").as[IndexedSeq[UnsignedInput]] + dataInputs <- cursor.downField("dataInputs").as[IndexedSeq[DataInput]] + outputsWithIndex <- cursor.downField("outputs").as[IndexedSeq[(ErgoBoxCandidate, Option[BoxId])]] + } yield new UnsignedErgoLikeTransaction(inputs, dataInputs, outputsWithIndex.map(_._1)) + } + + implicit val ergoLikeTransactionTemplateDecoder: Decoder[ErgoLikeTransactionTemplate[_ <: UnsignedInput]] = { + ergoLikeTransactionDecoder.asInstanceOf[Decoder[ErgoLikeTransactionTemplate[_ <: UnsignedInput]]] or + unsignedErgoLikeTransactionDecoder.asInstanceOf[Decoder[ErgoLikeTransactionTemplate[_ <: UnsignedInput]]] + } + implicit val sigmaValidationSettingsEncoder: Encoder[SigmaValidationSettings] = { v => SigmaValidationSettingsSerializer.toBytes(v).asJson } @@ -340,8 +383,7 @@ trait JsonCodecs { "preHeader" -> ctx.preHeader.asJson, "dataBoxes" -> ctx.dataBoxes.asJson, "boxesToSpend" -> ctx.boxesToSpend.asJson, - // TODO: handle unsigned tx - "spendingTransaction" -> ctx.spendingTransaction.asInstanceOf[ErgoLikeTransaction].asJson, + "spendingTransaction" -> ctx.spendingTransaction.asJson, "selfIndex" -> ctx.selfIndex.asJson, "extension" -> ctx.extension.asJson, "validationSettings" -> ctx.validationSettings.asJson, @@ -357,7 +399,7 @@ trait JsonCodecs { preHeader <- cursor.downField("preHeader").as[PreHeader] dataBoxes <- cursor.downField("dataBoxes").as[IndexedSeq[ErgoBox]] boxesToSpend <- cursor.downField("boxesToSpend").as[IndexedSeq[ErgoBox]] - spendingTransaction <- cursor.downField("spendingTransaction").as[ErgoLikeTransaction] + spendingTransaction <- cursor.downField("spendingTransaction").as(ergoLikeTransactionTemplateDecoder) selfIndex <- cursor.downField("selfIndex").as[Int] extension <- cursor.downField("extension").as[ContextExtension] validationSettings <- cursor.downField("validationSettings").as[SigmaValidationSettings] diff --git a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 8741c85a98..a44ed13470 100644 --- a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -336,12 +336,10 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with val digest32CollGen: Gen[Digest32Coll] = digest32Gen.map(Digest32Coll @@ _.toColl) val ergoTransactionGen: Gen[ErgoLikeTransaction] = for { - inputs <- Gen.nonEmptyListOf(inputGen) - tokens <- tokensGen - dataInputs <- Gen.listOf(dataInputGen) - outputsCount <- Gen.chooseNum(50, 200) - outputCandidates <- Gen.listOfN(outputsCount, ergoBoxCandidateGen(tokens)) - } yield new ErgoLikeTransaction(inputs.toIndexedSeq, dataInputs.toIndexedSeq, outputCandidates.toIndexedSeq) + inputBoxIds <- Gen.nonEmptyListOf(boxIdGen) + dataInputBoxIds <- Gen.listOf(boxIdGen) + tx <- ergoLikeTransactionGen(inputBoxIds, dataInputBoxIds) + } yield tx // distinct list of elements from a given generator // with a maximum number of elements to discard @@ -682,30 +680,49 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with votes <- minerVotesGen } yield CPreHeader(version, parentId, timestamp, nBits, height, minerPk, votes) + def ergoLikeTransactionGen(inputBoxesIds: Seq[BoxId], dataInputBoxIds: Seq[BoxId]): Gen[ErgoLikeTransaction] = for { + tokens <- tokensGen + outputsCount <- Gen.chooseNum(50, 200) + outputCandidates <- Gen.listOfN(outputsCount, ergoBoxCandidateGen(tokens)) + proofs <- Gen.listOfN(inputBoxesIds.length, serializedProverResultGen) + } yield new ErgoLikeTransaction( + inputs = inputBoxesIds.zip(proofs).map(t => Input(t._1, t._2)).toIndexedSeq, + dataInputs = dataInputBoxIds.map(DataInput).toIndexedSeq, + outputCandidates = outputCandidates.toIndexedSeq + ) + + def unsignedErgoLikeTransactionGen(inputBoxesIds: Seq[BoxId], dataInputBoxIds: Seq[BoxId]): Gen[UnsignedErgoLikeTransaction] = for { + tokens <- tokensGen + outputsCount <- Gen.chooseNum(50, 200) + outputCandidates <- Gen.listOfN(outputsCount, ergoBoxCandidateGen(tokens)) + contextExtensions <- Gen.listOfN(inputBoxesIds.length, contextExtensionGen) + } yield new UnsignedErgoLikeTransaction( + inputs = inputBoxesIds.zip(contextExtensions).map(t => new UnsignedInput(t._1, t._2)).toIndexedSeq, + dataInputs = dataInputBoxIds.map(DataInput).toIndexedSeq, + outputCandidates = outputCandidates.toIndexedSeq + ) val ergoLikeContextGen: Gen[ErgoLikeContext] = for { stateRoot <- avlTreeGen headers <- headersGen(stateRoot) preHeader <- preHeaderGen(headers.headOption.map(_.id).getOrElse(modifierIdBytesGen.sample.get)) - tokens <- tokensGen dataBoxes <- Gen.nonEmptyListOf(ergoBoxGen) boxesToSpend <- Gen.nonEmptyListOf(ergoBoxGen) extension <- contextExtensionGen - outputsCount <- Gen.chooseNum(50, 200) - outputCandidates <- Gen.listOfN(outputsCount, ergoBoxCandidateGen(tokens)) costLimit <- arbLong.arbitrary initCost <- arbLong.arbitrary avlTreeFlags <- avlTreeFlagsGen + spendingTransaction <- Gen.oneOf( + unsignedErgoLikeTransactionGen(boxesToSpend.map(_.id), dataBoxes.map(_.id)), + ergoLikeTransactionGen(boxesToSpend.map(_.id), dataBoxes.map(_.id)) + ) } yield new ErgoLikeContext( lastBlockUtxoRoot = AvlTreeData(ADDigest @@ stateRoot.digest.toArray, avlTreeFlags, unsignedIntGen.sample.get), headers = headers.toColl, preHeader = preHeader, dataBoxes = dataBoxes.toIndexedSeq, boxesToSpend = boxesToSpend.toIndexedSeq, - spendingTransaction = new ErgoLikeTransaction( - boxesToSpend.map(b => Input(b.id, serializedProverResultGen.sample.get)).toIndexedSeq, - dataBoxes.map(b => DataInput(b.id)).toIndexedSeq, - outputCandidates.toIndexedSeq), + spendingTransaction = spendingTransaction, selfIndex = 0, extension = extension, validationSettings = ValidationRules.currentSettings, From 607a3c897700a7e23be43cf570ef63d71bf066f6 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 6 Aug 2019 14:44:27 +0300 Subject: [PATCH 35/64] add json roundtrip spec; --- src/main/scala/org/ergoplatform/Input.scala | 5 + .../ergoplatform/JsonSerializationSpec.scala | 107 +++++++++++++++++- .../generators/ObjectGenerators.scala | 44 +++++-- 3 files changed, 144 insertions(+), 12 deletions(-) diff --git a/src/main/scala/org/ergoplatform/Input.scala b/src/main/scala/org/ergoplatform/Input.scala index 94fc16643a..43ab4dbd71 100644 --- a/src/main/scala/org/ergoplatform/Input.scala +++ b/src/main/scala/org/ergoplatform/Input.scala @@ -16,6 +16,11 @@ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} */ case class DataInput(boxId: BoxId) { override def toString: String = s"DataInput(${ErgoAlgos.encode(boxId)})" + + override def equals(obj: Any): Boolean = obj match { + case x: DataInput => util.Arrays.equals(boxId, x.boxId) + case _ => false + } } /** diff --git a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala index 8a8941a369..0b2580d25a 100644 --- a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala +++ b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala @@ -2,17 +2,116 @@ package org.ergoplatform import io.circe._ import io.circe.syntax._ +import org.ergoplatform.validation.ValidationRules +import scorex.crypto.authds.{ADDigest, ADKey} +import scorex.crypto.hash.Digest32 +import scorex.util.ModifierId +import sigmastate.{AvlTreeData, SType} +import sigmastate.Values.{ErgoTree, EvaluatedValue} import sigmastate.helpers.SigmaTestingCommons +import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.serialization.SerializationSpecification +import special.collection.Coll +import special.sigma.{Header, PreHeader} class JsonSerializationSpec extends SigmaTestingCommons with SerializationSpecification with JsonCodecs { + def jsonRoundTrip[T](v: T)(implicit encoder: Encoder[T], decoder: Decoder[T]): Unit = { + val json = v.asJson + withClue(s"\n for JSON: ${json.spaces2}") { json.as[T].toTry.get shouldEqual v } + } + property("ErgoLikeContext should be encoded into JSON and decoded back correctly") { - forAll(ergoLikeContextGen) { ctx => - val ctxJson: Json = ctx.asJson - val ctxDecoded: ErgoLikeContext = ctxJson.as[ErgoLikeContext].toTry.get - ctxDecoded shouldEqual ctx + forAll(ergoLikeContextGen) { v: ErgoLikeContext => jsonRoundTrip(v) } + } + + property("sigma.BigInt should be encoded into JSON and decoded back correctly") { + forAll { v: special.sigma.BigInt => jsonRoundTrip(v) } + } + + property("byte array should be encoded into JSON and decoded back correctly") { + forAll(byteArrayGen(0, 1000)) { v: Array[Byte] => jsonRoundTrip(v) } + } + + property("byte coll should be encoded into JSON and decoded back correctly") { + forAll(byteCollGen(0, 1000)) { v: Coll[Byte] => jsonRoundTrip(v) } + } + + property("ADKey should be encoded into JSON and decoded back correctly") { + forAll(boxIdGen) { v: ADKey => jsonRoundTrip(v) } + } + + property("ADDigest should be encoded into JSON and decoded back correctly") { + forAll(aDDigestGen) { v: ADDigest => jsonRoundTrip(v) } + } + + property("Digest32 should be encoded into JSON and decoded back correctly") { + forAll(digest32Gen) { v: Digest32 => jsonRoundTrip(v) } + } + + property("ModifierId should be encoded into JSON and decoded back correctly") { + forAll(modifierIdGen) { v: ModifierId => jsonRoundTrip(v) } + } + + property("Header should be encoded into JSON and decoded back correctly") { + forAll(headerGen) { v: Header => jsonRoundTrip(v) } + } + + property("PreHeader should be encoded into JSON and decoded back correctly") { + forAll(preHeaderGen) { v: PreHeader => jsonRoundTrip(v) } + } + + property("EvaluatedValue[SType] should be encoded into JSON and decoded back correctly") { + forAll(evaluatedValueGen) { v: EvaluatedValue[SType] => jsonRoundTrip(v) } + } + + property("DataInput should be encoded into JSON and decoded back correctly") { + forAll(dataInputGen) { v: DataInput => jsonRoundTrip(v) } + } + + property("Input should be encoded into JSON and decoded back correctly") { + forAll(inputGen) { v: Input => jsonRoundTrip(v) } + } + + property("UnsignedInput should be encoded into JSON and decoded back correctly") { + forAll(unsignedInputGen) { v: UnsignedInput => jsonRoundTrip(v) } + } + + property("ContextExtension should be encoded into JSON and decoded back correctly") { + forAll(contextExtensionGen) { v: ContextExtension => jsonRoundTrip(v) } + } + + property("ProverResult should be encoded into JSON and decoded back correctly") { + forAll(serializedProverResultGen) { v: ProverResult => jsonRoundTrip(v) } + } + + property("AvlTreeData should be encoded into JSON and decoded back correctly") { + forAll(avlTreeDataGen) { v: AvlTreeData => jsonRoundTrip(v) } + } + + property("ErgoTree should be encoded into JSON and decoded back correctly") { + forAll(ergoTreeGen) { v: ErgoTree => jsonRoundTrip(v) } + } + + property("ErgoBox should be encoded into JSON and decoded back correctly") { + forAll(ergoBoxGen) { v: ErgoBox => jsonRoundTrip(v) } + } + + property("ErgoLikeTransaction should be encoded into JSON and decoded back correctly") { + forAll(ergoLikeTransactionGen) { v: ErgoLikeTransaction => jsonRoundTrip(v) } + } + + property("UnsignedErgoLikeTransaction should be encoded into JSON and decoded back correctly") { + forAll(unsignedErgoLikeTransactionGen) { v: UnsignedErgoLikeTransaction => jsonRoundTrip(v) } + } + + property("ErgoLikeTransactionTemplate should be encoded into JSON and decoded back correctly") { + forAll(ergoLikeTransactionTemplateGen) { v: ErgoLikeTransactionTemplate[_ <: UnsignedInput] => + v.asJson.as(ergoLikeTransactionTemplateDecoder).toTry.get shouldEqual v } } + property("SigmaValidationSettingsEncoder should be encoded into JSON and decoded back correctly") { + jsonRoundTrip(ValidationRules.currentSettings) + } } diff --git a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index a44ed13470..c25156fc23 100644 --- a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -166,15 +166,17 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with val taggedAvlTreeGen: Gen[TaggedAvlTree] = arbByte.arbitrary.map { v => TaggedAvlTree(v).asInstanceOf[TaggedAvlTree] } + val evaluatedValueGen: Gen[EvaluatedValue[SType]] = + Gen.oneOf(booleanConstGen.asInstanceOf[Gen[EvaluatedValue[SType]]], byteArrayConstGen, longConstGen) + def additionalRegistersGen(cnt: Byte): Seq[Gen[(NonMandatoryRegisterId, EvaluatedValue[SType])]] = { (0 until cnt) .map(_ + ErgoBox.startingNonMandatoryIndex) .map(rI => ErgoBox.registerByIndex(rI).asInstanceOf[NonMandatoryRegisterId]) .map { r => for { - arr <- byteArrayConstGen - v <- Gen.oneOf(TrueLeaf, FalseLeaf, arr) - } yield r -> v.asInstanceOf[EvaluatedValue[SType]] + v <- evaluatedValueGen + } yield r -> v } } @@ -227,11 +229,9 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with .map(_ + 1) .map { varId => for { - arr <- byteArrayConstGen - longConst <- longConstGen - v <- Gen.oneOf(TrueLeaf, FalseLeaf, arr, longConst) + v <- evaluatedValueGen } - yield varId.toByte -> v.asInstanceOf[EvaluatedValue[SType]] + yield varId.toByte -> v } def avlTreeFlagsGen: Gen[AvlTreeFlags] = for { @@ -373,6 +373,8 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with def byteCollGen(length: Int): Gen[Coll[Byte]] = byteArrayGen(length).map(_.toColl) + def byteCollGen(minLength: Int, maxLength: Int): Gen[Coll[Byte]] = byteArrayGen(minLength, maxLength).map(_.toColl) + val minerVotesGen: Gen[Coll[Byte]] = byteCollGen(CHeader.VotesSize) val nonceBytesGen: Gen[Coll[Byte]] = byteCollGen(CHeader.NonceSize) @@ -646,6 +648,12 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with ErgoTree.withoutSegregation)) } yield treeBuilder(prop) + val headerGen: Gen[Header] = for { + stateRoot <- avlTreeGen + parentId <- modifierIdBytesGen + header <- headerGen(stateRoot, parentId) + } yield header + def headerGen(stateRoot: AvlTree, parentId: Coll[Byte]): Gen[Header] = for { id <- modifierIdBytesGen version <- arbByte.arbitrary @@ -671,6 +679,11 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with h :+ headerGen(stateRoot, h.last.id).sample.get }.reverse + val preHeaderGen: Gen[PreHeader] = for { + parentId <- modifierIdBytesGen + preHeader <- preHeaderGen(parentId) + } yield preHeader + def preHeaderGen(parentId: Coll[Byte]): Gen[PreHeader] = for { version <- arbByte.arbitrary timestamp <- arbLong.arbitrary @@ -680,6 +693,12 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with votes <- minerVotesGen } yield CPreHeader(version, parentId, timestamp, nBits, height, minerPk, votes) + val ergoLikeTransactionGen: Gen[ErgoLikeTransaction] = for { + inputBoxesIds <- Gen.nonEmptyListOf(boxIdGen) + dataInputBoxIds <- Gen.listOf(boxIdGen) + tx <- ergoLikeTransactionGen(inputBoxesIds, dataInputBoxIds) + } yield tx + def ergoLikeTransactionGen(inputBoxesIds: Seq[BoxId], dataInputBoxIds: Seq[BoxId]): Gen[ErgoLikeTransaction] = for { tokens <- tokensGen outputsCount <- Gen.chooseNum(50, 200) @@ -691,6 +710,12 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with outputCandidates = outputCandidates.toIndexedSeq ) + val unsignedErgoLikeTransactionGen: Gen[UnsignedErgoLikeTransaction] = for { + inputBoxesIds <- Gen.nonEmptyListOf(boxIdGen) + dataInputBoxIds <- Gen.listOf(boxIdGen) + tx <- unsignedErgoLikeTransactionGen(inputBoxesIds, dataInputBoxIds) + } yield tx + def unsignedErgoLikeTransactionGen(inputBoxesIds: Seq[BoxId], dataInputBoxIds: Seq[BoxId]): Gen[UnsignedErgoLikeTransaction] = for { tokens <- tokensGen outputsCount <- Gen.chooseNum(50, 200) @@ -702,11 +727,14 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with outputCandidates = outputCandidates.toIndexedSeq ) + val ergoLikeTransactionTemplateGen: Gen[ErgoLikeTransactionTemplate[_ <: UnsignedInput]] = + Gen.oneOf(unsignedErgoLikeTransactionGen, ergoLikeTransactionGen) + val ergoLikeContextGen: Gen[ErgoLikeContext] = for { stateRoot <- avlTreeGen headers <- headersGen(stateRoot) preHeader <- preHeaderGen(headers.headOption.map(_.id).getOrElse(modifierIdBytesGen.sample.get)) - dataBoxes <- Gen.nonEmptyListOf(ergoBoxGen) + dataBoxes <- Gen.listOf(ergoBoxGen) boxesToSpend <- Gen.nonEmptyListOf(ergoBoxGen) extension <- contextExtensionGen costLimit <- arbLong.arbitrary From bd6d16255e6c39d3535e59c6d5a8503f55ac42df Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 6 Aug 2019 14:54:21 +0300 Subject: [PATCH 36/64] set spam test branch to i4-add-input-hash; --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 821f27969f..5d34a2d6ff 100644 --- a/build.sbt +++ b/build.sbt @@ -262,7 +262,7 @@ commands += Command.command("ergoItTest") { state => } def runSpamTestTask(task: String, sigmastateVersion: String, log: Logger): Unit = { - val spamBranch = "master" + val spamBranch = "i4-add-input-hash" val envVars = Seq("SIGMASTATE_VERSION" -> sigmastateVersion, "SPECIAL_VERSION" -> specialVersion, // SSH_SPAM_REPO_KEY should be set (see Jenkins Credentials Binding Plugin) From d107eb561113ab459472e20c5311915a977ddb0a Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Wed, 7 Aug 2019 15:59:03 +0300 Subject: [PATCH 37/64] ordered ErgoBox.additionalRegisters in Json repr; --- .../scala/org/ergoplatform/JsonCodecs.scala | 12 +++++-- .../ergoplatform/JsonSerializationSpec.scala | 32 +++++++++++++++++-- .../generators/ObjectGenerators.scala | 12 ++++--- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index 474648d4b0..fa9e804c3f 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -276,15 +276,21 @@ trait JsonCodecs { decodeErgoTree(_.asInstanceOf[ErgoTree]) } + implicit def registersEncoder[T <: EvaluatedValue[_ <: SType]]: Encoder[Map[NonMandatoryRegisterId, T]] = { m => + Json.obj( + m.toSeq + .sortBy(_._1.number) + .map { case (k, v) => registerIdEncoder(k) -> evaluatedValueEncoder(v) }: _*) + } + implicit val ergoBoxEncoder: Encoder[ErgoBox] = { box => Json.obj( "boxId" -> box.id.asJson, "value" -> box.value.asJson, "ergoTree" -> ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(box.ergoTree).asJson, - "assets" -> box.additionalTokens.toArray.toSeq - .asJson, //(Encoder.encodeSeq(Encoder.encodeTuple2(digest32Encoder, Encoder.encodeLong))), + "assets" -> box.additionalTokens.toArray.toSeq.asJson, "creationHeight" -> box.creationHeight.asJson, - "additionalRegisters" -> box.additionalRegisters.asInstanceOf[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]].asJson, + "additionalRegisters" -> box.additionalRegisters.asJson, "transactionId" -> box.transactionId.asJson, "index" -> box.index.asJson ) diff --git a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala index 0b2580d25a..48f6fec54f 100644 --- a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala +++ b/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala @@ -2,14 +2,17 @@ package org.ergoplatform import io.circe._ import io.circe.syntax._ +import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, R4, R5, R6, R7, R8} import org.ergoplatform.validation.ValidationRules import scorex.crypto.authds.{ADDigest, ADKey} import scorex.crypto.hash.Digest32 import scorex.util.ModifierId +import scorex.util.encode.Base16 import sigmastate.{AvlTreeData, SType} -import sigmastate.Values.{ErgoTree, EvaluatedValue} +import sigmastate.Values.{ByteArrayConstant, ByteConstant, ErgoTree, EvaluatedValue, IntConstant, LongArrayConstant, SigmaPropConstant} +import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.helpers.SigmaTestingCommons -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigmastate.interpreter.{ContextExtension, CryptoConstants, ProverResult} import sigmastate.serialization.SerializationSpecification import special.collection.Coll import special.sigma.{Header, PreHeader} @@ -114,4 +117,29 @@ class JsonSerializationSpec extends SigmaTestingCommons with SerializationSpecif property("SigmaValidationSettingsEncoder should be encoded into JSON and decoded back correctly") { jsonRoundTrip(ValidationRules.currentSettings) } + + property("ErgoBox.additionalRegisters should be encoded into JSON in certain order") { + val minerPkHex = "0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942" + val minerPk = Base16.decode(minerPkHex).map { point => + ProveDlog( + CryptoConstants.dlogGroup.curve.decodePoint(point).asInstanceOf[CryptoConstants.EcPointType] + ) + }.get + val regs = Map( + R7 -> LongArrayConstant(Array(1L, 2L, 1234123L)), + R4 -> ByteConstant(1), + R6 -> IntConstant(10), + R5 -> SigmaPropConstant(minerPk), + R8 -> ByteArrayConstant(Base16.decode("123456123456123456123456123456123456123456123456123456123456123456").get), + ) + // registers should be ordered by their number in Json + regs.asJson.spaces2 shouldEqual + """{ + | "R4" : "0201", + | "R5" : "08cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942", + | "R6" : "0414", + | "R7" : "1103020496d39601", + | "R8" : "0e21123456123456123456123456123456123456123456123456123456123456123456" + |}""".stripMargin + } } diff --git a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index c25156fc23..561f8bdde1 100644 --- a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -170,7 +170,7 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with Gen.oneOf(booleanConstGen.asInstanceOf[Gen[EvaluatedValue[SType]]], byteArrayConstGen, longConstGen) def additionalRegistersGen(cnt: Byte): Seq[Gen[(NonMandatoryRegisterId, EvaluatedValue[SType])]] = { - (0 until cnt) + util.Random.shuffle((0 until cnt).toList) .map(_ + ErgoBox.startingNonMandatoryIndex) .map(rI => ErgoBox.registerByIndex(rI).asInstanceOf[NonMandatoryRegisterId]) .map { r => @@ -305,11 +305,15 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with candidate <- ergoBoxCandidateGen(tokens) } yield candidate.toBox(tId, boxId) + val additionalRegistersGen: Gen[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]] = for { + regNum <- Gen.chooseNum[Byte](0, ErgoBox.nonMandatoryRegistersCount) + regs <- Gen.sequence(additionalRegistersGen(regNum)) + } yield regs.asScala.toMap + def ergoBoxCandidateGen(availableTokens: Seq[Digest32]): Gen[ErgoBoxCandidate] = for { l <- arbLong.arbitrary b <- ergoTreeGen.filter(t => t.bytes.length < MaxPropositionBytes.value) - regNum <- Gen.chooseNum[Byte](0, ErgoBox.nonMandatoryRegistersCount) - ar <- Gen.sequence(additionalRegistersGen(regNum)) + ar <- additionalRegistersGen tokensCount <- Gen.chooseNum[Int](0, 20) tokens <- if(availableTokens.nonEmpty) { Gen.listOfN(tokensCount, Gen.oneOf(availableTokens)) @@ -318,7 +322,7 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with } tokenAmounts <- Gen.listOfN(tokensCount, Gen.oneOf(1, 500, 20000, 10000000, Long.MaxValue)) creationHeight <- heightGen - } yield new ErgoBoxCandidate(l, b, creationHeight, tokens.toColl.zip(tokenAmounts.toColl), ar.asScala.toMap) + } yield new ErgoBoxCandidate(l, b, creationHeight, tokens.toColl.zip(tokenAmounts.toColl), ar) val boxConstantGen: Gen[BoxConstant] = ergoBoxGen.map { v => BoxConstant(CostingBox(false, v)) } From d2f268a4e5b440a9facc4ac32e3fb48f38f78cb3 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 8 Aug 2019 13:54:43 +0300 Subject: [PATCH 38/64] move most of the ErgoLikeContext object to tests under ErgoLikeContextTesting name; --- .../org/ergoplatform/ErgoLikeContext.scala | 146 ++++++------------ .../ergoplatform/ErgoScriptPredefSpec.scala | 32 ++-- .../ergoplatform/dsl/TestContractSpec.scala | 25 ++- .../sigmastate/CalcSha256Specification.scala | 6 +- .../scala/sigmastate/FailingToProveSpec.scala | 10 +- .../SoftForkabilitySpecification.scala | 6 +- .../TestingInterpreterSpecification.scala | 8 +- .../sigmastate/eval/ErgoScriptTestkit.scala | 9 +- .../helpers/ErgoLikeContextTesting.scala | 87 +++++++++++ .../helpers/ErgoTransactionValidator.scala | 2 +- .../helpers/SigmaTestingCommons.scala | 33 ++-- .../DeserializationResilience.scala | 4 +- .../SigSerializerSpecification.scala | 6 +- .../utxo/AVLTreeScriptsSpecification.scala | 24 +-- .../utxo/BasicOpsSpecification.scala | 8 +- .../BlockchainSimulationSpecification.scala | 8 +- .../CollectionOperationsSpecification.scala | 30 ++-- .../utxo/ComplexSigSpecification.scala | 74 ++++----- .../utxo/ContextEnrichingSpecification.scala | 12 +- .../ErgoLikeInterpreterSpecification.scala | 78 +++++----- .../utxo/ThresholdSpecification.scala | 18 +-- .../benchmarks/CrowdfundingBenchmark.scala | 8 +- .../BlockchainSimulationTestingCommons.scala | 16 +- .../AtomicSwapExampleSpecification.scala | 18 +-- .../examples/CoinEmissionSpecification.scala | 4 +- ...alletAdvContractExampleSpecification.scala | 10 +- ...ldWalletContractExampleSpecification.scala | 18 +-- .../examples/CoopExampleSpecification.scala | 6 +- .../DHTupleExampleSpecification.scala | 6 +- .../DemurrageExampleSpecification.scala | 26 ++-- .../examples/FsmExampleSpecification.scala | 30 ++-- .../sigmastate/utxo/examples/IcoExample.scala | 13 +- .../utxo/examples/LetsSpecification.scala | 12 +- .../examples/MASTExampleSpecification.scala | 12 +- .../examples/MixExampleSpecification.scala | 14 +- .../OracleExamplesSpecification.scala | 14 +- .../RPSGameExampleSpecification.scala | 30 ++-- .../ReversibleTxExampleSpecification.scala | 14 +- .../utxo/examples/Rule110Specification.scala | 40 ++--- .../TimedPaymentExampleSpecification.scala | 10 +- .../XorGameExampleSpecification.scala | 18 +-- 41 files changed, 493 insertions(+), 452 deletions(-) create mode 100644 src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index b8d04bc499..257a2adc8d 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -2,28 +2,21 @@ package org.ergoplatform import java.util -import org.ergoplatform.ErgoConstants.ScriptCostLimit import org.ergoplatform.ErgoLikeContext.Height -import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} -import scalan.RType -import scalan.RType._ +import org.ergoplatform.validation.SigmaValidationSettings import sigmastate.SType._ import sigmastate.Values._ import sigmastate._ import sigmastate.eval.Extensions._ import sigmastate.eval._ -import sigmastate.interpreter.{ContextExtension, CryptoConstants, InterpreterContext} +import sigmastate.interpreter.{ContextExtension, InterpreterContext} +import sigmastate.serialization.OpCodes import sigmastate.serialization.OpCodes.OpCode -import sigmastate.serialization.{GroupElementSerializer, OpCodes, SigmaSerializer} import special.collection.Coll import special.sigma import special.sigma.{AnyValue, Box, GroupElement, Header, PreHeader} import spire.syntax.all.cfor -import scala.util.Try - -case class BlockchainState(currentHeight: Height, lastBlockUtxoRoot: AvlTreeData) - /** * TODO lastBlockUtxoRoot should be calculated from headers if it is nonEmpty * @@ -53,26 +46,47 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val initCost: Long ) extends InterpreterContext { + /* NOHF PROOF: + + */ assert(preHeader != null, "preHeader cannot be null") + /* NOHF PROOF: + + */ assert(spendingTransaction != null, "spendingTransaction cannot be null") + /* NOHF PROOF: + + */ assert(boxesToSpend.isDefinedAt(selfIndex), s"Self box if defined should be among boxesToSpend") assert(headers.toArray.headOption.forall(h => java.util.Arrays.equals(h.stateRoot.digest.toArray, lastBlockUtxoRoot.digest)), "Incorrect lastBlockUtxoRoot") cfor(0)(_ < headers.length, _ + 1) { i => if (i > 0) assert(headers(i - 1).parentId == headers(i).id, s"Incorrect chain: ${headers(i - 1).parentId},${headers(i).id}") } assert(headers.toArray.headOption.forall(_.id == preHeader.parentId), s"preHeader.parentId should be id of the best header") + /* NOHF PROOF: + + */ assert(spendingTransaction.dataInputs.length == dataBoxes.length && spendingTransaction.dataInputs.forall(dataInput => dataBoxes.exists(b => util.Arrays.equals(b.id, dataInput.boxId))), "dataBoxes do not correspond to spendingTransaction.dataInputs") // TODO assert boxesToSpend correspond to spendingTransaction.inputs + /* NOHF PROOF: + + */ // height of a block with the current `spendingTransaction` val currentHeight: Height = preHeader.height + /* NOHF PROOF: + + */ // public key of a miner of the block with the current `spendingTransaction` val minerPubkey: GroupElement = preHeader.minerPk + /* NOHF PROOF: + + */ val self: ErgoBox = boxesToSpend(selfIndex) override def withCostLimit(newCostLimit: Long): ErgoLikeContext = @@ -100,13 +114,35 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, newSpendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) - import ErgoLikeContext._ - import Evaluation._ override def toSigmaContext(IR: Evaluation, isCost: Boolean, extensions: Map[Byte, AnyValue] = Map()): sigma.Context = { implicit val IRForBox: Evaluation = IR + import Evaluation._ + + def contextVars(m: Map[Byte, AnyValue])(implicit IR: Evaluation): Coll[AnyValue] = { + val maxKey = if (m.keys.isEmpty) 0 else m.keys.max + val res = new Array[AnyValue](maxKey + 1) + for ((id, v) <- m) { + assert(res(id) == null, s"register $id is defined more then once") + res(id) = v + } + IR.sigmaDslBuilderValue.Colls.fromArray(res) + } + + implicit class ErgoBoxOps(val ebox: ErgoBox) { + def toTestBox(isCost: Boolean): Box = { + /* NOHF PROOF: + + */ + new CostingBox(isCost, ebox) + } + } + val dataInputs = this.dataBoxes.toArray.map(_.toTestBox(isCost)).toColl val inputs = boxesToSpend.toArray.map(_.toTestBox(isCost)).toColl + /* NOHF PROOF: + +*/ val outputs = spendingTransaction.outputs.toArray.map(_.toTestBox(isCost)).toColl val varMap = extension.values.mapValues { case v: EvaluatedValue[_] => val tVal = stypeToRType[SType](v.tpe) @@ -150,95 +186,11 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, } object ErgoLikeContext { - type Height = Int - /* NO HF PROOF: - Changed: val dummyPubkey from `Array[Byte] = Array.fill(32)(0: Byte)` to `GroupElementSerializer.toBytes(CryptoConstants.dlogGroup.generator)` - Motivation: to avoid exception on deserialization(wrong size, needs to be 33 bytes) and later in GroupElement.toString (infinity was not handled) and to provide more practical value in tests. - Safety: - Used only in tests and not used in ergo. - Examined ergo code: all (with IDE's "find usages" action). -*/ - val dummyPubkey: Array[Byte] = GroupElementSerializer.toBytes(CryptoConstants.dlogGroup.generator) - - val noBoxes = IndexedSeq.empty[ErgoBox] - val noHeaders = CostingSigmaDslBuilder.Colls.emptyColl[Header] - def dummyPreHeader(currentHeight: Height, minerPk: Array[Byte]): PreHeader = CPreHeader(0, - parentId = Colls.emptyColl[Byte], - timestamp = 3, - nBits = 0, - height = currentHeight, - minerPk = GroupElementSerializer.parse(SigmaSerializer.startReader(minerPk)), - votes = Colls.emptyColl[Byte] - ) + type Height = Int /** Maximimum number of headers in `headers` collection of the context. */ val MaxHeaders = ErgoConstants.MaxHeaders.value - - def apply(currentHeight: Height, - lastBlockUtxoRoot: AvlTreeData, - minerPubkey: Array[Byte], - boxesToSpend: IndexedSeq[ErgoBox], - spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], - self: ErgoBox, - extension: ContextExtension = ContextExtension.empty, - vs: SigmaValidationSettings = ValidationRules.currentSettings) = - new ErgoLikeContext(lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), noBoxes, - boxesToSpend, spendingTransaction, boxesToSpend.indexOf(self), extension, vs, ScriptCostLimit.value, 0L) - - def apply(currentHeight: Height, - lastBlockUtxoRoot: AvlTreeData, - minerPubkey: Array[Byte], - dataBoxes: IndexedSeq[ErgoBox], - boxesToSpend: IndexedSeq[ErgoBox], - spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], - selfIndex: Int) = - new ErgoLikeContext(lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), - dataBoxes, boxesToSpend, spendingTransaction, selfIndex, ContextExtension.empty, ValidationRules.currentSettings, ScriptCostLimit.value, 0L) - - - def dummy(selfDesc: ErgoBox) = ErgoLikeContext(currentHeight = 0, - lastBlockUtxoRoot = AvlTreeData.dummy, dummyPubkey, boxesToSpend = IndexedSeq(selfDesc), - spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), self = selfDesc) - - def fromTransaction(tx: ErgoLikeTransaction, - blockchainState: BlockchainState, - boxesReader: ErgoBoxReader, - inputIndex: Int): Try[ErgoLikeContext] = Try { - - val boxes = tx.inputs.map(_.boxId).map(id => boxesReader.byId(id).get) - - val proverExtension = tx.inputs(inputIndex).spendingProof.extension - - ErgoLikeContext(blockchainState.currentHeight, - blockchainState.lastBlockUtxoRoot, - dummyPubkey, - boxes, - tx, - boxes(inputIndex), - proverExtension) - } - - val noInputs: Array[Box] = Array[Box]() - val noOutputs: Array[Box] = Array[Box]() - - import special.sigma._ - - def contextVars(m: Map[Byte, AnyValue])(implicit IR: Evaluation): Coll[AnyValue] = { - val maxKey = if (m.keys.isEmpty) 0 else m.keys.max - val res = new Array[AnyValue](maxKey + 1) - for ((id, v) <- m) { - assert(res(id) == null, s"register $id is defined more then once") - res(id) = v - } - IR.sigmaDslBuilderValue.Colls.fromArray(res) - } - - implicit class ErgoBoxOps(val ebox: ErgoBox) extends AnyVal { - def toTestBox(isCost: Boolean): Box = { - new CostingBox(isCost, ebox) - } - } } /** When interpreted evaluates to a ByteArrayConstant built from Context.minerPubkey */ diff --git a/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala b/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala index 3b77da522e..9ca011b09a 100644 --- a/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala +++ b/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala @@ -5,17 +5,17 @@ import org.ergoplatform.ErgoBox.R4 import org.ergoplatform.mining.emission.EmissionRules import org.ergoplatform.settings.MonetarySettings import org.scalacheck.Gen -import scorex.crypto.hash.{Digest32, Blake2b256} +import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util.Random -import sigmastate.Values.{SigmaPropConstant, CollectionConstant, ByteArrayConstant, IntConstant, ErgoTree} +import sigmastate.Values.{ByteArrayConstant, CollectionConstant, ErgoTree, IntConstant, SigmaPropConstant} import sigmastate._ -import sigmastate.basics.DLogProtocol.{ProveDlog, DLogProverInput} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} -import sigmastate.interpreter.{ProverResult, ContextExtension} +import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.lang.Terms.ValueOps import sigmastate.serialization.ValueSerializer -import sigmastate.utxo.{CostTable, ExtractCreationInfo, ByIndex, SelectField} +import sigmastate.utxo.{ByIndex, CostTable, ExtractCreationInfo, SelectField} import scalan.util.BenchmarkUtil._ import ErgoScriptPredef._ @@ -48,7 +48,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(minerBox)) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = nextHeight, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = pk, @@ -106,10 +106,10 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { val newFoundersBox = ErgoBox(remainingAmount, newProp, 0, Seq(), Map(R4 -> outputR4Val)) val collectedBox = ErgoBox(inputBoxes.head.value - remainingAmount, TrueProp, 0) val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(newFoundersBox, collectedBox)) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = height, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction, self = inputBoxes.head) @@ -127,17 +127,17 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { val inputs = inputBoxes.map(b => Input(b.id, emptyProverResult)) val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(ErgoBox(inputBoxes.head.value, TrueProp, 0))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = inputBoxes.head.creationHeight + settings.minerRewardDelay, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction, self = inputBoxes.head) - val prevBlockCtx = ErgoLikeContext( + val prevBlockCtx = ErgoLikeContextTesting( currentHeight = inputBoxes.head.creationHeight + settings.minerRewardDelay - 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction, self = inputBoxes.head) @@ -216,10 +216,10 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { val amount = inputBoxes.map(_.value).sum val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(ErgoBox(amount, pubkey.toSigmaProp, 0))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction, self = inputBoxes.head).withCostLimit(CostTable.ScriptLimit * 10) @@ -293,7 +293,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(newEmissionBox, minerBox)) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = nextHeight, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = pkBytes, diff --git a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index d07acf79d0..290a97d919 100644 --- a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -3,25 +3,24 @@ package org.ergoplatform.dsl import sigmastate.interpreter.Interpreter.ScriptNameProp import scala.collection.mutable -import sigmastate.interpreter.{ProverResult, ContextExtension, CostedProverResult} +import sigmastate.interpreter.{ContextExtension, CostedProverResult, ProverResult} import scala.collection.mutable.ArrayBuffer import org.ergoplatform.ErgoBox.NonMandatoryRegisterId import org.ergoplatform.ErgoConstants.ScriptCostLimit -import org.ergoplatform.ErgoLikeContext.{dummyPreHeader, noHeaders} import scalan.Nullable import scorex.crypto.hash.Digest32 import scala.util.Try -import org.ergoplatform.{ErgoLikeContext, ErgoBox} -import org.ergoplatform.dsl.ContractSyntax.{Token, TokenId, ErgoScript, Proposition} +import org.ergoplatform.{ErgoBox, ErgoLikeContext} +import org.ergoplatform.dsl.ContractSyntax.{ErgoScript, Proposition, Token, TokenId} import org.ergoplatform.validation.ValidationRules import sigmastate.{AvlTreeData, SType} import sigmastate.Values.{ErgoTree, EvaluatedValue} -import sigmastate.eval.{IRContext, CSigmaProp, Evaluation} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.eval.{CSigmaProp, Evaluation, IRContext} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.lang.Terms.ValueOps -import special.sigma.{AnyValue, TestValue, SigmaProp} +import special.sigma.{AnyValue, SigmaProp, TestValue} case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRContext) extends ContractSpec { @@ -81,18 +80,14 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC val propSpec = utxoBox.propSpec val boxesToSpend = tx.inputs.map(_.utxoBox.ergoBox).toIndexedSeq val dataBoxes = tx.dataInputs.map(_.utxoBox.ergoBox).toIndexedSeq - val ctx = new ErgoLikeContext( + val ctx = ErgoLikeContextTesting( + currentHeight = tx.block.height, lastBlockUtxoRoot = AvlTreeData.dummy, - headers = noHeaders, - preHeader = dummyPreHeader(tx.block.height, ErgoLikeContext.dummyPubkey), + minerPubkey = ErgoLikeContextTesting.dummyPubkey, dataBoxes = dataBoxes, boxesToSpend = boxesToSpend, spendingTransaction = testSuite.createTransaction(dataBoxes, tx.outputs.map(_.ergoBox).toIndexedSeq), - selfIndex = boxesToSpend.indexOf(utxoBox.ergoBox), - extension = ContextExtension.empty, - validationSettings = ValidationRules.currentSettings, - costLimit = ScriptCostLimit.value, - initCost = 0L) + selfIndex = boxesToSpend.indexOf(utxoBox.ergoBox) ) ctx } def runDsl(extensions: Map[Byte, AnyValue] = Map()): SigmaProp = { diff --git a/src/test/scala/sigmastate/CalcSha256Specification.scala b/src/test/scala/sigmastate/CalcSha256Specification.scala index 39f1fea9ef..ee120a71fd 100644 --- a/src/test/scala/sigmastate/CalcSha256Specification.scala +++ b/src/test/scala/sigmastate/CalcSha256Specification.scala @@ -3,8 +3,8 @@ package sigmastate import org.ergoplatform.ErgoLikeContext import org.scalatest.prop.TableFor2 import scorex.util.encode.Base16 -import sigmastate.Values.{CollectionConstant, ByteArrayConstant} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.Values.{ByteArrayConstant, CollectionConstant} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons} class CalcSha256Specification extends SigmaTestingCommons { implicit lazy val IR = new TestingIRContext @@ -30,7 +30,7 @@ class CalcSha256Specification extends SigmaTestingCommons { property("CalcSha256: Should pass standard tests.") { val int = new ContextEnrichingTestProvingInterpreter() - val ctx = ErgoLikeContext.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf) forAll(objects) { (in, result) => val expectedResult = decodeString(result) val calcSha256 = EQ(CalcSha256(stringToByteConstant(in)), expectedResult) diff --git a/src/test/scala/sigmastate/FailingToProveSpec.scala b/src/test/scala/sigmastate/FailingToProveSpec.scala index 2dc1ecfb6d..475e52f020 100644 --- a/src/test/scala/sigmastate/FailingToProveSpec.scala +++ b/src/test/scala/sigmastate/FailingToProveSpec.scala @@ -1,7 +1,7 @@ package sigmastate import org.ergoplatform.{ErgoBox, ErgoLikeContext, ErgoLikeInterpreter, ErgoLikeTransaction} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.lang.Terms._ import org.scalatest.TryValues._ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} @@ -36,13 +36,13 @@ class FailingToProveSpec extends SigmaTestingCommons { val o1 = ErgoBox(101L, TrueProp, 5001) val o2 = ErgoBox(99L, TrueProp, 5001) val tx = createTransaction(IndexedSeq(o1, o2)) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 5001, lastBlockUtxoRoot = AvlTreeData.dummy, boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx, self = selfBox, - minerPubkey = ErgoLikeContext.dummyPubkey) + minerPubkey = ErgoLikeContextTesting.dummyPubkey) val proof = interpreter.prove(emptyEnv + (ScriptNameProp -> "prove"), compiledScript, ctx, fakeMessage).success.value.proof verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), compiledScript, ctx, proof, fakeMessage) should be a 'success } @@ -70,13 +70,13 @@ class FailingToProveSpec extends SigmaTestingCommons { val o2 = ErgoBox(98L, TrueProp, 5001) val o3 = ErgoBox(100L, TrueProp, 5001) val tx = createTransaction(IndexedSeq(o1, o2, o3)) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 5001, lastBlockUtxoRoot = AvlTreeData.dummy, boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx, self = selfBox, - minerPubkey = ErgoLikeContext.dummyPubkey) + minerPubkey = ErgoLikeContextTesting.dummyPubkey) val proof = interpreter.prove(emptyEnv + (ScriptNameProp -> "prove"), compiledScript, ctx, fakeMessage).success.value.proof verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), compiledScript, ctx, proof, fakeMessage) should be a 'success } diff --git a/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index e857645e46..7aab722500 100644 --- a/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -7,7 +7,7 @@ import sigmastate.SPrimType.MaxPrimTypeCode import sigmastate.Values.ErgoTree.EmptyConstants import sigmastate.Values.{ByteArrayConstant, ErgoTree, IntConstant, NotReadyValueInt, Tuple, UnparsedErgoTree, ValueCompanion} import sigmastate.eval.Colls -import sigmastate.helpers.{ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter} +import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter} import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.lang.Terms._ @@ -38,8 +38,8 @@ class SoftForkabilitySpecification extends SigmaTestingData { val blockHeight = 110 def createContext(h: Int, tx: ErgoLikeTransaction, vs: SigmaValidationSettings) = - ErgoLikeContext(h, - AvlTreeData.dummy, ErgoLikeContext.dummyPubkey, IndexedSeq(fakeSelf), + ErgoLikeContextTesting(h, + AvlTreeData.dummy, ErgoLikeContextTesting.dummyPubkey, IndexedSeq(fakeSelf), tx, fakeSelf, vs = vs) def proveTx(name: String, tx: ErgoLikeTransaction, vs: SigmaValidationSettings): ProverResult = { diff --git a/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index bc9354dc10..046ebc1de9 100644 --- a/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -1,6 +1,6 @@ package sigmastate -import sigmastate.basics.DLogProtocol.{ProveDlog, DLogProverInput} +import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog} import scorex.crypto.hash.Blake2b256 import sigmastate.Values._ import sigmastate.interpreter._ @@ -9,7 +9,7 @@ import Interpreter._ import sigmastate.lang.Terms._ import org.ergoplatform._ import scorex.util.encode.Base58 -import sigmastate.helpers.{ErgoLikeTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} import sigmastate.serialization.ValueSerializer import TrivialProp._ @@ -23,8 +23,8 @@ class TestingInterpreterSpecification extends SigmaTestingCommons { implicit val soundness = CryptoConstants.soundnessBits def testingContext(h: Int) = - ErgoLikeContext(h, - AvlTreeData.dummy, ErgoLikeContext.dummyPubkey, IndexedSeq(fakeSelf), + ErgoLikeContextTesting(h, + AvlTreeData.dummy, ErgoLikeContextTesting.dummyPubkey, IndexedSeq(fakeSelf), ErgoLikeTransaction(IndexedSeq.empty, IndexedSeq.empty), fakeSelf) diff --git a/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala b/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala index 2c7f7d10d5..46c200903f 100644 --- a/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala +++ b/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala @@ -11,6 +11,7 @@ import sigmastate.utxo.CostTable import scalan.BaseCtxTests import sigmastate.lang.{LangTests, SigmaCompiler} import sigmastate.helpers.ContextEnrichingTestProvingInterpreter +import sigmastate.helpers.ErgoLikeContextTesting import sigmastate.interpreter.ContextExtension import sigmastate.interpreter.Interpreter.ScriptEnv import sigmastate.serialization.ErgoTreeSerializer @@ -37,10 +38,10 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests def newErgoContext(height: Int, boxToSpend: ErgoBox, extension: Map[Byte, EvaluatedValue[SType]] = Map()): ErgoLikeContext = { val tx1 = new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(), IndexedSeq(boxToSpend)) - val ergoCtx = ErgoLikeContext( + val ergoCtx = ErgoLikeContextTesting( currentHeight = height, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(boxToSpend), spendingTransaction = tx1, self = boxToSpend, @@ -78,10 +79,10 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests lazy val tx1Output1 = ErgoBox(minToRaise, projectPubKey, 0) lazy val tx1Output2 = ErgoBox(1, projectPubKey, 0) lazy val tx1 = new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(), IndexedSeq(tx1Output1, tx1Output2)) - lazy val ergoCtx = ErgoLikeContext( + lazy val ergoCtx = ErgoLikeContextTesting( currentHeight = timeout - 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(boxToSpend), spendingTransaction = tx1, self = boxToSpend, diff --git a/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala b/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala new file mode 100644 index 0000000000..2e5537ea4d --- /dev/null +++ b/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala @@ -0,0 +1,87 @@ +package sigmastate.helpers + +import org.ergoplatform.ErgoConstants.ScriptCostLimit +import org.ergoplatform.ErgoLikeContext.Height +import org.ergoplatform.{ErgoBox, ErgoBoxReader, ErgoLikeContext, ErgoLikeTransaction, ErgoLikeTransactionTemplate, UnsignedInput} +import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} +import sigmastate.AvlTreeData +import sigmastate.eval._ +import sigmastate.interpreter.{ContextExtension, CryptoConstants} +import sigmastate.serialization.{GroupElementSerializer, SigmaSerializer} +import special.collection.Coll +import special.sigma.{Box, Header, PreHeader} + +import scala.util.Try + +object ErgoLikeContextTesting { + /* NO HF PROOF: + Changed: val dummyPubkey from `Array[Byte] = Array.fill(32)(0: Byte)` to `GroupElementSerializer.toBytes(CryptoConstants.dlogGroup.generator)` + Motivation: to avoid exception on deserialization(wrong size, needs to be 33 bytes) and later in GroupElement.toString (infinity was not handled) and to provide more practical value in tests. + Safety: + Used only in tests and not used in ergo. + Examined ergo code: all (with IDE's "find usages" action). +*/ + val dummyPubkey: Array[Byte] = GroupElementSerializer.toBytes(CryptoConstants.dlogGroup.generator) + + val noBoxes: IndexedSeq[ErgoBox] = IndexedSeq.empty[ErgoBox] + val noHeaders: Coll[Header] = CostingSigmaDslBuilder.Colls.emptyColl[Header] + + private def dummyPreHeader(currentHeight: Height, minerPk: Array[Byte]): PreHeader = CPreHeader(0, + parentId = Colls.emptyColl[Byte], + timestamp = 3, + nBits = 0, + height = currentHeight, + minerPk = GroupElementSerializer.parse(SigmaSerializer.startReader(minerPk)), + votes = Colls.emptyColl[Byte] + ) + + def apply(currentHeight: Height, + lastBlockUtxoRoot: AvlTreeData, + minerPubkey: Array[Byte], + boxesToSpend: IndexedSeq[ErgoBox], + spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], + self: ErgoBox, + extension: ContextExtension = ContextExtension.empty, + vs: SigmaValidationSettings = ValidationRules.currentSettings) = + new ErgoLikeContext(lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), noBoxes, + boxesToSpend, spendingTransaction, boxesToSpend.indexOf(self), extension, vs, ScriptCostLimit.value, 0L) + + def apply(currentHeight: Height, + lastBlockUtxoRoot: AvlTreeData, + minerPubkey: Array[Byte], + dataBoxes: IndexedSeq[ErgoBox], + boxesToSpend: IndexedSeq[ErgoBox], + spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], + selfIndex: Int) = + new ErgoLikeContext(lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, ContextExtension.empty, ValidationRules.currentSettings, ScriptCostLimit.value, 0L) + + + def dummy(selfDesc: ErgoBox) = ErgoLikeContextTesting(currentHeight = 0, + lastBlockUtxoRoot = AvlTreeData.dummy, dummyPubkey, boxesToSpend = IndexedSeq(selfDesc), + spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), self = selfDesc) + + def fromTransaction(tx: ErgoLikeTransaction, + blockchainState: BlockchainState, + boxesReader: ErgoBoxReader, + inputIndex: Int): Try[ErgoLikeContext] = Try { + + val boxes = tx.inputs.map(_.boxId).map(id => boxesReader.byId(id).get) + + val proverExtension = tx.inputs(inputIndex).spendingProof.extension + + ErgoLikeContextTesting(blockchainState.currentHeight, + blockchainState.lastBlockUtxoRoot, + dummyPubkey, + boxes, + tx, + boxes(inputIndex), + proverExtension) + } + + val noInputs: Array[Box] = Array[Box]() + val noOutputs: Array[Box] = Array[Box]() +} + +case class BlockchainState(currentHeight: Height, lastBlockUtxoRoot: AvlTreeData) + diff --git a/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala b/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala index 6f3782b8d6..1d1717ff6b 100644 --- a/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala +++ b/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala @@ -36,7 +36,7 @@ class ErgoTransactionValidator(implicit IR: IRContext) { val proverExtension = tx.inputs(idx).spendingProof.extension val context = - ErgoLikeContext(blockchainState.currentHeight, blockchainState.lastBlockUtxoRoot, minerPubkey, boxes, + ErgoLikeContextTesting(blockchainState.currentHeight, blockchainState.lastBlockUtxoRoot, minerPubkey, boxes, tx, box, proverExtension) val verificationResult = verifier.verify( emptyEnv + (ScriptNameProp -> s"height_${blockchainState.currentHeight }_verify"), diff --git a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala b/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala index 1f923d879b..263c02fc3f 100644 --- a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala +++ b/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala @@ -2,29 +2,34 @@ package sigmastate.helpers import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix import org.ergoplatform.ErgoBox.NonMandatoryRegisterId +import org.ergoplatform.ErgoConstants.ScriptCostLimit +import org.ergoplatform.ErgoLikeContext.Height import org.ergoplatform.ErgoScriptPredef.TrueProp import org.ergoplatform._ -import org.ergoplatform.validation.ValidationSpecification +import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules, ValidationSpecification} import org.scalacheck.Arbitrary.arbByte import org.scalacheck.Gen -import org.scalatest.prop.{PropertyChecks, GeneratorDrivenPropertyChecks} -import org.scalatest.{PropSpec, Assertion, Matchers} -import scalan.{TestUtils, TestContexts, RType} -import scorex.crypto.hash.{Digest32, Blake2b256} +import org.scalatest.prop.{GeneratorDrivenPropertyChecks, PropertyChecks} +import org.scalatest.{Assertion, Matchers, PropSpec} +import scalan.{RType, TestContexts, TestUtils} +import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util.serialization.{VLQByteStringReader, VLQByteStringWriter} import sigma.types.IsPrimView -import sigmastate.Values.{Constant, EvaluatedValue, SValue, Value, ErgoTree, GroupElementConstant} -import sigmastate.interpreter.Interpreter.{ScriptNameProp, ScriptEnv} -import sigmastate.interpreter.{CryptoConstants, Interpreter} -import sigmastate.lang.{TransformingSigmaBuilder, SigmaCompiler} -import sigmastate.serialization.{ValueSerializer, SigmaSerializer} -import sigmastate.{SGroupElement, SType} -import sigmastate.eval.{CompiletimeCosting, IRContext, Evaluation, _} +import sigmastate.Values.{Constant, ErgoTree, EvaluatedValue, GroupElementConstant, SValue, Value} +import sigmastate.interpreter.Interpreter.{ScriptEnv, ScriptNameProp} +import sigmastate.interpreter.{ContextExtension, CryptoConstants, Interpreter} +import sigmastate.lang.{SigmaCompiler, TransformingSigmaBuilder} +import sigmastate.serialization.{GroupElementSerializer, SigmaSerializer, ValueSerializer} +import sigmastate.{AvlTreeData, SGroupElement, SType} +import sigmastate.eval.{CompiletimeCosting, Evaluation, IRContext, _} import sigmastate.interpreter.CryptoConstants.EcPointType +import special.collection.Coll import special.sigma +import special.sigma.{Box, Header, PreHeader} import scala.annotation.tailrec import scala.language.implicitConversions +import scala.util.Try trait SigmaTestingCommons extends PropSpec with PropertyChecks @@ -33,7 +38,7 @@ trait SigmaTestingCommons extends PropSpec val fakeSelf: ErgoBox = createBox(0, TrueProp) - val fakeContext: ErgoLikeContext = ErgoLikeContext.dummy(fakeSelf) + val fakeContext: ErgoLikeContext = ErgoLikeContextTesting.dummy(fakeSelf) //fake message, in a real-life a message is to be derived from a spending transaction val fakeMessage = Blake2b256("Hello World") @@ -159,7 +164,7 @@ trait SigmaTestingCommons extends PropSpec implicit val cA = tA.classTag val x = fromPrimView(in) val context = - ErgoLikeContext.dummy(createBox(0, TrueProp)) + ErgoLikeContextTesting.dummy(createBox(0, TrueProp)) .withBindings(1.toByte -> Constant[SType](x.asInstanceOf[SType#WrappedType], tpeA)).withBindings(bindings: _*) val calcCtx = context.toSigmaContext(IR, isCost = false) val (res, _) = valueFun(calcCtx) diff --git a/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/src/test/scala/sigmastate/serialization/DeserializationResilience.scala index 9a96af0403..4ba603dfc7 100644 --- a/src/test/scala/sigmastate/serialization/DeserializationResilience.scala +++ b/src/test/scala/sigmastate/serialization/DeserializationResilience.scala @@ -11,7 +11,7 @@ import sigmastate.Values.{BlockValue, ErgoTree, GetVarInt, IntConstant, SValue, import sigmastate._ import sigmastate.eval.Extensions._ import sigmastate.eval._ -import sigmastate.helpers.{ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.interpreter.{ContextExtension, CostedProverResult, CryptoConstants} import sigmastate.lang.Terms._ @@ -263,7 +263,7 @@ class DeserializationResilience extends SerializationSpecification with SigmaTes assertExceptionThrown({ val verifier = new ErgoLikeTestInterpreter val pr = CostedProverResult(Array[Byte](), ContextExtension(Map()), 0L) - val ctx = ErgoLikeContext.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf) val (res, calcTime) = BenchmarkUtil.measureTime { verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), ErgoTree(ErgoTree.DefaultHeader, IndexedSeq(), recursiveScript), ctx, pr, fakeMessage) diff --git a/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala b/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala index 26dcc3edae..5586730f9e 100644 --- a/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala +++ b/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala @@ -9,7 +9,7 @@ import sigmastate.Values.{SigmaBoolean, SigmaPropConstant, SigmaPropValue, Value import sigmastate._ import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.ProveDHTuple -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons} import sigmastate.serialization.generators.ObjectGenerators import sigmastate.utxo.Transformer @@ -72,10 +72,10 @@ class SigSerializerSpecification extends SigmaTestingCommons with ObjectGenerato val expr = sb.toSigmaProp val challenge = Array.fill(32)(Random.nextInt(100).toByte) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) diff --git a/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala index f70f972259..eefa1df334 100644 --- a/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala +++ b/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala @@ -3,21 +3,21 @@ package sigmastate.utxo import com.google.common.primitives.Longs import org.ergoplatform.ErgoScriptPredef.TrueProp import org.ergoplatform._ -import org.ergoplatform.dsl.{SigmaContractSyntax, ContractSpec, TestContractSpec} +import org.ergoplatform.dsl.{ContractSpec, SigmaContractSyntax, TestContractSpec} import scorex.crypto.authds.avltree.batch._ import scorex.crypto.authds.{ADKey, ADValue} import scorex.crypto.hash.{Blake2b256, Digest32} import sigmastate.SCollection.SByteArray import sigmastate.Values._ import sigmastate._ -import sigmastate.eval.{IRContext, CSigmaProp} +import sigmastate.eval.{CSigmaProp, IRContext} import sigmastate.eval._ import sigmastate.eval.Extensions._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ import special.collection.Coll -import special.sigma.{Context, AvlTree} +import special.sigma.{AvlTree, Context} class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => @@ -217,10 +217,10 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(SigmaDsl.avlTree(treeData)))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, self = s) @@ -251,10 +251,10 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => val recipientProposition = new ContextEnrichingTestProvingInterpreter().dlogSecrets.head.publicImage val selfBox = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(SigmaDsl.avlTree(treeData)))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), createTransaction(ErgoBox(1, recipientProposition, 0)), self = selfBox) @@ -321,10 +321,10 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(treeData), reg2 -> ByteArrayConstant(key))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, self = s) val pr = prover.prove(prop, ctx, fakeMessage).get @@ -373,10 +373,10 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(treeData))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, self = s) val pr = prover.prove(env + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).get diff --git a/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 78e5ba71a7..4a4da55565 100644 --- a/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -1,15 +1,15 @@ package sigmastate.utxo import java.math.BigInteger + import org.ergoplatform.ErgoBox.{R6, R8} -import org.ergoplatform.ErgoLikeContext.dummyPubkey import org.ergoplatform._ import scalan.RType import sigmastate.SCollection.SByteArray import sigmastate.Values._ import sigmastate._ import sigmastate.eval.Extensions._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ import special.sigma.InvalidType @@ -77,8 +77,8 @@ class BasicOpsSpecification extends SigmaTestingCommons { reg2 -> IntConstant(10))) val tx = createTransaction(newBox1) - val ctx = ErgoLikeContext(currentHeight = 0, - lastBlockUtxoRoot = AvlTreeData.dummy, dummyPubkey, boxesToSpend = IndexedSeq(boxToSpend), + val ctx = ErgoLikeContextTesting(currentHeight = 0, + lastBlockUtxoRoot = AvlTreeData.dummy, ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(boxToSpend), spendingTransaction = tx, self = boxToSpend) val pr = prover.prove(env + (ScriptNameProp -> s"${name}_prove"), prop, ctx, fakeMessage).fold(t => throw t, identity) diff --git a/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala b/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala index 6da37d6189..71f0a06e52 100644 --- a/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala +++ b/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala @@ -11,7 +11,7 @@ import scorex.crypto.authds.{ADDigest, ADKey, ADValue} import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util._ import sigmastate.Values.{IntConstant, LongConstant} -import sigmastate.helpers.{ErgoLikeTestProvingInterpreter, ErgoTransactionValidator, SigmaTestingCommons} +import sigmastate.helpers.{BlockchainState, ErgoLikeContextTesting, ErgoLikeTestProvingInterpreter, ErgoTransactionValidator, SigmaTestingCommons} import sigmastate.interpreter.ContextExtension import sigmastate.eval._ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} @@ -36,9 +36,9 @@ class BlockchainSimulationSpecification extends SigmaTestingCommons { new ErgoBoxCandidate(10, minerPubKey, height, Colls.emptyColl[(TokenId, Long)], Map(heightReg -> IntConstant(height + windowSize))) val unsignedInput = new UnsignedInput(box.id) val tx = UnsignedErgoLikeTransaction(IndexedSeq(unsignedInput), IndexedSeq(newBoxCandidate)) - val context = ErgoLikeContext(height + 1, + val context = ErgoLikeContextTesting(height + 1, state.state.lastBlockUtxoRoot, - ErgoLikeContext.dummyPubkey, + ErgoLikeContextTesting.dummyPubkey, IndexedSeq(box), tx, box, @@ -215,7 +215,7 @@ object BlockchainSimulationSpecification { val boxes = (1 to 30).map(_ => ErgoBox(10, GE(Height, IntConstant(i)).toSigmaProp, 0, Seq(), Map(heightReg -> IntConstant(i)), txId)) ergoplatform.ErgoLikeTransaction(IndexedSeq(), boxes) }, - ErgoLikeContext.dummyPubkey + ErgoLikeContextTesting.dummyPubkey ) def initialState(block: Block = initBlock)(implicit IR: IRContext): ValidationState = { diff --git a/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala b/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala index 7b6c266ac6..2b419441b3 100644 --- a/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala +++ b/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala @@ -4,7 +4,7 @@ import org.ergoplatform import org.ergoplatform.ErgoScriptPredef.TrueProp import sigmastate.Values._ import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.lang.Terms._ import org.ergoplatform._ import sigmastate.SCollection._ @@ -19,10 +19,10 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { outputs: IndexedSeq[ErgoBox]): ErgoLikeContext = { val (selfBox, toSpend) = if (boxesToSpend.isEmpty) (fakeSelf, IndexedSeq(fakeSelf)) else (boxesToSpend(0), boxesToSpend) - ergoplatform.ErgoLikeContext( + ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = toSpend, spendingTransaction = createTransaction(outputs), self = selfBox) @@ -97,10 +97,10 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { val spendingTransaction = createTransaction(newBoxes) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, self = fakeSelf) @@ -129,10 +129,10 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { val spendingTransaction = createTransaction(newBoxes) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, self = fakeSelf) @@ -159,10 +159,10 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { val spendingTransaction = createTransaction(newBoxes) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, self = fakeSelf) @@ -199,10 +199,10 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> LongConstant(5))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, self = s) @@ -242,10 +242,10 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> LongConstant(5))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, self = s) @@ -273,10 +273,10 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { val s = ErgoBox(21, pubkey, 0) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, self = s) diff --git a/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala b/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala index 3993391914..ec1bb36d2e 100644 --- a/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala @@ -5,7 +5,7 @@ import org.scalacheck.Gen import sigmastate.Values.IntConstant import sigmastate._ import sigmastate.lang.Terms._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import scala.util.Random @@ -36,10 +36,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(pubkeyA, pubkeyB) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -69,10 +69,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(pubkeyA, pubkeyB, pubkeyC) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -103,10 +103,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(SigmaOr(pubkeyA, pubkeyB), pubkeyC) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -138,10 +138,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(pubkeyA1, pubkeyA2, pubkeyA3, pubkeyA4) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -169,10 +169,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(SigmaAnd(pubkeyA, pubkeyB), SigmaAnd(pubkeyC, pubkeyD)) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -210,10 +210,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(SigmaAnd(pubkeyA, pubkeyB), SigmaOr(pubkeyC, pubkeyD)) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -247,10 +247,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaAnd(pubkeyA, pubkeyB) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -280,10 +280,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(SigmaAnd(pubkeyA, pubkeyB), pubkeyC) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -320,10 +320,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaAnd(SigmaOr(pubkeyA, pubkeyB), SigmaOr(pubkeyC, pubkeyD)) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -361,10 +361,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaAnd(SigmaAnd(pubkeyA, pubkeyB), SigmaOr(pubkeyC, pubkeyD)) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -405,10 +405,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(SigmaOr(pubkeyA, pubkeyB), SigmaOr(pubkeyC, pubkeyD)) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -443,10 +443,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(GT(Height, IntConstant(500)).toSigmaProp, SigmaOr(pubkeyA, pubkeyB)) compiledProp shouldBe prop - val ctx1 = ErgoLikeContext( + val ctx1 = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -456,10 +456,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { verifier.verify(compiledProp, ctx1, prB, fakeMessage).get._1 shouldBe true proverC.prove(compiledProp, ctx1, fakeMessage).isFailure shouldBe true - val ctx2 = ErgoLikeContext( + val ctx2 = ErgoLikeContextTesting( currentHeight = 501, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -485,10 +485,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(SigmaOr(pubkeyA, pubkeyB), SigmaAnd(pubkeyC, GT(Height, IntConstant(500)).toSigmaProp)) compiledProp shouldBe prop - val ctx1 = ErgoLikeContext( + val ctx1 = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -500,10 +500,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { proverC.prove(compiledProp, ctx1, fakeMessage).isFailure shouldBe true - val ctx2 = ErgoLikeContext( + val ctx2 = ErgoLikeContextTesting( currentHeight = 501, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -533,10 +533,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { val prop = SigmaOr(SigmaOr(pubkeyA, pubkeyB), SigmaAnd(pubkeyC, GT(Height, IntConstant(500)).toSigmaProp)) compiledProp shouldBe prop - val ctx1 = ErgoLikeContext( + val ctx1 = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -548,10 +548,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { proverC.prove(compiledProp, ctx1, fakeMessage).isFailure shouldBe true - val ctx2 = ErgoLikeContext( + val ctx2 = ErgoLikeContextTesting( currentHeight = 501, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -583,10 +583,10 @@ class ComplexSigSpecification extends SigmaTestingCommons { kNumKeysCombinations.map(combs => CAND(combs.map(_.publicImage))) ) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) diff --git a/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala b/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala index 4143faac81..a719c43ade 100644 --- a/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala @@ -6,7 +6,7 @@ import scorex.crypto.hash.Blake2b256 import sigmastate.Values._ import sigmastate._ import sigmastate.lang.Terms._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import special.collection.Coll @@ -31,7 +31,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { ) compiledScript shouldBe prop - val ctx = ErgoLikeContext.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf) val pr = prover.prove(compiledScript, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) @@ -63,7 +63,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { ) compiledScript shouldBe prop - val ctx = ErgoLikeContext.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf) val pr = prover.prove(compiledScript, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) @@ -93,7 +93,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { val prop = EQ(Xor(GetVarByteArray(k1).get, GetVarByteArray(k2).get), ByteArrayConstant(r)).toSigmaProp compiledScript shouldBe prop - val ctx = ErgoLikeContext.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf) val pr = prover.prove(prop, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) @@ -124,7 +124,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { val prop = EQ(CalcBlake2b256(GetVarByteArray(1).get), ByteArrayConstant(Blake2b256(preimage.toArray))).toSigmaProp compiledScript shouldBe prop - val ctx = ErgoLikeContext.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf) val pr = prover.prove(prop, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) @@ -152,7 +152,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { ByteArrayConstant(Blake2b256(preimage2.append(preimage1).toArray))).toSigmaProp compiledScript shouldBe prop - val ctx = ErgoLikeContext.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf) val pr = prover.prove(prop, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) diff --git a/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala index 4b6b75adca..a047fe56a9 100644 --- a/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala @@ -14,10 +14,10 @@ import sigmastate.eval._ import sigmastate.interpreter.Interpreter._ import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.ProveDHTuple -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.InterpreterException -import sigmastate.serialization.{ValueSerializer, SerializationSpecification} +import sigmastate.serialization.{SerializationSpecification, ValueSerializer} class ErgoLikeInterpreterSpecification extends SigmaTestingCommons with SerializationSpecification { @@ -34,7 +34,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val h1 = SigmaPropConstant(prover1.dlogSecrets.head.publicImage) val h2 = SigmaPropConstant(prover2.dlogSecrets.head.publicImage) - val ctx = ErgoLikeContext.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf) val e = compile(Map("h1" -> h1.treeWithSegregation.bytes, "h2" -> h2.treeWithSegregation.bytes), "h1 == h1") val exp = TrueLeaf @@ -69,10 +69,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons compiledProp2 shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -99,10 +99,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val prop = SigmaOr(pubkeyA, pubdhB) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -126,10 +126,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val prop = SigmaAnd(pubkeyA, pubdhA) compiledProp shouldBe prop - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -181,10 +181,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons compiledProp } - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = height, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, self = fakeSelf) @@ -244,10 +244,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val spendingTransaction = createTransaction(newBoxes) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, self = fakeSelf) @@ -274,10 +274,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val spendingTransaction = createTransaction(newBoxes) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, self = fakeSelf) @@ -310,10 +310,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val recipientProposition = SigmaPropConstant(new ContextEnrichingTestProvingInterpreter().dlogSecrets.head.publicImage) val selfBox = ErgoBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map()) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), createTransaction(ErgoBox(1, recipientProposition, 0)), self = selfBox) @@ -354,10 +354,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons Map(regPubkey1 -> GroupElementConstant(pubkey1.value), regPubkey2 -> GroupElementConstant(pubkey2.value))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s1), spendingTransaction, self = s1) @@ -369,10 +369,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons //make sure that wrong case couldn't be proved val s2 = ErgoBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map(regPubkey1 -> GroupElementConstant(pubkey1.value))) - val wrongCtx = ErgoLikeContext( + val wrongCtx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s2), spendingTransaction, self = s2) @@ -404,10 +404,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val recipientProposition = new ContextEnrichingTestProvingInterpreter().dlogSecrets.head.publicImage val selfBox = ErgoBox(20, TrueProp, 0, Seq(), Map()) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), createTransaction(ErgoBox(1, recipientProposition, 0)), self = selfBox) @@ -457,10 +457,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val s = ErgoBox(10, prop, 0, Seq(), Map()) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(brother, s), spendingTransaction, self = s) @@ -468,10 +468,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove_prop"), prop, ctx, fakeMessage).fold(t => throw t, x => x) verifier.verify(emptyEnv + (ScriptNameProp -> "verify_prop"), prop, ctx, pr, fakeMessage).fold(t => throw t, x => x)._1 shouldBe true - val wrongCtx = ErgoLikeContext( + val wrongCtx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(brotherWithWrongId, s), spendingTransaction, self = s) @@ -537,10 +537,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val s = ErgoBox(10, prop, 0, Seq(), Map()) - val ctx1 = ErgoLikeContext( + val ctx1 = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(friend, s), spendingTransaction, self = s) @@ -548,10 +548,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val pr1 = prover.prove(prop, ctx1, fakeMessage).success.value verifier.verify(prop, ctx1, pr1, fakeMessage).success.value._1 shouldBe true - val ctx2 = ErgoLikeContext( + val ctx2 = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s, friend), spendingTransaction, self = s) @@ -562,10 +562,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val pr3 = prover.prove(prop, ctx2, fakeMessage).success.value verifier.verify(prop, ctx2, pr3, fakeMessage).success.value._1 shouldBe true - val wrongCtx1 = ErgoLikeContext( + val wrongCtx1 = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(friendWithWrongId, s), spendingTransaction, self = s) @@ -612,10 +612,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val spendingTransaction = createTransaction(output) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(input0, input1, input2, input3), spendingTransaction, self = input3) @@ -637,10 +637,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons // expect SBoolean in the register val prop = DeserializeRegister(R4, SBoolean).toSigmaProp - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(box), createTransaction(IndexedSeq(ErgoBox(10, TrueProp, 0))), self = box) @@ -662,10 +662,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons ).toSigmaProp val box = ErgoBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map()) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(box), createTransaction(IndexedSeq(ErgoBox(10, TrueProp, 0))), self = box) diff --git a/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala b/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala index ebcf49a52a..cc10e30d81 100644 --- a/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala @@ -4,7 +4,7 @@ import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction} import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog} import sigmastate.Values.{ConcreteCollection, FalseLeaf, IntConstant, SigmaPropConstant, SigmaPropValue, TrueLeaf} import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.CosterException @@ -34,10 +34,10 @@ class ThresholdSpecification extends SigmaTestingCommons { val proverAC = proverA.withSecrets(Seq(skC)) val proverBC = proverB.withSecrets(Seq(skC)) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -113,10 +113,10 @@ class ThresholdSpecification extends SigmaTestingCommons { property("threshold reduce to crypto") { import TrivialProp._ val prover = new ContextEnrichingTestProvingInterpreter - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -283,10 +283,10 @@ class ThresholdSpecification extends SigmaTestingCommons { val goodProvers = Seq(goodProver1, goodProver2, goodProver3, goodProver4) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -330,10 +330,10 @@ class ThresholdSpecification extends SigmaTestingCommons { for (i <- secrets.indices) { provers = provers ++ provers.map(p => (p._1 + 1, p._2.withSecrets(secrets(i)))) } - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) diff --git a/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala b/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala index bc2bf4dd57..c24a80983a 100644 --- a/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala +++ b/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala @@ -1,10 +1,10 @@ package sigmastate.utxo.benchmarks -import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction, ErgoBox, ErgoScriptPredef} +import org.ergoplatform.{ErgoBox, ErgoLikeContext, ErgoLikeTransaction, ErgoScriptPredef} import sigmastate.Values._ import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons} import scalan.util.BenchmarkUtil._ class CrowdfundingBenchmark extends SigmaTestingCommons { @@ -16,10 +16,10 @@ class CrowdfundingBenchmark extends SigmaTestingCommons { val tx1Output2 = ErgoBox(1, contract.projectPubKey, 0) //normally this transaction would invalid, but we're not checking it in this test val tx = createTransaction(IndexedSeq(tx1Output1, tx1Output2)) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = contract.timeout - 1, // HEIGHT < timeout, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(), spendingTransaction = tx, self = outputToSpend) diff --git a/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala b/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala index 676cfb8f3f..769781e081 100644 --- a/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala +++ b/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala @@ -3,19 +3,19 @@ package sigmastate.utxo.blockchain import org.ergoplatform.ErgoBox.TokenId import org.ergoplatform._ import scorex.crypto.authds.{ADDigest, ADKey, ADValue} -import scorex.crypto.authds.avltree.batch.{Remove, BatchAVLProver, Insert} -import scorex.crypto.hash.{Digest32, Blake2b256} -import sigmastate.{GE, AvlTreeData, AvlTreeFlags, Values} -import sigmastate.Values.{LongConstant, ErgoTree} +import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Remove} +import scorex.crypto.hash.{Blake2b256, Digest32} +import sigmastate.{AvlTreeData, AvlTreeFlags, GE, Values} +import sigmastate.Values.{ErgoTree, LongConstant} import sigmastate.eval._ -import sigmastate.helpers.{ErgoLikeTestProvingInterpreter, SigmaTestingCommons, ErgoTransactionValidator} +import sigmastate.helpers.{BlockchainState, ErgoLikeContextTesting, ErgoLikeTestProvingInterpreter, ErgoTransactionValidator, SigmaTestingCommons} import scala.collection.mutable import scala.util.{Random, Try} import scorex.util._ import sigmastate.interpreter.ContextExtension import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} -import sigmastate.utxo.blockchain.BlockchainSimulationTestingCommons.{ValidationState, FullBlock} +import sigmastate.utxo.blockchain.BlockchainSimulationTestingCommons.{FullBlock, ValidationState} import scala.annotation.tailrec @@ -51,7 +51,7 @@ trait BlockchainSimulationTestingCommons extends SigmaTestingCommons { new ErgoBoxCandidate(10, prop, height, Colls.emptyColl[(TokenId, Long)], Map()) val unsignedInput = new UnsignedInput(box.id) val tx = UnsignedErgoLikeTransaction(IndexedSeq(unsignedInput), IndexedSeq(newBoxCandidate)) - val context = ErgoLikeContext(height + 1, + val context = ErgoLikeContextTesting(height + 1, state.state.lastBlockUtxoRoot, minerPubkey, IndexedSeq(box), @@ -150,7 +150,7 @@ object BlockchainSimulationTestingCommons extends SigmaTestingCommons { val boxes = (1 to 50).map(_ => ErgoBox(10, Values.TrueLeaf.toSigmaProp, i, Seq(), Map(), txId)) createTransaction(boxes) }, - ErgoLikeContext.dummyPubkey + ErgoLikeContextTesting.dummyPubkey ) def initialState(block: FullBlock = initBlock)(implicit IR: IRContext): ValidationState = { diff --git a/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala index 74e9319ede..3c002f63c6 100644 --- a/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala @@ -6,7 +6,7 @@ import scorex.utils.Random import sigmastate.Values._ import sigmastate._ import interpreter.Interpreter._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.lang.Terms._ import sigmastate.utxo.SizeOf @@ -97,10 +97,10 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { //Preliminary checks: //B can't spend coins of A in chain1 (generate a valid proof) - val ctxf1 = ErgoLikeContext( + val ctxf1 = ErgoLikeContextTesting( currentHeight = height1 + 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -110,20 +110,20 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { proverA.prove(env, prop1, ctxf1, fakeMessage).isSuccess shouldBe false //B cant't withdraw his coins in chain2 (generate a valid proof) - val ctxf2 = ErgoLikeContext( + val ctxf2 = ErgoLikeContextTesting( currentHeight = height2 + 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) proverB.prove(env, prop2, ctxf2, fakeMessage).isSuccess shouldBe false //Successful run below: //A spends coins of B in chain2 - val ctx1 = ErgoLikeContext( + val ctx1 = ErgoLikeContextTesting( currentHeight = height2 + 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) @@ -135,10 +135,10 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { val proverB2 = proverB.withContextExtender(1, t.asInstanceOf[CollectionConstant[SByte.type]]) //B spends coins of A in chain1 with knowledge of x - val ctx2 = ErgoLikeContext( + val ctx2 = ErgoLikeContextTesting( currentHeight = height1 + 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) diff --git a/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala b/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala index dc0543e29b..d684ff908a 100644 --- a/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala @@ -3,7 +3,7 @@ package sigmastate.utxo.examples import org.ergoplatform._ import scorex.util.ScorexLogging import sigmastate.Values.IntConstant -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons} import sigmastate.interpreter.ContextExtension import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.lang.Terms._ @@ -145,7 +145,7 @@ class CoinEmissionSpecification extends SigmaTestingCommons with ScorexLogging { ) } - val context = ErgoLikeContext(height, + val context = ErgoLikeContextTesting(height, state.state.lastBlockUtxoRoot, minerPubkey, IndexedSeq(emissionBox), diff --git a/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala index a3955d476c..1933f73c0d 100644 --- a/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala @@ -4,7 +4,7 @@ import org.ergoplatform.ErgoBox.{R4, R5, R6} import org.ergoplatform._ import sigmastate.AvlTreeData import sigmastate.Values.{IntConstant, LongConstant} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ @@ -127,10 +127,10 @@ class ColdWalletAdvContractExampleSpecification extends SigmaTestingCommons { //normally this transaction would be invalid, but we're not checking it in this test val firstWithdrawTx1Key = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(firstChangeOutput1Key, firstWithdrawOutput1Key)) - val firstWithdrawContext1Key = ErgoLikeContext( + val firstWithdrawContext1Key = ErgoLikeContextTesting( currentHeight = firstWithdrawHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = firstWithdrawTx1Key, self = depositOutput @@ -163,10 +163,10 @@ class ColdWalletAdvContractExampleSpecification extends SigmaTestingCommons { //normally this transaction would be invalid, but we're not checking it in this test val firstWithdrawTx2Key = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(firstChangeOutput2Key, firstWithdrawOutput2Key)) - val firstWithdrawContext2Key = ErgoLikeContext( + val firstWithdrawContext2Key = ErgoLikeContextTesting( currentHeight = firstWithdrawHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = firstWithdrawTx2Key, self = depositOutput diff --git a/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala index d0bfa03882..64b0bf4b1c 100644 --- a/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala @@ -2,7 +2,7 @@ package sigmastate.utxo.examples import org.ergoplatform.ErgoBox.{R4, R5} import org.ergoplatform._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.AvlTreeData import sigmastate.Values.{IntConstant, LongConstant} import sigmastate.interpreter.Interpreter.ScriptNameProp @@ -93,10 +93,10 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { val withdrawTxAliceAndBob = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(withdrawOutputAliceAndBob)) - val withdrawContextAliceandBob = ErgoLikeContext( + val withdrawContextAliceandBob = ErgoLikeContextTesting( currentHeight = firstWithdrawHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTxAliceAndBob, self = depositOutput @@ -123,10 +123,10 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { //normally this transaction would be invalid, but we're not checking it in this test val firstWithdrawTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(firstChangeOutput, firstWithdrawOutput)) - val firstWithdrawContext = ErgoLikeContext( + val firstWithdrawContext = ErgoLikeContextTesting( currentHeight = firstWithdrawHeight, // 51 lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = firstWithdrawTx, self = depositOutput @@ -152,10 +152,10 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { // normally this transaction would be invalid, but we're not checking it in this test val withdrawTxInvalid = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(changeOutputInvalid, withdrawOutputInvalid)) - val withdrawContextInvalid = ErgoLikeContext( + val withdrawContextInvalid = ErgoLikeContextTesting( currentHeight = firstWithdrawHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTxInvalid, self = depositOutput @@ -186,10 +186,10 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { //normally this transaction would be invalid, but we're not checking it in this test val secondWithdrawTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(secondChangeOutput, secondWithdrawOutput)) - val secondWithdrawContext = ErgoLikeContext( + val secondWithdrawContext = ErgoLikeContextTesting( currentHeight = secondWithdrawHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(firstChangeOutput), spendingTransaction = secondWithdrawTx, self = firstChangeOutput diff --git a/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala index cbf578a0ef..b058028605 100644 --- a/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala @@ -6,7 +6,7 @@ import org.scalatest.TryValues._ import sigmastate.basics.DLogProtocol.ProveDlog import scorex.crypto.hash.Blake2b256 import sigmastate.Values.{ByteArrayConstant, SigmaPropValue, Value} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.lang.Terms._ import sigmastate.{AvlTreeData, SBoolean} @@ -20,10 +20,10 @@ class CoopExampleSpecification extends SigmaTestingCommons { def mkCtx(height: Int, tx: ErgoLikeTransaction, self: ErgoBox): ErgoLikeContext = { - ErgoLikeContext( + ErgoLikeContextTesting( currentHeight = height, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(self), spendingTransaction = tx, self = self) diff --git a/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala index fa551e6a20..3a44b051bf 100644 --- a/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala @@ -9,7 +9,7 @@ import sigmastate.AvlTreeData import sigmastate.Values.GroupElementConstant import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.{DiffieHellmanTupleProverInput, ProveDHTuple} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.CryptoConstants import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ @@ -79,10 +79,10 @@ class DHTupleExampleSpecification extends SigmaTestingCommons { val tx = createTransaction(IndexedSeq(outBox)) - val context = ErgoLikeContext( + val context = ErgoLikeContextTesting( currentHeight = 70, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(inBox), spendingTransaction = tx, self = inBox diff --git a/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala index 65877b7013..0dc337b296 100644 --- a/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala @@ -4,7 +4,7 @@ import sigmastate.interpreter.Interpreter._ import org.ergoplatform._ import sigmastate.Values.ShortConstant import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.ContextExtension import sigmastate.lang.Terms._ @@ -84,10 +84,10 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { val tx1 = createTransaction(createBox(outValue, prop, currentHeight1)) val selfBox = createBox(inValue, prop, inHeight) - val ctx1 = ErgoLikeContext( + val ctx1 = ErgoLikeContextTesting( currentHeight1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx1, self = selfBox, @@ -104,10 +104,10 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { //case 2: demurrage time has come val currentHeight2 = inHeight + demurragePeriod val tx2 = createTransaction(createBox(outValue, prop, currentHeight2)) - val ctx2 = ErgoLikeContext( + val ctx2 = ErgoLikeContextTesting( currentHeight2, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx2, self = selfBox, @@ -120,10 +120,10 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { //miner can spend "demurrageCoeff * demurragePeriod" tokens val b = createBox(outValue, prop, currentHeight2) val tx3 = createTransaction(b) - val ctx3 = ErgoLikeContext( + val ctx3 = ErgoLikeContextTesting( currentHeight = currentHeight2, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(b, selfBox), spendingTransaction = tx3, self = selfBox) @@ -137,10 +137,10 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { //miner can't spend more val b2 = createBox(outValue - 1, prop, currentHeight2) val tx4 = createTransaction(b2) - val ctx4 = ErgoLikeContext( + val ctx4 = ErgoLikeContextTesting( currentHeight = currentHeight2, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(b2, selfBox), spendingTransaction = tx4, self = selfBox, @@ -152,10 +152,10 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { //miner can spend less val tx5 = createTransaction(createBox(outValue + 1, prop, currentHeight2)) - val ctx5 = ErgoLikeContext( + val ctx5 = ErgoLikeContextTesting( currentHeight = currentHeight2, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx5, self = selfBox, @@ -169,10 +169,10 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { val b3 = createBox(iv, ErgoScriptPredef.FalseProp, currentHeight2) val tx6 = createTransaction(b3) val selfBox6 = createBox(iv, prop, inHeight) - val ctx6 = ErgoLikeContext( + val ctx6 = ErgoLikeContextTesting( currentHeight = currentHeight2, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(b3, selfBox6), spendingTransaction = tx6, self = selfBox6, diff --git a/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala index 112f114600..213cad5606 100644 --- a/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala @@ -1,16 +1,16 @@ package sigmastate.utxo.examples import org.ergoplatform._ -import scorex.crypto.authds.avltree.batch.{Lookup, BatchAVLProver, Insert} +import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Lookup} import scorex.crypto.authds.{ADKey, ADValue} import scorex.crypto.hash -import scorex.crypto.hash.{Digest32, Blake2b256} +import scorex.crypto.hash.{Blake2b256, Digest32} import sigmastate.SCollection.SByteArray import sigmastate.Values._ import sigmastate._ import sigmastate.eval._ import sigmastate.lang.Terms._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.serialization.ValueSerializer import sigmastate.utxo._ @@ -143,10 +143,10 @@ class FsmExampleSpecification extends SigmaTestingCommons { avlProver.performOneOperation(Lookup(ADKey @@ (transition12 ++ script1Hash))) val transition12Proof = avlProver.generateProof() - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox1), createTransaction(fsmBox2), self = fsmBox1) @@ -163,10 +163,10 @@ class FsmExampleSpecification extends SigmaTestingCommons { avlProver.performOneOperation(Lookup(ADKey @@ (transition21 ++ script2Hash))) val transition21Proof = avlProver.generateProof() - val ctx2 = ErgoLikeContext( + val ctx2 = ErgoLikeContextTesting( currentHeight = 51, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox2), createTransaction(fsmBox1), self = fsmBox2) @@ -191,10 +191,10 @@ class FsmExampleSpecification extends SigmaTestingCommons { avlProver.performOneOperation(Lookup(ADKey @@ (transition13 ++ script1Hash))) val transition13Proof = avlProver.generateProof() - val ctx3 = ErgoLikeContext( + val ctx3 = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox1), createTransaction(fsmBox3), self = fsmBox1) @@ -218,10 +218,10 @@ class FsmExampleSpecification extends SigmaTestingCommons { avlProver.performOneOperation(Lookup(ADKey @@ (transition23 ++ script3Hash))) val transition23Proof = avlProver.generateProof() - val ctx23 = ErgoLikeContext( + val ctx23 = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox2), createTransaction(fsmBox3), self = fsmBox2) @@ -240,10 +240,10 @@ class FsmExampleSpecification extends SigmaTestingCommons { avlProver.performOneOperation(Lookup(ADKey @@ (transition30 ++ script4Hash))) val transition30Proof = avlProver.generateProof() - val ctx30 = ErgoLikeContext( + val ctx30 = ErgoLikeContextTesting( currentHeight = 52, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox3), createTransaction(freeBox), self = fsmBox3) @@ -256,10 +256,10 @@ class FsmExampleSpecification extends SigmaTestingCommons { (new ErgoLikeTestInterpreter).verify(fsmScript, ctx30, spendingProof30, fakeMessage).get._1 shouldBe true //it is impossible to leave FSM at state2 - val ctx20 = ErgoLikeContext( + val ctx20 = ErgoLikeContextTesting( currentHeight = 52, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox2), createTransaction(freeBox), self = fsmBox2) diff --git a/src/test/scala/sigmastate/utxo/examples/IcoExample.scala b/src/test/scala/sigmastate/utxo/examples/IcoExample.scala index e5992e6a68..7089cb0f3c 100644 --- a/src/test/scala/sigmastate/utxo/examples/IcoExample.scala +++ b/src/test/scala/sigmastate/utxo/examples/IcoExample.scala @@ -10,6 +10,7 @@ import scorex.crypto.hash.{Digest32, Blake2b256} import sigmastate.Values.{AvlTreeConstant, IntArrayConstant, CollectionConstant, ByteArrayConstant, SigmaPropValue} import sigmastate._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.ErgoLikeContextTesting import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ import sigmastate.serialization.ErgoTreeSerializer @@ -406,10 +407,10 @@ class IcoExample extends SigmaTestingCommons { suite => val fundingTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(projectBoxAfter, feeBox)) - val fundingContext = ErgoLikeContext( + val fundingContext = ErgoLikeContextTesting( currentHeight = 1000, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction = fundingTx, self = projectBoxBefore) @@ -443,10 +444,10 @@ class IcoExample extends SigmaTestingCommons { suite => val issuanceTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(projectBoxAfterClosing, ergoWithdrawalBox, feeBox)) - val issuanceContext = ErgoLikeContext( + val issuanceContext = ErgoLikeContextTesting( currentHeight = 1000, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(projectBoxBeforeClosing), spendingTransaction = issuanceTx, self = projectBoxBeforeClosing) @@ -515,10 +516,10 @@ class IcoExample extends SigmaTestingCommons { suite => val outputs = IndexedSeq(projectBoxAfter) ++ withdrawBoxes ++ IndexedSeq(feeBox) val fundingTx = ErgoLikeTransaction(IndexedSeq(), outputs) - val fundingContext = ErgoLikeContext( + val fundingContext = ErgoLikeContextTesting( currentHeight = 1000, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(projectBoxBefore), spendingTransaction = fundingTx, self = projectBoxBefore) diff --git a/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala b/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala index 01b6d063c8..3268eabad7 100644 --- a/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala @@ -6,9 +6,9 @@ import scorex.crypto.authds.{ADKey, ADValue} import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Lookup} import scorex.crypto.hash.{Blake2b256, Digest32} import sigmastate.{AvlTreeData, AvlTreeFlags, TrivialProp} -import sigmastate.Values.{ByteArrayConstant, AvlTreeConstant, SigmaPropConstant, LongConstant} +import sigmastate.Values.{AvlTreeConstant, ByteArrayConstant, LongConstant, SigmaPropConstant} import sigmastate.eval.{IRContext, SigmaDsl} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.serialization.ErgoTreeSerializer import sigmastate.lang.Terms._ @@ -302,10 +302,10 @@ class LetsSpecification extends SigmaTestingCommons { val issuanceTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(projectBoxAfter, userBox, feeBox)) - val fundingContext = ErgoLikeContext( + val fundingContext = ErgoLikeContextTesting( currentHeight = 1000, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(projectBoxBefore), spendingTransaction = issuanceTx, self = projectBoxBefore) @@ -349,10 +349,10 @@ class LetsSpecification extends SigmaTestingCommons { val issuanceTx = new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(directoryDataInput), IndexedSeq(userBoxAfter0, userBoxAfter1)) - val exchangeContext = ErgoLikeContext( + val exchangeContext = ErgoLikeContextTesting( currentHeight = 1000, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, dataBoxes = IndexedSeq(directoryBox), boxesToSpend = IndexedSeq(userBoxBefore0, userBoxBefore1), spendingTransaction = issuanceTx, diff --git a/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala index 8fad6e8025..b705017af3 100644 --- a/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala @@ -3,11 +3,11 @@ package sigmastate.utxo.examples import org.ergoplatform._ import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Lookup} import scorex.crypto.authds.{ADKey, ADValue} -import scorex.crypto.hash.{Digest32, Blake2b256} +import scorex.crypto.hash.{Blake2b256, Digest32} import sigmastate.SCollection.SByteArray import sigmastate.Values._ import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.lang.Terms._ import sigmastate.interpreter.Interpreter._ import sigmastate.serialization.ValueSerializer @@ -48,10 +48,10 @@ class MASTExampleSpecification extends SigmaTestingCommons { val input1 = ErgoBox(20, prop, 0) val tx = UnsignedErgoLikeTransaction(IndexedSeq(input1).map(i => new UnsignedInput(i.id)), IndexedSeq(ErgoBox(1, ErgoScriptPredef.TrueProp, 0))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(input1), tx, self = input1) @@ -102,10 +102,10 @@ class MASTExampleSpecification extends SigmaTestingCommons { val recipientProposition = new ContextEnrichingTestProvingInterpreter().dlogSecrets.head.publicImage val selfBox = ErgoBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(treeData))) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), createTransaction(ErgoBox(1, recipientProposition, 0)), self = selfBox) diff --git a/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala index f3c0998420..98098e43c9 100644 --- a/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala @@ -9,7 +9,7 @@ import sigmastate.AvlTreeData import sigmastate.Values.GroupElementConstant import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.{DiffieHellmanTupleProverInput, ProveDHTuple} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.CryptoConstants import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ @@ -156,10 +156,10 @@ class MixExampleSpecification extends SigmaTestingCommons { // normally this transaction would be invalid, but we're not checking it in this test val fullMixTx = createTransaction(IndexedSeq(fullMixOutput0, fullMixOutput1)) - val fullMixContext = ErgoLikeContext( + val fullMixContext = ErgoLikeContextTesting( currentHeight = fullMixCreationHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(halfMixOutput), spendingTransaction = fullMixTx, self = halfMixOutput @@ -211,10 +211,10 @@ class MixExampleSpecification extends SigmaTestingCommons { (fullMixOutput1, fullMixOutput0) } - val aliceSpendContext = ErgoLikeContext( + val aliceSpendContext = ErgoLikeContextTesting( currentHeight = spendHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(aliceAnonBox), spendingTransaction = spendingTx, self = aliceAnonBox @@ -233,10 +233,10 @@ class MixExampleSpecification extends SigmaTestingCommons { //// Bob spending his output ////////////////////////////////////////////// - val bobSpendContext = ErgoLikeContext( + val bobSpendContext = ErgoLikeContextTesting( currentHeight = spendHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(bobAnonBox), spendingTransaction = spendingTx, self = bobAnonBox diff --git a/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala index 161ca518b7..6e5f297808 100644 --- a/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala @@ -6,16 +6,16 @@ import com.google.common.primitives.Longs import org.ergoplatform.ErgoBox.RegisterId import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Lookup} import scorex.crypto.authds.{ADKey, ADValue} -import scorex.crypto.hash.{Digest32, Blake2b256} +import scorex.crypto.hash.{Blake2b256, Digest32} import sigmastate.SCollection.SByteArray import sigmastate.Values._ import sigmastate._ import sigmastate.eval._ import sigmastate.lang.Terms._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.CryptoConstants import org.ergoplatform._ -import org.ergoplatform.dsl.{SigmaContractSyntax, ContractSpec, TestContractSpec, StdContracts} +import org.ergoplatform.dsl.{ContractSpec, SigmaContractSyntax, StdContracts, TestContractSpec} import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.utxo._ import special.sigma.Context @@ -172,10 +172,10 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => val propBob = withinTimeframe(sinceHeight, timeout, bobPubKey.isProven)(propAlong).toSigmaProp val sBob = ErgoBox(10, propBob, 0, Seq(), Map(), boxIndex = 4) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = treeData, - ErgoLikeContext.dummyPubkey, + ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(sAlice, sBob), spendingTransaction, self = sAlice) @@ -249,10 +249,10 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => val newBoxes = IndexedSeq(newBox1) val spendingTransaction = createTransaction(newBoxes) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(sOracle, sAlice, sBob), spendingTransaction, self = sOracle) diff --git a/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala index b80fb1f36b..be1b72a08d 100644 --- a/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala @@ -8,7 +8,7 @@ import scorex.utils.Random import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant, SigmaBoolean, SigmaPropConstant} import sigmastate._ import sigmastate.basics.DLogProtocol.ProveDlog -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ import sigmastate.utxo._ @@ -155,10 +155,10 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { //normally this transaction would invalid (why?), but we're not checking it in this test val fullGameTx = createTransaction(IndexedSeq(fullGameOutput0, fullGameOutput1)) - val fullGameContext = ErgoLikeContext( + val fullGameContext = ErgoLikeContextTesting( currentHeight = fullGameCreationHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(halfGameOutput), spendingTransaction = fullGameTx, self = halfGameOutput // what is the use of self? @@ -191,19 +191,19 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { val aliceProver = alice.withContextExtender(0, ByteArrayConstant(s)).withContextExtender(1, ByteConstant(a)) val bobProver = bob.withContextExtender(0, ByteArrayConstant(s)).withContextExtender(1, ByteConstant(a)) - val winContext0 = ErgoLikeContext( + val winContext0 = ErgoLikeContextTesting( currentHeight = gameOverHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0, fullGameOutput1), spendingTransaction = gameOverTx, self = fullGameOutput0 ) - val winContext1 = ErgoLikeContext( + val winContext1 = ErgoLikeContextTesting( currentHeight = gameOverHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0, fullGameOutput1), spendingTransaction = gameOverTx, self = fullGameOutput1 @@ -216,10 +216,10 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { // Possibility 1.1: draw ///////////////////////////////////////////////////////// - val drawContextAlice = ErgoLikeContext( + val drawContextAlice = ErgoLikeContextTesting( currentHeight = gameOverHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0), spendingTransaction = gameOverTx, self = fullGameOutput0 @@ -228,10 +228,10 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { val proofAliceDraw = aliceProver.prove(fullGameEnv, fullGameScript, drawContextAlice, fakeMessage).get verifier.verify(fullGameEnv, fullGameScript, drawContextAlice, proofAliceDraw, fakeMessage).get._1 shouldBe true - val drawContextBob = ErgoLikeContext( + val drawContextBob = ErgoLikeContextTesting( currentHeight = gameOverHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput1), spendingTransaction = gameOverTx, self = fullGameOutput1 @@ -277,18 +277,18 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { //normally this transaction would invalid (why?), but we're not checking it in this test val defaultWinTx = createTransaction(defaultWinOutput) - val defaultWinContext0 = ErgoLikeContext( + val defaultWinContext0 = ErgoLikeContextTesting( currentHeight = defaultWinHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0, fullGameOutput1), spendingTransaction = defaultWinTx, self = fullGameOutput0 // what is the use of self? ) - val defaultWinContext1 = ErgoLikeContext( + val defaultWinContext1 = ErgoLikeContextTesting( currentHeight = defaultWinHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0, fullGameOutput1), spendingTransaction = defaultWinTx, self = fullGameOutput1 // what is the use of self? diff --git a/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala index 564389d24e..ca736e18dc 100644 --- a/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala @@ -5,7 +5,7 @@ import org.ergoplatform._ import scorex.crypto.hash.Blake2b256 import sigmastate.Values.{IntConstant, SigmaPropConstant} import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ @@ -143,10 +143,10 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { //normally this transaction would be invalid (why?), but we're not checking it in this test val withdrawTx = createTransaction(reversibleWithdrawOutput) - val withdrawContext = ErgoLikeContext( + val withdrawContext = ErgoLikeContextTesting( currentHeight = withdrawHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTx, self = depositOutput @@ -172,10 +172,10 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { //normally this transaction would be invalid (why?), but we're not checking it in this test val bobSpendTx = createTransaction(bobSpendOutput) - val bobSpendContext = ErgoLikeContext( + val bobSpendContext = ErgoLikeContextTesting( currentHeight = bobSpendHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(reversibleWithdrawOutput), spendingTransaction = bobSpendTx, self = reversibleWithdrawOutput @@ -199,10 +199,10 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { //normally this transaction would be invalid (why?), but we're not checking it in this test val carolSpendTx = createTransaction(carolSpendOutput) - val carolSpendContext = ErgoLikeContext( + val carolSpendContext = ErgoLikeContextTesting( currentHeight = carolSpendHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(reversibleWithdrawOutput), spendingTransaction = carolSpendTx, self = reversibleWithdrawOutput diff --git a/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala b/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala index 0cde3cd427..7d6bd0615c 100644 --- a/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala +++ b/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala @@ -3,10 +3,10 @@ package sigmastate.utxo.examples import org.ergoplatform._ import scorex.crypto.hash.Blake2b256 import scorex.util._ -import sigmastate.Values.{LongConstant, FalseLeaf, TrueLeaf, GetVarByteArray, Value, ByteArrayConstant, IntConstant, BooleanConstant, ByteConstant} +import sigmastate.Values.{BooleanConstant, ByteArrayConstant, ByteConstant, FalseLeaf, GetVarByteArray, IntConstant, LongConstant, TrueLeaf, Value} import sigmastate._ import sigmastate.eval._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.ContextExtension import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer @@ -55,10 +55,10 @@ class Rule110Specification extends SigmaTestingCommons { val output = ErgoBox(1, prop, 0, Seq(), Map(reg1 -> ByteArrayConstant(Array[Byte](1, 1, 1, 1, 1, 0)))) val tx = UnsignedErgoLikeTransaction(IndexedSeq(new UnsignedInput(input.id)), IndexedSeq(output)) - val ctx = ErgoLikeContext( + val ctx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(input), tx, self = input).withCostLimit(maxCost) @@ -217,10 +217,10 @@ class Rule110Specification extends SigmaTestingCommons { val nProver = new ContextEnrichingTestProvingInterpreter() .withContextExtender(scriptId, ByteArrayConstant(normalCaseBytes)) - val nCtx = ErgoLikeContext( + val nCtx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(nIn0, nIn1, nIn2), nTx, self = nIn0) @@ -239,10 +239,10 @@ class Rule110Specification extends SigmaTestingCommons { val rProver = new ContextEnrichingTestProvingInterpreter() .withContextExtender(scriptId, ByteArrayConstant(rightmostBytes)) - val rCtx = ErgoLikeContext( + val rCtx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(rIn0, rIn1), rTx, self = rIn0) @@ -261,10 +261,10 @@ class Rule110Specification extends SigmaTestingCommons { val lnProver = new ContextEnrichingTestProvingInterpreter() .withContextExtender(scriptId, ByteArrayConstant(nLeftmostBytes)) - val lnCtx = ErgoLikeContext( + val lnCtx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(lnIn0, lnIn1), lnTx, self = lnIn0) @@ -282,10 +282,10 @@ class Rule110Specification extends SigmaTestingCommons { val lProver = new ContextEnrichingTestProvingInterpreter() .withContextExtender(scriptId, ByteArrayConstant(leftmostBytes)) - val lCtx = ErgoLikeContext( + val lCtx = ErgoLikeContextTesting( currentHeight = 1, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(lIn0), lTx, self = lIn0) @@ -405,7 +405,7 @@ class Rule110Specification extends SigmaTestingCommons { val initBlock = FullBlock( IndexedSeq(createTransaction(coins)), - ErgoLikeContext.dummyPubkey + ErgoLikeContextTesting.dummyPubkey ) val genesisState = ValidationState.initialState(initBlock) @@ -438,27 +438,27 @@ class Rule110Specification extends SigmaTestingCommons { IndexedSeq(c, left.toCandidate, center.toCandidate, right.toCandidate) ) - val contextLeft = ErgoLikeContext(row, + val contextLeft = ErgoLikeContextTesting(row, state.state.lastBlockUtxoRoot, - ErgoLikeContext.dummyPubkey, + ErgoLikeContextTesting.dummyPubkey, IndexedSeq(left, center, right), ut, left, ContextExtension.empty) val proverResultLeft = prover.prove(left.ergoTree, contextLeft, ut.messageToSign).get - val contextCenter = ErgoLikeContext(row, + val contextCenter = ErgoLikeContextTesting(row, state.state.lastBlockUtxoRoot, - ErgoLikeContext.dummyPubkey, + ErgoLikeContextTesting.dummyPubkey, IndexedSeq(left, center, right), ut, center, ContextExtension.empty) val proverResultCenter = prover.prove(center.ergoTree, contextCenter, ut.messageToSign).get - val contextRight = ErgoLikeContext(row, + val contextRight = ErgoLikeContextTesting(row, state.state.lastBlockUtxoRoot, - ErgoLikeContext.dummyPubkey, + ErgoLikeContextTesting.dummyPubkey, IndexedSeq(left, center, right), ut, right, @@ -468,7 +468,7 @@ class Rule110Specification extends SigmaTestingCommons { } } - val firstRowBlock = FullBlock(generateTransactionsForRow(genesisState, 1), ErgoLikeContext.dummyPubkey) + val firstRowBlock = FullBlock(generateTransactionsForRow(genesisState, 1), ErgoLikeContextTesting.dummyPubkey) val t0 = System.currentTimeMillis() val firstRowState = genesisState.applyBlock(firstRowBlock, 10000000).get diff --git a/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala index 3ceafee273..5b9b1300ac 100644 --- a/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala @@ -4,7 +4,7 @@ import org.ergoplatform.ErgoBox.{R4, R5} import org.ergoplatform._ import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant} import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.InterpreterException @@ -58,10 +58,10 @@ class TimedPaymentExampleSpecification extends SigmaTestingCommons { //normally this transaction would be invalid, but we're not checking it in this test val withdrawTx = createTransaction(IndexedSeq(timedWithdrawOutput)) - val withdrawContext = ErgoLikeContext( + val withdrawContext = ErgoLikeContextTesting( currentHeight = 109, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTx, self = depositOutput @@ -75,10 +75,10 @@ class TimedPaymentExampleSpecification extends SigmaTestingCommons { verifier.verify(env, script, withdrawContext, proofWithdraw, fakeMessage).get._1 shouldBe true - val withdrawContextBad = ErgoLikeContext( + val withdrawContextBad = ErgoLikeContextTesting( currentHeight = 111, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTx, self = depositOutput diff --git a/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala index 05f1fca36a..606d64f17a 100644 --- a/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala @@ -8,7 +8,7 @@ import scorex.utils.Random import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant, SigmaPropConstant} import sigmastate._ import sigmastate.basics.DLogProtocol.ProveDlog -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ import sigmastate.utxo._ @@ -144,10 +144,10 @@ class XorGameExampleSpecification extends SigmaTestingCommons { //normally this transaction would invalid (why?), but we're not checking it in this test val abortHalfGameTx = createTransaction(abortHalfGameOutput) - val abortHalfGameContext = ErgoLikeContext( + val abortHalfGameContext = ErgoLikeContextTesting( currentHeight = abortHalfGameHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(halfGameOutput), spendingTransaction = abortHalfGameTx, self = halfGameOutput // what is the use of self? @@ -180,10 +180,10 @@ class XorGameExampleSpecification extends SigmaTestingCommons { //normally this transaction would invalid (why?), but we're not checking it in this test val fullGameTx = createTransaction(fullGameOutput) - val fullGameContext = ErgoLikeContext( + val fullGameContext = ErgoLikeContextTesting( currentHeight = fullGameCreationHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(halfGameOutput), spendingTransaction = fullGameTx, self = halfGameOutput // what is the use of self? @@ -230,10 +230,10 @@ class XorGameExampleSpecification extends SigmaTestingCommons { //normally this transaction would invalid (why?), but we're not checking it in this test val gameOverTx = createTransaction(gameOverOutput) - val gameOverContext = ErgoLikeContext( + val gameOverContext = ErgoLikeContextTesting( currentHeight = gameOverHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput), spendingTransaction = gameOverTx, self = fullGameOutput // what is the use of self? @@ -257,10 +257,10 @@ class XorGameExampleSpecification extends SigmaTestingCommons { //normally this transaction would invalid (why?), but we're not checking it in this test val defaultWinTx = createTransaction(defaultWinOutput) - val defaultWinContext = ErgoLikeContext( + val defaultWinContext = ErgoLikeContextTesting( currentHeight = defaultWinHeight, lastBlockUtxoRoot = AvlTreeData.dummy, - minerPubkey = ErgoLikeContext.dummyPubkey, + minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput), spendingTransaction = defaultWinTx, self = fullGameOutput // what is the use of self? From 1b1bafc6dcca7cd30cb8efef9e95cdd1956d41d1 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 8 Aug 2019 14:25:52 +0300 Subject: [PATCH 39/64] fix build; --- src/test/scala/special/sigma/SigmaDslTest.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/scala/special/sigma/SigmaDslTest.scala b/src/test/scala/special/sigma/SigmaDslTest.scala index 15599989ed..1b6a555751 100644 --- a/src/test/scala/special/sigma/SigmaDslTest.scala +++ b/src/test/scala/special/sigma/SigmaDslTest.scala @@ -2,7 +2,6 @@ package special.sigma import java.math.BigInteger -import org.ergoplatform.ErgoLikeContext.dummyPubkey import org.ergoplatform.ErgoScriptPredef.TrueProp import org.ergoplatform.dsl.{SigmaContractSyntax, TestContractSpec} import org.ergoplatform._ From 799e8864a48bfb5f30818da763ecb1073c63f718 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 8 Aug 2019 14:26:35 +0300 Subject: [PATCH 40/64] remove ErgoLikeContext.currentHeight, minerPubkey, self; --- .../org/ergoplatform/ErgoLikeContext.scala | 49 +++++++++---------- .../ergoplatform/ErgoLikeInterpreter.scala | 2 +- .../CrowdFundingKernelContract.scala | 4 +- .../DemurrageExampleSpecification.scala | 2 +- 4 files changed, 27 insertions(+), 30 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 257a2adc8d..bb76617c18 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -47,15 +47,25 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, ) extends InterpreterContext { /* NOHF PROOF: - + Added: assert(preHeader != null) + Motivation: to fail early, rather then on evaluation on `CONTEXT.preHeader` access + Safety: According to ergo design PreHeader should always exist. + Examined ergo code: all that leads to ErgoLikeContext creation. + Fixed some cases in ergo where PreHeader might be null. */ assert(preHeader != null, "preHeader cannot be null") /* NOHF PROOF: - + Added: assert(spendingTransaction != null) + Motivation: to fail early + Safety: According to ergo design spendingTransaction should always exist. + Examined ergo code: all that leads to ErgoLikeContext creation. */ assert(spendingTransaction != null, "spendingTransaction cannot be null") /* NOHF PROOF: - + Added: assert that box with `selfIndex` exist in boxesToSpend + Motivation: to fail early, rather than when going into evaluation + Safety: ergo itself uses index to identify the box + Examined ergo code: all that leads to ErgoLikeContext creation. */ assert(boxesToSpend.isDefinedAt(selfIndex), s"Self box if defined should be among boxesToSpend") assert(headers.toArray.headOption.forall(h => java.util.Arrays.equals(h.stateRoot.digest.toArray, lastBlockUtxoRoot.digest)), "Incorrect lastBlockUtxoRoot") @@ -64,7 +74,10 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, } assert(headers.toArray.headOption.forall(_.id == preHeader.parentId), s"preHeader.parentId should be id of the best header") /* NOHF PROOF: - + Added: assert that dataBoxes corresponds to spendingTransaction.dataInputs + Motivation: to fail early, rather than when going into evaluation + Safety: dataBoxes and spendingTransaction are supplied separately in ergo. No checks in ergo. + Examined ergo code: all that leads to ErgoLikeContext creation. */ assert(spendingTransaction.dataInputs.length == dataBoxes.length && spendingTransaction.dataInputs.forall(dataInput => dataBoxes.exists(b => util.Arrays.equals(b.id, dataInput.boxId))), @@ -72,23 +85,6 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, // TODO assert boxesToSpend correspond to spendingTransaction.inputs - /* NOHF PROOF: - - */ - // height of a block with the current `spendingTransaction` - val currentHeight: Height = preHeader.height - - /* NOHF PROOF: - - */ - // public key of a miner of the block with the current `spendingTransaction` - val minerPubkey: GroupElement = preHeader.minerPk - - /* NOHF PROOF: - - */ - val self: ErgoBox = boxesToSpend(selfIndex) - override def withCostLimit(newCostLimit: Long): ErgoLikeContext = new ErgoLikeContext( lastBlockUtxoRoot, headers, preHeader, @@ -132,7 +128,10 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, implicit class ErgoBoxOps(val ebox: ErgoBox) { def toTestBox(isCost: Boolean): Box = { /* NOHF PROOF: - + Added: assert that dataBoxes corresponds to spendingTransaction.dataInputs + Motivation: to fail early, rather than when going into evaluation + Safety: dataBoxes and spendingTransaction are supplied separately in ergo. No checks in ergo. + Examined ergo code: all that leads to ErgoLikeContext creation. */ new CostingBox(isCost, ebox) } @@ -151,10 +150,8 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val vars = contextVars(varMap ++ extensions) val avlTree = CAvlTree(lastBlockUtxoRoot) CostingDataContext( - dataInputs, headers, preHeader, inputs, outputs, currentHeight, self.toTestBox(isCost), avlTree, - minerPubkey.getEncoded, - vars, - isCost) + dataInputs, headers, preHeader, inputs, outputs, preHeader.height, boxesToSpend(selfIndex).toTestBox(isCost), avlTree, + preHeader.minerPk.getEncoded, vars, isCost) } diff --git a/src/main/scala/org/ergoplatform/ErgoLikeInterpreter.scala b/src/main/scala/org/ergoplatform/ErgoLikeInterpreter.scala index 91d5c5622d..7deda754c0 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeInterpreter.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeInterpreter.scala @@ -13,7 +13,7 @@ class ErgoLikeInterpreter(implicit val IR: IRContext) extends Interpreter { override def substDeserialize(context: CTX, updateContext: CTX => Unit, node: SValue): Option[SValue] = node match { case d: DeserializeRegister[_] => - context.self.get(d.reg).flatMap { v => + context.boxesToSpend(context.selfIndex).get(d.reg).flatMap { v => v match { case eba: EvaluatedValue[SByteArray]@unchecked => val (ctx1, outVal) = deserializeMeasured(context, eba.value.toArray) diff --git a/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingKernelContract.scala b/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingKernelContract.scala index bb52ae09f2..c15933dd47 100644 --- a/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingKernelContract.scala +++ b/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingKernelContract.scala @@ -54,9 +54,9 @@ class CrowdFundingKernelContract( } def prove(ctx: ErgoLikeContext, message: Array[Byte]): Array[Byte] = { - val c1 = ctx.currentHeight >= timeout //&& isProven(backerPubKey, fakeMessage) + val c1 = ctx.preHeader.height >= timeout //&& isProven(backerPubKey, fakeMessage) val c2 = Array( - ctx.currentHeight < timeout, + ctx.preHeader.height < timeout, ctx.spendingTransaction.outputs.exists(out => { out.value >= minToRaise && util.Arrays.equals(out.propositionBytes, projectPubKey.toSigmaProp.treeWithSegregation.bytes) diff --git a/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala index 0dc337b296..65befc4e8b 100644 --- a/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala @@ -128,7 +128,7 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { spendingTransaction = tx3, self = selfBox) - assert(ctx3.spendingTransaction.outputs.head.propositionBytes sameElements ctx3.self.propositionBytes) + assert(ctx3.spendingTransaction.outputs.head.propositionBytes sameElements ctx3.boxesToSpend(ctx3.selfIndex).propositionBytes) val mProverRes1 = minerProver.prove(prop, ctx3, fakeMessage).get val _ctx3: ErgoLikeContext = ctx3.withExtension(mProverRes1.extension) From 223890af1f977799794860aa5460681a1930c5cb Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 8 Aug 2019 14:54:24 +0300 Subject: [PATCH 41/64] add NOHF comments; moved ErgoBoxOps to Extensions; --- .../org/ergoplatform/ErgoLikeContext.scala | 19 +++++-------------- .../scala/sigmastate/eval/Extensions.scala | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index bb76617c18..88a38f84b9 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -125,23 +125,14 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, IR.sigmaDslBuilderValue.Colls.fromArray(res) } - implicit class ErgoBoxOps(val ebox: ErgoBox) { - def toTestBox(isCost: Boolean): Box = { - /* NOHF PROOF: - Added: assert that dataBoxes corresponds to spendingTransaction.dataInputs - Motivation: to fail early, rather than when going into evaluation - Safety: dataBoxes and spendingTransaction are supplied separately in ergo. No checks in ergo. - Examined ergo code: all that leads to ErgoLikeContext creation. - */ - new CostingBox(isCost, ebox) - } - } - val dataInputs = this.dataBoxes.toArray.map(_.toTestBox(isCost)).toColl val inputs = boxesToSpend.toArray.map(_.toTestBox(isCost)).toColl /* NOHF PROOF: - -*/ + Changed: removed check for spendingTransaction == null + Motivation: spendingTransaction cannot be null + Safety: in ergo spendingTransaction cannot be null + Examined ergo code: all that leads to ErgoLikeContext creation. + */ val outputs = spendingTransaction.outputs.toArray.map(_.toTestBox(isCost)).toColl val varMap = extension.values.mapValues { case v: EvaluatedValue[_] => val tVal = stypeToRType[SType](v.tpe) diff --git a/src/main/scala/sigmastate/eval/Extensions.scala b/src/main/scala/sigmastate/eval/Extensions.scala index 4f343bbc79..627312cd3c 100644 --- a/src/main/scala/sigmastate/eval/Extensions.scala +++ b/src/main/scala/sigmastate/eval/Extensions.scala @@ -9,6 +9,7 @@ import sigmastate.lang.DefaultSigmaBuilder import special.collection.Coll import special.sigma._ import SType.AnyOps +import org.ergoplatform.ErgoBox import spire.syntax.all._ object Extensions { @@ -58,4 +59,17 @@ object Extensions { } def toAnyValue[A:RType](x: A) = new TestValue(x, RType[A].asInstanceOf[RType[Any]]) + + implicit class ErgoBoxOps(val ebox: ErgoBox) extends AnyVal { + def toTestBox(isCost: Boolean): Box = { + /* NOHF PROOF: + Changed: removed check for ebox == null + Motivation: box cannot be null + Safety: used in ErgoLikeContext where boxes cannot be null + Examined ergo code: all that leads to ErgoLikeContext creation. + */ + CostingBox(isCost, ebox) + } + } + } From f1d8e6cf4ed41a92590b543880415351dc928acc Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 8 Aug 2019 15:35:45 +0300 Subject: [PATCH 42/64] make ErgoLikeContextTesting.dummyPreHeader public; --- src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala b/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala index 2e5537ea4d..f3e9fd7fa0 100644 --- a/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala +++ b/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala @@ -26,7 +26,7 @@ object ErgoLikeContextTesting { val noBoxes: IndexedSeq[ErgoBox] = IndexedSeq.empty[ErgoBox] val noHeaders: Coll[Header] = CostingSigmaDslBuilder.Colls.emptyColl[Header] - private def dummyPreHeader(currentHeight: Height, minerPk: Array[Byte]): PreHeader = CPreHeader(0, + def dummyPreHeader(currentHeight: Height, minerPk: Array[Byte]): PreHeader = CPreHeader(0, parentId = Colls.emptyColl[Byte], timestamp = 3, nBits = 0, From 644b899b3fc1211cdf5f413a9fc74d835ad4e92a Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 8 Aug 2019 15:59:38 +0300 Subject: [PATCH 43/64] restore ErgoLikeContext.self (calculated); --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 88a38f84b9..477ae622b3 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -85,6 +85,14 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, // TODO assert boxesToSpend correspond to spendingTransaction.inputs + /* NOHF PROOF: + Changed: make `self` a property returning box from `boxesToSpend`. + Motivation: avoid DRY and avoid user error when trying to get the box from `boxesToSpend` supplying wrong index. + Safety: selfIndex are used internally in ergo. + Examined ergo code: all that leads to ErgoLikeContext creation. + */ + val self: ErgoBox = boxesToSpend(selfIndex) + override def withCostLimit(newCostLimit: Long): ErgoLikeContext = new ErgoLikeContext( lastBlockUtxoRoot, headers, preHeader, From 7ca134631be80d3533348996bf966cee5c359a65 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Sun, 11 Aug 2019 10:26:31 +0300 Subject: [PATCH 44/64] comment; --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 477ae622b3..d81130e4f9 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -88,7 +88,7 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, /* NOHF PROOF: Changed: make `self` a property returning box from `boxesToSpend`. Motivation: avoid DRY and avoid user error when trying to get the box from `boxesToSpend` supplying wrong index. - Safety: selfIndex are used internally in ergo. + Safety: index of the box and not the box itself are used internally in ergo. Examined ergo code: all that leads to ErgoLikeContext creation. */ val self: ErgoBox = boxesToSpend(selfIndex) From d9da36b15b08541faf61e19fbe514a82ba9ecf6c Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 09:52:23 +0300 Subject: [PATCH 45/64] Update src/main/scala/org/ergoplatform/ErgoLikeContext.scala Co-Authored-By: Alexander Slesarenko --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index d81130e4f9..4ba02af946 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -174,7 +174,7 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, } override def hashCode(): Int = { - val state = Seq(lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) + val state = Array(lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) } From 5225d5e07f2cc42df1cc0b0aee627ca020c52097 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 09:57:56 +0300 Subject: [PATCH 46/64] use imperative loop in ErgoLikeContext.hashCode; --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 4ba02af946..d65b842d26 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -175,7 +175,11 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, override def hashCode(): Int = { val state = Array(lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) - state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b) + var hashCode = 0 + cfor(0)(_ < state.length, _ + 1) { i => + hashCode = 31 * hashCode + state(i).hashCode + } + hashCode } override def toString = s"ErgoLikeContext(lastBlockUtxoRoot=$lastBlockUtxoRoot, headers=$headers, preHeader=$preHeader, dataBoxes=$dataBoxes, boxesToSpend=$boxesToSpend, spendingTransaction=$spendingTransaction, selfIndex=$selfIndex, extension=$extension, validationSettings=$validationSettings, costLimit=$costLimit, initCost=$initCost)" From ee8b58eff2add5ee35f296202176a5bc91ea8ea4 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 10:03:13 +0300 Subject: [PATCH 47/64] override UnsignedErgoLikeTransaction.hashCode; --- src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index df5e836686..8594f8f3f8 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -74,6 +74,8 @@ class UnsignedErgoLikeTransaction(override val inputs: IndexedSeq[UnsignedInput] case tx: UnsignedErgoLikeTransaction => this.id == tx.id case _ => false } + + override def hashCode(): Int = id.hashCode() } object UnsignedErgoLikeTransaction { From ec3d5b2f29228b5146096c08cf77833c192ae0cc Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 10:03:54 +0300 Subject: [PATCH 48/64] Update src/main/scala/org/ergoplatform/ErgoLikeContext.scala Co-Authored-By: Alexander Slesarenko --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index d65b842d26..9ab1b48acb 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -231,7 +231,7 @@ case object LastBlockUtxoRootHash extends NotReadyValueAvlTree with ValueCompani } -/** When interpreted evaluates to a BoxConstant built from Context.selfIndex */ +/** When interpreted evaluates to a BoxConstant built from context.boxesToSpend(context.selfIndex) */ case object Self extends NotReadyValueBox with ValueCompanion { override def companion = this override def opCode: OpCode = OpCodes.SelfCode From 6220e69a60eb9698a323723a86ac0b2f6ee62f46 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 10:06:50 +0300 Subject: [PATCH 49/64] remove assert, id is taken from map keys; --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 9ab1b48acb..794c572ce6 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -127,7 +127,6 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val maxKey = if (m.keys.isEmpty) 0 else m.keys.max val res = new Array[AnyValue](maxKey + 1) for ((id, v) <- m) { - assert(res(id) == null, s"register $id is defined more then once") res(id) = v } IR.sigmaDslBuilderValue.Colls.fromArray(res) From fb85e6cbcae72ca082d11c026d57cb0c7a5deec5 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 10:57:20 +0300 Subject: [PATCH 50/64] move ErgoLikeTransaction to tests (ErgoLikeTransactionTesting); --- .../ergoplatform/ErgoLikeTransaction.scala | 2 - .../helpers/ErgoLikeTransactionTesting.scala | 8 ++++ .../SigSerializerSpecification.scala | 4 +- .../utxo/ComplexSigSpecification.scala | 38 +++++++++---------- .../ErgoLikeInterpreterSpecification.scala | 8 ++-- .../utxo/ThresholdSpecification.scala | 10 ++--- .../AtomicSwapExampleSpecification.scala | 10 ++--- 7 files changed, 43 insertions(+), 37 deletions(-) create mode 100644 src/test/scala/sigmastate/helpers/ErgoLikeTransactionTesting.scala diff --git a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index 8594f8f3f8..4b1f9aee38 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -177,8 +177,6 @@ object ErgoLikeTransaction { val TransactionIdBytesSize: Short = 32 - val dummy = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()) - /** * Bytes that should be signed by provers. * Contains all the transaction bytes except of signatures diff --git a/src/test/scala/sigmastate/helpers/ErgoLikeTransactionTesting.scala b/src/test/scala/sigmastate/helpers/ErgoLikeTransactionTesting.scala new file mode 100644 index 0000000000..2672f0841b --- /dev/null +++ b/src/test/scala/sigmastate/helpers/ErgoLikeTransactionTesting.scala @@ -0,0 +1,8 @@ +package sigmastate.helpers + +import org.ergoplatform.ErgoLikeTransaction + +object ErgoLikeTransactionTesting { + + val dummy = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()) +} diff --git a/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala b/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala index 5586730f9e..2fdcb553f6 100644 --- a/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala +++ b/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala @@ -9,7 +9,7 @@ import sigmastate.Values.{SigmaBoolean, SigmaPropConstant, SigmaPropValue, Value import sigmastate._ import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.ProveDHTuple -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTransactionTesting, SigmaTestingCommons} import sigmastate.serialization.generators.ObjectGenerators import sigmastate.utxo.Transformer @@ -77,7 +77,7 @@ class SigSerializerSpecification extends SigmaTestingCommons with ObjectGenerato lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) // get sigma conjectures out of transformers diff --git a/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala b/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala index ec1bb36d2e..e11bcb6969 100644 --- a/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala @@ -5,7 +5,7 @@ import org.scalacheck.Gen import sigmastate.Values.IntConstant import sigmastate._ import sigmastate.lang.Terms._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTransactionTesting, SigmaTestingCommons} import scala.util.Random @@ -41,7 +41,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -74,7 +74,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -108,7 +108,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -143,7 +143,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -174,7 +174,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -215,7 +215,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -252,7 +252,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -285,7 +285,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -325,7 +325,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -366,7 +366,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -410,7 +410,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -448,7 +448,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx1, fakeMessage).get verifier.verify(compiledProp, ctx1, prA, fakeMessage).get._1 shouldBe true @@ -461,7 +461,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prC = proverC.prove(compiledProp, ctx2, fakeMessage).get verifier.verify(compiledProp, ctx2, prC, fakeMessage).get._1 shouldBe true @@ -490,7 +490,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx1, fakeMessage).get @@ -505,7 +505,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA2 = proverA.prove(compiledProp, ctx2, fakeMessage).get @@ -538,7 +538,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx1, fakeMessage).get @@ -553,7 +553,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA2 = proverA.prove(compiledProp, ctx2, fakeMessage).get @@ -588,7 +588,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) // any prover alone (no added secrets) should fail diff --git a/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala index a047fe56a9..1244348741 100644 --- a/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala @@ -14,7 +14,7 @@ import sigmastate.eval._ import sigmastate.interpreter.Interpreter._ import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.ProveDHTuple -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTransactionTesting, SigmaTestingCommons} import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.InterpreterException import sigmastate.serialization.{SerializationSpecification, ValueSerializer} @@ -74,7 +74,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val pr = prover.prove(prop, ctx, fakeMessage).get @@ -104,7 +104,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -131,7 +131,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get diff --git a/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala b/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala index cc10e30d81..c68f1dc03a 100644 --- a/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala +++ b/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala @@ -4,7 +4,7 @@ import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction} import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog} import sigmastate.Values.{ConcreteCollection, FalseLeaf, IntConstant, SigmaPropConstant, SigmaPropValue, TrueLeaf} import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTransactionTesting, SigmaTestingCommons} import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.CosterException @@ -39,7 +39,7 @@ class ThresholdSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val env = Map("pubkeyA" -> pubkeyA, "pubkeyB" -> pubkeyB, "pubkeyC" -> pubkeyC) @@ -118,7 +118,7 @@ class ThresholdSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) case class TestCase(numTrue: Int, vector: Seq[SigmaPropValue], dlogOnlyVector: DlogOnlyVector) @@ -288,7 +288,7 @@ class ThresholdSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val verifier = new ErgoLikeTestInterpreter @@ -335,7 +335,7 @@ class ThresholdSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val verifier = new ErgoLikeTestInterpreter diff --git a/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala b/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala index 3c002f63c6..3952bef3a1 100644 --- a/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala +++ b/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala @@ -6,7 +6,7 @@ import scorex.utils.Random import sigmastate.Values._ import sigmastate._ import interpreter.Interpreter._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTransactionTesting, SigmaTestingCommons} import sigmastate.lang.Terms._ import sigmastate.utxo.SizeOf @@ -102,7 +102,7 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) proverB.prove(env, prop1, ctxf1, fakeMessage).isSuccess shouldBe false @@ -114,7 +114,7 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { currentHeight = height2 + 1, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, - boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransaction.dummy, self = fakeSelf) + boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) proverB.prove(env, prop2, ctxf2, fakeMessage).isSuccess shouldBe false //Successful run below: @@ -125,7 +125,7 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val pr = proverA.prove(env, prop2, ctx1, fakeMessage).get verifier.verify(env, prop2, ctx1, pr, fakeMessage).get._1 shouldBe true @@ -140,7 +140,7 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), - spendingTransaction = ErgoLikeTransaction.dummy, + spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) val pr2 = proverB2.prove(env, prop1, ctx2, fakeMessage).get verifier.verify(env, prop1, ctx2, pr2, fakeMessage).get._1 shouldBe true From 1f27969cf66fcf10c1bba71e30ab6fd8a7f6fce6 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 11:01:02 +0300 Subject: [PATCH 51/64] override Input.hashCode and UnsignedInput.hashCode; --- src/main/scala/org/ergoplatform/Input.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/scala/org/ergoplatform/Input.scala b/src/main/scala/org/ergoplatform/Input.scala index 43ab4dbd71..e8b240bb20 100644 --- a/src/main/scala/org/ergoplatform/Input.scala +++ b/src/main/scala/org/ergoplatform/Input.scala @@ -21,6 +21,8 @@ case class DataInput(boxId: BoxId) { case x: DataInput => util.Arrays.equals(boxId, x.boxId) case _ => false } + + override def hashCode(): Int = boxId.hashCode } /** @@ -41,6 +43,8 @@ class UnsignedInput(val boxId: BoxId, val extension: ContextExtension) { case _ => false } + override def hashCode(): Int = boxId.hashCode + /** * Input, that should be signed by prover and verified by verifier. * Contains all the input data except of signature itself. From 69692bddc54b496dff68d8924a481daa73949a08 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 11:55:34 +0300 Subject: [PATCH 52/64] code cleanup; --- src/main/scala/sigmastate/AvlTreeData.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index f12f5aa0c2..4029653619 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -81,8 +81,7 @@ object AvlTreeData { AvlTreeFlags.AllOperationsAllowed, keyLength = 32) - def apply(avlTree: AvlTree): AvlTreeData = new AvlTreeData(ADDigest @@ avlTree.digest.toArray, - AvlTreeFlags.apply(avlTree.enabledOperations), avlTree.keyLength, avlTree.valueLengthOpt) + def apply(avlTree: AvlTree): AvlTreeData = sigmastate.eval.SigmaDsl.toAvlTreeData(avlTree) object serializer extends SigmaSerializer[AvlTreeData, AvlTreeData] { From d59bf0e5427a62bc647c30f3cc81ec1702fb5f75 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 11:55:59 +0300 Subject: [PATCH 53/64] code cleanup; --- src/main/scala/sigmastate/AvlTreeData.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index 4029653619..557e77a84c 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -4,6 +4,7 @@ import java.util import java.util.{Arrays, Objects} import scorex.crypto.authds.ADDigest +import sigmastate.eval.SigmaDsl import sigmastate.interpreter.CryptoConstants import sigmastate.serialization.SigmaSerializer import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} @@ -81,7 +82,7 @@ object AvlTreeData { AvlTreeFlags.AllOperationsAllowed, keyLength = 32) - def apply(avlTree: AvlTree): AvlTreeData = sigmastate.eval.SigmaDsl.toAvlTreeData(avlTree) + def apply(avlTree: AvlTree): AvlTreeData = SigmaDsl.toAvlTreeData(avlTree) object serializer extends SigmaSerializer[AvlTreeData, AvlTreeData] { From 8e21c7d5f591d640f78210b0190d8948aaa568e0 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 11:58:33 +0300 Subject: [PATCH 54/64] remove duplicating CGroupElement.decode; --- src/main/scala/org/ergoplatform/JsonCodecs.scala | 4 ++-- src/main/scala/sigmastate/eval/CostingDataContext.scala | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index fa9e804c3f..c8881d4e0e 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -135,7 +135,7 @@ trait JsonCodecs { powDistance <- cursor.downField("powDistance").as[special.sigma.BigInt] votes <- cursor.downField("votes").as[Coll[Byte]] } yield new CHeader(id, version, parentId, adProofsRoot, stateRoot, transactionsRoot, timestamp, nBits, - height, extensionRoot, CGroupElement.decode(minerPk), CGroupElement.decode(powOnetimePk), powNonce, powDistance, votes) + height, extensionRoot, SigmaDsl.decodePoint(minerPk), SigmaDsl.decodePoint(powOnetimePk), powNonce, powDistance, votes) } implicit val preHeaderEncoder: Encoder[PreHeader] = { v: PreHeader => @@ -159,7 +159,7 @@ trait JsonCodecs { height <- cursor.downField("height").as[Int] minerPk <- cursor.downField("minerPk").as[Coll[Byte]] votes <- cursor.downField("votes").as[Coll[Byte]] - } yield CPreHeader(version, parentId, timestamp, nBits, height, CGroupElement.decode(minerPk), votes) + } yield CPreHeader(version, parentId, timestamp, nBits, height, SigmaDsl.decodePoint(minerPk), votes) } implicit val evaluatedValueEncoder: Encoder[EvaluatedValue[_ <: SType]] = { value => diff --git a/src/main/scala/sigmastate/eval/CostingDataContext.scala b/src/main/scala/sigmastate/eval/CostingDataContext.scala index 76c9d4a700..bb7d15b661 100644 --- a/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -44,10 +44,6 @@ case class CGroupElement(override val wrappedValue: EcPointType) extends TestGro } -object CGroupElement { - def decode(bytes: Coll[Byte]): CGroupElement = CGroupElement(GroupElementSerializer.parse(bytes.toArray)) -} - case class CSigmaProp(sigmaTree: SigmaBoolean) extends SigmaProp with WrapperOf[SigmaBoolean] { override def wrappedValue: SigmaBoolean = sigmaTree From 97e953b5193466101a8b901160010fa04b628cc7 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Tue, 13 Aug 2019 12:53:29 +0300 Subject: [PATCH 55/64] comment; --- src/main/scala/sigmastate/eval/CostingDataContext.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/scala/sigmastate/eval/CostingDataContext.scala b/src/main/scala/sigmastate/eval/CostingDataContext.scala index bb7d15b661..e70f1519ab 100644 --- a/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -430,8 +430,10 @@ case class CHeader( } object CHeader { - val VotesSize = 3 - val NonceSize = 8 + // size of Header.votes array + val VotesSize: Int = 3 + // size of Header.powNonce array (nonce from Autolykos PoW solution) + val NonceSize: Int = 8 } class CCostModel extends CostModel { From 8c8b56a0e458dbe33fdf312a82ff7ddfdd7c6834 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 15 Aug 2019 11:23:19 +0300 Subject: [PATCH 56/64] rename ErgoConstants to SigmaConstants; --- src/main/scala/org/ergoplatform/ErgoBox.scala | 6 +++--- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 2 +- .../{ErgoConstants.scala => SigmaConstants.scala} | 2 +- .../scala/org/ergoplatform/validation/ValidationRules.scala | 2 +- src/main/scala/sigmastate/eval/CostingRules.scala | 6 +++--- src/main/scala/sigmastate/eval/RuntimeCosting.scala | 2 +- src/main/scala/sigmastate/eval/Sized.scala | 2 +- .../scala/sigmastate/serialization/SigmaSerializer.scala | 6 +++--- src/main/scala/sigmastate/trees.scala | 4 ++-- src/main/scala/sigmastate/types.scala | 6 +++--- src/main/scala/sigmastate/utxo/CostTable.scala | 4 ++-- src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala | 2 +- src/test/scala/sigmastate/CostingSpecification.scala | 2 +- .../scala/sigmastate/helpers/ErgoLikeContextTesting.scala | 2 +- src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala | 2 +- .../serialization/generators/ObjectGenerators.scala | 2 +- src/test/scala/special/sigma/SigmaDslTest.scala | 2 +- src/test/scala/special/sigma/SigmaTestingData.scala | 2 +- 18 files changed, 28 insertions(+), 28 deletions(-) rename src/main/scala/org/ergoplatform/{ErgoConstants.scala => SigmaConstants.scala} (99%) diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/src/main/scala/org/ergoplatform/ErgoBox.scala index 2dc508a564..0ab065f61c 100644 --- a/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -100,7 +100,7 @@ object ErgoBox { val size: Short = 32 } - val MaxBoxSize: Int = ErgoConstants.MaxBoxSize.value + val MaxBoxSize: Int = SigmaConstants.MaxBoxSize.value val STokenType = STuple(SByteArray, SLong) val STokensRegType = SCollection(STokenType) @@ -134,9 +134,9 @@ object ErgoBox { val TokensRegId: MandatoryRegisterId = R2 val ReferenceRegId: MandatoryRegisterId = R3 - val MaxTokens: Int = ErgoConstants.MaxTokens.value + val MaxTokens: Int = SigmaConstants.MaxTokens.value - val maxRegisters: Int = ErgoConstants.MaxRegisters.value + val maxRegisters: Int = SigmaConstants.MaxRegisters.value /** @hotspot don't beautify the code in this companion */ private val _mandatoryRegisters: Array[MandatoryRegisterId] = Array(R0, R1, R2, R3) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 794c572ce6..e42d5dc862 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -189,7 +189,7 @@ object ErgoLikeContext { type Height = Int /** Maximimum number of headers in `headers` collection of the context. */ - val MaxHeaders = ErgoConstants.MaxHeaders.value + val MaxHeaders = SigmaConstants.MaxHeaders.value } /** When interpreted evaluates to a ByteArrayConstant built from Context.minerPubkey */ diff --git a/src/main/scala/org/ergoplatform/ErgoConstants.scala b/src/main/scala/org/ergoplatform/SigmaConstants.scala similarity index 99% rename from src/main/scala/org/ergoplatform/ErgoConstants.scala rename to src/main/scala/org/ergoplatform/SigmaConstants.scala index aff3c56ce9..d5b6f4ab1e 100644 --- a/src/main/scala/org/ergoplatform/ErgoConstants.scala +++ b/src/main/scala/org/ergoplatform/SigmaConstants.scala @@ -14,7 +14,7 @@ case class SizeConstant[T: Numeric](value: T, id: Short, description: String) * but due to versioned execution, all versions of the values should be * available simultaneously. */ -object ErgoConstants { +object SigmaConstants { object MaxBoxSize extends SizeConstant[Int](4 * 1024, 1, "Box size should not be greater than provided value") { diff --git a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index 3466c28433..deb793a81e 100644 --- a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -3,7 +3,7 @@ package org.ergoplatform.validation import java.nio.ByteBuffer import java.util -import org.ergoplatform.ErgoConstants.MaxLoopLevelInCostFunction +import org.ergoplatform.SigmaConstants.MaxLoopLevelInCostFunction import scorex.util.ByteArrayBuilder import scorex.util.serialization.{VLQByteBufferReader, VLQByteBufferWriter} import sigma.util.Extensions.toUByte diff --git a/src/main/scala/sigmastate/eval/CostingRules.scala b/src/main/scala/sigmastate/eval/CostingRules.scala index a38d8176b8..3df3c9f14f 100644 --- a/src/main/scala/sigmastate/eval/CostingRules.scala +++ b/src/main/scala/sigmastate/eval/CostingRules.scala @@ -1,7 +1,7 @@ package sigmastate.eval -import org.ergoplatform.ErgoConstants.{MaxBoxSize, MaxBoxSizeWithoutRefs, MaxPropositionBytes} -import org.ergoplatform.{ErgoLikeContext, ErgoConstants} +import org.ergoplatform.SigmaConstants.{MaxBoxSize, MaxBoxSizeWithoutRefs, MaxPropositionBytes} +import org.ergoplatform.{ErgoLikeContext, SigmaConstants} import scalan.{SigmaLibrary, MutableLazy} import sigmastate._ import sigmastate.interpreter.CryptoConstants @@ -166,7 +166,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => val HeadersInfo = new KnownCollInfo(ErgoLikeContext.MaxHeaders, costedBuilder.mkSizePrim(Sized.SizeHeader.dataSize, element[Header])) - val TokensInfo = new KnownCollInfo(ErgoConstants.MaxTokens.value, + val TokensInfo = new KnownCollInfo(SigmaConstants.MaxTokens.value, mkSizePair(HashInfo.size, SizeLong)) diff --git a/src/main/scala/sigmastate/eval/RuntimeCosting.scala b/src/main/scala/sigmastate/eval/RuntimeCosting.scala index 88f064bf1f..2d87f8d821 100644 --- a/src/main/scala/sigmastate/eval/RuntimeCosting.scala +++ b/src/main/scala/sigmastate/eval/RuntimeCosting.scala @@ -17,7 +17,7 @@ import sigmastate.utxo.CostTable.Cost import sigmastate.utxo._ import scalan.compilation.GraphVizConfig import SType._ -import org.ergoplatform.ErgoConstants._ +import org.ergoplatform.SigmaConstants._ import scalan.RType._ import scorex.crypto.hash.{Sha256, Blake2b256} import sigmastate.interpreter.Interpreter.ScriptEnv diff --git a/src/main/scala/sigmastate/eval/Sized.scala b/src/main/scala/sigmastate/eval/Sized.scala index c752747b15..5c006383d6 100644 --- a/src/main/scala/sigmastate/eval/Sized.scala +++ b/src/main/scala/sigmastate/eval/Sized.scala @@ -6,7 +6,7 @@ import scalan.RType._ import sigmastate._ import special.sigma._ import SType.AnyOps -import org.ergoplatform.ErgoConstants.{MaxBoxSize, MaxTokens} +import org.ergoplatform.SigmaConstants.{MaxBoxSize, MaxTokens} import sigmastate.interpreter.CryptoConstants /** Type-class to give types a capability to build a Size structure. */ diff --git a/src/main/scala/sigmastate/serialization/SigmaSerializer.scala b/src/main/scala/sigmastate/serialization/SigmaSerializer.scala index fc6e0c4b56..e9b306be84 100644 --- a/src/main/scala/sigmastate/serialization/SigmaSerializer.scala +++ b/src/main/scala/sigmastate/serialization/SigmaSerializer.scala @@ -2,7 +2,7 @@ package sigmastate.serialization import java.nio.ByteBuffer -import org.ergoplatform.ErgoConstants +import org.ergoplatform.SigmaConstants import org.ergoplatform.validation.SigmaValidationSettings import scorex.util.ByteArrayBuilder import sigmastate.lang.exceptions.SerializerException @@ -14,8 +14,8 @@ object SigmaSerializer { type Position = Int type Consumed = Int - val MaxPropositionSize: Int = ErgoConstants.MaxPropositionBytes.value - val MaxTreeDepth: Int = ErgoConstants.MaxTreeDepth.value + val MaxPropositionSize: Int = SigmaConstants.MaxPropositionBytes.value + val MaxTreeDepth: Int = SigmaConstants.MaxTreeDepth.value /** Helper function to be use in serializers. * Starting position is marked and then used to compute number of consumed bytes. diff --git a/src/main/scala/sigmastate/trees.scala b/src/main/scala/sigmastate/trees.scala index 6d7407f5b3..cbf2405069 100644 --- a/src/main/scala/sigmastate/trees.scala +++ b/src/main/scala/sigmastate/trees.scala @@ -1,6 +1,6 @@ package sigmastate -import org.ergoplatform.ErgoConstants +import org.ergoplatform.SigmaConstants import org.ergoplatform.validation.SigmaValidationSettings import scorex.crypto.hash.{Sha256, Blake2b256, CryptographicHash32} import sigmastate.Operations._ @@ -269,7 +269,7 @@ case class AtLeast(bound: Value[SInt.type], input: Value[SCollection[SSigmaProp. object AtLeast extends ValueCompanion { override def opCode: OpCode = AtLeastCode - val MaxChildrenCount: Int = ErgoConstants.MaxChildrenCountForAtLeastOp.value + val MaxChildrenCount: Int = SigmaConstants.MaxChildrenCountForAtLeastOp.value def apply(bound: Value[SInt.type], children: Seq[SigmaPropValue]): AtLeast = AtLeast(bound, ConcreteCollection(children.toIndexedSeq)) diff --git a/src/main/scala/sigmastate/types.scala b/src/main/scala/sigmastate/types.scala index 8a35f39011..b2d8f8af22 100644 --- a/src/main/scala/sigmastate/types.scala +++ b/src/main/scala/sigmastate/types.scala @@ -646,7 +646,7 @@ case object SBigInt extends SPrimType with SEmbeddable with SNumericType with SM val RelationOpType = SFunc(Vector(SBigInt, SBigInt), SBoolean) /** The maximum size of BigInteger value in byte array representation. */ - val MaxSizeInBytes: Long = ErgoConstants.MaxBigIntSizeInBytes.value + val MaxSizeInBytes: Long = SigmaConstants.MaxBigIntSizeInBytes.value override def dataSize(v: SType#WrappedType): Long = MaxSizeInBytes @@ -748,7 +748,7 @@ case object SSigmaProp extends SProduct with SPrimType with SEmbeddable with SLo override def mkConstant(v: SigmaProp): Value[SSigmaProp.type] = SigmaPropConstant(v) /** The maximum size of SigmaProp value in serialized byte array representation. */ - val MaxSizeInBytes: Long = ErgoConstants.MaxSigmaPropSizeInBytes.value + val MaxSizeInBytes: Long = SigmaConstants.MaxSigmaPropSizeInBytes.value override def dataSize(v: SType#WrappedType): Long = MaxSizeInBytes @@ -1265,7 +1265,7 @@ object STuple extends STypeCompanion { def methods: Seq[SMethod] = sys.error(s"Shouldn't be called.") def apply(items: SType*): STuple = STuple(items.toIndexedSeq) - val MaxTupleLength: Int = ErgoConstants.MaxTupleLength.value + val MaxTupleLength: Int = SigmaConstants.MaxTupleLength.value private val componentNames = Array.tabulate(MaxTupleLength){ i => s"_${i + 1}" } def componentNameByIndex(i: Int): String = try componentNames(i) diff --git a/src/main/scala/sigmastate/utxo/CostTable.scala b/src/main/scala/sigmastate/utxo/CostTable.scala index 2eb8ac5e75..35857c29fc 100644 --- a/src/main/scala/sigmastate/utxo/CostTable.scala +++ b/src/main/scala/sigmastate/utxo/CostTable.scala @@ -1,6 +1,6 @@ package sigmastate.utxo -import org.ergoplatform.ErgoConstants +import org.ergoplatform.SigmaConstants import sigmastate.{Downcast, Upcast} import sigmastate.lang.SigmaParser import sigmastate.lang.Terms.OperationId @@ -305,7 +305,7 @@ object CostTable { } //Maximum cost of a script - val ScriptLimit = ErgoConstants.ScriptCostLimit.value + val ScriptLimit = SigmaConstants.ScriptCostLimit.value //Maximum number of expressions in initial(non-reduced script) val MaxExpressions = 300 diff --git a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index 290a97d919..556e6b5069 100644 --- a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -7,7 +7,7 @@ import sigmastate.interpreter.{ContextExtension, CostedProverResult, ProverResul import scala.collection.mutable.ArrayBuffer import org.ergoplatform.ErgoBox.NonMandatoryRegisterId -import org.ergoplatform.ErgoConstants.ScriptCostLimit +import org.ergoplatform.SigmaConstants.ScriptCostLimit import scalan.Nullable import scorex.crypto.hash.Digest32 diff --git a/src/test/scala/sigmastate/CostingSpecification.scala b/src/test/scala/sigmastate/CostingSpecification.scala index fa168d30d3..0b2667c28b 100644 --- a/src/test/scala/sigmastate/CostingSpecification.scala +++ b/src/test/scala/sigmastate/CostingSpecification.scala @@ -1,6 +1,6 @@ package sigmastate -import org.ergoplatform.ErgoConstants.ScriptCostLimit +import org.ergoplatform.SigmaConstants.ScriptCostLimit import org.ergoplatform.ErgoScriptPredef.TrueProp import org.ergoplatform.validation.ValidationRules import org.ergoplatform.{ErgoBox, ErgoLikeContext, ErgoLikeTransaction} diff --git a/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala b/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala index f3e9fd7fa0..dcdafbf166 100644 --- a/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala +++ b/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala @@ -1,6 +1,6 @@ package sigmastate.helpers -import org.ergoplatform.ErgoConstants.ScriptCostLimit +import org.ergoplatform.SigmaConstants.ScriptCostLimit import org.ergoplatform.ErgoLikeContext.Height import org.ergoplatform.{ErgoBox, ErgoBoxReader, ErgoLikeContext, ErgoLikeTransaction, ErgoLikeTransactionTemplate, UnsignedInput} import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} diff --git a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala b/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala index 263c02fc3f..5d93c51210 100644 --- a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala +++ b/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala @@ -2,7 +2,7 @@ package sigmastate.helpers import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix import org.ergoplatform.ErgoBox.NonMandatoryRegisterId -import org.ergoplatform.ErgoConstants.ScriptCostLimit +import org.ergoplatform.SigmaConstants.ScriptCostLimit import org.ergoplatform.ErgoLikeContext.Height import org.ergoplatform.ErgoScriptPredef.TrueProp import org.ergoplatform._ diff --git a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 561f8bdde1..9943bf0486 100644 --- a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -1,7 +1,7 @@ package sigmastate.serialization.generators import org.ergoplatform.ErgoBox._ -import org.ergoplatform.ErgoConstants.MaxPropositionBytes +import org.ergoplatform.SigmaConstants.MaxPropositionBytes import org.ergoplatform.ErgoScriptPredef.{FalseProp, TrueProp} import org.ergoplatform.validation._ import org.ergoplatform._ diff --git a/src/test/scala/special/sigma/SigmaDslTest.scala b/src/test/scala/special/sigma/SigmaDslTest.scala index 1b6a555751..2f0b7b0fc3 100644 --- a/src/test/scala/special/sigma/SigmaDslTest.scala +++ b/src/test/scala/special/sigma/SigmaDslTest.scala @@ -425,7 +425,7 @@ class SigmaDslTest extends PropSpec byteArrayToBigInt(x) } forAll { x: Array[Byte] => - whenever(x.length <= ErgoConstants.MaxBigIntSizeInBytes.value) { + whenever(x.length <= SigmaConstants.MaxBigIntSizeInBytes.value) { eq(Builder.DefaultCollBuilder.fromArray(x)) } } diff --git a/src/test/scala/special/sigma/SigmaTestingData.scala b/src/test/scala/special/sigma/SigmaTestingData.scala index 25f1668efc..6eab01e559 100644 --- a/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/src/test/scala/special/sigma/SigmaTestingData.scala @@ -1,6 +1,6 @@ package special.sigma -import org.ergoplatform.ErgoConstants.ScriptCostLimit +import org.ergoplatform.SigmaConstants.ScriptCostLimit import org.ergoplatform.validation.ValidationRules import sigmastate.interpreter.ContextExtension import org.scalacheck.Gen.containerOfN From cbf1b384139aa30a554e8b103d93a1092da0991d Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 15 Aug 2019 11:30:44 +0300 Subject: [PATCH 57/64] add SigmaConstants.VotesArraySize and AutolykosPoWSolutionNonceArraySize; --- .../org/ergoplatform/SigmaConstants.scala | 12 ++++++++++- .../sigmastate/eval/CostingDataContext.scala | 21 +++++++++---------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/main/scala/org/ergoplatform/SigmaConstants.scala b/src/main/scala/org/ergoplatform/SigmaConstants.scala index d5b6f4ab1e..5f3c86adc5 100644 --- a/src/main/scala/org/ergoplatform/SigmaConstants.scala +++ b/src/main/scala/org/ergoplatform/SigmaConstants.scala @@ -68,6 +68,14 @@ object SigmaConstants { "Maximum allowed loop level in a cost function") { } + object VotesArraySize extends SizeConstant[Int](3, 14, + "Size of of Header.votes array") { + } + + object AutolykosPowSolutionNonceArraySize extends SizeConstant[Int](8, 15, + "size of nonce array from Autolykos POW solution in Header.powNonce array") { + } + val ConstTable: Seq[SizeConstant[_]] = { val rows = Seq( MaxBoxSize, @@ -82,7 +90,9 @@ object SigmaConstants { MaxHeaders, MaxChildrenCountForAtLeastOp, ScriptCostLimit, - MaxLoopLevelInCostFunction + MaxLoopLevelInCostFunction, + VotesArraySize, + AutolykosPowSolutionNonceArraySize ) require(rows.length == rows.distinctBy(_.id).length, s"Duplicate constant id in $rows") rows diff --git a/src/main/scala/sigmastate/eval/CostingDataContext.scala b/src/main/scala/sigmastate/eval/CostingDataContext.scala index e70f1519ab..ab7156a562 100644 --- a/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -4,27 +4,28 @@ import java.math.BigInteger import java.util import org.bouncycastle.math.ec.ECPoint -import org.ergoplatform.ErgoBox +import org.ergoplatform.{ErgoBox, SigmaConstants} import org.ergoplatform.validation.ValidationRules import scorex.crypto.authds.avltree.batch._ -import scorex.crypto.authds.{ADDigest, ADKey, SerializedAdProof, ADValue} +import scorex.crypto.authds.{ADDigest, ADKey, ADValue, SerializedAdProof} import sigmastate.SCollection.SByteArray import sigmastate.{TrivialProp, _} -import sigmastate.Values.{Constant, EvaluatedValue, SValue, ConstantNode, Value, ErgoTree, SigmaBoolean} +import sigmastate.Values.{Constant, ConstantNode, ErgoTree, EvaluatedValue, SValue, SigmaBoolean, Value} import sigmastate.interpreter.CryptoConstants.EcPointType import sigmastate.interpreter.{CryptoConstants, Interpreter} -import special.collection.{Size, CSizeOption, SizeColl, CCostedBuilder, CollType, SizeOption, CostedBuilder, Coll} +import special.collection.{CCostedBuilder, CSizeOption, Coll, CollType, CostedBuilder, Size, SizeColl, SizeOption} import special.sigma.{Box, _} import sigmastate.eval.Extensions._ import spire.syntax.all.cfor -import scala.util.{Success, Failure} + +import scala.util.{Failure, Success} import scalan.RType -import scorex.crypto.hash.{Digest32, Sha256, Blake2b256} +import scorex.crypto.hash.{Blake2b256, Digest32, Sha256} import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.ProveDHTuple import sigmastate.lang.Terms.OperationId import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer -import sigmastate.serialization.{SigmaSerializer, GroupElementSerializer} +import sigmastate.serialization.{GroupElementSerializer, SigmaSerializer} import special.Types.TupleType import scala.reflect.ClassTag @@ -430,10 +431,8 @@ case class CHeader( } object CHeader { - // size of Header.votes array - val VotesSize: Int = 3 - // size of Header.powNonce array (nonce from Autolykos PoW solution) - val NonceSize: Int = 8 + val VotesSize: Int = SigmaConstants.VotesArraySize.value + val NonceSize: Int = SigmaConstants.AutolykosPowSolutionNonceArraySize.value } class CCostModel extends CostModel { From 79b305a98fd9635cbd874ff669924fd0d2ab24b5 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 15 Aug 2019 11:36:31 +0300 Subject: [PATCH 58/64] use deepHash for arrays; --- src/main/scala/org/ergoplatform/Input.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/org/ergoplatform/Input.scala b/src/main/scala/org/ergoplatform/Input.scala index e8b240bb20..d8bd8c6d1d 100644 --- a/src/main/scala/org/ergoplatform/Input.scala +++ b/src/main/scala/org/ergoplatform/Input.scala @@ -7,7 +7,7 @@ import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.ADKey import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.serialization.SigmaSerializer -import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} +import sigmastate.utils.{Helpers, SigmaByteReader, SigmaByteWriter} /** * Inputs, that are used to enrich script context, but won't be spent by the transaction @@ -22,7 +22,7 @@ case class DataInput(boxId: BoxId) { case _ => false } - override def hashCode(): Int = boxId.hashCode + override def hashCode(): Int = Helpers.deepHashCode(boxId) } /** @@ -43,7 +43,7 @@ class UnsignedInput(val boxId: BoxId, val extension: ContextExtension) { case _ => false } - override def hashCode(): Int = boxId.hashCode + override def hashCode(): Int = Helpers.deepHashCode(boxId) /** * Input, that should be signed by prover and verified by verifier. From f885554da1bb030a0f157f13b3cdd010eae14e96 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Thu, 15 Aug 2019 11:50:18 +0300 Subject: [PATCH 59/64] remove AvlTreeData dep to AvlTree; --- src/main/scala/org/ergoplatform/JsonCodecs.scala | 2 +- src/main/scala/sigmastate/AvlTreeData.scala | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/src/main/scala/org/ergoplatform/JsonCodecs.scala index c8881d4e0e..10dd58bff8 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -103,7 +103,7 @@ trait JsonCodecs { "version" -> h.version.asJson, "parentId" -> h.parentId.asJson, "adProofsRoot" -> h.ADProofsRoot.asJson, - "stateRoot" -> AvlTreeData(h.stateRoot).asJson, + "stateRoot" -> SigmaDsl.toAvlTreeData(h.stateRoot).asJson, "transactionsRoot" -> h.transactionsRoot.asJson, "timestamp" -> h.timestamp.asJson, "nBits" -> h.nBits.asJson, diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index 557e77a84c..4e403061ef 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -82,8 +82,6 @@ object AvlTreeData { AvlTreeFlags.AllOperationsAllowed, keyLength = 32) - def apply(avlTree: AvlTree): AvlTreeData = SigmaDsl.toAvlTreeData(avlTree) - object serializer extends SigmaSerializer[AvlTreeData, AvlTreeData] { override def serialize(data: AvlTreeData, w: SigmaByteWriter): Unit = { From 03dacbfcba79665f7bd99897d3db20bb70bef21b Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 19 Aug 2019 09:41:00 +0300 Subject: [PATCH 60/64] format comment; --- .../org/ergoplatform/ErgoLikeContext.scala | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index e42d5dc862..ad2cec71b3 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -20,18 +20,18 @@ import spire.syntax.all.cfor /** * TODO lastBlockUtxoRoot should be calculated from headers if it is nonEmpty * - * @param selfIndex - index of the box in `boxesToSpend` that contains the script we're evaluating - * @param lastBlockUtxoRoot - state root before current block application - * @param headers - fixed number of last block headers in descending order (first header is the newest one) - * @param preHeader - fields of block header with the current `spendingTransaction`, that can be predicted - * by a miner before it's formation - * @param dataBoxes - boxes, that corresponds to id's of `spendingTransaction.dataInputs` - * @param boxesToSpend - boxes, that corresponds to id's of `spendingTransaction.inputs` + * @param selfIndex - index of the box in `boxesToSpend` that contains the script we're evaluating + * @param lastBlockUtxoRoot - state root before current block application + * @param headers - fixed number of last block headers in descending order (first header is the newest one) + * @param preHeader - fields of block header with the current `spendingTransaction`, that can be predicted + * by a miner before it's formation + * @param dataBoxes - boxes, that corresponds to id's of `spendingTransaction.dataInputs` + * @param boxesToSpend - boxes, that corresponds to id's of `spendingTransaction.inputs` * @param spendingTransaction - transaction that contains `self` box - * @param extension - prover-defined key-value pairs, that may be used inside a script + * @param extension - prover-defined key-value pairs, that may be used inside a script * @param validationSettings validataion parameters passed to Interpreter.verify to detect soft-fork conditions - * @param costLimit hard limit on accumulated execution cost, if exceeded lead to CostLimitException to be thrown - * @param initCost initial value of execution cost already accumulated before Interpreter.verify is called + * @param costLimit hard limit on accumulated execution cost, if exceeded lead to CostLimitException to be thrown + * @param initCost initial value of execution cost already accumulated before Interpreter.verify is called */ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val headers: Coll[Header], From baa62e02ab6ffd50c0a8d51f5f9d968ddcc42ad2 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 19 Aug 2019 15:01:02 +0300 Subject: [PATCH 61/64] trigger CI build; --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index ad2cec71b3..11d59f219c 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -153,8 +153,6 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, } - def canEqual(other: Any): Boolean = other.isInstanceOf[ErgoLikeContext] - override def equals(other: Any): Boolean = other match { case that: ErgoLikeContext => (that canEqual this) && @@ -172,6 +170,8 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, case _ => false } + def canEqual(other: Any): Boolean = other.isInstanceOf[ErgoLikeContext] + override def hashCode(): Int = { val state = Array(lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) var hashCode = 0 From 9fbb6b05fa62194a73e93f8e52beefef4c945063 Mon Sep 17 00:00:00 2001 From: Alex Chepurnoy Date: Wed, 21 Aug 2019 17:42:00 +0300 Subject: [PATCH 62/64] unused imports and vals --- src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala | 4 +--- src/main/scala/sigmastate/AvlTreeData.scala | 2 -- src/main/scala/sigmastate/interpreter/CryptoFunctions.scala | 1 - src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala | 1 - 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala b/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala index 36e311c86d..624e713654 100644 --- a/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala +++ b/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala @@ -1,8 +1,6 @@ package org.ergoplatform.settings -import scorex.crypto.authds.LeafData -import scorex.crypto.authds.merkle.MerkleTree -import scorex.crypto.hash.{Blake2b256, Digest32} +import scorex.crypto.hash.Blake2b256 import scorex.util._ import special.collection.Coll diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/src/main/scala/sigmastate/AvlTreeData.scala index 4e403061ef..87adf2fb2a 100644 --- a/src/main/scala/sigmastate/AvlTreeData.scala +++ b/src/main/scala/sigmastate/AvlTreeData.scala @@ -4,11 +4,9 @@ import java.util import java.util.{Arrays, Objects} import scorex.crypto.authds.ADDigest -import sigmastate.eval.SigmaDsl import sigmastate.interpreter.CryptoConstants import sigmastate.serialization.SigmaSerializer import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} -import special.sigma.AvlTree case class AvlTreeFlags(insertAllowed: Boolean, updateAllowed: Boolean, removeAllowed: Boolean) { diff --git a/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala b/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala index db04394754..008048605c 100644 --- a/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala +++ b/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala @@ -1,6 +1,5 @@ package sigmastate.interpreter -import org.bouncycastle.math.ec.ECPoint import scorex.crypto.hash.Blake2b256 object CryptoFunctions { diff --git a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index 556e6b5069..7041058a58 100644 --- a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -77,7 +77,6 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC case class TestInputBox(tx: TransactionCandidate, utxoBox: OutBox) extends InputBox { private [dsl] def toErgoContext: ErgoLikeContext = { - val propSpec = utxoBox.propSpec val boxesToSpend = tx.inputs.map(_.utxoBox.ergoBox).toIndexedSeq val dataBoxes = tx.dataInputs.map(_.utxoBox.ergoBox).toIndexedSeq val ctx = ErgoLikeContextTesting( From db1895ef9f543909d3264ccc159c9a7ff21cdb05 Mon Sep 17 00:00:00 2001 From: Alex Chepurnoy Date: Thu, 22 Aug 2019 00:39:55 +0300 Subject: [PATCH 63/64] unused import in ErgoLikeContext --- src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 11d59f219c..bacbfa7312 100644 --- a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -2,7 +2,6 @@ package org.ergoplatform import java.util -import org.ergoplatform.ErgoLikeContext.Height import org.ergoplatform.validation.SigmaValidationSettings import sigmastate.SType._ import sigmastate.Values._ @@ -14,7 +13,7 @@ import sigmastate.serialization.OpCodes import sigmastate.serialization.OpCodes.OpCode import special.collection.Coll import special.sigma -import special.sigma.{AnyValue, Box, GroupElement, Header, PreHeader} +import special.sigma.{AnyValue, Header, PreHeader} import spire.syntax.all.cfor /** From 9d9e54f5a4a33c5ccf1762a9b79de9610cd7e0ad Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Fri, 23 Aug 2019 15:11:32 +0300 Subject: [PATCH 64/64] set spam test branch to master; --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 5d34a2d6ff..821f27969f 100644 --- a/build.sbt +++ b/build.sbt @@ -262,7 +262,7 @@ commands += Command.command("ergoItTest") { state => } def runSpamTestTask(task: String, sigmastateVersion: String, log: Logger): Unit = { - val spamBranch = "i4-add-input-hash" + val spamBranch = "master" val envVars = Seq("SIGMASTATE_VERSION" -> sigmastateVersion, "SPECIAL_VERSION" -> specialVersion, // SSH_SPAM_REPO_KEY should be set (see Jenkins Credentials Binding Plugin)