diff --git a/build.sbt b/build.sbt index ecda37a558..4b442315e9 100644 --- a/build.sbt +++ b/build.sbt @@ -18,8 +18,8 @@ lazy val commonSettings = Seq( // without the tag version resolves to [branch name]-[git commit hash]-SNAPSHOT // don't set the version manually resolvers ++= Seq("Sonatype Releases" at "https://oss.sonatype.org/content/repositories/releases/", - "Bintray" at "https://jcenter.bintray.com/", //for org.ethereum % leveldbjni-all "SonaType" at "https://oss.sonatype.org/content/groups/public", + "Repo for leveldbjni-all" at "https://gitlab.com/api/v4/projects/61211221/packages/maven", "Typesafe maven releases" at "https://dl.bintray.com/typesafe/maven-releases/", "Sonatype Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/"), homepage := Some(url("http://ergoplatform.org/")), @@ -33,11 +33,13 @@ lazy val commonSettings = Seq( ), ) +publishArtifact in (Compile, packageDoc) := false + val circeVersion = "0.13.0" val akkaVersion = "2.6.10" val akkaHttpVersion = "10.2.4" -val sigmaStateVersion = "5.0.13" +val sigmaStateVersion = "5.0.14-518-ca2df921-SNAPSHOT" val ficusVersion = "1.4.7" // for testing current sigmastate build (see sigmastate-ergo-it jenkins job) diff --git a/ergo-core/src/main/scala/org/ergoplatform/http/api/ApiCodecs.scala b/ergo-core/src/main/scala/org/ergoplatform/http/api/ApiCodecs.scala index 1b6c9b2214..d28f6f2418 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/http/api/ApiCodecs.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/http/api/ApiCodecs.scala @@ -1,6 +1,8 @@ package org.ergoplatform.http.api import cats.syntax.either._ +import sigmastate.utils.Helpers._ + import io.circe._ import io.circe.syntax._ import org.bouncycastle.util.BigIntegers @@ -14,24 +16,22 @@ import org.ergoplatform.sdk.wallet.secrets.{DhtSecretKey, DlogSecretKey} import org.ergoplatform.settings.{Algos, ErgoAlgos} import org.ergoplatform.wallet.Constants.ScanId import org.ergoplatform.wallet.boxes.TrackedBox -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.interpreter.TransactionHintsBag import org.ergoplatform.validation.ValidationResult import scorex.crypto.authds.merkle.MerkleProof import scorex.crypto.authds.{LeafData, Side} import scorex.crypto.hash.Digest import scorex.util.encode.Base16 -import sigmastate.Values.SigmaBoolean import sigmastate._ -import sigmastate.crypto.CryptoConstants.EcPointType -import sigmastate.crypto.DLogProtocol.{DLogProverInput, FirstDLogProverMessage, ProveDlog} +import sigmastate.crypto.DLogProtocol.{DLogProverInput, FirstDLogProverMessage} import sigmastate.crypto.VerifierMessage.Challenge import sigmastate.crypto._ import sigmastate.interpreter._ -import sigmastate.serialization.OpCodes -import org.ergoplatform.sdk.JsonCodecs -import sigmastate.eval.Extensions.ArrayOps -import sigmastate.utils.Helpers._ +import org.ergoplatform.sdk.{JsonCodecs, SecretString} +import sigma.crypto.EcPointType +import sigma.data._ +import sigma.serialization.{OpCodes, SigSerializer} +import sigma.Extensions.ArrayOps import java.math.BigInteger import scala.annotation.nowarn @@ -129,7 +129,7 @@ trait ApiCodecs extends JsonCodecs { }) implicit val secretBigIntEncoder: Encoder[BigInteger] = Encoder.instance { w => - ErgoAlgos.encode(BigIntegers.asUnsignedByteArray(CryptoConstants.groupSize, w)).asJson + ErgoAlgos.encode(BigIntegers.asUnsignedByteArray(sigma.crypto.groupSize, w)).asJson } implicit val secretBigIntDecoder: Decoder[BigInteger] = arrayBytesDecoder.map { bytes => diff --git a/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosPowScheme.scala b/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosPowScheme.scala index 5dd710da26..3b50158cc8 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosPowScheme.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosPowScheme.scala @@ -15,8 +15,8 @@ import org.ergoplatform.nodeView.mempool.TransactionMembershipProof import scorex.crypto.authds.{ADDigest, SerializedAdProof} import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util.{ModifierId, ScorexLogging} -import sigmastate.crypto.DLogProtocol.ProveDlog -import sigmastate.crypto.CryptoFacade +import sigma.crypto.CryptoFacade +import sigma.data.ProveDlog import scala.annotation.tailrec import scala.util.Try diff --git a/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosSolution.scala b/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosSolution.scala index cf745e685b..98849027d1 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosSolution.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosSolution.scala @@ -2,6 +2,7 @@ package org.ergoplatform.mining import cats.syntax.either._ import sigmastate.utils.Helpers._ + import io.circe.syntax._ import io.circe.{Decoder, Encoder, HCursor} import org.bouncycastle.util.BigIntegers @@ -10,8 +11,7 @@ import org.ergoplatform.modifiers.history.header.Header.Version import org.ergoplatform.settings.Algos import org.ergoplatform.serialization.ErgoSerializer import scorex.util.serialization.{Reader, Writer} -import sigmastate.crypto.CryptoConstants -import sigmastate.crypto.CryptoConstants.EcPointType +import sigma.crypto.{CryptoConstants, EcPointType} /** * Solution for an Autolykos PoW puzzle. diff --git a/ergo-core/src/main/scala/org/ergoplatform/mining/DefaultFakePowScheme.scala b/ergo-core/src/main/scala/org/ergoplatform/mining/DefaultFakePowScheme.scala index 732bf25805..b0829ee0f2 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/DefaultFakePowScheme.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/DefaultFakePowScheme.scala @@ -3,7 +3,7 @@ package org.ergoplatform.mining import org.ergoplatform.modifiers.history.header.Header import scorex.crypto.authds.ADDigest import scorex.crypto.hash.Digest32 -import sigmastate.crypto.CryptoConstants.EcPointType +import sigma.crypto.EcPointType import scala.util.{Random, Success, Try} diff --git a/ergo-core/src/main/scala/org/ergoplatform/mining/ProofOfUpcomingTransactions.scala b/ergo-core/src/main/scala/org/ergoplatform/mining/ProofOfUpcomingTransactions.scala index 1e7f87ba22..cfbff88ef2 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/ProofOfUpcomingTransactions.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/ProofOfUpcomingTransactions.scala @@ -2,6 +2,7 @@ package org.ergoplatform.mining import cats.syntax.either._ import sigmastate.utils.Helpers._ + import io.circe.{Encoder, Json} import org.ergoplatform.modifiers.history.BlockTransactions import org.ergoplatform.nodeView.mempool.TransactionMembershipProof diff --git a/ergo-core/src/main/scala/org/ergoplatform/mining/WorkMessage.scala b/ergo-core/src/main/scala/org/ergoplatform/mining/WorkMessage.scala index b79ffd1d08..5262bdc852 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/WorkMessage.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/WorkMessage.scala @@ -4,7 +4,7 @@ import io.circe.syntax._ import io.circe.{Encoder, Json} import org.ergoplatform.http.api.ApiCodecs import org.ergoplatform.nodeView.history.ErgoHistoryUtils.Height -import sigmastate.crypto.DLogProtocol.ProveDlog +import sigma.data.ProveDlog /** diff --git a/ergo-core/src/main/scala/org/ergoplatform/mining/mining.scala b/ergo-core/src/main/scala/org/ergoplatform/mining/mining.scala index e469225906..fd3f59888f 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/mining.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/mining.scala @@ -2,10 +2,9 @@ package org.ergoplatform import org.bouncycastle.util.BigIntegers import scorex.crypto.hash.Blake2b256 -import sigmastate.crypto.CryptoConstants.EcPointType -import sigmastate.crypto.{BcDlogGroup, CryptoConstants} +import sigma.crypto.{BcDlogGroup, CryptoConstants, EcPointType} +import sigma.serialization.{GroupElementSerializer, SigmaSerializer} import sigmastate.crypto.DLogProtocol.DLogProverInput -import sigmastate.serialization.{GroupElementSerializer, SigmaSerializer} package object mining { diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/ErgoFullBlock.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/ErgoFullBlock.scala index f59e9cb360..d90f5375ea 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/ErgoFullBlock.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/ErgoFullBlock.scala @@ -2,6 +2,7 @@ package org.ergoplatform.modifiers import cats.syntax.either._ import sigmastate.utils.Helpers._ + import io.circe.syntax._ import io.circe.{Decoder, Encoder, HCursor, Json} import org.ergoplatform.http.api.ApiCodecs diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/ADProofs.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/ADProofs.scala index 380600129c..5c0f8b2123 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/ADProofs.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/ADProofs.scala @@ -2,6 +2,7 @@ package org.ergoplatform.modifiers.history import cats.syntax.either._ import sigmastate.utils.Helpers._ + import io.circe.syntax._ import io.circe.{Decoder, Encoder, HCursor} import org.ergoplatform.http.api.ApiCodecs diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/BlockTransactions.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/BlockTransactions.scala index e14c98a784..50d7cac553 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/BlockTransactions.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/BlockTransactions.scala @@ -18,6 +18,7 @@ import scorex.crypto.hash.Digest32 import scorex.util.serialization.{Reader, Writer} import scorex.util.{ModifierId, bytesToId, idToBytes} import scorex.util.Extensions._ +import sigma.VersionContext import scala.annotation.nowarn import scala.collection.mutable @@ -145,7 +146,9 @@ object BlockTransactionsSerializer extends ErgoSerializer[BlockTransactions] { } w.putUInt(bt.txs.size.toLong) bt.txs.foreach { tx => - ErgoTransactionSerializer.serialize(tx, w) + VersionContext.withVersions(VersionContext.V6SoftForkVersion, VersionContext.V6SoftForkVersion) { + ErgoTransactionSerializer.serialize(tx, w) + } } } @@ -170,8 +173,13 @@ object BlockTransactionsSerializer extends ErgoSerializer[BlockTransactions] { txCount = r.getUInt().toIntExact } - val txs = (1 to txCount).map { _ => - ErgoTransactionSerializer.parse(r) + val txs: IndexedSeq[ErgoTransaction] = { + val version = VersionContext.fromBlockVersion(blockVersion) + VersionContext.withVersions(version.activatedVersion, version.ergoTreeVersion) { + (1 to txCount).map { _ => + ErgoTransactionSerializer.parse(r) + } + } } BlockTransactions(headerId, blockVersion, txs, Some(r.position - startPos)) } diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/PreHeader.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/PreHeader.scala index 7710383183..3f6e8b61d2 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/PreHeader.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/PreHeader.scala @@ -6,9 +6,9 @@ import org.ergoplatform.modifiers.history.header.Header._ import org.ergoplatform.nodeView.history.ErgoHistoryUtils._ import org.ergoplatform.settings.Constants import scorex.util._ -import sigmastate.crypto.CryptoConstants.EcPointType -import sigmastate.eval.CGroupElement -import sigmastate.eval.Extensions._ +import sigma.crypto.EcPointType +import sigma.data.CGroupElement +import sigma.Extensions._ /** * Only header fields that can be predicted by a miner diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/extension/Extension.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/extension/Extension.scala index 43c3869ef8..d063b53a52 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/extension/Extension.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/extension/Extension.scala @@ -2,6 +2,7 @@ package org.ergoplatform.modifiers.history.extension import cats.syntax.either._ import sigmastate.utils.Helpers._ + import com.google.common.primitives.Bytes import io.circe.syntax._ import io.circe.{Decoder, Encoder, HCursor} diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/Header.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/Header.scala index 092dcd219f..7f5d89117e 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/Header.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/Header.scala @@ -17,9 +17,10 @@ import org.ergoplatform.serialization.ErgoSerializer import scorex.crypto.authds.ADDigest import scorex.crypto.hash.Digest32 import scorex.util._ -import sigmastate.crypto.CryptoConstants.EcPointType -import sigmastate.eval.Extensions._ -import sigmastate.eval.{CAvlTree, CBigInt, CGroupElement, CHeader} +import sigma.Colls +import sigma.Extensions._ +import sigma.crypto.EcPointType +import sigma.data.{CAvlTree, CBigInt, CGroupElement, CHeader} import scala.annotation.nowarn import scala.concurrent.duration.FiniteDuration @@ -138,14 +139,31 @@ object Header extends ApiCodecs { */ val Interpreter50Version: Byte = 3 + /** + * Block version after the 6.0 soft-fork + * 6.0 interpreter (EIP-50) + */ + val Interpreter60Version: Byte = 4 + + // todo: pass NetworkType, not String + // todo: comments + def interpreter60VersionActivationHeight(networkTypeName: String): Int = { + if(networkTypeName == "mainnet") { + ??? // todo: set + } else if(networkTypeName == "testnet") { + 1548800 // todo: set + } else { + //devnet + ??? // todo: set + } + } def toSigma(header: Header): sigma.Header = CHeader( - id = header.id.toBytes.toColl, version = header.version, parentId = header.parentId.toBytes.toColl, ADProofsRoot = header.ADProofsRoot.asInstanceOf[Array[Byte]].toColl, - stateRoot = CAvlTree(ErgoInterpreter.avlTreeFromDigest(header.stateRoot.toColl)), + stateRootDigest = header.stateRoot.toColl, transactionsRoot = header.transactionsRoot.asInstanceOf[Array[Byte]].toColl, timestamp = header.timestamp, nBits = header.nBits, @@ -155,7 +173,8 @@ object Header extends ApiCodecs { powOnetimePk = CGroupElement(header.powSolution.w), powNonce = header.powSolution.n.toColl, powDistance = CBigInt(header.powSolution.d.bigInteger), - votes = header.votes.toColl + votes = header.votes.toColl, + unparsedBytes = Colls.emptyColl[Byte] // todo: fix after merging w. 5.0.23 ) val modifierTypeId: NetworkObjectTypeId.Value = HeaderTypeId.value diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/popow/PoPowHeader.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/popow/PoPowHeader.scala index 80bcccc649..c16b318bb7 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/popow/PoPowHeader.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/popow/PoPowHeader.scala @@ -2,6 +2,7 @@ package org.ergoplatform.modifiers.history.popow import cats.syntax.either._ import sigmastate.utils.Helpers._ + import cats.Traverse import cats.implicits.{catsStdInstancesForEither, catsStdInstancesForList} import io.circe.{Decoder, Encoder, Json} diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/mempool/ErgoTransaction.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/mempool/ErgoTransaction.scala index ab5c064f53..fc0c9f4998 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/mempool/ErgoTransaction.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/mempool/ErgoTransaction.scala @@ -3,7 +3,7 @@ package org.ergoplatform.modifiers.mempool import io.circe.syntax._ import org.ergoplatform.{DataInput, ErgoBox, ErgoBoxCandidate, ErgoLikeTransaction, ErgoLikeTransactionSerializer, Input} import org.ergoplatform.ErgoBox.BoxId -import org.ergoplatform.SigmaConstants.{MaxBoxSize, MaxPropositionBytes} +import org.ergoplatform._ import org.ergoplatform.http.api.ApiCodecs import org.ergoplatform.mining.emission.EmissionRules import org.ergoplatform.modifiers.history.header.Header @@ -27,8 +27,8 @@ import org.ergoplatform.validation.{InvalidModifier, ModifierValidator, Validati import scorex.db.ByteArrayUtils import scorex.util.serialization.{Reader, Writer} import scorex.util.{ModifierId, ScorexLogging, bytesToId} -import sigmastate.serialization.ConstantStore -import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} +import sigma.data.SigmaConstants.{MaxBoxSize, MaxPropositionBytes} +import sigma.serialization.{ConstantStore, SigmaByteReader, SigmaByteWriter} import java.util import scala.annotation.nowarn @@ -490,7 +490,7 @@ object ErgoTransactionSerializer extends ErgoSerializer[ErgoTransaction] { override def serialize(tx: ErgoTransaction, w: Writer): Unit = { val elt = new ErgoLikeTransaction(tx.inputs, tx.dataInputs, tx.outputCandidates) - ErgoLikeTransactionSerializer.serialize(elt, new SigmaByteWriter(w, None)) + ErgoLikeTransactionSerializer.serialize(elt, new SigmaByteWriter(w, None, None, None)) } override def parse(r: Reader): ErgoTransaction = { diff --git a/ergo-core/src/main/scala/org/ergoplatform/nodeView/state/ErgoStateContext.scala b/ergo-core/src/main/scala/org/ergoplatform/nodeView/state/ErgoStateContext.scala index d4ac70befb..6ce96e661b 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/nodeView/state/ErgoStateContext.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/nodeView/state/ErgoStateContext.scala @@ -9,19 +9,20 @@ import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer} import org.ergoplatform.modifiers.history.popow.NipopowAlgos import org.ergoplatform.nodeView.history.ErgoHistoryUtils import org.ergoplatform.nodeView.history.storage.modifierprocessors.ExtensionValidator -import org.ergoplatform.sdk.wallet.protocol.context.BlockchainStateContext import org.ergoplatform.settings.ValidationRules._ import org.ergoplatform.settings._ import org.ergoplatform.utils.ScorexEncoding import org.ergoplatform.serialization.ErgoSerializer import org.ergoplatform.validation.{InvalidModifier, ModifierValidator, ValidationState} +import org.ergoplatform.wallet.interpreter.VersionedBlockchainStateContext import scorex.crypto.authds.ADDigest import scorex.util.ScorexLogging import scorex.util.serialization.{Reader, Writer} -import sigmastate.crypto.CryptoConstants.EcPointType -import sigmastate.eval.Extensions.ArrayOps -import sigmastate.eval.SigmaDsl import sigma.Coll +import sigma.eval.SigmaDsl +import sigma.Extensions.ArrayOps +import sigma.crypto.EcPointType +import sigma.validation.SigmaValidationSettings import scala.collection.compat.immutable.ArraySeq import scala.util.{Failure, Success, Try} @@ -38,7 +39,7 @@ case class UpcomingStateContext(override val lastHeaders: Seq[Header], override val validationSettings: ErgoValidationSettings, override val votingData: VotingData)(implicit chainSettings: ChainSettings) extends ErgoStateContext(lastHeaders, lastExtensionOpt, genesisStateDigest, currentParameters, - validationSettings, votingData)(chainSettings) { + validationSettings, votingData)(chainSettings) { override def sigmaPreHeader: sigma.PreHeader = PreHeader.toSigma(predictedHeader) @@ -68,7 +69,7 @@ class ErgoStateContext(val lastHeaders: Seq[Header], val validationSettings: ErgoValidationSettings, val votingData: VotingData) (implicit val chainSettings: ChainSettings) - extends BlockchainStateContext + extends VersionedBlockchainStateContext with BytesSerializable with ScorexEncoding with ScorexLogging { @@ -78,6 +79,8 @@ class ErgoStateContext(val lastHeaders: Seq[Header], private val votingSettings = chainSettings.voting private val popowAlgos = new NipopowAlgos(chainSettings) + override val sigmaValidationSettings: SigmaValidationSettings = validationSettings.sigmaSettings + override def sigmaPreHeader: sigma.PreHeader = PreHeader.toSigma(lastHeaders.headOption.getOrElse(PreHeader.fake)) @@ -127,7 +130,7 @@ class ErgoStateContext(val lastHeaders: Seq[Header], currentParameters.update(height, forkVote, ArraySeq.unsafeWrapArray(votingData.epochVotes), proposedUpdate, votingSettings) val calculatedValidationSettings = validationSettings.updated(updated) UpcomingStateContext(lastHeaders, lastExtensionOpt, upcomingHeader, genesisStateDigest, calculatedParams, - calculatedValidationSettings, votingData) + calculatedValidationSettings, votingData) } /** @@ -192,7 +195,7 @@ class ErgoStateContext(val lastHeaders: Seq[Header], For the latter case, the light fullnode is just relied on PoW majority about parameters and validation settings. */ - val (calculatedParams, calculatedSettings) = if (currentParameters.height == 0) { + val (calculatedParamsPre60, calculatedSettings) = if (currentParameters.height == 0) { parsedParams -> parsedSettings } else { val (params, settingsUpdates) = currentParameters @@ -201,9 +204,24 @@ class ErgoStateContext(val lastHeaders: Seq[Header], params -> settings } + // 6.0: insert number of sub-blocks per block if it is not there + val calculatedParams = if ( + header.version >= Header.Interpreter60Version && + !calculatedParamsPre60.parametersTable.contains(Parameters.SubblocksPerBlockIncrease) && + !validationState.settings.isActive(exMatchParameters) + ) { + parsedParams.parametersTable.get(Parameters.SubblocksPerBlockIncrease) match { + case Some(value) => calculatedParamsPre60.withNumOfSubblocksPerBlock(value) + case None => calculatedParamsPre60.withNumOfSubblocksPerBlock(Parameters.SubblocksPerBlockDefault) + } + } else { + calculatedParamsPre60 + } + currentValidationState .validate(exBlockVersion, calculatedParams.blockVersion == header.version, InvalidModifier(s"${calculatedParams.blockVersion} == ${header.version}", extension.id, extension.modifierTypeId)) .validateNoFailure(exMatchParameters, Parameters.matchParameters(parsedParams, calculatedParams), extension.id, extension.modifierTypeId) + .validateNoFailure(exMatchParameters60, Parameters.matchParameters60(parsedParams, calculatedParams, header.version), extension.id, extension.modifierTypeId) .validate(exMatchValidationSettings, parsedSettings == calculatedSettings, InvalidModifier(s"$parsedSettings vs $calculatedSettings", extension.id, extension.modifierTypeId)) }.result }.result @@ -280,7 +298,7 @@ class ErgoStateContext(val lastHeaders: Seq[Header], * This function verifies whether a full block is valid against the ErgoStateContext instance, and modifies * the latter according to the former. * - * @param fb - block to apply + * @param fb - block to apply * @return updated state context or error */ def appendFullBlock(fb: ErgoFullBlock): Try[ErgoStateContext] = Try { diff --git a/ergo-core/src/main/scala/org/ergoplatform/settings/Constants.scala b/ergo-core/src/main/scala/org/ergoplatform/settings/Constants.scala index 02090c6afd..d271212fa9 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/settings/Constants.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/settings/Constants.scala @@ -3,8 +3,9 @@ package org.ergoplatform.settings import org.ergoplatform.mining.difficulty.DifficultySerializer import org.ergoplatform.nodeView.history.ErgoHistoryUtils.Difficulty import scorex.crypto.authds.avltree.batch.AvlTreeParameters -import sigmastate.Values -import sigmastate.Values.ErgoTree +import sigma.ast.{ErgoTree, FalseLeaf, TrueLeaf} +import sigma.ast.ErgoTree.{HeaderType, ZeroHeader} +import sigma.ast.syntax.{FalseSigmaProp, TrueSigmaProp} object Constants { /** @@ -42,9 +43,6 @@ object Constants { val SoftForkEpochs = 32 //about 45.5 days - def TrueLeaf: ErgoTree = Values.TrueLeaf.toSigmaProp - def FalseLeaf: ErgoTree = Values.FalseLeaf.toSigmaProp - val StringEncoding = "UTF-8" // Maximum extension size @@ -59,4 +57,8 @@ object Constants { */ object StateTreeParameters extends AvlTreeParameters(keySize = HashLength, valueSize = None, labelSize = HashLength) + def FalseTree: ErgoTree = ErgoTree.fromProposition(FalseLeaf.toSigmaProp) + + def TrueTree: ErgoTree = ErgoTree.fromProposition(TrueLeaf.toSigmaProp) + } diff --git a/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettings.scala b/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettings.scala index 3961e5f159..c102a4b52f 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettings.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettings.scala @@ -4,10 +4,10 @@ import org.ergoplatform.core.BytesSerializable import org.ergoplatform.http.api.ApiCodecs import org.ergoplatform.modifiers.history.extension.{Extension, ExtensionCandidate} import org.ergoplatform.utils -import org.ergoplatform.validation.SigmaValidationSettings import org.ergoplatform.serialization.ErgoSerializer import org.ergoplatform.validation.{InvalidModifier, ModifierValidator, ValidationResult, ValidationSettings} import scorex.util.serialization.{Reader, Writer} +import sigma.validation.SigmaValidationSettings import scala.util.Try diff --git a/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettingsUpdate.scala b/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettingsUpdate.scala index a98066a696..956ea474d6 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettingsUpdate.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettingsUpdate.scala @@ -3,11 +3,10 @@ package org.ergoplatform.settings import org.ergoplatform.validation.RuleStatusSerializer import org.ergoplatform.serialization.ErgoSerializer import scorex.util.serialization.{Reader, Writer} -import sigmastate.serialization.ConstantStore -import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} +import sigma.serialization.{ConstantStore, SigmaByteReader, SigmaByteWriter} case class ErgoValidationSettingsUpdate(rulesToDisable: Seq[Short], - statusUpdates: Seq[(Short, org.ergoplatform.validation.RuleStatus)]) { + statusUpdates: Seq[(Short, sigma.validation.RuleStatus)]) { def ++(that: ErgoValidationSettingsUpdate): ErgoValidationSettingsUpdate = { val newRules = (rulesToDisable ++ that.rulesToDisable).distinct.sorted @@ -23,10 +22,10 @@ object ErgoValidationSettingsUpdate { object ErgoValidationSettingsUpdateSerializer extends ErgoSerializer[ErgoValidationSettingsUpdate] { - private val FirstRule = org.ergoplatform.validation.ValidationRules.FirstRuleId + private val FirstRule = sigma.validation.ValidationRules.FirstRuleId override def serialize(obj: ErgoValidationSettingsUpdate, w: Writer): Unit = { - val sigmaWriter = new SigmaByteWriter(w, None) + val sigmaWriter = new SigmaByteWriter(w, None, None, None) w.putUInt(obj.rulesToDisable.length.toLong) obj.rulesToDisable.foreach { r => w.putUShort(r.toInt) diff --git a/ergo-core/src/main/scala/org/ergoplatform/settings/LaunchParameters.scala b/ergo-core/src/main/scala/org/ergoplatform/settings/LaunchParameters.scala deleted file mode 100644 index 25a0763f49..0000000000 --- a/ergo-core/src/main/scala/org/ergoplatform/settings/LaunchParameters.scala +++ /dev/null @@ -1,8 +0,0 @@ -package org.ergoplatform.settings - -/** - * Parameters corresponding to initial moment of time in the mainnet and the testnet - */ -object LaunchParameters extends Parameters(height = 0, - parametersTable = Parameters.DefaultParameters, - proposedUpdate = ErgoValidationSettingsUpdate.empty) diff --git a/ergo-core/src/main/scala/org/ergoplatform/settings/MainnetLaunchParameters.scala b/ergo-core/src/main/scala/org/ergoplatform/settings/MainnetLaunchParameters.scala new file mode 100644 index 0000000000..e9e6e946b2 --- /dev/null +++ b/ergo-core/src/main/scala/org/ergoplatform/settings/MainnetLaunchParameters.scala @@ -0,0 +1,18 @@ +package org.ergoplatform.settings + +import org.ergoplatform.modifiers.history.header.Header + +/** + * Parameters corresponding to initial moment of time in the mainnet and the testnet + */ +object MainnetLaunchParameters extends Parameters(height = 0, + parametersTable = Parameters.DefaultParameters, + proposedUpdate = ErgoValidationSettingsUpdate.empty) + +object TestnetLaunchParameters extends Parameters(height = 0, + parametersTable = Parameters.DefaultParameters, + proposedUpdate = ErgoValidationSettingsUpdate.empty) + +object DevnetLaunchParameters extends Parameters(height = 0, + parametersTable = Parameters.DefaultParameters.updated(Parameters.BlockVersion, Header.Interpreter50Version), + proposedUpdate = ErgoValidationSettingsUpdate.empty) diff --git a/ergo-core/src/main/scala/org/ergoplatform/settings/Parameters.scala b/ergo-core/src/main/scala/org/ergoplatform/settings/Parameters.scala index ba590ddcad..483168c680 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/settings/Parameters.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/settings/Parameters.scala @@ -8,10 +8,11 @@ import org.ergoplatform.serialization.ErgoSerializer import scorex.util.serialization.{Reader, Writer} import scorex.util.Extensions._ -import scala.util.Try +import scala.util.{Success, Try} import org.ergoplatform.http.api.ApiCodecs import org.ergoplatform.modifiers.history.extension.{Extension, ExtensionCandidate} import Extension.SystemParametersPrefix +import org.ergoplatform.modifiers.history.header.Header import org.ergoplatform.sdk.BlockchainParameters import scala.annotation.nowarn @@ -66,6 +67,13 @@ class Parameters(val height: Height, */ lazy val maxBlockCost: Int = parametersTable(MaxBlockCostIncrease) + /** + * Max total computation cost of a block. + */ + lazy val subBlocksPerBlock: Int = parametersTable(SubblocksPerBlockIncrease) + + lazy val subBlocksPerBlockOpt: Option[Int] = parametersTable.get(SubblocksPerBlockIncrease) + lazy val softForkStartingHeight: Option[Height] = parametersTable.get(SoftForkStartingHeight) lazy val softForkVotesCollected: Option[Int] = parametersTable.get(SoftForkVotesCollected) @@ -78,7 +86,13 @@ class Parameters(val height: Height, votingSettings: VotingSettings): (Parameters, ErgoValidationSettingsUpdate) = { val (table1, activatedUpdate) = updateFork(height, parametersTable, forkVote, epochVotes, proposedUpdate, votingSettings) val table2 = updateParams(table1, epochVotes, votingSettings) - (Parameters(height, table2, proposedUpdate), activatedUpdate) + // insert sub-blocks per block parameter on next epoch after block version v4 (protocol v6) activation + val table3 = if(table2.getOrElse(BlockVersion, -1) == 4 && !table2.contains(SubblocksPerBlockIncrease) && !activatedUpdate.rulesToDisable.contains(409)) { + table2.updated(SubblocksPerBlockIncrease, SubblocksPerBlockDefault) + } else { + table2 + } + (Parameters(height, table3, proposedUpdate), activatedUpdate) } def updateFork(height: Height, @@ -126,16 +140,16 @@ class Parameters(val height: Height, if (softForkStartingHeight.nonEmpty && height == softForkStartingHeight.get + votingEpochLength * (votingEpochs + activationEpochs) && softForkApproved(votes)) { - table = table.updated(BlockVersion, table(BlockVersion) + 1) + val newVersion = table(BlockVersion) + 1 + + table = table.updated(BlockVersion, newVersion) activatedUpdate = proposedUpdate } - // Forced version update to version 2 at height provided in settings - if (height == votingSettings.version2ActivationHeight) { - // Forced update should happen, but some soft-fork update happened before. - // Node should fail at this point, as the situation is unclear - require(table(BlockVersion) == 1, "Protocol version is not 1 on the hard-fork") - table = table.updated(BlockVersion, table(BlockVersion) + 1) + // Forced version update to version 2 at height provided in settings. + // Needed as it was non-voted hard-fork in the mainnet. + if (height == votingSettings.version2ActivationHeight && table(BlockVersion) == 1) { + table = table.updated(BlockVersion, 2) } (table, activatedUpdate) } @@ -217,6 +231,10 @@ class Parameters(val height: Height, Parameters(height, parametersTable.updated(MaxBlockCostIncrease, cost), proposedUpdate) } + def withNumOfSubblocksPerBlock(subblocksPerBlock: Int): Parameters = { + Parameters(height, parametersTable.updated(SubblocksPerBlockIncrease, subblocksPerBlock), proposedUpdate) + } + override def toString: String = s"Parameters(height: $height; ${parametersTable.mkString("; ")}; $proposedUpdate)" def canEqual(o: Any): Boolean = o.isInstanceOf[Parameters] @@ -266,6 +284,14 @@ object Parameters { val OutputCostIncrease: Byte = 8 val OutputCostDecrease: Byte = (-OutputCostIncrease).toByte + // added in protocol v6.0 (block version 4.0) + val SubblocksPerBlockIncrease: Byte = 9 + val SubblocksPerBlockDecrease: Byte = (-SubblocksPerBlockIncrease).toByte + + val SubblocksPerBlockDefault: Int = 30 + val SubblocksPerBlockStep: Int = 1 + val SubblocksPerBlockMin: Int = 2 + val SubblocksPerBlockMax: Int = 2048 //0.00001 Erg val StorageFeeFactorDefault: Int = 1250000 val StorageFeeFactorMax: Int = 2500000 @@ -317,19 +343,22 @@ object Parameters { val stepsTable: Map[Byte, Int] = Map( StorageFeeFactorIncrease -> StorageFeeFactorStep, - MinValuePerByteIncrease -> MinValueStep + MinValuePerByteIncrease -> MinValueStep, + SubblocksPerBlockIncrease -> SubblocksPerBlockStep ) val minValues: Map[Byte, Int] = Map( StorageFeeFactorIncrease -> StorageFeeFactorMin, MinValuePerByteIncrease -> MinValueMin, MaxBlockSizeIncrease -> MaxBlockSizeMin, - MaxBlockCostIncrease -> 16 * 1024 + MaxBlockCostIncrease -> 16 * 1024, + SubblocksPerBlockIncrease -> SubblocksPerBlockMin ) val maxValues: Map[Byte, Int] = Map( StorageFeeFactorIncrease -> StorageFeeFactorMax, - MinValuePerByteIncrease -> MinValueMax + MinValuePerByteIncrease -> MinValueMax, + SubblocksPerBlockIncrease -> SubblocksPerBlockMax ) val ParamVotesCount = 2 @@ -383,6 +412,28 @@ object Parameters { } } + def matchParameters60(p1: Parameters, p2: Parameters, blockVersion: Header.Version): Try[Unit] = { + if (blockVersion < Header.Interpreter60Version) { + Success(Unit) + } else { + Try { + if (p1.height != p2.height) { + throw new Exception(s"Different height in parameters, p1 = $p1, p2 = $p2") + } + if (!(p1.parametersTable.size <= p2.parametersTable.size)) { // the only difference from matchParameters + throw new Exception(s"Parameters differ in size, p1 = $p1, p2 = $p2") + } + if (p1.proposedUpdate != p2.proposedUpdate) { + throw new Exception(s"Parameters proposedUpdate differs, p1 = ${p1.proposedUpdate}, p2 = ${p2.proposedUpdate}") + } + p1.parametersTable.foreach { case (k, v) => + val v2 = p2.parametersTable(k) + if (v2 != v) throw new Exception(s"Calculated and received parameters differ in parameter $k ($v != $v2)") + } + } + } + } + } object ParametersSerializer extends ErgoSerializer[Parameters] with ApiCodecs { @@ -420,7 +471,8 @@ object ParametersSerializer extends ErgoSerializer[Parameters] with ApiCodecs { "tokenAccessCost" -> p.tokenAccessCost.asJson, "inputCost" -> p.inputCost.asJson, "dataInputCost" -> p.dataInputCost.asJson, - "outputCost" -> p.outputCost.asJson + "outputCost" -> p.outputCost.asJson, + "subblocksPerBlock" -> p.subBlocksPerBlockOpt.asJson ).asJson } diff --git a/ergo-core/src/main/scala/org/ergoplatform/settings/ValidationRules.scala b/ergo-core/src/main/scala/org/ergoplatform/settings/ValidationRules.scala index 96029c0994..fb4d5aa0b8 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/settings/ValidationRules.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/settings/ValidationRules.scala @@ -1,6 +1,5 @@ package org.ergoplatform.settings -import org.ergoplatform.SigmaConstants.{MaxBoxSize, MaxPropositionBytes} import org.ergoplatform.modifiers.{ErgoFullBlock, NetworkObjectTypeId} import org.ergoplatform.modifiers.history.extension.Extension import org.ergoplatform.modifiers.history.header.Header @@ -11,6 +10,7 @@ import org.ergoplatform.wallet.boxes.ErgoBoxAssetExtractor import org.ergoplatform.validation.{InvalidModifier, ModifierValidator} import org.ergoplatform.validation.ValidationResult.Invalid import scorex.util.ModifierId +import sigma.data.SigmaConstants.{MaxBoxSize, MaxPropositionBytes} object ValidationRules { @@ -299,6 +299,7 @@ object ValidationRules { val exParseValidationSettings: Short = 411 val exMatchValidationSettings: Short = 412 val exIlUnableToValidate: Short = 413 + val exMatchParameters60: Short = 414 // full block application val fbOperationFailed: Short = 500 diff --git a/ergo-core/src/main/scala/org/ergoplatform/utils/BoxUtils.scala b/ergo-core/src/main/scala/org/ergoplatform/utils/BoxUtils.scala index 3802b08077..b164feb8f3 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/utils/BoxUtils.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/utils/BoxUtils.scala @@ -4,8 +4,8 @@ import org.ergoplatform.ErgoBox.{AdditionalRegisters, TokenId} import org.ergoplatform.settings.{Algos, Parameters} import org.ergoplatform.{ErgoBox, ErgoBoxCandidate} import scorex.util.ModifierId +import sigma.ast.ErgoTree import sigma.{Coll, Colls} -import sigmastate.Values.ErgoTree import sigmastate.eval._ object BoxUtils { diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/AdProofSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/AdProofSpec.scala index 094c03397e..1f2838328e 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/AdProofSpec.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/modifiers/history/AdProofSpec.scala @@ -11,6 +11,7 @@ import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert} import scorex.crypto.hash.Digest32 import scorex.util._ import sigmastate.helpers.TestingHelpers._ +import org.ergoplatform.settings.Constants.TrueTree class AdProofSpec extends ErgoCorePropertyTest { import org.ergoplatform.utils.ErgoCoreTestConstants.startHeight @@ -31,12 +32,12 @@ class AdProofSpec extends ErgoCorePropertyTest { (IndexedSeq[Insert], PrevDigest, NewDigest, Proof) = { val prover = new BatchAVLProver[Digest32, HF](KL, None) - val zeroBox = testBox(0, Constants.TrueLeaf, startHeight, Seq(), Map(), Array.fill(32)(0: Byte).toModifierId) + val zeroBox = testBox(0, TrueTree, startHeight, Seq(), Map(), Array.fill(32)(0: Byte).toModifierId) prover.performOneOperation(Insert(zeroBox.id, ADValue @@ zeroBox.bytes)) prover.generateProof() val prevDigest = prover.digest - val boxes = (1 to howMany) map { i => testBox(1, Constants.TrueLeaf, startHeight, boxIndex = i.toShort) } + val boxes = (1 to howMany) map { i => testBox(1, TrueTree, startHeight, boxIndex = i.toShort) } boxes.foreach(box => prover.performOneOperation(Insert(box.id, ADValue @@ box.bytes))) val pf = prover.generateProof() @@ -70,14 +71,14 @@ class AdProofSpec extends ErgoCorePropertyTest { property("verify should be failed if there are more operations than expected") { val (operations, prevDigest, newDigest, pf) = createEnv() val proof = ADProofs(emptyModifierId, pf) - val moreInsertions = operations :+ insert(testBox(10, Constants.TrueLeaf, creationHeight = startHeight)) + val moreInsertions = operations :+ insert(testBox(10, TrueTree, creationHeight = startHeight)) proof.verify(StateChanges(IndexedSeq.empty, moreInsertions, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure } property("verify should be failed if there are illegal operation") { val (operations, prevDigest, newDigest, pf) = createEnv() val proof = ADProofs(emptyModifierId, pf) - val differentInsertions = operations.init :+ insert(testBox(10, Constants.TrueLeaf, creationHeight = startHeight)) + val differentInsertions = operations.init :+ insert(testBox(10, TrueTree, creationHeight = startHeight)) proof.verify(StateChanges(IndexedSeq.empty, differentInsertions, IndexedSeq.empty), prevDigest, newDigest) shouldBe 'failure } diff --git a/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoTransactionSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoTransactionSpec.scala index 003e2b0372..790299c472 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoTransactionSpec.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoTransactionSpec.scala @@ -1,5 +1,8 @@ package org.ergoplatform.modifiers.mempool +// needed for Scala 2.11 +import cats.syntax.either._ +import sigmastate.utils.Helpers._ import io.circe.syntax._ import org.ergoplatform.ErgoBox._ import org.ergoplatform.settings._ @@ -9,13 +12,13 @@ import scorex.crypto.authds.ADKey import scorex.util.encode.Base16 import scorex.util.ModifierId import sigma.Colls -import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant, LongArrayConstant, SigmaPropConstant} -import sigmastate.crypto.CryptoConstants -import sigmastate.crypto.DLogProtocol.ProveDlog import sigmastate.eval._ -import sigmastate.interpreter.{ContextExtension, ProverResult} -import cats.syntax.either._ -import sigmastate.utils.Helpers._ +import sigma.util.Extensions.SigmaBooleanOps +import sigma.ast.{ByteArrayConstant, ByteConstant, ErgoTree, IntConstant, LongArrayConstant, SigmaPropConstant} +import sigma.crypto.CryptoConstants +import sigma.data.ProveDlog +import sigma.interpreter.{ContextExtension, ProverResult} +import org.ergoplatform.settings.Constants.TrueTree class ErgoTransactionSpec extends ErgoCorePropertyTest { @@ -48,7 +51,7 @@ class ErgoTransactionSpec extends ErgoCorePropertyTest { new ProverResult(Base16.decode("5aea4d78a234c35accacdf8996b0af5b51e26fee29ea5c05468f23707d31c0df39400127391cd57a70eb856710db48bb9833606e0bf90340").get, ContextExtension.empty))) val outputCandidates: IndexedSeq[ErgoBoxCandidate] = IndexedSeq( - new ErgoBoxCandidate(1000000000L, minerPk, height, Colls.emptyColl, Map()), + new ErgoBoxCandidate(1000000000L, ErgoTree.fromSigmaBoolean(minerPk), height, Colls.emptyColl, Map()), new ErgoBoxCandidate(1000000L, chainSettings.monetary.feeProposition, height, Colls.emptyColl, Map()) ) val tx = ErgoTransaction(inputs: IndexedSeq[Input], outputCandidates: IndexedSeq[ErgoBoxCandidate]) @@ -62,7 +65,7 @@ class ErgoTransactionSpec extends ErgoCorePropertyTest { // tx with registers in outputs val outputCandidates2: IndexedSeq[ErgoBoxCandidate] = IndexedSeq( - new ErgoBoxCandidate(1000000000L, minerPk, height, Colls.emptyColl, + new ErgoBoxCandidate(1000000000L, ErgoTree.fromSigmaBoolean(minerPk), height, Colls.emptyColl, Map( R6 -> IntConstant(10), R4 -> ByteConstant(1), @@ -70,7 +73,7 @@ class ErgoTransactionSpec extends ErgoCorePropertyTest { R7 -> LongArrayConstant(Array(1L, 2L, 1234123L)), R8 -> ByteArrayConstant(Base16.decode("123456123456123456123456123456123456123456123456123456123456123456").get)) ), - new ErgoBoxCandidate(1000000000L, minerPk, height, Colls.emptyColl, Map())) + new ErgoBoxCandidate(1000000000L, ErgoTree.fromSigmaBoolean(minerPk), height, Colls.emptyColl, Map())) val tx2 = ErgoTransaction(inputs: IndexedSeq[Input], outputCandidates2: IndexedSeq[ErgoBoxCandidate]) Base16.encode(tx2.bytes) shouldBe "02c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f774238b4a04b4201da0578be3dac11067b567a73831f35b024a2e623c1f8da230407f63bab62c62ed9b93808b106b5a7e8b1751fa656f4c5de467400ca796a4fc9c0d746a69702a77bd78b1a80a5ef5bf5713bbd95d93a4f23b27ead385aea4d78a234c35accacdf8996b0af5b51e26fee29ea5c05468f23707d31c0df39400127391cd57a70eb856710db48bb9833606e0bf90340000000028094ebdc030008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942e8070005020108cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b94204141103020496d396010e211234561234561234561234561234561234561234561234561234561234561234568094ebdc030008cd0326df75ea615c18acc6bb4b517ac82795872f388d5d180aac90eaa84de750b942e8070000" @@ -88,7 +91,7 @@ class ErgoTransactionSpec extends ErgoCorePropertyTest { property("context extension with neg id") { val negId: Byte = -10 - val b = new ErgoBox(1000000000L, Constants.TrueLeaf, Colls.emptyColl, + val b = new ErgoBox(1000000000L, TrueTree, Colls.emptyColl, Map.empty, ModifierId @@ "c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742", 0, 0) val input = Input(b.id, ProverResult(Array.emptyByteArray, ContextExtension(Map(negId -> IntConstant(0))))) @@ -109,7 +112,7 @@ class ErgoTransactionSpec extends ErgoCorePropertyTest { property("context extension with neg and pos ids") { val negId: Byte = -20 - val b = new ErgoBox(1000000000L, Constants.TrueLeaf, Colls.emptyColl, + val b = new ErgoBox(1000000000L, TrueTree, Colls.emptyColl, Map.empty, ModifierId @@ "c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742", 0, 0) val ce = ContextExtension(Map(negId -> IntConstant(0), (-negId).toByte -> IntConstant(1))) diff --git a/ergo-core/src/test/scala/org/ergoplatform/network/HeaderSerializationSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/network/HeaderSerializationSpecification.scala index fb7821b255..234edad114 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/network/HeaderSerializationSpecification.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/network/HeaderSerializationSpecification.scala @@ -9,7 +9,7 @@ import scorex.crypto.authds.ADDigest import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util.ModifierId import scorex.util.encode.Base16 -import sigmastate.crypto.CryptoConstants.EcPointType +import sigma.crypto.EcPointType import java.nio.ByteBuffer diff --git a/ergo-core/src/test/scala/org/ergoplatform/reemission/ReemissionRulesSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/reemission/ReemissionRulesSpec.scala index c812ea77c0..5d1c54f844 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/reemission/ReemissionRulesSpec.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/reemission/ReemissionRulesSpec.scala @@ -6,9 +6,9 @@ import org.ergoplatform.utils.ErgoCorePropertyTest import scorex.crypto.hash.Blake2b256 import scorex.util.ModifierId import sigma.Colls -import sigmastate.AvlTreeData -import sigmastate.TrivialProp.TrueProp -import sigmastate.eval.Digest32Coll +import sigma.ast.ErgoTree +import sigma.data.TrivialProp.TrueProp +import sigma.data.{AvlTreeData, Digest32Coll} import sigmastate.helpers.TestingHelpers.testBox import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.interpreter.Interpreter.emptyEnv @@ -152,7 +152,7 @@ class ReemissionRulesSpec extends ErgoCorePropertyTest { // merging with 1 box - successful case val newReemissionBox = new ErgoBoxCandidate(reemissionBox.value + mergedValue - feeValue, prop, currentHeight, reemissionBoxAssets) - val feeBox = new ErgoBoxCandidate(feeValue, TrueProp, currentHeight) + val feeBox = new ErgoBoxCandidate(feeValue, ErgoTree.fromSigmaBoolean(TrueProp), currentHeight) val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox, feeBox)) checkRewardsTx(currentHeight, pkBytes, inputBoxes, spendingTransaction, true) @@ -167,7 +167,7 @@ class ReemissionRulesSpec extends ErgoCorePropertyTest { // paying too high fee val newReemissionBox3 = new ErgoBoxCandidate(reemissionBox.value + mergedValue - feeValue - 1, prop, currentHeight, reemissionBoxAssets) - val feeBox3 = new ErgoBoxCandidate(feeValue + 1, TrueProp, currentHeight) + val feeBox3 = new ErgoBoxCandidate(feeValue + 1, ErgoTree.fromSigmaBoolean(TrueProp), currentHeight) val spendingTransaction3 = ErgoLikeTransaction(inputs2, IndexedSeq(newReemissionBox3, feeBox3)) checkRewardsTx(currentHeight, pkBytes, inputBoxes, spendingTransaction3, false) @@ -181,7 +181,7 @@ class ReemissionRulesSpec extends ErgoCorePropertyTest { // reemission box value must be increased val feeValue5 = mergedValue val newReemissionBox5 = new ErgoBoxCandidate(reemissionBox.value + mergedValue - feeValue5, prop, currentHeight, reemissionBoxAssets) - val feeBox5 = new ErgoBoxCandidate(feeValue5, TrueProp, currentHeight) + val feeBox5 = new ErgoBoxCandidate(feeValue5, ErgoTree.fromSigmaBoolean(TrueProp), currentHeight) val spendingTransaction5 = ErgoLikeTransaction(inputs, IndexedSeq(newReemissionBox5, feeBox5)) checkRewardsTx(currentHeight, pkBytes, inputBoxes, spendingTransaction5, false) diff --git a/ergo-core/src/test/scala/org/ergoplatform/serialization/JsonSerializationCoreSpec.scala b/ergo-core/src/test/scala/org/ergoplatform/serialization/JsonSerializationCoreSpec.scala index 7a765c0fd0..360cb1c52e 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/serialization/JsonSerializationCoreSpec.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/serialization/JsonSerializationCoreSpec.scala @@ -12,9 +12,8 @@ import org.ergoplatform.settings.Algos import org.ergoplatform.utils.ErgoCorePropertyTest import org.ergoplatform.wallet.Constants.ScanId import org.ergoplatform.wallet.boxes.TrackedBox -import sigmastate.SType -import sigmastate.Values.{ErgoTree, EvaluatedValue} import cats.syntax.either._ +import sigma.ast.{ErgoTree, EvaluatedValue, SType} class JsonSerializationCoreSpec extends ErgoCorePropertyTest with ApiCodecs { diff --git a/ergo-core/src/test/scala/org/ergoplatform/settings/VotingSpecification.scala b/ergo-core/src/test/scala/org/ergoplatform/settings/VotingSpecification.scala index 72f4292c3a..1b118173a6 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/settings/VotingSpecification.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/settings/VotingSpecification.scala @@ -3,11 +3,11 @@ package org.ergoplatform.settings import org.ergoplatform.modifiers.history.extension.ExtensionCandidate import org.ergoplatform.modifiers.history.header.Header import org.ergoplatform.nodeView.state.{ErgoStateContext, VotingData} -import org.ergoplatform.settings.ValidationRules.rulesSpec +import org.ergoplatform.settings.ValidationRules.{exEmpty, exIlEncoding, exIlStructure, exIlUnableToValidate, rulesSpec} import org.ergoplatform.utils.ErgoCorePropertyTest -import org.ergoplatform.validation.{DisabledRule, ReplacedRule, ValidationRules => VR} +import sigma.validation.{DisabledRule, ReplacedRule, ValidationException} +import org.ergoplatform.validation.{ValidationRules => VR} import scorex.crypto.authds.ADDigest -import sigmastate.utils.Helpers._ import scala.util.Try @@ -38,7 +38,8 @@ class VotingSpecification extends ErgoCorePropertyTest { private val proposedUpdate = ErgoValidationSettingsUpdate( Seq(ValidationRules.exDuplicateKeys, ValidationRules.exValueLength), - Seq(VR.CheckDeserializedScriptType.id -> DisabledRule, VR.CheckValidOpCode.id -> ReplacedRule((VR.FirstRuleId + 11).toShort))) + Seq(VR.CheckDeserializedScriptType.id -> DisabledRule, + VR.CheckValidOpCode.id -> ReplacedRule((sigma.validation.ValidationRules.FirstRuleId + 11).toShort))) private val proposedUpdate2 = ErgoValidationSettingsUpdate(Seq(ValidationRules.fbOperationFailed), Seq()) val ctx: ErgoStateContext = { new ErgoStateContext(Seq.empty, None, genesisStateDigest, parameters, validationSettingsNoIl, VotingData.empty)(updSettings) @@ -53,10 +54,20 @@ class VotingSpecification extends ErgoCorePropertyTest { property("correct rule ids") { rulesSpec foreach { r => - r._1 < org.ergoplatform.validation.ValidationRules.FirstRuleId shouldBe true + r._1 < sigma.validation.ValidationRules.FirstRuleId shouldBe true } } + property(".toExtensionCandidate && .parseExtension") { + val update = ErgoValidationSettingsUpdate( + Seq.empty, + Seq(1011.toShort -> ReplacedRule(1016), 1007.toShort -> ReplacedRule(1017), 1008.toShort -> ReplacedRule(1018)) + ) + val vs = ErgoValidationSettings.initial.updated(update) + val vs2 = ErgoValidationSettings.parseExtension(vs.toExtensionCandidate).get + vs2.updateFromInitial == vs.updateFromInitial + } + property("ErgoValidationSettings toExtension/fromExtension roundtrip") { // initial settings should not be written into Extension at all val initial = ErgoValidationSettings.initial @@ -70,8 +81,8 @@ class VotingSpecification extends ErgoCorePropertyTest { } } - property("voting for non-existing parameter") { - val p: Parameters = Parameters(2, Map(BlockVersion -> 0), proposedUpdate) + property("voting for non-existing parameter - before block version V4") { + val p: Parameters = Parameters(2, Map(BlockVersion -> 3), proposedUpdate) val vr: VotingData = VotingData.empty val esc = new ErgoStateContext(Seq(), None, ADDigest @@ Array.fill(33)(0: Byte), p, validationSettingsNoIl, vr)(updSettings) val invalidVote = 100: Byte @@ -84,6 +95,35 @@ class VotingSpecification extends ErgoCorePropertyTest { // proposing a vote for non-existing param is not allowed val h2 = defaultHeaderGen.sample.get.copy(height = 2, votes = votes, version = 0: Byte) esc2.appendHeader(h2).toEither.left.get.getMessage.contains("Incorrect vote") shouldBe true + + // proposing a vote for non-existing param is not allowed + + val votes2 = Array(StorageFeeFactorDecrease, NoParameter, NoParameter) + val h22 = defaultHeaderGen.sample.get.copy(height = 2, votes = votes2, version = 0: Byte) + esc2.appendHeader(h22).toEither.left.get.getMessage.contains("Incorrect vote") shouldBe true + } + + property("voting for non-existing parameter - on and after block version V4") { + val p: Parameters = Parameters(2, Map(BlockVersion -> 4), proposedUpdate) + val vr: VotingData = VotingData.empty + val validationSettingsNoIl: ErgoValidationSettings = validationSettings + .updated(ErgoValidationSettingsUpdate(Seq(ValidationRules.hdrVotesUnknown), Seq())) + val esc = new ErgoStateContext(Seq(), None, ADDigest @@ Array.fill(33)(0: Byte), p, validationSettingsNoIl, vr)(updSettings) + val invalidVote = 100: Byte + val votes = Array(invalidVote , NoParameter, NoParameter) + + // voting for non-existing param is okay if not start of an epoch + val h = defaultHeaderGen.sample.get.copy(height = 1, votes = votes, version = 0: Byte) + val esc2 = esc.appendHeader(h).get + + // proposing a vote for non-existing param is not allowed + val h2 = defaultHeaderGen.sample.get.copy(height = 2, votes = votes, version = 0: Byte) + esc2.appendHeader(h2).toEither.toOption.isDefined shouldBe true + + // proposing a vote for decreasing param is not allowed + val votes2 = Array(StorageFeeFactorDecrease, NoParameter, NoParameter) + val h22 = defaultHeaderGen.sample.get.copy(height = 2, votes = votes2, version = 0: Byte) + esc2.appendHeader(h2).toEither.toOption.isDefined shouldBe true } //Simple checks for votes in header could be found also in NonVerifyADHistorySpecification("Header votes") @@ -112,6 +152,32 @@ class VotingSpecification extends ErgoCorePropertyTest { esc41.currentParameters.storageFeeFactor shouldBe (kInit + Parameters.StorageFeeFactorStep) } + //Simple checks for votes in header could be found also in NonVerifyADHistorySpecification("Header votes") + property("simple voting - decrease - start - conditions") { + val kInit = 1000000 + + val p: Parameters = Parameters(2, Map(StorageFeeFactorIncrease -> kInit, BlockVersion -> 0), proposedUpdate) + val vr: VotingData = VotingData.empty + val esc = new ErgoStateContext(Seq(), None, ADDigest @@ Array.fill(33)(0: Byte), p, validationSettingsNoIl, vr)(updSettings) + val votes = Array(StorageFeeFactorDecrease, NoParameter, NoParameter) + val h = defaultHeaderGen.sample.get.copy(height = 2, votes = votes, version = 0: Byte) + val esc2 = process(esc, p, h).get + + //no quorum gathered - no parameter change + val he = defaultHeaderGen.sample.get.copy(votes = Array.fill(3)(NoParameter), version = 0: Byte) + val esc30 = process(esc2, p, he).get + val esc40 = process(esc30, p, he).get + esc40.currentParameters.storageFeeFactor shouldBe kInit + + //quorum gathered - parameter change + val esc31 = process(esc2, p, h.copy(height = 3)).get + esc31.votingData.epochVotes.find(_._1 == StorageFeeFactorDecrease).get._2 shouldBe 2 + + val p4 = Parameters(4, Map(StorageFeeFactorIncrease -> (kInit - Parameters.StorageFeeFactorStep), BlockVersion -> 0), proposedUpdate) + val esc41 = process(esc31, p4, he.copy(height = 4)).get + esc41.currentParameters.storageFeeFactor shouldBe (kInit - Parameters.StorageFeeFactorStep) + } + /** * A test which is ensuring that approved soft-fork activates properly. * For the test, we have: @@ -194,6 +260,8 @@ class VotingSpecification extends ErgoCorePropertyTest { val esc12 = process(esc11, expectedParameters12, h12).get checkValidationSettings(esc12.validationSettings, proposedUpdate) + esc12.validationSettings.sigmaSettings.isSoftFork(VR.CheckValidOpCode.id, ValidationException("", VR.CheckValidOpCode, Seq.empty)) shouldBe true + // vote for soft-fork @ activation height val h12w = h12.copy(votes = forkVote) process(esc11, expectedParameters12, h12w).isFailure shouldBe true diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoCoreTestConstants.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoCoreTestConstants.scala index 92a52b21e0..5657276444 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoCoreTestConstants.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoCoreTestConstants.scala @@ -10,19 +10,20 @@ import org.ergoplatform.sdk.wallet.secrets.ExtendedSecretKey import org.ergoplatform.settings.Constants.HashLength import org.ergoplatform.settings.ValidationRules._ import org.ergoplatform.settings._ -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.interpreter.ErgoProvingInterpreter import org.ergoplatform.wallet.mnemonic.Mnemonic import org.ergoplatform.{DataInput, ErgoBox, ErgoTreePredef} import scorex.crypto.authds.ADDigest import scorex.crypto.hash.Digest32 import scorex.util.ScorexLogging -import sigmastate.Values.ErgoTree -import sigmastate.crypto.CryptoConstants.EcPointType -import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog} -import sigmastate.interpreter.{ContextExtension, ProverResult} import net.ceedubs.ficus.Ficus._ import org.ergoplatform.nodeView.state.{ErgoStateContext, UpcomingStateContext} +import org.ergoplatform.sdk.SecretString +import sigma.ast.ErgoTree +import sigma.crypto.EcPointType +import sigma.data.ProveDlog +import sigma.interpreter.{ContextExtension, ProverResult} +import sigmastate.crypto.DLogProtocol.DLogProverInput import java.io.File @@ -40,7 +41,7 @@ object ErgoCoreTestConstants extends ScorexLogging { implicit val validationSettingsNoIl: ErgoValidationSettings = validationSettings .updated(ErgoValidationSettingsUpdate(Seq(exIlUnableToValidate, exIlEncoding, exIlStructure, exEmpty), Seq())) - val parameters: Parameters = LaunchParameters + val parameters: Parameters = MainnetLaunchParameters val nipopowAlgos = new NipopowAlgos(chainSettings) val emission: EmissionRules = chainSettings.emissionRules diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoCoreGenerators.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoCoreGenerators.scala index 0cbb42425e..b2defcbf92 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoCoreGenerators.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoCoreGenerators.scala @@ -11,16 +11,18 @@ import org.ergoplatform.network.ModePeerFeature import org.ergoplatform.nodeView.history.{ErgoSyncInfo, ErgoSyncInfoV1, ErgoSyncInfoV2} import org.ergoplatform.nodeView.state.StateType import org.ergoplatform.settings.{Constants, ErgoValidationSettings, ErgoValidationSettingsUpdate, ValidationRules} -import org.ergoplatform.validation.{ChangedRule, DisabledRule, EnabledRule, ReplacedRule} +import sigma.validation.{ChangedRule, DisabledRule, EnabledRule, ReplacedRule} import org.scalacheck.Arbitrary.arbByte import org.scalacheck.{Arbitrary, Gen} import scorex.crypto.authds.{ADDigest, SerializedAdProof} import scorex.crypto.hash.Digest32 -import sigmastate.Values.ErgoTree -import sigmastate.crypto.CryptoConstants.EcPointType -import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog} -import sigmastate.crypto.{CryptoConstants, DiffieHellmanTupleProverInput, ProveDHTuple} -import sigmastate.interpreter.ProverResult +import sigma.ast.ErgoTree +import sigma.crypto.{CryptoConstants, EcPointType} +import sigma.data.{ProveDHTuple, ProveDlog} +import sigma.interpreter.ProverResult +import sigmastate.crypto.DLogProtocol.DLogProverInput +import sigmastate.crypto.DiffieHellmanTupleProverInput +import org.ergoplatform.settings.Constants.{FalseTree, TrueTree} import scala.util.Random @@ -28,13 +30,12 @@ object ErgoCoreGenerators { import org.ergoplatform.utils.generators.CoreObjectGenerators._ import org.ergoplatform.utils.ErgoCoreTestConstants._ - lazy val trueLeafGen: Gen[ErgoTree] = Gen.const(Constants.TrueLeaf) - lazy val falseLeafGen: Gen[ErgoTree] = Gen.const(Constants.FalseLeaf) + lazy val trueLeafGen: Gen[ErgoTree] = Gen.const(TrueTree) + lazy val falseLeafGen: Gen[ErgoTree] = Gen.const(FalseTree) lazy val smallPositiveInt: Gen[Int] = Gen.choose(1, 5) - lazy val noProofGen: Gen[ProverResult] = - Gen.const(emptyProverResult) + lazy val noProofGen: Gen[ProverResult] = Gen.const(emptyProverResult) lazy val dlogSecretWithPublicImageGen: Gen[(DLogProverInput, ProveDlog)] = for { secret <- genBytes(32).map(seed => BigIntegers.fromUnsignedByteArray(seed)) @@ -54,7 +55,7 @@ object ErgoCoreGenerators { seed <- genBytes(32) } yield DLogProverInput(BigIntegers.fromUnsignedByteArray(seed)).publicImage - lazy val proveDlogTreeGen: Gen[ErgoTree] = proveDlogGen.map(_.toSigmaProp) + lazy val proveDlogTreeGen: Gen[ErgoTree] = proveDlogGen.map(ErgoTree.fromSigmaBoolean) lazy val ergoPropositionGen: Gen[ErgoTree] = Gen.oneOf(trueLeafGen, falseLeafGen, proveDlogTreeGen) @@ -200,7 +201,7 @@ object ErgoCoreGenerators { lazy val ergoValidationSettingsUpdateGen: Gen[ErgoValidationSettingsUpdate] = for { n <- Gen.choose(1, 200) disabledRules = ValidationRules.rulesSpec.filter(_._2.mayBeDisabled).keys.take(n).toSeq - replacedRuleCode <- Gen.choose(org.ergoplatform.validation.ValidationRules.FirstRuleId, Short.MaxValue) + replacedRuleCode <- Gen.choose(sigma.validation.ValidationRules.FirstRuleId, Short.MaxValue) changedRuleValue <- genBoundedBytes(0, 127) statuses <- Gen.listOf(Gen.oneOf(DisabledRule, EnabledRule, ReplacedRule(replacedRuleCode), ChangedRule(changedRuleValue))) statusUpdates = org.ergoplatform.validation.ValidationRules.ruleSpecs.take(statuses.size).map(_.id).zip(statuses) diff --git a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoCoreTransactionGenerators.scala b/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoCoreTransactionGenerators.scala index 40a748d7c4..f5d00454d0 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoCoreTransactionGenerators.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/utils/generators/ErgoCoreTransactionGenerators.scala @@ -13,9 +13,10 @@ import org.ergoplatform._ import org.scalacheck.Gen import scorex.crypto.hash.Blake2b256 import scorex.util.ScorexLogging -import sigmastate.Values.ErgoTree -import sigmastate.crypto.DLogProtocol.ProveDlog +import sigma.ast.ErgoTree +import sigma.data.ProveDlog import sigmastate.eval.Extensions._ +import sigma.Extensions.ArrayOps import sigmastate.eval._ import scala.collection.JavaConverters._ @@ -39,7 +40,7 @@ object ErgoCoreTransactionGenerators extends ScorexLogging { ar <- additionalRegistersGen tokens <- additionalTokensGen value <- validValueGen - } yield new ErgoBoxCandidate(value, prop, h, tokens.toColl, ar) + } yield new ErgoBoxCandidate(value, prop, h, tokens.toArray.toColl, ar) def ergoAddressGen: Gen[ErgoAddress] = proveDlogGen.map(P2PKAddress.apply) @@ -48,7 +49,7 @@ object ErgoCoreTransactionGenerators extends ScorexLogging { ar <- additionalRegistersGen tokens <- additionalTokensGen value <- validValueGen - } yield new ErgoBoxCandidate(value, prop, h, tokens.toColl, ar) + } yield new ErgoBoxCandidate(value, ErgoTree.fromSigmaBoolean(prop), h, tokens.toArray.toColl, ar) lazy val ergoBoxGenNoProp: Gen[ErgoBox] = ergoBoxGen(propGen = trueLeafGen) diff --git a/ergo-wallet/src/main/java/org/ergoplatform/wallet/interface4j/crypto/ErgoSignature.java b/ergo-wallet/src/main/java/org/ergoplatform/wallet/interface4j/crypto/ErgoSignature.java index 989363a6f2..5bcfabbe3a 100644 --- a/ergo-wallet/src/main/java/org/ergoplatform/wallet/interface4j/crypto/ErgoSignature.java +++ b/ergo-wallet/src/main/java/org/ergoplatform/wallet/interface4j/crypto/ErgoSignature.java @@ -2,7 +2,7 @@ import org.bouncycastle.math.ec.custom.sec.SecP256K1Point; import scala.math.BigInt; -import sigmastate.crypto.Platform; +import sigma.crypto.Platform; import java.math.BigInteger; diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/contracts/ReemissionContracts.scala b/ergo-wallet/src/main/scala/org/ergoplatform/contracts/ReemissionContracts.scala index 7569b8c00c..b5774b5a88 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/contracts/ReemissionContracts.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/contracts/ReemissionContracts.scala @@ -4,9 +4,8 @@ import org.ergoplatform.ErgoBox.{R2, STokensRegType} import org.ergoplatform.ErgoTreePredef.{boxCreationHeight, expectedMinerOutScriptBytesVal} import org.ergoplatform.mining.emission.EmissionRules.CoinsInOneErgo import org.ergoplatform.settings.MonetarySettings -import org.ergoplatform.{Height, MinerPubkey, Outputs, Self} -import sigmastate.Values.{ByteArrayConstant, ErgoTree, IntConstant, LongConstant, SigmaPropValue, Value} -import sigmastate.utxo._ +import sigma.ast._ +import sigma.ast.syntax._ import sigmastate._ import sigma.Coll @@ -39,8 +38,8 @@ trait ReemissionContracts { /** Helper method to produce v1 tree from a SigmaPropValue instance (i.e. root node of AST).*/ private def v1Tree(prop: SigmaPropValue): ErgoTree = { val version: Byte = 1 - val headerFlags = ErgoTree.headerWithVersion(version) - ErgoTree.fromProposition(headerFlags, prop) + val header = ErgoTree.defaultHeaderWithVersion(version) + ErgoTree.fromProposition(header, prop) } /** diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/BoxSelector.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/BoxSelector.scala index f945b3e4bf..8f98714aed 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/BoxSelector.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/BoxSelector.scala @@ -1,10 +1,10 @@ package org.ergoplatform.wallet.boxes -import org.ergoplatform.SigmaConstants.MaxBoxSize import org.ergoplatform.sdk.wallet.TokensMap import org.ergoplatform.wallet.boxes.BoxSelector.{BoxSelectionError, BoxSelectionResult} import org.ergoplatform.{ErgoBoxAssets, ErgoBoxAssetsHolder} import scorex.util.ScorexLogging +import sigma.data.SigmaConstants.MaxBoxSize /** diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/ErgoBoxSerializer.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/ErgoBoxSerializer.scala index 6c5fb62563..62678c4eef 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/ErgoBoxSerializer.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/ErgoBoxSerializer.scala @@ -3,13 +3,12 @@ package org.ergoplatform.wallet.boxes import org.ergoplatform.ErgoBox import org.ergoplatform.wallet.serialization.ErgoWalletSerializer import scorex.util.serialization.{Reader, Writer} -import sigmastate.serialization.ConstantStore -import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} +import sigma.serialization.{ConstantStore, SigmaByteReader, SigmaByteWriter} object ErgoBoxSerializer extends ErgoWalletSerializer[ErgoBox] { override def serialize(box: ErgoBox, w: Writer): Unit = { - val writer = new SigmaByteWriter(w, None) + val writer = new SigmaByteWriter(w, None, None, None) ErgoBox.sigmaSerializer.serialize(box, writer) } diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/TrackedBox.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/TrackedBox.scala index 472b54e9f8..ae7872162c 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/TrackedBox.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/boxes/TrackedBox.scala @@ -8,7 +8,7 @@ import org.ergoplatform.wallet.serialization.ErgoWalletSerializer import org.ergoplatform.{ErgoBox, ErgoBoxAssets, ErgoLikeTransaction} import scorex.util.serialization.{Reader, Writer} import scorex.util.{ModifierId, bytesToId, idToBytes} -import sigma.Extensions._ +import sigma.Extensions.CollBytesOps /** * A box tracked by a wallet that contains Ergo box itself as well as diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/crypto/ErgoSignature.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/crypto/ErgoSignature.scala index 430fc8c894..1805a88145 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/crypto/ErgoSignature.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/crypto/ErgoSignature.scala @@ -3,8 +3,8 @@ package org.ergoplatform.wallet.crypto import org.bouncycastle.util.BigIntegers import scorex.crypto.hash.Blake2b256 import scorex.util.encode.Base16 -import sigmastate.crypto.CryptoConstants -import sigmastate.serialization.GroupElementSerializer +import sigma.crypto.EcPointType +import sigma.serialization.GroupElementSerializer import scala.annotation.tailrec @@ -13,7 +13,7 @@ import scala.annotation.tailrec */ object ErgoSignature { - import CryptoConstants._ + import sigma.crypto.CryptoConstants._ /** * Signs given `msg` using given `sk`. diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoInterpreter.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoInterpreter.scala index bdd423615f..f27e6843a1 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoInterpreter.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoInterpreter.scala @@ -5,10 +5,10 @@ import org.ergoplatform.sdk.BlockchainParameters import org.ergoplatform.wallet.protocol.Constants import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, ErgoLikeContext, ErgoLikeInterpreter} import scorex.util.ScorexLogging -import sigmastate.Values.ErgoTree import sigmastate.interpreter.Interpreter.{ScriptEnv, VerificationResult} -import sigmastate.{AvlTreeData, AvlTreeFlags} import sigma.Coll +import sigma.ast.ErgoTree +import sigma.data.{AvlTreeData, AvlTreeFlags} import scala.util.Try diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoProvingInterpreter.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoProvingInterpreter.scala index 62732ab788..4217b96130 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoProvingInterpreter.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoProvingInterpreter.scala @@ -5,13 +5,14 @@ import org.ergoplatform.sdk.BlockchainParameters import org.ergoplatform.sdk.utils.ArithUtils.{addExact, multiplyExact} import org.ergoplatform.sdk.wallet.protocol.context.BlockchainStateContext import org.ergoplatform.sdk.wallet.secrets.{ExtendedPublicKey, ExtendedSecretKey, SecretKey} -import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} +import org.ergoplatform.validation.ValidationRules import org.ergoplatform.wallet.boxes.ErgoBoxAssetExtractor import scorex.util.encode.Base16 -import sigmastate.AvlTreeData -import sigmastate.Values.SigmaBoolean +import sigma.data.{AvlTreeData, SigmaBoolean, SigmaLeaf} +import sigma.interpreter.ContextExtension +import sigma.validation.SigmaValidationSettings import sigmastate.crypto.SigmaProtocolPrivateInput -import sigmastate.interpreter.{ContextExtension, ProverInterpreter} +import sigmastate.interpreter.ProverInterpreter import sigma.{Coll, Header, PreHeader} import java.util @@ -45,7 +46,7 @@ class ErgoProvingInterpreter(val secretKeys: IndexedSeq[SecretKey], /** * Interpreter's secrets, in form of sigma protocols private inputs */ - val secrets: IndexedSeq[SigmaProtocolPrivateInput[_]] = secretKeys.map(_.privateInput) + val secrets: IndexedSeq[SigmaProtocolPrivateInput[_]] = secretKeys.map(_.privateInput.asInstanceOf[SigmaProtocolPrivateInput[SigmaLeaf]]) /** * Only secrets corresponding to hierarchical deterministic scheme (BIP-32 impl) @@ -99,7 +100,7 @@ class ErgoProvingInterpreter(val secretKeys: IndexedSeq[SecretKey], def signInputs(unsignedTx: UnsignedErgoLikeTransaction, boxesToSpend: IndexedSeq[ErgoBox], dataBoxes: IndexedSeq[ErgoBox], - stateContext: BlockchainStateContext, + stateContext: VersionedBlockchainStateContext, txHints: TransactionHintsBag): Try[(IndexedSeq[Input], Long)] = { if (unsignedTx.inputs.length != boxesToSpend.length) { Failure(new Exception("Not enough boxes to spend")) @@ -135,7 +136,7 @@ class ErgoProvingInterpreter(val secretKeys: IndexedSeq[SecretKey], unsignedTx, boxIdx.toShort, unsignedInput.extension, - ValidationRules.currentSettings, + stateContext.sigmaValidationSettings, params.maxBlockCost, totalCost, activatedScriptVersion @@ -163,7 +164,7 @@ class ErgoProvingInterpreter(val secretKeys: IndexedSeq[SecretKey], def sign(unsignedTx: UnsignedErgoLikeTransaction, boxesToSpend: IndexedSeq[ErgoBox], dataBoxes: IndexedSeq[ErgoBox], - stateContext: BlockchainStateContext, + stateContext: VersionedBlockchainStateContext, txHints: TransactionHintsBag = TransactionHintsBag.empty): Try[ErgoLikeTransaction] = { val signedInputs: Try[(IndexedSeq[Input], Long)] = diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoUnsafeProver.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoUnsafeProver.scala index c2b763cb65..2d373e7db3 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoUnsafeProver.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/ErgoUnsafeProver.scala @@ -2,8 +2,8 @@ package org.ergoplatform.wallet.interpreter import org.ergoplatform.{ErgoLikeTransaction, Input, UnsignedErgoLikeTransaction} import scorex.util.encode.Base16 +import sigma.interpreter.{ContextExtension, ProverResult} import sigmastate.crypto.DLogProtocol.DLogProverInput -import sigmastate.interpreter.{ContextExtension, ProverResult} /** * A naive Ergo prover implementation not performing transaction cost verification. diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/VersionedBlockchainStateContext.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/VersionedBlockchainStateContext.scala new file mode 100644 index 0000000000..32c245bdf5 --- /dev/null +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/interpreter/VersionedBlockchainStateContext.scala @@ -0,0 +1,8 @@ +package org.ergoplatform.wallet.interpreter + +import org.ergoplatform.sdk.wallet.protocol.context.BlockchainStateContext +import sigma.validation.SigmaValidationSettings + +abstract class VersionedBlockchainStateContext extends BlockchainStateContext { + val sigmaValidationSettings: SigmaValidationSettings +} diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/mnemonic/Mnemonic.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/mnemonic/Mnemonic.scala index 46871b6bdb..17cc6c70ab 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/mnemonic/Mnemonic.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/mnemonic/Mnemonic.scala @@ -1,12 +1,13 @@ package org.ergoplatform.wallet.mnemonic +import org.ergoplatform.sdk.SecretString + import java.text.Normalizer.Form.NFKD import java.text.Normalizer.normalize import javax.crypto.SecretKeyFactory import javax.crypto.spec.PBEKeySpec -import org.ergoplatform.wallet.interface4j.SecretString import scodec.bits.BitVector -import sigmastate.crypto.CryptoFacade +import sigma.crypto.CryptoFacade import scala.util.{Failure, Try} diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/protocol/context/InputContext.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/protocol/context/InputContext.scala index 941ab34052..6f81000456 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/protocol/context/InputContext.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/protocol/context/InputContext.scala @@ -1,6 +1,7 @@ package org.ergoplatform.wallet.protocol.context -import sigmastate.interpreter.ContextExtension +import sigma.interpreter.ContextExtension + /** * Part of execution context regarding a box to be spent. diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/secrets/JsonSecretStorage.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/secrets/JsonSecretStorage.scala index 173d4a69e8..7b93006316 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/secrets/JsonSecretStorage.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/secrets/JsonSecretStorage.scala @@ -2,10 +2,10 @@ package org.ergoplatform.wallet.secrets import io.circe.parser._ import io.circe.syntax._ +import org.ergoplatform.sdk.SecretString import org.ergoplatform.sdk.wallet.secrets.ExtendedSecretKey import org.ergoplatform.sdk.wallet.settings.EncryptionSettings import org.ergoplatform.wallet.crypto -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.mnemonic.Mnemonic import org.ergoplatform.wallet.settings.SecretStorageSettings import scorex.util.encode.Base16 diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/secrets/SecretStorage.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/secrets/SecretStorage.scala index 1f3ee1394e..ff0b177729 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/secrets/SecretStorage.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/secrets/SecretStorage.scala @@ -1,10 +1,10 @@ package org.ergoplatform.wallet.secrets +import org.ergoplatform.sdk.SecretString import org.ergoplatform.sdk.wallet.secrets.ExtendedSecretKey import java.io.File import scala.util.Try -import org.ergoplatform.wallet.interface4j.SecretString /** * Secret storage trait. diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/serialization/ErgoWalletSerializer.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/serialization/ErgoWalletSerializer.scala index bc9bf9071b..90d1f223ce 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/serialization/ErgoWalletSerializer.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/serialization/ErgoWalletSerializer.scala @@ -3,8 +3,7 @@ package org.ergoplatform.wallet.serialization import java.nio.ByteBuffer import scorex.util.ByteArrayBuilder import scorex.util.serialization._ -import sigmastate.serialization.{SigmaSerializer, ConstantStore} -import sigmastate.utils.{SigmaByteWriter, SigmaByteReader} +import sigma.serialization.{ConstantStore, SigmaByteReader, SigmaByteWriter, SigmaSerializer} import scala.util.Try @@ -30,7 +29,7 @@ object ErgoWalletSerializer { /** Creates a new serializer which delegates to the given [[SigmaSerializer]]. */ def fromSigmaSerializer[T](ss: SigmaSerializer[T, T]): ErgoWalletSerializer[T] = new ErgoWalletSerializer[T] { override def serialize(obj: T, w: Writer): Unit = { - val sw = new SigmaByteWriter(w, None) + val sw = new SigmaByteWriter(w, None, None, None) ss.serialize(obj, sw) } diff --git a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/transactions/TransactionBuilder.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/transactions/TransactionBuilder.scala index 745002eacf..68630aa588 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/wallet/transactions/TransactionBuilder.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/transactions/TransactionBuilder.scala @@ -7,11 +7,9 @@ import org.ergoplatform.wallet.boxes.{BoxSelector, DefaultBoxSelector} import scorex.crypto.authds.ADKey import scorex.util.encode.Base16 import scorex.util.{ModifierId, bytesToId} -import sigmastate.eval.Extensions._ -import sigmastate.eval._ import sigmastate.utils.Extensions._ import sigma.Coll -import sigma.Extensions._ +import sigma.Extensions.{ArrayOps, CollBytesOps} import scala.collection.JavaConverters._ import scala.util.Try @@ -48,7 +46,7 @@ object TransactionBuilder { feeAmt, ErgoTreePredef.feeProposition(), currentHeight, - Seq.empty[(ErgoBox.TokenId, Long)].toColl, + Array.empty[(ErgoBox.TokenId, Long)].toColl, Map.empty ) val paymentBoxes = @@ -57,7 +55,7 @@ object TransactionBuilder { transferAmt, recipientAddress.script, currentHeight, - Seq.empty[(ErgoBox.TokenId, Long)].toColl, + Array.empty[(ErgoBox.TokenId, Long)].toColl, Map.empty ) }.toVector @@ -70,7 +68,7 @@ object TransactionBuilder { changeAmt, changeAddress.script, currentHeight, - Seq.empty[(ErgoBox.TokenId, Long)].toColl, + Array.empty[(ErgoBox.TokenId, Long)].toColl, Map.empty ) paymentBoxes ++ Vector(feeBox, changeBox) @@ -112,21 +110,21 @@ object TransactionBuilder { transferAmt, recipientAddress.script, currentHeight, - Seq.empty[(ErgoBox.TokenId, Long)].toColl, + Array.empty[(ErgoBox.TokenId, Long)].toColl, Map.empty ) val fee = new ErgoBoxCandidate( feeAmt, ErgoTreePredef.feeProposition(), currentHeight, - Seq.empty[(ErgoBox.TokenId, Long)].toColl, + Array.empty[(ErgoBox.TokenId, Long)].toColl, Map.empty ) val change = new ErgoBoxCandidate( changeAmt, changeAddress.script, currentHeight, - Seq.empty[(ErgoBox.TokenId, Long)].toColl, + Array.empty[(ErgoBox.TokenId, Long)].toColl, Map.empty ) val unsignedInputs = inputIds diff --git a/ergo-wallet/src/test/java/org/ergoplatform/wallet/AddressGenerationDemo.java b/ergo-wallet/src/test/java/org/ergoplatform/wallet/AddressGenerationDemo.java index 35944bbf3b..5310e93193 100644 --- a/ergo-wallet/src/test/java/org/ergoplatform/wallet/AddressGenerationDemo.java +++ b/ergo-wallet/src/test/java/org/ergoplatform/wallet/AddressGenerationDemo.java @@ -2,10 +2,10 @@ import org.ergoplatform.ErgoAddressEncoder; import org.ergoplatform.P2PKAddress; +import org.ergoplatform.sdk.SecretString; import org.ergoplatform.sdk.wallet.secrets.DerivationPath; import org.ergoplatform.sdk.wallet.secrets.ExtendedPublicKey; import org.ergoplatform.sdk.wallet.secrets.ExtendedSecretKey; -import org.ergoplatform.wallet.interface4j.SecretString; import org.ergoplatform.wallet.mnemonic.Mnemonic; import scala.Option; diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/boxes/DefaultBoxSelectorSpec.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/boxes/DefaultBoxSelectorSpec.scala index f34f050501..14590b2df6 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/boxes/DefaultBoxSelectorSpec.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/boxes/DefaultBoxSelectorSpec.scala @@ -2,7 +2,6 @@ package org.ergoplatform.wallet.boxes import org.ergoplatform.ErgoBox.TokenId import org.ergoplatform.ErgoLikeTransaction -import org.ergoplatform.SigmaConstants.MaxBoxSize import org.ergoplatform.sdk.wallet.Constants.MaxAssetsPerBox import org.ergoplatform.wallet.Constants.PaymentsScanId import org.ergoplatform.wallet.boxes.DefaultBoxSelector.{NotEnoughErgsError, NotEnoughTokensError} @@ -11,12 +10,13 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.propspec.AnyPropSpec import scorex.crypto.hash.Blake2b256 import scorex.util.bytesToId -import sigmastate.Values -import sigmastate.Values.SigmaPropValue import sigmastate.eval.Extensions._ import sigmastate.helpers.TestingHelpers._ import sigmastate.utils.Extensions._ import sigma.Extensions._ +import sigma.ast.ErgoTree +import sigma.ast.syntax.SigmaPropValue +import sigma.data.SigmaConstants.MaxBoxSize import scala.util.Random @@ -27,7 +27,7 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues private val onChainFilter = {box: TrackedBox => box.chainStatus.onChain} private val parentTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()) - private val TrueLeaf: SigmaPropValue = Values.TrueLeaf.toSigmaProp + private val TrueLeaf: SigmaPropValue = TrueLeaf.toSigmaProp private val StartHeight: Int = 0 private def genTokens(count: Int) = { @@ -37,7 +37,7 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues private val selector = new DefaultBoxSelector(None) property("returns error when it is impossible to select coins") { - val box = testBox(1, TrueLeaf, creationHeight = StartHeight) + val box = testBox(1, ErgoTree.fromProposition(TrueLeaf), creationHeight = StartHeight) val uBox = TrackedBox(parentTx, 0, None, box, Set(PaymentsScanId)) //target amount is too high @@ -55,9 +55,9 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues } property("properly selects coins - simple case with no assets") { - val box1 = testBox(1, TrueLeaf, creationHeight = StartHeight) - val box2 = testBox(10, TrueLeaf, creationHeight = StartHeight) - val box3 = testBox(100, TrueLeaf, creationHeight = StartHeight) + val box1 = testBox(1, ErgoTree.fromProposition(TrueLeaf), creationHeight = StartHeight) + val box2 = testBox(10, ErgoTree.fromProposition(TrueLeaf), creationHeight = StartHeight) + val box3 = testBox(100, ErgoTree.fromProposition(TrueLeaf), creationHeight = StartHeight) val uBox1 = TrackedBox(parentTx, 0, Option(100), box1, Set(PaymentsScanId)) val uBox2 = TrackedBox(parentTx, 1, None, box2, Set(PaymentsScanId)) @@ -101,9 +101,9 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues val assetId2 = bytesToId(Blake2b256("world")) val parentTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()) - val box1 = testBox(1 * MinBoxValue, TrueLeaf, StartHeight, Seq(assetId1.toTokenId -> 1)) - val box2 = testBox(10 * MinBoxValue, TrueLeaf, StartHeight, Seq(assetId2.toTokenId -> 10)) - val box3 = testBox(100 * MinBoxValue, TrueLeaf, StartHeight, Seq(assetId1.toTokenId -> 100)) + val box1 = testBox(1 * MinBoxValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, Seq(assetId1.toTokenId -> 1)) + val box2 = testBox(10 * MinBoxValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, Seq(assetId2.toTokenId -> 10)) + val box3 = testBox(100 * MinBoxValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, Seq(assetId1.toTokenId -> 100)) val uBox1 = TrackedBox(parentTx, 0, Some(100), box1, Set(PaymentsScanId)) val uBox2 = TrackedBox(parentTx, 1, None, box2, Set(PaymentsScanId)) @@ -150,17 +150,17 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues val assetId8 = bytesToId(Blake2b256("8")) val box1 = testBox( - 1 * MinBoxValue, TrueLeaf, StartHeight, + 1 * MinBoxValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, Seq(assetId1.toTokenId -> 1, assetId2.toTokenId -> 1, assetId3.toTokenId -> 1, assetId4.toTokenId -> 1)) val box2 = testBox( - 10 * MinBoxValue, TrueLeaf, StartHeight, + 10 * MinBoxValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, Seq(assetId5.toTokenId -> 10, assetId6.toTokenId -> 10, assetId7.toTokenId -> 10, assetId8.toTokenId -> 10)) val box3 = testBox( - 100 * MinBoxValue, TrueLeaf, StartHeight, + 100 * MinBoxValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, Seq(assetId3.toTokenId -> 100, assetId4.toTokenId -> 100, assetId5.toTokenId -> 100, assetId6.toTokenId -> 100)) @@ -201,13 +201,13 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues val tokens = (0 until MaxAssetsPerBox).map { _ => (scorex.util.Random.randomBytes(TokenId.size).toTokenId, Random.nextInt(100000000).toLong) } - val box = testBox(1 * MinBoxValue, TrueLeaf, StartHeight, tokens) + val box = testBox(1 * MinBoxValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, tokens) assert(box.bytes.length <= MaxBoxSize.value) } property("Select boxes such that change boxes are grouped by MaxAssetsPerBox") { // make selection such that '2 * MaxAssetsPerBox + 1' tokens generates exactly 2 change boxes with MaxAssetsPerBox tokens - val box1 = testBox(4 * MinBoxValue, TrueLeaf, StartHeight, genTokens(2 * MaxAssetsPerBox + 1)) + val box1 = testBox(4 * MinBoxValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, genTokens(2 * MaxAssetsPerBox + 1)) val uBox1 = TrackedBox(parentTx, 0, Some(100), box1, Set(PaymentsScanId)) val s1 = selector.select(Iterator(uBox1), noFilter, 1 * MinBoxValue, Map(bytesToId(Blake2b256("1")) -> 1)) s1 shouldBe 'right @@ -215,7 +215,7 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues s1.right.get.changeBoxes.forall(_.tokens.size == MaxAssetsPerBox) shouldBe true // make selection such that '2 * MaxAssetsPerBox + 2' tokens generates 3 change boxes, one with just a single token - val box2 = testBox(4 * MinBoxValue, TrueLeaf, StartHeight, genTokens(2 * MaxAssetsPerBox + 2)) + val box2 = testBox(4 * MinBoxValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, genTokens(2 * MaxAssetsPerBox + 2)) val uBox2 = TrackedBox(parentTx, 0, Some(100), box2, Set(PaymentsScanId)) val s2 = selector.select(Iterator(uBox2), noFilter, 1 * MinBoxValue, Map(bytesToId(Blake2b256("1")) -> 1)) s2 shouldBe 'right @@ -232,9 +232,9 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues val ergValue = 10 * MinBoxValue - val box1 = testBox(ergValue, TrueLeaf, StartHeight, Seq(tokenData)) + val box1 = testBox(ergValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, Seq(tokenData)) val uBox1 = TrackedBox(parentTx, 0, Some(100), box1, Set(PaymentsScanId)) - val box2 = testBox(ergValue, TrueLeaf, StartHeight) + val box2 = testBox(ergValue, ErgoTree.fromProposition(TrueLeaf), StartHeight) val uBox2 = TrackedBox(parentTx, 0, Some(100), box2, Set(PaymentsScanId)) val s1 = selector.select(Iterator(uBox1, uBox2), noFilter, ergValue, Map.empty) @@ -242,7 +242,7 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues s1.right.get.changeBoxes.size shouldBe 1 s1.right.get.changeBoxes.head.tokens(tokenId) shouldBe 2 - val box3 = testBox(ergValue, TrueLeaf, StartHeight) + val box3 = testBox(ergValue, ErgoTree.fromProposition(TrueLeaf), StartHeight) val uBox3 = TrackedBox(parentTx, 0, Some(100), box3, Set(PaymentsScanId)) val s2 = selector.select(Iterator(uBox2, uBox3), noFilter, ergValue, Map.empty) @@ -266,7 +266,7 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues val fullValue = 2000000000L val reemissionAmt = fullValue / 2 - val inputBox = testBox(fullValue, TrueLeaf, StartHeight, Array((reemissionTokenId, reemissionAmt))) + val inputBox = testBox(fullValue, ErgoTree.fromProposition(TrueLeaf), StartHeight, Array((reemissionTokenId, reemissionAmt))) val uBox = TrackedBox(parentTx, 0, Some(100), inputBox, Set(PaymentsScanId)) val s1 = selector.select(Iterator(uBox), noFilter, fullValue - reemissionAmt + 1, Map.empty) diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/boxes/ReplaceCompactCollectBoxSelectorSpec.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/boxes/ReplaceCompactCollectBoxSelectorSpec.scala index 300905a6f1..a28140d8f4 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/boxes/ReplaceCompactCollectBoxSelectorSpec.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/boxes/ReplaceCompactCollectBoxSelectorSpec.scala @@ -3,21 +3,21 @@ package org.ergoplatform.wallet.boxes import org.ergoplatform.wallet.Constants.PaymentsScanId import org.ergoplatform.ErgoLikeTransaction import org.ergoplatform.wallet.boxes.BoxSelector.BoxSelectionResult -import sigmastate.Values -import sigmastate.Values.SigmaPropValue import sigmastate.helpers.TestingHelpers._ import org.scalatest.EitherValues import org.scalatest.matchers.should.Matchers import org.scalatest.propspec.AnyPropSpec +import sigma.ast.ErgoTree +import sigma.ast.syntax.SigmaPropValue class ReplaceCompactCollectBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues { private val noFilter: TrackedBox => Boolean = _ => true val parentTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()) - val TrueLeaf: SigmaPropValue = Values.TrueLeaf.toSigmaProp + val TrueLeaf: SigmaPropValue = TrueLeaf.toSigmaProp - def box(value:Long) = testBox(value, TrueLeaf, 0) + def box(value:Long) = testBox(value, ErgoTree.fromProposition(TrueLeaf), 0) def trackedBox(value:Long) = TrackedBox(parentTx, 0, None, box(value), Set(PaymentsScanId)) property("compress() done properly") { diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/interpreter/ErgoProvingInterpreterSpec.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/interpreter/ErgoProvingInterpreterSpec.scala index 4c09d1c40a..c8723f91e5 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/interpreter/ErgoProvingInterpreterSpec.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/interpreter/ErgoProvingInterpreterSpec.scala @@ -9,10 +9,11 @@ import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import scorex.util.{ModifierId, Random} import scorex.util.encode.Base16 import sigma.Colls -import sigmastate.CTHRESHOLD -import sigmastate.Values.{GroupElementConstant, SigmaBoolean} -import sigmastate.interpreter.{ContextExtension, HintsBag} -import sigmastate.serialization.ErgoTreeSerializer +import sigma.ast.{ErgoTree, GroupElementConstant} +import sigma.data.{CGroupElement, CTHRESHOLD, SigmaBoolean} +import sigma.interpreter.ContextExtension +import sigma.serialization.ErgoTreeSerializer +import sigmastate.interpreter.HintsBag class ErgoProvingInterpreterSpec @@ -63,7 +64,7 @@ class ErgoProvingInterpreterSpec val creationHeight = 10000 - val boxCandidate = new ErgoBoxCandidate(value, prop, creationHeight) + val boxCandidate = new ErgoBoxCandidate(value, ErgoTree.fromProposition(prop), creationHeight) val fakeTxId = ModifierId @@ Base16.encode(Array.fill(32)(5: Byte)) val inputBox = boxCandidate.toBox(fakeTxId, 0.toShort) @@ -94,7 +95,7 @@ class ErgoProvingInterpreterSpec val value = 100000000L val creationHeight = 10000 - val boxCandidate = new ErgoBoxCandidate(value, pk, creationHeight) + val boxCandidate = new ErgoBoxCandidate(value, ErgoTree.fromSigmaBoolean(pk), creationHeight) val numOfInputs = 50 val fakeTxId = ModifierId @@ Base16.encode(Array.fill(32)(5: Byte)) diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/interpreter/InterpreterSpecCommon.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/interpreter/InterpreterSpecCommon.scala index 5f797a27d2..459f32f597 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/interpreter/InterpreterSpecCommon.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/interpreter/InterpreterSpecCommon.scala @@ -2,11 +2,14 @@ package org.ergoplatform.wallet.interpreter import org.ergoplatform.sdk.BlockchainParameters import org.ergoplatform.sdk.wallet.protocol.context.BlockchainStateContext +import org.ergoplatform.validation.ValidationRules import scorex.util.encode.Base16 -import sigmastate.crypto.CryptoConstants -import sigmastate.eval.Extensions.ArrayOps -import sigmastate.eval.{CGroupElement, CPreHeader} +import sigma.Extensions.ArrayOps +import sigma.crypto.CryptoConstants +import sigma.data.CGroupElement +import sigma.validation.SigmaValidationSettings import sigma.{Coll, Colls, Header, PreHeader} +import sigmastate.eval.CPreHeader trait InterpreterSpecCommon { @@ -35,7 +38,9 @@ trait InterpreterSpecCommon { override def blockVersion: Byte = 1 } - protected val stateContext = new BlockchainStateContext { + protected val stateContext = new VersionedBlockchainStateContext { + + override val sigmaValidationSettings: SigmaValidationSettings = ValidationRules.currentSettings override def sigmaLastHeaders: Coll[Header] = Colls.emptyColl diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/mnemonic/MnemonicSpec.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/mnemonic/MnemonicSpec.scala index aa6b40900b..eceb5aeadf 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/mnemonic/MnemonicSpec.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/mnemonic/MnemonicSpec.scala @@ -1,8 +1,8 @@ package org.ergoplatform.wallet.mnemonic +import org.ergoplatform.sdk.SecretString import java.text.Normalizer.Form.NFKD import java.text.Normalizer.normalize -import org.ergoplatform.wallet.interface4j.SecretString import org.scalatest.Assertion import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/DerivationPathSpec.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/DerivationPathSpec.scala index d754890c45..c4f8ddd3ba 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/DerivationPathSpec.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/DerivationPathSpec.scala @@ -1,8 +1,7 @@ package org.ergoplatform.wallet.secrets -import org.ergoplatform.sdk.wallet +import org.ergoplatform.sdk.{SecretString, wallet} import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedSecretKey} -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.mnemonic.Mnemonic import org.ergoplatform.{ErgoAddressEncoder, P2PKAddress} import org.scalatest.matchers.should.Matchers diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/ExtendedSecretKeySpec.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/ExtendedSecretKeySpec.scala index d59ff6c93a..53d000ea9f 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/ExtendedSecretKeySpec.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/ExtendedSecretKeySpec.scala @@ -1,8 +1,8 @@ package org.ergoplatform.wallet.secrets +import org.ergoplatform.sdk.SecretString import org.ergoplatform.{ErgoAddressEncoder, P2PKAddress} import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedSecretKey, Index} -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.mnemonic.Mnemonic import org.scalatest.Assertion import org.scalatest.matchers.should.Matchers diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/JsonSecretStorageSpec.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/JsonSecretStorageSpec.scala index 3a98cd5458..d408518d36 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/JsonSecretStorageSpec.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/secrets/JsonSecretStorageSpec.scala @@ -1,7 +1,7 @@ package org.ergoplatform.wallet.secrets +import org.ergoplatform.sdk.SecretString import org.ergoplatform.sdk.wallet.settings.EncryptionSettings -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.settings.SecretStorageSettings import org.ergoplatform.wallet.utils.FileUtils import org.scalacheck.Arbitrary diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/transactions/TransactionBuilderSpec.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/transactions/TransactionBuilderSpec.scala index f3bb1b4cbc..0578d3864d 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/transactions/TransactionBuilderSpec.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/transactions/TransactionBuilderSpec.scala @@ -2,20 +2,21 @@ package org.ergoplatform.wallet.transactions import org.ergoplatform.ErgoBox.TokenId import org.ergoplatform._ +import org.ergoplatform.sdk.SecretString import org.ergoplatform.sdk.wallet.TokensMap import org.ergoplatform.sdk.wallet.secrets.ExtendedSecretKey import org.ergoplatform.wallet.boxes.BoxSelector -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.mnemonic.Mnemonic import org.ergoplatform.wallet.utils.WalletTestHelpers import org.scalatest.matchers.should.Matchers -import sigmastate.Values -import sigmastate.Values.SigmaPropValue +import sigma.ast.{ErgoTree, TrueLeaf} +import sigma.ast.syntax.SigmaPropValue import sigmastate.eval.Extensions._ import sigmastate.eval._ import sigmastate.helpers.TestingHelpers._ import sigmastate.utils.Extensions._ import sigmastate.utils.Helpers._ +import sigma.Extensions.ArrayOps import scala.util.{Success, Try} @@ -35,20 +36,20 @@ class TransactionBuilderSpec extends WalletTestHelpers with Matchers { val minChangeValue = BoxSelector.MinBoxValue val minerRewardDelay = 720 - val TrueProp: SigmaPropValue = Values.TrueLeaf.toSigmaProp + val TrueProp: SigmaPropValue = TrueLeaf.toSigmaProp val tid1 = stringToId("t1") val tid2 = stringToId("t2") - def box(value: Long) = testBox(value, TrueProp, currentHeight) + def box(value: Long) = testBox(value, ErgoTree.fromProposition(TrueProp), currentHeight) def box(value: Long, tokens: Seq[(TokenId, Long)]) = - testBox(value, TrueProp, currentHeight, tokens) + testBox(value, ErgoTree.fromProposition(TrueProp), currentHeight, tokens) - def boxCandidate(value: Long) = new ErgoBoxCandidate(value, TrueProp, currentHeight) + def boxCandidate(value: Long) = new ErgoBoxCandidate(value, ErgoTree.fromProposition(TrueProp), currentHeight) def boxCandidate(value: Long, tokens: Seq[(TokenId, Long)]) = - new ErgoBoxCandidate(value, TrueProp, currentHeight, tokens.toColl) + new ErgoBoxCandidate(value, ErgoTree.fromProposition(TrueProp), currentHeight, tokens.toArray.toColl) def transaction(inputBox: ErgoBox, outBox: ErgoBoxCandidate, diff --git a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/utils/WalletGenerators.scala b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/utils/WalletGenerators.scala index f7256fd45a..b37799c153 100644 --- a/ergo-wallet/src/test/scala/org/ergoplatform/wallet/utils/WalletGenerators.scala +++ b/ergo-wallet/src/test/scala/org/ergoplatform/wallet/utils/WalletGenerators.scala @@ -3,7 +3,6 @@ package org.ergoplatform.wallet.utils import org.ergoplatform.ErgoBox.{BoxId, NonMandatoryRegisterId, TokenId} import org.ergoplatform.sdk.wallet.secrets._ import org.ergoplatform.sdk.wallet.settings.EncryptionSettings -import org.ergoplatform.wallet.Constants import org.ergoplatform.wallet.Constants.{PaymentsScanId, ScanId} import org.ergoplatform.wallet.boxes.TrackedBox import org.ergoplatform.wallet.mnemonic.{Mnemonic, WordList} @@ -12,13 +11,14 @@ import org.scalacheck.Arbitrary.arbByte import org.scalacheck.{Arbitrary, Gen} import scorex.crypto.authds.ADKey import scorex.util._ -import sigmastate.Values.{ByteArrayConstant, CollectionConstant, ErgoTree, EvaluatedValue, FalseLeaf, TrueLeaf} -import sigmastate.crypto.DLogProtocol.ProveDlog -import sigmastate.crypto.CryptoFacade.SecretKeyLength +import sigma.Extensions.ArrayOps +import sigma.ast.{ByteArrayConstant, ErgoTree, EvaluatedValue, FalseLeaf, SByte, SType, TrueLeaf} +import sigma.ast.syntax.CollectionConstant +import sigma.crypto.CryptoFacade.SecretKeyLength +import sigma.data.ProveDlog import sigmastate.eval.Extensions._ import sigmastate.eval._ import sigmastate.helpers.TestingHelpers._ -import sigmastate.{SByte, SType} object WalletGenerators { @@ -106,7 +106,7 @@ object WalletGenerators { Gen.choose(minValue, CoinsTotalTest / 1000) } - def ergoBoxGen(propGen: Gen[ErgoTree] = Gen.const(TrueLeaf.toSigmaProp), + def ergoBoxGen(propGen: Gen[ErgoTree] = Gen.const(ErgoTree.fromProposition(TrueLeaf.toSigmaProp)), tokensGen: Gen[Seq[(TokenId, Long)]] = additionalTokensGen, valueGenOpt: Option[Gen[Long]] = None, heightGen: Gen[Int] = heightGen): Gen[ErgoBox] = for { @@ -173,7 +173,7 @@ object WalletGenerators { def unsignedTxGen(secret: SecretKey): Gen[(IndexedSeq[ErgoBox], UnsignedErgoLikeTransaction)] = { - val dlog: Gen[ErgoTree] = Gen.const(secret.privateInput.publicImage.asInstanceOf[ProveDlog].toSigmaProp) + val dlog: Gen[ErgoTree] = Gen.const(ErgoTree.fromProposition(secret.privateInput.publicImage.asInstanceOf[ProveDlog])) for { ins <- Gen.listOfN(2, ergoBoxGen(dlog)) @@ -183,7 +183,7 @@ object WalletGenerators { value, ErgoTreePredef.feeProposition(), h, - Seq.empty[(ErgoBox.TokenId, Long)].toColl, + Array.empty[(ErgoBox.TokenId, Long)].toColl, Map.empty ) unsignedInputs = ins diff --git a/papers/whitepaper/img/batching/proofSizeFromBatchSize2.png b/papers/whitepaper/img/batching/proofSizeFromBatchSize2.png old mode 100755 new mode 100644 diff --git a/papers/whitepaper/img/batching/proofSizeFromTreeSize.png b/papers/whitepaper/img/batching/proofSizeFromTreeSize.png old mode 100755 new mode 100644 diff --git a/papers/whitepaper/img/proofSize.png b/papers/whitepaper/img/proofSize.png old mode 100755 new mode 100644 diff --git a/src/it/scala/org/ergoplatform/it/WalletSpec.scala b/src/it/scala/org/ergoplatform/it/WalletSpec.scala index 344b165e49..9b91de9417 100644 --- a/src/it/scala/org/ergoplatform/it/WalletSpec.scala +++ b/src/it/scala/org/ergoplatform/it/WalletSpec.scala @@ -10,22 +10,18 @@ import org.ergoplatform.it.api.NodeApi.UnexpectedStatusCodeException import org.ergoplatform.it.container.{IntegrationSuite, Node} import org.ergoplatform.it.util.RichEither import org.ergoplatform.modifiers.mempool.UnsignedErgoTransaction -import org.ergoplatform.nodeView.wallet.requests.{ - PaymentRequest, - RequestsHolder, - RequestsHolderEncoder -} import org.ergoplatform.nodeView.wallet.{AugWalletTransaction, ErgoWalletServiceImpl} +import org.ergoplatform.nodeView.wallet.requests.{PaymentRequest, RequestsHolder, RequestsHolderEncoder} +import org.ergoplatform.sdk.SecretString +import org.ergoplatform.settings.Constants.TrueTree import org.ergoplatform.settings.{Args, ErgoSettings, ErgoSettingsReader} import org.ergoplatform.utils.{ErgoTestHelpers, WalletTestOps} -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.boxes.ErgoBoxSerializer import org.ergoplatform.{ErgoBox, P2PKAddress} import org.scalatest.wordspec.AsyncWordSpec import scorex.util.ModifierId import scorex.util.encode.Base16 import sigma.Colls -import sigmastate.Values.{ErgoTree, TrueLeaf} import scala.concurrent.ExecutionContext @@ -104,13 +100,12 @@ class WalletSpec } "it should generate unsigned transaction" in { - import sigmastate.eval._ val mnemonic = SecretString.create(walletAutoInitConfig.getString("ergo.wallet.testMnemonic")) val prover = new ErgoWalletServiceImpl(settings) .buildProverFromMnemonic(mnemonic, None, parameters) val pk = prover.hdPubKeys.head.key - val ergoTree = ErgoTree.fromProposition(TrueLeaf) + val ergoTree = TrueTree val transactionId = ModifierId @@ Base16.encode(Array.fill(32)(5: Byte)) val input = new ErgoBox( 60000000, @@ -127,7 +122,7 @@ class WalletSpec val paymentRequest = PaymentRequest( P2PKAddress(pk)(settings.addressEncoder), 50000000, - Seq.empty, + Array.empty, Map.empty ) val requestsHolder = RequestsHolder( diff --git a/src/main/resources/api/openapi-ai.yaml b/src/main/resources/api/openapi-ai.yaml index 84d7cd411d..a912af79a4 100644 --- a/src/main/resources/api/openapi-ai.yaml +++ b/src/main/resources/api/openapi-ai.yaml @@ -1,7 +1,7 @@ openapi: "3.0.2" info: - version: "5.0.22" + version: "6.0.0" title: Ergo Node API description: Specification of Ergo Node API for ChatGPT plugin. The following endpoints supported diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml index f3f3545e72..3ab3213f02 100644 --- a/src/main/resources/api/openapi.yaml +++ b/src/main/resources/api/openapi.yaml @@ -1,7 +1,7 @@ openapi: "3.0.2" info: - version: "5.0.22" + version: "6.0.0" title: Ergo Node API description: API docs for Ergo Node. Models are shared between all Ergo products contact: diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 37c2406a53..159e49f37c 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -163,7 +163,7 @@ ergo { # Blockchain protocol version supported by the client. # Please do not increase this value manually, this should be done by client developers. - protocolVersion = 3 + protocolVersion = 4 # Network address prefix, currently reserved values are 0 (Ergo mainnet) and 16 (Ergo testnet) addressPrefix = 16 @@ -353,7 +353,7 @@ ergo { # Put any non-zero value here to vote for soft-fork, or zero to vote against. # 120 = 0 # Put an array of rules to deactivate with the soft-fork - "rulesToDisable" = [] + "rulesToDisable" = [215, 409] } } @@ -436,7 +436,7 @@ scorex { nodeName = "ergo-node" # Network protocol version to be sent in handshakes - appVersion = 5.0.22 + appVersion = 6.0.0 # Network agent name. May contain information about client code # stack, starting from core code-base up to the end graphical interface. diff --git a/src/main/resources/devnet.conf b/src/main/resources/devnet.conf index 0e44dbb6c9..eb2916e616 100644 --- a/src/main/resources/devnet.conf +++ b/src/main/resources/devnet.conf @@ -3,18 +3,26 @@ ergo { networkType = "devnet" + + node { + mining = true + offlineGeneration = true + useExternalMiner = false + } + chain { - protocolVersion = 3 # 5.0 soft-fork + protocolVersion = 4 # 6.0 soft-fork # Network address prefix, currently reserved values are 0 (money chain mainnet) and 16 (money chain testnet) - addressPrefix = 32 + addressPrefix = 16 + # A difficulty the network starts with initialDifficultyHex = "01" # Length of an epoch in difficulty recalculation. 1 means difficulty recalculation every block - epochLength = 64 + epochLength = 16 - blockInterval = 1s + blockInterval = 100ms # Monetary config for chain monetary { @@ -27,10 +35,10 @@ ergo { votingLength = 128 # Voting epochs to vote for soft-fork - softForkEpochs = 32 + softForkEpochs = 8 # Voting epochs to activate a soft-fork after acceptance - activationEpochs = 32 + activationEpochs = 8 # Activation height for testnet protocol version 2 (client version 4.0.0 hard-fork) version2ActivationHeight = 128 @@ -42,19 +50,21 @@ ergo { genesisStateDigestHex = "cb63aa99a3060f341781d8662b58bf18b9ad258db4fe88d09f8f71cb668cad4502" } wallet.secretStorage.secretDir = ${ergo.directory}"/wallet/keystore" + + voting { + 120 = 1 + } } scorex { network { - magicBytes = [2, 0, 4, 8] + magicBytes = [2, 2, 4, 4] bindAddress = "0.0.0.0:9021" nodeName = "ergo-devnet-2.1" nodeName = ${?NODENAME} knownPeers = [ - "157.230.80.125:9021", - "178.128.38.1:9021" ] } restApi { - apiKeyHash = null + apiKeyHash = "324dcf027dd4a30a932c441f365a25e86b173defa4b8e58948253471b81b72cf" } } \ No newline at end of file diff --git a/src/main/resources/testnet.conf b/src/main/resources/testnet.conf index 0d15c032a1..6aea5b2b00 100644 --- a/src/main/resources/testnet.conf +++ b/src/main/resources/testnet.conf @@ -30,7 +30,7 @@ ergo { } chain { - protocolVersion = 3 # 5.0 soft-fork + protocolVersion = 4 # 6.0 soft-fork # Network address prefix, currently reserved values are 0 (money chain mainnet) and 16 (money chain testnet) addressPrefix = 16 diff --git a/src/main/scala/org/ergoplatform/http/api/ApiRequestsCodecs.scala b/src/main/scala/org/ergoplatform/http/api/ApiRequestsCodecs.scala index 916a660eea..ec7a0ebc10 100644 --- a/src/main/scala/org/ergoplatform/http/api/ApiRequestsCodecs.scala +++ b/src/main/scala/org/ergoplatform/http/api/ApiRequestsCodecs.scala @@ -9,7 +9,7 @@ import org.ergoplatform.nodeView.wallet.requests.{ExternalSecret, GenerateCommit import org.ergoplatform.sdk.wallet.secrets.{DhtSecretKey, DlogSecretKey} import org.ergoplatform.wallet.interpreter.TransactionHintsBag import sigma.AnyValue -import sigmastate.Values.SigmaBoolean +import sigma.data.SigmaBoolean /** * JSON codecs for HTTP API requests related entities diff --git a/src/main/scala/org/ergoplatform/http/api/BlockchainApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/BlockchainApiRoute.scala index aa8e6aa7df..6af3830c5a 100644 --- a/src/main/scala/org/ergoplatform/http/api/BlockchainApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/BlockchainApiRoute.scala @@ -20,7 +20,7 @@ import org.ergoplatform.settings.{ErgoSettings, RESTApiSettings} import org.ergoplatform.http.api.ApiError.{BadRequest, InternalError} import scorex.core.api.http.ApiResponse import scorex.util.{ModifierId, bytesToId} -import sigmastate.Values.ErgoTree +import sigma.ast.ErgoTree import spire.implicits.cfor import scala.concurrent.duration.{Duration, SECONDS} diff --git a/src/main/scala/org/ergoplatform/http/api/ErgoBaseApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ErgoBaseApiRoute.scala index f12badfb0b..14d732654b 100644 --- a/src/main/scala/org/ergoplatform/http/api/ErgoBaseApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ErgoBaseApiRoute.scala @@ -9,15 +9,15 @@ import org.ergoplatform.nodeView.mempool.ErgoMemPoolReader import org.ergoplatform.nodeView.state.{ErgoStateReader, UtxoStateReader} import org.ergoplatform.settings.{Algos, ErgoSettings} import scorex.core.api.http.ApiRoute -import scorex.util.{bytesToId, ModifierId} +import scorex.util.{ModifierId, bytesToId} import akka.pattern.ask import io.circe.syntax.EncoderOps import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedTransaction import org.ergoplatform.nodeView.mempool.ErgoMemPoolUtils.ProcessingOutcome import org.ergoplatform.nodeView.mempool.ErgoMemPoolUtils.ProcessingOutcome._ import scorex.util.encode.Base16 -import sigmastate.Values.ErgoTree -import sigmastate.serialization.ErgoTreeSerializer +import sigma.ast.ErgoTree +import sigma.serialization.ErgoTreeSerializer import scala.concurrent.{ExecutionContextExecutor, Future} import scala.util.{Failure, Success, Try} diff --git a/src/main/scala/org/ergoplatform/http/api/ErgoUtilsApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ErgoUtilsApiRoute.scala index 87775dba7a..5305794ff2 100644 --- a/src/main/scala/org/ergoplatform/http/api/ErgoUtilsApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ErgoUtilsApiRoute.scala @@ -12,11 +12,11 @@ import scorex.core.api.http.{ApiResponse, ApiRoute} import org.ergoplatform.utils.ScorexEncoding import scorex.crypto.hash.Blake2b256 import scorex.util.encode.Base16 -import sigmastate.crypto.DLogProtocol.ProveDlog +import sigma.data.ProveDlog +import sigma.serialization.{ErgoTreeSerializer, GroupElementSerializer, SigmaSerializer} import java.security.SecureRandom import scala.util.Failure -import sigmastate.serialization.{ErgoTreeSerializer, GroupElementSerializer, SigmaSerializer} class ErgoUtilsApiRoute(val ergoSettings: ErgoSettings)( implicit val context: ActorRefFactory diff --git a/src/main/scala/org/ergoplatform/http/api/MiningApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/MiningApiRoute.scala index 89a7dbb280..dd645a8dc6 100644 --- a/src/main/scala/org/ergoplatform/http/api/MiningApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/MiningApiRoute.scala @@ -12,7 +12,7 @@ import org.ergoplatform.nodeView.wallet.ErgoAddressJsonEncoder import org.ergoplatform.settings.{ErgoSettings, RESTApiSettings} import org.ergoplatform.{ErgoAddress, ErgoTreePredef, Pay2SAddress} import scorex.core.api.http.ApiResponse -import sigmastate.crypto.DLogProtocol.ProveDlog +import sigma.data.ProveDlog import scala.concurrent.Future diff --git a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala index 752b4eb112..abc407338d 100644 --- a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala @@ -14,8 +14,8 @@ import ScanEntities._ import org.ergoplatform.ErgoBox.R1 import org.ergoplatform.http.api.ApiError.BadRequest import org.ergoplatform.wallet.Constants.ScanId -import sigmastate.Values.ByteArrayConstant -import sigmastate.serialization.ErgoTreeSerializer +import sigma.ast.ByteArrayConstant +import sigma.serialization.ErgoTreeSerializer /** * This class contains methods to register / deregister and list external scans, and also to serve them. diff --git a/src/main/scala/org/ergoplatform/http/api/ScriptApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ScriptApiRoute.scala index 3ab560a3c1..0f9bf90598 100644 --- a/src/main/scala/org/ergoplatform/http/api/ScriptApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ScriptApiRoute.scala @@ -9,20 +9,18 @@ import org.ergoplatform._ import org.ergoplatform.http.api.ApiError.BadRequest import org.ergoplatform.http.api.requests.{CryptoResult, ExecuteRequest} import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers} -import org.ergoplatform.nodeView.wallet.ErgoWalletReader import org.ergoplatform.nodeView.wallet.requests.PaymentRequestDecoder import org.ergoplatform.settings.{ErgoSettings, RESTApiSettings} import scorex.core.api.http.ApiResponse import scorex.util.encode.Base16 -import sigmastate.Values.{ByteArrayConstant, ErgoTree} -import sigmastate._ -import sigmastate.crypto.DLogProtocol.ProveDlog -import sigmastate.eval.CompiletimeIRContext +import sigma.VersionContext +import sigma.ast.{ByteArrayConstant, ErgoTree, SBoolean, SSigmaProp, Value} +import sigma.compiler.{CompilerResult, SigmaCompiler} +import sigma.compiler.ir.CompiletimeIRContext +import sigma.data.ProveDlog +import sigma.serialization.ValueSerializer import sigmastate.interpreter.Interpreter -import sigmastate.lang.{CompilerResult, SigmaCompiler} -import sigmastate.serialization.ValueSerializer -import scala.concurrent.Future import scala.concurrent.duration._ import scala.util.{Failure, Success, Try} @@ -59,38 +57,50 @@ case class ScriptApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings) keys.zipWithIndex.map { case (pk, i) => s"myPubKey_$i" -> pk }.toMap } - private def compileSource(source: String, env: Map[String, Any]): Try[ErgoTree] = { - import sigmastate.Values._ + private def compileSource(source: String, env: Map[String, Any], treeVersion: Int = 0): Try[ErgoTree] = { val compiler = new SigmaCompiler(ergoSettings.chainSettings.addressPrefix) + val ergoTreeHeader = ErgoTree.defaultHeaderWithVersion(treeVersion.toByte) Try(compiler.compile(env, source)(new CompiletimeIRContext)).flatMap { case CompilerResult(_, _, _, script: Value[SSigmaProp.type@unchecked]) if script.tpe == SSigmaProp => - Success(script) + Success(ErgoTree.fromProposition(ergoTreeHeader, script)) case CompilerResult(_, _, _, script: Value[SBoolean.type@unchecked]) if script.tpe == SBoolean => - Success(script.toSigmaProp) + Success(ErgoTree.fromProposition(ergoTreeHeader, script.toSigmaProp)) case other => Failure(new Exception(s"Source compilation result is of type ${other.buildTree.tpe}, but `SBoolean` expected")) } } - private def withWalletOp[T](op: ErgoWalletReader => Future[T])(toRoute: T => Route): Route = { - onSuccess((readersHolder ? GetReaders).mapTo[Readers].flatMap(r => op(r.w)))(toRoute) + private def withWalletAndStateOp[T](op: (Readers) => T)(toRoute: T => Route): Route = { + onSuccess((readersHolder ? GetReaders).mapTo[Readers].map(r => op(r)))(toRoute) } + // todo: unite p2sAddress and p2shAddress def p2sAddressR: Route = (path("p2sAddress") & post & source) { source => - withWalletOp(_.publicKeys(0, loadMaxKeys)) { addrs => - compileSource(source, keysToEnv(addrs.map(_.pubkey))).map(Pay2SAddress.apply).fold( - e => BadRequest(e.getMessage), - address => ApiResponse(addressResponse(address)) - ) + withWalletAndStateOp(r => (r.w.publicKeys(0, loadMaxKeys), r.s.stateContext)) { case (addrsF, sc) => + onSuccess(addrsF) { addrs => + val version = VersionContext.fromBlockVersion(sc.blockVersion) + VersionContext.withVersions(version.activatedVersion, version.ergoTreeVersion) { + // todo: treeVersion == 1 is used here, revisit, likely 0 should be default for now + compileSource(source, keysToEnv(addrs.map(_.pubkey)), 1).map(Pay2SAddress.apply).fold( + e => BadRequest(e.getMessage), + address => ApiResponse(addressResponse(address)) + ) + } + } } } def p2shAddressR: Route = (path("p2shAddress") & post & source) { source => - withWalletOp(_.publicKeys(0, loadMaxKeys)) { addrs => - compileSource(source, keysToEnv(addrs.map(_.pubkey))).map(Pay2SHAddress.apply).fold( - e => BadRequest(e.getMessage), - address => ApiResponse(addressResponse(address)) - ) + withWalletAndStateOp(r => (r.w.publicKeys(0, loadMaxKeys), r.s.stateContext.blockVersion)) { case (addrsF, bv) => + onSuccess(addrsF) { addrs => + val version = VersionContext.fromBlockVersion(bv) + VersionContext.withVersions(version.activatedVersion, version.ergoTreeVersion) { + compileSource(source, keysToEnv(addrs.map(_.pubkey))).map(Pay2SHAddress.apply).fold( + e => BadRequest(e.getMessage), + address => ApiResponse(addressResponse(address)) + ) + } + } } } diff --git a/src/main/scala/org/ergoplatform/http/api/TransactionsApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/TransactionsApiRoute.scala index 0cc95f24a3..8c1ff76b8a 100644 --- a/src/main/scala/org/ergoplatform/http/api/TransactionsApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/TransactionsApiRoute.scala @@ -17,8 +17,7 @@ import org.ergoplatform.settings.{Algos, ErgoSettings, RESTApiSettings} import scorex.core.api.http.ApiResponse import scorex.crypto.authds.ADKey import scorex.util.encode.Base16 -import sigmastate.SType -import sigmastate.Values.EvaluatedValue +import sigma.ast.{EvaluatedValue, SType} import sigmastate.eval.Extensions.ArrayByteOps import scala.concurrent.Future diff --git a/src/main/scala/org/ergoplatform/http/api/WalletApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/WalletApiRoute.scala index 6a090e42d7..1232e882fd 100644 --- a/src/main/scala/org/ergoplatform/http/api/WalletApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/WalletApiRoute.scala @@ -12,7 +12,6 @@ import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers} import org.ergoplatform.nodeView.wallet._ import org.ergoplatform.nodeView.wallet.requests._ import org.ergoplatform.settings.{ErgoSettings, RESTApiSettings} -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.Constants import org.ergoplatform.wallet.Constants.ScanId import org.ergoplatform.wallet.boxes.ErgoBoxSerializer @@ -24,6 +23,7 @@ import scala.concurrent.Future import scala.concurrent.duration._ import scala.util.{Failure, Success, Try} import akka.http.scaladsl.server.MissingQueryParamRejection +import org.ergoplatform.sdk.SecretString case class WalletApiRoute(readersHolder: ActorRef, nodeViewActorRef: ActorRef, @@ -152,7 +152,7 @@ case class WalletApiRoute(readersHolder: ActorRef, private def withFee(requests: Seq[TransactionGenerationRequest]): Seq[TransactionGenerationRequest] = { requests :+ PaymentRequest(Pay2SAddress(ergoSettings.chainSettings.monetary.feeProposition), - ergoSettings.walletSettings.defaultTransactionFee, Seq.empty, Map.empty) + ergoSettings.walletSettings.defaultTransactionFee, Array.empty, Map.empty) } private def generateTransactionAndProcess(requests: Seq[TransactionGenerationRequest], diff --git a/src/main/scala/org/ergoplatform/http/api/requests/CryptoResult.scala b/src/main/scala/org/ergoplatform/http/api/requests/CryptoResult.scala index 0df36c67d7..d06e827ebb 100644 --- a/src/main/scala/org/ergoplatform/http/api/requests/CryptoResult.scala +++ b/src/main/scala/org/ergoplatform/http/api/requests/CryptoResult.scala @@ -1,6 +1,7 @@ package org.ergoplatform.http.api.requests -import sigmastate.Values.SigmaBoolean +import sigma.data.SigmaBoolean + /** * Result of reduction of ErgoTree for context provided (used in /script/executeWithContext) diff --git a/src/main/scala/org/ergoplatform/http/api/requests/HintExtractionRequest.scala b/src/main/scala/org/ergoplatform/http/api/requests/HintExtractionRequest.scala index e3e6162e63..799771ae36 100644 --- a/src/main/scala/org/ergoplatform/http/api/requests/HintExtractionRequest.scala +++ b/src/main/scala/org/ergoplatform/http/api/requests/HintExtractionRequest.scala @@ -1,7 +1,7 @@ package org.ergoplatform.http.api.requests import org.ergoplatform.modifiers.mempool.ErgoTransaction -import sigmastate.Values.SigmaBoolean +import sigma.data.SigmaBoolean /** * Represent a request for extracting prover hints from transaction. diff --git a/src/main/scala/org/ergoplatform/local/ErgoStatsCollector.scala b/src/main/scala/org/ergoplatform/local/ErgoStatsCollector.scala index 39091b904a..e7ece1a034 100644 --- a/src/main/scala/org/ergoplatform/local/ErgoStatsCollector.scala +++ b/src/main/scala/org/ergoplatform/local/ErgoStatsCollector.scala @@ -12,7 +12,7 @@ import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers} import org.ergoplatform.nodeView.history.ErgoHistory import org.ergoplatform.nodeView.history.ErgoHistoryUtils._ import org.ergoplatform.nodeView.state.{ErgoStateReader, StateType} -import org.ergoplatform.settings.{Algos, ErgoSettings, LaunchParameters, Parameters} +import org.ergoplatform.settings.{Algos, ErgoSettings, Parameters} import scorex.core.network.ConnectedPeer import scorex.core.network.NetworkController.ReceivableMessages.{GetConnectedPeers, GetPeersStatus} import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages._ @@ -63,7 +63,7 @@ class ErgoStatsCollector(readersHolder: ActorRef, launchTime = System.currentTimeMillis(), lastIncomingMessageTime = System.currentTimeMillis(), None, - LaunchParameters, + settings.launchParameters, eip27Supported = true, settings.scorexSettings.restApi.publicUrl, settings.nodeSettings.extraIndex) diff --git a/src/main/scala/org/ergoplatform/mining/CandidateGenerator.scala b/src/main/scala/org/ergoplatform/mining/CandidateGenerator.scala index a42b50e6db..27b87bed7b 100644 --- a/src/main/scala/org/ergoplatform/mining/CandidateGenerator.scala +++ b/src/main/scala/org/ergoplatform/mining/CandidateGenerator.scala @@ -27,12 +27,12 @@ import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, ErgoTreePredef, Input} import scorex.crypto.hash.Digest32 import scorex.util.encode.Base16 import scorex.util.{ModifierId, ScorexLogging} -import sigmastate.ErgoBoxRType -import sigmastate.crypto.DLogProtocol.ProveDlog -import sigmastate.crypto.CryptoFacade -import sigmastate.eval.Extensions._ -import sigmastate.eval._ -import sigmastate.interpreter.ProverResult +import sigma.ast.syntax.ErgoBoxRType +import sigma.Extensions.ArrayOps +import sigma.crypto.CryptoFacade +import sigma.data.{Digest32Coll, ProveDlog} +import sigma.interpreter.ProverResult +import sigma.validation.ReplacedRule import sigma.{Coll, Colls} import scala.annotation.tailrec @@ -356,7 +356,16 @@ object CandidateGenerator extends ScorexLogging { ) None } else { - val desiredUpdate = ergoSettings.votingTargets.desiredUpdate + val desiredUpdate = if (stateContext.blockVersion == 3) { + ergoSettings.votingTargets.desiredUpdate.copy(statusUpdates = + // todo: do new rules to replace old ones, with the same behavior + // 1007 is needed to switch off primitive type validation to add Unsigned Big Int support + // 1008 is needed to switch off non-primitive type validation to add Option & Header types support + // 1011 is needed to add new methods + Seq(1011.toShort -> ReplacedRule(1016), 1007.toShort -> ReplacedRule(1017), 1008.toShort -> ReplacedRule(1018))) + } else { + ergoSettings.votingTargets.desiredUpdate + } Some( createCandidate( pk, @@ -399,8 +408,10 @@ object CandidateGenerator extends ScorexLogging { val nextHeightCondition = if (ergoSettings.networkType.isMainNet) { nextHeight >= 823297 // mainnet voting start height, first block of epoch #804 + } else if(ergoSettings.networkType.isTestNet) { + nextHeight >= 1548800 // testnet voting start height } else { - nextHeight >= 4096 + nextHeight >= 8 // devnet voting start height } // we automatically vote for 5.0 soft-fork in the mainnet if 120 = 0 vote not provided in settings @@ -410,10 +421,6 @@ object CandidateGenerator extends ScorexLogging { ergoSettings.votingTargets.softForkOption.getOrElse(0) == 1 } - //todo: remove after 5.0 soft-fork activation - log.debug(s"betterVersion: $betterVersion, forkVotingAllowed: $forkVotingAllowed, " + - s"forkOrdered: $forkOrdered, nextHeightCondition: $nextHeightCondition") - betterVersion && forkVotingAllowed && forkOrdered && @@ -427,7 +434,6 @@ object CandidateGenerator extends ScorexLogging { * @param history - blockchain reader (to extract parent) * @param proposedUpdate - votes for parameters update or/and soft-fork * @param state - UTXO set reader - * @param timeProvider - network time provider * @param poolTxs - memory pool transactions * @param emissionTxOpt - optional emission transaction * @param prioritizedTransactions - transactions which are going into the block in the first place @@ -746,7 +752,7 @@ object CandidateGenerator extends ScorexLogging { val feeTxOpt: Option[ErgoTransaction] = if (feeBoxes.nonEmpty) { val feeAmount = feeBoxes.map(_.value).sum val feeAssets = - feeBoxes.toColl.flatMap(_.additionalTokens).take(MaxAssetsPerBox) + feeBoxes.toArray.toColl.flatMap(_.additionalTokens).take(MaxAssetsPerBox) val inputs = feeBoxes.map(b => new Input(b.id, ProverResult.empty)) val minerBox = new ErgoBoxCandidate(feeAmount, minerProp, nextHeight, feeAssets, Map()) diff --git a/src/main/scala/org/ergoplatform/mining/ErgoMiner.scala b/src/main/scala/org/ergoplatform/mining/ErgoMiner.scala index 82b8630abd..4b970ecdb2 100644 --- a/src/main/scala/org/ergoplatform/mining/ErgoMiner.scala +++ b/src/main/scala/org/ergoplatform/mining/ErgoMiner.scala @@ -10,7 +10,8 @@ import org.ergoplatform.settings.ErgoSettings import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.GetDataFromCurrentView import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages.FullBlockApplied import scorex.util.ScorexLogging -import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog} +import sigma.data.ProveDlog +import sigmastate.crypto.DLogProtocol.DLogProverInput import scala.concurrent.duration._ import scala.util.{Failure, Success} diff --git a/src/main/scala/org/ergoplatform/network/ErgoNodeViewSynchronizer.scala b/src/main/scala/org/ergoplatform/network/ErgoNodeViewSynchronizer.scala index e2a550282a..696f41739f 100644 --- a/src/main/scala/org/ergoplatform/network/ErgoNodeViewSynchronizer.scala +++ b/src/main/scala/org/ergoplatform/network/ErgoNodeViewSynchronizer.scala @@ -36,6 +36,7 @@ import org.ergoplatform.modifiers.history.extension.{Extension, ExtensionSeriali import org.ergoplatform.modifiers.transaction.TooHighCostError import org.ergoplatform.serialization.{ErgoSerializer, ManifestSerializer, SubtreeSerializer} import scorex.crypto.authds.avltree.batch.VersionedLDBAVLStorage.splitDigest +import sigma.VersionContext import scala.annotation.tailrec import scala.collection.mutable @@ -192,7 +193,7 @@ class ErgoNodeViewSynchronizer(networkControllerRef: ActorRef, */ private def processFirstTxProcessingCacheRecord(): Unit = { txProcessingCache.headOption.foreach { case (txId, processingCacheRecord) => - parseAndProcessTransaction(txId, processingCacheRecord.txBytes, processingCacheRecord.source) + parseAndProcessTransaction(txId, processingCacheRecord.txBytes, fullBlockHeight = 0, remote = processingCacheRecord.source) txProcessingCache -= txId } } @@ -679,6 +680,7 @@ class ErgoNodeViewSynchronizer(networkControllerRef: ActorRef, } private def transactionsFromRemote(requestedModifiers: Map[ModifierId, Array[Byte]], + hr: ErgoHistory, mp: ErgoMemPool, remote: ConnectedPeer): Unit = { // filter out transactions already in the mempool @@ -694,7 +696,7 @@ class ErgoNodeViewSynchronizer(networkControllerRef: ActorRef, } toProcess.foreach { case (txId, txBytes) => - parseAndProcessTransaction(txId, txBytes, remote) + parseAndProcessTransaction(txId, txBytes, hr.fullBlockHeight, remote) } toPutIntoCache.foreach { case (txId, txBytes) => txProcessingCache.put(txId, new TransactionProcessingCacheRecord(txBytes, remote)) @@ -753,7 +755,7 @@ class ErgoNodeViewSynchronizer(networkControllerRef: ActorRef, val requestedModifiers = processSpam(remote, typeId, modifiers, blockAppliedTxsCache) if (typeId == ErgoTransaction.modifierTypeId) { - transactionsFromRemote(requestedModifiers, mp, remote) + transactionsFromRemote(requestedModifiers, hr, mp, remote) } else { blockSectionsFromRemote(hr, typeId, requestedModifiers, remote) } @@ -763,14 +765,22 @@ class ErgoNodeViewSynchronizer(networkControllerRef: ActorRef, * Parse transaction coming from remote, filtering out immediately too big one, and send parsed transaction * to mempool for processing */ - def parseAndProcessTransaction(id: ModifierId, bytes: Array[Byte], remote: ConnectedPeer): Unit = { + // todo: remove 6.0 versioning logic and fullBlockHeight after 6.0 activation + def parseAndProcessTransaction(id: ModifierId, bytes: Array[Byte], fullBlockHeight: Int, remote: ConnectedPeer): Unit = { if (bytes.length > settings.nodeSettings.maxTransactionSize) { deliveryTracker.setInvalid(id, ErgoTransaction.modifierTypeId) penalizeMisbehavingPeer(remote) log.warn(s"Transaction size ${bytes.length} from ${remote.toString} " + s"exceeds limit ${settings.nodeSettings.maxTransactionSize}") } else { - ErgoTransactionSerializer.parseBytesTry(bytes) match { + val scriptVersion = if (fullBlockHeight > Header.interpreter60VersionActivationHeight(settings.networkType.verboseName)) { + VersionContext.V6SoftForkVersion + } else { + VersionContext.JitActivationVersion + } + // tree version is properly set in ErgoTreeSerializer inside + val parseResult = VersionContext.withVersions(scriptVersion, scriptVersion)(ErgoTransactionSerializer.parseBytesTry(bytes)) + parseResult match { case Success(tx) if id == tx.id => val utx = UnconfirmedTransaction(tx, bytes, Some(remote)) viewHolderRef ! TransactionFromRemote(utx) diff --git a/src/main/scala/org/ergoplatform/nodeView/ErgoNodeViewHolder.scala b/src/main/scala/org/ergoplatform/nodeView/ErgoNodeViewHolder.scala index e68b9d4693..4eec4f5970 100644 --- a/src/main/scala/org/ergoplatform/nodeView/ErgoNodeViewHolder.scala +++ b/src/main/scala/org/ergoplatform/nodeView/ErgoNodeViewHolder.scala @@ -13,7 +13,7 @@ import org.ergoplatform.nodeView.mempool.ErgoMemPoolUtils.ProcessingOutcome import org.ergoplatform.nodeView.state._ import org.ergoplatform.nodeView.wallet.ErgoWallet import org.ergoplatform.wallet.utils.FileUtils -import org.ergoplatform.settings.{Algos, Constants, ErgoSettings, LaunchParameters, NetworkType, ScorexSettings} +import org.ergoplatform.settings.{Algos, Constants, ErgoSettings, NetworkType, ScorexSettings} import org.ergoplatform.core._ import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages._ import org.ergoplatform.nodeView.ErgoNodeViewHolder.{BlockAppliedTransactions, CurrentView, DownloadRequest} @@ -414,8 +414,7 @@ abstract class ErgoNodeViewHolder[State <: ErgoState[State]](settings: ErgoSetti val history = ErgoHistory.readOrGenerate(settings) - val wallet = ErgoWallet.readOrGenerate( - history.getReader, settings, LaunchParameters) + val wallet = ErgoWallet.readOrGenerate(history.getReader, settings, settings.launchParameters) val memPool = ErgoMemPool.empty(settings) diff --git a/src/main/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexer.scala b/src/main/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexer.scala index dbda566f34..b2d33c4eeb 100644 --- a/src/main/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexer.scala +++ b/src/main/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexer.scala @@ -15,8 +15,8 @@ import org.ergoplatform.nodeView.history.extra.IndexedTokenSerializer.uniqueId import org.ergoplatform.nodeView.history.storage.HistoryStorage import org.ergoplatform.settings.{Algos, CacheSettings, ChainSettings} import scorex.util.{ModifierId, ScorexLogging, bytesToId} -import sigmastate.Values.ErgoTree import sigma.Extensions._ +import sigma.ast.ErgoTree import java.nio.ByteBuffer import scala.collection.mutable.ArrayBuffer diff --git a/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedErgoAddress.scala b/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedErgoAddress.scala index c95acc381d..33e932a0b4 100644 --- a/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedErgoAddress.scala +++ b/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedErgoAddress.scala @@ -8,7 +8,7 @@ import org.ergoplatform.settings.Algos import org.ergoplatform.serialization.ErgoSerializer import scorex.util.{ModifierId, bytesToId} import scorex.util.serialization.{Reader, Writer} -import sigmastate.Values.ErgoTree +import sigma.ast.ErgoTree import scala.collection.mutable.ArrayBuffer diff --git a/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedToken.scala b/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedToken.scala index e29b0fc04d..7175a0fdde 100644 --- a/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedToken.scala +++ b/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedToken.scala @@ -9,9 +9,9 @@ import org.ergoplatform.settings.Algos import org.ergoplatform.serialization.ErgoSerializer import scorex.util.{ModifierId, bytesToId} import scorex.util.serialization.{Reader, Writer} -import sigmastate.Values.CollectionConstant -import sigmastate.SByte import sigma.Extensions._ +import sigma.ast.SByte +import sigma.ast.syntax.CollectionConstant import scala.collection.mutable.ArrayBuffer diff --git a/src/main/scala/org/ergoplatform/nodeView/state/ErgoState.scala b/src/main/scala/org/ergoplatform/nodeView/state/ErgoState.scala index 31362aa4d2..3adef8c30e 100644 --- a/src/main/scala/org/ergoplatform/nodeView/state/ErgoState.scala +++ b/src/main/scala/org/ergoplatform/nodeView/state/ErgoState.scala @@ -12,20 +12,20 @@ import org.ergoplatform.modifiers.mempool.ErgoTransaction import org.ergoplatform.modifiers.state.StateChanges import org.ergoplatform.nodeView.history.ErgoHistoryUtils._ import org.ergoplatform.settings.ValidationRules._ -import org.ergoplatform.settings.{ChainSettings, Constants, ErgoSettings, LaunchParameters, NodeConfigurationSettings} +import org.ergoplatform.settings.{ChainSettings, ErgoSettings, NodeConfigurationSettings} import org.ergoplatform.wallet.interpreter.ErgoInterpreter import org.ergoplatform.validation.ValidationResult.Valid import org.ergoplatform.validation.{ModifierValidator, ValidationResult} import org.ergoplatform.core.{VersionTag, idToVersion} import org.ergoplatform.nodeView.LocallyGeneratedModifier +import org.ergoplatform.settings.Constants.FalseTree import scorex.crypto.authds.avltree.batch.{Insert, Lookup, Remove} import scorex.crypto.authds.{ADDigest, ADValue} import scorex.util.encode.Base16 import scorex.util.{ModifierId, ScorexLogging, bytesToId} -import sigmastate.AtLeast -import sigmastate.Values.{ByteArrayConstant, ErgoTree, IntConstant, SigmaPropConstant} -import sigmastate.crypto.DLogProtocol.ProveDlog -import sigmastate.serialization.ValueSerializer +import sigma.ast.{AtLeast, ByteArrayConstant, ErgoTree, IntConstant, SigmaPropConstant} +import sigma.data.{CSigmaDslBuilder, ProveDlog} +import sigma.serialization.ValueSerializer import spire.syntax.all.cfor import scala.annotation.tailrec @@ -126,6 +126,7 @@ object ErgoState extends ScorexLogging { case Success(box) => collectBoxesById(remainingBoxIds, resultingBoxes.map(_ += box)) case Failure(ex) => + println("box not found") Failure(ex) } } @@ -205,7 +206,6 @@ object ErgoState extends ScorexLogging { ergoTree: ErgoTree, additionalTokens: Seq[(TokenId, Long)] = Seq.empty, additionalRegisters: AdditionalRegisters = Map.empty): ErgoBox = { - import sigmastate.eval._ val creationHeight: Int = EmptyHistoryHeight @@ -213,7 +213,7 @@ object ErgoState extends ScorexLogging { val boxIndex: Short = 0: Short new ErgoBox(value, ergoTree, - CostingSigmaDslBuilder.Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]), + CSigmaDslBuilder.Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]), additionalRegisters, transactionId, boxIndex, creationHeight) } @@ -252,7 +252,7 @@ object ErgoState extends ScorexLogging { private def noPremineBox(chainSettings: ChainSettings): ErgoBox = { val proofsBytes = chainSettings.noPremineProof.map(b => ByteArrayConstant(b.getBytes("UTF-8"))) val proofs = ErgoBox.nonMandatoryRegisters.zip(proofsBytes).toMap - createGenesisBox(EmissionRules.CoinsInOneErgo, Constants.FalseLeaf, Seq.empty, proofs) + createGenesisBox(EmissionRules.CoinsInOneErgo, FalseTree, Seq.empty, proofs) } /** @@ -274,8 +274,7 @@ object ErgoState extends ScorexLogging { val boxes = genesisBoxes(settings.chainSettings) val bh = BoxHolder(boxes) - UtxoState.fromBoxHolder(bh, boxes.headOption, stateDir, settings, LaunchParameters).ensuring(us => { - log.info(s"Genesis UTXO state generated with hex digest ${Base16.encode(us.rootDigest)}") + UtxoState.fromBoxHolder(bh, boxes.headOption, stateDir, settings, settings.launchParameters).ensuring(us => { java.util.Arrays.equals(us.rootDigest, settings.chainSettings.genesisStateDigest) && us.version == genesisStateVersion }) -> bh } diff --git a/src/main/scala/org/ergoplatform/nodeView/state/ErgoStateReader.scala b/src/main/scala/org/ergoplatform/nodeView/state/ErgoStateReader.scala index 9b57c853cf..b044737d84 100644 --- a/src/main/scala/org/ergoplatform/nodeView/state/ErgoStateReader.scala +++ b/src/main/scala/org/ergoplatform/nodeView/state/ErgoStateReader.scala @@ -3,7 +3,7 @@ package org.ergoplatform.nodeView.state import org.ergoplatform.{ErgoBox, NodeViewComponent} import org.ergoplatform.nodeView.history.ErgoHistoryUtils.Height import org.ergoplatform.nodeView.history.ErgoHistoryReader -import org.ergoplatform.settings.{Algos, Constants, ErgoSettings, LaunchParameters, Parameters} +import org.ergoplatform.settings.{Algos, Constants, ErgoSettings, Parameters} import org.ergoplatform.core.VersionTag import scorex.crypto.authds.ADDigest import scorex.crypto.hash.Digest32 @@ -69,14 +69,15 @@ object ErgoStateReader extends ScorexLogging { .flatMap(b => ErgoStateContextSerializer(settings.chainSettings).parseBytesTry(b).toOption) .getOrElse { log.warn("Can't read blockchain parameters from database") - ErgoStateContext.empty(settings.chainSettings, LaunchParameters) + ErgoStateContext.empty(settings.chainSettings, settings.launchParameters) } } /** * Method to reconstruct state context (used in scripts execution) corresponding to last block of a voting epoch, - * except of voting-defined blockchain parameters. Basically, this method is setting proper last headers. - * Then the first block of a new epoch will set the parameters. + * except of voting-defined blockchain parameters and protocol version. Basically, this method is setting + * proper last headers. Then the first block of a new epoch will set the parameters. + * * @param historyReader - history reader to get heights from * @param height - height for which state context will be reconstructed * @param settings - chain and node settings @@ -94,7 +95,7 @@ object ErgoStateReader extends ScorexLogging { if (lastHeaders.size != Constants.LastHeadersInContext) { Failure(new Exception(s"Only ${lastHeaders.size} headers found in reconstructStateContextBeforeEpoch")) } else { - val empty = ErgoStateContext.empty(settings.chainSettings, LaunchParameters) + val empty = ErgoStateContext.empty(settings.chainSettings, settings.launchParameters) val esc = new ErgoStateContext( lastHeaders, None, empty.genesisStateDigest, diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActor.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActor.scala index c65599f212..6dfb6ebc0d 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActor.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActor.scala @@ -13,12 +13,13 @@ import org.ergoplatform.sdk.wallet.secrets.DerivationPath import org.ergoplatform.settings._ import org.ergoplatform.wallet.Constants.ScanId import org.ergoplatform.wallet.boxes.BoxSelector -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.nodeView.wallet.ErgoWalletActorMessages._ import org.ergoplatform._ import org.ergoplatform.core.VersionTag +import org.ergoplatform.sdk.SecretString import org.ergoplatform.utils.ScorexEncoding import scorex.util.ScorexLogging + import scala.concurrent.duration._ import scala.util.{Failure, Success} diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActorMessages.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActorMessages.scala index c1f12a4941..a5b3d470fe 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActorMessages.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActorMessages.scala @@ -10,13 +10,14 @@ import org.ergoplatform.nodeView.wallet.scanning.{Scan, ScanRequest} import org.ergoplatform.sdk.wallet.secrets.DerivationPath import org.ergoplatform.wallet.Constants.ScanId import org.ergoplatform.wallet.boxes.ChainStatus -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.interpreter.TransactionHintsBag import org.ergoplatform._ import org.ergoplatform.core.VersionTag +import org.ergoplatform.sdk.SecretString import scorex.util.ModifierId -import sigmastate.Values.SigmaBoolean -import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog} +import sigma.data.{ProveDlog, SigmaBoolean} +import sigmastate.crypto.DLogProtocol.DLogProverInput + import scala.util.Try /** diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletReader.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletReader.scala index ca8fa867d0..c566a6fd15 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletReader.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletReader.scala @@ -10,15 +10,15 @@ import org.ergoplatform.nodeView.wallet.ErgoWalletServiceUtils.DeriveNextKeyResu import org.ergoplatform.nodeView.wallet.persistence.WalletDigest import org.ergoplatform.nodeView.wallet.requests.{BoxesRequest, ExternalSecret, TransactionGenerationRequest} import org.ergoplatform.nodeView.wallet.scanning.ScanRequest +import org.ergoplatform.sdk.SecretString import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedPublicKey} import org.ergoplatform.wallet.Constants.ScanId import org.ergoplatform.wallet.boxes.ChainStatus import org.ergoplatform.wallet.boxes.ChainStatus.{OffChain, OnChain} -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.interpreter.TransactionHintsBag import org.ergoplatform.{ErgoBox, NodeViewComponent, P2PKAddress} import scorex.util.ModifierId -import sigmastate.Values.SigmaBoolean +import sigma.data.SigmaBoolean import sigmastate.crypto.DLogProtocol.DLogProverInput import java.util.concurrent.TimeUnit diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletService.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletService.scala index 04173ca03c..3ddcdc255b 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletService.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletService.scala @@ -11,20 +11,20 @@ import org.ergoplatform.nodeView.wallet.models.{ChangeBox, CollectedBoxes} import org.ergoplatform.nodeView.wallet.persistence.{WalletRegistry, WalletStorage} import org.ergoplatform.nodeView.wallet.requests.{ExternalSecret, TransactionGenerationRequest} import org.ergoplatform.nodeView.wallet.scanning.{Scan, ScanRequest} +import org.ergoplatform.sdk.SecretString import org.ergoplatform.sdk.wallet.secrets.DerivationPath import org.ergoplatform.settings.{ErgoSettings, Parameters} import org.ergoplatform.wallet.Constants.ScanId import org.ergoplatform.wallet.boxes.{BoxSelector, TrackedBox} -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.interpreter.{ErgoProvingInterpreter, TransactionHintsBag} import org.ergoplatform.wallet.mnemonic.Mnemonic import org.ergoplatform.wallet.secrets.JsonSecretStorage import org.ergoplatform.wallet.settings.SecretStorageSettings import org.ergoplatform.wallet.utils.FileUtils import scorex.util.ModifierId -import sigmastate.Values.SigmaBoolean import sigmastate.crypto.DLogProtocol.DLogProverInput import sigma.Extensions.CollBytesOps +import sigma.data.SigmaBoolean import java.io.FileNotFoundException import scala.collection.compat.immutable.ArraySeq diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSupport.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSupport.scala index 2854306ddd..1202bc3ec3 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSupport.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSupport.scala @@ -8,6 +8,7 @@ import org.ergoplatform.modifiers.mempool.UnsignedErgoTransaction import org.ergoplatform.nodeView.wallet.ErgoWalletServiceUtils.DeriveNextKeyResult import org.ergoplatform.nodeView.wallet.persistence.WalletStorage import org.ergoplatform.nodeView.wallet.requests._ +import org.ergoplatform.sdk.SecretString import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedPublicKey, ExtendedSecretKey} import org.ergoplatform.sdk.wallet.{AssetUtils, TokensMap} import org.ergoplatform.settings.{ErgoSettings, Parameters} @@ -15,16 +16,15 @@ import org.ergoplatform.utils.BoxUtils import org.ergoplatform.wallet.Constants.PaymentsScanId import org.ergoplatform.wallet.boxes.BoxSelector.BoxSelectionResult import org.ergoplatform.wallet.boxes.{BoxSelector, TrackedBox} -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.interpreter.ErgoProvingInterpreter import org.ergoplatform.wallet.mnemonic.Mnemonic import org.ergoplatform.wallet.transactions.TransactionBuilder import scorex.util.ScorexLogging import sigma.Colls -import sigmastate.Values.ByteArrayConstant -import sigmastate.crypto.DLogProtocol.ProveDlog +import sigma.ast.{ByteArrayConstant, ErgoTree} import sigmastate.eval.Extensions._ -import sigmastate.eval._ +import sigma.Extensions.ArrayOps +import sigma.data.ProveDlog import sigmastate.utils.Extensions._ import scala.util.{Failure, Success, Try} @@ -101,7 +101,7 @@ trait ErgoWalletSupport extends ScorexLogging { // merge tokens from burn request with auto-burn mechanism private def mergeBurnWhitelistTokens(state: ErgoWalletState, - inputBoxes: Seq[TrackedBox], + inputBoxes: Array[TrackedBox], burnTokensRequestMap: TokensMap): TokensMap = { val input = inputBoxes.flatMap(_.tokens) state.walletVars.settings.walletSettings.tokensWhitelist match { @@ -254,8 +254,8 @@ trait ErgoWalletSupport extends ScorexLogging { case changeBox: ErgoBoxAssets => // todo: is this extra check needed ? val reemissionTokenId = ergoSettings.chainSettings.reemission.reemissionTokenId - val assets = changeBox.tokens.filterKeys(_ != reemissionTokenId).map(t => t._1.toTokenId -> t._2).toIndexedSeq - new ErgoBoxCandidate(changeBox.value, changeAddressOpt.get, walletHeight, assets.toColl) + val assets = changeBox.tokens.filterKeys(_ != reemissionTokenId).map(t => t._1.toTokenId -> t._2).toArray + new ErgoBoxCandidate(changeBox.value, ErgoTree.fromProposition(changeAddressOpt.get), walletHeight, assets.toColl) } val inputBoxes = selectionResult.inputBoxes.toIndexedSeq new UnsignedErgoTransaction( @@ -309,12 +309,13 @@ trait ErgoWalletSupport extends ScorexLogging { val (requestsWithBurnTokens, requestsWithoutBurnTokens) = requests.partition(_.isInstanceOf[BurnTokensRequest]) val burnTokensRequestMap = TransactionBuilder.collTokensToMap( requestsWithBurnTokens + .toArray .map(_.asInstanceOf[BurnTokensRequest]) .flatMap(_.assetsToBurn) .toColl ) //filter out tokens on whitelist from wallet and merge the rest with burnTokens from requests - val burnTokensMap = mergeBurnWhitelistTokens(state, inputBoxes, burnTokensRequestMap) + val burnTokensMap = mergeBurnWhitelistTokens(state, inputBoxes.toArray, burnTokensRequestMap) //We're getting id of the first input, it will be used in case of asset issuance (asset id == first input id) requestsToBoxCandidates(requestsWithoutBurnTokens, inputBoxes.head.box.id, state.fullHeight, state.parameters, state.walletVars.publicKeyAddresses) diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/IdUtils.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/IdUtils.scala index a3040f805c..f3358d4885 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/IdUtils.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/IdUtils.scala @@ -4,9 +4,9 @@ import org.ergoplatform.ErgoBox.{BoxId, TokenId} import org.ergoplatform.settings.Algos import scorex.crypto.authds.ADKey import scorex.util.ModifierId -import sigmastate.eval.Digest32Coll -import sigmastate.eval.Extensions.ArrayOps +import sigma.data.Digest32Coll import supertagged.TaggedType +import sigma.Extensions.ArrayOps object IdUtils { diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/WalletCache.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/WalletCache.scala index 4ead415b3b..d3701fa4cc 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/WalletCache.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/WalletCache.scala @@ -4,7 +4,7 @@ import com.google.common.hash.{BloomFilter, Funnels} import org.ergoplatform.sdk.wallet.secrets.ExtendedPublicKey import org.ergoplatform.settings.ErgoSettings import org.ergoplatform.{ErgoAddressEncoder, ErgoTreePredef, P2PKAddress} -import sigmastate.Values +import sigma.ast.ErgoTree import sigmastate.eval._ import scala.util.Try @@ -20,7 +20,7 @@ final case class WalletCache(publicKeyAddresses: Seq[P2PKAddress], implicit val addressEncoder: ErgoAddressEncoder = settings.addressEncoder // Mining rewards are being tracked only if mining = true in config - private val miningScripts: Seq[Values.ErgoTree] = { + private val miningScripts: Seq[ErgoTree] = { if (settings.nodeSettings.mining) { WalletCache.miningScripts(trackedPubKeys, settings) } else { @@ -47,7 +47,7 @@ final case class WalletCache(publicKeyAddresses: Seq[P2PKAddress], object WalletCache { def miningScripts(trackedPubKeys: Seq[ExtendedPublicKey], - settings: ErgoSettings): Seq[Values.ErgoTree] = { + settings: ErgoSettings): Seq[ErgoTree] = { trackedPubKeys.map { pk => ErgoTreePredef.rewardOutputScript(settings.miningRewardDelay, pk.key) } diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/WalletTransaction.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/WalletTransaction.scala index edd19a8fcc..1ed83dab11 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/WalletTransaction.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/WalletTransaction.scala @@ -7,6 +7,7 @@ import org.ergoplatform.serialization.ErgoSerializer import scorex.util.ModifierId import scorex.util.serialization.{Reader, Writer} import scorex.util.Extensions._ +import sigma.VersionContext /** * Transaction stored in the wallet. @@ -57,7 +58,10 @@ object WalletTransactionSerializer extends ErgoSerializer[WalletTransaction] { } val txBytesLen = r.getUInt().toIntExact - val tx = ErgoTransactionSerializer.parseBytes(r.getBytes(txBytesLen)) + // we use max supported script/tree to always parse everything there + val tx = (VersionContext.withVersions(VersionContext.MaxSupportedScriptVersion, VersionContext.MaxSupportedScriptVersion) { + ErgoTransactionSerializer.parseBytes(r.getBytes(txBytesLen)) + }) WalletTransaction(tx, inclusionHeight, scanIds) } diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/persistence/WalletStorage.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/persistence/WalletStorage.scala index 2f52c218f0..09eb04bc2f 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/persistence/WalletStorage.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/persistence/WalletStorage.scala @@ -10,7 +10,7 @@ import org.ergoplatform.wallet.Constants.{PaymentsScanId, ScanId} import scorex.crypto.hash.Blake2b256 import scorex.db.{LDBFactory, LDBKVStore} import scorex.util.ScorexLogging -import sigmastate.serialization.SigmaSerializer +import sigma.serialization.SigmaSerializer import java.io.File import scala.util.{Failure, Success, Try} diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/requests/AssetIssueRequest.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/requests/AssetIssueRequest.scala index 0dd6fd72d0..f804541184 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/requests/AssetIssueRequest.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/requests/AssetIssueRequest.scala @@ -7,8 +7,7 @@ import org.ergoplatform.ErgoBox.NonMandatoryRegisterId import org.ergoplatform.http.api.ApiCodecs import org.ergoplatform.nodeView.wallet.ErgoAddressJsonEncoder import org.ergoplatform.settings.ErgoSettings -import sigmastate.SType -import sigmastate.Values.EvaluatedValue +import sigma.ast.{EvaluatedValue, SType} /** * Request for new asset issuing. diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/requests/BurnTokensRequest.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/requests/BurnTokensRequest.scala index 4766626eb3..054f48b2e8 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/requests/BurnTokensRequest.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/requests/BurnTokensRequest.scala @@ -11,7 +11,7 @@ import org.ergoplatform.ErgoBox * @param assetsToBurn sequence of token id's and amount to burn * */ -case class BurnTokensRequest(assetsToBurn: Seq[(ErgoBox.TokenId, Long)]) +case class BurnTokensRequest(assetsToBurn: Array[(ErgoBox.TokenId, Long)]) extends TransactionGenerationRequest class BurnTokensRequestEncoder extends Encoder[BurnTokensRequest] { @@ -27,7 +27,7 @@ class BurnTokensRequestDecoder extends Decoder[BurnTokensRequest] { def apply(cursor: HCursor): Decoder.Result[BurnTokensRequest] = { for { assetsToBurn <- cursor.downField("assetsToBurn").as[Option[Seq[(ErgoBox.TokenId, Long)]]] - } yield BurnTokensRequest(assetsToBurn.toSeq.flatten) + } yield BurnTokensRequest(assetsToBurn.toArray.flatten) } } diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/requests/PaymentRequest.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/requests/PaymentRequest.scala index 9b44cdccb8..0a20acd83f 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/requests/PaymentRequest.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/requests/PaymentRequest.scala @@ -7,15 +7,14 @@ import org.ergoplatform.modifiers.mempool.ErgoTransaction._ import org.ergoplatform.nodeView.wallet.ErgoAddressJsonEncoder import org.ergoplatform.settings.ErgoSettings import org.ergoplatform.{ErgoAddress, ErgoBox} -import sigmastate.SType -import sigmastate.Values.EvaluatedValue +import sigma.ast.{EvaluatedValue, SType} /** * A payment request contains an address (probably containing script), value, assets, additional registers. */ case class PaymentRequest(address: ErgoAddress, value: Long, - assets: Seq[(ErgoBox.TokenId, Long)], + assets: Array[(ErgoBox.TokenId, Long)], registers: Map[NonMandatoryRegisterId, EvaluatedValue[_ <: SType]]) extends TransactionGenerationRequest @@ -46,7 +45,7 @@ class PaymentRequestDecoder(ergoSettings: ErgoSettings) extends Decoder[PaymentR value <- cursor.downField("value").as[Long] assets <- cursor.downField("assets").as[Option[Seq[(ErgoBox.TokenId, Long)]]] registers <- cursor.downField("registers").as[Option[Map[NonMandatoryRegisterId, EvaluatedValue[SType]]]] - } yield PaymentRequest(address, value, assets.toSeq.flatten, registers.getOrElse(Map.empty)) + } yield PaymentRequest(address, value, assets.toArray.flatten, registers.getOrElse(Map.empty)) } } diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/requests/RequestsHolder.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/requests/RequestsHolder.scala index 4ff6d38fbb..3c012e727c 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/requests/RequestsHolder.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/requests/RequestsHolder.scala @@ -19,7 +19,7 @@ case class RequestsHolder(requests: Seq[TransactionGenerationRequest], def withFee(): Seq[TransactionGenerationRequest] = { val address = Pay2SAddress(ErgoTreePredef.feeProposition(minerRewardDelay)) val feeRequests = feeOpt - .map(PaymentRequest(address, _, assets = Seq.empty, registers = Map.empty)) + .map(PaymentRequest(address, _, assets = Array.empty, registers = Map.empty)) .toSeq requests ++ feeRequests } diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicate.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicate.scala index 133c1736ef..29c71f6d98 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicate.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicate.scala @@ -1,9 +1,8 @@ package org.ergoplatform.nodeView.wallet.scanning import org.ergoplatform.ErgoBox -import sigmastate.Values.EvaluatedValue -import sigmastate.{SType, Values} import sigma.Extensions._ +import sigma.ast.{BooleanConstant, ByteArrayConstant, EvaluatedValue, GroupElementConstant, IntConstant, LongConstant, SType} /** * Basic interface for box scanning predicate functionality @@ -26,10 +25,10 @@ case class ContainsScanningPredicate(regId: ErgoBox.RegisterId, override def filter(box: ErgoBox): Boolean = { value match { - case Values.ByteArrayConstant(bytes) => + case ByteArrayConstant(bytes) => box.get(regId).exists { _ match { - case Values.ByteArrayConstant(arr) => arr.toArray.containsSlice(bytes.toArray) + case ByteArrayConstant(arr) => arr.toArray.containsSlice(bytes.toArray) case _ => false } } @@ -59,42 +58,42 @@ case class EqualsScanningPredicate(regId: ErgoBox.RegisterId, value: EvaluatedVa //todo: try to remove boilerplate below override def filter(box: ErgoBox): Boolean = { value match { - case Values.ByteArrayConstant(bytes) => + case ByteArrayConstant(bytes) => if(box.get(regId).isDefined && box.get(regId).get.tpe.equals(value.tpe)) { box.get(regId).exists { _ match { - case Values.ByteArrayConstant(arr) => arr.toArray.sameElements(bytes.toArray) + case ByteArrayConstant(arr) => arr.toArray.sameElements(bytes.toArray) case _ => false } } } else { false } - case Values.GroupElementConstant(groupElement) => + case GroupElementConstant(groupElement) => box.get(regId).exists { _ match { - case Values.GroupElementConstant(ge) => groupElement == ge + case GroupElementConstant(ge) => groupElement == ge case _ => false } } - case Values.BooleanConstant(bool) => + case BooleanConstant(bool) => box.get(regId).exists { _ match { - case Values.BooleanConstant(b) => bool == b + case BooleanConstant(b) => bool == b case _ => false } } - case Values.IntConstant(int) => + case IntConstant(int) => box.get(regId).exists { _ match { - case Values.IntConstant(i) => int == i + case IntConstant(i) => int == i case _ => false } } - case Values.LongConstant(long) => + case LongConstant(long) => box.get(regId).exists { _ match { - case Values.IntConstant(l) => long == l + case IntConstant(l) => long == l case _ => false } } diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecs.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecs.scala index c57b4923ff..8944686ab1 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecs.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecs.scala @@ -5,9 +5,8 @@ import io.circe.{Decoder, Encoder, Json} import org.ergoplatform.ErgoBox import org.ergoplatform.ErgoBox.RegisterId import org.ergoplatform.http.api.ApiCodecs -import sigmastate.SType -import sigmastate.Values.EvaluatedValue import sigma.Extensions._ +import sigma.ast.{EvaluatedValue, SType} object ScanningPredicateJsonCodecs extends ApiCodecs { diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSerializer.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSerializer.scala index 330c071373..ec1a6b4dda 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSerializer.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSerializer.scala @@ -5,10 +5,9 @@ import org.ergoplatform.ErgoBox.RegisterId import org.ergoplatform.serialization.ErgoSerializer import scorex.util.Extensions._ import scorex.util.serialization.{Reader, Writer} -import sigmastate.SType -import sigmastate.Values.EvaluatedValue +import sigma.ast.{EvaluatedValue, SType} +import sigma.serialization.ValueSerializer import sigmastate.eval.Extensions.ArrayByteOps -import sigmastate.serialization.ValueSerializer object ScanningPredicateSerializer extends ErgoSerializer[ScanningPredicate] { diff --git a/src/main/scala/org/ergoplatform/reemission/ReemissionRulesUtils.scala b/src/main/scala/org/ergoplatform/reemission/ReemissionRulesUtils.scala index f149097489..231b5bbfff 100644 --- a/src/main/scala/org/ergoplatform/reemission/ReemissionRulesUtils.scala +++ b/src/main/scala/org/ergoplatform/reemission/ReemissionRulesUtils.scala @@ -3,10 +3,9 @@ package org.ergoplatform.reemission import org.ergoplatform.mining.emission.EmissionRules import org.ergoplatform.settings.ErgoSettingsReader import org.ergoplatform.{ErgoAddressEncoder, Pay2SAddress} -import sigmastate.SBoolean -import sigmastate.Values.Value -import sigmastate.eval.CompiletimeIRContext -import sigmastate.lang.{CompilerSettings, SigmaCompiler, TransformingSigmaBuilder} +import sigma.ast.{ErgoTree, SBoolean, TransformingSigmaBuilder, Value} +import sigma.compiler.ir.CompiletimeIRContext +import sigma.compiler.{CompilerSettings, SigmaCompiler} import scala.util.Try @@ -36,7 +35,7 @@ object ReemissionRulesUtils { val compiler = SigmaCompiler(CompilerSettings(networkPrefix, TransformingSigmaBuilder, lowerMethodCalls = true)) val compiled = Try(compiler.compile(Map.empty, source)(new CompiletimeIRContext)).get.asInstanceOf[Value[SBoolean.type]].toSigmaProp - Pay2SAddress.apply(compiled) + Pay2SAddress.apply(ErgoTree.fromProposition(compiled)) } def main(args: Array[String]): Unit = { diff --git a/src/main/scala/org/ergoplatform/settings/ErgoSettings.scala b/src/main/scala/org/ergoplatform/settings/ErgoSettings.scala index 8ada7c5c16..4eb27b9d31 100644 --- a/src/main/scala/org/ergoplatform/settings/ErgoSettings.scala +++ b/src/main/scala/org/ergoplatform/settings/ErgoSettings.scala @@ -3,7 +3,7 @@ package org.ergoplatform.settings import org.ergoplatform.mining.groupElemFromBytes import org.ergoplatform.{ErgoAddressEncoder, P2PKAddress} import scorex.util.encode.Base16 -import sigmastate.crypto.DLogProtocol.ProveDlog +import sigma.data.ProveDlog import scala.util.Try @@ -29,6 +29,16 @@ case class ErgoSettings(directory: String, .toOption } + def launchParameters: Parameters = { + if (networkType == NetworkType.DevNet) { + DevnetLaunchParameters + } else if (networkType == NetworkType.TestNet) { + TestnetLaunchParameters + } else { + MainnetLaunchParameters + } + } + } object ErgoSettings { diff --git a/src/main/scala/org/ergoplatform/settings/NetworkType.scala b/src/main/scala/org/ergoplatform/settings/NetworkType.scala index 6160cc4a8f..e7d6865797 100644 --- a/src/main/scala/org/ergoplatform/settings/NetworkType.scala +++ b/src/main/scala/org/ergoplatform/settings/NetworkType.scala @@ -1,8 +1,12 @@ package org.ergoplatform.settings +import org.ergoplatform.ErgoAddressEncoder + sealed trait NetworkType { - val verboseName: String - def isMainNet: Boolean = false + def verboseName: String + def isMainNet: Boolean + def isTestNet: Boolean + def addressPrefix: Byte } object NetworkType { @@ -12,16 +16,24 @@ object NetworkType { def fromString(name: String): Option[NetworkType] = all.find(_.verboseName == name) case object MainNet extends NetworkType { - val verboseName: String = "mainnet" - override def isMainNet: Boolean = true + override val verboseName: String = "mainnet" + override val isMainNet: Boolean = true + override val isTestNet: Boolean = false + override val addressPrefix: Byte = ErgoAddressEncoder.MainnetNetworkPrefix } case object TestNet extends NetworkType { - val verboseName: String = "testnet" + override val verboseName: String = "testnet" + override val isMainNet: Boolean = false + override val isTestNet: Boolean = true + override val addressPrefix: Byte = ErgoAddressEncoder.TestnetNetworkPrefix } case object DevNet extends NetworkType { - val verboseName: String = "devnet" + override val verboseName: String = "devnet" + override val isMainNet: Boolean = false + override val isTestNet: Boolean = false + override val addressPrefix: Byte = 32 } } diff --git a/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala index c3a1c33851..4898defea9 100644 --- a/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala +++ b/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala @@ -17,7 +17,7 @@ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import scorex.crypto.authds.ADKey import scorex.utils.Random -import sigmastate.Values.ByteArrayConstant +import sigma.ast.ByteArrayConstant import scala.concurrent.duration._ import scala.util.Try diff --git a/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala index 9b6239fa0c..a8bad6b1b2 100644 --- a/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala +++ b/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala @@ -10,12 +10,13 @@ import org.ergoplatform.settings.{Args, ErgoSettings, ErgoSettingsReader} import org.ergoplatform.utils.Stubs import io.circe.syntax._ import org.ergoplatform.http.api.ScriptApiRoute +import org.ergoplatform.settings.Constants.TrueTree import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import scorex.util.encode.Base16 -import sigmastate.SByte -import sigmastate.Values.{CollectionConstant, ErgoTree, TrueLeaf} -import sigmastate.serialization.{ErgoTreeSerializer, ValueSerializer} +import sigma.ast.SByte +import sigma.ast.syntax.CollectionConstant +import sigma.serialization.{ErgoTreeSerializer, ValueSerializer} class ScriptApiRouteSpec extends AnyFlatSpec @@ -106,8 +107,7 @@ class ScriptApiRouteSpec extends AnyFlatSpec val p2pk = "3WvsT2Gm4EpsM9Pg18PdY6XyhNNMqXDsvJTbbf6ihLvAmSb7u5RN" Get(s"$prefix/$suffix/$p2pk") ~> route ~> check(assertion(responseAs[Json], p2pk)) - val script = TrueLeaf - val tree = ErgoTree.fromProposition(script) + val tree = TrueTree val p2sh = Pay2SHAddress.apply(tree).toString() p2sh shouldBe "rbcrmKEYduUvADj9Ts3dSVSG27h54pgrq5fPuwB" @@ -143,8 +143,7 @@ class ScriptApiRouteSpec extends AnyFlatSpec val p2sh = "rbcrmKEYduUvADj9Ts3dSVSG27h54pgrq5fPuwB" Get(s"$prefix/$suffix/$p2sh") ~> route ~> check(assertion(responseAs[Json], p2sh)) - val script = TrueLeaf - val tree = ErgoTree.fromProposition(script) + val tree = TrueTree val p2s = addressEncoder.toString(addressEncoder.fromProposition(tree).get) p2s shouldBe "Ms7smJwLGbUAjuWQ" Get(s"$prefix/$suffix/$p2s") ~> route ~> check(assertion(responseAs[Json], p2s)) diff --git a/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala index 416dea8b59..38dd7290b7 100644 --- a/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala +++ b/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala @@ -11,17 +11,17 @@ import org.ergoplatform.ErgoBox.{AdditionalRegisters, NonMandatoryRegisterId, To import org.ergoplatform.http.api.{ApiCodecs, TransactionsApiRoute} import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction} import org.ergoplatform.nodeView.ErgoReadersHolder.{GetDataFromHistory, GetReaders, Readers} -import org.ergoplatform.settings.{Constants, RESTApiSettings} +import org.ergoplatform.settings.RESTApiSettings import org.ergoplatform.utils.Stubs import org.ergoplatform.{DataInput, ErgoBox, ErgoBoxCandidate, Input} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import scorex.util.encode.Base16 -import sigmastate.SType -import sigmastate.Values.{ByteArrayConstant, EvaluatedValue} import sigmastate.eval.Extensions._ -import sigmastate.eval._ -import sigma.Extensions._ +import sigma.Extensions.ArrayOps +import sigma.ast.{ByteArrayConstant, EvaluatedValue, SType} +import org.ergoplatform.settings.Constants.TrueTree +import sigma.Extensions.CollBytesOps import java.net.InetSocketAddress import scala.concurrent.duration._ @@ -54,7 +54,7 @@ class TransactionApiRouteSpec extends AnyFlatSpec ) val output: ErgoBoxCandidate = - new ErgoBoxCandidate(inputBox.value, Constants.TrueLeaf, creationHeight = 0, tokens.toColl, registers) + new ErgoBoxCandidate(inputBox.value, TrueTree, creationHeight = 0, tokens.toArray.toColl, registers) val tx: ErgoTransaction = ErgoTransaction(IndexedSeq(input), IndexedSeq(dataInput), IndexedSeq(output)) val chainedInput = Input(tx.outputs.head.id, emptyProverResult) diff --git a/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala index e613f35261..06a7523f1e 100644 --- a/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala +++ b/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala @@ -13,7 +13,7 @@ import org.ergoplatform.settings.RESTApiSettings import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import scorex.util.encode.Base16 -import sigmastate.serialization.ErgoTreeSerializer +import sigma.serialization.ErgoTreeSerializer import scala.concurrent.duration._ diff --git a/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala index 1655fbb576..abbab0c452 100644 --- a/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala +++ b/src/test/scala/org/ergoplatform/http/routes/WalletApiRouteSpec.scala @@ -10,7 +10,7 @@ import org.ergoplatform.http.api.{ApiCodecs, ApiExtraCodecs, ApiRequestsCodecs, import org.ergoplatform.modifiers.mempool.ErgoTransaction import org.ergoplatform.nodeView.wallet.requests.{AssetIssueRequestEncoder, PaymentRequest, PaymentRequestEncoder, _} import org.ergoplatform.nodeView.wallet.{AugWalletTransaction, ErgoAddressJsonEncoder} -import org.ergoplatform.settings.{Args, Constants, ErgoSettings, ErgoSettingsReader} +import org.ergoplatform.settings.{Args, ErgoSettings, ErgoSettingsReader} import org.ergoplatform.utils.Stubs import org.ergoplatform.{ErgoAddress, Pay2SAddress} import org.ergoplatform.wallet.{Constants => WalletConstants} @@ -20,6 +20,7 @@ import org.scalatest.matchers.should.Matchers import scala.util.{Random, Try} import scala.concurrent.duration._ import akka.http.scaladsl.server.MissingQueryParamRejection +import org.ergoplatform.settings.Constants.FalseTree import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators class WalletApiRouteSpec extends AnyFlatSpec @@ -50,8 +51,8 @@ class WalletApiRouteSpec extends AnyFlatSpec implicit val requestsHolderEncoder: RequestsHolderEncoder = new RequestsHolderEncoder(ergoSettings) implicit val addressJsonDecoder: Decoder[ErgoAddress] = ErgoAddressJsonEncoder(settings.chainSettings).decoder - val paymentRequest = PaymentRequest(Pay2SAddress(Constants.FalseLeaf)(settings.addressEncoder), 100L, Seq.empty, Map.empty) - val assetIssueRequest = AssetIssueRequest(Pay2SAddress(Constants.FalseLeaf)(settings.addressEncoder), None, 100L, "TEST", "Test", 8) + val paymentRequest = PaymentRequest(Pay2SAddress(FalseTree)(settings.addressEncoder), 100L, Array.empty, Map.empty) + val assetIssueRequest = AssetIssueRequest(Pay2SAddress(FalseTree)(settings.addressEncoder), None, 100L, "TEST", "Test", 8) val requestsHolder = RequestsHolder( (0 to 10).flatMap(_ => Seq(paymentRequest, assetIssueRequest)), Some(10000L), diff --git a/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala b/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala index c742768150..65ea9ae8ae 100644 --- a/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala +++ b/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala @@ -9,18 +9,19 @@ import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.{LocallyG import org.ergoplatform.nodeView.mempool.ErgoMemPoolUtils.ProcessingOutcome import org.ergoplatform.nodeView.state.ErgoState import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState -import org.ergoplatform.settings.{Algos, Constants, ErgoSettings} +import org.ergoplatform.settings.{Algos, ErgoSettings} import org.ergoplatform.utils.ErgoCoreTestConstants.parameters import org.ergoplatform.utils.fixtures.NodeViewFixture import org.ergoplatform.utils.{ErgoTestHelpers, MempoolTestHelpers, NodeViewTestOps, RandomWrapper} import org.scalatest.flatspec.AnyFlatSpec import scorex.core.network.NetworkController.ReceivableMessages.SendToNetwork -import sigmastate.Values.ErgoTree -import sigmastate.eval.{IRContext, RuntimeIRContext} +import sigma.ast.ErgoTree +import sigma.ast.syntax.ValueOps +import sigma.compiler.SigmaCompiler +import sigma.compiler.ir.CompiletimeIRContext +import sigma.serialization.ErgoTreeSerializer import sigmastate.interpreter.Interpreter.emptyEnv -import sigmastate.lang.SigmaCompiler -import sigmastate.lang.Terms.ValueOps -import sigmastate.serialization.ErgoTreeSerializer +import org.ergoplatform.settings.Constants.TrueTree import scala.concurrent.duration._ @@ -30,8 +31,6 @@ class MempoolAuditorSpec extends AnyFlatSpec with NodeViewTestOps with ErgoTestH import org.ergoplatform.utils.generators.ErgoCoreGenerators._ import org.ergoplatform.utils.generators.ValidBlocksGenerators._ - implicit lazy val context: IRContext = new RuntimeIRContext - val cleanupDuration: FiniteDuration = 200.millis val settingsToTest: ErgoSettings = settings.copy( nodeSettings = settings.nodeSettings.copy( @@ -57,12 +56,12 @@ class MempoolAuditorSpec extends AnyFlatSpec with NodeViewTestOps with ErgoTestH applyBlock(genesis) shouldBe 'success getRootHash shouldBe Algos.encode(wusAfterGenesis.rootDigest) - val boxes = ErgoState.newBoxes(genesis.transactions).find(_.ergoTree == Constants.TrueLeaf) + val boxes = ErgoState.newBoxes(genesis.transactions).find(_.ergoTree == TrueTree) boxes.nonEmpty shouldBe true val script = s"{sigmaProp(HEIGHT == ${genesis.height} + 1)}" val compiler = new SigmaCompiler(ErgoAddressEncoder.MainnetNetworkPrefix) - val prop = compiler.compile(emptyEnv, script).buildTree + val prop = compiler.compile(emptyEnv, script)(new CompiletimeIRContext).buildTree val tree = ErgoTree.fromProposition(prop.asSigmaProp) val bs = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(tree) @@ -70,7 +69,7 @@ class MempoolAuditorSpec extends AnyFlatSpec with NodeViewTestOps with ErgoTestH val validTx = validTransactionFromBoxes(boxes.toIndexedSeq, outputsProposition = tree) - val temporarilyValidTx = validTransactionFromBoxes(validTx.outputs, outputsProposition = proveDlogGen.sample.get) + val temporarilyValidTx = validTransactionFromBoxes(validTx.outputs, outputsProposition = ErgoTree.fromProposition(proveDlogGen.sample.get)) subscribeEvents(classOf[FailedTransaction]) nodeViewHolderRef ! LocallyGeneratedTransaction(UnconfirmedTransaction(validTx, None)) diff --git a/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala b/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala index 7ef123a1d7..e1a9595d9f 100644 --- a/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala +++ b/src/test/scala/org/ergoplatform/mining/CandidateGeneratorPropSpec.scala @@ -7,7 +7,7 @@ import org.ergoplatform.settings.MonetarySettings import org.ergoplatform.utils.{ErgoCorePropertyTest, RandomWrapper} import org.ergoplatform.wallet.interpreter.ErgoInterpreter import org.scalacheck.Gen -import sigmastate.crypto.DLogProtocol.ProveDlog +import sigma.data.ProveDlog import scala.concurrent.duration._ diff --git a/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala b/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala index 7e3a383111..17026c41fd 100644 --- a/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala +++ b/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala @@ -20,7 +20,8 @@ import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, ErgoTreePredef, Input} import org.scalatest.concurrent.Eventually import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers -import sigmastate.crypto.DLogProtocol +import sigma.ast.ErgoTree +import sigma.data.ProveDlog import sigmastate.crypto.DLogProtocol.DLogProverInput import scala.concurrent.duration._ @@ -200,7 +201,7 @@ class CandidateGeneratorSpec extends AnyFlatSpec with Matchers with ErgoTestHelp } // build new transaction that uses miner's reward as input - val prop: DLogProtocol.ProveDlog = + val prop: ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test".getBytes())).publicImage val newlyMinedBlock = readers.h.bestFullBlockOpt.get val rewardBox: ErgoBox = newlyMinedBlock.transactions.last.outputs.last @@ -210,7 +211,7 @@ class CandidateGeneratorSpec extends AnyFlatSpec with Matchers with ErgoTestHelp val input = Input(rewardBox.id, emptyProverResult) val outputs = IndexedSeq( - new ErgoBoxCandidate(rewardBox.value, prop, readers.s.stateContext.currentHeight) + new ErgoBoxCandidate(rewardBox.value, ErgoTree.fromSigmaBoolean(prop), readers.s.stateContext.currentHeight) ) val unsignedTx = new UnsignedErgoTransaction(IndexedSeq(input), IndexedSeq(), outputs) diff --git a/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala b/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala index 35aff7e1df..9e17e85b4a 100644 --- a/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala +++ b/src/test/scala/org/ergoplatform/mining/ErgoMinerSpec.scala @@ -23,9 +23,8 @@ import org.ergoplatform.wallet.interpreter.ErgoInterpreter import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, ErgoTreePredef, Input} import org.scalatest.concurrent.Eventually import org.scalatest.flatspec.AnyFlatSpec -import sigmastate.SigmaAnd -import sigmastate.Values.{ErgoTree, SigmaPropConstant} -import sigmastate.crypto.DLogProtocol +import sigma.ast.{ErgoTree, SigmaAnd, SigmaPropConstant} +import sigma.data.ProveDlog import sigmastate.crypto.DLogProtocol.DLogProverInput import scala.annotation.tailrec @@ -65,10 +64,9 @@ class ErgoMinerSpec extends AnyFlatSpec with ErgoTestHelpers with Eventually { val testProbe = new TestProbe(system) system.eventStream.subscribe(testProbe.ref, newBlockSignal) val ergoSettings: ErgoSettings = defaultSettings.copy(directory = createTempDir.getAbsolutePath) - val complexScript: ErgoTree = (0 until 100).foldLeft(SigmaAnd(SigmaPropConstant(defaultMinerPk), SigmaPropConstant(defaultMinerPk))) { (l, _) => + val complexScript: ErgoTree = ErgoTree.fromProposition((0 until 100).foldLeft(SigmaAnd(SigmaPropConstant(defaultMinerPk), SigmaPropConstant(defaultMinerPk))) { (l, _) => SigmaAnd(SigmaPropConstant(defaultMinerPk), l) - } - complexScript.complexity shouldBe 28077 + }) val nodeViewHolderRef: ActorRef = ErgoNodeViewRef(ergoSettings) val readersHolderRef: ActorRef = ErgoReadersHolderRef(nodeViewHolderRef) @@ -175,7 +173,7 @@ class ErgoMinerSpec extends AnyFlatSpec with ErgoTestHelpers with Eventually { val feeBox = new ErgoBoxCandidate(boxToSend.value / desiredSize, feeProp, r.s.stateContext.currentHeight) val outputs = (1 until desiredSize).map { _ => - new ErgoBoxCandidate(boxToSend.value / desiredSize, defaultMinerPk, r.s.stateContext.currentHeight) + new ErgoBoxCandidate(boxToSend.value / desiredSize, ErgoTree.fromSigmaBoolean(defaultMinerPk), r.s.stateContext.currentHeight) } val unsignedTx = new UnsignedErgoTransaction(inputs, IndexedSeq(), feeBox +: outputs) ErgoTransaction( @@ -239,18 +237,18 @@ class ErgoMinerSpec extends AnyFlatSpec with ErgoTestHelpers with Eventually { testProbe.expectMsgClass(newBlockDelay, newBlockSignal) - val prop1: DLogProtocol.ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test1".getBytes())).publicImage - val prop2: DLogProtocol.ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test2".getBytes())).publicImage + val prop1: ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test1".getBytes())).publicImage + val prop2: ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test2".getBytes())).publicImage val boxToDoubleSpend: ErgoBox = r.h.bestFullBlockOpt.get.transactions.last.outputs.last boxToDoubleSpend.propositionBytes shouldBe ErgoTreePredef.rewardOutputScript(emission.settings.minerRewardDelay, defaultMinerPk).bytes val input = Input(boxToDoubleSpend.id, emptyProverResult) - val outputs1 = IndexedSeq(new ErgoBoxCandidate(boxToDoubleSpend.value, prop1, r.s.stateContext.currentHeight)) + val outputs1 = IndexedSeq(new ErgoBoxCandidate(boxToDoubleSpend.value, ErgoTree.fromSigmaBoolean(prop1), r.s.stateContext.currentHeight)) val unsignedTx1 = new UnsignedErgoTransaction(IndexedSeq(input), IndexedSeq(), outputs1) val tx1 = defaultProver.sign(unsignedTx1, IndexedSeq(boxToDoubleSpend), IndexedSeq(), r.s.stateContext).get - val outputs2 = IndexedSeq(new ErgoBoxCandidate(boxToDoubleSpend.value, prop2, r.s.stateContext.currentHeight)) + val outputs2 = IndexedSeq(new ErgoBoxCandidate(boxToDoubleSpend.value, ErgoTree.fromSigmaBoolean(prop2), r.s.stateContext.currentHeight)) val unsignedTx2 = new UnsignedErgoTransaction(IndexedSeq(input), IndexedSeq(), outputs2) val tx2 = ErgoTransaction(defaultProver.sign(unsignedTx2, IndexedSeq(boxToDoubleSpend), IndexedSeq(), r.s.stateContext).get) @@ -334,18 +332,18 @@ class ErgoMinerSpec extends AnyFlatSpec with ErgoTestHelpers with Eventually { testProbe.expectMsgClass(newBlockDelay, newBlockSignal) - val prop1: DLogProtocol.ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test1".getBytes())).publicImage - val prop2: DLogProtocol.ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test2".getBytes())).publicImage + val prop1: ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test1".getBytes())).publicImage + val prop2: ProveDlog = DLogProverInput(BigIntegers.fromUnsignedByteArray("test2".getBytes())).publicImage val mBox: ErgoBox = r.h.bestFullBlockOpt.get.transactions.last.outputs.last val mInput = Input(mBox.id, emptyProverResult) - val outputs1 = IndexedSeq(new ErgoBoxCandidate(mBox.value, prop1, r.s.stateContext.currentHeight)) + val outputs1 = IndexedSeq(new ErgoBoxCandidate(mBox.value, ErgoTree.fromSigmaBoolean(prop1), r.s.stateContext.currentHeight)) val unsignedTx1 = new UnsignedErgoTransaction(IndexedSeq(mInput), IndexedSeq(), outputs1) val mandatoryTxLike1 = defaultProver.sign(unsignedTx1, IndexedSeq(mBox), IndexedSeq(), r.s.stateContext).get val mandatoryTx1 = ErgoTransaction(mandatoryTxLike1) - val outputs2 = IndexedSeq(new ErgoBoxCandidate(mBox.value, prop2, r.s.stateContext.currentHeight)) + val outputs2 = IndexedSeq(new ErgoBoxCandidate(mBox.value, ErgoTree.fromSigmaBoolean(prop2), r.s.stateContext.currentHeight)) val unsignedTx2 = new UnsignedErgoTransaction(IndexedSeq(mInput), IndexedSeq(), outputs2) val mandatoryTxLike2 = defaultProver.sign(unsignedTx2, IndexedSeq(mBox), IndexedSeq(), r.s.stateContext).get val mandatoryTx2 = ErgoTransaction(mandatoryTxLike2) diff --git a/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoNodeTransactionSpec.scala b/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoNodeTransactionSpec.scala index 47aa907efe..b60366e99c 100644 --- a/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoNodeTransactionSpec.scala +++ b/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoNodeTransactionSpec.scala @@ -1,30 +1,36 @@ package org.ergoplatform.modifiers.mempool -import org.ergoplatform.ErgoBox.TokenId +import org.ergoplatform.ErgoBox.{R4, TokenId} import org.ergoplatform.nodeView.state.{ErgoStateContext, VotingData} import org.ergoplatform.settings._ -import org.ergoplatform.utils.ErgoCorePropertyTest +import org.ergoplatform.utils.{ErgoCompilerHelpers, ErgoCorePropertyTest, ErgoStateContextHelpers} import org.ergoplatform.wallet.interpreter.ErgoInterpreter -import org.ergoplatform.{ErgoBox, ErgoBoxCandidate} +import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, ErgoTreePredef, Input} import scorex.util.{ModifierId, bytesToId} import sigmastate.eval.Extensions._ import org.ergoplatform.nodeView.ErgoContext import org.ergoplatform.sdk.wallet.protocol.context.TransactionContext import org.ergoplatform.settings.Parameters.MaxBlockCostIncrease import org.ergoplatform.settings.ValidationRules.{bsBlockTransactionsCost, txAssetsInOneBox} -import org.ergoplatform.wallet.boxes.ErgoBoxAssetExtractor +import org.ergoplatform.wallet.boxes.{ErgoBoxAssetExtractor, ErgoBoxSerializer} import org.ergoplatform.wallet.interpreter.TransactionHintsBag import org.ergoplatform.wallet.protocol.context.InputContext import org.scalacheck.Gen import sigma.util.BenchmarkUtil import scorex.crypto.hash.Blake2b256 -import sigmastate.AND +import scorex.util.encode.Base16 +import sigma.{Colls, VersionContext} +import sigma.ast.ErgoTree.DefaultHeader +import sigma.ast.{AND, ErgoTree, TrueLeaf, UnsignedBigIntConstant} +import sigma.interpreter.{ContextExtension, ProverResult} +import sigma.serialization.ErgoTreeSerializer.DefaultSerializer import sigmastate.helpers.TestingHelpers._ -import sigmastate.Values.TrueLeaf +import java.math.BigInteger import scala.util.{Random, Try} -class ErgoNodeTransactionSpec extends ErgoCorePropertyTest { +class ErgoNodeTransactionSpec extends ErgoCorePropertyTest with ErgoCompilerHelpers with ErgoStateContextHelpers { + import org.ergoplatform.utils.ErgoCoreTestConstants._ import org.ergoplatform.utils.ErgoNodeTestConstants._ import org.ergoplatform.utils.generators.ErgoCoreGenerators._ @@ -82,18 +88,6 @@ class ErgoNodeTransactionSpec extends ErgoCorePropertyTest { } property("monotonic creation height") { - def stateContext(height: Int, blockVersion: Byte): ErgoStateContext = { - val header = defaultHeaderGen.sample.get.copy(version = blockVersion, height = height) - val params = Parameters(LaunchParameters.height, - LaunchParameters.parametersTable.updated(Parameters.BlockVersion, blockVersion), - LaunchParameters.proposedUpdate) - new ErgoStateContext(Seq(header), None, genesisStateDigest, params, ErgoValidationSettings.initial, - VotingData.empty)(settings.chainSettings) - } - - def stateContextForTx(tx: ErgoTransaction, blockVersion: Byte): ErgoStateContext = { - stateContext(tx.outputs.map(_.creationHeight).max, blockVersion) - } def updateOutputHeight(box: ErgoBoxCandidate, value: Int): ErgoBoxCandidate = { new ErgoBoxCandidate(box.value, box.ergoTree, value, box.additionalTokens, box.additionalRegisters) @@ -102,7 +96,7 @@ class ErgoNodeTransactionSpec extends ErgoCorePropertyTest { def updateInputHeight(box: ErgoBox): ErgoBox = { val creationHeight = scala.util.Random.nextInt(1000) + 1 new ErgoBox(box.value, box.ergoTree, box.additionalTokens, box.additionalRegisters, - box.transactionId, box.index, creationHeight) + box.transactionId, box.index, creationHeight) } // retuns random transaction along with inputs, @@ -110,17 +104,17 @@ class ErgoNodeTransactionSpec extends ErgoCorePropertyTest { // otherwise, it does not hold val txGen = boxesGenTemplate(minAssets = 0, maxAssets = 5, minInputs = 5, maxInputs = 10, propositionGen = trueLeafGen).map { case (boxes, _) => boxes.map(updateInputHeight) - }.map{ boxes => + }.map { boxes => val fixed = Random.nextBoolean() val maxHeight = boxes.map(_.creationHeight).max val preUnsignedTx = validUnsignedTransactionFromBoxes(boxes) - val unsignedTx = if(fixed) { - preUnsignedTx.copy(outputCandidates = preUnsignedTx.outputCandidates.map{out => + val unsignedTx = if (fixed) { + preUnsignedTx.copy(outputCandidates = preUnsignedTx.outputCandidates.map { out => val creationHeight = maxHeight + Random.nextInt(3) updateOutputHeight(out, creationHeight) }) } else { - preUnsignedTx.copy(outputCandidates = preUnsignedTx.outputCandidates.map{out => + preUnsignedTx.copy(outputCandidates = preUnsignedTx.outputCandidates.map { out => val creationHeight = maxHeight - (Random.nextInt(maxHeight) + 1) updateOutputHeight(out, creationHeight) }) @@ -131,16 +125,16 @@ class ErgoNodeTransactionSpec extends ErgoCorePropertyTest { (boxes, tx, fixed) } - forAll(txGen){ case (boxes, tx, fixed) => + forAll(txGen) { case (boxes, tx, fixed) => // with initial block version == 1, monotonic rule does not work - tx.statefulValidity(boxes, IndexedSeq.empty, stateContextForTx(tx, blockVersion = 1)).isSuccess shouldBe true + tx.statefulValidity(boxes, IndexedSeq.empty, stateContextForTx(tx, blockVersion = 1, settings)).isSuccess shouldBe true // with pre-5.0 block version == 2, monotonic rule does not work as well - tx.statefulValidity(boxes, IndexedSeq.empty, stateContextForTx(tx, blockVersion = 2)).isSuccess shouldBe true + tx.statefulValidity(boxes, IndexedSeq.empty, stateContextForTx(tx, blockVersion = 2, settings)).isSuccess shouldBe true // starting from block version == 3, monotonic rule works, // so validation fails if transaction is not following the rule (fixed == false) - val ctx3 = stateContextForTx(tx, blockVersion = 3) + val ctx3 = stateContextForTx(tx, blockVersion = 3, settings) if (fixed) { tx.statefulValidity(boxes, IndexedSeq.empty, ctx3).isSuccess shouldBe true } else { @@ -153,329 +147,442 @@ class ErgoNodeTransactionSpec extends ErgoCorePropertyTest { } } - property("a valid transaction is valid") { - forAll(validErgoTransactionGen) { case (from, tx) => - tx.statelessValidity().isSuccess shouldBe true - tx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe true - } - } - - property("ergo preservation law holds") { - forAll(validErgoTransactionGen, smallPositiveInt) { case ((from, tx), deltaAbs) => - val delta = if (Random.nextBoolean()) -deltaAbs else deltaAbs - - val wrongTx = tx.copy(outputCandidates = - modifyValue(tx.outputCandidates.head, delta) +: tx.outputCandidates.tail) - - wrongTx.statelessValidity().isSuccess && - wrongTx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe false - } - } - - property("impossible to create a negative-value output") { - forAll(validErgoTransactionGen) { case (from, tx) => - val negValue = Math.min(Math.abs(Random.nextLong()), Long.MaxValue - tx.outputCandidates.head.value) - val wrongTx = tx.copy(outputCandidates = - modifyValue(tx.outputCandidates.head, -(tx.outputCandidates.head.value + negValue)) +: tx.outputCandidates.tail) - - wrongTx.statelessValidity().isSuccess shouldBe false - wrongTx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe false - } - } - - property("impossible to overflow ergo tokens") { - forAll(validErgoTransactionGen) { case (from, tx) => - val overflowSurplus = (Long.MaxValue - tx.outputCandidates.map(_.value).sum) + 1 - - val wrongTx = tx.copy(outputCandidates = - modifyValue(tx.outputCandidates.head, overflowSurplus) +: tx.outputCandidates.tail) - - wrongTx.statelessValidity().isSuccess shouldBe false - wrongTx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe false - } - } - - property("assets preservation law holds") { - forAll(validErgoTransactionWithAssetsGen) { case (from, tx) => - checkTx(from, updateAnAsset(tx, from, _ + 1)) shouldBe 'failure - } - } - - property("impossible to create an asset of negative amount") { - forAll(validErgoTransactionWithAssetsGen) { case (from, tx) => - checkTx(from, updateAnAsset(tx, from, _ => -1)) shouldBe 'failure - } - } - - property("impossible to create an asset of zero amount") { - forAll(validErgoTransactionWithAssetsGen) { case (from, tx) => - checkTx(from, updateAnAsset(tx, from, _ => 0)) shouldBe 'failure - } - } - - property("impossible to overflow an asset value") { - val gen = validErgoTransactionGenTemplate(minAssets = 1, maxAssets = 1, maxInputs = 16, propositionGen = trueLeafGen) - forAll(gen) { case (from, tx) => - val tokenOpt = tx.outputCandidates.flatMap(_.additionalTokens.toArray) - .groupBy(_._1).find(_._2.size >= 2) - - whenever(tokenOpt.nonEmpty) { - val tokenId = tokenOpt.get._1 - val tokenAmount = tokenOpt.get._2.map(_._2).sum - - var modified = false - val updCandidates = tx.outputCandidates.map { c => - val updTokens = c.additionalTokens.map { case (id, amount) => - if (!modified && id == tokenId) { - modified = true - id -> ((Long.MaxValue - tokenAmount) + amount + 1) - } else { - id -> amount - } - } - new ErgoBoxCandidate(c.value, c.ergoTree, startHeight, updTokens, c.additionalRegisters) - } - - val wrongTx = tx.copy(outputCandidates = updCandidates) - checkTx(from, wrongTx) shouldBe 'failure - } - } - } - - property("stateful validation should catch false proposition") { - val propositionGen = Gen.const(Constants.FalseLeaf) - val gen = validErgoTransactionGenTemplate(1, 1, 1, propositionGen) - forAll(gen) { case (from, tx) => - tx.statelessValidity().isSuccess shouldBe true - val validity = tx.statefulValidity(from, emptyDataBoxes, emptyStateContext) - validity.isSuccess shouldBe false - val e = validity.failed.get - e.getMessage should startWith(ValidationRules.errorMessage(ValidationRules.txScriptValidation, "", emptyModifierId, ErgoTransaction.modifierTypeId)) - } - } - - property("assets usage correctly affects transaction total cost") { - val txGen = validErgoTransactionGenTemplate(1, 1,16, propositionGen = trueLeafGen) - forAll(txGen) { case (from, tx) => - val initTxCost = tx.statefulValidity(from, emptyDataBoxes, emptyStateContext).get - - // already existing token from one of the inputs - val existingToken = from.flatMap(_.additionalTokens.toArray).toSet.head - // completely new token - val randomToken = (scorex.util.Random.randomBytes().toTokenId, Random.nextInt(100000000).toLong) - - val in0 = from.last - // new token added to the last input - val modifiedIn0 = testBox(in0.value, in0.ergoTree, in0.creationHeight, - in0.additionalTokens.toArray.toSeq :+ randomToken, in0.additionalRegisters, in0.transactionId, in0.index) - val txInMod0 = tx.inputs.last.copy(boxId = modifiedIn0.id) - - val in1 = from.last - // existing token added to the last input - val modifiedIn1 = testBox(in1.value, in1.ergoTree, in1.creationHeight, - in1.additionalTokens.toArray.toSeq :+ existingToken, in1.additionalRegisters, in1.transactionId, in1.index) - val txInMod1 = tx.inputs.last.copy(boxId = modifiedIn1.id) - - val out0 = tx.outputs.last - // new token added to the last output - val modifiedOut0 = testBox(out0.value, out0.ergoTree, out0.creationHeight, - out0.additionalTokens.toArray.toSeq :+ randomToken, out0.additionalRegisters, out0.transactionId, out0.index) - // existing token added to the last output - val modifiedOut1 = testBox(out0.value, out0.ergoTree, out0.creationHeight, - out0.additionalTokens.toArray.toSeq :+ existingToken, out0.additionalRegisters, out0.transactionId, out0.index) - - // update transaction inputs and outputs accordingly - val txMod0 = tx.copy(inputs = tx.inputs.init :+ txInMod0) // new token group added to one input - val txMod1 = tx.copy(inputs = tx.inputs.init :+ txInMod1) // existing token added to one input - val txMod2 = tx.copy(inputs = tx.inputs.init :+ txInMod0, // new token group added to one input and one output - outputCandidates = tx.outputCandidates.init :+ modifiedOut0) - val txMod3 = tx.copy(inputs = tx.inputs.init :+ txInMod1, // existing token added to one input and one output - outputCandidates = tx.outputCandidates.init :+ modifiedOut1) - - val inputIncTxCost0 = txMod0.statefulValidity(from.init :+ modifiedIn0, emptyDataBoxes, emptyStateContext).get - val inputIncTxCost1 = txMod1.statefulValidity(from.init :+ modifiedIn1, emptyDataBoxes, emptyStateContext).get - val outputIncTxCost0 = txMod2.statefulValidity(from.init :+ modifiedIn0, emptyDataBoxes, emptyStateContext).get - val outputIncTxCost1 = txMod3.statefulValidity(from.init :+ modifiedIn1, emptyDataBoxes, emptyStateContext).get - - (inputIncTxCost0 - initTxCost) shouldEqual Parameters.TokenAccessCostDefault * 2 // one more group + one more token in total - (inputIncTxCost1 - initTxCost) shouldEqual Parameters.TokenAccessCostDefault // one more token in total - (outputIncTxCost0 - inputIncTxCost0) shouldEqual Parameters.TokenAccessCostDefault * 2 - (outputIncTxCost1 - inputIncTxCost1) shouldEqual Parameters.TokenAccessCostDefault - } - } - - property("spam simulation (transaction validation cost with too many tokens exceeds block limit)") { - val bxsQty = 392 // with greater value test is failing with collection size exception - val (inputs, tx) = validErgoTransactionGenTemplate(1, 1,16).sample.get // it takes too long to test with `forAll` - val tokens = (0 until 255).map(_ => (scorex.util.Random.randomBytes().toTokenId, Random.nextLong)) - val (in, out) = { - val in0 = inputs.head - val out0 = tx.outputs.head - val inputsMod = (0 until bxsQty).map { i => - testBox(10000000000L, in0.ergoTree, in0.creationHeight, - tokens, in0.additionalRegisters, in0.transactionId, i.toShort) - } - val outputsMod = (0 until bxsQty).map { i => - testBox(10000000000L, out0.ergoTree, out0.creationHeight, - tokens, out0.additionalRegisters, out0.transactionId, i.toShort) - } - inputsMod -> outputsMod - } - val inputsPointers = { - val inSample = tx.inputs.head - (0 until bxsQty).map(i => inSample.copy(boxId = in(i).id)) - } - val txMod = tx.copy(inputs = inputsPointers, outputCandidates = out) - val validFailure = txMod.statefulValidity(in, emptyDataBoxes, emptyStateContext) - validFailure.failed.get.getMessage should startWith(ValidationRules.errorMessage(txAssetsInOneBox, "", emptyModifierId, ErgoTransaction.modifierTypeId).take(30)) - } - - property("transaction with too many inputs should be rejected") { - - //we assume that verifier must finish verification of any script in less time than 250K hash calculations - // (for the Blake2b256 hash function over a single block input) - val Timeout: Long = { - val hf = Blake2b256 - - //just in case to heat up JVM - (1 to 5000000).foreach(i => hf(s"$i-$i")) - - val t0 = System.currentTimeMillis() - (1 to 250000).foreach(i => hf(s"$i")) - val t = System.currentTimeMillis() - t - t0 - } - - val gen = validErgoTransactionGenTemplate(0, 0, 2000, trueLeafGen) - val (from, tx) = gen.sample.get - tx.statelessValidity().isSuccess shouldBe true - - //check that spam transaction is being rejected quickly - implicit val verifier: ErgoInterpreter = ErgoInterpreter(parameters) - val (validity, time0) = BenchmarkUtil.measureTime(tx.statefulValidity(from, IndexedSeq(), emptyStateContext)) - validity.isSuccess shouldBe false - assert(time0 <= Timeout) - - val cause = validity.failed.get.getMessage - cause should startWith(ValidationRules.errorMessage(bsBlockTransactionsCost, "", emptyModifierId, ErgoTransaction.modifierTypeId).take(30)) - - //check that spam transaction validation with no cost limit is indeed taking too much time - import Parameters._ - val maxCost = (Int.MaxValue - 10) / 10 // cannot use Int.MaxValue directly due to overflow when it is converted to block cost - val ps = Parameters(0, DefaultParameters.updated(MaxBlockCostIncrease, maxCost), emptyVSUpdate) - val sc = new ErgoStateContext(Seq.empty, None, genesisStateDigest, ps, ErgoValidationSettings.initial, - VotingData.empty)(settings.chainSettings) - .upcoming(org.ergoplatform.mining.group.generator, - 0L, - settings.chainSettings.initialNBits, - Array.fill(3)(0.toByte), - ErgoValidationSettingsUpdate.empty, - 0.toByte) - val (_, time) = BenchmarkUtil.measureTime( - tx.statefulValidity(from, IndexedSeq(), sc)(verifier) - ) - - assert(time > Timeout) - } - - property("transaction cost") { - def paramsWith(manualCost: Int) = Parameters( - 0, - Parameters.DefaultParameters + (MaxBlockCostIncrease -> manualCost), - ErgoValidationSettingsUpdate.empty - ) - - val gen = validErgoTransactionGenTemplate(0, 0,10, trueLeafGen) - val (from, tx) = gen.sample.get - tx.statelessValidity().isSuccess shouldBe true - - // calculate costs manually - val initialCost: Long = - tx.inputs.size * parameters.inputCost + - tx.dataInputs.size * parameters.dataInputCost + - tx.outputs.size * parameters.outputCost + - ErgoInterpreter.interpreterInitCost - val (outAssets, outAssetsNum) = tx.outAssetsTry.get - val (inAssets, inAssetsNum) = ErgoBoxAssetExtractor.extractAssets(from).get - val totalAssetsAccessCost = - (outAssetsNum + inAssetsNum) * parameters.tokenAccessCost + - (inAssets.size + outAssets.size) * parameters.tokenAccessCost - val scriptsValidationCosts = tx.inputs.size + 1 // +1 for the block to JIT cost scaling - println(s"tx.inputs.size: ${tx.inputs.size}") - println(s"initialCost + totalAssetsAccessCost: ${initialCost + totalAssetsAccessCost}") - val approxCost: Int = (initialCost + totalAssetsAccessCost + scriptsValidationCosts).toInt - - - // check that validation pass if cost limit equals to approximated cost - val sc = stateContextWith(paramsWith(approxCost)) - sc.currentParameters.maxBlockCost shouldBe approxCost - val calculatedCost = tx.statefulValidity(from, IndexedSeq(), sc)(ErgoInterpreter(sc.currentParameters)).get - approxCost - calculatedCost <= 1 shouldBe true - - // transaction exceeds computations limit - val sc2 = stateContextWith(paramsWith(approxCost - 1)) - tx.statefulValidity(from, IndexedSeq(), sc2)(ErgoInterpreter(sc2.currentParameters)) shouldBe 'failure - - // transaction exceeds computations limit due to non-zero accumulatedCost - tx.statefulValidity(from, IndexedSeq(), sc, accumulatedCost = 1)(ErgoInterpreter(sc.currentParameters)) shouldBe 'failure - } - - property("cost accumulated correctly across inputs") { - val accInitCost = 100000 - - def inputCost(tx: ErgoTransaction, from: IndexedSeq[ErgoBox]): Long = { - val idx = 0 - val input = tx.inputs(idx) - val proof = input.spendingProof - val transactionContext = TransactionContext(from, IndexedSeq(), tx) - val inputContext = InputContext(idx.toShort, proof.extension) - - val ctx = new ErgoContext( - emptyStateContext, transactionContext, inputContext, - costLimit = emptyStateContext.currentParameters.maxBlockCost, - initCost = 0) - - val messageToSign = tx.messageToSign - - val inputCost = verifier.verify(from(idx).ergoTree, ctx, proof, messageToSign).get._2 - - inputCost - } - - forAll(smallPositiveInt) { inputsNum => - - val nonTrivialTrueGen = Gen.const(AND(Seq(TrueLeaf, TrueLeaf)).toSigmaProp.treeWithSegregation) - val gen = validErgoTransactionGenTemplate(0, 0, inputsNum, nonTrivialTrueGen) - val (from, tx) = gen.sample.get - tx.statelessValidity().isSuccess shouldBe true - - tx.inputs.length shouldBe inputsNum - - val tokenAccessCost = emptyStateContext.currentParameters.tokenAccessCost - - val txCost = tx.statefulValidity(from, IndexedSeq(), emptyStateContext, accInitCost).get - - val (inAssets, inAssetsNum): (Map[Seq[Byte], Long], Int) = ErgoBoxAssetExtractor.extractAssets(from).get - val (outAssets, outAssetsNum): (Map[Seq[Byte], Long], Int) = ErgoBoxAssetExtractor.extractAssets(tx.outputs).get - - val assetsCost = inAssetsNum * tokenAccessCost + inAssets.size * tokenAccessCost + - outAssetsNum * tokenAccessCost + outAssets.size * tokenAccessCost - - val unsignedTx = UnsignedErgoTransaction(tx.inputs, tx.dataInputs, tx.outputCandidates) - val signerTxCost = - defaultProver.signInputs(unsignedTx, from, Vector.empty, emptyStateContext, TransactionHintsBag.empty).get._2 - - val signerTxCostWithInitCost = signerTxCost + accInitCost - signerTxCostWithInitCost shouldBe txCost // signer and verifier costs should be the same - - val initialCost: Long = - tx.inputs.size * parameters.inputCost + - tx.dataInputs.size * parameters.dataInputCost + - tx.outputs.size * parameters.outputCost + - ErgoInterpreter.interpreterInitCost + - assetsCost - - txCost shouldBe (accInitCost + initialCost + inputCost(tx, from) * inputsNum) - } - } + property("a valid transaction is valid") { + forAll(validErgoTransactionGen) { case (from, tx) => + tx.statelessValidity().isSuccess shouldBe true + tx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe true + } + } + + property("ergo preservation law holds") { + forAll(validErgoTransactionGen, smallPositiveInt) { case ((from, tx), deltaAbs) => + val delta = if (Random.nextBoolean()) -deltaAbs else deltaAbs + + val wrongTx = tx.copy(outputCandidates = + modifyValue(tx.outputCandidates.head, delta) +: tx.outputCandidates.tail) + + wrongTx.statelessValidity().isSuccess && + wrongTx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe false + } + } + + property("impossible to create a negative-value output") { + forAll(validErgoTransactionGen) { case (from, tx) => + val negValue = Math.min(Math.abs(Random.nextLong()), Long.MaxValue - tx.outputCandidates.head.value) + val wrongTx = tx.copy(outputCandidates = + modifyValue(tx.outputCandidates.head, -(tx.outputCandidates.head.value + negValue)) +: tx.outputCandidates.tail) + + wrongTx.statelessValidity().isSuccess shouldBe false + wrongTx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe false + } + } + + property("impossible to overflow ergo tokens") { + forAll(validErgoTransactionGen) { case (from, tx) => + val overflowSurplus = (Long.MaxValue - tx.outputCandidates.map(_.value).sum) + 1 + + val wrongTx = tx.copy(outputCandidates = + modifyValue(tx.outputCandidates.head, overflowSurplus) +: tx.outputCandidates.tail) + + wrongTx.statelessValidity().isSuccess shouldBe false + wrongTx.statefulValidity(from, emptyDataBoxes, emptyStateContext).isSuccess shouldBe false + } + } + + property("assets preservation law holds") { + forAll(validErgoTransactionWithAssetsGen) { case (from, tx) => + checkTx(from, updateAnAsset(tx, from, _ + 1)) shouldBe 'failure + } + } + + property("impossible to create an asset of negative amount") { + forAll(validErgoTransactionWithAssetsGen) { case (from, tx) => + checkTx(from, updateAnAsset(tx, from, _ => -1)) shouldBe 'failure + } + } + + property("impossible to create an asset of zero amount") { + forAll(validErgoTransactionWithAssetsGen) { case (from, tx) => + checkTx(from, updateAnAsset(tx, from, _ => 0)) shouldBe 'failure + } + } + + property("impossible to overflow an asset value") { + val gen = validErgoTransactionGenTemplate(minAssets = 1, maxAssets = 1, maxInputs = 16, propositionGen = trueLeafGen) + forAll(gen) { case (from, tx) => + val tokenOpt = tx.outputCandidates.flatMap(_.additionalTokens.toArray) + .groupBy(_._1).find(_._2.size >= 2) + + whenever(tokenOpt.nonEmpty) { + val tokenId = tokenOpt.get._1 + val tokenAmount = tokenOpt.get._2.map(_._2).sum + + var modified = false + val updCandidates = tx.outputCandidates.map { c => + val updTokens = c.additionalTokens.map { case (id, amount) => + if (!modified && id == tokenId) { + modified = true + id -> ((Long.MaxValue - tokenAmount) + amount + 1) + } else { + id -> amount + } + } + new ErgoBoxCandidate(c.value, c.ergoTree, startHeight, updTokens, c.additionalRegisters) + } + + val wrongTx = tx.copy(outputCandidates = updCandidates) + checkTx(from, wrongTx) shouldBe 'failure + } + } + } + + property("stateful validation should catch false proposition") { + val propositionGen = Gen.const(Constants.FalseTree) + val gen = validErgoTransactionGenTemplate(1, 1, 1, propositionGen) + forAll(gen) { case (from, tx) => + tx.statelessValidity().isSuccess shouldBe true + val validity = tx.statefulValidity(from, emptyDataBoxes, emptyStateContext) + validity.isSuccess shouldBe false + val e = validity.failed.get + e.getMessage should startWith(ValidationRules.errorMessage(ValidationRules.txScriptValidation, "", emptyModifierId, ErgoTransaction.modifierTypeId)) + } + } + + property("assets usage correctly affects transaction total cost") { + val txGen = validErgoTransactionGenTemplate(1, 1, 16, propositionGen = trueLeafGen) + forAll(txGen) { case (from, tx) => + val initTxCost = tx.statefulValidity(from, emptyDataBoxes, emptyStateContext).get + + // already existing token from one of the inputs + val existingToken = from.flatMap(_.additionalTokens.toArray).toSet.head + // completely new token + val randomToken = (scorex.util.Random.randomBytes().toTokenId, Random.nextInt(100000000).toLong) + + val in0 = from.last + // new token added to the last input + val modifiedIn0 = testBox(in0.value, in0.ergoTree, in0.creationHeight, + in0.additionalTokens.toArray.toSeq :+ randomToken, in0.additionalRegisters, in0.transactionId, in0.index) + val txInMod0 = tx.inputs.last.copy(boxId = modifiedIn0.id) + + val in1 = from.last + // existing token added to the last input + val modifiedIn1 = testBox(in1.value, in1.ergoTree, in1.creationHeight, + in1.additionalTokens.toArray.toSeq :+ existingToken, in1.additionalRegisters, in1.transactionId, in1.index) + val txInMod1 = tx.inputs.last.copy(boxId = modifiedIn1.id) + + val out0 = tx.outputs.last + // new token added to the last output + val modifiedOut0 = testBox(out0.value, out0.ergoTree, out0.creationHeight, + out0.additionalTokens.toArray.toSeq :+ randomToken, out0.additionalRegisters, out0.transactionId, out0.index) + // existing token added to the last output + val modifiedOut1 = testBox(out0.value, out0.ergoTree, out0.creationHeight, + out0.additionalTokens.toArray.toSeq :+ existingToken, out0.additionalRegisters, out0.transactionId, out0.index) + + // update transaction inputs and outputs accordingly + val txMod0 = tx.copy(inputs = tx.inputs.init :+ txInMod0) // new token group added to one input + val txMod1 = tx.copy(inputs = tx.inputs.init :+ txInMod1) // existing token added to one input + val txMod2 = tx.copy(inputs = tx.inputs.init :+ txInMod0, // new token group added to one input and one output + outputCandidates = tx.outputCandidates.init :+ modifiedOut0) + val txMod3 = tx.copy(inputs = tx.inputs.init :+ txInMod1, // existing token added to one input and one output + outputCandidates = tx.outputCandidates.init :+ modifiedOut1) + + val inputIncTxCost0 = txMod0.statefulValidity(from.init :+ modifiedIn0, emptyDataBoxes, emptyStateContext).get + val inputIncTxCost1 = txMod1.statefulValidity(from.init :+ modifiedIn1, emptyDataBoxes, emptyStateContext).get + val outputIncTxCost0 = txMod2.statefulValidity(from.init :+ modifiedIn0, emptyDataBoxes, emptyStateContext).get + val outputIncTxCost1 = txMod3.statefulValidity(from.init :+ modifiedIn1, emptyDataBoxes, emptyStateContext).get + + (inputIncTxCost0 - initTxCost) shouldEqual Parameters.TokenAccessCostDefault * 2 // one more group + one more token in total + (inputIncTxCost1 - initTxCost) shouldEqual Parameters.TokenAccessCostDefault // one more token in total + (outputIncTxCost0 - inputIncTxCost0) shouldEqual Parameters.TokenAccessCostDefault * 2 + (outputIncTxCost1 - inputIncTxCost1) shouldEqual Parameters.TokenAccessCostDefault + } + } + + property("spam simulation (transaction validation cost with too many tokens exceeds block limit)") { + val bxsQty = 392 // with greater value test is failing with collection size exception + val (inputs, tx) = validErgoTransactionGenTemplate(1, 1, 16).sample.get // it takes too long to test with `forAll` + val tokens = (0 until 255).map(_ => (scorex.util.Random.randomBytes().toTokenId, Random.nextLong)) + val (in, out) = { + val in0 = inputs.head + val out0 = tx.outputs.head + val inputsMod = (0 until bxsQty).map { i => + testBox(10000000000L, in0.ergoTree, in0.creationHeight, + tokens, in0.additionalRegisters, in0.transactionId, i.toShort) + } + val outputsMod = (0 until bxsQty).map { i => + testBox(10000000000L, out0.ergoTree, out0.creationHeight, + tokens, out0.additionalRegisters, out0.transactionId, i.toShort) + } + inputsMod -> outputsMod + } + val inputsPointers = { + val inSample = tx.inputs.head + (0 until bxsQty).map(i => inSample.copy(boxId = in(i).id)) + } + val txMod = tx.copy(inputs = inputsPointers, outputCandidates = out) + val validFailure = txMod.statefulValidity(in, emptyDataBoxes, emptyStateContext) + validFailure.failed.get.getMessage should startWith(ValidationRules.errorMessage(txAssetsInOneBox, "", emptyModifierId, ErgoTransaction.modifierTypeId).take(30)) + } + + property("transaction with too many inputs should be rejected") { + + //we assume that verifier must finish verification of any script in less time than 250K hash calculations + // (for the Blake2b256 hash function over a single block input) + val Timeout: Long = { + val hf = Blake2b256 + + //just in case to heat up JVM + (1 to 5000000).foreach(i => hf(s"$i-$i")) + + val t0 = System.currentTimeMillis() + (1 to 250000).foreach(i => hf(s"$i")) + val t = System.currentTimeMillis() + t - t0 + } + + val gen = validErgoTransactionGenTemplate(0, 0, 2000, trueLeafGen) + val (from, tx) = gen.sample.get + tx.statelessValidity().isSuccess shouldBe true + + //check that spam transaction is being rejected quickly + implicit val verifier: ErgoInterpreter = ErgoInterpreter(parameters) + val (validity, time0) = BenchmarkUtil.measureTime(tx.statefulValidity(from, IndexedSeq(), emptyStateContext)) + validity.isSuccess shouldBe false + assert(time0 <= Timeout) + + val cause = validity.failed.get.getMessage + cause should startWith(ValidationRules.errorMessage(bsBlockTransactionsCost, "", emptyModifierId, ErgoTransaction.modifierTypeId).take(30)) + + //check that spam transaction validation with no cost limit is indeed taking too much time + import Parameters._ + val maxCost = (Int.MaxValue - 10) / 10 // cannot use Int.MaxValue directly due to overflow when it is converted to block cost + val ps = Parameters(0, DefaultParameters.updated(MaxBlockCostIncrease, maxCost), emptyVSUpdate) + val sc = new ErgoStateContext(Seq.empty, None, genesisStateDigest, ps, ErgoValidationSettings.initial, + VotingData.empty)(settings.chainSettings) + .upcoming(org.ergoplatform.mining.group.generator, + 0L, + settings.chainSettings.initialNBits, + Array.fill(3)(0.toByte), + ErgoValidationSettingsUpdate.empty, + 0.toByte) + val (_, time) = BenchmarkUtil.measureTime( + tx.statefulValidity(from, IndexedSeq(), sc)(verifier) + ) + + assert(time > Timeout) + } + + property("transaction cost") { + def paramsWith(manualCost: Int) = Parameters( + 0, + Parameters.DefaultParameters + (MaxBlockCostIncrease -> manualCost), + ErgoValidationSettingsUpdate.empty + ) + + val gen = validErgoTransactionGenTemplate(0, 0, 10, trueLeafGen) + val (from, tx) = gen.sample.get + tx.statelessValidity().isSuccess shouldBe true + + // calculate costs manually + val initialCost: Long = + tx.inputs.size * parameters.inputCost + + tx.dataInputs.size * parameters.dataInputCost + + tx.outputs.size * parameters.outputCost + + ErgoInterpreter.interpreterInitCost + val (outAssets, outAssetsNum) = tx.outAssetsTry.get + val (inAssets, inAssetsNum) = ErgoBoxAssetExtractor.extractAssets(from).get + val totalAssetsAccessCost = + (outAssetsNum + inAssetsNum) * parameters.tokenAccessCost + + (inAssets.size + outAssets.size) * parameters.tokenAccessCost + val scriptsValidationCosts = tx.inputs.size + 1 // +1 for the block to JIT cost scaling + println(s"tx.inputs.size: ${tx.inputs.size}") + println(s"initialCost + totalAssetsAccessCost: ${initialCost + totalAssetsAccessCost}") + val approxCost: Int = (initialCost + totalAssetsAccessCost + scriptsValidationCosts).toInt + + + // check that validation pass if cost limit equals to approximated cost + val sc = stateContextWith(paramsWith(approxCost)) + sc.currentParameters.maxBlockCost shouldBe approxCost + println("bv: " + sc.currentParameters.blockVersion) + val calculatedCost = tx.statefulValidity(from, IndexedSeq(), sc)(ErgoInterpreter(sc.currentParameters)).get + approxCost - calculatedCost <= 1 shouldBe true + + // transaction exceeds computations limit + val sc2 = stateContextWith(paramsWith(approxCost - 1)) + tx.statefulValidity(from, IndexedSeq(), sc2)(ErgoInterpreter(sc2.currentParameters)) shouldBe 'failure + + // transaction exceeds computations limit due to non-zero accumulatedCost + tx.statefulValidity(from, IndexedSeq(), sc, accumulatedCost = 1)(ErgoInterpreter(sc.currentParameters)) shouldBe 'failure + } + + property("cost accumulated correctly across inputs") { + val accInitCost = 100000 + + def inputCost(tx: ErgoTransaction, from: IndexedSeq[ErgoBox]): Long = { + val idx = 0 + val input = tx.inputs(idx) + val proof = input.spendingProof + val transactionContext = TransactionContext(from, IndexedSeq(), tx) + val inputContext = InputContext(idx.toShort, proof.extension) + + val ctx = new ErgoContext( + emptyStateContext, transactionContext, inputContext, + costLimit = emptyStateContext.currentParameters.maxBlockCost, + initCost = 0) + + val messageToSign = tx.messageToSign + + val inputCost = verifier.verify(from(idx).ergoTree, ctx, proof, messageToSign).get._2 + + inputCost + } + + forAll(smallPositiveInt) { inputsNum => + + val nonTrivialTrueGen = Gen.const(ErgoTree.withSegregation(DefaultHeader, AND(Seq(TrueLeaf, TrueLeaf)).toSigmaProp)) + val gen = validErgoTransactionGenTemplate(0, 0, inputsNum, nonTrivialTrueGen) + val (from, tx) = gen.sample.get + tx.statelessValidity().isSuccess shouldBe true + + tx.inputs.length shouldBe inputsNum + + val tokenAccessCost = emptyStateContext.currentParameters.tokenAccessCost + + val txCost = tx.statefulValidity(from, IndexedSeq(), emptyStateContext, accInitCost).get + + val (inAssets, inAssetsNum): (Map[Seq[Byte], Long], Int) = ErgoBoxAssetExtractor.extractAssets(from).get + val (outAssets, outAssetsNum): (Map[Seq[Byte], Long], Int) = ErgoBoxAssetExtractor.extractAssets(tx.outputs).get + + val assetsCost = inAssetsNum * tokenAccessCost + inAssets.size * tokenAccessCost + + outAssetsNum * tokenAccessCost + outAssets.size * tokenAccessCost + + val unsignedTx = UnsignedErgoTransaction(tx.inputs, tx.dataInputs, tx.outputCandidates) + val signerTxCost = + defaultProver.signInputs(unsignedTx, from, Vector.empty, emptyStateContext, TransactionHintsBag.empty).get._2 + + val signerTxCostWithInitCost = signerTxCost + accInitCost + signerTxCostWithInitCost shouldBe txCost // signer and verifier costs should be the same + + val initialCost: Long = + tx.inputs.size * parameters.inputCost + + tx.dataInputs.size * parameters.dataInputCost + + tx.outputs.size * parameters.outputCost + + ErgoInterpreter.interpreterInitCost + + assetsCost + + txCost shouldBe (accInitCost + initialCost + inputCost(tx, from) * inputsNum) + } + } + + private val v60scripts = Array( + "sigmaProp(Global.serialize(2).size > 0)", + """{ + | val b = 1.toByte + | b.toBits == Coll(false, false, false, false, false, false, false, true) + |}""".stripMargin, + """{ + | val b = bigInt("-1") + | val m = unsignedBigInt("5") + | val ub = b.toUnsignedMod(m) + | ub >= 0 + | } """.stripMargin /*, + """{ + | val oh = getVar[Option[Header]](21).get + | sigmaProp(oh.isDefined) + | } """.stripMargin */ + ) + + property("Execution of 6.0 Ergoscript - v3 tree") { + + v60scripts.foreach { script => + val protocolVersion = 4.toByte + val treeVersion = (protocolVersion - 1).toByte + val params = new Parameters(0, DevnetLaunchParameters.parametersTable.updated(123, protocolVersion), ErgoValidationSettingsUpdate.empty) + + val stateContext = emptyStateContext.copy(currentParameters = params)(chainSettings) + stateContext.blockVersion shouldBe protocolVersion + + val ergoTree = compileSourceV6(script, treeVersion) + + ergoTree.root.isRight shouldBe true // parsed + + val b = new ErgoBox(1000000000L, ergoTree, Colls.emptyColl, + Map.empty, ModifierId @@ "c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742", + 0, 0) + val input = Input(b.id, ProverResult(Array.emptyByteArray, ContextExtension.empty)) + + val oc = new ErgoBoxCandidate(b.value, b.ergoTree, b.creationHeight) + + val utx = new ErgoTransaction(IndexedSeq(input), IndexedSeq.empty, IndexedSeq(oc)) + + val f = utx.statefulValidity(IndexedSeq(b), IndexedSeq.empty, stateContext, 0)(defaultProver) + f.isSuccess shouldBe true + } + } + + property("Execution of 6.0 Ergoscript reducing to false") { + + val protocolVersion = 4.toByte + val treeVersion = (protocolVersion - 1).toByte + val params = new Parameters(0, DevnetLaunchParameters.parametersTable.updated(123, protocolVersion), ErgoValidationSettingsUpdate.empty) + + val stateContext = emptyStateContext.copy(currentParameters = params)(chainSettings) + stateContext.blockVersion shouldBe protocolVersion + + val ergoTree = compileSourceV6("sigmaProp(Global.serialize(2).size <= 0)", treeVersion) + + ergoTree.root.isRight shouldBe true // parsed + + val b = new ErgoBox(1000000000L, ergoTree, Colls.emptyColl, + Map.empty, ModifierId @@ "c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742", + 0, 0) + val input = Input(b.id, ProverResult(Array.emptyByteArray, ContextExtension.empty)) + + val oc = new ErgoBoxCandidate(b.value, b.ergoTree, b.creationHeight) + + val utx = new ErgoTransaction(IndexedSeq(input), IndexedSeq.empty, IndexedSeq(oc)) + + val f = utx.statefulValidity(IndexedSeq(b), IndexedSeq.empty, stateContext, 0)(defaultProver) + f.isSuccess shouldBe false + f.failed.get.getMessage.contains("#0 => Success((false,") shouldBe true + } + + property("6.0 execution of unparsed Ergoscript reducing to false") { + + val protocolVersion = 4.toByte + val params = new Parameters(0, DevnetLaunchParameters.parametersTable.updated(123, protocolVersion), ErgoValidationSettingsUpdate.empty) + + val stateContext = emptyStateContext.copy(currentParameters = params)(chainSettings) + stateContext.blockVersion shouldBe protocolVersion + + // v2 tree but v3 instructions + val ergoTree = DefaultSerializer.deserializeErgoTree(Base16.decode("1a150206022edf0580fcf622d193db060873007e730106").get) + ergoTree.root.isRight shouldBe false + + val b = new ErgoBox(1000000000L, ergoTree, Colls.emptyColl, + Map.empty, ModifierId @@ "c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742", + 0, 0) + val input = Input(b.id, ProverResult(Array.emptyByteArray, ContextExtension.empty)) + + val oc = new ErgoBoxCandidate(b.value, b.ergoTree, b.creationHeight) + + val utx = new ErgoTransaction(IndexedSeq(input), IndexedSeq.empty, IndexedSeq(oc)) + + val f = utx.statefulValidity(IndexedSeq(b), IndexedSeq.empty, stateContext, 0)(defaultProver) + f.isSuccess shouldBe false + } + + property("Boxes containing 6.0 data types") { + val ubic = UnsignedBigIntConstant(new BigInteger("2")) + val b = new ErgoBox(1000000000L, ErgoTreePredef.TrueProp(ErgoTree.defaultHeaderWithVersion(3.toByte)), Colls.emptyColl, + Map(R4 -> ubic), ModifierId @@ "c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742", + 0, 0) + + VersionContext.withVersions(3, 3) { + val bytes = ErgoBoxSerializer.toBytes(b) + println(Base16.encode(bytes)) + ErgoBoxSerializer.parseBytes(bytes) shouldBe b + } + } + } diff --git a/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala b/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala index 1cfa6f8219..6cacff30d8 100644 --- a/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala +++ b/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala @@ -8,11 +8,11 @@ import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, Input} import org.scalatest.Assertion import scorex.util.encode.Base16 import sigma.Colls -import sigmastate.Values.{ErgoTree, ShortConstant} -import sigmastate.interpreter.{ContextExtension, ProverResult} -import sigmastate.eval._ +import sigma.ast.{ErgoTree, ShortConstant} +import sigma.interpreter.{ContextExtension, ProverResult} +import sigma.serialization.ErgoTreeSerializer import sigmastate.helpers.TestingHelpers._ -import sigmastate.serialization.ErgoTreeSerializer +import org.ergoplatform.settings.Constants.TrueTree class ExpirationSpecification extends ErgoCorePropertyTest { import org.ergoplatform.utils.ErgoCoreTestConstants._ @@ -88,7 +88,7 @@ class ExpirationSpecification extends ErgoCorePropertyTest { forAll(unspendableErgoBoxGen()) { from => constructTest(from, 0, h => { val fee = Math.min(parameters.storageFeeFactor * from.bytes.length, from.value) - val feeBoxCandidate = new ErgoBoxCandidate(fee, Constants.TrueLeaf, creationHeight = h) + val feeBoxCandidate = new ErgoBoxCandidate(fee, TrueTree, creationHeight = h) IndexedSeq(changeValue(from, -fee), Some(feeBoxCandidate)).flatten }, expectedValidity = true) } @@ -98,7 +98,7 @@ class ExpirationSpecification extends ErgoCorePropertyTest { forAll(unspendableErgoBoxGen(parameters.storageFeeFactor * 100 + 1, Long.MaxValue)) { from => constructTest(from, 0, h => { val fee = Math.min(parameters.storageFeeFactor * from.bytes.length + 1, from.value) - val feeBoxCandidate = new ErgoBoxCandidate(fee, Constants.TrueLeaf, creationHeight = h) + val feeBoxCandidate = new ErgoBoxCandidate(fee, TrueTree, creationHeight = h) IndexedSeq(changeValue(from, -fee), Some(feeBoxCandidate)).flatten }, expectedValidity = false) } @@ -108,7 +108,7 @@ class ExpirationSpecification extends ErgoCorePropertyTest { forAll(unspendableErgoBoxGen(parameters.storageFeeFactor * 100 + 1, Long.MaxValue)) { from => constructTest(from, 1, h => { val fee = Math.min(parameters.storageFeeFactor * from.bytes.length + 1, from.value) - val feeBoxCandidate = new ErgoBoxCandidate(fee, Constants.TrueLeaf, creationHeight = h) + val feeBoxCandidate = new ErgoBoxCandidate(fee, TrueTree, creationHeight = h) IndexedSeq(changeValue(from, -fee), Some(feeBoxCandidate)).flatten }, expectedValidity = false) @@ -119,7 +119,7 @@ class ExpirationSpecification extends ErgoCorePropertyTest { forAll(unspendableErgoBoxGen()) { from => constructTest(from, -1, h => { val fee = Math.min(parameters.storageFeeFactor * from.bytes.length, from.value) - val feeBoxCandidate = new ErgoBoxCandidate(fee, Constants.TrueLeaf, creationHeight = h) + val feeBoxCandidate = new ErgoBoxCandidate(fee, TrueTree, creationHeight = h) IndexedSeq(changeValue(from, -fee), Some(feeBoxCandidate)).flatten }, expectedValidity = false) } @@ -127,7 +127,7 @@ class ExpirationSpecification extends ErgoCorePropertyTest { property("script changed spending w. same value") { forAll(unspendableErgoBoxGen()) { from => - val out = new ErgoBoxCandidate(from.value, Constants.TrueLeaf, from.creationHeight + 1, from.additionalTokens) + val out = new ErgoBoxCandidate(from.value, TrueTree, from.creationHeight + 1, from.additionalTokens) constructTest(from, 0, _ => IndexedSeq(out), expectedValidity = false) } } @@ -156,14 +156,14 @@ class ExpirationSpecification extends ErgoCorePropertyTest { forAll(unspendableErgoBoxGen(minValue, Long.MaxValue)) { from => val outcome = from.value <= from.bytes.length * parameters.storageFeeFactor - val out1 = new ErgoBoxCandidate(from.value - minValue, Constants.TrueLeaf, creationHeight = from.creationHeight + 1) + val out1 = new ErgoBoxCandidate(from.value - minValue, TrueTree, creationHeight = from.creationHeight + 1) constructTest(from, 0, _ => IndexedSeq(out1, out2), expectedValidity = outcome) } } property("destructing the whole box when its value no more than storage fee") { forAll(unspendableErgoBoxGen(maxValue = parameters.storageFeeFactor)) { from => - val out = new ErgoBoxCandidate(from.value, Constants.TrueLeaf, creationHeight = from.creationHeight + 1) + val out = new ErgoBoxCandidate(from.value, TrueTree, creationHeight = from.creationHeight + 1) constructTest(from, 0, _ => IndexedSeq(out), expectedValidity = true) } } diff --git a/src/test/scala/org/ergoplatform/nodeView/history/extra/ChainGenerator.scala b/src/test/scala/org/ergoplatform/nodeView/history/extra/ChainGenerator.scala index feffd72bb1..09657ea670 100644 --- a/src/test/scala/org/ergoplatform/nodeView/history/extra/ChainGenerator.scala +++ b/src/test/scala/org/ergoplatform/nodeView/history/extra/ChainGenerator.scala @@ -16,11 +16,10 @@ import org.ergoplatform.utils.ErgoTestHelpers import org.ergoplatform._ import org.scalatest.matchers.should.Matchers import scorex.util.ModifierId +import sigma.ast.ErgoTree +import sigma.data.ProveDlog import sigma.{Coll, Colls} -import sigmastate.Values -import sigmastate.crypto.DLogProtocol.ProveDlog import sigmastate.eval.Extensions._ -import sigmastate.eval._ import java.io.File import scala.annotation.tailrec @@ -40,8 +39,8 @@ object ChainGenerator extends ErgoTestHelpers with Matchers { val RewardDelay: Int = initSettings.chainSettings.monetary.minerRewardDelay val MaxTxsPerBlock: Int = 10 val minerPk: ProveDlog = defaultProver.hdKeys.head.publicImage - val selfAddressScript: Values.ErgoTree = P2PKAddress(minerPk).script - val minerProp: Values.ErgoTree = ErgoTreePredef.rewardOutputScript(RewardDelay, minerPk) + val selfAddressScript: ErgoTree = P2PKAddress(minerPk).script + val minerProp: ErgoTree = ErgoTreePredef.rewardOutputScript(RewardDelay, minerPk) val votingEpochLength: Height = votingSettings.votingLength val protocolVersion: Byte = initSettings.chainSettings.protocolVersion val minimalSuffix = 2 diff --git a/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala b/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala index 5ee89a9a4c..f4adc6632d 100644 --- a/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/mempool/ErgoMemPoolSpec.scala @@ -1,15 +1,16 @@ package org.ergoplatform.nodeView.mempool import org.ergoplatform.{ErgoBoxCandidate, Input} -import org.ergoplatform.nodeView.mempool.ErgoMemPoolUtils.{SortingOption, ProcessingOutcome} +import org.ergoplatform.nodeView.mempool.ErgoMemPoolUtils.{ProcessingOutcome, SortingOption} import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction} import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState +import org.ergoplatform.settings.Constants.TrueTree import org.ergoplatform.settings.ErgoSettings import org.ergoplatform.utils.ErgoTestHelpers import org.scalatest.flatspec.AnyFlatSpec import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks -import sigmastate.Values.{ByteArrayConstant, TrueLeaf} -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigma.ast.ByteArrayConstant +import sigma.interpreter.{ContextExtension, ProverResult} class ErgoMemPoolSpec extends AnyFlatSpec with ErgoTestHelpers @@ -102,7 +103,7 @@ class ErgoMemPoolSpec extends AnyFlatSpec val feeProp = settings.chainSettings.monetary.feeProposition val inputBox = wus.takeBoxes(100).collectFirst{ - case box if box.ergoTree == TrueLeaf.toSigmaProp.treeWithSegregation => box + case box if box.ergoTree == TrueTree => box }.get val feeOut = new ErgoBoxCandidate(inputBox.value, feeProp, creationHeight = 0) diff --git a/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala b/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala index ebe42d897d..8cb9fc2c3d 100644 --- a/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala @@ -4,17 +4,18 @@ import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix import org.ergoplatform.ErgoTreePredef.boxCreationHeight import org.ergoplatform.nodeView.state.{BoxHolder, ErgoState, UtxoState} import org.ergoplatform.settings.Algos +import org.ergoplatform.settings.Constants.{FalseTree, TrueTree} import org.ergoplatform.utils.{ErgoCorePropertyTest, RandomWrapper} import org.ergoplatform.wallet.utils.FileUtils -import org.ergoplatform.{ErgoBox, ErgoTreePredef, Height, Self} +import org.ergoplatform.{ErgoBox, ErgoTreePredef} import scorex.crypto.authds.avltree.batch.Remove -import sigmastate.Values._ +import sigma.ast.syntax.ValueOps +import sigma.ast.{EQ, ErgoTree, GE, Height, IntConstant, Self, SigmaAnd, SigmaOr, SigmaPropConstant, TransformingSigmaBuilder} +import sigma.compiler.ir.{CompiletimeIRContext, IRContext} +import sigma.compiler.{CompilerSettings, SigmaCompiler} +import sigma.crypto.CryptoConstants.dlogGroup +import sigma.data.ProveDlog import sigmastate._ -import sigmastate.crypto.CryptoConstants.dlogGroup -import sigmastate.crypto.DLogProtocol.ProveDlog -import sigmastate.eval.{CompiletimeIRContext, IRContext} -import sigmastate.lang.Terms._ -import sigmastate.lang.{CompilerSettings, SigmaCompiler, TransformingSigmaBuilder} import scala.util.Try @@ -33,16 +34,21 @@ class ScriptsSpec extends ErgoCorePropertyTest with FileUtils { property("simple operations without cryptography") { // true/false - applyBlockSpendingScript(Values.TrueLeaf.toSigmaProp) shouldBe 'success - applyBlockSpendingScript(Values.FalseLeaf.toSigmaProp) shouldBe 'failure + applyBlockSpendingScript(TrueTree) shouldBe 'success + applyBlockSpendingScript(FalseTree) shouldBe 'failure // eq - applyBlockSpendingScript(EQ(IntConstant(1), IntConstant(1)).toSigmaProp) shouldBe 'success - applyBlockSpendingScript(EQ(IntConstant(1), IntConstant(2)).toSigmaProp) shouldBe 'failure + applyBlockSpendingScript( + ErgoTree.fromProposition(EQ(IntConstant(1), IntConstant(1)).toSigmaProp)) shouldBe 'success + applyBlockSpendingScript( + ErgoTree.fromProposition(EQ(IntConstant(1), IntConstant(2)).toSigmaProp)) shouldBe 'failure // math - applyBlockSpendingScript(EQ(Plus(1, 2), Minus(6, 3)).toSigmaProp) shouldBe 'success - applyBlockSpendingScript(EQ(Multiply(1, 2), Divide(7, 3)).toSigmaProp) shouldBe 'success + applyBlockSpendingScript( + ErgoTree.fromProposition(EQ(Plus(1, 2), Minus(6, 3)).toSigmaProp)) shouldBe 'success + applyBlockSpendingScript( + ErgoTree.fromProposition(EQ(Multiply(1, 2), Divide(7, 3)).toSigmaProp)) shouldBe 'success // context - applyBlockSpendingScript(EQ(IntConstant(1), Height).toSigmaProp) shouldBe 'success + applyBlockSpendingScript( + ErgoTree.fromProposition(EQ(IntConstant(1), Height).toSigmaProp)) shouldBe 'success applyBlockSpendingScript(fromString("CONTEXT.preHeader.height == 1")) shouldBe 'success applyBlockSpendingScript(fromString("CONTEXT.headers.size == 0")) shouldBe 'success applyBlockSpendingScript(fromString(s"CONTEXT.dataInputs.exists{ (box: Box) => box.value == ${fixedBox.value}L}")) shouldBe 'success @@ -50,23 +56,31 @@ class ScriptsSpec extends ErgoCorePropertyTest with FileUtils { } property("simple crypto") { - applyBlockSpendingScript(defaultMinerPk) shouldBe 'success - applyBlockSpendingScript(SigmaAnd(defaultProver.hdKeys.map(s => SigmaPropConstant(s.publicImage)))) shouldBe 'success - applyBlockSpendingScript(SigmaAnd(defaultMinerPk, ProveDlog(dlogGroup.generator))) shouldBe 'failure - applyBlockSpendingScript(SigmaOr(defaultMinerPk, ProveDlog(dlogGroup.generator))) shouldBe 'success + applyBlockSpendingScript(ErgoTree.fromSigmaBoolean(defaultMinerPk)) shouldBe 'success + applyBlockSpendingScript( + ErgoTree.fromProposition( + SigmaAnd(defaultProver.hdKeys.map(s => SigmaPropConstant(s.publicImage))))) shouldBe 'success + applyBlockSpendingScript( + ErgoTree.fromProposition( + SigmaAnd(defaultMinerPk, ProveDlog(dlogGroup.generator)))) shouldBe 'failure + applyBlockSpendingScript( + ErgoTree.fromProposition( + SigmaOr(defaultMinerPk, ProveDlog(dlogGroup.generator)))) shouldBe 'success } property("predef scripts") { delta shouldBe -1000 - applyBlockSpendingScript(GE(Height, Plus(boxCreationHeight(Self), IntConstant(delta))).toSigmaProp) shouldBe 'success + applyBlockSpendingScript( + ErgoTree.fromProposition( + GE(Height, Plus(boxCreationHeight(Self), IntConstant(delta))).toSigmaProp)) shouldBe 'success applyBlockSpendingScript(ErgoTreePredef.rewardOutputScript(delta, defaultMinerPk)) shouldBe 'success // applyBlockSpendingScript(ErgoScriptPredef.feeProposition(delta)) shouldBe 'success } private def fromString(str: String): ErgoTree = { - compiler.compile(Map(), str).buildTree.asBoolValue.toSigmaProp + ErgoTree.fromProposition(compiler.compile(Map(), str).buildTree.asBoolValue.toSigmaProp) } private def applyBlockSpendingScript(script: ErgoTree): Try[UtxoState] = { diff --git a/src/test/scala/org/ergoplatform/nodeView/state/DigestStateSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/state/DigestStateSpecification.scala index 6378bf8f0d..f136241f42 100644 --- a/src/test/scala/org/ergoplatform/nodeView/state/DigestStateSpecification.scala +++ b/src/test/scala/org/ergoplatform/nodeView/state/DigestStateSpecification.scala @@ -7,7 +7,7 @@ import org.ergoplatform.modifiers.mempool.ErgoTransaction import org.ergoplatform.utils.{ErgoCorePropertyTest, RandomWrapper} import org.ergoplatform.core._ import scorex.crypto.authds.ADDigest -import sigmastate.interpreter.ProverResult +import sigma.interpreter.ProverResult class DigestStateSpecification extends ErgoCorePropertyTest { import org.ergoplatform.utils.ErgoNodeTestConstants._ diff --git a/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala index 11e53bcf18..5e2c636020 100644 --- a/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala +++ b/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala @@ -1,21 +1,23 @@ package org.ergoplatform.nodeView.state +import org.ergoplatform.ErgoBoxCandidate import org.ergoplatform.modifiers.ErgoFullBlock import org.ergoplatform.modifiers.history.BlockTransactions import org.ergoplatform.modifiers.history.header.Header import org.ergoplatform.modifiers.mempool.ErgoTransaction import org.ergoplatform.settings.{Args, ErgoSettingsReader} -import org.ergoplatform.utils.{ErgoCorePropertyTest, RandomWrapper} +import org.ergoplatform.utils.{ErgoCompilerHelpers, ErgoCorePropertyTest, ErgoStateContextHelpers, RandomWrapper} import org.ergoplatform.wallet.boxes.ErgoBoxSerializer import org.scalacheck.Gen -import org.ergoplatform.core.bytesToVersion -import org.ergoplatform.validation.ValidationResult.Valid +import org.ergoplatform.core.{bytesToId, bytesToVersion} +import org.ergoplatform.settings.Constants.TrueTree +import org.ergoplatform.validation.ValidationResult.{Invalid, Valid} import scorex.db.ByteArrayWrapper import scala.collection.mutable import scala.util.{Failure, Try} -class ErgoStateSpecification extends ErgoCorePropertyTest { +class ErgoStateSpecification extends ErgoCorePropertyTest with ErgoCompilerHelpers with ErgoStateContextHelpers { import org.ergoplatform.utils.ErgoNodeTestConstants._ import org.ergoplatform.utils.ErgoCoreTestConstants._ import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators._ @@ -192,4 +194,39 @@ class ErgoStateSpecification extends ErgoCorePropertyTest { // no transactions are valid assert(ErgoState.execTransactions(Seq.empty, stateContext, settings.nodeSettings)(id => Try(boxes(ByteArrayWrapper(id)))).isValid) } + + property("ErgoState.execTransactions() - invalid 6.0 spending after 6.0 activation") { + val sc = stateContext(1, 4, settings) + + val bx = new ErgoBoxCandidate(1000000000L, TrueTree, 0).toBox(bytesToId(Array.fill(32)(0.toByte)), 0) + val tx1 = validTransactionFromBoxes(IndexedSeq(bx), outputsProposition = TrueTree) + + val ergoTree = compileSourceV6("sigmaProp(Global.serialize(2).size <= 0)", treeVersion = 3) + + val tx2 = validTransactionFromBoxes(tx1.outputs, outputsProposition = ergoTree) + + val tx3 = validTransactionFromBoxes(tx2.outputs, outputsProposition = TrueTree) + + val txs = IndexedSeq(tx1, tx2, tx3) + + val boxes = (IndexedSeq(bx) ++ txs.flatMap(_.outputs)).map(o => ByteArrayWrapper(o.id) -> o).toMap + + val execRes = ErgoState.execTransactions(txs, sc, settings.nodeSettings)(id => Try(boxes(ByteArrayWrapper(id)))) + execRes.isInstanceOf[Invalid] shouldBe true + execRes.asInstanceOf[Invalid].errors.head.message.startsWith("Scripts of all transaction inputs should pass verification") shouldBe true + + val ergoTree2 = compileSourceV6("sigmaProp(Global.serialize(2).size > 0)", treeVersion = 3) + + val tx22 = validTransactionFromBoxes(tx1.outputs, outputsProposition = ergoTree2) + + val tx32 = validTransactionFromBoxes(tx22.outputs, outputsProposition = TrueTree) + + val txs2 = IndexedSeq(tx1, tx22, tx32) + + val boxes2 = (IndexedSeq(bx) ++ txs2.flatMap(_.outputs)).map(o => ByteArrayWrapper(o.id) -> o).toMap + + val execRes2 = ErgoState.execTransactions(txs2, sc, settings.nodeSettings)(id => Try(boxes2(ByteArrayWrapper(id)))) + execRes2.isInstanceOf[Valid[_]] shouldBe true + } + } diff --git a/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala index 6c609d30bc..087fe37857 100644 --- a/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala +++ b/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala @@ -13,17 +13,19 @@ import org.ergoplatform.nodeView.history.ErgoHistoryUtils._ import org.ergoplatform.modifiers.transaction.TooHighCostError import org.ergoplatform.core.idToVersion import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState -import org.ergoplatform.settings.Constants +import org.ergoplatform.settings.Constants.FalseTree import org.ergoplatform.utils.{ErgoCorePropertyTest, RandomWrapper} import org.scalatest.OptionValues import scorex.crypto.authds.ADKey import scorex.db.ByteArrayWrapper import scorex.util.{ModifierId, bytesToId} import scorex.util.encode.Base16 -import sigmastate.Values.ByteArrayConstant -import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog} -import sigmastate.interpreter.ProverResult +import sigma.ast.{ByteArrayConstant, ErgoTree} +import sigma.data.ProveDlog +import sigma.interpreter.ProverResult +import sigmastate.crypto.DLogProtocol.DLogProverInput import sigmastate.helpers.TestingHelpers._ +import org.ergoplatform.settings.Constants.TrueTree import scala.concurrent.duration.Duration import scala.concurrent.{Await, ExecutionContext, ExecutionContextExecutor, Future} @@ -51,7 +53,7 @@ class UtxoStateSpecification extends ErgoCorePropertyTest with OptionValues { val inputs = IndexedSeq(Input(foundersBox.id, emptyProverResult)) val remaining = emission.remainingFoundationRewardAtHeight(height) val newFoundersBox = testBox(remaining, foundersBox.ergoTree, height, Seq(), Map(R4 -> foundersBox.additionalRegisters(R4))) - val rewardBox = testBox(foundersBox.value - remaining, defaultProver.hdKeys.last.publicImage, height) + val rewardBox = testBox(foundersBox.value - remaining, ErgoTree.fromSigmaBoolean(defaultProver.hdKeys.last.publicImage), height) val newBoxes = IndexedSeq(newFoundersBox, rewardBox) val unsignedTx = new UnsignedErgoTransaction(inputs, IndexedSeq(), newBoxes) val tx: ErgoTransaction = ErgoTransaction(defaultProver.sign(unsignedTx, IndexedSeq(foundersBox), emptyDataBoxes, us.stateContext).get) @@ -95,7 +97,7 @@ class UtxoStateSpecification extends ErgoCorePropertyTest with OptionValues { val inputs = IndexedSeq(Input(foundersBox.id, emptyProverResult)) val newBoxes = IndexedSeq( testBox(remaining, foundersBox.ergoTree, height, Seq(), foundersBox.additionalRegisters), - testBox(foundersBox.value - remaining, rewardPk, height, Seq()) + testBox(foundersBox.value - remaining, ErgoTree.fromSigmaBoolean(rewardPk), height, Seq()) ) val unsignedTx = new UnsignedErgoTransaction(inputs, IndexedSeq(), newBoxes) val tx = ErgoTransaction(defaultProver.sign(unsignedTx, IndexedSeq(foundersBox), emptyDataBoxes, us.stateContext).get) @@ -355,7 +357,7 @@ class UtxoStateSpecification extends ErgoCorePropertyTest with OptionValues { val spendingTx = ErgoTransaction( IndexedSeq(spendingTxInput), IndexedSeq(), - IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight)) + IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, TrueTree, creationHeight = startHeight)) ) val txs = txsFromHolder :+ spendingTx @@ -380,25 +382,25 @@ class UtxoStateSpecification extends ErgoCorePropertyTest with OptionValues { val spendingTx = ErgoTransaction( IndexedSeq(spendingTxInput), IndexedSeq(), - IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight)) + IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, TrueTree, creationHeight = startHeight)) ) val spending2Tx = ErgoTransaction( IndexedSeq(Input(spendingTx.outputs.head.id, emptyProverResult)), IndexedSeq(), - IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight)) + IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, TrueTree, creationHeight = startHeight)) ) val spending3Tx = ErgoTransaction( IndexedSeq(Input(spending2Tx.outputs.head.id, emptyProverResult)), IndexedSeq(), - IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight)) + IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, TrueTree, creationHeight = startHeight)) ) val spending4Tx = ErgoTransaction( IndexedSeq(Input(spending2Tx.outputs.head.id, emptyProverResult)), IndexedSeq(), - IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.FalseLeaf, creationHeight = startHeight)) + IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, FalseTree, creationHeight = startHeight)) ) val txs = txsFromHolder ++ Seq(spendingTx, spending2Tx, spending3Tx, spending4Tx) @@ -420,7 +422,7 @@ class UtxoStateSpecification extends ErgoCorePropertyTest with OptionValues { val spendingTx = ErgoTransaction( IndexedSeq(spendingTxInput), IndexedSeq(), - IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, Constants.TrueLeaf, creationHeight = startHeight))) + IndexedSeq(new ErgoBoxCandidate(boxToSpend.value, TrueTree, creationHeight = startHeight))) val txs = spendingTx +: txsFromHolder diff --git a/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala b/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala index 3891af32bc..f262713afb 100644 --- a/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/viewholder/ErgoNodeViewHolderSpec.scala @@ -8,7 +8,7 @@ import org.ergoplatform.nodeView.history.ErgoHistoryUtils._ import org.ergoplatform.nodeView.state.StateType.Utxo import org.ergoplatform.nodeView.state._ import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState -import org.ergoplatform.settings.{Algos, Constants, ErgoSettings} +import org.ergoplatform.settings.{Algos, ErgoSettings} import org.ergoplatform.utils.{ErgoCorePropertyTest, NodeViewTestConfig, NodeViewTestOps, TestCase} import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages._ import org.ergoplatform.network.ErgoNodeViewSynchronizerMessages._ @@ -18,6 +18,7 @@ import org.ergoplatform.nodeView.mempool.ErgoMemPoolUtils.ProcessingOutcome.Acce import org.ergoplatform.wallet.utils.FileUtils import scorex.crypto.authds.{ADKey, SerializedAdProof} import scorex.util.{ModifierId, bytesToId} +import org.ergoplatform.settings.Constants.TrueTree class ErgoNodeViewHolderSpec extends ErgoCorePropertyTest with NodeViewTestOps with FileUtils { import org.ergoplatform.utils.ErgoNodeTestConstants._ @@ -148,7 +149,7 @@ class ErgoNodeViewHolderSpec extends ErgoCorePropertyTest with NodeViewTestOps w val genesis = validFullBlock(parentOpt = None, us, bh) applyBlock(genesis) shouldBe 'success - val boxes = ErgoState.newBoxes(genesis.transactions).find(_.ergoTree == Constants.TrueLeaf) + val boxes = ErgoState.newBoxes(genesis.transactions).find(_.ergoTree == TrueTree) boxes.nonEmpty shouldBe true val tx = UnconfirmedTransaction(validTransactionFromBoxes(boxes.toIndexedSeq), None) diff --git a/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala b/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala index 99d126f685..be837f9c0e 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala @@ -9,7 +9,9 @@ import org.ergoplatform.nodeView.wallet.WalletScanLogic.ScanResults import org.ergoplatform.nodeView.wallet.persistence.{OffChainRegistry, WalletRegistry, WalletStorage} import org.ergoplatform.nodeView.wallet.requests.{AssetIssueRequest, PaymentRequest} import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanRequest, ScanWalletInteraction} +import org.ergoplatform.sdk.SecretString import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedSecretKey} +import org.ergoplatform.settings.Constants.TrueTree import org.ergoplatform.settings.ErgoSettings import org.ergoplatform.utils.fixtures.WalletFixture import org.ergoplatform.utils.{ErgoCorePropertyTest, MempoolTestHelpers, WalletTestOps} @@ -17,16 +19,14 @@ import org.ergoplatform.wallet.Constants.{PaymentsScanId, ScanId} import org.ergoplatform.wallet.boxes.BoxSelector.BoxSelectionResult import org.ergoplatform.wallet.boxes.{ErgoBoxSerializer, ReplaceCompactCollectBoxSelector, TrackedBox} import org.ergoplatform.wallet.crypto.ErgoSignature -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.mnemonic.Mnemonic import org.scalacheck.Gen import org.scalatest.BeforeAndAfterAll import scorex.db.{LDBKVStore, LDBVersionedStore} import scorex.util.encode.Base16 -import sigmastate.Values.{ByteArrayConstant, EvaluatedValue} -import sigmastate.eval.Extensions.ArrayOps +import sigma.Extensions.ArrayOps +import sigma.ast.{ByteArrayConstant, EvaluatedValue, FalseLeaf, SType} import sigmastate.helpers.TestingHelpers.testBox -import sigmastate.{SType, Values} import scala.collection.compat.immutable.ArraySeq import scala.util.Random @@ -97,7 +97,7 @@ class ErgoWalletServiceSpec ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), creationOutIndex = 0, None, - testBox(1L, Values.TrueLeaf.toSigmaProp, 0), + testBox(1L, TrueTree, 0), Set(PaymentsScanId) ) ) @@ -121,7 +121,7 @@ class ErgoWalletServiceSpec property("it should generate valid box candidates from payment request") { forAll(validErgoTransactionGen) { case (ergoBoxes, _) => - val paymentRequest = PaymentRequest(pks.head, 1, Seq.empty, Map.empty) + val paymentRequest = PaymentRequest(pks.head, 1, Array.empty, Map.empty) val paymentCandidates = requestsToBoxCandidates(Seq(paymentRequest), ergoBoxes.head.id, startHeight, parameters, pks).get paymentCandidates shouldBe List(new ErgoBoxCandidate(value = 1, ergoTree = pks.head.script, startHeight)) } @@ -132,7 +132,7 @@ class ErgoWalletServiceSpec case (ergoBoxes, _) => val ergoBox = ergoBoxes.head - val registers: Option[Map[NonMandatoryRegisterId, EvaluatedValue[_ <: SType]]] = Option(Map(ErgoBox.R4 -> sigmastate.Values.FalseLeaf)) + val registers: Option[Map[NonMandatoryRegisterId, EvaluatedValue[_ <: SType]]] = Option(Map(ErgoBox.R4 -> FalseLeaf)) val illegalAssetIssueRequest = AssetIssueRequest(address = pks.head, Some(1), amount = 1, "test", "test", 4, registers) val invalidCandidates = requestsToBoxCandidates(Seq(illegalAssetIssueRequest), ergoBox.id, startHeight, parameters, pks) invalidCandidates.failed.get.getMessage shouldBe "Additional registers contain R0...R6" @@ -173,7 +173,7 @@ class ErgoWalletServiceSpec Base16.encode(ErgoBoxSerializer.toBytes(box.box)) } - val paymentRequest = PaymentRequest(pks.head, 50000, Seq.empty, Map.empty) + val paymentRequest = PaymentRequest(pks.head, 50000, Array.empty, Map.empty) val boxSelector = new ReplaceCompactCollectBoxSelector(settings.walletSettings.maxInputs, settings.walletSettings.optimalInputs, None) val walletService = new ErgoWalletServiceImpl(ergoSettings) @@ -252,7 +252,7 @@ class ErgoWalletServiceSpec .map { box => Base16.encode(ErgoBoxSerializer.toBytes(box)) } - val paymentRequest = PaymentRequest(pks.head, 50000, Seq.empty, Map.empty) + val paymentRequest = PaymentRequest(pks.head, 50000, Array.empty, Map.empty) val boxSelector = new ReplaceCompactCollectBoxSelector(settings.walletSettings.maxInputs, settings.walletSettings.optimalInputs, None) val (tx, inputs, dataInputs) = generateUnsignedTransaction(wState, boxSelector, Seq(paymentRequest), inputsRaw = encodedBoxes, dataInputsRaw = Seq.empty).get diff --git a/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala b/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala index b646684250..84cdf928a9 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala @@ -7,7 +7,7 @@ import org.ergoplatform.nodeView.wallet.IdUtils._ import org.ergoplatform.nodeView.wallet.persistence.{WalletDigest, WalletDigestSerializer} import org.ergoplatform.nodeView.wallet.requests.{AssetIssueRequest, BurnTokensRequest, ExternalSecret, PaymentRequest} import org.ergoplatform.sdk.wallet.secrets.PrimitiveSecretKey -import org.ergoplatform.settings.{Algos, Constants} +import org.ergoplatform.settings.Algos import org.ergoplatform.utils._ import org.ergoplatform.utils.fixtures.WalletFixture import org.ergoplatform.wallet.boxes.BoxSelector.MinBoxValue @@ -17,10 +17,12 @@ import org.scalacheck.Gen import org.scalatest.concurrent.Eventually import scorex.util.ModifierId import scorex.util.encode.Base16 +import sigma.Extensions.ArrayOps +import sigma.ast.ErgoTree +import sigma.data.{CAND, CTHRESHOLD} import sigmastate.crypto.DLogProtocol.DLogProverInput import sigmastate.eval.Extensions._ -import sigmastate.eval._ -import sigmastate.{CAND, CTHRESHOLD} +import org.ergoplatform.settings.Constants.TrueTree import scala.concurrent.duration._ @@ -57,7 +59,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu // prepare a lot of inputs val inputsToCreate = 50 val sumToSpend = (snap.walletBalance - MinBoxValue) / (inputsToCreate + 1) - val req = (0 until inputsToCreate).map(_ => PaymentRequest(addresses.head, sumToSpend, Seq.empty, Map.empty)) + val req = (0 until inputsToCreate).map(_ => PaymentRequest(addresses.head, sumToSpend, Array.empty, Map.empty)) log.info(s"Confirmed balance $snap") log.info(s"Payment request $req") val tx = await(wallet.generateTransaction(req)).get @@ -73,7 +75,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu eventually { // generate transaction spending part of inputs val newSumToSpend = tx.outputs.head.value - val req2 = Seq(PaymentRequest(addresses.head, newSumToSpend, Seq.empty, Map.empty)) + val req2 = Seq(PaymentRequest(addresses.head, newSumToSpend, Array.empty, Map.empty)) log.info(s"Payment requests 2 $req2") val tx2 = await(wallet.generateTransaction(req2)).get (req2, tx2) @@ -107,7 +109,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val tokenDescription: String = s"ERG description" val tokenDecimals: Int = 9 val feeAmount = availableAmount / 4 - val feeReq = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), feeAmount, Seq.empty, Map.empty) + val feeReq = PaymentRequest(Pay2SAddress(TrueTree), feeAmount, Array.empty, Map.empty) val req = AssetIssueRequest(address, None, emissionAmount, tokenName, tokenDescription, tokenDecimals) val tx = await(wallet.generateTransaction(Seq(feeReq, req))).get log.info(s"Generated transaction $tx") @@ -140,9 +142,9 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val confirmedBalance = getConfirmedBalances.walletBalance //pay out all the wallet balance: - val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq + val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toArray assetToSpend should not be empty - val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty) + val req1 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance, assetToSpend, Map.empty) val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get tx1.outputs.size shouldBe 1 @@ -152,7 +154,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu //change == 1: val assetToSpend2 = assetToSpend.map { case (tokenId, tokenValue) => (tokenId, tokenValue - 1) } val assetToReturn = assetToSpend.map { case (tokenId, _) => (tokenId, 1L) } - val req2 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance - MinBoxValue, assetToSpend2, Map.empty) + val req2 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance - MinBoxValue, assetToSpend2, Map.empty) val tx2 = await(wallet.generateTransaction(Seq(req2))).get tx2.outputs.size shouldBe 2 @@ -180,9 +182,9 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val confirmedBalance = getConfirmedBalances.walletBalance //pay out all the wallet balance: - val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq + val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toArray assetToSpend should not be empty - val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty) + val req1 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance, assetToSpend, Map.empty) val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get tx1.outputs.size shouldBe 1 @@ -218,9 +220,9 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val confirmedBalance = getConfirmedBalances.walletBalance log.error(s"Confirmed balance $confirmedBalance") //pay out all the wallet balance: - val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq + val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toArray assetToSpend should not be empty - val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty) + val req1 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance, assetToSpend, Map.empty) val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get tx1.outputs.size shouldBe 1 @@ -228,9 +230,9 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu toAssetMap(tx1.outputs.head.additionalTokens.toArray) shouldBe toAssetMap(assetToSpend) //change == 1: - val assetToSpend2 = assetToSpend.map { case (tokenId, tokenValue) => (tokenId, tokenValue - 1) } + val assetToSpend2 = assetToSpend.map{ case (tokenId, tokenValue) => (tokenId, tokenValue - 1) } val assetToReturn = assetToSpend.map { case (tokenId, _) => (tokenId, 1L) } - val req2 = Seq(BurnTokensRequest(assetToSpend2), PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance - MinBoxValue, Seq.empty, Map.empty)) + val req2 = Seq(BurnTokensRequest(assetToSpend2), PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance - MinBoxValue, Array.empty, Map.empty)) val tx2 = await(wallet.generateTransaction(req2)).get tx2.outputs.size shouldBe 2 @@ -272,7 +274,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu Some(assetToSpend.map(x => encodedTokenId(x._1))) shouldBe ww.settings.walletSettings.tokensWhitelist assetToSpend should not be empty - val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance / 2, Seq.empty, Map.empty) + val req1 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance / 2, Array.empty, Map.empty) val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get tx1.outputs.size shouldBe 2 @@ -304,7 +306,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq assetToSpend should not be empty - val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance / 2, Seq.empty, Map.empty) + val req1 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance / 2, Array.empty, Map.empty) val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get tx1.outputs.size shouldBe 2 @@ -336,7 +338,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq assetToSpend should not be empty - val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance / 2, Seq.empty, Map.empty) + val req1 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance / 2, Array.empty, Map.empty) val tx1 = await(wallet.generateTransaction(Seq(req1), boxesToUseEncoded)).get tx1.outputs.size shouldBe 2 @@ -359,13 +361,13 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val (tx, block, assetsToSpend) = eventually { val snap = getConfirmedBalances - val assetsToSpend = assetsByTokenId(initialBoxes).toSeq + val assetsToSpend = assetsByTokenId(initialBoxes).toArray assetsToSpend should not be empty val sumToSpend = snap.walletBalance / (addresses.length + 1) val req = PaymentRequest(addresses.head, sumToSpend, assetsToSpend, Map.empty) +: - addresses.tail.map(a => PaymentRequest(a, sumToSpend, Seq.empty, Map.empty)) + addresses.tail.map(a => PaymentRequest(a, sumToSpend, Array.empty, Map.empty)) log.info(s"Confirmed balance $snap") log.info(s"Payment request $req") val tx = await(wallet.generateTransaction(req)).get @@ -388,7 +390,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val newSnap = getConfirmedBalances val newSumToSpend = newSnap.walletBalance / addresses.length val req2 = PaymentRequest(addresses.head, newSumToSpend, assetsToSpend, Map.empty) +: - addresses.tail.map(a => PaymentRequest(a, newSumToSpend, Seq.empty, Map.empty)) + addresses.tail.map(a => PaymentRequest(a, newSumToSpend, Array.empty, Map.empty)) log.info(s"New balance $newSnap") log.info(s"Payment requests 2 $req2") val tx2 = await(wallet.generateTransaction(req2)).get @@ -704,7 +706,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu // We need this second block to have something to rollback. Just spent some balance to anyone val balanceToSpend = randomLong(initialBalance) - val onchainSpendingTx = makeTx(initialBoxes, emptyProverResult, balanceToSpend, address.pubkey) + val onchainSpendingTx = makeTx(initialBoxes, emptyProverResult, balanceToSpend, ErgoTree.fromSigmaBoolean(address.pubkey)) val boxesToSpend = boxesAvailable(onchainSpendingTx, address.pubkey) val block = makeNextBlock(getUtxoState, Seq(onchainSpendingTx)) applyBlock(block) shouldBe 'success @@ -764,7 +766,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu eventually { val initialBalance = getConfirmedBalances.walletBalance val balanceToSpend = randomLong(balanceAmount(boxesToSpend)) - val creationTx = makeTx(boxesToSpend, emptyProverResult, balanceToSpend, pubKey, randomNewAsset) + val creationTx = makeTx(boxesToSpend, emptyProverResult, balanceToSpend, ErgoTree.fromSigmaBoolean(pubKey), randomNewAsset) val initialAssets = assetAmount(boxesAvailable(creationTx, pubKey)) initialAssets should not be empty log.info(s"Initial balance: $initialBalance") @@ -931,7 +933,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val initialBalance = balanceAmount(initialBoxes) val balancePicked = randomLong(initialBalance) - val creationTx = makeTx(initialBoxes, emptyProverResult, balancePicked, address.pubkey, randomNewAsset) + val creationTx = makeTx(initialBoxes, emptyProverResult, balancePicked, ErgoTree.fromSigmaBoolean(address.pubkey), randomNewAsset) val boxesToSpend = boxesAvailable(creationTx, address.pubkey) val balanceToSpend = balanceAmount(boxesToSpend) @@ -993,9 +995,9 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val confirmedBalance = getConfirmedBalances.walletBalance //pay out all the wallet balance: - val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq + val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toArray assetToSpend should not be empty - val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty) + val req1 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance, assetToSpend, Map.empty) val tx1 = await(wallet.generateTransaction(Seq(req1))).get tx1.outputs.size shouldBe 1 @@ -1005,7 +1007,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu //change == 1: val assetToSpend2 = assetToSpend.map { case (tokenId, tokenValue) => (tokenId, tokenValue - 1) } val assetToReturn = assetToSpend.map { case (tokenId, _) => (tokenId, 1L) } - val req2 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance - MinBoxValue, assetToSpend2, Map.empty) + val req2 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance - MinBoxValue, assetToSpend2, Map.empty) val tx2 = await(wallet.generateTransaction(Seq(req2))).get tx2.outputs.size shouldBe 2 @@ -1027,9 +1029,9 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val confirmedBalance = getConfirmedBalances.walletBalance //pay out all the wallet balance: - val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq + val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toArray assetToSpend should not be empty - val req1 = PaymentRequest(Pay2SAddress(Constants.TrueLeaf), confirmedBalance, assetToSpend, Map.empty) + val req1 = PaymentRequest(Pay2SAddress(TrueTree), confirmedBalance, assetToSpend, Map.empty) val utx = await(wallet.generateUnsignedTransaction(Seq(req1))).get utx.outputs.size shouldBe 1 @@ -1059,9 +1061,11 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val confirmedBalance = getConfirmedBalances.walletBalance //pay out all the wallet balance: - val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq + val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toArray assetToSpend should not be empty - val req1 = PaymentRequest(Pay2SAddress(CAND(Seq(secret1.publicImage, secret2.publicImage))), confirmedBalance, assetToSpend, Map.empty) + val req1 = PaymentRequest( + Pay2SAddress(ErgoTree.fromSigmaBoolean(CAND(Seq(secret1.publicImage, secret2.publicImage)))), + confirmedBalance, assetToSpend, Map.empty) val tx = await(wallet.generateTransaction(Seq(req1))).get @@ -1096,9 +1100,9 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu val confirmedBalance = getConfirmedBalances.walletBalance //pay out all the wallet balance: - val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq + val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toArray assetToSpend should not be empty - val addr = Pay2SAddress(CTHRESHOLD(2, Seq(secret1.publicImage, secret2.publicImage, secret3.publicImage))) + val addr = Pay2SAddress(ErgoTree.fromSigmaBoolean(CTHRESHOLD(2, Seq(secret1.publicImage, secret2.publicImage, secret3.publicImage)))) val req1 = PaymentRequest(addr, confirmedBalance, assetToSpend, Map.empty) val tx = await(wallet.generateTransaction(Seq(req1))).get diff --git a/src/test/scala/org/ergoplatform/nodeView/wallet/WalletScanLogicSpec.scala b/src/test/scala/org/ergoplatform/nodeView/wallet/WalletScanLogicSpec.scala index 0bcc37dacf..c57d58fed7 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/WalletScanLogicSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/WalletScanLogicSpec.scala @@ -10,7 +10,8 @@ import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanR import org.ergoplatform.wallet.Constants import org.ergoplatform.wallet.Constants.ScanId import org.scalacheck.Gen -import sigmastate.Values.{ByteArrayConstant, ErgoTree, FalseLeaf, TrueLeaf} +import sigma.ast.{ByteArrayConstant, ErgoTree} +import org.ergoplatform.settings.Constants.{FalseTree, TrueTree} import scala.util.Random @@ -35,21 +36,20 @@ class WalletScanLogicSpec extends ErgoCorePropertyTest with DBSpec with WalletTe private val monetarySettings = initSettings.chainSettings.monetary.copy(minerRewardDelay = 720) private val s = initSettings.copy(chainSettings = initSettings.chainSettings.copy(monetary = monetarySettings)) - private val trueProp = org.ergoplatform.settings.Constants.TrueLeaf - private val scanningPredicate = EqualsScanningPredicate(ErgoBox.ScriptRegId, ByteArrayConstant(trueProp.bytes)) + private val scanningPredicate = EqualsScanningPredicate(ErgoBox.ScriptRegId, ByteArrayConstant(TrueTree.bytes)) private val appReq = ScanRequest("True detector", scanningPredicate, Some(ScanWalletInteraction.Off), None) private val scanId: ScanId = ScanId @@ 50.toShort private val pubkeys = prover.hdPubKeys private val miningScripts = WalletCache.miningScripts(pubkeys, s) - private def paymentsGen: Gen[List[ErgoTree]] = Gen.listOf(Gen.oneOf(pubkeys.map(_.key.toSigmaProp: ErgoTree))) + private def paymentsGen: Gen[List[ErgoTree]] = Gen.listOf(Gen.oneOf(pubkeys.map(ek => ErgoTree.fromSigmaBoolean(ek.key)))) private def miningRewardsGen: Gen[List[ErgoTree]] = Gen.listOf(Gen.oneOf(miningScripts)) - private def nonTrackablePaymentsGen: Gen[List[ErgoTree]] = Gen.nonEmptyListOf(Gen.const(FalseLeaf.toSigmaProp)) + private def nonTrackablePaymentsGen: Gen[List[ErgoTree]] = Gen.nonEmptyListOf(Gen.const(FalseTree)) - private def appPaymentsGen: Gen[List[ErgoTree]] = Gen.listOf(Gen.const(trueProp)) + private def appPaymentsGen: Gen[List[ErgoTree]] = Gen.listOf(Gen.const(TrueTree)) private def walletVarsGen: Gen[WalletVars] = { for { @@ -195,7 +195,7 @@ class WalletScanLogicSpec extends ErgoCorePropertyTest with DBSpec with WalletTe //applying a transaction spending outputs of the previous transaction val inputs2 = spendingTx.outputs.map(_.id).map(id => Input(id, emptyProverResult)) - val outputs2 = IndexedSeq(new ErgoBoxCandidate(spendingTx.outputs.map(_.value).sum, FalseLeaf.toSigmaProp, height1)) + val outputs2 = IndexedSeq(new ErgoBoxCandidate(spendingTx.outputs.map(_.value).sum, FalseTree, height1)) val spendingTx2 = new ErgoTransaction(inputs2, IndexedSeq.empty, outputs2) val (r3, o3, f3) = @@ -242,7 +242,7 @@ class WalletScanLogicSpec extends ErgoCorePropertyTest with DBSpec with WalletTe property("external scan prioritized over payments one if walletInteraction = off, otherwise shared") { val intFlagGen = Gen.oneOf(ScanWalletInteraction.Off, ScanWalletInteraction.Shared, ScanWalletInteraction.Forced) forAll(intFlagGen) { intFlag => - val pk = pubkeys.head.key.toSigmaProp: ErgoTree + val pk = ErgoTree.fromSigmaBoolean(pubkeys.head.key) val outs = IndexedSeq(new ErgoBoxCandidate(1000, pk, creationHeight = 1)) val tx = new ErgoTransaction(fakeInputs, IndexedSeq.empty, outs) @@ -266,12 +266,11 @@ class WalletScanLogicSpec extends ErgoCorePropertyTest with DBSpec with WalletTe } property("scan with forced flag is sharing boxes with the p2k-wallet") { - val trueProp = TrueLeaf.toSigmaProp.treeWithSegregation: ErgoTree - val outs = IndexedSeq(new ErgoBoxCandidate(1000, trueProp, creationHeight = 1)) + val outs = IndexedSeq(new ErgoBoxCandidate(1000, TrueTree, creationHeight = 1)) val tx = new ErgoTransaction(fakeInputs, IndexedSeq.empty, outs) val cache = WalletCache(pubkeys, s) - val paymentPredicate = EqualsScanningPredicate(ErgoBox.ScriptRegId, ByteArrayConstant(trueProp.bytes)) + val paymentPredicate = EqualsScanningPredicate(ErgoBox.ScriptRegId, ByteArrayConstant(TrueTree.bytes)) val paymentScanReq = ScanRequest("Payment scan", paymentPredicate, Some(ScanWalletInteraction.Forced), Some(false)) val walletVars = WalletVars(None, Seq(paymentScanReq.toScan(scanId).get), Some(cache))(s) diff --git a/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/OffChainRegistrySpec.scala b/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/OffChainRegistrySpec.scala index 455cb3a813..4b8c173d0c 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/OffChainRegistrySpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/OffChainRegistrySpec.scala @@ -3,13 +3,14 @@ package org.ergoplatform.nodeView.wallet.persistence import org.ergoplatform.ErgoBox import org.ergoplatform.nodeView.wallet.IdUtils.{EncodedBoxId, encodedBoxId} import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, Scan, ScanWalletInteraction} +import org.ergoplatform.settings.Constants.TrueTree import org.ergoplatform.utils.WalletTestOps import org.ergoplatform.wallet.Constants import org.scalacheck.Gen import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks -import sigmastate.Values.ByteArrayConstant +import sigma.ast.ByteArrayConstant import scala.collection.immutable.TreeSet import scala.util.Random @@ -42,8 +43,7 @@ class OffChainRegistrySpec //check remove-offchain flag boxes.filter(_.scans.size > 1).flatMap(_.scans).find(_ != Constants.PaymentsScanId).map { scanId => - val trueProp = org.ergoplatform.settings.Constants.TrueLeaf - val p = EqualsScanningPredicate(ErgoBox.R1, ByteArrayConstant(trueProp.bytes)) + val p = EqualsScanningPredicate(ErgoBox.R1, ByteArrayConstant(TrueTree.bytes)) val scan = Scan(scanId, "_", p, ScanWalletInteraction.Off, removeOffchain = false) val filtered = boxes.filter(tb => tb.scans.contains(scanId)) diff --git a/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistryBenchmark.scala b/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistryBenchmark.scala index 95055d74ed..0311eb7ca6 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistryBenchmark.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/WalletRegistryBenchmark.scala @@ -11,8 +11,10 @@ import org.ergoplatform.wallet.interpreter.ErgoProvingInterpreter import org.ergoplatform.{ErgoAddressEncoder, ErgoBox, Input} import scorex.util.ModifierId import scorex.util.encode.Base16 -import sigmastate.Values.ErgoTree -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigma.ast.ErgoTree +import sigma.interpreter.{ContextExtension, ProverResult} +import sigma.ast.ErgoTree +import sigma.data.CSigmaDslBuilder import scala.collection.compat.immutable.ArraySeq @@ -27,9 +29,8 @@ object WalletRegistryBenchmark extends App { additionalRegisters: AdditionalRegisters = Map.empty, transactionId: ModifierId = ErgoBox.allZerosModifierId, boxIndex: Short = 0): ErgoBox = { - import sigmastate.eval._ new ErgoBox(value, ergoTree, - CostingSigmaDslBuilder.Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]), + CSigmaDslBuilder.Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]), additionalRegisters, transactionId, boxIndex, creationHeight) } @@ -51,7 +52,7 @@ object WalletRegistryBenchmark extends App { val walletVars = WalletVars.apply(storage, settings).withProver(prover) val boxes = walletVars.proverOpt.get.hdPubKeys.map { pk => - createBox(1000000000, pk.key, 1) + createBox(1000000000, ErgoTree.fromSigmaBoolean(pk.key), 1) }.map { box => TrackedBox(box, 2, Set(Constants.PaymentsScanId)) } diff --git a/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecsSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecsSpecification.scala index 9f2cf36e0d..fabf69b42b 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecsSpecification.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateJsonCodecsSpecification.scala @@ -4,7 +4,7 @@ import io.circe.parser._ import org.ergoplatform.ErgoBox import org.ergoplatform.utils.ErgoCorePropertyTest import scorex.util.encode.Base16 -import sigmastate.Values.ByteArrayConstant +import sigma.ast.ByteArrayConstant import sigmastate.eval.Extensions.ArrayByteOps import scala.language.implicitConversions diff --git a/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSpecification.scala index 672b39d64b..0b73e6730b 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSpecification.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicateSpecification.scala @@ -5,7 +5,7 @@ import org.ergoplatform.ErgoBox.R1 import org.ergoplatform.utils.ErgoCorePropertyTest import org.ergoplatform.wallet.serialization.JsonCodecsWrapper import org.ergoplatform.{ErgoTreePredef, P2PKAddress} -import sigmastate.Values.ByteArrayConstant +import sigma.ast.{ByteArrayConstant, ErgoTree} import sigmastate.eval.Extensions.ArrayByteOps import sigmastate.helpers.TestingHelpers._ @@ -97,10 +97,10 @@ class ScanningPredicateSpecification extends ErgoCorePropertyTest { property("containsAsset") { forAll(proveDlogGen) { pk => forAll(assetGen) { case (tokenId, amt) => - val box = testBox(value = 1, pk, creationHeight = 0, additionalTokens = Seq(tokenId -> amt)) + val box = testBox(value = 1, ErgoTree.fromSigmaBoolean(pk), creationHeight = 0, additionalTokens = Seq(tokenId -> amt)) ContainsAssetPredicate(tokenId).filter(box) shouldBe true - val emptyBox = testBox(value = 1, pk, creationHeight = 0) + val emptyBox = testBox(value = 1, ErgoTree.fromSigmaBoolean(pk), creationHeight = 0) ContainsAssetPredicate(tokenId).filter(emptyBox) shouldBe false ContainsAssetPredicate(mutateRandomByte(tokenId.toArray).toTokenId).filter(box) shouldBe false diff --git a/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala b/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala index 7b7175feec..5e41d64c34 100644 --- a/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala +++ b/src/test/scala/org/ergoplatform/tools/ChainGenerator.scala @@ -17,7 +17,7 @@ import org.ergoplatform.utils.{ErgoTestHelpers, HistoryTestHelpers} import org.ergoplatform.wallet.boxes.{BoxSelector, ReplaceCompactCollectBoxSelector} import org.scalatest.matchers.should.Matchers import scorex.util.ModifierId -import sigmastate.crypto.DLogProtocol.ProveDlog +import sigma.data.ProveDlog import java.io.File import scala.annotation.tailrec diff --git a/src/test/scala/org/ergoplatform/tools/ConfigGenerator.scala b/src/test/scala/org/ergoplatform/tools/ConfigGenerator.scala index f120d1be1c..4be76d0fa6 100644 --- a/src/test/scala/org/ergoplatform/tools/ConfigGenerator.scala +++ b/src/test/scala/org/ergoplatform/tools/ConfigGenerator.scala @@ -1,10 +1,10 @@ package org.ergoplatform.tools -import java.io.{File, PrintWriter} +import org.ergoplatform.sdk.SecretString +import java.io.{File, PrintWriter} import org.ergoplatform.utils.ErgoTestHelpers import org.ergoplatform.wallet.mnemonic.Mnemonic -import org.ergoplatform.wallet.interface4j.SecretString object ConfigGenerator extends App with ErgoTestHelpers { import org.ergoplatform.utils.ErgoNodeTestConstants._ diff --git a/src/test/scala/org/ergoplatform/tools/DefaultParametersPrinter.scala b/src/test/scala/org/ergoplatform/tools/DefaultParametersPrinter.scala index 05bee3973a..61931cb336 100644 --- a/src/test/scala/org/ergoplatform/tools/DefaultParametersPrinter.scala +++ b/src/test/scala/org/ergoplatform/tools/DefaultParametersPrinter.scala @@ -1,6 +1,6 @@ package org.ergoplatform.tools -import org.ergoplatform.settings.LaunchParameters.parametersTable +import org.ergoplatform.settings.MainnetLaunchParameters.parametersTable import org.ergoplatform.settings.Parameters.{maxValues, minValues, parametersDescs, stepsTable} object DefaultParametersPrinter extends App { diff --git a/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala b/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala index 9eebe3f4b7..fffd6b4c7a 100644 --- a/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala +++ b/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala @@ -2,15 +2,15 @@ package org.ergoplatform.tools import org.ergoplatform.modifiers.mempool.ErgoTransaction import org.ergoplatform.settings.Constants._ -import org.ergoplatform.settings.LaunchParameters._ +import org.ergoplatform.settings.MainnetLaunchParameters._ import org.ergoplatform.{ErgoBoxCandidate, Input} import scorex.crypto.authds.ADKey import scorex.utils.Random import sigma.Colls +import sigma.ast.ErgoTree +import sigma.interpreter.{ContextExtension, ProverResult} import sigmastate.crypto.DLogProtocol.DLogProverInput import sigmastate.eval.Extensions.ArrayByteOps -import sigmastate.eval._ -import sigmastate.interpreter.{ContextExtension, ProverResult} object FeeSimulator extends App { @@ -25,9 +25,9 @@ object FeeSimulator extends App { val creationHeight: Int = 100000 val box1 = new ErgoBoxCandidate( - scala.util.Random.nextLong(), k1, creationHeight, + scala.util.Random.nextLong(), ErgoTree.fromSigmaBoolean(k1), creationHeight, Colls.fromItems(Random.randomBytes(32).toTokenId -> scala.util.Random.nextLong())) - val box2 = new ErgoBoxCandidate(scala.util.Random.nextLong(), k2, creationHeight) + val box2 = new ErgoBoxCandidate(scala.util.Random.nextLong(), ErgoTree.fromSigmaBoolean(k2), creationHeight) val simpleTx = ErgoTransaction(IndexedSeq(input, input), IndexedSeq(box1, box2)) val stdSize = simpleTx.outputs.map(_.bytes.length).sum / simpleTx.outputs.length diff --git a/src/test/scala/org/ergoplatform/utils/ErgoCompilerHelpers.scala b/src/test/scala/org/ergoplatform/utils/ErgoCompilerHelpers.scala new file mode 100644 index 0000000000..8033f57129 --- /dev/null +++ b/src/test/scala/org/ergoplatform/utils/ErgoCompilerHelpers.scala @@ -0,0 +1,31 @@ +package org.ergoplatform.utils + +import sigma.VersionContext +import sigma.ast.{ErgoTree, SBoolean, SSigmaProp, Value} +import sigma.compiler.{CompilerResult, SigmaCompiler} +import sigma.compiler.ir.CompiletimeIRContext + +import scala.util.{Failure, Success, Try} + +trait ErgoCompilerHelpers { + + private def compileSource(source: String, scriptVersion: Byte, treeVersion: Byte) = { + VersionContext.withVersions(scriptVersion, treeVersion) { + val compiler = new SigmaCompiler(16.toByte) + val ergoTreeHeader = ErgoTree.defaultHeaderWithVersion(treeVersion) + val ergoTree = Try(compiler.compile(Map.empty, source)(new CompiletimeIRContext)).flatMap { + case CompilerResult(_, _, _, script: Value[SSigmaProp.type@unchecked]) if script.tpe == SSigmaProp => + Success(ErgoTree.fromProposition(ergoTreeHeader, script)) + case CompilerResult(_, _, _, script: Value[SBoolean.type@unchecked]) if script.tpe == SBoolean => + Success(ErgoTree.fromProposition(ergoTreeHeader, script.toSigmaProp)) + case other => + Failure(new Exception(s"Source compilation result is of type ${other.buildTree.tpe}, but `SBoolean` expected")) + }.get + ergoTree + } + } + + def compileSourceV5(source: String, treeVersion: Byte): ErgoTree = compileSource(source, 2, treeVersion) + def compileSourceV6(source: String, treeVersion: Byte): ErgoTree = compileSource(source, 3, treeVersion) + +} diff --git a/src/test/scala/org/ergoplatform/utils/ErgoStateContextHelpers.scala b/src/test/scala/org/ergoplatform/utils/ErgoStateContextHelpers.scala new file mode 100644 index 0000000000..07598e89a3 --- /dev/null +++ b/src/test/scala/org/ergoplatform/utils/ErgoStateContextHelpers.scala @@ -0,0 +1,24 @@ +package org.ergoplatform.utils + +import org.ergoplatform.modifiers.mempool.ErgoTransaction +import org.ergoplatform.nodeView.state.{ErgoStateContext, VotingData} +import org.ergoplatform.settings.{ErgoSettings, ErgoValidationSettings, MainnetLaunchParameters, Parameters} +import org.ergoplatform.utils.ErgoCoreTestConstants.genesisStateDigest +import org.ergoplatform.utils.generators.ErgoCoreGenerators.defaultHeaderGen + +trait ErgoStateContextHelpers { + + def stateContext(height: Int, blockVersion: Byte, settings: ErgoSettings): ErgoStateContext = { + val header = defaultHeaderGen.sample.get.copy(version = blockVersion, height = height) + val params = Parameters(MainnetLaunchParameters.height, + MainnetLaunchParameters.parametersTable.updated(Parameters.BlockVersion, blockVersion), + MainnetLaunchParameters.proposedUpdate) + new ErgoStateContext(Seq(header), None, genesisStateDigest, params, ErgoValidationSettings.initial, + VotingData.empty)(settings.chainSettings) + } + + def stateContextForTx(tx: ErgoTransaction, blockVersion: Byte, settings: ErgoSettings): ErgoStateContext = { + stateContext(tx.outputs.map(_.creationHeight).max, blockVersion, settings: ErgoSettings) + } + +} diff --git a/src/test/scala/org/ergoplatform/utils/Stubs.scala b/src/test/scala/org/ergoplatform/utils/Stubs.scala index b63519caf1..5385a7308d 100644 --- a/src/test/scala/org/ergoplatform/utils/Stubs.scala +++ b/src/test/scala/org/ergoplatform/utils/Stubs.scala @@ -28,18 +28,19 @@ import org.ergoplatform.settings.Constants.HashLength import org.ergoplatform.settings.{ScorexSettings, _} import org.ergoplatform.wallet.Constants.{PaymentsScanId, ScanId} import org.ergoplatform.wallet.boxes.{ChainStatus, TrackedBox} -import org.ergoplatform.wallet.interface4j.SecretString import org.ergoplatform.wallet.interpreter.ErgoProvingInterpreter import org.ergoplatform.wallet.mnemonic.Mnemonic import org.ergoplatform.wallet.utils.TestFileUtils import org.scalacheck.Gen import scorex.core.network.NetworkController.ReceivableMessages.GetConnectedPeers import org.ergoplatform.network.peer.PeerManager.ReceivableMessages.{GetAllPeers, GetBlacklistedPeers} +import org.ergoplatform.sdk.SecretString import scorex.crypto.authds.ADDigest import scorex.crypto.hash.Digest32 import scorex.db.ByteArrayWrapper import scorex.util.Random -import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog} +import sigma.data.ProveDlog +import sigmastate.crypto.DLogProtocol.DLogProverInput import scala.collection.mutable import scala.concurrent.duration._ diff --git a/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala b/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala index b4f6652c16..531c4cfc7d 100644 --- a/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala +++ b/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala @@ -11,18 +11,17 @@ import org.ergoplatform.nodeView.wallet.ErgoWallet import org.ergoplatform.nodeView.wallet.IdUtils._ import org.ergoplatform.nodeView.wallet.persistence.WalletDigest import org.ergoplatform.sdk.wallet.TokensMap -import org.ergoplatform.settings.Constants import org.ergoplatform.utils.fixtures.WalletFixture import scorex.crypto.authds.ADKey import scorex.crypto.hash.Blake2b256 import scorex.util.ModifierId import sigma.Colls -import sigmastate.Values.ErgoTree -import sigmastate.crypto.DLogProtocol.ProveDlog import sigmastate.eval.Extensions._ -import sigmastate.eval._ -import sigmastate.interpreter.ProverResult import sigma.Extensions._ +import sigma.ast.ErgoTree +import sigma.data.ProveDlog +import sigma.interpreter.ProverResult +import org.ergoplatform.settings.Constants.TrueTree trait WalletTestOps extends NodeViewBaseOps { import org.ergoplatform.utils.ErgoNodeTestConstants._ @@ -124,21 +123,21 @@ trait WalletTestOps extends NodeViewBaseOps { def creatingCandidate = new ErgoBoxCandidate(balanceToReturn, scriptToReturn, startHeight, replaceNewAssetStub(assets, inputs).toColl) - val spendingOutput = if (balanceToSpend > 0) Some(new ErgoBoxCandidate(balanceToSpend, Constants.TrueLeaf, creationHeight = startHeight)) else None + val spendingOutput = if (balanceToSpend > 0) Some(new ErgoBoxCandidate(balanceToSpend, TrueTree, creationHeight = startHeight)) else None val creatingOutput = if (balanceToReturn > 0) Some(creatingCandidate) else None ErgoTransaction(inputs.toIndexedSeq, spendingOutput.toIndexedSeq ++ creatingOutput.toIndexedSeq) } - private def replaceNewAssetStub(assets: Seq[(TokenId, Long)], inputs: Seq[Input]): Seq[(TokenId, Long)] = { + private def replaceNewAssetStub(assets: Seq[(TokenId, Long)], inputs: Seq[Input]): Array[(TokenId, Long)] = { def isNewAsset(tokenId: TokenId, value: Long): Boolean = tokenId == newAssetIdStub val (newAsset, spentAssets) = assets.partition((isNewAsset _).tupled) - newAsset.map(inputs.head.boxId.toTokenId -> _._2) ++ spentAssets + (newAsset.map(inputs.head.boxId.toTokenId -> _._2) ++ spentAssets).toArray } - def randomNewAsset: Seq[(TokenId, Long)] = Seq(newAssetIdStub -> randomLong()) + def randomNewAsset: Array[(TokenId, Long)] = Array(newAssetIdStub -> randomLong()) - def assetsWithRandom(boxes: Seq[ErgoBox]): Seq[(TokenId, Long)] = randomNewAsset ++ assetsByTokenId(boxes) + def assetsWithRandom(boxes: Seq[ErgoBox]): Array[(TokenId, Long)] = randomNewAsset ++ assetsByTokenId(boxes) val fakeInputs: IndexedSeq[Input] = IndexedSeq(Input(ADKey @@ Array.fill(32)(0: Byte), emptyProverResult)) diff --git a/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala b/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala index 089c52ba21..6c13a90365 100644 --- a/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala +++ b/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala @@ -9,14 +9,13 @@ import org.ergoplatform.modifiers.history.popow.{NipopowAlgos, PoPowHeader} import org.ergoplatform.modifiers.mempool.ErgoTransaction import org.ergoplatform.modifiers.{BlockSection, ErgoFullBlock, NonHeaderBlockSection} import org.ergoplatform.nodeView.history.ErgoHistory -import org.ergoplatform.settings.Constants +import org.ergoplatform.settings.Constants.TrueTree import org.ergoplatform.utils.BoxUtils import scorex.crypto.authds.{ADKey, SerializedAdProof} import scorex.crypto.hash.Digest32 import sigma.Colls -import sigmastate.eval._ +import sigma.interpreter.{ContextExtension, ProverResult} import sigmastate.helpers.TestingHelpers._ -import sigmastate.interpreter.{ContextExtension, ProverResult} import scala.util.Random @@ -137,8 +136,8 @@ object ChainGenerator { extension: ExtensionCandidate = defaultExtension): Stream[ErgoFullBlock] = { val proof = ProverResult(Array(0x7c.toByte), ContextExtension.empty) val inputs = IndexedSeq(Input(ADKey @@ Array.fill(32)(0: Byte), proof)) - val minimalAmount = BoxUtils.minimalErgoAmountSimulated(Constants.TrueLeaf, Colls.emptyColl, Map(), parameters) - val outputs = IndexedSeq(testBox(minimalAmount, Constants.TrueLeaf, creationHeight = startHeight)) + val minimalAmount = BoxUtils.minimalErgoAmountSimulated(TrueTree, Colls.emptyColl, Map(), parameters) + val outputs = IndexedSeq(testBox(minimalAmount, TrueTree, creationHeight = startHeight)) def txs = Seq(ErgoTransaction(inputs, outputs)) diff --git a/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeTransactionGenerators.scala b/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeTransactionGenerators.scala index 73b1362e77..1182317510 100644 --- a/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeTransactionGenerators.scala +++ b/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeTransactionGenerators.scala @@ -6,7 +6,6 @@ import org.ergoplatform.nodeView.state.{BoxHolder, ErgoStateContext} import org.ergoplatform.nodeView.wallet.requests.{ExternalSecret, TransactionSigningRequest} import org.ergoplatform.nodeView.wallet.{AugWalletTransaction, WalletTransaction} import org.ergoplatform.sdk.wallet.secrets.{DhtSecretKey, DlogSecretKey} -import org.ergoplatform.settings.Constants import org.ergoplatform.utils.{BoxUtils, RandomLike, RandomWrapper} import org.ergoplatform.sdk.wallet.Constants.MaxAssetsPerBox import org.ergoplatform.wallet.interpreter.TransactionHintsBag @@ -16,9 +15,11 @@ import org.scalacheck.Gen import scorex.db.ByteArrayWrapper import scorex.util.ScorexLogging import scorex.util.encode.Base16 -import sigmastate.Values.ErgoTree +import sigma.ast.ErgoTree import sigmastate.eval.Extensions._ import sigmastate.helpers.TestingHelpers._ +import org.ergoplatform.settings.Constants.TrueTree + import scala.collection.mutable import scala.util.Random @@ -58,7 +59,7 @@ object ErgoNodeTransactionGenerators extends ScorexLogging { def validUnsignedTransactionFromBoxes(boxesToSpend: IndexedSeq[ErgoBox], rnd: RandomLike = new RandomWrapper, issueNew: Boolean = true, - outputsProposition: ErgoTree = Constants.TrueLeaf, + outputsProposition: ErgoTree = TrueTree, dataBoxes: IndexedSeq[ErgoBox] = IndexedSeq()): UnsignedErgoTransaction = { require(boxesToSpend.nonEmpty, "At least one box is needed to generate a transaction") @@ -144,7 +145,7 @@ object ErgoNodeTransactionGenerators extends ScorexLogging { def validTransactionFromBoxes(boxesToSpend: IndexedSeq[ErgoBox], rnd: RandomLike = new RandomWrapper, issueNew: Boolean = true, - outputsProposition: ErgoTree = Constants.TrueLeaf, + outputsProposition: ErgoTree = TrueTree, stateCtxOpt: Option[ErgoStateContext] = None, dataBoxes: IndexedSeq[ErgoBox] = IndexedSeq()): ErgoTransaction = { val unsignedTx = validUnsignedTransactionFromBoxes(boxesToSpend, rnd, issueNew, outputsProposition, dataBoxes) @@ -196,7 +197,7 @@ object ErgoNodeTransactionGenerators extends ScorexLogging { def transactionSigningRequestGen(includeInputs: Boolean): Gen[TransactionSigningRequest] = for { (secret, pubKey) <- dlogSecretWithPublicImageGen (secretDh, _) <- dhtSecretWithPublicImageGen - (inputBoxes, utx) <- validUnsignedErgoTransactionGen(pubKey) + (inputBoxes, utx) <- validUnsignedErgoTransactionGen(ErgoTree.fromSigmaBoolean(pubKey)) inputBoxesEncoded = inputBoxes.map(b => Base16.encode(b.bytes)) secretSeq = Seq(ExternalSecret(DlogSecretKey(secret)), ExternalSecret(DhtSecretKey(secretDh))) } yield TransactionSigningRequest(utx, TransactionHintsBag.empty, secretSeq, diff --git a/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeWalletGenerators.scala b/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeWalletGenerators.scala index 013f6e1c50..c919365ff9 100644 --- a/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeWalletGenerators.scala +++ b/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeWalletGenerators.scala @@ -6,11 +6,11 @@ import org.ergoplatform.nodeView.wallet.IdUtils._ import org.ergoplatform.nodeView.wallet.persistence.WalletDigest import org.ergoplatform.nodeView.wallet.requests.{AssetIssueRequest, BurnTokensRequest, PaymentRequest} import org.ergoplatform.nodeView.wallet.scanning._ -import org.ergoplatform.settings.Constants +import org.ergoplatform.settings.Constants.FalseTree import org.ergoplatform.wallet.Constants.ScanId import org.ergoplatform.wallet.boxes.TrackedBox import org.scalacheck.Gen -import sigmastate.Values.ByteArrayConstant +import sigma.ast.ByteArrayConstant object ErgoNodeWalletGenerators { import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators._ @@ -86,13 +86,13 @@ object ErgoNodeWalletGenerators { value <- Gen.choose(1L, 100000L) assets <- additionalTokensGen registers <- additionalRegistersGen - } yield PaymentRequest(Pay2SAddress(Constants.FalseLeaf), value, assets, registers) + } yield PaymentRequest(Pay2SAddress(FalseTree), value, assets.toArray, registers) } def burnTokensRequestGen: Gen[BurnTokensRequest] = { for { assets <- additionalTokensGen - } yield BurnTokensRequest(assets) + } yield BurnTokensRequest(assets.toArray) } def assetIssueRequestGen: Gen[AssetIssueRequest] = { @@ -101,7 +101,7 @@ object ErgoNodeWalletGenerators { name <- Gen.alphaUpperStr description <- Gen.alphaLowerStr decimals <- Gen.choose(4, 16) - } yield AssetIssueRequest(Pay2SAddress(Constants.FalseLeaf), None, amount, name, description, decimals) + } yield AssetIssueRequest(Pay2SAddress(FalseTree), None, amount, name, description, decimals) } def registrySummaryGen: Gen[WalletDigest] = { diff --git a/src/test/scala/org/ergoplatform/utils/generators/ValidBlocksGenerators.scala b/src/test/scala/org/ergoplatform/utils/generators/ValidBlocksGenerators.scala index e09ef9c9cc..33b5f7c1af 100644 --- a/src/test/scala/org/ergoplatform/utils/generators/ValidBlocksGenerators.scala +++ b/src/test/scala/org/ergoplatform/utils/generators/ValidBlocksGenerators.scala @@ -49,11 +49,13 @@ object ValidBlocksGenerators validTransactionsFromBoxes(sizeLimit, stateBoxesIn, Seq(), rnd) } - /** @param sizeLimit maximum transactions size in bytes */ + /** @param sizeLimit maximum transactions size in bytes + * @return generated transactions and unspent outputs + * */ def validTransactionsFromBoxes(sizeLimit: Int, - stateBoxesIn: Seq[ErgoBox], - dataBoxesIn: Seq[ErgoBox], - rnd: RandomLike): (Seq[ErgoTransaction], Seq[ErgoBox]) = { + stateBoxesIn: Seq[ErgoBox], + dataBoxesIn: Seq[ErgoBox], + rnd: RandomLike): (Seq[ErgoTransaction], Seq[ErgoBox]) = { var createdEmissionBox: Seq[ErgoBox] = Seq() @tailrec @@ -156,7 +158,7 @@ object ValidBlocksGenerators val num = 1 + rnd.nextInt(3) val allBoxes = wus.takeBoxes(num + rnd.nextInt(100)) - val anyoneCanSpendBoxes = allBoxes.filter(_.ergoTree == Constants.TrueLeaf) + val anyoneCanSpendBoxes = allBoxes.filter(_.ergoTree == Constants.TrueTree) val boxes = if (anyoneCanSpendBoxes.nonEmpty) anyoneCanSpendBoxes else allBoxes validTransactionsFromBoxes(num, boxes, rnd)._1