diff --git a/.github/workflows/check-pr.yaml b/.github/workflows/check-pr.yaml index d28aa2c3936..8ba1de3c422 100644 --- a/.github/workflows/check-pr.yaml +++ b/.github/workflows/check-pr.yaml @@ -17,19 +17,19 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' gpg-private-key: ${{ secrets.OSSRH_GPG_KEY }} gpg-passphrase: ${{ secrets.OSSRH_GPG_PASSPHRASE }} - uses: sbt/setup-sbt@v1 - name: Check PR - run: sbt -J-Xlog:gc*=debug:file=./gc.log --batch "scalafmtCheck;checkPR" - - if: always() - name: Fix test names and durations for Qase - run: | - find node/tests/target/test-reports -name "*.xml" -exec sed -E -i \ - -e 's/time="(0(\.0+)?|-0\.[0-9]+)"/time="0.001"/g' \ - -e 's/name="([^"]*)(NODE-[0-9]+ )([^"]*)"/name="\2 \1\3"/g' {} + + run: sbt -J-Xlog:gc*=debug:file=./gc.log --batch checkPR + #- if: always() + # name: Fix test names and durations for Qase + # run: | + # find node/tests/target/test-reports -name "*.xml" -exec sed -E -i \ + # -e 's/time="(0(\.0+)?|-0\.[0-9]+)"/time="0.001"/g' \ + # -e 's/name="([^"]*)(NODE-[0-9]+ )([^"]*)"/name="\2 \1\3"/g' {} + # Temporarily disabled because of 402 Payment Required # - uses: qase-tms/gh-actions/run-create@v1 # if: always() @@ -100,7 +100,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - uses: actions/download-artifact@v7 with: name: waves-fat-jar @@ -125,7 +125,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - uses: actions/download-artifact@v7 with: name: file-compiler @@ -140,7 +140,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' - uses: sbt/setup-sbt@v1 - name: Run Integration Tests @@ -174,7 +174,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' gpg-private-key: ${{ secrets.OSSRH_GPG_KEY }} gpg-passphrase: ${{ secrets.OSSRH_GPG_PASSPHRASE }} diff --git a/.github/workflows/on-push-default-branch.yml b/.github/workflows/on-push-default-branch.yml index 538f5b6ed13..a638ba51d55 100644 --- a/.github/workflows/on-push-default-branch.yml +++ b/.github/workflows/on-push-default-branch.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' - uses: sbt/setup-sbt@v1 - uses: scalacenter/sbt-dependency-submission@v3 @@ -28,7 +28,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' gpg-private-key: ${{ secrets.OSSRH_GPG_KEY }} gpg-passphrase: ${{ secrets.OSSRH_GPG_PASSPHRASE }} diff --git a/.github/workflows/on-release-published.yml b/.github/workflows/on-release-published.yml index c4f5a5919e5..03a377fa30d 100644 --- a/.github/workflows/on-release-published.yml +++ b/.github/workflows/on-release-published.yml @@ -61,7 +61,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' - uses: sbt/setup-sbt@v1 - run: sbt --batch 'buildRIDERunnerForDocker' @@ -106,7 +106,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' gpg-private-key: ${{ secrets.OSSRH_GPG_KEY }} gpg-passphrase: ${{ secrets.OSSRH_GPG_PASSPHRASE }} diff --git a/.github/workflows/prepare-release-draft.yml b/.github/workflows/prepare-release-draft.yml index 58c1af70713..6707d1a7ed3 100644 --- a/.github/workflows/prepare-release-draft.yml +++ b/.github/workflows/prepare-release-draft.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' - uses: sbt/setup-sbt@v1 - run: ./.github/workflows/prepare-release-draft.sh diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml index 1c35dcc3e99..faaa60011ef 100644 --- a/.github/workflows/publish-docker-image.yml +++ b/.github/workflows/publish-docker-image.yml @@ -67,7 +67,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' - uses: sbt/setup-sbt@v1 - name: Build tarballs for docker diff --git a/.github/workflows/publish-to-npmjs.yml b/.github/workflows/publish-to-npmjs.yml index 26f50111419..303ef5d7fb5 100644 --- a/.github/workflows/publish-to-npmjs.yml +++ b/.github/workflows/publish-to-npmjs.yml @@ -34,7 +34,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'sbt' - uses: sbt/setup-sbt@v1 - run: sbt -Dproject.version=${{ steps.ghd.outputs.describe }} --batch ';lang-tests/test;lang-tests-js/test;repl/test;langJS/fullOptJS;replJS/fullOptJS' diff --git a/benchmark/src/test/scala/com/wavesplatform/common/HashBenchmark.scala b/benchmark/src/test/scala/com/wavesplatform/common/HashBenchmark.scala index 7803a8ee57b..e9473407926 100644 --- a/benchmark/src/test/scala/com/wavesplatform/common/HashBenchmark.scala +++ b/benchmark/src/test/scala/com/wavesplatform/common/HashBenchmark.scala @@ -6,7 +6,7 @@ import com.wavesplatform.lang.v1.FunctionHeader.Native import com.wavesplatform.lang.v1.compiler.Terms.{CONST_BYTESTR, EXPR, FUNCTION_CALL} import com.wavesplatform.lang.v1.eval import com.wavesplatform.lang.v1.evaluator.FunctionIds -import org.openjdk.jmh.annotations.{Level as _, *} +import org.openjdk.jmh.annotations.* import org.openjdk.jmh.infra.Blackhole import java.util.concurrent.TimeUnit diff --git a/benchmark/src/test/scala/com/wavesplatform/common/MerkleBenchmark.scala b/benchmark/src/test/scala/com/wavesplatform/common/MerkleBenchmark.scala index 892e886f92d..a41342d9835 100644 --- a/benchmark/src/test/scala/com/wavesplatform/common/MerkleBenchmark.scala +++ b/benchmark/src/test/scala/com/wavesplatform/common/MerkleBenchmark.scala @@ -9,7 +9,7 @@ import com.wavesplatform.lang.v1.FunctionHeader.Native import com.wavesplatform.lang.v1.compiler.Terms.{ARR, CONST_BYTESTR, CONST_LONG, EXPR, FUNCTION_CALL} import com.wavesplatform.lang.v1.eval import com.wavesplatform.lang.v1.evaluator.FunctionIds -import org.openjdk.jmh.annotations.{Level as _, *} +import org.openjdk.jmh.annotations.* import org.openjdk.jmh.infra.Blackhole import java.util.concurrent.TimeUnit diff --git a/build.sbt b/build.sbt index fb5b2cf7559..cf7d9763ef3 100644 --- a/build.sbt +++ b/build.sbt @@ -150,7 +150,6 @@ lazy val `repl-js` = repl.js lazy val `curve25519-test` = project.dependsOn(node) lazy val `waves-node` = (project in file(".")) - .configs(Dependencies.DebArm64, Dependencies.DebAmd64) .aggregate( `lang-js`, `lang-jvm`, @@ -171,7 +170,7 @@ lazy val `waves-node` = (project in file(".")) inScope(Global)( Seq( - scalaVersion := "3.7.4", + scalaVersion := "3.8.1", organization := "com.wavesplatform", organizationName := "Waves Platform", organizationHomepage := Some(url("https://wavesplatform.com")), @@ -206,7 +205,7 @@ inScope(Global)( */ testOptions += Tests.Argument("-oIDOF", "-u", "target/test-reports"), testOptions += Tests.Setup(_ => sys.props("sbt-testing") = "true"), - network := Network.default(), + network := Network.default(), resolvers ++= Resolver.sonatypeCentralSnapshots +: Seq(Resolver.mavenLocal), Compile / packageDoc / publishArtifact := false, concurrentRestrictions := Seq(Tags.limit(Tags.Test, math.min(EvaluateTask.SystemProcessors, 8))), @@ -219,12 +218,8 @@ inScope(Global)( ) ) -lazy val packageAll = taskKey[Unit]("Package all artifacts") -packageAll := { - (node / assembly).value - (`ride-runner` / assembly).value - buildDebPackages.value - buildTarballsForDocker.value +commands += Command.command("packageAll"){ state => + "node / assembly" :: "ride-runner / assembly" :: "buildDebPackages" :: "buildTarballsForDocker" :: state } lazy val buildTarballsForDocker = taskKey[Unit]("Package node and grpc-server tarballs and copy them to docker/target") @@ -250,19 +245,9 @@ buildRIDERunnerForDocker := { lazy val compilePRRaw = taskKey[Unit]("Compile the project") compilePRRaw := Def .sequential( - clean, - Def.task { - (`lang-tests` / Test / compile).value - (`repl-jvm` / Test / compile).value - (`lang-tests-js` / Test / compile).value - (`grpc-server` / Test / compile).value - (`node-tests` / Test / compile).value - (`node-it` / Test / compile).value - (benchmark / Test / compile).value - (`node-generator` / Compile / compile).value - (`ride-runner` / Test / compile).value - (`lang-jvm` / Test / compile).value - } + clean.all(ScopeFilter(inAnyProject)), + scalafmtCheck.all(ScopeFilter(inAnyProject, inConfigurations(Compile))), + compile.all(ScopeFilter(inAnyProject, inConfigurations(Test))) ) .value @@ -270,19 +255,14 @@ lazy val checkPRRaw = taskKey[Unit]("Compile the project and run unit tests") checkPRRaw := Def .sequential( compilePRRaw, - Def.task { - (`lang-tests` / Test / test).value - (`repl-jvm` / Test / test).value - (`lang-js` / Compile / fullOptJS).value - (`lang-tests-js` / Test / test).value - (`grpc-server` / Test / test).value - (`node-tests` / Test / test).value - (`repl-js` / Compile / fullOptJS).value - (`ride-runner` / Test / test).value - (node / assembly).value - buildTarballsForDocker.value - (`lang-jvm` / assembly).value - } + Def.sequential( + test.all( + ScopeFilter(inProjects(`lang-tests`, `repl-jvm`, `lang-tests-js`, `grpc-server`, `node-tests`, `ride-runner`), inConfigurations(Test)) + ), + fullOptJS.all(ScopeFilter(inProjects(`lang-js`, `repl-js`), inConfigurations(Compile))), + assembly.all(ScopeFilter(inProjects(node, `lang-jvm`))), + buildTarballsForDocker + ) ) .value @@ -290,7 +270,7 @@ def commandWithFatalWarnings(commandName: String, task: TaskKey[Unit]): Command Command.command(commandName) { state => val extracted = Project.extract(state) val newState = extracted.appendWithoutSession( - Seq(Global / scalacOptions ++= Seq("-Xfatal-warnings")), + Seq(Global / scalacOptions ++= Seq("-Werror")), state ) @@ -298,18 +278,16 @@ def commandWithFatalWarnings(commandName: String, task: TaskKey[Unit]): Command state } -def compilePR = commandWithFatalWarnings("compilePR", compilePRRaw) -def checkPR = commandWithFatalWarnings("checkPR", checkPRRaw) +def compilePR: Command = commandWithFatalWarnings("compilePR", compilePRRaw) +def checkPR: Command = commandWithFatalWarnings("checkPR", checkPRRaw) -lazy val completeQaseRun = taskKey[Unit]("Complete Qase run") -completeQaseRun := Def.task { - (`lang-testkit` / Test / runMain).toTask(" com.wavesplatform.report.QaseRunCompleter").value -}.value - -lazy val buildDebPackages = taskKey[Unit]("Build DEB packages") -buildDebPackages := { - (`grpc-server` / Debian / packageBin).value - (node / Debian / packageBin).value +commands += Command.command("buildDebPackages") { state => + "set node / Debian / packageArchitecture := \"arm64\"" :: + "node/ Debian / packageBin" :: + "set node / Debian / packageArchitecture := \"amd64\"" :: + "node / Debian / packageBin" :: + "grpc-server / Debian / packageBin" :: + state } lazy val buildPlatformIndependentArtifacts = taskKey[Unit]("Build fat JARs for node and ride-runner and TGZ for grpc-server") @@ -319,20 +297,10 @@ buildPlatformIndependentArtifacts := { (`grpc-server` / Universal / packageZipTarball).value } -lazy val buildReleaseArtifacts: Command = Command("buildReleaseArtifacts")(_ => Network.networkParser) { (state, args) => - args.toSet[Network].foreach { n => - val newState = Project - .extract(state) - .appendWithoutSession( - Seq(Global / network := n), - state - ) - Project.extract(newState).runTask(buildDebPackages, newState) - } - - Project.extract(state).runTask(buildPlatformIndependentArtifacts, state) - - state +commands += Command("buildReleaseArtifacts")(_ => Network.networkParser) { (state, args) => + args.toSet[Network].toList.flatMap { n => + s"set Global / network := $n" :: "buildDebPackages" :: Nil + } ::: "buildPlatformIndependentArtifacts" :: state } /** Command: generateGenesis @@ -367,4 +335,4 @@ def generateGenesisCommand: Command = state } -commands ++= Seq(compilePR, checkPR, buildReleaseArtifacts, generateGenesisCommand) +commands ++= Seq(compilePR, checkPR, generateGenesisCommand) diff --git a/curve25519-test/src/main/scala/com/wavesplatform/curve25519/test/App.scala b/curve25519-test/src/main/scala/com/wavesplatform/curve25519/test/App.scala index ba8333c2975..65662cb15fc 100644 --- a/curve25519-test/src/main/scala/com/wavesplatform/curve25519/test/App.scala +++ b/curve25519-test/src/main/scala/com/wavesplatform/curve25519/test/App.scala @@ -1,16 +1,15 @@ package com.wavesplatform.curve25519.test -import java.io.* -import java.util -import java.util.concurrent.* -import java.util.concurrent.atomic.AtomicLong - import com.google.common.io.{BaseEncoding, CountingOutputStream} import com.google.common.primitives.{Bytes, Ints, Longs} import com.typesafe.scalalogging.StrictLogging import monix.execution.Scheduler import org.whispersystems.curve25519.{Curve25519Provider, JavaCurve25519Provider, NativeCurve25519Provider} +import java.io.* +import java.util +import java.util.concurrent.* +import java.util.concurrent.atomic.AtomicLong import scala.annotation.tailrec import scala.concurrent.duration.* import scala.reflect.ClassTag @@ -127,8 +126,8 @@ object App extends StrictLogging { ctor.newInstance().asInstanceOf[A] } - private val multiplier = 0x5DEECE66DL - private val addend = 0xBL + private val multiplier = 0x5deece66dL + private val addend = 0xbL private val mask = (1L << 48) - 1 private val MaxMessageLength = 150 * 1024 @@ -141,10 +140,10 @@ object App extends StrictLogging { val nv = (seqNr * multiplier + addend) & mask val value = nv << 32 | nv Bytes.concat( - Longs.toByteArray(value ^ (randomSeed & 0xF000F000F000F000L)), - Longs.toByteArray(value ^ (randomSeed & 0x0F000F000F000F00L)), - Longs.toByteArray(value ^ (randomSeed & 0x00F000F000F000F0L)), - Longs.toByteArray(value ^ (randomSeed & 0x000F000F000F000FL)) + Longs.toByteArray(value ^ (randomSeed & 0xf000f000f000f000L)), + Longs.toByteArray(value ^ (randomSeed & 0x0f000f000f000f00L)), + Longs.toByteArray(value ^ (randomSeed & 0x00f000f000f000f0L)), + Longs.toByteArray(value ^ (randomSeed & 0x000f000f000f000fL)) ) } @@ -231,7 +230,7 @@ object App extends StrictLogging { def main(args: Array[String]): Unit = { val nativeProvider = provider[NativeCurve25519Provider] val javaProvider = provider[JavaCurve25519Provider] - val latch = new CountDownLatch(workerCount) + val latch = new CountDownLatch(workerCount) args(0).toLowerCase match { case "verify" => @@ -323,11 +322,10 @@ object App extends StrictLogging { ) latch.await() - maybeOut.foreach { - case (out, writer, _) => - writer.join() - out.flush() - out.close() + maybeOut.foreach { case (out, writer, _) => + writer.join() + out.flush() + out.close() } } } diff --git a/lang/shared/src/main/scala/com/wavesplatform/lang/v1/compiler/Terms.scala b/lang/shared/src/main/scala/com/wavesplatform/lang/v1/compiler/Terms.scala index 51a4679e1a1..491c563cf7c 100644 --- a/lang/shared/src/main/scala/com/wavesplatform/lang/v1/compiler/Terms.scala +++ b/lang/shared/src/main/scala/com/wavesplatform/lang/v1/compiler/Terms.scala @@ -358,7 +358,7 @@ object Terms { else caseType - override def hashCode(): Int = MurmurHash3.productHash(this) + override def hashCode(): Int = MurmurHash3.caseClassHash(this) override def equals(obj: Any): Boolean = obj match { case CaseObj(`caseType`, `fields`) => true diff --git a/lang/shared/src/main/scala/com/wavesplatform/lang/v1/evaluator/ctx/impl/waves/Functions.scala b/lang/shared/src/main/scala/com/wavesplatform/lang/v1/evaluator/ctx/impl/waves/Functions.scala index 28303abbf8d..a698e52b261 100644 --- a/lang/shared/src/main/scala/com/wavesplatform/lang/v1/evaluator/ctx/impl/waves/Functions.scala +++ b/lang/shared/src/main/scala/com/wavesplatform/lang/v1/evaluator/ctx/impl/waves/Functions.scala @@ -16,7 +16,7 @@ import com.wavesplatform.lang.v1.evaluator.FunctionIds.* import com.wavesplatform.lang.v1.evaluator.ctx.impl.* import com.wavesplatform.lang.v1.evaluator.ctx.impl.EnvironmentFunctions.AddressLength import com.wavesplatform.lang.v1.evaluator.ctx.impl.converters.* -import com.wavesplatform.lang.v1.evaluator.ctx.impl.waves.Bindings.{scriptTransfer as _, *} +import com.wavesplatform.lang.v1.evaluator.ctx.impl.waves.Bindings.{buildAssetInfo, transactionObject} import com.wavesplatform.lang.v1.evaluator.ctx.impl.waves.Types.* import com.wavesplatform.lang.v1.evaluator.ctx.{BaseFunction, NativeFunction, UserFunction} import com.wavesplatform.lang.v1.evaluator.{ContextfulNativeFunction, ContextfulUserFunction, FunctionIds, Log} diff --git a/node-generator/src/main/scala/com/wavesplatform/generator/NarrowTransactionGenerator.scala b/node-generator/src/main/scala/com/wavesplatform/generator/NarrowTransactionGenerator.scala index d4f97802db2..6ac79b9c2a3 100644 --- a/node-generator/src/main/scala/com/wavesplatform/generator/NarrowTransactionGenerator.scala +++ b/node-generator/src/main/scala/com/wavesplatform/generator/NarrowTransactionGenerator.scala @@ -1,6 +1,7 @@ package com.wavesplatform.generator import cats.Show +import com.typesafe.scalalogging.Logger import com.wavesplatform.account.{Address, KeyPair, SeedKeyPair} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2.explicitGet @@ -24,7 +25,7 @@ import com.wavesplatform.transaction.smart.{InvokeScriptTransaction, SetScriptTr import com.wavesplatform.transaction.transfer.* import com.wavesplatform.transaction.transfer.MassTransferTransaction.ParsedTransfer import com.wavesplatform.transaction.utils.Signed -import com.wavesplatform.utils.{LoggerFacade, NTP} +import com.wavesplatform.utils.NTP import org.slf4j.LoggerFactory import org.web3j.crypto.Bip32ECKeyPair import pureconfig.ConfigReader @@ -48,7 +49,7 @@ class NarrowTransactionGenerator( ) extends TransactionGenerator { import NarrowTransactionGenerator.* - private val log = LoggerFacade(LoggerFactory.getLogger(getClass)) + private val log = Logger(LoggerFactory.getLogger(getClass)) private val typeGen = DistributedRandomGenerator(settings.probabilities) private def correctVersion(v: TxVersion): TxVersion = diff --git a/node-generator/src/main/scala/com/wavesplatform/generator/TransactionsGeneratorApp.scala b/node-generator/src/main/scala/com/wavesplatform/generator/TransactionsGeneratorApp.scala index 59eb2f2b164..b984c19c4d9 100644 --- a/node-generator/src/main/scala/com/wavesplatform/generator/TransactionsGeneratorApp.scala +++ b/node-generator/src/main/scala/com/wavesplatform/generator/TransactionsGeneratorApp.scala @@ -2,6 +2,7 @@ package com.wavesplatform.generator import cats.implicits.showInterpolator import com.typesafe.config.ConfigFactory +import com.typesafe.scalalogging.Logger import com.wavesplatform.Application import com.wavesplatform.account.AddressScheme import com.wavesplatform.features.EstimatorProvider.* @@ -11,7 +12,7 @@ import com.wavesplatform.generator.cli.ScoptImplicits import com.wavesplatform.generator.utils.Universe import com.wavesplatform.network.client.NetworkSender import com.wavesplatform.transaction.Transaction -import com.wavesplatform.utils.{LoggerFacade, NTP} +import com.wavesplatform.utils.NTP import monix.execution.Scheduler import org.asynchttpclient.AsyncHttpClient import org.asynchttpclient.Dsl.asyncHttpClient @@ -29,7 +30,7 @@ object TransactionsGeneratorApp extends ScoptImplicits { def main(args: Array[String]): Unit = { implicit val httpClient: AsyncHttpClient = asyncHttpClient() - val log = LoggerFacade(LoggerFactory.getLogger("generator")) + val log = Logger(LoggerFactory.getLogger("generator")) val parser = new OptionParser[GeneratorSettings]("generator") { head("TransactionsGenerator - Waves load testing transactions generator") diff --git a/node-generator/src/main/scala/com/wavesplatform/generator/utils/Gen.scala b/node-generator/src/main/scala/com/wavesplatform/generator/utils/Gen.scala index e63e577f421..2176bc2fa45 100644 --- a/node-generator/src/main/scala/com/wavesplatform/generator/utils/Gen.scala +++ b/node-generator/src/main/scala/com/wavesplatform/generator/utils/Gen.scala @@ -13,16 +13,12 @@ import com.wavesplatform.transaction.smart.script.ScriptCompiler import com.wavesplatform.transaction.transfer.* import com.wavesplatform.transaction.transfer.MassTransferTransaction.ParsedTransfer import com.wavesplatform.transaction.{Transaction, TxNonNegativeAmount} -import com.wavesplatform.utils.LoggerFacade -import org.slf4j.LoggerFactory import java.util.concurrent.ThreadLocalRandom object Gen { private def random = ThreadLocalRandom.current - val log = LoggerFacade(LoggerFactory.getLogger("Gen")) - def script(complexity: Boolean = true, estimator: ScriptEstimator): Script = { val s = if (complexity) s""" |${(for (b <- 1 to 10) yield { diff --git a/node-it/src/test/scala/com/wavesplatform/it/Node.scala b/node-it/src/test/scala/com/wavesplatform/it/Node.scala index d8be39b9c0a..b2aad4340d0 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/Node.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/Node.scala @@ -3,13 +3,13 @@ package com.wavesplatform.it import java.net.{InetSocketAddress, URL} import scala.concurrent.duration.FiniteDuration import com.typesafe.config.Config +import com.typesafe.scalalogging.Logger import com.wavesplatform.account.{KeyPair, PublicKey, SeedKeyPair} import com.wavesplatform.common.utils.EitherExt2.* import com.wavesplatform.it.util.GlobalTimer import com.wavesplatform.settings.WavesSettings import com.wavesplatform.state.diffs.FeeValidation import com.wavesplatform.transaction.TransactionType -import com.wavesplatform.utils.LoggerFacade import com.wavesplatform.wallet.Wallet import io.grpc.{ManagedChannel, ManagedChannelBuilder} import org.asynchttpclient.* @@ -17,8 +17,7 @@ import org.asynchttpclient.Dsl.{config as clientConfig, *} import org.slf4j.LoggerFactory abstract class Node(val config: Config) extends AutoCloseable { - lazy val log: LoggerFacade = - LoggerFacade(LoggerFactory.getLogger(this.name)) + lazy val log: Logger = Logger(LoggerFactory.getLogger(this.name)) val settings: WavesSettings = WavesSettings.fromRootConfig(config) val client: AsyncHttpClient = asyncHttpClient( diff --git a/node-it/src/test/scala/com/wavesplatform/it/ReportingTestName.scala b/node-it/src/test/scala/com/wavesplatform/it/ReportingTestName.scala index 0e53a7d621b..5374f39e944 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/ReportingTestName.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/ReportingTestName.scala @@ -1,9 +1,9 @@ package com.wavesplatform.it +import com.typesafe.scalalogging.Logger import com.wavesplatform.api.http.DebugMessage import com.wavesplatform.it.ReportingTestName.CaptureCancel import com.wavesplatform.it.api.AsyncHttpApi.* -import com.wavesplatform.utils.{LoggerFacade, ScorexLogging} import org.scalatest.events.* import org.scalatest.* import org.slf4j.LoggerFactory @@ -11,9 +11,9 @@ import org.slf4j.LoggerFactory import scala.concurrent.duration.* import scala.concurrent.{Await, Future} -trait ReportingTestName extends SuiteMixin with ScorexLogging { +trait ReportingTestName extends SuiteMixin { th: Suite & Nodes => - override protected lazy val log = LoggerFacade(LoggerFactory.getLogger("Test")) + private lazy val log = Logger(LoggerFactory.getLogger("Test")) abstract override protected def runTest(testName: String, args: Args): Status = { printTestWorkflow(s"Test '$testName' started") diff --git a/node-it/src/test/scala/com/wavesplatform/it/sync/finalization/OneNodeFinalizationTestSuite.scala b/node-it/src/test/scala/com/wavesplatform/it/sync/finalization/OneNodeFinalizationTestSuite.scala index 61cad0ad4ad..7b09d2b7a9d 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/sync/finalization/OneNodeFinalizationTestSuite.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/sync/finalization/OneNodeFinalizationTestSuite.scala @@ -8,12 +8,13 @@ import com.wavesplatform.it.api.SyncHttpApi.* import com.wavesplatform.it.{BaseFreeSpec, NodeConfigs} import com.wavesplatform.state.Height import com.wavesplatform.test.NumericExt +import com.wavesplatform.utils.ScorexLogging import org.apache.pekko.http.scaladsl.model.StatusCodes import org.scalatest.OptionValues import scala.concurrent.duration.DurationInt -class OneNodeFinalizationTestSuite extends BaseFreeSpec with OptionValues { +class OneNodeFinalizationTestSuite extends BaseFreeSpec, OptionValues, ScorexLogging { override protected def nodeConfigs: Seq[Config] = NodeConfigs.newBuilder .overrideBase(_.quorum(0)) diff --git a/node-it/src/test/scala/com/wavesplatform/it/sync/finalization/TwoNodesFinalizationTestSuite.scala b/node-it/src/test/scala/com/wavesplatform/it/sync/finalization/TwoNodesFinalizationTestSuite.scala index f4aaf0f8d36..00288b390a1 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/sync/finalization/TwoNodesFinalizationTestSuite.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/sync/finalization/TwoNodesFinalizationTestSuite.scala @@ -8,11 +8,12 @@ import com.wavesplatform.it.api.SyncHttpApi.* import com.wavesplatform.it.{BaseFreeSpec, NodeConfigs} import com.wavesplatform.state.Height import com.wavesplatform.test.NumericExt +import com.wavesplatform.utils.ScorexLogging import org.scalatest.OptionValues import scala.concurrent.duration.DurationInt -class TwoNodesFinalizationTestSuite extends BaseFreeSpec with OptionValues { +class TwoNodesFinalizationTestSuite extends BaseFreeSpec, OptionValues, ScorexLogging { override protected def nodeConfigs: Seq[Config] = NodeConfigs.newBuilder .overrideBase(_.preactivatedFeatures((BlockchainFeatures.DeterministicFinality.id, Height(0)))) diff --git a/node-it/src/test/scala/com/wavesplatform/it/sync/network/NetworkSeparationTestSuite.scala b/node-it/src/test/scala/com/wavesplatform/it/sync/network/NetworkSeparationTestSuite.scala index ed1cfed49a6..47e971199b5 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/sync/network/NetworkSeparationTestSuite.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/sync/network/NetworkSeparationTestSuite.scala @@ -5,11 +5,12 @@ import com.wavesplatform.it.api.SyncHttpApi.* import com.wavesplatform.it.sync.{issueAmount, issueFee, minFee} import com.wavesplatform.it.{BaseFreeSpec, Node, WaitForHeight2} import com.wavesplatform.state.Height +import com.wavesplatform.utils.ScorexLogging import scala.concurrent.Await import scala.concurrent.duration.* -class NetworkSeparationTestSuite extends BaseFreeSpec with WaitForHeight2 { +class NetworkSeparationTestSuite extends BaseFreeSpec, WaitForHeight2, ScorexLogging { import NetworkSeparationTestSuite.* override protected def nodeConfigs: Seq[Config] = Configs diff --git a/node/build.sbt b/node/build.sbt index 0a40b7d8c03..944f4224268 100644 --- a/node/build.sbt +++ b/node/build.sbt @@ -14,7 +14,7 @@ enablePlugins( libraryDependencies ++= Dependencies.node.value instrumentation := false -debArchitecture := Amd64 +debArchitecture := Arm64 javaAgents ++= { if (instrumentation.value) { @@ -161,14 +161,14 @@ inConfig(Debian)( maintainer := "com.wavesplatform", packageSource := sourceDirectory.value / "package", linuxStartScriptTemplate := (packageSource.value / "systemd.service").toURI.toURL, - debianPackageDependencies += "java11-runtime-headless", + debianPackageDependencies += "java17-runtime-headless", maintainerScripts := maintainerScriptsFromDirectory(packageSource.value / "debian", Seq("postinst", "postrm", "prerm")), linuxPackageMappings := { val classifier = if (packageArchitecture.value == "amd64") "linux-x86_64" else "linux-aarch_64" val platformSpecificMappings = packageMapping( (Optional / update).value .select(artifactFilter(classifier = classifier)) - .map(_ -> (defaultLinuxInstallLocation.value + "/" + (Debian / packageName).value)): _* + .map(f => f -> (defaultLinuxInstallLocation.value + "/" + (Debian / packageName).value + "/lib/software.amazon.cryptools." + f.getName)): _* ) linuxPackageMappings.value.map(m => diff --git a/node/src/main/scala/com/wavesplatform/Application.scala b/node/src/main/scala/com/wavesplatform/Application.scala index b8dae1de368..2a72e591939 100644 --- a/node/src/main/scala/com/wavesplatform/Application.scala +++ b/node/src/main/scala/com/wavesplatform/Application.scala @@ -4,6 +4,7 @@ import cats.Eq import cats.instances.bigInt.* import cats.syntax.option.* import com.typesafe.config.* +import com.typesafe.scalalogging.Logger import com.wavesplatform.account.AddressScheme import com.wavesplatform.actor.RootActorSystem import com.wavesplatform.api.BlockMeta @@ -130,7 +131,7 @@ class Application(val actorSystem: ActorSystem, val settings: WavesSettings, con maybeUtx = Some(utxStorage) val timer = new HashedWheelTimer() - val utxSynchronizerLogger = LoggerFacade(LoggerFactory.getLogger(classOf[TransactionPublisher])) + val utxSynchronizerLogger = Logger(LoggerFactory.getLogger(classOf[TransactionPublisher])) val timedTxValidator = Schedulers.timeBoundedFixedPool( timer, @@ -673,7 +674,7 @@ object Application extends ScorexLogging { import com.wavesplatform.settings.Constants val settings = loadApplicationConfig(configFile.map(new File(_))) - val log = LoggerFacade(LoggerFactory.getLogger(getClass)) + val log = Logger(LoggerFactory.getLogger(getClass)) val modeInfo = if (settings.enableLightMode) "in light mode" else "in full mode" log.info(s"Starting $modeInfo...") sys.addShutdownHook { diff --git a/node/src/main/scala/com/wavesplatform/api/http/CompositeHttpService.scala b/node/src/main/scala/com/wavesplatform/api/http/CompositeHttpService.scala index 000abdfee67..aa88144e1d6 100644 --- a/node/src/main/scala/com/wavesplatform/api/http/CompositeHttpService.scala +++ b/node/src/main/scala/com/wavesplatform/api/http/CompositeHttpService.scala @@ -45,7 +45,7 @@ case class CompositeHttpService(routes: Seq[ApiRoute], settings: RestAPISettings private val CorsAllowAllOrigin = "origin-from-request" private def logRequestResponse(req: HttpRequest): PartialFunction[RouteResult, RouteResult] = { case r @ Complete(resp) => - log.logger + log.underlying .atLevel(if (resp.status == StatusCodes.OK) Level.INFO else Level.WARN) .log { () => s"HTTP ${resp.status.value} from ${req.method.value} ${req.uri}${req.attribute(requestTimestamp).fold("")(ts => f" in ${(System.nanoTime() - ts) * 1e-6}%.3f ms")}" diff --git a/node/src/main/scala/com/wavesplatform/database/Keys.scala b/node/src/main/scala/com/wavesplatform/database/Keys.scala index 766f8ab2f25..86d8bf1ad5b 100644 --- a/node/src/main/scala/com/wavesplatform/database/Keys.scala +++ b/node/src/main/scala/com/wavesplatform/database/Keys.scala @@ -251,18 +251,18 @@ object Keys { historyKey(MaliciousMinerBanHeights, addressBytes) // Writes only after DeterministicFinality activation - val finalizedHeight: Key[Option[Height]] = Key.opt( + val finalizedHeight: Key[Option[Height]] = Key( FinalizedBlockHeight, Array.emptyByteArray, - bytes => com.wavesplatform.state.Height(Ints.fromByteArray(bytes)), - _.toByteArray + bytes => Option(bytes).collect { case bs if bs.length == Ints.BYTES => com.wavesplatform.state.Height(Ints.fromByteArray(bytes)) }, + _.fold(Array.emptyByteArray)(_.toByteArray) ) - def finalizedHeightAt(at: Height): Key[Option[Height]] = Key.opt( + def finalizedHeightAt(at: Height): Key[Option[Height]] = Key( FinalizedBlockHeightAt, h(at), - bytes => com.wavesplatform.state.Height(Ints.fromByteArray(bytes)), - _.toByteArray + bytes => Option(bytes).collect { case bs if bs.length == Ints.BYTES => com.wavesplatform.state.Height(Ints.fromByteArray(bytes)) }, + _.fold(Array.emptyByteArray)(_.toByteArray) ) /** Key: Int(committedPeriod.start) ++ Int(commitmentHeight) diff --git a/node/src/main/scala/com/wavesplatform/database/RocksDBWriter.scala b/node/src/main/scala/com/wavesplatform/database/RocksDBWriter.scala index e8da17e2c31..d44d6303264 100644 --- a/node/src/main/scala/com/wavesplatform/database/RocksDBWriter.scala +++ b/node/src/main/scala/com/wavesplatform/database/RocksDBWriter.scala @@ -6,6 +6,7 @@ import com.google.common.collect.MultimapBuilder import com.google.common.hash.{BloomFilter, Funnels} import com.google.common.primitives.Ints import com.google.common.util.concurrent.MoreExecutors +import com.typesafe.scalalogging.Logger import com.wavesplatform.account.{Address, Alias, PublicKey} import com.wavesplatform.api.common.WavesBalanceIterator import com.wavesplatform.block.Block.BlockId @@ -34,7 +35,7 @@ import com.wavesplatform.transaction.lease.{LeaseCancelTransaction, LeaseTransac import com.wavesplatform.transaction.smart.{InvokeExpressionTransaction, InvokeScriptTransaction, SetScriptTransaction} import com.wavesplatform.transaction.transfer.* import com.wavesplatform.transaction.{CommitToGenerationTransaction, *} -import com.wavesplatform.utils.{LoggerFacade, ScorexLogging} +import com.wavesplatform.utils.ScorexLogging import io.netty.util.concurrent.DefaultThreadFactory import org.rocksdb.Status import org.slf4j.LoggerFactory @@ -160,7 +161,7 @@ class RocksDBWriter( with AutoCloseable { import rdb.db as writableDB - private val log = LoggerFacade(LoggerFactory.getLogger(classOf[RocksDBWriter])) + private val log = Logger(LoggerFactory.getLogger(classOf[RocksDBWriter])) private var disabledAliases = writableDB.get(Keys.disabledAliases) diff --git a/node/src/main/scala/com/wavesplatform/metrics/Instrumented.scala b/node/src/main/scala/com/wavesplatform/metrics/Instrumented.scala index 99b1be3c6b4..ddbbd3058d5 100644 --- a/node/src/main/scala/com/wavesplatform/metrics/Instrumented.scala +++ b/node/src/main/scala/com/wavesplatform/metrics/Instrumented.scala @@ -1,6 +1,6 @@ package com.wavesplatform.metrics -import com.wavesplatform.utils.LoggerFacade +import com.typesafe.scalalogging.Logger import kamon.metric.{MeasurementUnit, Metric} object Instrumented { @@ -18,7 +18,7 @@ object Instrumented { (result, nanos / NanosInMS) } - def logMeasure[R](log: LoggerFacade, action: String)(f: => R): R = { + def logMeasure[R](log: Logger, action: String)(f: => R): R = { val (result, time) = Instrumented.withTimeMillis(f) log.trace(s"$action took ${time}ms") result diff --git a/node/src/main/scala/com/wavesplatform/network/PeerDatabaseImpl.scala b/node/src/main/scala/com/wavesplatform/network/PeerDatabaseImpl.scala index 072f2073581..4efc138144a 100644 --- a/node/src/main/scala/com/wavesplatform/network/PeerDatabaseImpl.scala +++ b/node/src/main/scala/com/wavesplatform/network/PeerDatabaseImpl.scala @@ -128,7 +128,9 @@ class PeerDatabaseImpl(settings: NetworkSettings, ticker: Ticker = Ticker.system val selectedNextUnverified = nextUnverified() - val randomKnownPeer = Random.shuffle(knownPeers.keySet.filterNot(excludeAddress)).headOption + val filteredKnownPeers = knownPeers.keySet.filterNot(excludeAddress) + val randomKnownPeer = + (if (filteredKnownPeers.size > 1) filteredKnownPeers.view.drop(Random.nextInt(filteredKnownPeers.size)) else filteredKnownPeers).headOption val selectedCandidate = resolvedPeersFromConfig .filterNot(excludeAddress) diff --git a/node/src/main/scala/com/wavesplatform/state/appender/package.scala b/node/src/main/scala/com/wavesplatform/state/appender/package.scala index 0258d879808..1aa74761c31 100644 --- a/node/src/main/scala/com/wavesplatform/state/appender/package.scala +++ b/node/src/main/scala/com/wavesplatform/state/appender/package.scala @@ -3,6 +3,7 @@ package com.wavesplatform.state import cats.instances.seq.* import cats.syntax.either.* import cats.syntax.traverse.* +import com.typesafe.scalalogging.Logger import com.wavesplatform.account.{Address, PublicKey} import com.wavesplatform.block.{Block, BlockEndorsement, BlockSnapshot, FinalizationVoting} import com.wavesplatform.common.state.ByteStr @@ -18,7 +19,7 @@ import com.wavesplatform.state.BlockchainUpdaterImpl.BlockApplyResult import com.wavesplatform.state.BlockchainUpdaterImpl.BlockApplyResult.Applied import com.wavesplatform.transaction.* import com.wavesplatform.transaction.TxValidationError.{BlockAppendError, BlockFromFuture, GenericError} -import com.wavesplatform.utils.{LoggerFacade, Time} +import com.wavesplatform.utils.Time import com.wavesplatform.utx.UtxPool import kamon.Kamon @@ -85,7 +86,7 @@ package object appender { utx: UtxPool, pos: PoSSelector, time: Time, - log: LoggerFacade, + log: Logger, verify: Boolean, txSignParCheck: Boolean )(block: Block, snapshot: Option[BlockSnapshotResponse]): Either[ValidationError, BlockApplyResult] = @@ -159,7 +160,7 @@ package object appender { utx: UtxPool, pos: PoSSelector, time: Time, - log: LoggerFacade, + log: Logger, verify: Boolean, txSignParCheck: Boolean )(block: Block, snapshot: Option[BlockSnapshotResponse]): Either[ValidationError, BlockApplyResult] = diff --git a/node/src/main/scala/com/wavesplatform/transaction/assets/exchange/EthOrders.scala b/node/src/main/scala/com/wavesplatform/transaction/assets/exchange/EthOrders.scala index f0753731cc6..be88b37b59e 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/assets/exchange/EthOrders.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/assets/exchange/EthOrders.scala @@ -12,7 +12,7 @@ import org.web3j.crypto.Sign.SignatureData import org.web3j.crypto.{ECDSASignature, ECKeyPair, Sign, StructuredDataEncoder} import play.api.libs.json.{JsObject, Json} -object EthOrders extends App { +object EthOrders { private lazy val toSnakeCase = CaseFormat.UPPER_CAMEL.converterTo(CaseFormat.UPPER_UNDERSCORE) def toEip712Json(order: Order): JsObject = { diff --git a/node/src/main/scala/com/wavesplatform/transaction/smart/Verifier.scala b/node/src/main/scala/com/wavesplatform/transaction/smart/Verifier.scala index f1f9890b977..dec313d1899 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/smart/Verifier.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/smart/Verifier.scala @@ -160,9 +160,9 @@ object Verifier extends ScorexLogging { execResult: Either[String, EVALUATED] ): Unit = result match { - case Left(_) if log.logger.isDebugEnabled => log.debug(buildLogs(id, execLog, execResult)) - case _ if log.logger.isTraceEnabled => log.trace(buildLogs(id, execLog, execResult)) - case _ => () + case Left(_) if log.underlying.isDebugEnabled => log.debug(buildLogs(id, execLog, execResult)) + case _ if log.underlying.isTraceEnabled => log.trace(buildLogs(id, execLog, execResult)) + case _ => () } private def verifyTx( diff --git a/node/src/main/scala/com/wavesplatform/utils/ScorexLogging.scala b/node/src/main/scala/com/wavesplatform/utils/ScorexLogging.scala index aa88149c617..319e813f7e3 100644 --- a/node/src/main/scala/com/wavesplatform/utils/ScorexLogging.scala +++ b/node/src/main/scala/com/wavesplatform/utils/ScorexLogging.scala @@ -1,69 +1,13 @@ package com.wavesplatform.utils +import com.typesafe.scalalogging.Logger import monix.eval.Task import monix.execution.{CancelableFuture, Scheduler} import monix.reactive.Observable -import org.slf4j.{Logger, LoggerFactory} - -case class LoggerFacade(logger: Logger) { - def trace(message: => String, throwable: Throwable): Unit = { - if (logger.isTraceEnabled) - logger.trace(message, throwable) - } - - def trace(message: => String): Unit = { - if (logger.isTraceEnabled) - logger.trace(message) - } - - def debug(message: => String, arg: Any): Unit = { - if (logger.isDebugEnabled) - logger.debug(message, arg) - } - - def debug(message: => String): Unit = { - if (logger.isDebugEnabled) - logger.debug(message) - } - - def info(message: => String): Unit = { - if (logger.isInfoEnabled) - logger.info(message) - } - - def info(message: => String, arg: Any): Unit = { - if (logger.isInfoEnabled) - logger.info(message, arg) - } - - def info(message: => String, throwable: Throwable): Unit = { - if (logger.isInfoEnabled) - logger.info(message, throwable) - } - - def warn(message: => String): Unit = { - if (logger.isWarnEnabled) - logger.warn(message) - } - - def warn(message: => String, throwable: Throwable): Unit = { - if (logger.isWarnEnabled) - logger.warn(message, throwable) - } - - def error(message: => String): Unit = { - if (logger.isErrorEnabled) - logger.error(message) - } - - def error(message: => String, throwable: Throwable): Unit = { - if (logger.isErrorEnabled) - logger.error(message, throwable) - } -} +import org.slf4j.LoggerFactory trait ScorexLogging { - protected lazy val log = LoggerFacade(LoggerFactory.getLogger(this.getClass)) + protected lazy val log = Logger(LoggerFactory.getLogger(this.getClass)) implicit class TaskExt[A](t: Task[A]) { def runAsyncLogErr(implicit s: Scheduler): CancelableFuture[A] = diff --git a/node/src/main/scala/com/wavesplatform/utx/UtxPoolImpl.scala b/node/src/main/scala/com/wavesplatform/utx/UtxPoolImpl.scala index a20b737e7b9..1d3e1dec2c6 100644 --- a/node/src/main/scala/com/wavesplatform/utx/UtxPoolImpl.scala +++ b/node/src/main/scala/com/wavesplatform/utx/UtxPoolImpl.scala @@ -1,6 +1,7 @@ package com.wavesplatform.utx import cats.implicits.catsSyntaxSemigroup +import com.typesafe.scalalogging.Logger import com.wavesplatform.ResponsivenessLogs import com.wavesplatform.account.Address import com.wavesplatform.common.state.ByteStr @@ -23,7 +24,7 @@ import com.wavesplatform.transaction.assets.exchange.ExchangeTransaction import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.smart.script.trace.TracedResult import com.wavesplatform.transaction.transfer.* -import com.wavesplatform.utils.{LoggerFacade, Schedulers, ScorexLogging, Time} +import com.wavesplatform.utils.{Schedulers, ScorexLogging, Time} import com.wavesplatform.utx.UtxPool.PackStrategy import kamon.Kamon import kamon.metric.MeasurementUnit @@ -477,7 +478,7 @@ case class UtxPoolImpl( (packResult.transactions.map(_.reverse), packResult.constraint, packResult.stateHash) } - private val traceLogger = LoggerFacade(LoggerFactory.getLogger(this.getClass.getCanonicalName + ".trace")) + private val traceLogger = Logger(LoggerFactory.getLogger(this.getClass.getCanonicalName + ".trace")) traceLogger.trace("Validation trace reporting is enabled") @scala.annotation.tailrec diff --git a/node/testkit/src/main/scala/com/wavesplatform/test/CatchLogs.scala b/node/testkit/src/main/scala/com/wavesplatform/test/CatchLogs.scala index 6385c8230f6..771000b18db 100644 --- a/node/testkit/src/main/scala/com/wavesplatform/test/CatchLogs.scala +++ b/node/testkit/src/main/scala/com/wavesplatform/test/CatchLogs.scala @@ -11,7 +11,7 @@ trait CatchLogs { this: ScorexLogging => import ch.qos.logback.classic.Logger val inMemoryLog = { - val logger = log.logger.asInstanceOf[Logger] + val logger = log.underlying.asInstanceOf[Logger] val r = new InMemoryAppender() r.setContext(logger.getLoggerContext) r.start() diff --git a/node/tests/src/test/scala/com/wavesplatform/features/FeatureProviderTest.scala b/node/tests/src/test/scala/com/wavesplatform/features/FeatureProviderTest.scala index d3935e595a2..d2e6086e55b 100644 --- a/node/tests/src/test/scala/com/wavesplatform/features/FeatureProviderTest.scala +++ b/node/tests/src/test/scala/com/wavesplatform/features/FeatureProviderTest.scala @@ -4,10 +4,10 @@ import com.wavesplatform.block.Block import com.wavesplatform.settings.{BlockchainSettings, FunctionalitySettings, GenesisSettings, RewardsSettings} import com.wavesplatform.state.{Blockchain, Height} import com.wavesplatform.test.FlatSpec +import com.wavesplatform.utils.EmptyBlockchain import org.scalacheck.Gen -import org.scalamock.scalatest.MockFactory -class FeatureProviderTest extends FlatSpec with MockFactory { +class FeatureProviderTest extends FlatSpec { "blockVersionAt" should "return valid version" in { val fs = FunctionalitySettings.MAINNET val v3ActivationHeight = Height(fs.blockVersion3AfterHeight) @@ -24,10 +24,11 @@ class FeatureProviderTest extends FlatSpec with MockFactory { BlockchainFeatures.BlockV5.id -> v5ActivationHeight ) - val blockchain = mock[Blockchain] - (() => blockchain.height).expects().anyNumberOfTimes().returning(1) - (() => blockchain.activatedFeatures).expects().anyNumberOfTimes().returning(features) - (() => blockchain.settings).expects().anyNumberOfTimes().returning(BlockchainSettings('W', fs, GenesisSettings.MAINNET, RewardsSettings.MAINNET)) + val blockchain = new EmptyBlockchain { + override def height: Int = 1 + override def activatedFeatures: Map[Short, Height] = features + override lazy val settings: BlockchainSettings = BlockchainSettings('W', fs, GenesisSettings.MAINNET, RewardsSettings.MAINNET) + } forAll(Gen.choose(1, v5ActivationHeight.toInt * 2)) { h => if (h == genesisAt) blockchain.blockVersionAt(h) shouldBe Block.GenesisBlockVersion diff --git a/node/tests/src/test/scala/com/wavesplatform/finalization/BlockEndorsementBroadcastAfterFinalizationSpec.scala b/node/tests/src/test/scala/com/wavesplatform/finalization/BlockEndorsementBroadcastAfterFinalizationSpec.scala index c0a33f88626..7fcbb33b04a 100644 --- a/node/tests/src/test/scala/com/wavesplatform/finalization/BlockEndorsementBroadcastAfterFinalizationSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/finalization/BlockEndorsementBroadcastAfterFinalizationSpec.scala @@ -19,7 +19,6 @@ import com.wavesplatform.wallet.Wallet import io.netty.channel.embedded.EmbeddedChannel import io.netty.channel.group.DefaultChannelGroup import io.netty.util.concurrent.GlobalEventExecutor -import monix.eval.Task import monix.execution.Scheduler.Implicits.global import monix.execution.schedulers.SchedulerService import org.scalactic.source.Position diff --git a/node/tests/src/test/scala/com/wavesplatform/finalization/ChallengingAfterFinalizationSuite.scala b/node/tests/src/test/scala/com/wavesplatform/finalization/ChallengingAfterFinalizationSuite.scala index 45a55790c06..f9aee0aa3af 100644 --- a/node/tests/src/test/scala/com/wavesplatform/finalization/ChallengingAfterFinalizationSuite.scala +++ b/node/tests/src/test/scala/com/wavesplatform/finalization/ChallengingAfterFinalizationSuite.scala @@ -6,7 +6,6 @@ import com.wavesplatform.crypto.DigestLength import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.history.Domain -import com.wavesplatform.settings.* import com.wavesplatform.state.* import com.wavesplatform.test.DomainPresets.WavesSettingsOps import com.wavesplatform.test.{FreeSpec, TestSchedulerOps} diff --git a/node/tests/src/test/scala/com/wavesplatform/finalization/FinalizationSuite.scala b/node/tests/src/test/scala/com/wavesplatform/finalization/FinalizationSuite.scala index 575f000b09c..9b2488aaed6 100644 --- a/node/tests/src/test/scala/com/wavesplatform/finalization/FinalizationSuite.scala +++ b/node/tests/src/test/scala/com/wavesplatform/finalization/FinalizationSuite.scala @@ -1,6 +1,6 @@ package com.wavesplatform.finalization -import com.wavesplatform.block.{Block, FinalizationVoting} +import com.wavesplatform.block.Block import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.history.Domain diff --git a/node/tests/src/test/scala/com/wavesplatform/finalization/MinerWithFinalitySuite.scala b/node/tests/src/test/scala/com/wavesplatform/finalization/MinerWithFinalitySuite.scala index a92f4aefaff..e9ad5cb4465 100644 --- a/node/tests/src/test/scala/com/wavesplatform/finalization/MinerWithFinalitySuite.scala +++ b/node/tests/src/test/scala/com/wavesplatform/finalization/MinerWithFinalitySuite.scala @@ -10,7 +10,6 @@ import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.history.Domain import com.wavesplatform.mining.{Miner, MinerImpl} import com.wavesplatform.network.EndorseBlock -import com.wavesplatform.settings.* import com.wavesplatform.state.* import com.wavesplatform.test.DomainPresets.WavesSettingsOps import com.wavesplatform.test.{CatchLogs, FreeSpec, NumericExt, TestSchedulerOps, TestTime} diff --git a/node/tests/src/test/scala/com/wavesplatform/finalization/MultipleAccountsMinerWithFinalitySuite.scala b/node/tests/src/test/scala/com/wavesplatform/finalization/MultipleAccountsMinerWithFinalitySuite.scala index ca6725cda3a..b626e54c504 100644 --- a/node/tests/src/test/scala/com/wavesplatform/finalization/MultipleAccountsMinerWithFinalitySuite.scala +++ b/node/tests/src/test/scala/com/wavesplatform/finalization/MultipleAccountsMinerWithFinalitySuite.scala @@ -5,7 +5,6 @@ import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.history.Domain import com.wavesplatform.mining.{Miner, MinerImpl} -import com.wavesplatform.settings.* import com.wavesplatform.state.* import com.wavesplatform.test.DomainPresets.WavesSettingsOps import com.wavesplatform.test.{CatchLogs, FreeSpec, NumericExt, TestSchedulerOps, TestTime} diff --git a/node/tests/src/test/scala/com/wavesplatform/http/SpentComplexitySpec.scala b/node/tests/src/test/scala/com/wavesplatform/http/SpentComplexitySpec.scala index 6d8cf7b0bb0..7273950ffd9 100644 --- a/node/tests/src/test/scala/com/wavesplatform/http/SpentComplexitySpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/http/SpentComplexitySpec.scala @@ -16,7 +16,6 @@ import com.wavesplatform.transaction.transfer.TransferTransaction import com.wavesplatform.transaction.utils.Signed import com.wavesplatform.utils.SharedSchedulerMixin import com.wavesplatform.{BlockGen, TestWallet} -import org.scalamock.scalatest.MockFactory import org.scalatest.OptionValues import play.api.libs.json.JsObject @@ -25,7 +24,6 @@ import scala.concurrent.duration.* class SpentComplexitySpec extends RouteSpec("/transactions") with RestAPISettingsHelper - with MockFactory with BlockGen with OptionValues with TestWallet diff --git a/node/tests/src/test/scala/com/wavesplatform/http/TransactionBroadcastSpec.scala b/node/tests/src/test/scala/com/wavesplatform/http/TransactionBroadcastSpec.scala index 4a80866fa5d..4b4aa8cc9c7 100644 --- a/node/tests/src/test/scala/com/wavesplatform/http/TransactionBroadcastSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/http/TransactionBroadcastSpec.scala @@ -1,8 +1,6 @@ package com.wavesplatform.http -import com.wavesplatform.transaction.assets.exchange.* import com.wavesplatform.account.{AddressScheme, KeyPair} -import com.wavesplatform.api.common.CommonTransactionsApi import com.wavesplatform.api.http.{RouteTimeout, TransactionsApiRoute} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.db.WithDomain @@ -11,21 +9,30 @@ import com.wavesplatform.lang.directives.values.V5 import com.wavesplatform.lang.v1.traits.domain.{Lease, Recipient} import com.wavesplatform.network.TransactionPublisher import com.wavesplatform.settings.WavesSettings -import com.wavesplatform.state.{Blockchain, SnapshotBlockchain} -import com.wavesplatform.test.NumericExt -import com.wavesplatform.test.TestTime -import com.wavesplatform.test.SharedDomain import com.wavesplatform.test.DomainPresets.TransactionStateSnapshot +import com.wavesplatform.test.{NumericExt, SharedDomain, TestTime} import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.TxValidationError.GenericError +import com.wavesplatform.transaction.assets.exchange.* import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment import com.wavesplatform.transaction.smart.script.trace.{AccountVerifierTrace, TracedResult} import com.wavesplatform.transaction.utils.EthConverters.* -import com.wavesplatform.transaction.{Asset, AssetIdLength, Proofs, TransactionSignOps, TxExchangeAmount, TxHelpers, TxMatcherFee, TxOrderPrice, TxPositiveAmount, TxVersion} -import com.wavesplatform.utils.{EthEncoding, EthHelpers, SharedSchedulerMixin} -import com.wavesplatform.wallet.Wallet -import org.scalamock.scalatest.PathMockFactory +import com.wavesplatform.transaction.{ + Asset, + AssetIdLength, + Proofs, + Transaction, + TransactionSignOps, + TxExchangeAmount, + TxHelpers, + TxMatcherFee, + TxOrderPrice, + TxPositiveAmount, + TxVersion +} +import com.wavesplatform.utils.{EmptyBlockchain, EthEncoding, EthHelpers, SharedSchedulerMixin} +import io.netty.channel.Channel import org.web3j.crypto.Bip32ECKeyPair import play.api.libs.json.{JsObject, JsValue, Json} @@ -109,7 +116,7 @@ class TransactionBroadcastSpec2 | "orderType": "buy", | "amount": 1, | "price": 100, - | "timestamp": ${timestamp}, + | "timestamp": $timestamp, | "expiration": ${timestamp + 10000}, | "matcherFee": 100000, | "signature": "", @@ -131,7 +138,7 @@ class TransactionBroadcastSpec2 | "orderType": "sell", | "amount": 1, | "price": 100, - | "timestamp": ${timestamp}, + | "timestamp": $timestamp, | "expiration": ${timestamp + 10000}, | "matcherFee": 100000, | "signature": "", @@ -192,388 +199,388 @@ class TransactionBroadcastSpec2 val dAppScript = TxHelpers.script( s""" - |{-# STDLIB_VERSION 5 #-} - |{-# SCRIPT_TYPE ACCOUNT #-} - |{-# CONTENT_TYPE DAPP #-} - | - |@Callable(i) - |func test() = { - | let test = 1 - | if (test == 1) - | then - | [ - | Lease(Address(base58'${recipient1.bytes}'), $amount1, $nonce1), - | Lease(Alias("${recipient2.name}"), $amount2, $nonce2), - | LeaseCancel(base58'$leaseCancelId') - | ] - | else [] - |}""".stripMargin + |{-# STDLIB_VERSION 5 #-} + |{-# SCRIPT_TYPE ACCOUNT #-} + |{-# CONTENT_TYPE DAPP #-} + | + |@Callable(i) + |func test() = { + | let test = 1 + | if (test == 1) + | then + | [ + | Lease(Address(base58'${recipient1.bytes}'), $amount1, $nonce1), + | Lease(Alias("${recipient2.name}"), $amount2, $nonce2), + | LeaseCancel(base58'$leaseCancelId') + | ] + | else [] + |}""".stripMargin ) domain.appendBlock(TxHelpers.setScript(TxHelpers.defaultSigner, dAppScript)) val expectedJson = - s"""{ - | "error" : 306, - | "message" : "Error while executing dApp: Lease with id=$leaseCancelId not found", - | "transaction" : { - | "type" : 16, - | "id" : "${invoke.id()}", - | "fee" : 500000, - | "feeAssetId" : null, - | "timestamp" : ${invoke.timestamp}, - | "version" : 1, - | "sender" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9", - | "senderPublicKey" : "9BUoYQYq7K38mkk61q8aMH9kD9fKSVL1Fib7FbH6nUkQ", - | "proofs" : [ "${invoke.signature}" ], - | "dApp" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9", - | "payment" : [ ], - | "call" : { - | "function" : "test", - | "args" : [ ] - | } - | }, - | "trace" : [ { - | "type" : "verifier", - | "id" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9", - | "result" : "success", - | "error" : null - | }, { - | "type" : "dApp", - | "id" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9", - | "function" : "test", - | "args" : [ ], - | "invocations" : [ ], - | "result" : { - | "data" : [ ], - | "transfers" : [ ], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ { - | "recipient" : "${recipient1.bytes}", - | "amount" : $amount1, - | "nonce" : $nonce1, - | "id" : "$leaseId1" - | }, { - | "recipient" : "alias:T:${recipient2.name}", - | "amount" : $amount2, - | "nonce" : $nonce2, - | "id" : "$leaseId2" - | } ], - | "leaseCancels" : [ { - | "id" : "$leaseCancelId" - | } ], - | "invokes" : [ ] - | }, - | "error" : null, - | "vars" : [ { - | "name" : "i", - | "type" : "Invocation", - | "value" : { - | "originCaller" : { - | "type" : "Address", - | "value" : { - | "bytes" : { - | "type" : "ByteVector", - | "value" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9" - | } - | } - | }, - | "payments" : { - | "type" : "Array", - | "value" : [ ] - | }, - | "callerPublicKey" : { - | "type" : "ByteVector", - | "value" : "9BUoYQYq7K38mkk61q8aMH9kD9fKSVL1Fib7FbH6nUkQ" - | }, - | "feeAssetId" : { - | "type" : "Unit", - | "value" : { } - | }, - | "originCallerPublicKey" : { - | "type" : "ByteVector", - | "value" : "9BUoYQYq7K38mkk61q8aMH9kD9fKSVL1Fib7FbH6nUkQ" - | }, - | "transactionId" : { - | "type" : "ByteVector", - | "value" : "${invoke.id()}" - | }, - | "caller" : { - | "type" : "Address", - | "value" : { - | "bytes" : { - | "type" : "ByteVector", - | "value" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9" - | } - | } - | }, - | "fee" : { - | "type" : "Int", - | "value" : 500000 - | } - | } - | }, { - | "name" : "test.@args", - | "type" : "Array", - | "value" : [ ] - | }, { - | "name" : "test", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "==.@args", - | "type" : "Array", - | "value" : [ { - | "type" : "Int", - | "value" : 1 - | }, { - | "type" : "Int", - | "value" : 1 - | } ] - | }, { - | "name" : "==.@complexity", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "@complexityLimit", - | "type" : "Int", - | "value" : 25999 - | }, { - | "name" : "Address.@args", - | "type" : "Array", - | "value" : [ { - | "type" : "ByteVector", - | "value" : "3NAgxLPGnw3RGv9JT6NTDaG5D1iLUehg2xd" - | } ] - | }, { - | "name" : "Address.@complexity", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "@complexityLimit", - | "type" : "Int", - | "value" : 25998 - | }, { - | "name" : "Lease.@args", - | "type" : "Array", - | "value" : [ { - | "type" : "Address", - | "value" : { - | "bytes" : { - | "type" : "ByteVector", - | "value" : "3NAgxLPGnw3RGv9JT6NTDaG5D1iLUehg2xd" - | } - | } - | }, { - | "type" : "Int", - | "value" : 100 - | }, { - | "type" : "Int", - | "value" : 0 - | } ] - | }, { - | "name" : "Lease.@complexity", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "@complexityLimit", - | "type" : "Int", - | "value" : 25997 - | }, { - | "name" : "Alias.@args", - | "type" : "Array", - | "value" : [ { - | "type" : "String", - | "value" : "some_alias" - | } ] - | }, { - | "name" : "Alias.@complexity", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "@complexityLimit", - | "type" : "Int", - | "value" : 25996 - | }, { - | "name" : "Lease.@args", - | "type" : "Array", - | "value" : [ { - | "type" : "Alias", - | "value" : { - | "alias" : { - | "type" : "String", - | "value" : "some_alias" - | } - | } - | }, { - | "type" : "Int", - | "value" : 20 - | }, { - | "type" : "Int", - | "value" : 2 - | } ] - | }, { - | "name" : "Lease.@complexity", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "@complexityLimit", - | "type" : "Int", - | "value" : 25995 - | }, { - | "name" : "LeaseCancel.@args", - | "type" : "Array", - | "value" : [ { - | "type" : "ByteVector", - | "value" : "$leaseCancelId" - | } ] - | }, { - | "name" : "LeaseCancel.@complexity", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "@complexityLimit", - | "type" : "Int", - | "value" : 25994 - | }, { - | "name" : "cons.@args", - | "type" : "Array", - | "value" : [ { - | "type" : "LeaseCancel", - | "value" : { - | "leaseId" : { - | "type" : "ByteVector", - | "value" : "$leaseCancelId" - | } - | } - | }, { - | "type" : "Array", - | "value" : [ ] - | } ] - | }, { - | "name" : "cons.@complexity", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "@complexityLimit", - | "type" : "Int", - | "value" : 25993 - | }, { - | "name" : "cons.@args", - | "type" : "Array", - | "value" : [ { - | "type" : "Lease", - | "value" : { - | "recipient" : { - | "type" : "Alias", - | "value" : { - | "alias" : { - | "type" : "String", - | "value" : "some_alias" - | } - | } - | }, - | "amount" : { - | "type" : "Int", - | "value" : 20 - | }, - | "nonce" : { - | "type" : "Int", - | "value" : 2 - | } - | } - | }, { - | "type" : "Array", - | "value" : [ { - | "type" : "LeaseCancel", - | "value" : { - | "leaseId" : { - | "type" : "ByteVector", - | "value" : "$leaseCancelId" - | } - | } - | } ] - | } ] - | }, { - | "name" : "cons.@complexity", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "@complexityLimit", - | "type" : "Int", - | "value" : 25992 - | }, { - | "name" : "cons.@args", - | "type" : "Array", - | "value" : [ { - | "type" : "Lease", - | "value" : { - | "recipient" : { - | "type" : "Address", - | "value" : { - | "bytes" : { - | "type" : "ByteVector", - | "value" : "3NAgxLPGnw3RGv9JT6NTDaG5D1iLUehg2xd" - | } - | } - | }, - | "amount" : { - | "type" : "Int", - | "value" : 100 - | }, - | "nonce" : { - | "type" : "Int", - | "value" : 0 - | } - | } - | }, { - | "type" : "Array", - | "value" : [ { - | "type" : "Lease", - | "value" : { - | "recipient" : { - | "type" : "Alias", - | "value" : { - | "alias" : { - | "type" : "String", - | "value" : "some_alias" - | } - | } - | }, - | "amount" : { - | "type" : "Int", - | "value" : 20 - | }, - | "nonce" : { - | "type" : "Int", - | "value" : 2 - | } - | } - | }, { - | "type" : "LeaseCancel", - | "value" : { - | "leaseId" : { - | "type" : "ByteVector", - | "value" : "$leaseCancelId" - | } - | } - | } ] - | } ] - | }, { - | "name" : "cons.@complexity", - | "type" : "Int", - | "value" : 1 - | }, { - | "name" : "@complexityLimit", - | "type" : "Int", - | "value" : 25991 - | } ] - | } ] - |} - |""".stripMargin + s"""{ + | "error" : 306, + | "message" : "Error while executing dApp: Lease with id=$leaseCancelId not found", + | "transaction" : { + | "type" : 16, + | "id" : "${invoke.id()}", + | "fee" : 500000, + | "feeAssetId" : null, + | "timestamp" : ${invoke.timestamp}, + | "version" : 1, + | "sender" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9", + | "senderPublicKey" : "9BUoYQYq7K38mkk61q8aMH9kD9fKSVL1Fib7FbH6nUkQ", + | "proofs" : [ "${invoke.signature}" ], + | "dApp" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9", + | "payment" : [ ], + | "call" : { + | "function" : "test", + | "args" : [ ] + | } + | }, + | "trace" : [ { + | "type" : "verifier", + | "id" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9", + | "result" : "success", + | "error" : null + | }, { + | "type" : "dApp", + | "id" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9", + | "function" : "test", + | "args" : [ ], + | "invocations" : [ ], + | "result" : { + | "data" : [ ], + | "transfers" : [ ], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ { + | "recipient" : "${recipient1.bytes}", + | "amount" : $amount1, + | "nonce" : $nonce1, + | "id" : "$leaseId1" + | }, { + | "recipient" : "alias:T:${recipient2.name}", + | "amount" : $amount2, + | "nonce" : $nonce2, + | "id" : "$leaseId2" + | } ], + | "leaseCancels" : [ { + | "id" : "$leaseCancelId" + | } ], + | "invokes" : [ ] + | }, + | "error" : null, + | "vars" : [ { + | "name" : "i", + | "type" : "Invocation", + | "value" : { + | "originCaller" : { + | "type" : "Address", + | "value" : { + | "bytes" : { + | "type" : "ByteVector", + | "value" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9" + | } + | } + | }, + | "payments" : { + | "type" : "Array", + | "value" : [ ] + | }, + | "callerPublicKey" : { + | "type" : "ByteVector", + | "value" : "9BUoYQYq7K38mkk61q8aMH9kD9fKSVL1Fib7FbH6nUkQ" + | }, + | "feeAssetId" : { + | "type" : "Unit", + | "value" : { } + | }, + | "originCallerPublicKey" : { + | "type" : "ByteVector", + | "value" : "9BUoYQYq7K38mkk61q8aMH9kD9fKSVL1Fib7FbH6nUkQ" + | }, + | "transactionId" : { + | "type" : "ByteVector", + | "value" : "${invoke.id()}" + | }, + | "caller" : { + | "type" : "Address", + | "value" : { + | "bytes" : { + | "type" : "ByteVector", + | "value" : "3MtGzgmNa5fMjGCcPi5nqMTdtZkfojyWHL9" + | } + | } + | }, + | "fee" : { + | "type" : "Int", + | "value" : 500000 + | } + | } + | }, { + | "name" : "test.@args", + | "type" : "Array", + | "value" : [ ] + | }, { + | "name" : "test", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "==.@args", + | "type" : "Array", + | "value" : [ { + | "type" : "Int", + | "value" : 1 + | }, { + | "type" : "Int", + | "value" : 1 + | } ] + | }, { + | "name" : "==.@complexity", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "@complexityLimit", + | "type" : "Int", + | "value" : 25999 + | }, { + | "name" : "Address.@args", + | "type" : "Array", + | "value" : [ { + | "type" : "ByteVector", + | "value" : "3NAgxLPGnw3RGv9JT6NTDaG5D1iLUehg2xd" + | } ] + | }, { + | "name" : "Address.@complexity", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "@complexityLimit", + | "type" : "Int", + | "value" : 25998 + | }, { + | "name" : "Lease.@args", + | "type" : "Array", + | "value" : [ { + | "type" : "Address", + | "value" : { + | "bytes" : { + | "type" : "ByteVector", + | "value" : "3NAgxLPGnw3RGv9JT6NTDaG5D1iLUehg2xd" + | } + | } + | }, { + | "type" : "Int", + | "value" : 100 + | }, { + | "type" : "Int", + | "value" : 0 + | } ] + | }, { + | "name" : "Lease.@complexity", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "@complexityLimit", + | "type" : "Int", + | "value" : 25997 + | }, { + | "name" : "Alias.@args", + | "type" : "Array", + | "value" : [ { + | "type" : "String", + | "value" : "some_alias" + | } ] + | }, { + | "name" : "Alias.@complexity", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "@complexityLimit", + | "type" : "Int", + | "value" : 25996 + | }, { + | "name" : "Lease.@args", + | "type" : "Array", + | "value" : [ { + | "type" : "Alias", + | "value" : { + | "alias" : { + | "type" : "String", + | "value" : "some_alias" + | } + | } + | }, { + | "type" : "Int", + | "value" : 20 + | }, { + | "type" : "Int", + | "value" : 2 + | } ] + | }, { + | "name" : "Lease.@complexity", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "@complexityLimit", + | "type" : "Int", + | "value" : 25995 + | }, { + | "name" : "LeaseCancel.@args", + | "type" : "Array", + | "value" : [ { + | "type" : "ByteVector", + | "value" : "$leaseCancelId" + | } ] + | }, { + | "name" : "LeaseCancel.@complexity", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "@complexityLimit", + | "type" : "Int", + | "value" : 25994 + | }, { + | "name" : "cons.@args", + | "type" : "Array", + | "value" : [ { + | "type" : "LeaseCancel", + | "value" : { + | "leaseId" : { + | "type" : "ByteVector", + | "value" : "$leaseCancelId" + | } + | } + | }, { + | "type" : "Array", + | "value" : [ ] + | } ] + | }, { + | "name" : "cons.@complexity", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "@complexityLimit", + | "type" : "Int", + | "value" : 25993 + | }, { + | "name" : "cons.@args", + | "type" : "Array", + | "value" : [ { + | "type" : "Lease", + | "value" : { + | "recipient" : { + | "type" : "Alias", + | "value" : { + | "alias" : { + | "type" : "String", + | "value" : "some_alias" + | } + | } + | }, + | "amount" : { + | "type" : "Int", + | "value" : 20 + | }, + | "nonce" : { + | "type" : "Int", + | "value" : 2 + | } + | } + | }, { + | "type" : "Array", + | "value" : [ { + | "type" : "LeaseCancel", + | "value" : { + | "leaseId" : { + | "type" : "ByteVector", + | "value" : "$leaseCancelId" + | } + | } + | } ] + | } ] + | }, { + | "name" : "cons.@complexity", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "@complexityLimit", + | "type" : "Int", + | "value" : 25992 + | }, { + | "name" : "cons.@args", + | "type" : "Array", + | "value" : [ { + | "type" : "Lease", + | "value" : { + | "recipient" : { + | "type" : "Address", + | "value" : { + | "bytes" : { + | "type" : "ByteVector", + | "value" : "3NAgxLPGnw3RGv9JT6NTDaG5D1iLUehg2xd" + | } + | } + | }, + | "amount" : { + | "type" : "Int", + | "value" : 100 + | }, + | "nonce" : { + | "type" : "Int", + | "value" : 0 + | } + | } + | }, { + | "type" : "Array", + | "value" : [ { + | "type" : "Lease", + | "value" : { + | "recipient" : { + | "type" : "Alias", + | "value" : { + | "alias" : { + | "type" : "String", + | "value" : "some_alias" + | } + | } + | }, + | "amount" : { + | "type" : "Int", + | "value" : 20 + | }, + | "nonce" : { + | "type" : "Int", + | "value" : 2 + | } + | } + | }, { + | "type" : "LeaseCancel", + | "value" : { + | "leaseId" : { + | "type" : "ByteVector", + | "value" : "$leaseCancelId" + | } + | } + | } ] + | } ] + | }, { + | "name" : "cons.@complexity", + | "type" : "Int", + | "value" : 1 + | }, { + | "name" : "@complexityLimit", + | "type" : "Int", + | "value" : 25991 + | } ] + | } ] + |} + |""".stripMargin Post(routePath("/broadcast?trace=true"), invoke.json()) ~> route ~> check { responseAs[JsObject] should matchJson(expectedJson) @@ -582,25 +589,27 @@ class TransactionBroadcastSpec2 } } - class TransactionBroadcastSpec extends RouteSpec("/transactions") with RestAPISettingsHelper - with PathMockFactory with EthHelpers with WithDomain with SharedSchedulerMixin { - private val blockchain = stub[Blockchain] - private val transactionPublisher = stub[TransactionPublisher] - private val testTime = new TestTime + private val seed = new Array[Byte](32) + Random.nextBytes(seed) + private val sender: KeyPair = KeyPair(seed) + + private val transactionPublisher: TransactionPublisher = (_: Transaction, _: Option[Channel]) => + Future.successful(TracedResult(Right(true), List(AccountVerifierTrace(sender.toAddress, Some(GenericError("Error in account script")))))) + private val testTime = new TestTime private val transactionsApiRoute = new TransactionsApiRoute( restAPISettings, - stub[CommonTransactionsApi], - stub[Wallet], - blockchain, - stub[() => SnapshotBlockchain], - mockFunction[Int], + null, + null, + EmptyBlockchain, + () => ???, + () => 0, transactionPublisher, testTime, new RouteTimeout(60.seconds)(using sharedScheduler) @@ -609,10 +618,8 @@ class TransactionBroadcastSpec private val route = seal(transactionsApiRoute.route) "invoke script" - { + def withInvokeScriptTransaction(f: (KeyPair, InvokeScriptTransaction) => Unit): Unit = { - val seed = new Array[Byte](32) - Random.nextBytes(seed) - val sender: KeyPair = KeyPair(seed) val ist = InvokeScriptTransaction( TxVersion.V1, sender.publicKey, @@ -629,25 +636,13 @@ class TransactionBroadcastSpec } "shows trace when trace is enabled" in withInvokeScriptTransaction { (sender, ist) => - val accountTrace = AccountVerifierTrace(sender.toAddress, Some(GenericError("Error in account script"))) - (transactionPublisher.validateAndBroadcast) - .when(*, None) - .returning( - Future.successful(TracedResult(Right(true), List(accountTrace))) - ) Post(routePath("/broadcast?trace=true"), ist.json()) ~> route ~> check { val result = responseAs[JsObject] - (result \ "trace").as[JsValue] shouldBe Json.arr(accountTrace.json) + (result \ "trace").as[JsValue] shouldBe Json.arr(AccountVerifierTrace(sender.toAddress, Some(GenericError("Error in account script"))).json) } } - "does not show trace when trace is disabled" in withInvokeScriptTransaction { (sender, ist) => - val accountTrace = AccountVerifierTrace(sender.toAddress, Some(GenericError("Error in account script"))) - (transactionPublisher.validateAndBroadcast) - .when(*, None) - .returning( - Future.successful(TracedResult(Right(true), List(accountTrace))) - ) + "does not show trace when trace is disabled" in withInvokeScriptTransaction { (_, ist) => Post(routePath("/broadcast"), ist.json()) ~> route ~> check { (responseAs[JsObject] \ "trace") shouldBe empty } @@ -689,7 +684,7 @@ class TransactionBroadcastSpec txs.foreach { tx => Post(routePath("/broadcast"), tx.json()) ~> route ~> check { val result = responseAs[JsObject].toString - result should include regex ("Invalid validation. Size of asset id.*not equal 32 bytes") + result should include regex "Invalid validation. Size of asset id.*not equal 32 bytes" } } } diff --git a/node/tests/src/test/scala/com/wavesplatform/http/UtilsRouteEvaluateSpec.scala b/node/tests/src/test/scala/com/wavesplatform/http/UtilsRouteEvaluateSpec.scala index 207ebb2ecfa..6dcd28b86a2 100644 --- a/node/tests/src/test/scala/com/wavesplatform/http/UtilsRouteEvaluateSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/http/UtilsRouteEvaluateSpec.scala @@ -7,36 +7,28 @@ import com.wavesplatform.api.http.utils.{UtilsApiRoute, UtilsInvocationRequest} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.db.WithDomain import com.wavesplatform.db.WithState.AddrWithBalance -import com.wavesplatform.history.DefaultBlockchainSettings import com.wavesplatform.lang.directives.values.V6 import com.wavesplatform.lang.script.Script import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.lang.v1.estimator.v3.ScriptEstimatorV3 import com.wavesplatform.lang.v1.evaluator.ctx.impl.PureContext -import com.wavesplatform.state.{Blockchain, IntegerDataEntry, LeaseBalance} +import com.wavesplatform.state.IntegerDataEntry import com.wavesplatform.test.DomainPresets.{RideV5, RideV6} import com.wavesplatform.test.NumericExt import com.wavesplatform.transaction.Asset.IssuedAsset import com.wavesplatform.transaction.TxHelpers.* import com.wavesplatform.transaction.{Asset, AssetIdLength, TxHelpers} -import com.wavesplatform.utils.{Schedulers, Time} +import com.wavesplatform.utils.{EmptyBlockchain, Schedulers, Time} import io.netty.util.HashedWheelTimer import monix.execution.schedulers.SchedulerService import org.apache.pekko.http.scaladsl.model.headers.Accept -import org.scalamock.scalatest.PathMockFactory import org.scalatest.Inside import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks as PropertyChecks import play.api.libs.json.* import scala.concurrent.duration.DurationInt -class UtilsRouteEvaluateSpec - extends RouteSpec("/utils") - with RestAPISettingsHelper - with PropertyChecks - with PathMockFactory - with Inside - with WithDomain { +class UtilsRouteEvaluateSpec extends RouteSpec("/utils"), RestAPISettingsHelper, PropertyChecks, Inside, WithDomain { private val timer = new HashedWheelTimer() private val timeBounded: SchedulerService = Schedulers.timeBoundedFixedPool(timer, 5.seconds, 1, "rest-time-limited") private val utilsApi: UtilsApiRoute = UtilsApiRoute( @@ -48,7 +40,7 @@ class UtilsRouteEvaluateSpec Int.MaxValue, () => ScriptEstimatorV3.latest, timeBounded, - stub[Blockchain]("globalBlockchain") + new EmptyBlockchain {} ) override def afterAll(): Unit = { @@ -253,15 +245,6 @@ class UtilsRouteEvaluateSpec responseJson shouldBe Json.obj("type" -> "Int", "value" -> (xFromContract - 1)) } - (() => utilsApi.blockchain.settings) - .when() - .returning(DefaultBlockchainSettings) - .anyNumberOfTimes() - (utilsApi.blockchain.leaseBalance) - .when(*) - .returning(LeaseBalance.empty) - .anyNumberOfTimes() - evalScript(""" testSyncInvoke() """) ~> route ~> check { val result = responseAs[JsObject] (result - "stateChanges") should matchJson( diff --git a/node/tests/src/test/scala/com/wavesplatform/http/UtilsRouteSpec.scala b/node/tests/src/test/scala/com/wavesplatform/http/UtilsRouteSpec.scala index 4fff1b77954..9ea9ae09fbe 100644 --- a/node/tests/src/test/scala/com/wavesplatform/http/UtilsRouteSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/http/UtilsRouteSpec.scala @@ -22,23 +22,22 @@ import com.wavesplatform.lang.v1.evaluator.ctx.impl.PureContext import com.wavesplatform.lang.{Global, contract} import com.wavesplatform.protobuf.dapp.DAppMeta import com.wavesplatform.protobuf.dapp.DAppMeta.CallableFuncSignature -import com.wavesplatform.settings.TestSettings +import com.wavesplatform.settings.{BlockchainSettings, TestSettings} +import com.wavesplatform.state.Height import com.wavesplatform.state.diffs.FeeValidation -import com.wavesplatform.state.{Blockchain, Height} import com.wavesplatform.transaction.smart.script.ScriptCompiler -import com.wavesplatform.utils.{Schedulers, Time} +import com.wavesplatform.utils.{EmptyBlockchain, Schedulers, Time} import io.netty.util.HashedWheelTimer import monix.execution.schedulers.SchedulerService import org.apache.pekko.http.scaladsl.testkit.RouteTestTimeout import org.scalacheck.Gen -import org.scalamock.scalatest.PathMockFactory import org.scalatest.Inside import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks as PropertyChecks import play.api.libs.json.* import scala.concurrent.duration.* -class UtilsRouteSpec extends RouteSpec("/utils") with RestAPISettingsHelper with PropertyChecks with PathMockFactory with Inside with WithDomain { +class UtilsRouteSpec extends RouteSpec("/utils"), RestAPISettingsHelper, PropertyChecks, Inside, WithDomain { private val estimator = ScriptEstimatorV2 protected override implicit val routeTestTimeout: RouteTestTimeout = RouteTestTimeout(20.seconds) @@ -58,7 +57,7 @@ class UtilsRouteSpec extends RouteSpec("/utils") with RestAPISettingsHelper with Int.MaxValue, () => estimator, timeBounded, - stub[Blockchain]("globalBlockchain") + EmptyBlockchain ) override def afterAll(): Unit = { @@ -66,7 +65,6 @@ class UtilsRouteSpec extends RouteSpec("/utils") with RestAPISettingsHelper with super.afterAll() } - (() => utilsApi.blockchain.activatedFeatures).when().returning(Map()).anyNumberOfTimes() private val route = seal(utilsApi.route) val script: FUNCTION_CALL = FUNCTION_CALL( @@ -621,10 +619,11 @@ class UtilsRouteSpec extends RouteSpec("/utils") with RestAPISettingsHelper with } routePath(s"/script/compileCode after SynchronousCalls") in { - val blockchain = stub[Blockchain]("blockchain") - val route = seal(utilsApi.copy(blockchain = blockchain).route) - (() => blockchain.activatedFeatures).when().returning(Map(BlockchainFeatures.SynchronousCalls.id -> Height(0))) - (() => blockchain.settings).when().returning(TestSettings.Default.blockchainSettings) + val blockchain = new EmptyBlockchain { + override lazy val settings: BlockchainSettings = TestSettings.Default.blockchainSettings + override def activatedFeatures: Map[Short, Height] = Map(BlockchainFeatures.SynchronousCalls.id -> Height(0)) + } + val route = seal(utilsApi.copy(blockchain = blockchain).route) Post(routePath("/script/compileCode"), dAppWithoutVerifier) ~> route ~> check { val json = responseAs[JsValue] @@ -658,15 +657,13 @@ class UtilsRouteSpec extends RouteSpec("/utils") with RestAPISettingsHelper with } routePath(s"/script/compileCode after ContinuationTransaction") in { - val blockchain = stub[Blockchain]("blockchain") - val route = seal(utilsApi.copy(blockchain = blockchain).route) - (() => blockchain.activatedFeatures) - .when() - .returning( + val blockchain = new EmptyBlockchain { + override def activatedFeatures: Map[Short, Height] = Seq(BlockchainFeatures.SynchronousCalls, BlockchainFeatures.RideV6, BlockchainFeatures.ContinuationTransaction) .map(x => x.id -> Height(0)) .toMap - ) + } + val route = seal(utilsApi.copy(blockchain = blockchain).route) Post(routePath("/script/compileCode"), freeCall) ~> route ~> check { val json = responseAs[JsValue] @@ -784,11 +781,11 @@ class UtilsRouteSpec extends RouteSpec("/utils") with RestAPISettingsHelper with } routePath(s"/script/estimate after RideV6") in { - val blockchain = stub[Blockchain]("blockchain") - val route = seal(utilsApi.copy(blockchain = blockchain).route) - (() => blockchain.activatedFeatures) - .when() - .returning(Map(BlockchainFeatures.SynchronousCalls.id -> Height(0), BlockchainFeatures.RideV6.id -> Height(0))) + val blockchain = new EmptyBlockchain { + override def activatedFeatures: Map[Short, Height] = + Map(BlockchainFeatures.SynchronousCalls.id -> Height(0), BlockchainFeatures.RideV6.id -> Height(0)) + } + val route = seal(utilsApi.copy(blockchain = blockchain).route) Post(routePath("/script/estimate"), freeCallExpr) ~> route ~> check { val json = responseAs[JsValue] diff --git a/node/tests/src/test/scala/com/wavesplatform/lagonaki/unit/MicroBlockSpecification.scala b/node/tests/src/test/scala/com/wavesplatform/lagonaki/unit/MicroBlockSpecification.scala index 5468572fdd4..1f43968dec7 100644 --- a/node/tests/src/test/scala/com/wavesplatform/lagonaki/unit/MicroBlockSpecification.scala +++ b/node/tests/src/test/scala/com/wavesplatform/lagonaki/unit/MicroBlockSpecification.scala @@ -17,11 +17,10 @@ import com.wavesplatform.test.* import com.wavesplatform.transaction.* import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.transfer.* -import org.scalamock.scalatest.MockFactory import scala.util.Random -class MicroBlockSpecification extends FunSuite with MockFactory { +class MicroBlockSpecification extends FunSuite { private val prevResBlockSig = ByteStr(Array.fill(Block.BlockIdLength)(Random.nextInt(100).toByte)) private val totalResBlockSig = ByteStr(Array.fill(Block.BlockIdLength)(Random.nextInt(100).toByte)) diff --git a/node/tests/src/test/scala/com/wavesplatform/mining/LastMicroBlockSuite.scala b/node/tests/src/test/scala/com/wavesplatform/mining/LastMicroBlockSuite.scala index 4be07ca1c10..e60ddd5ef76 100644 --- a/node/tests/src/test/scala/com/wavesplatform/mining/LastMicroBlockSuite.scala +++ b/node/tests/src/test/scala/com/wavesplatform/mining/LastMicroBlockSuite.scala @@ -6,7 +6,6 @@ import com.wavesplatform.common.state.ByteStr import com.wavesplatform.db.WithDomain import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.history.Domain -import com.wavesplatform.settings.* import com.wavesplatform.state import com.wavesplatform.state.* import com.wavesplatform.test.{FreeSpec, TestSchedulerOps, TestTime} diff --git a/node/tests/src/test/scala/com/wavesplatform/mining/MicroBlockMinerSpec.scala b/node/tests/src/test/scala/com/wavesplatform/mining/MicroBlockMinerSpec.scala index a49e37865fb..2db5cda1e56 100644 --- a/node/tests/src/test/scala/com/wavesplatform/mining/MicroBlockMinerSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/mining/MicroBlockMinerSpec.scala @@ -21,13 +21,12 @@ import com.wavesplatform.utx.{UtxPool, UtxPoolImpl, UtxPriorityPool} import monix.execution.Scheduler import monix.reactive.Observable import monix.reactive.subjects.ConcurrentSubject -import org.scalamock.scalatest.PathMockFactory import java.util.concurrent.CountDownLatch import scala.concurrent.duration.* import scala.util.Random -class MicroBlockMinerSpec extends FlatSpec with PathMockFactory with WithDomain { +class MicroBlockMinerSpec extends FlatSpec with WithDomain { "Micro block miner" should "generate microblocks in flat interval" in { val scheduler = Schedulers.singleThread("test") val acc = TestValues.keyPair diff --git a/node/tests/src/test/scala/com/wavesplatform/mining/MiningFailuresSuite.scala b/node/tests/src/test/scala/com/wavesplatform/mining/MiningFailuresSuite.scala index 7e3fab2e37b..d5c513bf60d 100644 --- a/node/tests/src/test/scala/com/wavesplatform/mining/MiningFailuresSuite.scala +++ b/node/tests/src/test/scala/com/wavesplatform/mining/MiningFailuresSuite.scala @@ -2,18 +2,21 @@ package com.wavesplatform.mining import com.typesafe.config.ConfigFactory import com.wavesplatform.WithNewDBForEachTest -import com.wavesplatform.account.KeyPair -import com.wavesplatform.block.{Block, SignedBlockHeader} +import com.wavesplatform.account.{Address, KeyPair} +import com.wavesplatform.api.BlockMeta +import com.wavesplatform.block.{Block, BlockSnapshot, MicroBlock, MicroBlockSnapshot, SignedBlockHeader} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.consensus.PoSSelector import com.wavesplatform.lagonaki.mocks.TestBlock +import com.wavesplatform.lang.ValidationError import com.wavesplatform.settings.* import com.wavesplatform.state.BlockchainUpdaterImpl.BlockApplyResult.Applied import com.wavesplatform.state.diffs.ENOUGH_AMT -import com.wavesplatform.state.{BalanceSnapshot, BlockEndorser, BlockMinerInfo, Blockchain, EndorsementStorage, Height, NG} +import com.wavesplatform.state.* import com.wavesplatform.test.FlatSpec -import com.wavesplatform.transaction.BlockchainUpdater +import com.wavesplatform.transaction.{BlockchainUpdater, DiscardedBlocks, LastBlockInfo, Transaction} import com.wavesplatform.transaction.TxValidationError.BlockFromFuture +import com.wavesplatform.utils.EmptyBlockchain import com.wavesplatform.utx.UtxPoolImpl import com.wavesplatform.wallet.Wallet import io.netty.channel.group.DefaultChannelGroup @@ -21,16 +24,95 @@ import io.netty.util.concurrent.GlobalEventExecutor import monix.eval.Task import monix.execution.Scheduler import monix.execution.Scheduler.Implicits.global +import monix.execution.atomic.AtomicInt import monix.reactive.Observable -import org.scalamock.scalatest.PathMockFactory -class MiningFailuresSuite extends FlatSpec with PathMockFactory with WithNewDBForEachTest { +class MiningFailuresSuite extends FlatSpec, WithNewDBForEachTest { trait BlockchainUpdaterNG extends Blockchain with BlockchainUpdater with NG behavior of "Miner" it should "generate valid blocks ignoring time errors " in { - val blockchainUpdater = stub[BlockchainUpdaterNG] + @volatile var minedBlock: Block = null + val genesis = TestBlock.create(System.currentTimeMillis(), Nil).block + val blockchainUpdater = new EmptyBlockchain with BlockchainUpdater with NG { + override def height: Int = 1 + + override def heightOf(blockId: ByteStr): Option[Int] = Some(1) + + override def hitSource(height: Int): Option[ByteStr] = Some(ByteStr(new Array[Byte](32))) + + override def blockHeader(height: Int): Option[SignedBlockHeader] = Some(SignedBlockHeader(genesis.header, genesis.signature)) + + override def balanceSnapshots(address: Address, from: Int, to: Option[ByteStr]): Seq[BalanceSnapshot] = + Seq(BalanceSnapshot(Height(1), ENOUGH_AMT, 0, 0, 0)) + + override def bestLastBlockInfo(maxMicroblockTimestampMs: Long): Option[BlockMinerInfo] = Some( + BlockMinerInfo( + genesis.header.baseTarget, + genesis.header.generationSignature, + genesis.header.timestamp, + genesis.id() + ) + ) + + override def isLastBlockId(id: ByteStr): Boolean = true + + private val counter = AtomicInt(0) + + override def processBlock( + block: Block, + hitSource: ByteStr, + snapshot: Option[BlockSnapshot], + generatorSet: GeneratorSet, + challengedHitSource: Option[ByteStr], + verify: Boolean, + txSignParCheck: Boolean + ): Either[ValidationError, BlockchainUpdaterImpl.BlockApplyResult] = + if (counter.getAndIncrement() >= 9) { + minedBlock = block + Right(Applied(Nil, 0, Seq.empty)) + } else + Left(BlockFromFuture(100, 100)) + + override def processMicroBlock( + microBlock: MicroBlock, + snapshot: Option[MicroBlockSnapshot], + verify: Boolean + ): Either[ValidationError, Block.BlockId] = ??? + + override def computeNextReward: Option[Long] = Some(0) + + override def removeAfter(blockId: ByteStr): Either[ValidationError, DiscardedBlocks] = Right(Seq.empty) + + override def lastBlockInfo: Observable[LastBlockInfo] = Observable.empty + + override def referencedBlockchain(reference: ByteStr): Blockchain = this + + override def shutdown(): Unit = {} + + override def microBlock(id: ByteStr): Option[MicroBlock] = None + + override def microblockIds: Seq[Block.BlockId] = Seq.empty + + override def liquidBlock(id: ByteStr): Option[Block] = None + + override def liquidBlockSnapshot(id: ByteStr): Option[StateSnapshot] = None + + override def microBlockSnapshot(totalBlockId: ByteStr): Option[StateSnapshot] = None + + override def liquidTransactions(id: ByteStr): Option[Seq[(TxMeta, Transaction)]] = None + + override def liquidBlockMeta: Option[BlockMeta] = None + + override def bestLiquidSnapshot: Option[StateSnapshot] = None + + override def bestLiquidSnapshotAndFees: Option[(StateSnapshot, Long, Long)] = None + + override def snapshotBlockchain: SnapshotBlockchain = ??? + + override def currentGeneratorSet: Option[GeneratorSet] = ??? + } val wavesSettings = { val config = ConfigFactory @@ -76,42 +158,6 @@ class MiningFailuresSuite extends FlatSpec with PathMockFactory with WithNewDBFo ) -> scheduler } - val genesis = TestBlock.create(System.currentTimeMillis(), Nil).block - (blockchainUpdater.isLastBlockId).when(genesis.id()).returning(true) - (blockchainUpdater.heightOf).when(genesis.id()).returning(Some(1)).anyNumberOfTimes() - (blockchainUpdater.heightOf).when(genesis.header.reference).returning(Some(1)).anyNumberOfTimes() - (() => blockchainUpdater.height).when().returning(1) - (() => blockchainUpdater.settings).when().returning(blockchainSettings) - (blockchainUpdater.blockHeader).when(*).returns(Some(SignedBlockHeader(genesis.header, genesis.signature))) - (() => blockchainUpdater.activatedFeatures).when().returning(Map.empty) - (() => blockchainUpdater.approvedFeatures).when().returning(Map.empty) - (blockchainUpdater.hitSource).when(*).returns(Some(ByteStr(new Array[Byte](32)))) - (blockchainUpdater.effectiveBalanceBanHeights).when(*).returns(Seq.empty) - (blockchainUpdater.bestLastBlockInfo) - .when(*) - .returning( - Some( - BlockMinerInfo( - genesis.header.baseTarget, - genesis.header.generationSignature, - genesis.header.timestamp, - genesis.id() - ) - ) - ) - - var minedBlock: Block = null - (blockchainUpdater.processBlock).when(*, *, *, *, *, *, *).returning(Left(BlockFromFuture(100, 100))).repeated(10) - (blockchainUpdater.processBlock) - .when(*, *, *, *, *, *, *) - .onCall { (block, _, _, _, _, _, _) => - minedBlock = block - Right(Applied(Nil, 0, Seq.empty)) - } - .once() - (blockchainUpdater.balanceSnapshots).when(*, *, *).returning(Seq(BalanceSnapshot(Height(1), ENOUGH_AMT, 0, 0, 0))) - (blockchainUpdater.committedGenerators).when(*).returning(IndexedSeq.empty) - val account = accountGen.sample.get val generateBlock = generateBlockTask(miner)(account) generateBlock.runSyncUnsafe() shouldBe ((): Unit) diff --git a/node/tests/src/test/scala/com/wavesplatform/mining/MultiDimensionalMiningConstraintSuite.scala b/node/tests/src/test/scala/com/wavesplatform/mining/MultiDimensionalMiningConstraintSuite.scala index f8aef6f707f..02bb5af3b55 100644 --- a/node/tests/src/test/scala/com/wavesplatform/mining/MultiDimensionalMiningConstraintSuite.scala +++ b/node/tests/src/test/scala/com/wavesplatform/mining/MultiDimensionalMiningConstraintSuite.scala @@ -1,12 +1,12 @@ package com.wavesplatform.mining -import com.wavesplatform.state.{Blockchain, StateSnapshot} +import com.wavesplatform.state.StateSnapshot import com.wavesplatform.test.FreeSpec import com.wavesplatform.transaction.Transaction +import com.wavesplatform.utils.EmptyBlockchain import org.scalacheck.{Arbitrary, Gen} -import org.scalamock.scalatest.PathMockFactory -class MultiDimensionalMiningConstraintSuite extends FreeSpec with PathMockFactory { +class MultiDimensionalMiningConstraintSuite extends FreeSpec { "MultiDimensionalMiningConstraint" - { "isFull" - { val emptyConstraintGen: Gen[MultiDimensionalMiningConstraint] = for { @@ -40,7 +40,7 @@ class MultiDimensionalMiningConstraintSuite extends FreeSpec with PathMockFactor } "put(transaction)" - tests(createConstConstraint(_, transactionSize = 1, "txSize")) { (initConstraint, txs) => - txs.foldLeft(initConstraint)(_.put(stub[Blockchain], _, StateSnapshot.empty)) + txs.foldLeft(initConstraint)(_.put(EmptyBlockchain, _, StateSnapshot.empty)) } } diff --git a/node/tests/src/test/scala/com/wavesplatform/mining/OneDimensionalMiningConstraintSuite.scala b/node/tests/src/test/scala/com/wavesplatform/mining/OneDimensionalMiningConstraintSuite.scala index 09aa39d93f2..77ab9843f1f 100644 --- a/node/tests/src/test/scala/com/wavesplatform/mining/OneDimensionalMiningConstraintSuite.scala +++ b/node/tests/src/test/scala/com/wavesplatform/mining/OneDimensionalMiningConstraintSuite.scala @@ -1,12 +1,12 @@ package com.wavesplatform.mining -import com.wavesplatform.state.{Blockchain, StateSnapshot} +import com.wavesplatform.state.StateSnapshot import com.wavesplatform.test.FreeSpec import com.wavesplatform.transaction.Transaction +import com.wavesplatform.utils.EmptyBlockchain import org.scalacheck.Gen -import org.scalamock.scalatest.PathMockFactory -class OneDimensionalMiningConstraintSuite extends FreeSpec with PathMockFactory { +class OneDimensionalMiningConstraintSuite extends FreeSpec { "OneDimensionalMiningConstraint" - { "should be full if the limit is 0, but not overfilled" in { val tank = createConstConstraint(0, 1, "const") @@ -16,7 +16,7 @@ class OneDimensionalMiningConstraintSuite extends FreeSpec with PathMockFactory "put(transaction)" - tests { (maxTxs, txs) => val constraint = createConstConstraint(maxTxs, transactionSize = 1, "txSize") - txs.foldLeft(constraint)(_.put(stub[Blockchain], _, StateSnapshot.empty)) + txs.foldLeft(constraint)(_.put(EmptyBlockchain, _, StateSnapshot.empty)) } } diff --git a/node/tests/src/test/scala/com/wavesplatform/mining/ScriptComplexityMiningConstraintSuite.scala b/node/tests/src/test/scala/com/wavesplatform/mining/ScriptComplexityMiningConstraintSuite.scala index bc88e935562..2a5b7569019 100644 --- a/node/tests/src/test/scala/com/wavesplatform/mining/ScriptComplexityMiningConstraintSuite.scala +++ b/node/tests/src/test/scala/com/wavesplatform/mining/ScriptComplexityMiningConstraintSuite.scala @@ -1,21 +1,21 @@ package com.wavesplatform.mining import com.typesafe.config.ConfigFactory -import com.wavesplatform.account.KeyPair +import com.wavesplatform.account.{Address, KeyPair} import com.wavesplatform.common.utils.EitherExt2.* import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.lang.v1.estimator.v3.ScriptEstimatorV3 -import com.wavesplatform.settings.WavesSettings +import com.wavesplatform.settings.{BlockchainSettings, WavesSettings} import com.wavesplatform.state.diffs.TransactionDiffer -import com.wavesplatform.state.{AccountScriptInfo, Blockchain, Height, LeaseBalance} +import com.wavesplatform.state.{AccountScriptInfo, Height} import com.wavesplatform.test.FlatSpec import com.wavesplatform.transaction.smart.script.ScriptCompiler -import com.wavesplatform.transaction.{DataTransaction, Transaction, TxVersion} +import com.wavesplatform.transaction.{Asset, DataTransaction, Transaction, TxVersion} +import com.wavesplatform.utils.EmptyBlockchain import org.scalacheck.Gen -import org.scalamock.scalatest.PathMockFactory -class ScriptComplexityMiningConstraintSuite extends FlatSpec with PathMockFactory { - private val settings = WavesSettings.fromRootConfig(ConfigFactory.load()) +class ScriptComplexityMiningConstraintSuite extends FlatSpec { + private val defaultSettings = WavesSettings.fromRootConfig(ConfigFactory.load()) private val complexity = OneDimensionalMiningConstraint(1000, TxEstimators.scriptsComplexity, "MaxScriptsComplexityInBlock") private val maxTxs = OneDimensionalMiningConstraint(3, TxEstimators.one, "MaxTxsInMicroBlock") @@ -25,21 +25,21 @@ class ScriptComplexityMiningConstraintSuite extends FlatSpec with PathMockFactor "ScriptComplexityMiningConstraint" should "accept non-scripted txs after limit" in { forAll(preconditions) { case (acc1, acc2, tx1, tx2, tx3) => - val blockchain = stub[Blockchain] - (() => blockchain.settings).when().returning(settings.blockchainSettings) - (() => blockchain.height).when().returning(1) - (() => blockchain.activatedFeatures).when().returning(Map(BlockchainFeatures.DataTransaction.id -> Height(0))) + val blockchain = new EmptyBlockchain { + override lazy val settings: BlockchainSettings = defaultSettings.blockchainSettings + override def height: Int = 1 + override def activatedFeatures: Map[Short, Height] = Map(BlockchainFeatures.DataTransaction.id -> Height(0)) + override def wavesBalances(addresses: Seq[Address]): Map[Address, Long] = Map(acc1.toAddress -> 10000000, acc2.toAddress -> 10000000) + override def balance(address: Address, mayBeAssetId: Asset): Long = 10000000 + override def accountScript(address: Address): Option[AccountScriptInfo] = + if (address == tx1.sender.toAddress) Some(AccountScriptInfo(acc1.publicKey, script, 1000, Map.empty)) else None + } val txDiffer = (tx: Transaction) => { val time = System.currentTimeMillis() TransactionDiffer(Some(time - 1000), time)(blockchain, tx).resultE .explicitGet() } - (blockchain.balance).when(*, *).returning(10000000) - (blockchain.wavesBalances).when(*).returning(Map(acc1.toAddress -> 10000000, acc2.toAddress -> 10000000)) - (blockchain.leaseBalance).when(*).returning(LeaseBalance(0, 0)) - (blockchain.accountScript).when(tx1.sender.toAddress).returning(Some(AccountScriptInfo(acc1.publicKey, script, 1000, Map.empty))) - (blockchain.accountScript).when(*).returning(None) val c1 = constraint.put(blockchain, tx1, txDiffer(tx1)) val cOverfilled = c1.put(blockchain, tx1, txDiffer(tx1)) diff --git a/node/tests/src/test/scala/com/wavesplatform/network/BrokenConnectionDetectorSpec.scala b/node/tests/src/test/scala/com/wavesplatform/network/BrokenConnectionDetectorSpec.scala index 9a9e477dcf1..0b979172e57 100644 --- a/node/tests/src/test/scala/com/wavesplatform/network/BrokenConnectionDetectorSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/network/BrokenConnectionDetectorSpec.scala @@ -2,11 +2,10 @@ package com.wavesplatform.network import com.wavesplatform.test.FreeSpec import io.netty.channel.embedded.EmbeddedChannel -import org.scalamock.scalatest.MockFactory import scala.concurrent.duration.DurationInt -class BrokenConnectionDetectorSpec extends FreeSpec with MockFactory { +class BrokenConnectionDetectorSpec extends FreeSpec { "should not close an active connection until the timeout" in { val handler = new BrokenConnectionDetector(400.millis) diff --git a/node/tests/src/test/scala/com/wavesplatform/network/ChannelGroupExtSpec.scala b/node/tests/src/test/scala/com/wavesplatform/network/ChannelGroupExtSpec.scala index e23fb1c3d55..3d5aa6649fb 100644 --- a/node/tests/src/test/scala/com/wavesplatform/network/ChannelGroupExtSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/network/ChannelGroupExtSpec.scala @@ -7,12 +7,11 @@ import io.netty.channel.* import io.netty.channel.embedded.EmbeddedChannel import io.netty.channel.group.DefaultChannelGroup import io.netty.util.concurrent.GlobalEventExecutor -import org.scalamock.scalatest.MockFactory import scala.jdk.CollectionConverters.* import scala.util.Random -class ChannelGroupExtSpec extends FreeSpec with MockFactory { +class ChannelGroupExtSpec extends FreeSpec { "broadcast" - { "should not send a message to the excluded channels" in { val message = "test" diff --git a/node/tests/src/test/scala/com/wavesplatform/network/ClientSpec.scala b/node/tests/src/test/scala/com/wavesplatform/network/ClientSpec.scala index e95a0426793..490b674fa39 100644 --- a/node/tests/src/test/scala/com/wavesplatform/network/ClientSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/network/ClientSpec.scala @@ -8,12 +8,11 @@ import io.netty.buffer.{ByteBuf, Unpooled} import io.netty.channel.embedded.EmbeddedChannel import io.netty.channel.group.{ChannelGroup, DefaultChannelGroup} import io.netty.util.concurrent.GlobalEventExecutor -import org.scalamock.scalatest.MockFactory import scala.concurrent.duration.DurationInt import scala.util.Random -class ClientSpec extends FreeSpec with MockFactory { +class ClientSpec extends FreeSpec { private val clientHandshake = new Handshake( applicationName = "wavesI", diff --git a/node/tests/src/test/scala/com/wavesplatform/network/HandshakeDecoderSpec.scala b/node/tests/src/test/scala/com/wavesplatform/network/HandshakeDecoderSpec.scala index 3f38ceb6780..ba3d173fd93 100644 --- a/node/tests/src/test/scala/com/wavesplatform/network/HandshakeDecoderSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/network/HandshakeDecoderSpec.scala @@ -8,9 +8,8 @@ import io.netty.buffer.Unpooled import io.netty.channel.embedded.EmbeddedChannel import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter} import org.scalacheck.{Arbitrary, Gen} -import org.scalamock.scalatest.MockFactory -class HandshakeDecoderSpec extends FreeSpec with MockFactory { +class HandshakeDecoderSpec extends FreeSpec { "should read a handshake and remove itself from the pipeline" in { var mayBeDecodedHandshake: Option[Handshake] = None diff --git a/node/tests/src/test/scala/com/wavesplatform/network/LegacyFrameCodecSpec.scala b/node/tests/src/test/scala/com/wavesplatform/network/LegacyFrameCodecSpec.scala index 2ac18cd739c..cf7e85654a1 100644 --- a/node/tests/src/test/scala/com/wavesplatform/network/LegacyFrameCodecSpec.scala +++ b/node/tests/src/test/scala/com/wavesplatform/network/LegacyFrameCodecSpec.scala @@ -12,11 +12,10 @@ import io.netty.buffer.Unpooled.wrappedBuffer import io.netty.buffer.{ByteBuf, Unpooled} import io.netty.channel.embedded.EmbeddedChannel import org.scalacheck.Gen -import org.scalamock.scalatest.MockFactory import scala.concurrent.duration.DurationInt -class LegacyFrameCodecSpec extends FreeSpec with MockFactory { +class LegacyFrameCodecSpec extends FreeSpec { "should handle one message" in forAll(issueGen) { origTx => val codec = new LegacyFrameCodecL1(PeerDatabase.NoOp, 3.minutes) diff --git a/node/tests/src/test/scala/com/wavesplatform/state/diffs/ExchangeTransactionDiffTest.scala b/node/tests/src/test/scala/com/wavesplatform/state/diffs/ExchangeTransactionDiffTest.scala index ed0f7bccf87..6c1e5f259ae 100644 --- a/node/tests/src/test/scala/com/wavesplatform/state/diffs/ExchangeTransactionDiffTest.scala +++ b/node/tests/src/test/scala/com/wavesplatform/state/diffs/ExchangeTransactionDiffTest.scala @@ -1,6 +1,5 @@ package com.wavesplatform.state.diffs -import cats.Order as _ import com.wavesplatform.account.{Address, AddressScheme, KeyPair, PrivateKey} import com.wavesplatform.block.Block import com.wavesplatform.common.state.ByteStr diff --git a/node/tests/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptActionLimitsTest.scala b/node/tests/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptActionLimitsTest.scala index 3157a8e6e1f..a733b1ae120 100644 --- a/node/tests/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptActionLimitsTest.scala +++ b/node/tests/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptActionLimitsTest.scala @@ -16,7 +16,7 @@ import com.wavesplatform.settings.{FunctionalitySettings, TestFunctionalitySetti import com.wavesplatform.state.* import com.wavesplatform.state.diffs.produceRejectOrFailedDiff import com.wavesplatform.test.* -import com.wavesplatform.transaction.{utils as _, *} +import com.wavesplatform.transaction.* import com.wavesplatform.transaction.Asset.Waves import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment diff --git a/node/tests/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptTransactionDiffTest.scala b/node/tests/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptTransactionDiffTest.scala index d87a6cab255..43a6d7c7952 100644 --- a/node/tests/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptTransactionDiffTest.scala +++ b/node/tests/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptTransactionDiffTest.scala @@ -43,7 +43,7 @@ import com.wavesplatform.transaction.assets.* import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment import com.wavesplatform.transaction.smart.script.trace.{AssetVerifierTrace, InvokeScriptTrace, TracedResult} import com.wavesplatform.transaction.smart.{InvokeScriptTransaction, SetScriptTransaction} -import com.wavesplatform.transaction.{Asset, utils as _, *} +import com.wavesplatform.transaction.* import com.wavesplatform.utils.EmptyBlockchain import org.scalatest.{EitherValues, Inside} diff --git a/node/tests/src/test/scala/com/wavesplatform/state/diffs/smart/predef/MatcherBlockchainTest.scala b/node/tests/src/test/scala/com/wavesplatform/state/diffs/smart/predef/MatcherBlockchainTest.scala index 4172f70c755..73923518e50 100644 --- a/node/tests/src/test/scala/com/wavesplatform/state/diffs/smart/predef/MatcherBlockchainTest.scala +++ b/node/tests/src/test/scala/com/wavesplatform/state/diffs/smart/predef/MatcherBlockchainTest.scala @@ -20,9 +20,8 @@ import com.wavesplatform.transaction.Asset.Waves import com.wavesplatform.transaction.smart.script.ScriptRunner import com.wavesplatform.transaction.transfer.TransferTransaction import com.wavesplatform.transaction.{Asset, ERC20Address, Transaction} -import org.scalamock.scalatest.MockFactory -class MatcherBlockchainTest extends PropSpec with MockFactory with WithDomain { +class MatcherBlockchainTest extends PropSpec, WithDomain { property("ScriptRunner.applyGeneric() avoids Blockchain calls") { val blockchain: Blockchain = new Blockchain { override def settings: BlockchainSettings = ??? diff --git a/node/tests/src/test/scala/com/wavesplatform/state/diffs/smart/predef/TransactionBindingsTest.scala b/node/tests/src/test/scala/com/wavesplatform/state/diffs/smart/predef/TransactionBindingsTest.scala index cf1e4de2ae2..081299da284 100644 --- a/node/tests/src/test/scala/com/wavesplatform/state/diffs/smart/predef/TransactionBindingsTest.scala +++ b/node/tests/src/test/scala/com/wavesplatform/state/diffs/smart/predef/TransactionBindingsTest.scala @@ -23,7 +23,7 @@ import com.wavesplatform.lang.v1.evaluator.ctx.impl.{CryptoContext, GlobalValNam import com.wavesplatform.lang.v1.parser.Parser import com.wavesplatform.lang.v1.traits.Environment import com.wavesplatform.lang.{Common, Global} -import com.wavesplatform.settings.WavesSettings +import com.wavesplatform.settings.{BlockchainSettings, WavesSettings} import com.wavesplatform.state.* import com.wavesplatform.state.diffs.ci.* import com.wavesplatform.test.* @@ -36,13 +36,12 @@ import com.wavesplatform.transaction.smart.{InvokeExpressionTransaction, InvokeS import com.wavesplatform.transaction.{Asset, CommitToGenerationTransaction, DataTransaction, Proofs, TxHelpers, TxVersion} import com.wavesplatform.utils.EmptyBlockchain import monix.eval.Coeval -import org.scalamock.scalatest.PathMockFactory import org.scalatest.EitherValues import play.api.libs.json.Json import scala.util.Random -class TransactionBindingsTest extends PropSpec with PathMockFactory with EitherValues with WithDomain { +class TransactionBindingsTest extends PropSpec, EitherValues, WithDomain { private val T = 'T'.toByte property("TransferTransaction binding") { @@ -146,7 +145,7 @@ class TransactionBindingsTest extends PropSpec with PathMockFactory with EitherV } property("CreateAliasTransaction binding") { - val tx = TxHelpers.createAlias("alias") + val tx = TxHelpers.createAlias() val result = runScript[CONST_BOOLEAN]( s""" |match tx { @@ -353,10 +352,10 @@ class TransactionBindingsTest extends PropSpec with PathMockFactory with EitherV | } |""".stripMargin - val blockchain = stub[Blockchain] - (() => blockchain.settings).when().returning(WavesSettings.default().blockchainSettings) - (() => blockchain.activatedFeatures).when().returning(Map(BlockchainFeatures.BlockV5.id -> Height(0))) - (() => blockchain.settings).when().returning(WavesSettings.default().blockchainSettings) + val blockchain = new EmptyBlockchain { + override lazy val settings: BlockchainSettings = WavesSettings.default().blockchainSettings + override def activatedFeatures: Map[Short, Height] = Map(BlockchainFeatures.BlockV5.id -> Height(0)) + } val result = runScriptWithCustomContext[CONST_BOOLEAN](script, tx, V4, blockchain) result shouldBe evaluated(true) @@ -917,8 +916,9 @@ class TransactionBindingsTest extends PropSpec with PathMockFactory with EitherV val expr = Parser.parseExpr(script).get.value val directives = DirectiveSet(V2, Account, Expression).explicitGet() - val blockchain = stub[Blockchain] - (() => blockchain.activatedFeatures).when().returning(Map(BlockchainFeatures.BlockV5.id -> Height(0))) + val blockchain = new EmptyBlockchain { + override def activatedFeatures: Map[Short, Height] = Map(BlockchainFeatures.BlockV5.id -> Height(0)) + } val ctx = PureContext.build(V2, useNewPowPrecision = true).withEnvironment[Environment] |+| diff --git a/node/tests/src/test/scala/com/wavesplatform/utils/ObservedLoadingCacheSpecification.scala b/node/tests/src/test/scala/com/wavesplatform/utils/ObservedLoadingCacheSpecification.scala index 3e63ffb52bc..f30ab61520d 100644 --- a/node/tests/src/test/scala/com/wavesplatform/utils/ObservedLoadingCacheSpecification.scala +++ b/node/tests/src/test/scala/com/wavesplatform/utils/ObservedLoadingCacheSpecification.scala @@ -2,67 +2,58 @@ package com.wavesplatform.utils import com.google.common.base.Ticker import com.google.common.cache.{CacheBuilder, CacheLoader, LoadingCache} - -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicLong import com.wavesplatform.test.FreeSpec -import monix.execution.Ack import monix.reactive.Observer -import org.scalamock.scalatest.MockFactory +import org.apache.commons.io.output.WriterOutputStream -import scala.concurrent.Future +import java.io.{PrintStream, StringWriter} +import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicLong import scala.concurrent.duration.DurationInt import scala.jdk.CollectionConverters.* -class ObservedLoadingCacheSpecification extends FreeSpec with MockFactory { +class ObservedLoadingCacheSpecification extends FreeSpec { import com.wavesplatform.utils.ObservedLoadingCacheSpecification.FakeTicker private val ExpiringTime = 10.minutes "notifies" - { "on refresh" in test { (loadingCache, changes, _) => - (changes.onNext).expects("foo").returning(Future.successful(Ack.Continue)).once() - - loadingCache.refresh("foo") + loadingCache.refresh("foo") + changes.toString shouldBe "0: --> foo\n" } "on put" in test { (loadingCache, changes, _) => - (changes.onNext).expects("foo").returning(Future.successful(Ack.Continue)).once() - - loadingCache.put("foo", 10) + loadingCache.put("foo", 10) + changes.toString shouldBe "0: --> foo\n" } "on putAll" in test { (loadingCache, changes, _) => - (changes.onNext).expects("foo").returning(Future.successful(Ack.Continue)).once() - (changes.onNext).expects("bar").returning(Future.successful(Ack.Continue)).once() - - loadingCache.putAll(Map[String, Integer]("foo" -> 10, "bar" -> 11).asJava) + loadingCache.putAll(Map[String, Integer]("foo" -> 10, "bar" -> 11).asJava) + changes.toString shouldBe "0: --> foo\n1: --> bar\n" } "on invalidate" in test { (loadingCache, changes, _) => - (changes.onNext).expects("foo").returning(Future.successful(Ack.Continue)).once() - - loadingCache.invalidate("foo") + loadingCache.invalidate("foo") + changes.toString shouldBe "0: --> foo\n" } "on invalidateAll" in test { (loadingCache, changes, _) => - (changes.onNext).expects("foo").returning(Future.successful(Ack.Continue)).once() - (changes.onNext).expects("bar").returning(Future.successful(Ack.Continue)).once() - - loadingCache.invalidateAll(Seq("foo", "bar").asJava) + loadingCache.invalidateAll(Seq("foo", "bar").asJava) + changes.toString shouldBe "0: --> foo\n1: --> bar\n" } } "don't notify" - { - "on cache expiration" in test { (loadingCache, changes, ticker) => - (changes.onNext).expects("foo").returning(Future.successful(Ack.Continue)).once() + "on cache expiration" in test { + (loadingCache, changes, ticker) => loadingCache.put("foo", 1) ticker.advance(ExpiringTime.toMillis + 100, TimeUnit.MILLISECONDS) + changes.toString shouldBe "0: --> foo\n" } } - private def test(f: (LoadingCache[String, Integer], Observer[String], FakeTicker) => Unit): Unit = { - val changes = mock[Observer[String]] - val ticker = new FakeTicker() + private def test(f: (LoadingCache[String, Integer], StringWriter, FakeTicker) => Unit): Unit = { + val ticker = new FakeTicker() val delegate = CacheBuilder .newBuilder() @@ -72,9 +63,13 @@ class ObservedLoadingCacheSpecification extends FreeSpec with MockFactory { override def load(key: String): Integer = key.length }) - val loadingCache = new ObservedLoadingCache(delegate, changes) + val sw = new StringWriter() + val loadingCache = new ObservedLoadingCache( + delegate, + Observer.dump("", new PrintStream(WriterOutputStream.builder().setWriter(sw).setWriteImmediately(true).get())) + ) - f(loadingCache, changes, ticker) + f(loadingCache, sw, ticker) } } diff --git a/node/tests/src/test/scala/com/wavesplatform/utx/UtxPoolSpecification.scala b/node/tests/src/test/scala/com/wavesplatform/utx/UtxPoolSpecification.scala index e2864fefc5f..8d078b517a5 100644 --- a/node/tests/src/test/scala/com/wavesplatform/utx/UtxPoolSpecification.scala +++ b/node/tests/src/test/scala/com/wavesplatform/utx/UtxPoolSpecification.scala @@ -4,7 +4,7 @@ import cats.data.NonEmptyList import com.wavesplatform import com.wavesplatform.* import com.wavesplatform.account.{Address, KeyPair, PublicKey} -import com.wavesplatform.block.{Block, SignedBlockHeader} +import com.wavesplatform.block.{Block, BlockHeader, SignedBlockHeader} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2.* import com.wavesplatform.consensus.TransactionsOrdering @@ -37,11 +37,10 @@ import com.wavesplatform.transaction.transfer.* import com.wavesplatform.transaction.transfer.MassTransferTransaction.ParsedTransfer import com.wavesplatform.transaction.utils.Signed import com.wavesplatform.transaction.{Transaction, *} -import com.wavesplatform.utils.Time +import com.wavesplatform.utils.{EmptyBlockchain, Time} import com.wavesplatform.utx.UtxPool.PackStrategy import org.scalacheck.Gen.* import org.scalacheck.{Arbitrary, Gen} -import org.scalamock.scalatest.MockFactory import org.scalatest.EitherValues import org.scalatest.concurrent.Eventually @@ -64,7 +63,7 @@ private object UtxPoolSpecification { } } -class UtxPoolSpecification extends FreeSpec with MockFactory with BlocksTransactionsHelpers with WithDomain with EitherValues with Eventually { +class UtxPoolSpecification extends FreeSpec, BlocksTransactionsHelpers, WithDomain, EitherValues, Eventually { private val PoolDefaultMaxBytes = 50 * 1024 * 1024 // 50 MB import DomainPresets.* @@ -1030,33 +1029,46 @@ class UtxPoolSpecification extends FreeSpec with MockFactory with BlocksTransact txs <- Gen.nonEmptyListOf(transfer(acc1, 10000000L, ntpTime).suchThat(_.fee.value < tx1.fee.value)) } yield (acc, acc1, tx1, txs) - forAll(gen) { case (acc, acc1, tx1, rest) => - val blockchain = stub[Blockchain] - (() => blockchain.settings).when().returning(WavesSettings.default().blockchainSettings) - (() => blockchain.height).when().returning(1) - (() => blockchain.activatedFeatures).when().returning(Map.empty) - - val utx = - new UtxPoolImpl( - ntpTime, - blockchain, - WavesSettings.default().utxSettings, - WavesSettings.default().maxTxErrorLogSize, - isMiningEnabled = true + forAll(gen) { case (acc, _, tx1, rest) => + + var utx: UtxPool = null // this is needed to resolve circular references between UTX and blockchain stub + val blockchain = new EmptyBlockchain { + override lazy val settings: BlockchainSettings = WavesSettings.default().blockchainSettings + override def balance(address: Address, mayBeAssetId: Asset): Long = ENOUGH_AMT + + override def blockHeader(height: Int): Option[SignedBlockHeader] = Some( + SignedBlockHeader( + BlockHeader( + 0, + System.currentTimeMillis(), + ByteStr.empty, + 0, + ByteStr.empty, + PublicKey(new Array[Byte](32)), + Vector.empty, + 0, + ByteStr.empty, + None, + None, + None + ), + ByteStr.empty + ) ) - (blockchain.balance).when(*, *).returning(ENOUGH_AMT).repeat((rest.length + 1) * 2) - - (blockchain.balance).when(*, *).returning(ENOUGH_AMT) - - (blockchain.wavesBalances).when(*).returning(Map(acc.toAddress -> ENOUGH_AMT, acc1.toAddress -> ENOUGH_AMT)) - (blockchain.leaseBalance).when(*).returning(LeaseBalance(0, 0)) - (blockchain.accountScript).when(*).onCall { (_: Address) => - utx.removeAll(rest) - None + override def accountScript(address: Address): Option[AccountScriptInfo] = { + if (address == acc.toAddress) utx.removeAll(rest) + None + } } - val tb = TestBlock.create(Nil).block - (blockchain.blockHeader).when(*).returning(Some(SignedBlockHeader(tb.header, tb.signature))) + + utx = new UtxPoolImpl( + ntpTime, + blockchain, + WavesSettings.default().utxSettings, + WavesSettings.default().maxTxErrorLogSize, + isMiningEnabled = true + ) utx.putIfNew(tx1).resultE should beRight rest.foreach(utx.putIfNew(_).resultE should beRight) diff --git a/node/tests/src/test/scala/tools/FirstDifferentBlock.scala b/node/tests/src/test/scala/tools/FirstDifferentBlock.scala index 3b6782073e9..0c88705f197 100644 --- a/node/tests/src/test/scala/tools/FirstDifferentBlock.scala +++ b/node/tests/src/test/scala/tools/FirstDifferentBlock.scala @@ -2,7 +2,7 @@ package tools import play.api.libs.json.Json -object FirstDifferentBlock extends App { +object FirstDifferentBlock { def get(url: String) = scala.io.Source.fromURL(url).mkString @@ -41,5 +41,5 @@ object FirstDifferentBlock extends App { } } - println("first different block height is " + firstDifferent(1, 258, nodeComparator(DEVNET3D, DEVNET3))) + @main def run(): Unit = println("first different block height is " + firstDifferent(1, 258, nodeComparator(DEVNET3D, DEVNET3))) } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 20ea857e569..491a5da2936 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,10 +4,6 @@ import sbt.{Def, *} import scalapb.compiler.Version.scalapbVersion object Dependencies { - val DebAmd64 = config("DebAmd64") - val DebArm64 = config("DebArm64") - - private def nettyModule(module: String) = "io.netty" % s"netty-$module" % "4.2.10.Final" val gProtoVersion = "4.33.5" @@ -46,7 +42,7 @@ object Dependencies { private def jacksonModule(group: String, module: String, version: String = "2.20.1") = s"com.fasterxml.jackson.$group" % s"jackson-$module" % version - private def web3jModule(module: String) = "org.web3j" % module % "4.9.8" // 4.10+ requires Java 17 https://github.com/web3j/web3j/issues/1907 + private def web3jModule(module: String) = "org.web3j" % module % "4.13.0" // 4.14+ requires Java 21 https://github.com/LFDT-web3j/web3j/releases/tag/v4.14.0 def monixModule(module: String): Def.Initialize[ModuleID] = Def.setting("io.monix" %%% s"monix-$module" % "3.4.1") @@ -56,7 +52,7 @@ object Dependencies { val googleGuava = "com.google.guava" % "guava" % "33.5.0-jre" val kamonCore = kamonModule("core") val machinist = "org.typelevel" %% "machinist" % "0.6.8" - val logback = "ch.qos.logback" % "logback-classic" % "1.5.31" + val logback = "ch.qos.logback" % "logback-classic" % "1.5.32" val asyncHttpClient = "org.asynchttpclient" % "async-http-client" % "3.0.7" val curve25519 = "com.wavesplatform" % "curve25519-java" % "0.6.6" val nettyHandler = nettyModule("handler") @@ -217,5 +213,5 @@ object Dependencies { // https://github.com/sbt/sbt-javaagent#scopes // dist (only sbt-native-packager), because causes using logs before needed, so System.setProperty in RideRunnerWithPreparedStateApp has no effect. lazy val kanela = - Seq("io.kamon" % "kanela-agent" % "1.0.18" % "dist") + Seq("io.kamon" % "kanela-agent" % "2.0.0" % "dist") } diff --git a/project/IntegrationTestsPlugin.scala b/project/IntegrationTestsPlugin.scala index 4f7351d8833..a548d6fd18f 100644 --- a/project/IntegrationTestsPlugin.scala +++ b/project/IntegrationTestsPlugin.scala @@ -1,18 +1,18 @@ -import java.time.LocalDateTime -import java.time.format.DateTimeFormatter - -import com.spotify.docker.client.DefaultDockerClient -import sbt.Keys._ +import com.github.dockerjava.core.{DefaultDockerClientConfig, DockerClientImpl} +import com.github.dockerjava.httpclient5.ApacheDockerHttpClient +import sbt.* +import sbt.Keys.* import sbt.Tests.Group -import sbt._ +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter import scala.util.control.NonFatal // Separate projects for integration tests because of IDEA: https://youtrack.jetbrains.com/issue/SCL-14363#focus=streamItem-27-3061842.0-0 object IntegrationTestsPlugin extends AutoPlugin { object autoImport extends ItKeys - import autoImport._ + import autoImport.* override def projectSettings: Seq[Def.Setting[_]] = inConfig(Test)( @@ -74,12 +74,17 @@ object IntegrationTestsPlugin extends AutoPlugin { maxParallelSuites := Option(Integer.getInteger("waves.it.max-parallel-suites")) .getOrElse[Integer] { try { - val docker = DefaultDockerClient.fromEnv().build() + val config = DefaultDockerClientConfig.createDefaultConfigBuilder().build() + val httpClient = new ApacheDockerHttpClient.Builder().dockerHost(config.getDockerHost).build() + val dockerClient = DockerClientImpl.getInstance(config, httpClient) try { - val dockerCpu: Int = docker.info().cpus() + val dockerCpu = dockerClient.infoCmd().exec().getNCPU sLog.value.info(s"Docker CPU count: $dockerCpu") dockerCpu * 2 - } finally docker.close() + } finally { + httpClient.close() + dockerClient.close() + } } catch { case NonFatal(e) => sLog.value.warn(s"Could not connect to Docker, is the daemon running? ${e.getMessage}") diff --git a/project/Network.scala b/project/Network.scala index 3ef8e4e6229..127d7ba6e52 100644 --- a/project/Network.scala +++ b/project/Network.scala @@ -1,10 +1,10 @@ -import sbt._ -import complete.DefaultParsers._ -import sbt.complete._ +import sbt.* +import complete.DefaultParsers.* +import sbt.complete.* sealed abstract class Network(val suffix: String) { lazy val packageSuffix: String = if (suffix == Mainnet.suffix) "" else "-" + suffix - override val toString: String = suffix +// override val toString: String = suffix } object Network { @@ -20,7 +20,7 @@ object Network { def default(): Network = sys.props.get("network").fold[Network](Mainnet)(apply) } -object Mainnet extends Network("mainnet") -object Testnet extends Network("testnet") -object Devnet extends Network("devnet") -object Stagenet extends Network("stagenet") +case object Mainnet extends Network("mainnet") +case object Testnet extends Network("testnet") +case object Devnet extends Network("devnet") +case object Stagenet extends Network("stagenet") diff --git a/project/build.properties b/project/build.properties index bcdf77384e3..c605beba567 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.12.1 +sbt.version=1.12.3 diff --git a/project/plugins.sbt b/project/plugins.sbt index 9938440eefb..080b101096c 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -11,20 +11,22 @@ libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "1.0.0-alpha Seq( "com.eed3si9n" % "sbt-assembly" % "2.3.1", "com.github.sbt" % "sbt-git" % "2.1.0", - "com.github.sbt" % "sbt-native-packager" % "1.11.3", + "com.github.sbt" % "sbt-native-packager" % "1.11.7", "com.github.sbt" % "sbt-pgp" % "2.3.1", "com.lightbend.sbt" % "sbt-javaagent" % "0.1.6", "org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2", - "org.scala-js" % "sbt-scalajs" % "1.20.1", - "org.scalameta" % "sbt-scalafmt" % "2.5.5", + "org.scala-js" % "sbt-scalajs" % "1.20.2", + "org.scalameta" % "sbt-scalafmt" % "2.5.6", "pl.project13.scala" % "sbt-jmh" % "0.4.8" ).map(addSbtPlugin) +val dockerJavaVersion = "3.7.0" + libraryDependencies ++= Seq( - "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.20.0", - "org.hjson" % "hjson" % "3.1.0", - "org.vafer" % "jdeb" % "1.14" artifacts Artifact("jdeb", "jar", "jar"), - "org.slf4j" % "jcl-over-slf4j" % "2.0.17", - ("com.spotify" % "docker-client" % "8.16.0") - .exclude("commons-logging", "commons-logging") + "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.21.0", + "org.hjson" % "hjson" % "3.1.0", + "org.vafer" % "jdeb" % "1.14" artifacts Artifact("jdeb", "jar", "jar"), + "org.slf4j" % "jcl-over-slf4j" % "2.0.17", + "com.github.docker-java" % "docker-java-core" % dockerJavaVersion, + "com.github.docker-java" % "docker-java-transport-httpclient5" % dockerJavaVersion ) diff --git a/ride-runner/build.sbt b/ride-runner/build.sbt index 63384aa1774..807858c9218 100644 --- a/ride-runner/build.sbt +++ b/ride-runner/build.sbt @@ -79,7 +79,7 @@ inConfig(Debian)( maintainer := "com.wavesplatform", packageSource := sourceDirectory.value / "package", linuxStartScriptTemplate := (packageSource.value / "systemd.service").toURI.toURL, - debianPackageDependencies += "java11-runtime-headless", + debianPackageDependencies += "java17-runtime-headless", maintainerScripts := maintainerScriptsFromDirectory(packageSource.value / "debian", Seq("postinst", "postrm", "prerm")) ) ) diff --git a/ride-runner/src/main/scala/com/wavesplatform/api/observers/ManualGrpcObserver.scala b/ride-runner/src/main/scala/com/wavesplatform/api/observers/ManualGrpcObserver.scala index 28dd4882a02..9381c5e9682 100644 --- a/ride-runner/src/main/scala/com/wavesplatform/api/observers/ManualGrpcObserver.scala +++ b/ride-runner/src/main/scala/com/wavesplatform/api/observers/ManualGrpcObserver.scala @@ -1,13 +1,14 @@ package com.wavesplatform.api.observers -import com.wavesplatform.utils.{LoggerFacade, ScorexLogging} +import com.typesafe.scalalogging.Logger +import com.wavesplatform.utils.ScorexLogging import io.grpc.stub.{ClientCallStreamObserver, ClientResponseObserver} import org.slf4j.LoggerFactory import java.util.concurrent.atomic.AtomicBoolean -class ManualGrpcObserver[RequestT, EventT] extends ClientResponseObserver[RequestT, EventT] with ScorexLogging { - protected override lazy val log = LoggerFacade(LoggerFactory.getLogger(s"${getClass.getSimpleName}#${hashCode()}")) +class ManualGrpcObserver[RequestT, EventT] extends ClientResponseObserver[RequestT, EventT], ScorexLogging { + protected override lazy val log = Logger(LoggerFactory.getLogger(s"${getClass.getSimpleName}#${hashCode()}")) private val working = new AtomicBoolean(false) private var requestStream: ClientCallStreamObserver[RequestT] = null diff --git a/ride-runner/src/main/scala/com/wavesplatform/ride/runner/caches/disk/DefaultDiskCaches.scala b/ride-runner/src/main/scala/com/wavesplatform/ride/runner/caches/disk/DefaultDiskCaches.scala index a5268d551a5..9b080895092 100644 --- a/ride-runner/src/main/scala/com/wavesplatform/ride/runner/caches/disk/DefaultDiskCaches.scala +++ b/ride-runner/src/main/scala/com/wavesplatform/ride/runner/caches/disk/DefaultDiskCaches.scala @@ -2,6 +2,7 @@ package com.wavesplatform.ride.runner.caches.disk import cats.syntax.option.* import com.github.benmanes.caffeine.cache.{Cache, Caffeine} +import com.typesafe.scalalogging.Logger import com.wavesplatform.account.{Address, Alias} import com.wavesplatform.blockchain.SignedBlockHeaderWithVrf import com.wavesplatform.collections.syntax.* @@ -13,7 +14,7 @@ import com.wavesplatform.ride.runner.stats.KamonCaffeineStats import com.wavesplatform.state.{DataEntry, EmptyDataEntry, Height, LeaseBalance, TransactionId} import com.wavesplatform.transaction.Asset import com.wavesplatform.transaction.Asset.IssuedAsset -import com.wavesplatform.utils.{LoggerFacade, ScorexLogging} +import com.wavesplatform.utils.ScorexLogging import org.slf4j.LoggerFactory import java.lang.Long as JLong @@ -402,7 +403,7 @@ class DefaultDiskCaches private (storage: RideDbAccess, initialBlockHeadersLastH log.trace("setActivatedFeatures") } - private def mkLogger(name: String) = LoggerFacade(LoggerFactory.getLogger(s"${getClass.getName}.$name")) + private def mkLogger(name: String) = Logger(LoggerFactory.getLogger(s"${getClass.getName}.$name")) } object DefaultDiskCaches { diff --git a/ride-runner/src/main/scala/com/wavesplatform/ride/runner/entrypoints/AppInitializer.scala b/ride-runner/src/main/scala/com/wavesplatform/ride/runner/entrypoints/AppInitializer.scala index 10448c227cb..5845c5400f5 100644 --- a/ride-runner/src/main/scala/com/wavesplatform/ride/runner/entrypoints/AppInitializer.scala +++ b/ride-runner/src/main/scala/com/wavesplatform/ride/runner/entrypoints/AppInitializer.scala @@ -5,7 +5,7 @@ import com.typesafe.config.{Config, ConfigFactory, ConfigParseOptions} import com.wavesplatform.Version import com.wavesplatform.account.AddressScheme import com.wavesplatform.ride.runner.entrypoints.settings.RideRunnerGlobalSettings -import com.wavesplatform.settings.{loadConfig as _, *} +import com.wavesplatform.settings.BlockchainSettings import com.wavesplatform.utils.{Misconfiguration, ScorexLogging, forceStopApplication} import java.io.File