diff --git a/build.sbt b/build.sbt index 123c2cfc12..38fcb0fd47 100644 --- a/build.sbt +++ b/build.sbt @@ -37,7 +37,7 @@ 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" 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..e27d66153b 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 @@ -21,17 +21,16 @@ 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 sigma.serialization.{OpCodes, SigSerializer} import org.ergoplatform.sdk.JsonCodecs -import sigmastate.eval.Extensions.ArrayOps -import sigmastate.utils.Helpers._ +import sigma.Extensions.ArrayOps +import sigma.crypto._ +import sigma.data._ import java.math.BigInteger import scala.annotation.nowarn @@ -129,7 +128,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..70d90454ec 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 @@ -27,6 +27,10 @@ import scala.util.Try * Based on k-sum problem, so general idea is to find k numbers in a table of size N, such that * sum of numbers (or a hash of the sum) is less than target value. * + * There are two version of Autolykos PoW scheme, Autolykos v1 and v2. The main difference is that + * Autolykos v1 is (weakly) non-outsourceable, while v2 is outsourceable and also eliminates some vectors of + * optimizations a miner could follow. + * * See https://docs.ergoplatform.com/ErgoPow.pdf for details * * CPU Mining process is implemented in inefficient way and should not be used in real environment. @@ -58,7 +62,8 @@ class AutolykosPowScheme(val k: Int, val n: Int) extends ScorexLogging { val IncreasePeriodForN: Height = 50 * 1024 /** - * On this height, the table (`N` value) will stop to grow + * On this height, the table (`N` value) will stop to grow. + * Max N on and after this height would be 2,143,944,600 which is still less than 2^^31. */ val NIncreasementHeightMax: Height = 4198400 @@ -97,25 +102,37 @@ class AutolykosPowScheme(val k: Int, val n: Int) extends ScorexLogging { * Checks that `header` contains correct solution of the Autolykos PoW puzzle. */ def validate(header: Header): Try[Unit] = Try { - val b = getB(header.nBits) if (header.version == 1) { // for version 1, we check equality of left and right sides of the equation - require(checkPoWForVersion1(header, b), "Incorrect points") + require(checkPoWForVersion1(header), "Incorrect points") } else { - // for version 2, we're calculating hit and compare it with target - val hit = hitForVersion2(header) - require(hit < b, "h(f) < b condition not met") + require(checkPoWForVersion2(header), "h(f) < b condition not met") } } + /** + * Check PoW for Autolykos v2 header + * + * @param header - header to check PoW for + * @return whether PoW is valid or not + */ + def checkPoWForVersion2(header: Header): Boolean = { + val b = getB(header.nBits) + // for version 2, we're calculating hit and compare it with target + val hit = hitForVersion2(header) + hit < b + } + /** * Check PoW for Autolykos v1 header * * @param header - header to check PoW for - * @param b - PoW target * @return whether PoW is valid or not */ - def checkPoWForVersion1(header: Header, b: BigInt): Boolean = { + def checkPoWForVersion1(header: Header): Boolean = { + + val b = getB(header.nBits) // PoW target + val version = 1: Byte val msg = msgByHeader(header) @@ -152,7 +169,6 @@ class AutolykosPowScheme(val k: Int, val n: Int) extends ScorexLogging { * @return PoW hit */ def hitForVersion2(header: Header): BigInt = { - val version = 2: Byte val msg = msgByHeader(header) val nonce = header.powSolution.n @@ -161,6 +177,25 @@ class AutolykosPowScheme(val k: Int, val n: Int) extends ScorexLogging { val N = calcN(header) + hitForVersion2ForMessage(msg, nonce, h, N) + } + + /** + * Get a PoW hit for custom message (not necessarily a block header) with Autolykos v2. + * + * PoW then can can be checked as hit < b, where b is PoW target value + * + * @param msg - message to check PoW on + * @param nonce - PoW nonce + * @param h - for Ergo blockchain, this is height encoded as bytes. For other use-cases, could be + * unique value on each call or constant (in the latter case more pre-computations + * could be possible + * @param N - table size + * @return pow hit + */ + def hitForVersion2ForMessage(msg: Array[Byte], nonce: Array[Byte], h: Array[Byte], N: Int): BigInt = { + val version = 2: Byte // autolykos protocol version, used in genElement only + val prei8 = BigIntegers.fromUnsignedByteArray(hash(Bytes.concat(msg, nonce)).takeRight(8)) val i = BigIntegers.asUnsignedByteArray(4, prei8.mod(BigInt(N).underlying())) val f = Blake2b256(Bytes.concat(i, h, M)).drop(1) // .drop(1) is the same as takeRight(31) @@ -244,7 +279,9 @@ class AutolykosPowScheme(val k: Int, val n: Int) extends ScorexLogging { //Proving-related code which is not critical for consensus below /** - * Find a nonce from `minNonce` to `maxNonce`, such that header with the specified fields will contain + * Autolykos solver suitable for CPU-mining in testnet and devnets. + * + * Finds a nonce from `minNonce` to `maxNonce`, such that header with the specified fields will contain * correct solution of the Autolykos PoW puzzle. */ def prove(parentOpt: Option[Header], @@ -262,7 +299,7 @@ class AutolykosPowScheme(val k: Int, val n: Int) extends ScorexLogging { val (parentId, height) = AutolykosPowScheme.derivedHeaderFields(parentOpt) val h = HeaderWithoutPow(version, parentId, adProofsRoot, stateRoot, transactionsRoot, timestamp, - nBits, height, extensionHash, votes) + nBits, height, extensionHash, votes, Array.emptyByteArray) val msg = msgByHeader(h) val b = getB(nBits) val x = randomSecret() 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..20f3237a10 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosSolution.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/AutolykosSolution.scala @@ -10,8 +10,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/CandidateUtils.scala b/ergo-core/src/main/scala/org/ergoplatform/mining/CandidateUtils.scala index 0ad1d87624..aee8cc3fc7 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/CandidateUtils.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/CandidateUtils.scala @@ -29,7 +29,8 @@ object CandidateUtils { candidate.nBits, height, extensionRoot, - candidate.votes + candidate.votes, + Array.emptyByteArray ) } } 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..c3375a45c6 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} @@ -33,7 +33,7 @@ class DefaultFakePowScheme(k: Int, n: Int) extends AutolykosPowScheme(k, n) { val d: BigInt = q / (height + 10) val s = AutolykosSolution(pk, w, n, d) Some(Header(version, parentId, adProofsRoot, stateRoot, transactionsRoot, timestamp, - nBits, height, extensionHash, s, votes)) + nBits, height, extensionHash, s, votes, Array.emptyByteArray)) } override def realDifficulty(header: Header): PrivateKey = header.requiredDifficulty diff --git a/ergo-core/src/main/scala/org/ergoplatform/mining/NumericHash.scala b/ergo-core/src/main/scala/org/ergoplatform/mining/ModQHash.scala similarity index 91% rename from ergo-core/src/main/scala/org/ergoplatform/mining/NumericHash.scala rename to ergo-core/src/main/scala/org/ergoplatform/mining/ModQHash.scala index 0b4beb4bd0..1d4f360332 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/NumericHash.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/ModQHash.scala @@ -12,8 +12,10 @@ import scala.annotation.tailrec * in range from 0 to a maximum number divisible by q without remainder. * If yes, it returns the result mod q, otherwise make one more iteration using hash as an input. * This is done to ensure uniform distribution of the resulting numbers. + * + * Used in Autolykos v1 only! */ -class NumericHash(val q: BigInt) extends ScorexLogging with ScorexEncoding { +class ModQHash(val q: BigInt) extends ScorexLogging with ScorexEncoding { assert(q.bigInteger.bitLength() <= 256, "We use 256 bit hash here") // biggest number <= 2^256 that is divisible by q without remainder val validRange: BigInt = (BigInt(2).pow(256) / q) * q 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/difficulty/DifficultySerializer.scala b/ergo-core/src/main/scala/org/ergoplatform/mining/difficulty/DifficultySerializer.scala index a4aefe426d..3c42fc6303 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/mining/difficulty/DifficultySerializer.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/mining/difficulty/DifficultySerializer.scala @@ -40,7 +40,7 @@ object DifficultySerializer extends ErgoSerializer[NBits] { if (size >= 1) bytes(4) = ((compact >> 16) & 0xFF).toByte if (size >= 2) bytes(5) = ((compact >> 8) & 0xFF).toByte if (size >= 3) bytes(6) = (compact & 0xFF).toByte - decodeMPI(bytes, hasLength = true) + decodeMPI(bytes) } /** @@ -78,19 +78,13 @@ object DifficultySerializer extends ErgoSerializer[NBits] { * MPI encoded numbers are produced by the OpenSSL BN_bn2mpi function. They consist of * a 4 byte big endian length field, followed by the stated number of bytes representing * the number in big endian format (with a sign bit). - * - * @param hasLength can be set to false if the given array is missing the 4 byte length field */ - @SuppressWarnings(Array("NullAssignment")) - private def decodeMPI(mpi: Array[Byte], hasLength: Boolean): BigInteger = { - var buf: Array[Byte] = null // scalastyle:ignore - if (hasLength) { - val length: Int = readUint32BE(mpi).toInt - buf = new Array[Byte](length) - System.arraycopy(mpi, 4, buf, 0, length) - } else { - buf = mpi - } + private def decodeMPI(mpi: Array[Byte]): BigInteger = { + + val length: Int = readUint32BE(mpi).toInt + val buf = new Array[Byte](length) + System.arraycopy(mpi, 4, buf, 0, length) + if (buf.length == 0) { BigInteger.ZERO } else { 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..cf4ce0637f 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 { @@ -19,14 +18,14 @@ package object mining { // and also to obtain target in both Autolykos v1 and v2 val q: BigInt = group.order - private val hashFn: NumericHash = new NumericHash(q) + private val modQHashFn: ModQHash = new ModQHash(q) /** * Hash function which output is in Zq. Used in Autolykos v.1 * @param in - input (bit-string) * @return - output(in Zq) */ - def hashModQ(in: Array[Byte]): BigInt = hashFn.hash(in) + def hashModQ(in: Array[Byte]): BigInt = modQHashFn.hash(in) /** * Convert byte array to unsigned integer 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..946f42b3b0 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.Extensions.ArrayOps +import sigma.crypto.EcPointType +import sigma.data.CGroupElement /** * Only header fields that can be predicted by a miner 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..6aad02eade 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 @@ -1,6 +1,6 @@ package org.ergoplatform.modifiers.history.header -import cats.syntax.either._ +import cats.syntax.either._ // needed for Scala 2.11 import sigmastate.utils.Helpers._ import io.circe.syntax._ import io.circe.{Decoder, Encoder, HCursor} @@ -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.Extensions.ArrayOps +import sigma.crypto.EcPointType +import sigma.data.{CAvlTree, CBigInt, CGroupElement} +import sigmastate.eval.CHeader import scala.annotation.nowarn import scala.concurrent.duration.FiniteDuration @@ -40,6 +41,7 @@ import scala.concurrent.duration.FiniteDuration * @param extensionRoot - Merkle tree digest of the extension section of the block * @param powSolution - solution for the proof-of-work puzzle * @param votes - votes for changing system parameters + * @param unparsedBytes - bytes of fields added in future versions of the protocol and not parseable * @param sizeOpt - optionally, size of the header (to avoid serialization on calling .length) */ case class Header(override val version: Header.Version, @@ -53,8 +55,9 @@ case class Header(override val version: Header.Version, override val extensionRoot: Digest32, powSolution: AutolykosSolution, override val votes: Array[Byte], //3 bytes + override val unparsedBytes: Array[Byte], override val sizeOpt: Option[Int] = None) extends HeaderWithoutPow(version, parentId, ADProofsRoot, stateRoot, transactionsRoot, timestamp, - nBits, height, extensionRoot, votes) with PreHeader with BlockSection { + nBits, height, extensionRoot, votes, unparsedBytes) with PreHeader with BlockSection { override def serializedId: Array[Header.Version] = Algos.hash(bytes) @@ -138,6 +141,11 @@ 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 def toSigma(header: Header): sigma.Header = CHeader( @@ -180,7 +188,8 @@ object Header extends ApiCodecs { "size" -> h.size.asJson, "extensionId" -> Algos.encode(h.extensionId).asJson, "transactionsId" -> Algos.encode(h.transactionsId).asJson, - "adProofsId" -> Algos.encode(h.ADProofsId).asJson + "adProofsId" -> Algos.encode(h.ADProofsId).asJson, + "unparsedBytes" -> Algos.encode(h.unparsedBytes).asJson ).asJson } @@ -197,8 +206,10 @@ object Header extends ApiCodecs { version <- c.downField("version").as[Byte] votes <- c.downField("votes").as[String] solutions <- c.downField("powSolutions").as[AutolykosSolution] + unparsedBytes <- c.downField("unparsedBytes").as[Option[Array[Byte]]] } yield Header(version, parentId, adProofsRoot, stateRoot, - transactionsRoot, timestamp, nBits, height, extensionHash, solutions, Algos.decode(votes).get) + transactionsRoot, timestamp, nBits, height, extensionHash, solutions, Algos.decode(votes).get, + unparsedBytes.getOrElse(Array.emptyByteArray)) } } diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/HeaderSerializer.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/HeaderSerializer.scala index b6123e1141..c7688bac61 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/HeaderSerializer.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/HeaderSerializer.scala @@ -30,9 +30,11 @@ object HeaderSerializer extends ErgoSerializer[Header] { w.putBytes(h.votes) // For block version >= 2, this new byte encodes length of possible new fields. - // Set to 0 for now, so no new fields. + // starting from 5.0.23, new fields also included. + // They should be added in >= 5 bock version, see serializer if (h.version > Header.InitialVersion) { - w.putUByte(0) + w.putUByte(h.unparsedBytes.length) + w.putBytes(h.unparsedBytes) } } @@ -56,15 +58,20 @@ object HeaderSerializer extends ErgoSerializer[Header] { // For block version >= 2, a new byte encodes length of possible new fields. // If this byte > 0, we read new fields but do nothing, as semantics of the fields is not known. - if (version > Header.InitialVersion) { + val unparsedBytes = if (version > Header.InitialVersion) { val newFieldsSize = r.getUByte() - if (newFieldsSize > 0) { + if (newFieldsSize > 0 && version > Header.Interpreter60Version) { + // new bytes could be added only for block version >= 5 r.getBytes(newFieldsSize) + } else { + Array.emptyByteArray } + } else { + Array.emptyByteArray } HeaderWithoutPow(version, parentId, ADProofsRoot, stateRoot, transactionsRoot, timestamp, - nBits, height, extensionHash, votes) + nBits, height, extensionHash, votes, unparsedBytes) } override def parse(r: Reader): Header = { diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/HeaderWithoutPow.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/HeaderWithoutPow.scala index ffe10380a2..067468f2c6 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/HeaderWithoutPow.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/HeaderWithoutPow.scala @@ -17,19 +17,20 @@ class HeaderWithoutPow(val version: Header.Version, // 1 byte val nBits: Long, //actually it is unsigned int val height: Int, val extensionRoot: Digest32, - val votes: Array[Byte]) { //3 bytes + val votes: Array[Byte], //3 bytes + val unparsedBytes: Array[Byte]) { def toHeader(powSolution: AutolykosSolution, headerSize: Option[Int] = None): Header = Header(version, parentId, ADProofsRoot, stateRoot, transactionsRoot, timestamp, - nBits, height, extensionRoot, powSolution, votes, headerSize) + nBits, height, extensionRoot, powSolution, votes, unparsedBytes, headerSize) } object HeaderWithoutPow { def apply(version: Header.Version, parentId: ModifierId, ADProofsRoot: Digest32, stateRoot: ADDigest, transactionsRoot: Digest32, timestamp: Header.Timestamp, nBits: Long, height: Int, - extensionRoot: Digest32, votes: Array[Byte]): HeaderWithoutPow = { + extensionRoot: Digest32, votes: Array[Byte], unparsedBytes: Array[Byte]): HeaderWithoutPow = { new HeaderWithoutPow(version, parentId, ADProofsRoot, stateRoot, transactionsRoot, timestamp, - nBits, height, extensionRoot, votes) + nBits, height, extensionRoot, votes, unparsedBytes) } } diff --git a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/PreGenesisHeader.scala b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/PreGenesisHeader.scala index 7cebffbc5e..4924c63783 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/PreGenesisHeader.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/modifiers/history/header/PreGenesisHeader.scala @@ -18,6 +18,7 @@ object PreGenesisHeader extends Header( extensionRoot = null, powSolution = null, votes = null, + unparsedBytes = Array.emptyByteArray, sizeOpt = None) { override def serializedId: Array[Byte] = idToBytes(Header.GenesisParentId) 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..b2b9f1f082 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 sigma.data.SigmaConstants.{MaxBoxSize, MaxPropositionBytes} import org.ergoplatform.http.api.ApiCodecs import org.ergoplatform.mining.emission.EmissionRules import org.ergoplatform.modifiers.history.header.Header @@ -27,8 +27,7 @@ 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.serialization.{ConstantStore, SigmaByteReader, SigmaByteWriter} import java.util import scala.annotation.nowarn 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..23311a896f 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 @@ -18,10 +18,10 @@ import org.ergoplatform.validation.{InvalidModifier, ModifierValidator, Validati 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.Extensions.ArrayOps +import sigma.crypto.EcPointType +import sigma.{Coll, Colls} +import sigma.eval.SigmaDsl import scala.collection.compat.immutable.ArraySeq import scala.util.{Failure, Success, Try} @@ -82,7 +82,7 @@ class ErgoStateContext(val lastHeaders: Seq[Header], PreHeader.toSigma(lastHeaders.headOption.getOrElse(PreHeader.fake)) override def sigmaLastHeaders: Coll[sigma.Header] = - SigmaDsl.Colls.fromArray(lastHeaders.drop(1).map(h => Header.toSigma(h)).toArray) + Colls.fromArray(lastHeaders.drop(1).map(h => Header.toSigma(h)).toArray) // todo remove from ErgoLikeContext and from ErgoStateContext // State root hash before the last block 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..fabdb3e11a 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,7 @@ 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 object Constants { /** @@ -42,8 +41,8 @@ object Constants { val SoftForkEpochs = 32 //about 45.5 days - def TrueLeaf: ErgoTree = Values.TrueLeaf.toSigmaProp - def FalseLeaf: ErgoTree = Values.FalseLeaf.toSigmaProp + def TrueLeaf: ErgoTree = ErgoTree.fromProposition(sigma.ast.TrueLeaf.toSigmaProp) + def FalseLeaf: ErgoTree = ErgoTree.fromProposition(sigma.ast.FalseLeaf.toSigmaProp) val StringEncoding = "UTF-8" 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..846cece555 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettings.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/settings/ErgoValidationSettings.scala @@ -4,17 +4,15 @@ 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 /** - * Ergo configuration of validation. - * - * Specifies the strategy to be used (fail-fast) and validation rules with their statuses. + * Container for validation rules along with their statuses. * Contains delta from the initial validation rules `updateFromInitial` as well as calculated current rules, * that might also be computed by applying `updateFromInitial` to `ErgoValidationSettings.initial` * @@ -29,6 +27,9 @@ case class ErgoValidationSettings(rules: Map[Short, RuleStatus], override type M = ErgoValidationSettings + /** + * In regards with consensus rules, it is worth to fail fast to avoid spam issues. + */ override val isFailFast: Boolean = true override def getError(id: Short, invalidMod: InvalidModifier): ValidationResult.Invalid = { 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..74d7062fe2 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,7 +22,7 @@ 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) 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..b33234f2d2 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,6 @@ package org.ergoplatform.settings -import org.ergoplatform.SigmaConstants.{MaxBoxSize, MaxPropositionBytes} +import sigma.data.SigmaConstants.{MaxBoxSize, MaxPropositionBytes} import org.ergoplatform.modifiers.{ErgoFullBlock, NetworkObjectTypeId} import org.ergoplatform.modifiers.history.extension.Extension import org.ergoplatform.modifiers.history.header.Header 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..5af2fd8bb4 100644 --- a/ergo-core/src/main/scala/org/ergoplatform/utils/BoxUtils.scala +++ b/ergo-core/src/main/scala/org/ergoplatform/utils/BoxUtils.scala @@ -5,8 +5,7 @@ import org.ergoplatform.settings.{Algos, Parameters} import org.ergoplatform.{ErgoBox, ErgoBoxCandidate} import scorex.util.ModifierId import sigma.{Coll, Colls} -import sigmastate.Values.ErgoTree -import sigmastate.eval._ +import sigma.ast.ErgoTree object BoxUtils { 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..c07210fd9d 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 @@ -9,12 +9,12 @@ 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 sigma.eval._ import cats.syntax.either._ +import sigma.ast.{ByteArrayConstant, ByteConstant, ErgoTree, IntConstant, LongArrayConstant, SigmaPropConstant} +import sigma.crypto.CryptoConstants +import sigma.data.ProveDlog +import sigma.interpreter.{ContextExtension, ProverResult} import sigmastate.utils.Helpers._ @@ -48,7 +48,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 +62,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 +70,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" @@ -105,7 +105,6 @@ class ErgoTransactionSpec extends ErgoCorePropertyTest { txTry.toEither.left.get.isInstanceOf[NegativeArraySizeException] shouldBe true } - property("context extension with neg and pos ids") { val negId: Byte = -20 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..3e4efcfcda 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 @@ -43,7 +43,7 @@ class HeaderSerializationSpecification extends ErgoCorePropertyTest { val votes = Array[Byte](4, 3, 0) val h = Header(version, parentId, adProofsRoot, stateRoot, transactionsRoot, timestamp, nBits, - height, extensionRoot, powSolution, votes) + height, extensionRoot, powSolution, votes, Array.emptyByteArray) h.id shouldBe "8cf6dca6b9505243e36192fa107735024c0000cf4594b1daa2dc4e13ee86f26f" @@ -141,7 +141,7 @@ class HeaderSerializationSpecification extends ErgoCorePropertyTest { val votes = Array[Byte](0, 0, 0) val h = Header(version, parentId, adProofsRoot, stateRoot, transactionsRoot, timestamp, nBits, - height, extensionRoot, powSolution, votes) + height, extensionRoot, powSolution, votes, Array.emptyByteArray) h.id shouldBe "f46c89e44f13a92d8409341490f97f05c85785fa8d2d2164332cc066eda95c39" 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..fd8de4dd5b 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/settings/VotingSpecification.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/settings/VotingSpecification.scala @@ -4,9 +4,11 @@ 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.validation.{ValidationRules => VR} import org.ergoplatform.utils.ErgoCorePropertyTest -import org.ergoplatform.validation.{DisabledRule, ReplacedRule, ValidationRules => VR} +import org.ergoplatform.validation.{ValidationRules => VR} import scorex.crypto.authds.ADDigest +import sigma.validation.{DisabledRule, ReplacedRule} import sigmastate.utils.Helpers._ import scala.util.Try @@ -38,7 +40,7 @@ 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,7 +55,7 @@ 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 } } 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..5f1a2f892b 100644 --- a/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoCoreTestConstants.scala +++ b/ergo-core/src/test/scala/org/ergoplatform/utils/ErgoCoreTestConstants.scala @@ -17,10 +17,11 @@ 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 sigma.ast.ErgoTree +import sigma.crypto.EcPointType +import sigma.data.ProveDlog +import sigma.interpreter.{ContextExtension, ProverResult} +import sigmastate.crypto.DLogProtocol.DLogProverInput import net.ceedubs.ficus.Ficus._ import org.ergoplatform.nodeView.state.{ErgoStateContext, UpcomingStateContext} 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..ea4ced0bef 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,17 @@ 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 sigmastate.crypto.DLogProtocol.DLogProverInput +import sigmastate.crypto.DiffieHellmanTupleProverInput +import sigma.interpreter.ProverResult import scala.util.Random @@ -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(dl => ErgoTree.fromSigmaBoolean(dl)) lazy val ergoPropositionGen: Gen[ErgoTree] = Gen.oneOf(trueLeafGen, falseLeafGen, proveDlogTreeGen) @@ -172,6 +173,7 @@ object ErgoCoreGenerators { extensionHash, powSolution, Array.fill(3)(0: Byte), + Array.emptyByteArray, None ) @@ -200,7 +202,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..e17ebe3d03 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,10 +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 sigma.eval.Extensions._ import sigmastate.eval.Extensions._ -import sigmastate.eval._ import scala.collection.JavaConverters._ import scala.collection.mutable @@ -48,7 +48,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.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..4dd66c3d9d 100644 --- a/ergo-wallet/src/main/scala/org/ergoplatform/contracts/ReemissionContracts.scala +++ b/ergo-wallet/src/main/scala/org/ergoplatform/contracts/ReemissionContracts.scala @@ -4,11 +4,10 @@ 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 sigmastate._ import sigma.Coll +import sigma.ast._ +import sigma.ast.syntax._ /** * Container for re-emission related contracts. Contains re-emission contract and pay-to-reemission contract. @@ -39,7 +38,9 @@ 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) + // it used to be ErgoTree.headerWithVersion(version) before Sigma v5.0.14, + // which used the default header, now this is made explicit via naming + val headerFlags = ErgoTree.defaultHeaderWithVersion(version) ErgoTree.fromProposition(headerFlags, 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..7bd3bb4c59 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,8 +3,8 @@ 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 +import sigma.serialization.{SigmaByteReader, SigmaByteWriter} object ErgoBoxSerializer extends ErgoWalletSerializer[ErgoBox] { 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..9b1b7c00cd 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.{CryptoConstants, EcPointType} +import sigma.serialization.GroupElementSerializer import scala.annotation.tailrec 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..072fa40f38 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,9 +5,9 @@ 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 sigma.ast.ErgoTree import sigmastate.interpreter.Interpreter.{ScriptEnv, VerificationResult} -import sigmastate.{AvlTreeData, AvlTreeFlags} +import sigma.data.{AvlTreeData, AvlTreeFlags} import sigma.Coll 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..3cf842b6ec 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.interpreter.ContextExtension +import sigma.validation.SigmaValidationSettings +import sigma.data.{AvlTreeData, SigmaBoolean, SigmaLeaf} 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) 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..6dbe2542dc 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 @@ -3,7 +3,7 @@ package org.ergoplatform.wallet.interpreter import org.ergoplatform.{ErgoLikeTransaction, Input, UnsignedErgoLikeTransaction} import scorex.util.encode.Base16 import sigmastate.crypto.DLogProtocol.DLogProverInput -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigma.interpreter.{ContextExtension, ProverResult} /** * A naive Ergo prover implementation not performing transaction cost verification. 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..5916eb2a02 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 @@ -6,7 +6,7 @@ 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..1ed6f117ca 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,6 @@ 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/serialization/ErgoWalletSerializer.scala b/ergo-wallet/src/main/scala/org/ergoplatform/wallet/serialization/ErgoWalletSerializer.scala index bc9bf9071b..4f69d11421 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._ import scala.util.Try 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..e09185060b 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,8 +7,7 @@ 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 sigma.eval.Extensions.EvalIterableOps import sigmastate.utils.Extensions._ import sigma.Coll import sigma.Extensions._ 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..ec15eb83b7 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,8 @@ 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 = sigma.ast.TrueLeaf.toSigmaProp + private val TrueTree = ErgoTree.fromProposition(TrueLeaf) private val StartHeight: Int = 0 private def genTokens(count: Int) = { @@ -37,7 +38,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, TrueTree, creationHeight = StartHeight) val uBox = TrackedBox(parentTx, 0, None, box, Set(PaymentsScanId)) //target amount is too high @@ -55,9 +56,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, TrueTree, creationHeight = StartHeight) + val box2 = testBox(10, TrueTree, creationHeight = StartHeight) + val box3 = testBox(100, TrueTree, creationHeight = StartHeight) val uBox1 = TrackedBox(parentTx, 0, Option(100), box1, Set(PaymentsScanId)) val uBox2 = TrackedBox(parentTx, 1, None, box2, Set(PaymentsScanId)) @@ -101,9 +102,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, TrueTree, StartHeight, Seq(assetId1.toTokenId -> 1)) + val box2 = testBox(10 * MinBoxValue, TrueTree, StartHeight, Seq(assetId2.toTokenId -> 10)) + val box3 = testBox(100 * MinBoxValue, TrueTree, 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 +151,17 @@ class DefaultBoxSelectorSpec extends AnyPropSpec with Matchers with EitherValues val assetId8 = bytesToId(Blake2b256("8")) val box1 = testBox( - 1 * MinBoxValue, TrueLeaf, StartHeight, + 1 * MinBoxValue, TrueTree, StartHeight, Seq(assetId1.toTokenId -> 1, assetId2.toTokenId -> 1, assetId3.toTokenId -> 1, assetId4.toTokenId -> 1)) val box2 = testBox( - 10 * MinBoxValue, TrueLeaf, StartHeight, + 10 * MinBoxValue, TrueTree, StartHeight, Seq(assetId5.toTokenId -> 10, assetId6.toTokenId -> 10, assetId7.toTokenId -> 10, assetId8.toTokenId -> 10)) val box3 = testBox( - 100 * MinBoxValue, TrueLeaf, StartHeight, + 100 * MinBoxValue, TrueTree, StartHeight, Seq(assetId3.toTokenId -> 100, assetId4.toTokenId -> 100, assetId5.toTokenId -> 100, assetId6.toTokenId -> 100)) @@ -201,13 +202,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, TrueTree, 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, TrueTree, 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 +216,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, TrueTree, 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 +233,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, TrueTree, StartHeight, Seq(tokenData)) val uBox1 = TrackedBox(parentTx, 0, Some(100), box1, Set(PaymentsScanId)) - val box2 = testBox(ergValue, TrueLeaf, StartHeight) + val box2 = testBox(ergValue, TrueTree, StartHeight) val uBox2 = TrackedBox(parentTx, 0, Some(100), box2, Set(PaymentsScanId)) val s1 = selector.select(Iterator(uBox1, uBox2), noFilter, ergValue, Map.empty) @@ -242,7 +243,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, TrueTree, StartHeight) val uBox3 = TrackedBox(parentTx, 0, Some(100), box3, Set(PaymentsScanId)) val s2 = selector.select(Iterator(uBox2, uBox3), noFilter, ergValue, Map.empty) @@ -266,7 +267,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, TrueTree, 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..00e3101d29 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 = sigma.ast.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..f800675a3d 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.fromSigmaBoolean(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..127b20ff6e 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 @@ -3,9 +3,10 @@ package org.ergoplatform.wallet.interpreter import org.ergoplatform.sdk.BlockchainParameters import org.ergoplatform.sdk.wallet.protocol.context.BlockchainStateContext 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 sigmastate.eval.CPreHeader import sigma.{Coll, Colls, Header, PreHeader} trait InterpreterSpecCommon { 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..213fb00086 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 @@ -9,13 +9,13 @@ 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.eval.Extensions.EvalIterableOps import scala.util.{Success, Try} @@ -35,20 +35,21 @@ 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 TrueTree = ErgoTree.fromProposition(TrueProp) val tid1 = stringToId("t1") val tid2 = stringToId("t2") - def box(value: Long) = testBox(value, TrueProp, currentHeight) + def box(value: Long) = testBox(value, TrueTree, currentHeight) def box(value: Long, tokens: Seq[(TokenId, Long)]) = - testBox(value, TrueProp, currentHeight, tokens) + testBox(value, TrueTree, currentHeight, tokens) - def boxCandidate(value: Long) = new ErgoBoxCandidate(value, TrueProp, currentHeight) + def boxCandidate(value: Long) = new ErgoBoxCandidate(value, TrueTree, currentHeight) def boxCandidate(value: Long, tokens: Seq[(TokenId, Long)]) = - new ErgoBoxCandidate(value, TrueProp, currentHeight, tokens.toColl) + new ErgoBoxCandidate(value, TrueTree, currentHeight, tokens.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..4731f8a3c4 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,13 @@ 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.ast._ +import sigma.ast.syntax._ +import sigma.crypto.CryptoFacade.SecretKeyLength +import sigma.data.ProveDlog import sigmastate.eval.Extensions._ -import sigmastate.eval._ import sigmastate.helpers.TestingHelpers._ -import sigmastate.{SByte, SType} +import sigma.eval.Extensions._ object WalletGenerators { @@ -106,7 +105,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 +172,10 @@ 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].toSigmaPropValue)) for { ins <- Gen.listOfN(2, ergoBoxGen(dlog)) diff --git a/src/it/scala/org/ergoplatform/it/WalletSpec.scala b/src/it/scala/org/ergoplatform/it/WalletSpec.scala index 344b165e49..4633f219a5 100644 --- a/src/it/scala/org/ergoplatform/it/WalletSpec.scala +++ b/src/it/scala/org/ergoplatform/it/WalletSpec.scala @@ -10,11 +10,7 @@ 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.requests.{PaymentRequest, RequestsHolder, RequestsHolderEncoder} import org.ergoplatform.nodeView.wallet.{AugWalletTransaction, ErgoWalletServiceImpl} import org.ergoplatform.settings.{Args, ErgoSettings, ErgoSettingsReader} import org.ergoplatform.utils.{ErgoTestHelpers, WalletTestOps} @@ -25,7 +21,8 @@ import org.scalatest.wordspec.AsyncWordSpec import scorex.util.ModifierId import scorex.util.encode.Base16 import sigma.Colls -import sigmastate.Values.{ErgoTree, TrueLeaf} +import sigma.ast.ErgoTree +import sigma.data.TrivialProp.TrueProp import scala.concurrent.ExecutionContext @@ -104,13 +101,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 = ErgoTree.fromProposition(TrueProp) val transactionId = ModifierId @@ Base16.encode(Array.fill(32)(5: Byte)) val input = new ErgoBox( 60000000, diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml index f3f3545e72..2f6f15a0a5 100644 --- a/src/main/resources/api/openapi.yaml +++ b/src/main/resources/api/openapi.yaml @@ -1302,6 +1302,15 @@ components: type: string description: hex-encoded serialized box bytes + PrivateKeyRequest: + description: Request for getting a secret corresponding to wallet address + type: object + required: + - address + properties: + address: + $ref: '#/components/schemas/ErgoAddress' + PaymentRequest: description: Request for generation of payment transaction to a given address type: object @@ -4881,7 +4890,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/ErgoAddress" + $ref: "#/components/schemas/PrivateKeyRequest" responses: '200': description: Successfully retrieved secret key @@ -6643,7 +6652,36 @@ paths: application/json: schema: $ref: '#/components/schemas/ApiError' - + /blockchain/tokens: + post: + summary: Retrieve minting information about a list of tokens + operationId: getTokensByIds + tags: + - blockchain + requestBody: + required: true + content: + application/json: + schema: + type: array + items: + type: string + description: Token ID + responses: + '200': + description: Array of tokens with the provided IDs + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/IndexedToken' + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/ApiError' /blockchain/balance: post: summary: Retrieve confirmed and unconfirmed balance of an address diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 37c2406a53..cbc5dd4382 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -79,8 +79,8 @@ ergo { mempoolCapacity = 1000 # Interval for mempool transaction re-check. We check transaction when it is entering the mempool, and then - # re-check it every interval value - mempoolCleanupDuration = 20m + # re-check it every interval value (but only on new block arrival) + mempoolCleanupDuration = 30s # Mempool transaction sorting scheme ("random", "bySize", or "byExecutionCost") mempoolSorting = "random" diff --git a/src/main/scala/org/ergoplatform/ErgoApp.scala b/src/main/scala/org/ergoplatform/ErgoApp.scala index 323bd5f227..cf8ad93170 100644 --- a/src/main/scala/org/ergoplatform/ErgoApp.scala +++ b/src/main/scala/org/ergoplatform/ErgoApp.scala @@ -106,14 +106,6 @@ class ErgoApp(args: Args) extends ScorexLogging { None } - // Create an instance of ExtraIndexer actor (will start if "extraIndex = true" in config) - private val indexerOpt: Option[ActorRef] = - if (ergoSettings.nodeSettings.extraIndex) { - Some(ExtraIndexer(ergoSettings.chainSettings, ergoSettings.cacheSettings)) - } else { - None - } - private val syncTracker = ErgoSyncTracker(scorexSettings.network) private val deliveryTracker: DeliveryTracker = DeliveryTracker.empty(ergoSettings) @@ -144,6 +136,7 @@ class ErgoApp(args: Args) extends ScorexLogging { ManifestSpec.messageCode -> ergoNodeViewSynchronizerRef, GetUtxoSnapshotChunkSpec.messageCode-> ergoNodeViewSynchronizerRef, UtxoSnapshotChunkSpec.messageCode -> ergoNodeViewSynchronizerRef, + // nipopows exchange related messages GetNipopowProofSpec.messageCode -> ergoNodeViewSynchronizerRef, NipopowProofSpec.messageCode -> ergoNodeViewSynchronizerRef ) @@ -179,6 +172,14 @@ class ErgoApp(args: Args) extends ScorexLogging { ergoSettings ) + // Create an instance of ExtraIndexer actor (will start if "extraIndex = true" in config) + private val indexerOpt: Option[ActorRef] = + if (ergoSettings.nodeSettings.extraIndex) { + Some(ExtraIndexer(ergoSettings.chainSettings, ergoSettings.cacheSettings)) + } else { + None + } + private val apiRoutes: Seq[ApiRoute] = Seq( EmissionApiRoute(ergoSettings), ErgoUtilsApiRoute(ergoSettings), diff --git a/src/main/scala/org/ergoplatform/GlobalConstants.scala b/src/main/scala/org/ergoplatform/GlobalConstants.scala index 5d396394ba..2536689a4f 100644 --- a/src/main/scala/org/ergoplatform/GlobalConstants.scala +++ b/src/main/scala/org/ergoplatform/GlobalConstants.scala @@ -12,4 +12,5 @@ object GlobalConstants { val ApiDispatcher = "api-dispatcher" val IndexerDispatcher = "indexer-dispatcher" + } 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..7e05ecdd8e 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} @@ -32,7 +32,7 @@ case class BlockchainApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSetting val settings: RESTApiSettings = ergoSettings.scorexSettings.restApi - private implicit val segmentTreshold: Int = indexerOpt.map { indexer => + private lazy val segmentTreshold: Int = indexerOpt.map { indexer => Await.result[Int]((indexer ? GetSegmentThreshold).asInstanceOf[Future[Int]], Duration(3, SECONDS)) }.getOrElse(0) @@ -85,6 +85,7 @@ case class BlockchainApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSetting getBoxesByErgoTreeR ~ getBoxesByErgoTreeUnspentR ~ getTokenInfoByIdR ~ + getTokenInfoByIdsR ~ getAddressBalanceTotalR ~ getAddressBalanceTotalGetRoute } @@ -151,7 +152,7 @@ case class BlockchainApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSetting private def getTxsByAddress(addr: ErgoAddress, offset: Int, limit: Int): Future[(Seq[IndexedErgoTransaction],Long)] = getHistory.map { history => getAddress(addr)(history) match { - case Some(addr) => (addr.retrieveTxs(history, offset, limit), addr.txCount) + case Some(addr) => (addr.retrieveTxs(history, offset, limit)(segmentTreshold), addr.txCount(segmentTreshold)) case None => (Seq.empty[IndexedErgoTransaction], 0L) } } @@ -219,7 +220,7 @@ case class BlockchainApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSetting private def getBoxesByAddress(addr: ErgoAddress, offset: Int, limit: Int): Future[(Seq[IndexedErgoBox],Long)] = getHistory.map { history => getAddress(addr)(history) match { - case Some(addr) => (addr.retrieveBoxes(history, offset, limit).reverse, addr.boxCount) + case Some(addr) => (addr.retrieveBoxes(history, offset, limit)(segmentTreshold).reverse, addr.boxCount(segmentTreshold)) case None => (Seq.empty[IndexedErgoBox], 0L) } } @@ -311,7 +312,7 @@ case class BlockchainApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSetting private def getBoxesByErgoTree(tree: ErgoTree, offset: Int, limit: Int): Future[(Seq[IndexedErgoBox],Long)] = getHistory.map { history => getAddress(tree)(history) match { - case Some(iEa) => (iEa.retrieveBoxes(history, offset, limit).reverse, iEa.boxCount) + case Some(iEa) => (iEa.retrieveBoxes(history, offset, limit)(segmentTreshold).reverse, iEa.boxCount(segmentTreshold)) case None => (Seq.empty[IndexedErgoBox], 0L) } } @@ -341,6 +342,12 @@ case class BlockchainApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSetting } } + private def getTokenInfoByIds(ids: Seq[ModifierId]): Future[Seq[IndexedToken]] = { + getHistory.map { history => + ids.flatMap(id => history.typedExtraIndexById[IndexedToken](uniqueId(id))) + } + } + private def getTokenInfoById(id: ModifierId): Future[Option[IndexedToken]] = { getHistory.map { history => history.typedExtraIndexById[IndexedToken](uniqueId(id)) @@ -351,10 +358,14 @@ case class BlockchainApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSetting ApiResponse(getTokenInfoById(id)) } + private def getTokenInfoByIdsR: Route = (post & pathPrefix("tokens") & entity(as[Seq[ModifierId]])) { ids => + ApiResponse(getTokenInfoByIds(ids)) + } + private def getBoxesByTokenId(id: ModifierId, offset: Int, limit: Int): Future[(Seq[IndexedErgoBox],Long)] = getHistory.map { history => history.typedExtraIndexById[IndexedToken](uniqueId(id)) match { - case Some(token) => (token.retrieveBoxes(history, offset, limit), token.boxCount) + case Some(token) => (token.retrieveBoxes(history, offset, limit)(segmentTreshold), token.boxCount(segmentTreshold)) case None => (Seq.empty[IndexedErgoBox], 0L) } } diff --git a/src/main/scala/org/ergoplatform/http/api/ErgoBaseApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ErgoBaseApiRoute.scala index f12badfb0b..50162b59f9 100644 --- a/src/main/scala/org/ergoplatform/http/api/ErgoBaseApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ErgoBaseApiRoute.scala @@ -16,8 +16,8 @@ import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGe 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..f2d65ca128 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 java.security.SecureRandom import scala.util.Failure -import sigmastate.serialization.{ErgoTreeSerializer, GroupElementSerializer, SigmaSerializer} +import sigma.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..6a2b614235 100644 --- a/src/main/scala/org/ergoplatform/http/api/ScriptApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ScriptApiRoute.scala @@ -14,13 +14,12 @@ 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 sigma.ast.{ByteArrayConstant, ErgoTree} +import sigma.data.ProveDlog import sigmastate.eval.CompiletimeIRContext import sigmastate.interpreter.Interpreter import sigmastate.lang.{CompilerResult, SigmaCompiler} -import sigmastate.serialization.ValueSerializer +import sigma.serialization.ValueSerializer import scala.concurrent.Future import scala.concurrent.duration._ @@ -60,13 +59,13 @@ case class ScriptApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings) } private def compileSource(source: String, env: Map[String, Any]): Try[ErgoTree] = { - import sigmastate.Values._ + import sigma.ast._ val compiler = new SigmaCompiler(ergoSettings.chainSettings.addressPrefix) Try(compiler.compile(env, source)(new CompiletimeIRContext)).flatMap { case CompilerResult(_, _, _, script: Value[SSigmaProp.type@unchecked]) if script.tpe == SSigmaProp => - Success(script) + Success(ErgoTree.fromProposition(script)) case CompilerResult(_, _, _, script: Value[SBoolean.type@unchecked]) if script.tpe == SBoolean => - Success(script.toSigmaProp) + Success(ErgoTree.fromProposition(script.toSigmaProp)) case other => Failure(new Exception(s"Source compilation result is of type ${other.buildTree.tpe}, but `SBoolean` expected")) } diff --git a/src/main/scala/org/ergoplatform/http/api/TransactionsApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/TransactionsApiRoute.scala index 0cc95f24a3..489e8ac6aa 100644 --- a/src/main/scala/org/ergoplatform/http/api/TransactionsApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/TransactionsApiRoute.scala @@ -17,8 +17,8 @@ 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.SType +import sigma.ast.EvaluatedValue import sigmastate.eval.Extensions.ArrayByteOps import scala.concurrent.Future 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..beac5636ac 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,6 @@ 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/CleanupWorker.scala b/src/main/scala/org/ergoplatform/local/CleanupWorker.scala index 0db0c9fce8..ecc9c16e00 100644 --- a/src/main/scala/org/ergoplatform/local/CleanupWorker.scala +++ b/src/main/scala/org/ergoplatform/local/CleanupWorker.scala @@ -66,8 +66,8 @@ class CleanupWorker(nodeViewHolderRef: ActorRef, val now = System.currentTimeMillis() - val allPoolTxs = mempool.getAllPrioritized // Check transactions sorted by priority. Parent transaction comes before its children. + val allPoolTxs = mempool.getAllPrioritized val txsToValidate = allPoolTxs.filter { utx => (now - utx.lastCheckedTime) > TimeLimit }.toList diff --git a/src/main/scala/org/ergoplatform/mining/CandidateGenerator.scala b/src/main/scala/org/ergoplatform/mining/CandidateGenerator.scala index a42b50e6db..b90c98ee9e 100644 --- a/src/main/scala/org/ergoplatform/mining/CandidateGenerator.scala +++ b/src/main/scala/org/ergoplatform/mining/CandidateGenerator.scala @@ -27,12 +27,10 @@ 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.data.{Digest32Coll, ProveDlog} +import sigma.crypto.CryptoFacade +import sigma.eval.Extensions.EvalIterableOps +import sigma.interpreter.ProverResult import sigma.{Coll, Colls} import scala.annotation.tailrec @@ -74,7 +72,7 @@ class CandidateGenerator( override def receive: Receive = { - /** first we need to get Readers to have some initial state to work with */ + // first we need to get Readers to have some initial state to work with case Readers(h, s: UtxoStateReader, m, _) => val lastHeaders = h.lastHeaders(500).headers val avgMiningTime = getBlockMiningTimeAvg(lastHeaders.map(_.timestamp)) @@ -118,10 +116,10 @@ class CandidateGenerator( case _: NodeViewChange => // Just ignore all other NodeView Changes - /** - * When new block is applied, either one mined by us or received from peers isn't equal to our candidate's parent, - * we need to generate new candidate and possibly also discard existing solution if it is also behind - */ + /* + * When new block is applied, either one mined by us or received from peers isn't equal to our candidate's parent, + * we need to generate new candidate and possibly also discard existing solution if it is also behind + */ case FullBlockApplied(header) => log.info( s"Preparing new candidate on getting new block at ${header.height}" @@ -745,8 +743,9 @@ object CandidateGenerator extends ScorexLogging { .filter(b => java.util.Arrays.equals(b.propositionBytes, propositionBytes) && !inputs.exists(i => java.util.Arrays.equals(i.boxId, b.id))) val feeTxOpt: Option[ErgoTransaction] = if (feeBoxes.nonEmpty) { val feeAmount = feeBoxes.map(_.value).sum - val feeAssets = - feeBoxes.toColl.flatMap(_.additionalTokens).take(MaxAssetsPerBox) + val feeAssets = feeBoxes + .flatMap(_.additionalTokens.toArray) + .toColl.take(MaxAssetsPerBox) val inputs = feeBoxes.map(b => new Input(b.id, ProverResult.empty)) val minerBox = new ErgoBoxCandidate(feeAmount, minerProp, nextHeight, feeAssets, Map()) @@ -884,7 +883,7 @@ object CandidateGenerator extends ScorexLogging { } /** - * Derives header without pow from [[CandidateBlock]]. + * Derives header without pow from a block candidate provided */ def deriveUnprovenHeader(candidate: CandidateBlock): HeaderWithoutPow = { val (parentId, height) = derivedHeaderFields(candidate.parentOpt) @@ -903,7 +902,8 @@ object CandidateGenerator extends ScorexLogging { candidate.nBits, height, extensionRoot, - candidate.votes + candidate.votes, + Array.emptyByteArray ) } diff --git a/src/main/scala/org/ergoplatform/mining/ErgoMiner.scala b/src/main/scala/org/ergoplatform/mining/ErgoMiner.scala index 82b8630abd..4157bcd3e2 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} @@ -68,7 +69,7 @@ class ErgoMiner( override def receive: Receive = { - /** at first keep trying to obtain secret and public key as we cannot mine without it */ + // at first keep trying to obtain secret and public key as we cannot mine without it case walletQuery: WalletQuery => viewHolderRef ! GetDataFromCurrentView[DigestState, Unit] { v => walletQuery match { @@ -143,13 +144,13 @@ class ErgoMiner( case ReadMinerPk => // used in /mining/rewardAddress API method sender() ! StatusReply.success(minerState.publicKey) - /** - * Non obvious but case when mining is enabled, but miner isn't started yet. Initialization case. - * We've received block that been generated by somebody else or genesis while we doesn't start. - * And this block was generated after our miner had been started. That means that we are ready - * to start mining. - * This block could be either genesis or generated by another node. - */ + /* + * Non obvious but case when mining is enabled, but miner isn't started yet. Initialization case. + * We've received block that been generated by somebody else or genesis while we doesn't start. + * And this block was generated after our miner had been started. That means that we are ready + * to start mining. + * This block could be either genesis or generated by another node. + */ case FullBlockApplied(header) if shouldStartMine(header) => log.info("Starting mining triggered by incoming block") diff --git a/src/main/scala/org/ergoplatform/nodeView/ErgoNodeViewHolder.scala b/src/main/scala/org/ergoplatform/nodeView/ErgoNodeViewHolder.scala index e68b9d4693..19af8bba61 100644 --- a/src/main/scala/org/ergoplatform/nodeView/ErgoNodeViewHolder.scala +++ b/src/main/scala/org/ergoplatform/nodeView/ErgoNodeViewHolder.scala @@ -402,7 +402,7 @@ abstract class ErgoNodeViewHolder[State <: ErgoState[State]](settings: ErgoSetti .flatMap(extractTransactions) .filter(tx => !appliedTxs.exists(_.id == tx.id)) .map(tx => UnconfirmedTransaction(tx, None)) - memPool.remove(appliedTxs).put(rolledBackTxs) + memPool.removeWithDoubleSpends(appliedTxs).put(rolledBackTxs) } /** diff --git a/src/main/scala/org/ergoplatform/nodeView/history/ErgoHistoryReader.scala b/src/main/scala/org/ergoplatform/nodeView/history/ErgoHistoryReader.scala index 3fde451134..9f7a45f0fe 100644 --- a/src/main/scala/org/ergoplatform/nodeView/history/ErgoHistoryReader.scala +++ b/src/main/scala/org/ergoplatform/nodeView/history/ErgoHistoryReader.scala @@ -361,9 +361,9 @@ trait ErgoHistoryReader * @return */ def syncInfoV1: ErgoSyncInfoV1 = { - /** - * Return last count headers from best headers chain if exist or chain up to genesis otherwise - */ + /* + * Return last count headers from best headers chain if exist or chain up to genesis otherwise + */ def lastHeaderIds(count: Int): IndexedSeq[ModifierId] = { val currentHeight = headersHeight val from = Math.max(currentHeight - count + 1, 1) 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..29636c920a 100644 --- a/src/main/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexer.scala +++ b/src/main/scala/org/ergoplatform/nodeView/history/extra/ExtraIndexer.scala @@ -15,7 +15,7 @@ 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.ast.ErgoTree import sigma.Extensions._ import java.nio.ByteBuffer @@ -86,22 +86,32 @@ trait ExtraIndexerBase extends Actor with Stash with ScorexLogging { * @param height - blockheight to get transations from * @return transactions at height */ - private def getBlockTransactionsAt(height: Int): BlockTransactions = { - val txs = blockCache.remove(height).getOrElse(history.bestBlockTransactionsAt(height).get) - if (height % 1000 == 0) blockCache.keySet.filter(_ < height).map(blockCache.remove) - if (readingUpTo - height < 300 && chainHeight - height > 1000) { - readingUpTo = math.min(height + 1001, chainHeight) - val blockNums = height + 1 to readingUpTo by 50 - blockNums.zip(blockNums.tail).map { range => // ranges of 50 blocks for each thread to read - Future { - (range._1 until range._2).foreach { blockNum => - blockCache.put(blockNum, history.bestBlockTransactionsAt(blockNum).get) + private def getBlockTransactionsAt(height: Int): Option[BlockTransactions] = + blockCache.remove(height).orElse(history.bestBlockTransactionsAt(height)).map { txs => + if (height % 1000 == 0) blockCache.keySet.filter(_ < height).map(blockCache.remove) + if (readingUpTo - height < 300 && chainHeight - height > 1000) { + readingUpTo = math.min(height + 1001, chainHeight) + + if(height < history.fullBlockHeight - 1000) { + val blockNums = height + 1 to readingUpTo by 250 + blockNums.zip(blockNums.tail).map { range => // ranges of 250 blocks for each thread to read + Future { + (range._1 until range._2).foreach { blockNum => + history.bestBlockTransactionsAt(blockNum).map(blockCache.put(blockNum, _)) + } + } + } + } else { + val blockNums = height + 1 to readingUpTo + Future { + blockNums.foreach { blockNum => + history.bestBlockTransactionsAt(blockNum).map(blockCache.put(blockNum, _)) + } } } } + txs } - txs - } /** * Spend an IndexedErgoBox from buffer or database. Also record tokens for later use in balance tracking logic. @@ -149,7 +159,7 @@ trait ExtraIndexerBase extends Actor with Stash with ScorexLogging { } case None => // address not found at all spendOrReceive match { - case Left(iEb) => log.warn(s"Unknown address spent box ${bytesToId(iEb.box.id)}") // spend box should never happen by an unknown address + case Left(iEb) => log.error(s"Unknown address spent box ${bytesToId(iEb.box.id)}") // spend box should never happen by an unknown address case Right(iEb) => trees.put(id, IndexedErgoAddress(id).initBalance.addTx(state.globalTxIndex).addBox(iEb)) // receive box, new address } } @@ -176,7 +186,7 @@ trait ExtraIndexerBase extends Actor with Stash with ScorexLogging { case Right(iEb) => tokens.put(id, x.addBox(iEb)) // receive box } case None => // token not found at all - log.warn(s"Unknown token $id") // spend box should never happen by an unknown token + log.error(s"Unknown token $id") // spend box should never happen by an unknown token } } @@ -234,18 +244,25 @@ trait ExtraIndexerBase extends Actor with Stash with ScorexLogging { * @param headerOpt - header to index blocktransactions of (used after caught up with chain) */ protected def index(state: IndexerState, headerOpt: Option[Header] = None): IndexerState = { - val bt = headerOpt.flatMap { header => + val btOpt = headerOpt.flatMap { header => history.typedModifierById[BlockTransactions](header.transactionsId) - }.getOrElse(getBlockTransactionsAt(state.indexedHeight)) + }.orElse(getBlockTransactionsAt(state.indexedHeight)) val height = headerOpt.map(_.height).getOrElse(state.indexedHeight) + if (btOpt.isEmpty) { + log.error(s"Could not read block $height / $chainHeight from database, waiting for new block until retrying") + return state.decrementIndexedHeight.copy(caughtUp = true) + } + + val txs: Seq[ErgoTransaction] = btOpt.get.txs + var boxCount: Int = 0 implicit var newState: IndexerState = state // record transactions and boxes - cfor(0)(_ < bt.txs.length, _ + 1) { n => + cfor(0)(_ < txs.length, _ + 1) { n => - val tx: ErgoTransaction = bt.txs(n) + val tx: ErgoTransaction = txs(n) val inputs: Array[Long] = Array.ofDim[Long](tx.inputs.length) val outputs: Array[Long] = Array.ofDim[Long](tx.outputs.length) @@ -302,7 +319,7 @@ trait ExtraIndexerBase extends Actor with Stash with ScorexLogging { } - log.info(s"Buffered block $height / $chainHeight [txs: ${bt.txs.length}, boxes: $boxCount] (buffer: $modCount / $saveLimit)") + log.info(s"Buffered block $height / $chainHeight [txs: ${txs.length}, boxes: $boxCount] (buffer: $modCount / $saveLimit)") val maxHeight = headerOpt.map(_.height).getOrElse(chainHeight) newState.copy(caughtUp = newState.indexedHeight == maxHeight) @@ -314,7 +331,7 @@ trait ExtraIndexerBase extends Actor with Stash with ScorexLogging { * @param state - current state of indexer * @param height - starting height */ - protected def removeAfter(state: IndexerState, height: Int): IndexerState = { + private def removeAfter(state: IndexerState, height: Int): IndexerState = { var newState: IndexerState = state @@ -406,7 +423,7 @@ trait ExtraIndexerBase extends Actor with Stash with ScorexLogging { val newState: IndexerState = index(state.incrementIndexedHeight, Some(header)) saveProgress(newState) context.become(loaded(newState)) - } else if(header.height > state.indexedHeight + 1) { // applied block is ahead of indexer + } else if (header.height > state.indexedHeight + 1) { // applied block is ahead of indexer context.become(loaded(state.copy(caughtUp = false))) self ! Index() } else // applied block has already been indexed, skipping duplicate @@ -420,8 +437,8 @@ trait ExtraIndexerBase extends Actor with Stash with ScorexLogging { history.heightOf(branchPoint) match { case Some(branchHeight) => if (branchHeight < state.indexedHeight) { - context.become (loaded (state.copy (rollbackTo = branchHeight) ) ) - self ! RemoveAfter (branchHeight) + context.become(loaded(state.copy(rollbackTo = branchHeight))) + self ! RemoveAfter(branchHeight) } case None => log.error(s"No rollback height found for $branchPoint") 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..036bf3ba4f 100644 --- a/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedToken.scala +++ b/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexedToken.scala @@ -1,17 +1,17 @@ package org.ergoplatform.nodeView.history.extra -import org.ergoplatform.{ErgoAddressEncoder, ErgoBox} import org.ergoplatform.ErgoBox.{R4, R5, R6} -import org.ergoplatform.nodeView.history.{ErgoHistory, ErgoHistoryReader} import org.ergoplatform.nodeView.history.extra.ExtraIndexer.{ExtraIndexTypeId, fastIdToBytes} import org.ergoplatform.nodeView.history.extra.IndexedTokenSerializer.{ByteColl, uniqueId} -import org.ergoplatform.settings.Algos +import org.ergoplatform.nodeView.history.{ErgoHistory, ErgoHistoryReader} import org.ergoplatform.serialization.ErgoSerializer -import scorex.util.{ModifierId, bytesToId} +import org.ergoplatform.settings.Algos +import org.ergoplatform.{ErgoAddressEncoder, ErgoBox} import scorex.util.serialization.{Reader, Writer} -import sigmastate.Values.CollectionConstant -import sigmastate.SByte +import scorex.util.{ModifierId, bytesToId} import sigma.Extensions._ +import sigma.ast.SByte +import sigma.ast.syntax.CollectionConstant import scala.collection.mutable.ArrayBuffer @@ -167,7 +167,7 @@ object IndexedToken { * so they are checked with Try-catches. * * @param iEb - box to use - * @param tokenIndex - token index to check in [[ErgoBox.additionalTokens]] + * @param tokenIndex - token index to check in box' `additionalTokens` * @return token index */ def fromBox(iEb: IndexedErgoBox, tokenIndex: Int): IndexedToken = { diff --git a/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexerState.scala b/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexerState.scala index 05dec8d177..30f8fc4eeb 100644 --- a/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexerState.scala +++ b/src/main/scala/org/ergoplatform/nodeView/history/extra/IndexerState.scala @@ -20,6 +20,7 @@ case class IndexerState(indexedHeight: Int, def rollbackInProgress: Boolean = rollbackTo > 0 def incrementIndexedHeight: IndexerState = copy(indexedHeight = indexedHeight + 1) + def decrementIndexedHeight: IndexerState = copy(indexedHeight = indexedHeight - 1) def incrementTxIndex: IndexerState = copy(globalTxIndex = globalTxIndex + 1) def incrementBoxIndex: IndexerState = copy(globalBoxIndex = globalBoxIndex + 1) diff --git a/src/main/scala/org/ergoplatform/nodeView/history/extra/Segment.scala b/src/main/scala/org/ergoplatform/nodeView/history/extra/Segment.scala index af6e501f88..6aaa25a0f2 100644 --- a/src/main/scala/org/ergoplatform/nodeView/history/extra/Segment.scala +++ b/src/main/scala/org/ergoplatform/nodeView/history/extra/Segment.scala @@ -271,7 +271,7 @@ abstract class Segment[T <: Segment[_] : ClassTag](val parentId: ModifierId, * @param mempool - mempool to use, if unconfirmed is true * @param offset - items to skip from the start * @param limit - items to retrieve - * @param sortDir - whether to start retrieval from newest box ([[DESC]]) or oldest box ([[ASC]]) + * @param sortDir - whether to start retrieval from newest box (DESC) or oldest box (ASC) * @param unconfirmed - whether to include unconfirmed boxes * @param spentBoxesIdsInMempool - Set of box IDs that are spent in the mempool (to be excluded if necessary) * @return array of unspent boxes @@ -317,7 +317,7 @@ abstract class Segment[T <: Segment[_] : ClassTag](val parentId: ModifierId, } /** - * Logic for [[Segment.rollback]] + * Logic for `Segment.rollback` * * @param txTarget - remove transaction numbers above this number * @param boxTarget - remove box numbers above this number diff --git a/src/main/scala/org/ergoplatform/nodeView/mempool/ErgoMemPool.scala b/src/main/scala/org/ergoplatform/nodeView/mempool/ErgoMemPool.scala index df08cd4858..58f008bfec 100644 --- a/src/main/scala/org/ergoplatform/nodeView/mempool/ErgoMemPool.scala +++ b/src/main/scala/org/ergoplatform/nodeView/mempool/ErgoMemPool.scala @@ -106,15 +106,37 @@ class ErgoMemPool private[mempool](private[mempool] val pool: OrderedTxPool, } /** - * Remove transaction from the pool + * Remove transaction from the pool along with its double-spends */ - def remove(tx: ErgoTransaction): ErgoMemPool = { - log.debug(s"Removing transaction ${tx.id} from the mempool") - new ErgoMemPool(pool.remove(tx), updateStatsOnRemoval(tx), sortingOption) + def removeTxAndDoubleSpends(tx: ErgoTransaction): ErgoMemPool = { + def removeTx(mp: ErgoMemPool, tx: ErgoTransaction): ErgoMemPool = { + log.debug(s"Removing transaction ${tx.id} from the mempool") + new ErgoMemPool(mp.pool.remove(tx), mp.updateStatsOnRemoval(tx), sortingOption) + } + + val poolWithoutTx = removeTx(this, tx) + val doubleSpentTransactionIds = tx.inputs.flatMap(i => + poolWithoutTx.pool.inputs.get(i.boxId) + ).toSet + val doubleSpentTransactions = doubleSpentTransactionIds.flatMap { txId => + poolWithoutTx.pool.orderedTransactions.get(txId) + } + doubleSpentTransactions.foldLeft(poolWithoutTx) { case (pool, tx) => + removeTx(pool, tx.transaction) + } } - def remove(txs: TraversableOnce[ErgoTransaction]): ErgoMemPool = { - txs.foldLeft(this) { case (acc, tx) => acc.remove(tx) } + /** + * Remove provided transactions and their doublespends from the pool + */ + def removeWithDoubleSpends(txs: TraversableOnce[ErgoTransaction]): ErgoMemPool = { + txs.foldLeft(this) { case (memPool, tx) => + if (memPool.contains(tx.id)) { // tx could be removed earlier in this loop as double-spend of another tx + memPool.removeTxAndDoubleSpends(tx) + } else { + memPool + } + } } /** diff --git a/src/main/scala/org/ergoplatform/nodeView/state/DigestState.scala b/src/main/scala/org/ergoplatform/nodeView/state/DigestState.scala index 3c5a3a4721..94a51540b7 100644 --- a/src/main/scala/org/ergoplatform/nodeView/state/DigestState.scala +++ b/src/main/scala/org/ergoplatform/nodeView/state/DigestState.scala @@ -154,7 +154,7 @@ class DigestState protected(override val version: VersionTag, object DigestState extends ScorexLogging with ScorexEncoding { /** - * Creates [[DigestState]] from existing [[ErgoStateContext]] corresponding to some `version` and `rootHash`. + * Creates [[DigestState]] with provided `ErgoStateContext` instance corresponding to some version` and `rootHash`. */ def recover(version: VersionTag, rootHash: ADDigest, diff --git a/src/main/scala/org/ergoplatform/nodeView/state/ErgoState.scala b/src/main/scala/org/ergoplatform/nodeView/state/ErgoState.scala index 31362aa4d2..2dc8e87b83 100644 --- a/src/main/scala/org/ergoplatform/nodeView/state/ErgoState.scala +++ b/src/main/scala/org/ergoplatform/nodeView/state/ErgoState.scala @@ -22,10 +22,10 @@ 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.Colls +import sigma.ast._ +import sigma.data.ProveDlog +import sigma.serialization.ValueSerializer import spire.syntax.all.cfor import scala.annotation.tailrec @@ -205,15 +205,13 @@ object ErgoState extends ScorexLogging { ergoTree: ErgoTree, additionalTokens: Seq[(TokenId, Long)] = Seq.empty, additionalRegisters: AdditionalRegisters = Map.empty): ErgoBox = { - import sigmastate.eval._ - val creationHeight: Int = EmptyHistoryHeight val transactionId: ModifierId = ErgoBox.allZerosModifierId val boxIndex: Short = 0: Short new ErgoBox(value, ergoTree, - CostingSigmaDslBuilder.Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]), + Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]), additionalRegisters, transactionId, boxIndex, creationHeight) } diff --git a/src/main/scala/org/ergoplatform/nodeView/state/UtxoState.scala b/src/main/scala/org/ergoplatform/nodeView/state/UtxoState.scala index 01b98a59ef..a16f29265b 100644 --- a/src/main/scala/org/ergoplatform/nodeView/state/UtxoState.scala +++ b/src/main/scala/org/ergoplatform/nodeView/state/UtxoState.scala @@ -159,19 +159,19 @@ class UtxoState(override val persistentProver: PersistentBatchAVLProver[Digest32 log.error("Calculated proofHash is not equal to the declared one, doing another attempt") - /** - * Proof generated was different from one announced. - * - * In most cases, announced proof is okay, and as proof is already checked, problem in some - * extra bytes added to the proof. - * - * Could be related to https://github.com/ergoplatform/ergo/issues/1614 - * - * So the problem could appear on mining nodes only, and caused by - * proofsForTransactions() wasting the tree unexpectedly. - * - * We are trying to generate proof again now. - */ + /* + * Proof generated was different from one announced. + * + * In most cases, announced proof is okay, and as proof is already checked, problem in some + * extra bytes added to the proof. + * + * Could be related to https://github.com/ergoplatform/ergo/issues/1614 + * + * So the problem could appear on mining nodes only, and caused by + * proofsForTransactions() wasting the tree unexpectedly. + * + * We are trying to generate proof again now. + */ persistentProver.rollback(inRoot) .ensuring(java.util.Arrays.equals(persistentProver.digest, inRoot)) diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActor.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActor.scala index c65599f212..b64b43522f 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActor.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActor.scala @@ -116,7 +116,7 @@ class ErgoWalletActor(settings: ErgoSettings, case _: RestoreWallet | _: InitWallet => sender() ! Failure(new Exception("Wallet is already initialized or testMnemonic is set. Clear current secret to re-init it.")) - /** READERS */ + /* READERS */ case ReadBalances(chainStatus) => val walletDigest = if (chainStatus.onChain) { state.registry.fetchDigest() @@ -194,7 +194,7 @@ class ErgoWalletActor(settings: ErgoSettings, case ReadScans => sender() ! ReadScansResponse(state.walletVars.externalScans) - /** STATE CHANGE */ + /* STATE CHANGE */ case ChangedMempool(mr: ErgoMemPoolReader@unchecked) => val newState = ergoWalletService.updateUtxoState(state.copy(mempoolReaderOpt = Some(mr))) context.become(loadedWallet(newState)) @@ -219,7 +219,7 @@ class ErgoWalletActor(settings: ErgoSettings, context.become(loadedWallet(state.copy(error = Some(errorMsg)))) } - /** SCAN COMMANDS */ + /* SCAN COMMANDS */ //scan mempool transaction case ScanOffChain(tx) => val dustLimit = settings.walletSettings.dustLimit @@ -300,7 +300,7 @@ class ErgoWalletActor(settings: ErgoSettings, log.warn("Avoiding rollback as wallet is not initialized yet") } - /** WALLET COMMANDS */ + /* WALLET COMMANDS */ case CheckSeed(mnemonic, passOpt) => state.secretStorageOpt match { case Some(secretStorage) => diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActorMessages.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActorMessages.scala index c1f12a4941..6512cd6f50 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActorMessages.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletActorMessages.scala @@ -15,8 +15,8 @@ import org.ergoplatform.wallet.interpreter.TransactionHintsBag import org.ergoplatform._ import org.ergoplatform.core.VersionTag 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..f4314528a6 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletReader.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletReader.scala @@ -18,7 +18,7 @@ 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..505c4ec4b6 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletService.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletService.scala @@ -22,7 +22,7 @@ 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 sigma.data.SigmaBoolean import sigmastate.crypto.DLogProtocol.DLogProverInput import sigma.Extensions.CollBytesOps diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSupport.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSupport.scala index 2854306ddd..4ab8f3f07f 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSupport.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSupport.scala @@ -21,11 +21,11 @@ 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 sigma.data.ProveDlog import sigmastate.eval.Extensions._ -import sigmastate.eval._ import sigmastate.utils.Extensions._ +import sigma.eval.Extensions.EvalIterableOps import scala.util.{Failure, Success, Try} @@ -255,7 +255,7 @@ trait ErgoWalletSupport extends ScorexLogging { // 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) + new ErgoBoxCandidate(changeBox.value, ErgoTree.fromSigmaBoolean(changeAddressOpt.get), walletHeight, assets.toColl) } val inputBoxes = selectionResult.inputBoxes.toIndexedSeq new UnsignedErgoTransaction( diff --git a/src/main/scala/org/ergoplatform/nodeView/wallet/IdUtils.scala b/src/main/scala/org/ergoplatform/nodeView/wallet/IdUtils.scala index a3040f805c..1652fd3162 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/IdUtils.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/IdUtils.scala @@ -4,8 +4,8 @@ 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 sigma.Extensions.ArrayOps import supertagged.TaggedType 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/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..c46b69cb45 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._ /** * Request for new asset issuing. 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..ff17cd8efe 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/requests/PaymentRequest.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/requests/PaymentRequest.scala @@ -7,8 +7,7 @@ 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.{SType, EvaluatedValue} /** * A payment request contains an address (probably containing script), value, assets, additional registers. 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..b9c3b4c30f 100644 --- a/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicate.scala +++ b/src/main/scala/org/ergoplatform/nodeView/wallet/scanning/ScanningPredicate.scala @@ -1,8 +1,8 @@ package org.ergoplatform.nodeView.wallet.scanning import org.ergoplatform.ErgoBox -import sigmastate.Values.EvaluatedValue -import sigmastate.{SType, Values} +import sigma.ast.EvaluatedValue +import sigma.ast._ import sigma.Extensions._ /** @@ -26,10 +26,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 +59,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..f2b8cec9cd 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._ import sigmastate.eval.Extensions.ArrayByteOps -import sigmastate.serialization.ValueSerializer +import sigma.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..1a86ff0751 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 sigma.ast._ import sigmastate.eval.CompiletimeIRContext -import sigmastate.lang.{CompilerSettings, SigmaCompiler, TransformingSigmaBuilder} +import sigmastate.lang.{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..e0e9136bdd 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 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..9e6716584a 100644 --- a/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala +++ b/src/test/scala/org/ergoplatform/http/routes/ScriptApiRouteSpec.scala @@ -13,10 +13,9 @@ import org.ergoplatform.http.api.ScriptApiRoute 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.syntax.CollectionConstant +import sigma.ast.{ErgoTree, SByte, TrueLeaf} +import sigma.serialization.{ErgoTreeSerializer, ValueSerializer} class ScriptApiRouteSpec extends AnyFlatSpec with Matchers @@ -106,7 +105,7 @@ class ScriptApiRouteSpec extends AnyFlatSpec val p2pk = "3WvsT2Gm4EpsM9Pg18PdY6XyhNNMqXDsvJTbbf6ihLvAmSb7u5RN" Get(s"$prefix/$suffix/$p2pk") ~> route ~> check(assertion(responseAs[Json], p2pk)) - val script = TrueLeaf + val script = TrueLeaf.toSigmaProp val tree = ErgoTree.fromProposition(script) val p2sh = Pay2SHAddress.apply(tree).toString() @@ -128,7 +127,7 @@ class ScriptApiRouteSpec extends AnyFlatSpec val bac = ValueSerializer.deserialize(vbs).asInstanceOf[CollectionConstant[SByte.type]] - val bs = bac.value.toArray.map(_.byteValue()) + val bs = bac.value.toArray.map(b => b.byteValue()) val tree = ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bs) @@ -143,7 +142,7 @@ class ScriptApiRouteSpec extends AnyFlatSpec val p2sh = "rbcrmKEYduUvADj9Ts3dSVSG27h54pgrq5fPuwB" Get(s"$prefix/$suffix/$p2sh") ~> route ~> check(assertion(responseAs[Json], p2sh)) - val script = TrueLeaf + val script = TrueLeaf.toSigmaProp val tree = ErgoTree.fromProposition(script) val p2s = addressEncoder.toString(addressEncoder.fromProposition(tree).get) p2s shouldBe "Ms7smJwLGbUAjuWQ" diff --git a/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala index 416dea8b59..598b6f4c81 100644 --- a/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala +++ b/src/test/scala/org/ergoplatform/http/routes/TransactionApiRouteSpec.scala @@ -17,11 +17,10 @@ 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.eval.Extensions.EvalIterableOps +import sigma.ast.{ByteArrayConstant, EvaluatedValue, SType} import java.net.InetSocketAddress import scala.concurrent.duration._ diff --git a/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala index e613f35261..65a86e920c 100644 --- a/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala +++ b/src/test/scala/org/ergoplatform/http/routes/UtilsApiRouteSpec.scala @@ -13,7 +13,8 @@ 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 sigma.serialization.ErgoTreeSerializer import scala.concurrent.duration._ diff --git a/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala b/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala index c742768150..df2c446e35 100644 --- a/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala +++ b/src/test/scala/org/ergoplatform/local/MempoolAuditorSpec.scala @@ -15,12 +15,12 @@ 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 sigma.ast.ErgoTree +import sigma.ast.syntax.ValueOps import sigmastate.eval.{IRContext, RuntimeIRContext} import sigmastate.interpreter.Interpreter.emptyEnv import sigmastate.lang.SigmaCompiler -import sigmastate.lang.Terms.ValueOps -import sigmastate.serialization.ErgoTreeSerializer +import sigma.serialization.ErgoTreeSerializer import scala.concurrent.duration._ @@ -70,7 +70,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.fromSigmaBoolean(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..cb245c6dc6 100644 --- a/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala +++ b/src/test/scala/org/ergoplatform/mining/CandidateGeneratorSpec.scala @@ -19,8 +19,9 @@ import org.ergoplatform.utils.ErgoTestHelpers import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, ErgoTreePredef, Input} import org.scalatest.concurrent.Eventually import org.scalatest.flatspec.AnyFlatSpec +import sigma.ast.ErgoTree +import sigma.data.ProveDlog import org.scalatest.matchers.should.Matchers -import sigmastate.crypto.DLogProtocol 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..e1543727fc 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,13 @@ 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, _) => - SigmaAnd(SigmaPropConstant(defaultMinerPk), l) + val complexScript: ErgoTree = { + val start = SigmaAnd(SigmaPropConstant(defaultMinerPk), SigmaPropConstant(defaultMinerPk)) + val tree = ErgoTree.fromProposition((0 until 100).foldLeft(start) { (l, _) => + SigmaAnd(SigmaPropConstant(defaultMinerPk), l) + }) + tree } - complexScript.complexity shouldBe 28077 val nodeViewHolderRef: ActorRef = ErgoNodeViewRef(ergoSettings) val readersHolderRef: ActorRef = ErgoReadersHolderRef(nodeViewHolderRef) @@ -175,7 +177,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 +241,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 +336,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..4e7969b4cc 100644 --- a/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoNodeTransactionSpec.scala +++ b/src/test/scala/org/ergoplatform/modifiers/mempool/ErgoNodeTransactionSpec.scala @@ -5,22 +5,28 @@ import org.ergoplatform.nodeView.state.{ErgoStateContext, VotingData} import org.ergoplatform.settings._ import org.ergoplatform.utils.ErgoCorePropertyTest import org.ergoplatform.wallet.interpreter.ErgoInterpreter -import org.ergoplatform.{ErgoBox, ErgoBoxCandidate} +import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, 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.validation.ValidationRules.CheckAndGetMethod import org.ergoplatform.wallet.boxes.ErgoBoxAssetExtractor 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 +import sigma.ast.ErgoTree.ZeroHeader +import sigma.ast.{AND, ErgoTree, TrueLeaf} +import sigma.interpreter.{ContextExtension, ProverResult} +import sigma.serialization.ErgoTreeSerializer.DefaultSerializer +import sigma.validation.ReplacedRule import sigmastate.helpers.TestingHelpers._ -import sigmastate.Values.TrueLeaf import scala.util.{Random, Try} @@ -444,7 +450,7 @@ class ErgoNodeTransactionSpec extends ErgoCorePropertyTest { forAll(smallPositiveInt) { inputsNum => - val nonTrivialTrueGen = Gen.const(AND(Seq(TrueLeaf, TrueLeaf)).toSigmaProp.treeWithSegregation) + val nonTrivialTrueGen = Gen.const(ErgoTree.withSegregation(ZeroHeader, AND(Seq(TrueLeaf, TrueLeaf)).toSigmaProp)) val gen = validErgoTransactionGenTemplate(0, 0, inputsNum, nonTrivialTrueGen) val (from, tx) = gen.sample.get tx.statelessValidity().isSuccess shouldBe true @@ -478,4 +484,45 @@ class ErgoNodeTransactionSpec extends ErgoCorePropertyTest { txCost shouldBe (accInitCost + initialCost + inputCost(tx, from) * inputsNum) } } + + /** + * In this test we check how current version of the node (block protocol v3, at the moment of writing this test) will + * execute a script which contains a method added in next version of the protocol (namely, BigInt.nbits), which + * is unknown to the node. + * + * As shown in the test, rule #1110 (CheckAndGetMethod) should be replaced for new methods to be passed by the node + * not recognizing it. + */ + property("Soft-forked execution of Ergoscript containing unknown methods") { + + val activatedVersion = 3.toByte + val params = new Parameters(0, LaunchParameters.parametersTable.updated(123, activatedVersion + 1), ErgoValidationSettingsUpdate.empty) + + // for next version, rule 1011 should be replaced , otherwise transaction validation will fail + // in this test, the rule is replaced with self, but for real activation this choice should be revised + val ruleId = CheckAndGetMethod.id + val updVs = ErgoValidationSettings.initial.updated(ErgoValidationSettingsUpdate(Seq(), Seq(ruleId -> ReplacedRule(ruleId)))) + + val stateContext = emptyStateContext.copy(currentParameters = params, validationSettings = updVs)(chainSettings) + stateContext.blockVersion shouldBe activatedVersion + 1 + + // the following ergo tree contains SBigInt.nbits method which is not supported by this client (as of 5.x version) + // ergo tree version is 3, less value (e.g. version = 2 which gives 1a130206022edf0580fcf622d193db060873007301) + // also works + val ergoTree = DefaultSerializer.deserializeErgoTree(Base16.decode("1b130206022edf0580fcf622d193db060873007301").get) + + ergoTree.root.isLeft shouldBe true // unparsed + + 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)) + + utx.statefulValidity(IndexedSeq(b), IndexedSeq.empty, stateContext, 0)(defaultProver).isSuccess shouldBe true + } + } diff --git a/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala b/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala index 1cfa6f8219..e2289cf0a6 100644 --- a/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala +++ b/src/test/scala/org/ergoplatform/modifiers/mempool/ExpirationSpecification.scala @@ -8,11 +8,10 @@ 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 sigmastate.helpers.TestingHelpers._ -import sigmastate.serialization.ErgoTreeSerializer +import sigma.serialization.ErgoTreeSerializer class ExpirationSpecification extends ErgoCorePropertyTest { import org.ergoplatform.utils.ErgoCoreTestConstants._ 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..6480e04a9b 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.{Coll, Colls} -import sigmastate.Values -import sigmastate.crypto.DLogProtocol.ProveDlog +import sigma.data.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..bc7ea92dac 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.ErgoSettings -import org.ergoplatform.utils.ErgoTestHelpers +import org.ergoplatform.utils.{ErgoTestHelpers, RandomWrapper} import org.scalatest.flatspec.AnyFlatSpec import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks -import sigmastate.Values.{ByteArrayConstant, TrueLeaf} -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigma.ast.ErgoTree.ZeroHeader +import sigma.ast.{ByteArrayConstant, ErgoTree, TrueLeaf} +import sigma.interpreter.{ContextExtension, ProverResult} class ErgoMemPoolSpec extends AnyFlatSpec with ErgoTestHelpers @@ -101,8 +102,9 @@ class ErgoMemPoolSpec extends AnyFlatSpec val wus = WrappedUtxoState(us, bh, settings, extendedParameters).applyModifier(genesis)(_ => ()).get val feeProp = settings.chainSettings.monetary.feeProposition + val trueTree = ErgoTree.withSegregation(ZeroHeader, TrueLeaf.toSigmaProp) 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) @@ -297,11 +299,41 @@ class ErgoMemPoolSpec extends AnyFlatSpec } pool.size shouldBe (family_depth + 1) * txs.size allTxs.foreach { tx => - pool = pool.remove(tx.transaction) + pool = pool.removeTxAndDoubleSpends(tx.transaction) } pool.size shouldBe 0 } + it should "correctly remove doublespents of a transaction from pool" in { + val (us, bh) = createUtxoState(settings) + val genesis = validFullBlock(None, us, bh) + val wus = WrappedUtxoState(us, bh, settings, parameters).applyModifier(genesis)(_ => ()).get + val boxes = wus.takeBoxes(4) + + val limit = 10000 + + val tx1 = validTransactionsFromBoxes(limit, boxes.take(1), new RandomWrapper) + ._1.map(tx => UnconfirmedTransaction(tx, None)).head + + val tx2 = validTransactionsFromBoxes(limit, boxes.takeRight(2), new RandomWrapper) + ._1.map(tx => UnconfirmedTransaction(tx, None)).head + + val tx3 = validTransactionsFromBoxes(limit, boxes.take(1), new RandomWrapper) + ._1.map(tx => UnconfirmedTransaction(tx, None)).head + + tx1.transaction.inputs.head.boxId shouldBe tx3.transaction.inputs.head.boxId + + var pool = ErgoMemPool.empty(settings) + Seq(tx2, tx3).foreach { tx => + pool = pool.put(tx) + } + + pool = pool.removeTxAndDoubleSpends(tx1.transaction) + pool.contains(tx1.transaction) shouldBe false + pool.contains(tx2.transaction) shouldBe true + pool.contains(tx3.transaction) shouldBe false + } + it should "return results take / getAll / getAllPrioritized sorted by priority" in { val feeProp = settings.chainSettings.monetary.feeProposition @@ -376,7 +408,7 @@ class ErgoMemPoolSpec extends AnyFlatSpec pool.stats.snapTakenTxns shouldBe MemPoolStatistics(System.currentTimeMillis(),0,System.currentTimeMillis()).snapTakenTxns allTxs.foreach { tx => - pool = pool.remove(tx.transaction) + pool = pool.removeTxAndDoubleSpends(tx.transaction) } pool.size shouldBe 0 pool.stats.takenTxns shouldBe (family_depth + 1) * txs.size diff --git a/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala b/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala index ebe42d897d..034f6dd2a6 100644 --- a/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/mempool/ScriptsSpec.scala @@ -6,23 +6,23 @@ import org.ergoplatform.nodeView.state.{BoxHolder, ErgoState, UtxoState} import org.ergoplatform.settings.Algos 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.{TransformingSigmaBuilder, _} +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 sigmastate.lang.{CompilerSettings, SigmaCompiler} import scala.util.Try class ScriptsSpec extends ErgoCorePropertyTest with FileUtils { - import org.ergoplatform.utils.ErgoNodeTestConstants._ import org.ergoplatform.utils.ErgoCoreTestConstants._ - import org.ergoplatform.wallet.utils.WalletGenerators._ + import org.ergoplatform.utils.ErgoNodeTestConstants._ import org.ergoplatform.utils.generators.ValidBlocksGenerators._ + import org.ergoplatform.wallet.utils.WalletGenerators._ val compiler = SigmaCompiler( CompilerSettings(TestnetNetworkPrefix, TransformingSigmaBuilder, lowerMethodCalls = true) @@ -30,19 +30,21 @@ class ScriptsSpec extends ErgoCorePropertyTest with FileUtils { val delta = emission.settings.minerRewardDelay val fixedBox: ErgoBox = ergoBoxGen(fromString("1 == 1"), heightGen = 0).sample.get implicit lazy val context: IRContext = new CompiletimeIRContext + val trueTree = ErgoTree.fromProposition(TrueLeaf.toSigmaProp) + val falseTree = ErgoTree.fromProposition(FalseLeaf.toSigmaProp) 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 +52,25 @@ 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..d61fd82fbb 100644 --- a/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala +++ b/src/test/scala/org/ergoplatform/nodeView/state/ErgoStateSpecification.scala @@ -9,6 +9,7 @@ import org.ergoplatform.utils.{ErgoCorePropertyTest, RandomWrapper} import org.ergoplatform.wallet.boxes.ErgoBoxSerializer import org.scalacheck.Gen import org.ergoplatform.core.bytesToVersion +import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators.boxesHolderGen import org.ergoplatform.validation.ValidationResult.Valid import scorex.db.ByteArrayWrapper @@ -18,7 +19,6 @@ import scala.util.{Failure, Try} class ErgoStateSpecification extends ErgoCorePropertyTest { import org.ergoplatform.utils.ErgoNodeTestConstants._ import org.ergoplatform.utils.ErgoCoreTestConstants._ - import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators._ import org.ergoplatform.utils.generators.ErgoCoreTransactionGenerators._ import org.ergoplatform.utils.generators.ValidBlocksGenerators._ diff --git a/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala b/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala index 6c609d30bc..c8f361d673 100644 --- a/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala +++ b/src/test/scala/org/ergoplatform/nodeView/state/UtxoStateSpecification.scala @@ -14,15 +14,17 @@ 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.utils.generators.ErgoNodeTransactionGenerators.boxesHolderGen 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 sigmastate.crypto.DLogProtocol.DLogProverInput +import sigma.interpreter.ProverResult import sigmastate.helpers.TestingHelpers._ import scala.concurrent.duration.Duration @@ -32,7 +34,6 @@ import scala.util.Try class UtxoStateSpecification extends ErgoCorePropertyTest with OptionValues { import org.ergoplatform.utils.ErgoNodeTestConstants._ import org.ergoplatform.utils.ErgoCoreTestConstants._ - import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators._ import org.ergoplatform.utils.generators.ErgoCoreTransactionGenerators._ import org.ergoplatform.utils.generators.ErgoCoreGenerators._ import org.ergoplatform.utils.generators.ValidBlocksGenerators._ @@ -51,7 +52,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 +96,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) diff --git a/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala b/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala index 99d126f685..e3c4c00638 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletServiceSpec.scala @@ -12,6 +12,7 @@ import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanR import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedSecretKey} import org.ergoplatform.settings.ErgoSettings import org.ergoplatform.utils.fixtures.WalletFixture +import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators.validErgoTransactionGen import org.ergoplatform.utils.{ErgoCorePropertyTest, MempoolTestHelpers, WalletTestOps} import org.ergoplatform.wallet.Constants.{PaymentsScanId, ScanId} import org.ergoplatform.wallet.boxes.BoxSelector.BoxSelectionResult @@ -23,10 +24,9 @@ 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.ast.{ByteArrayConstant, ErgoTree, EvaluatedValue, FalseLeaf, SType, TrueLeaf} +import sigma.Extensions.ArrayOps import sigmastate.helpers.TestingHelpers.testBox -import sigmastate.{SType, Values} import scala.collection.compat.immutable.ArraySeq import scala.util.Random @@ -43,7 +43,6 @@ class ErgoWalletServiceSpec import org.ergoplatform.utils.generators.ErgoNodeWalletGenerators._ import org.ergoplatform.utils.generators.CoreObjectGenerators._ import org.ergoplatform.utils.generators.ErgoCoreGenerators._ - import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators._ import org.ergoplatform.utils.generators.ErgoCoreTransactionGenerators._ override val ergoSettings: ErgoSettings = settings @@ -97,7 +96,7 @@ class ErgoWalletServiceSpec ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), creationOutIndex = 0, None, - testBox(1L, Values.TrueLeaf.toSigmaProp, 0), + testBox(1L, ErgoTree.fromProposition(TrueLeaf.toSigmaProp), 0), Set(PaymentsScanId) ) ) @@ -132,7 +131,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" diff --git a/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala b/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala index b646684250..b415042895 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/ErgoWalletSpec.scala @@ -17,10 +17,11 @@ import org.scalacheck.Gen import org.scalatest.concurrent.Eventually import scorex.util.ModifierId import scorex.util.encode.Base16 -import sigmastate.crypto.DLogProtocol.DLogProverInput +import sigma.ast.ErgoTree +import sigma.data.{CAND, CTHRESHOLD} import sigmastate.eval.Extensions._ -import sigmastate.eval._ -import sigmastate.{CAND, CTHRESHOLD} +import sigma.eval.Extensions.EvalIterableOps +import sigmastate.crypto.DLogProtocol.DLogProverInput import scala.concurrent.duration._ @@ -704,7 +705,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 +765,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 +932,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) @@ -1061,7 +1062,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu //pay out all the wallet balance: val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq 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 @@ -1098,7 +1099,7 @@ class ErgoWalletSpec extends ErgoCorePropertyTest with WalletTestOps with Eventu //pay out all the wallet balance: val assetToSpend = assetsByTokenId(boxesAvailable(genesisBlock, pubKey)).toSeq 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..cad46f9749 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/WalletScanLogicSpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/WalletScanLogicSpec.scala @@ -3,14 +3,14 @@ package org.ergoplatform.nodeView.wallet import org.ergoplatform.utils.{ErgoCorePropertyTest, WalletTestOps} import WalletScanLogic.{extractWalletOutputs, scanBlockTransactions} import org.ergoplatform.db.DBSpec -import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, Input} import org.ergoplatform.modifiers.mempool.ErgoTransaction import org.ergoplatform.nodeView.wallet.persistence.{OffChainRegistry, WalletRegistry} import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanRequest, ScanWalletInteraction} import org.ergoplatform.wallet.Constants import org.ergoplatform.wallet.Constants.ScanId +import org.ergoplatform.{ErgoBox, ErgoBoxCandidate, Input} import org.scalacheck.Gen -import sigmastate.Values.{ByteArrayConstant, ErgoTree, FalseLeaf, TrueLeaf} +import sigma.ast.{ByteArrayConstant, ErgoTree, FalseLeaf, TrueLeaf} import scala.util.Random @@ -43,11 +43,11 @@ class WalletScanLogicSpec extends ErgoCorePropertyTest with DBSpec with WalletTe 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(epk => ErgoTree.fromSigmaBoolean(epk.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(ErgoTree.fromProposition(FalseLeaf.toSigmaProp))) private def appPaymentsGen: Gen[List[ErgoTree]] = Gen.listOf(Gen.const(trueProp)) @@ -195,7 +195,13 @@ 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, + ErgoTree.fromProposition(FalseLeaf.toSigmaProp), + height1 + ) + ) val spendingTx2 = new ErgoTransaction(inputs2, IndexedSeq.empty, outputs2) val (r3, o3, f3) = @@ -242,7 +248,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,7 +272,7 @@ 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 trueProp = ErgoTree.fromProposition(TrueLeaf.toSigmaProp) val outs = IndexedSeq(new ErgoBoxCandidate(1000, trueProp, creationHeight = 1)) val tx = new ErgoTransaction(fakeInputs, IndexedSeq.empty, outs) 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..d4f3d0187c 100644 --- a/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/OffChainRegistrySpec.scala +++ b/src/test/scala/org/ergoplatform/nodeView/wallet/persistence/OffChainRegistrySpec.scala @@ -9,7 +9,7 @@ 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 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..1dcec88dac 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,9 @@ 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.Colls +import sigma.ast.ErgoTree +import sigma.interpreter.{ContextExtension, ProverResult} import scala.collection.compat.immutable.ArraySeq @@ -27,9 +28,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)]), + Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]), additionalRegisters, transactionId, boxIndex, creationHeight) } @@ -51,7 +51,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/FeeSimulator.scala b/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala index 9eebe3f4b7..218c6f4753 100644 --- a/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala +++ b/src/test/scala/org/ergoplatform/tools/FeeSimulator.scala @@ -7,10 +7,10 @@ import org.ergoplatform.{ErgoBoxCandidate, Input} import scorex.crypto.authds.ADKey import scorex.utils.Random import sigma.Colls +import sigma.ast.ErgoTree import sigmastate.crypto.DLogProtocol.DLogProverInput import sigmastate.eval.Extensions.ArrayByteOps -import sigmastate.eval._ -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigma.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/Stubs.scala b/src/test/scala/org/ergoplatform/utils/Stubs.scala index b63519caf1..1414789dae 100644 --- a/src/test/scala/org/ergoplatform/utils/Stubs.scala +++ b/src/test/scala/org/ergoplatform/utils/Stubs.scala @@ -9,6 +9,7 @@ import org.ergoplatform.mining.{AutolykosSolution, CandidateGenerator, ErgoMiner import org.ergoplatform.modifiers.ErgoFullBlock import org.ergoplatform.modifiers.history.header.Header import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnconfirmedTransaction} +import org.ergoplatform.network.peer.PeerManager.ReceivableMessages.{GetAllPeers, GetBlacklistedPeers} import org.ergoplatform.network.{Handshake, PeerSpec, Version} import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedTransaction import org.ergoplatform.nodeView.ErgoReadersHolder.{GetDataFromHistory, GetReaders, Readers} @@ -25,7 +26,9 @@ import org.ergoplatform.nodeView.wallet.scanning.Scan import org.ergoplatform.sanity.ErgoSanity.HT import org.ergoplatform.sdk.wallet.secrets.{DerivationPath, ExtendedSecretKey} import org.ergoplatform.settings.Constants.HashLength -import org.ergoplatform.settings.{ScorexSettings, _} +import org.ergoplatform.settings._ +import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators +import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators.{augWalletTransactionForScanGen, augWalletTransactionGen, boxesHolderGen} import org.ergoplatform.wallet.Constants.{PaymentsScanId, ScanId} import org.ergoplatform.wallet.boxes.{ChainStatus, TrackedBox} import org.ergoplatform.wallet.interface4j.SecretString @@ -34,12 +37,12 @@ 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 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._ @@ -49,7 +52,6 @@ trait Stubs extends ErgoTestHelpers with TestFileUtils { import org.ergoplatform.utils.ErgoNodeTestConstants._ import org.ergoplatform.utils.ErgoCoreTestConstants._ import org.ergoplatform.utils.generators.ChainGenerator._ - import org.ergoplatform.utils.generators.ErgoNodeTransactionGenerators._ import org.ergoplatform.utils.generators.ErgoCoreTransactionGenerators._ import org.ergoplatform.utils.generators.ErgoCoreGenerators._ import org.ergoplatform.utils.generators.CoreObjectGenerators._ @@ -63,7 +65,7 @@ trait Stubs extends ErgoTestHelpers with TestFileUtils { val history: HT = applyChain(generateHistory(), chain) val digestState: DigestState = { - boxesHolderGen.map(WrappedUtxoState(_, createTempDir, None, parameters, settings)).map { wus => + ErgoNodeTransactionGenerators.boxesHolderGen.map(WrappedUtxoState(_, createTempDir, None, parameters, settings)).map { wus => DigestState.create(Some(wus.version), Some(wus.rootDigest), createTempDir, settings) } }.sample.value diff --git a/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala b/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala index b4f6652c16..95e28abfe7 100644 --- a/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala +++ b/src/test/scala/org/ergoplatform/utils/WalletTestOps.scala @@ -17,12 +17,12 @@ 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 sigma.ast.ErgoTree +import sigma.data.ProveDlog import sigmastate.eval.Extensions._ -import sigmastate.eval._ -import sigmastate.interpreter.ProverResult +import sigma.interpreter.ProverResult import sigma.Extensions._ +import sigma.eval.Extensions.EvalIterableOps trait WalletTestOps extends NodeViewBaseOps { import org.ergoplatform.utils.ErgoNodeTestConstants._ diff --git a/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala b/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala index 089c52ba21..3930a45a83 100644 --- a/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala +++ b/src/test/scala/org/ergoplatform/utils/generators/ChainGenerator.scala @@ -14,9 +14,8 @@ import org.ergoplatform.utils.BoxUtils import scorex.crypto.authds.{ADKey, SerializedAdProof} import scorex.crypto.hash.Digest32 import sigma.Colls -import sigmastate.eval._ import sigmastate.helpers.TestingHelpers._ -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigma.interpreter.{ContextExtension, ProverResult} import scala.util.Random diff --git a/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeTransactionGenerators.scala b/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeTransactionGenerators.scala index 73b1362e77..d995abf542 100644 --- a/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeTransactionGenerators.scala +++ b/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeTransactionGenerators.scala @@ -1,5 +1,6 @@ package org.ergoplatform.utils.generators +import org.ergoplatform.ErgoBox.TokenId import org.ergoplatform.modifiers.mempool.{ErgoTransaction, UnsignedErgoTransaction} import org.ergoplatform.nodeView.state.wrapped.WrappedUtxoState import org.ergoplatform.nodeView.state.{BoxHolder, ErgoStateContext} @@ -11,14 +12,19 @@ import org.ergoplatform.utils.{BoxUtils, RandomLike, RandomWrapper} import org.ergoplatform.sdk.wallet.Constants.MaxAssetsPerBox import org.ergoplatform.wallet.interpreter.TransactionHintsBag import org.ergoplatform._ +import org.ergoplatform.nodeView.history.ErgoHistoryUtils.EmptyHistoryHeight import org.ergoplatform.wallet.Constants.ScanId +import org.ergoplatform.wallet.utils.WalletGenerators.{additionalRegistersGen, additionalTokensGen, boxIdGen, ergoBoxGen, validValueGen} 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 sigma.data.ProveDlog import sigmastate.eval.Extensions._ import sigmastate.helpers.TestingHelpers._ +import sigma.eval.Extensions.EvalIterableOps + import scala.collection.mutable import scala.util.Random @@ -28,6 +34,60 @@ object ErgoNodeTransactionGenerators extends ScorexLogging { import org.ergoplatform.utils.ErgoNodeTestConstants._ import org.ergoplatform.utils.generators.ErgoCoreTransactionGenerators._ + val creationHeightGen: Gen[Int] = Gen.choose(0, Int.MaxValue / 2) + + lazy val ergoBoxCandidateGen: Gen[ErgoBoxCandidate] = for { + h <- creationHeightGen + prop <- trueLeafGen + ar <- additionalRegistersGen + tokens <- additionalTokensGen + value <- validValueGen + } yield new ErgoBoxCandidate(value, prop, h, tokens.toColl, ar) + + def ergoAddressGen: Gen[ErgoAddress] = proveDlogGen.map(P2PKAddress.apply) + + def ergoBoxCandidateGen(prop: ProveDlog): Gen[ErgoBoxCandidate] = for { + h <- creationHeightGen + ar <- additionalRegistersGen + tokens <- additionalTokensGen + value <- validValueGen + } yield new ErgoBoxCandidate(value, ErgoTree.fromSigmaBoolean(prop), h, tokens.toColl, ar) + + lazy val ergoBoxGenNoProp: Gen[ErgoBox] = ergoBoxGen(propGen = trueLeafGen) + + def ergoBoxGenForTokens(tokens: Seq[(TokenId, Long)], + propositionGen: Gen[ErgoTree]): Gen[ErgoBox] = { + ergoBoxGen(propGen = propositionGen, tokensGen = Gen.oneOf(tokens, tokens), heightGen = EmptyHistoryHeight) + } + + def unspendableErgoBoxGen(minValue: Long = parameters.minValuePerByte * 200, + maxValue: Long = coinsTotal): Gen[ErgoBox] = { + ergoBoxGen(propGen = falseLeafGen, valueGenOpt = Some(Gen.choose(minValue, maxValue))) + } + + lazy val inputGen: Gen[Input] = for { + boxId <- boxIdGen + spendingProof <- noProofGen + } yield Input(boxId, spendingProof) + + lazy val dataInputGen: Gen[DataInput] = for { + boxId <- boxIdGen + } yield DataInput(boxId) + + lazy val reallySmallInt: Gen[Int] = Gen.choose(0, 3) + + lazy val invalidErgoTransactionGen: Gen[ErgoTransaction] = for { + from: IndexedSeq[Input] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, inputGen).map(_.toIndexedSeq)) + dataInputs: IndexedSeq[DataInput] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, dataInputGen).map(_.toIndexedSeq)) + to: IndexedSeq[ErgoBoxCandidate] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, ergoBoxCandidateGen).map(_.toIndexedSeq)) + } yield ErgoTransaction(from, dataInputs, to) + + def invalidErgoTransactionGen(prop: ProveDlog): Gen[ErgoTransaction] = for { + from: IndexedSeq[Input] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, inputGen).map(_.toIndexedSeq)) + dataInputs: IndexedSeq[DataInput] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, dataInputGen).map(_.toIndexedSeq)) + to: IndexedSeq[ErgoBoxCandidate] <- reallySmallInt.flatMap(i => Gen.listOfN(i + 1, ergoBoxCandidateGen(prop)).map(_.toIndexedSeq)) + } yield ErgoTransaction(from, dataInputs, to) + lazy val walletTransactionGen: Gen[WalletTransaction] = for { tx <- invalidErgoTransactionGen inclusionHeight <- Gen.posNum[Int] @@ -196,7 +256,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..561e6dadc9 100644 --- a/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeWalletGenerators.scala +++ b/src/test/scala/org/ergoplatform/utils/generators/ErgoNodeWalletGenerators.scala @@ -10,7 +10,7 @@ import org.ergoplatform.settings.Constants 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._ diff --git a/src/test/scala/scorex/testkit/properties/mempool/MempoolTransactionsTest.scala b/src/test/scala/scorex/testkit/properties/mempool/MempoolTransactionsTest.scala index 891c854c7e..c8ccb676bd 100644 --- a/src/test/scala/scorex/testkit/properties/mempool/MempoolTransactionsTest.scala +++ b/src/test/scala/scorex/testkit/properties/mempool/MempoolTransactionsTest.scala @@ -84,7 +84,7 @@ trait MempoolTransactionsTest property("Size of mempool should decrease when removing a present transaction") { forAll(memPoolGenerator, unconfirmedTxSeqGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction]) => val m: ErgoMemPool = mp.put(unconfirmedTxs) - val m2: ErgoMemPool = m.remove(unconfirmedTxs.headOption.get.transaction) + val m2: ErgoMemPool = m.removeTxAndDoubleSpends(unconfirmedTxs.headOption.get.transaction) m2.size shouldBe unconfirmedTxs.size - 1 } } @@ -92,7 +92,7 @@ trait MempoolTransactionsTest property("Size of mempool should not decrease when removing a non-present transaction") { forAll(memPoolGenerator, unconfirmedTxSeqGenerator, unconfirmedTxGenerator) { (mp: ErgoMemPool, unconfirmedTxs: Seq[UnconfirmedTransaction], unconfirmedTx: UnconfirmedTransaction) => val m: ErgoMemPool = mp.put(unconfirmedTxs) - val m2: ErgoMemPool = m.remove(unconfirmedTx.transaction) + val m2: ErgoMemPool = m.removeTxAndDoubleSpends(unconfirmedTx.transaction) m2.size shouldBe unconfirmedTxs.size } }