From 97f1458274564ba86ed24bc359c19a75d394e917 Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Tue, 5 Dec 2023 14:08:04 +0300 Subject: [PATCH 1/9] Reduced number of arguments --- lang/doc/v8/funcs/blockchain-functions.hjson | 4 ++-- .../scala/com/wavesplatform/lang/utils/package.scala | 2 +- .../lang/v1/evaluator/ctx/impl/waves/Functions.scala | 5 ++--- .../com/wavesplatform/lang/v1/traits/Environment.scala | 2 +- .../src/main/scala/com/wavesplatform/lang/Common.scala | 2 +- .../wavesplatform/lang/compiler/DecompilerTest.scala | 2 +- .../transaction/smart/WavesEnvironment.scala | 10 +++++----- .../state/diffs/smart/predef/CalculateDelayTest.scala | 10 +++++----- 8 files changed, 18 insertions(+), 19 deletions(-) diff --git a/lang/doc/v8/funcs/blockchain-functions.hjson b/lang/doc/v8/funcs/blockchain-functions.hjson index ed60aad8d4..f5cd8722fc 100644 --- a/lang/doc/v8/funcs/blockchain-functions.hjson +++ b/lang/doc/v8/funcs/blockchain-functions.hjson @@ -72,9 +72,9 @@ } { name: "calculateDelay" - params: [ "ByteVector", "Int", "Address", "Int" ] + params: [ "ByteVector", "Address", "Int" ] doc: "Calculates mining delay using Fair PoS calculator." - paramsDoc: [ "hit source", "base target", "generator address", "generator balance" ] + paramsDoc: [ "hit source", "generator address", "generator balance" ] complexity: 1 } ] diff --git a/lang/shared/src/main/scala/com/wavesplatform/lang/utils/package.scala b/lang/shared/src/main/scala/com/wavesplatform/lang/utils/package.scala index c65012ac24..1c244dd1e5 100644 --- a/lang/shared/src/main/scala/com/wavesplatform/lang/utils/package.scala +++ b/lang/shared/src/main/scala/com/wavesplatform/lang/utils/package.scala @@ -53,7 +53,7 @@ package object utils { override def addressFromString(address: String): Either[String, Recipient.Address] = ??? override def addressFromPublicKey(publicKey: ByteStr): Either[String, Address] = ??? override def accountScript(addressOrAlias: Recipient): Option[Script] = ??? - override def calculateDelay(hs: ByteStr, bt: Long, gt: ByteStr, b: Long): Long = ??? + override def calculateDelay(hs: ByteStr, gt: ByteStr, b: Long): Long = ??? override def callScript( dApp: Address, func: String, 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 c12a726ef3..7f68a1abc2 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 @@ -1003,7 +1003,6 @@ object Functions { val args = Seq( ("hit source", BYTESTR), - ("base target", LONG), ("generator", addressType), ("balance", LONG) ) @@ -1018,7 +1017,7 @@ object Functions { new ContextfulNativeFunction.Simple[Environment]("calculateDelay", LONG, args) { override def evaluate[F[_]: Monad](env: Environment[F], args: List[EVALUATED]): F[Either[ExecutionError, EVALUATED]] = args match { - case CONST_BYTESTR(hitSource) :: CONST_LONG(baseTarget) :: CaseObj(`addressType`, fields) :: CONST_LONG(balance) :: Nil => + case CONST_BYTESTR(hitSource) :: CaseObj(`addressType`, fields) :: CONST_LONG(balance) :: Nil => val addressBytes = fields("bytes").asInstanceOf[CONST_BYTESTR].bs if (addressBytes.size > AddressLength) { val error = CommonError(s"Address bytes length = ${addressBytes.size} exceeds limit = $AddressLength") @@ -1027,7 +1026,7 @@ object Functions { val error = CommonError(s"Hit source bytes length = ${hitSource.size} exceeds limit = $MaxHitSourceLength") (error: ExecutionError).asLeft[EVALUATED].pure[F] } else { - val delay = env.calculateDelay(hitSource, baseTarget, addressBytes, balance) + val delay = env.calculateDelay(hitSource, addressBytes, balance) (CONST_LONG(delay): EVALUATED).asRight[ExecutionError].pure[F] } case xs => diff --git a/lang/shared/src/main/scala/com/wavesplatform/lang/v1/traits/Environment.scala b/lang/shared/src/main/scala/com/wavesplatform/lang/v1/traits/Environment.scala index ac61d73b63..d66e7cad2d 100644 --- a/lang/shared/src/main/scala/com/wavesplatform/lang/v1/traits/Environment.scala +++ b/lang/shared/src/main/scala/com/wavesplatform/lang/v1/traits/Environment.scala @@ -50,5 +50,5 @@ trait Environment[F[_]] { availableComplexity: Int, reentrant: Boolean ): Coeval[F[(Either[ValidationError, (EVALUATED, Log[F])], Int)]] - def calculateDelay(hitSource: ByteStr, baseTarget: Long, generator: ByteStr, balance: Long): Long + def calculateDelay(hitSource: ByteStr, generator: ByteStr, balance: Long): Long } diff --git a/lang/testkit/src/main/scala/com/wavesplatform/lang/Common.scala b/lang/testkit/src/main/scala/com/wavesplatform/lang/Common.scala index 730c910446..da202558c3 100644 --- a/lang/testkit/src/main/scala/com/wavesplatform/lang/Common.scala +++ b/lang/testkit/src/main/scala/com/wavesplatform/lang/Common.scala @@ -96,7 +96,7 @@ object Common { def addressFromString(address: String): Either[String, Recipient.Address] = ??? def addressFromPublicKey(publicKey: ByteStr): Either[String, Address] = ??? def accountScript(addressOrAlias: Recipient): Option[Script] = ??? - def calculateDelay(hs: ByteStr, bt: Long, gt: ByteStr, b: Long): Long = ??? + def calculateDelay(hs: ByteStr, gt: ByteStr, b: Long): Long = ??? def callScript( dApp: Address, func: String, diff --git a/lang/tests/src/test/scala/com/wavesplatform/lang/compiler/DecompilerTest.scala b/lang/tests/src/test/scala/com/wavesplatform/lang/compiler/DecompilerTest.scala index d78e73802a..4228979c5d 100644 --- a/lang/tests/src/test/scala/com/wavesplatform/lang/compiler/DecompilerTest.scala +++ b/lang/tests/src/test/scala/com/wavesplatform/lang/compiler/DecompilerTest.scala @@ -1118,7 +1118,7 @@ class DecompilerTest extends PropSpec { } property("calculateDelay()") { - val script = "calculateDelay(base58'aaa', 123, Address(base58'bbb'), 456)" + val script = "calculateDelay(base58'aaa', Address(base58'bbb'), 456)" assertDecompile(script, script, V8) } diff --git a/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala b/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala index f8bbd054bf..5796bfb1c5 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala @@ -1,7 +1,7 @@ package com.wavesplatform.transaction.smart -import cats.implicits.catsSyntaxSemigroup import cats.Id +import cats.implicits.catsSyntaxSemigroup import cats.syntax.either.* import com.wavesplatform.account import com.wavesplatform.account.{AddressOrAlias, PublicKey} @@ -22,11 +22,10 @@ import com.wavesplatform.lang.v1.traits.* import com.wavesplatform.lang.v1.traits.domain.* import com.wavesplatform.lang.v1.traits.domain.Recipient.* import com.wavesplatform.lang.{Global, ValidationError} -import com.wavesplatform.state.* import com.wavesplatform.state.BlockRewardCalculator.CurrentBlockRewardPart +import com.wavesplatform.state.* import com.wavesplatform.state.diffs.invoke.InvokeScriptDiff.validateIntermediateBalances import com.wavesplatform.state.diffs.invoke.{InvokeScript, InvokeScriptDiff, InvokeScriptTransactionLike} -import com.wavesplatform.state.SnapshotBlockchain import com.wavesplatform.transaction.Asset.* import com.wavesplatform.transaction.TxValidationError.{FailedTransactionError, GenericError} import com.wavesplatform.transaction.assets.exchange.Order @@ -268,8 +267,9 @@ class WavesEnvironment( reentrant: Boolean ): Coeval[(Either[ValidationError, (EVALUATED, Log[Id])], Int)] = ??? - override def calculateDelay(hitSource: ByteStr, baseTarget: Long, generator: ByteStr, balance: Long): Long = { - val hit = Global.blake2b256(hitSource.arr ++ generator.arr).take(PoSCalculator.HitSize) + override def calculateDelay(hitSource: ByteStr, generator: ByteStr, balance: Long): Long = { + val hit = Global.blake2b256(hitSource.arr ++ generator.arr).take(PoSCalculator.HitSize) + val baseTarget = blockchain.lastBlockHeader.map(_.header.baseTarget).getOrElse(0L) FairPoSCalculator.V2.calculateDelay(BigInt(1, hit), baseTarget, balance) } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala index af47ac69af..c27ea678ff 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala @@ -20,9 +20,9 @@ class CalculateDelayTest extends PropSpec with WithDomain { | let address1 = i.caller | let address2 = Address(base58'${signer(2).toAddress}') | let address3 = Address(base58'${signer(3).toAddress}') - | let lowest = calculateDelay(hitSource, lastBlock.baseTarget, address1, 10 * 1000 * 1000) - | let medium = calculateDelay(hitSource, lastBlock.baseTarget, address2, 30 * 1000 * 1000) - | let largest = calculateDelay(hitSource, lastBlock.baseTarget, address3, 90 * 1000 * 1000) + | let lowest = calculateDelay(hitSource, address1, 10 * 1000 * 1000) + | let medium = calculateDelay(hitSource, address2, 30 * 1000 * 1000) + | let largest = calculateDelay(hitSource, address3, 90 * 1000 * 1000) | [ | IntegerEntry("lowest", lowest), | IntegerEntry("medium", medium), @@ -32,13 +32,13 @@ class CalculateDelayTest extends PropSpec with WithDomain { | | @Callable(i) | func error1() = { - | strict r = calculateDelay(base58'${ByteStr.fill(97)(1)}', 0, i.caller, 0) + | strict r = calculateDelay(base58'${ByteStr.fill(97)(1)}', i.caller, 0) | [] | } | | @Callable(i) | func error2() = { - | strict r = calculateDelay(lastBlock.generationSignature, 0, Address(base58'${ByteStr.fill(27)(1)}'), 0) + | strict r = calculateDelay(lastBlock.generationSignature, Address(base58'${ByteStr.fill(27)(1)}'), 0) | [] | } """.stripMargin From a1205233a264d8aca0c04457b4d8a5918bd4f717 Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Tue, 5 Dec 2023 14:09:24 +0300 Subject: [PATCH 2/9] Corrected error message --- .../lang/v1/evaluator/ctx/impl/waves/Functions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7f68a1abc2..4bd8d27cd2 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 @@ -1030,7 +1030,7 @@ object Functions { (CONST_LONG(delay): EVALUATED).asRight[ExecutionError].pure[F] } case xs => - notImplemented[Id, EVALUATED]("calculateDelay(hitSource: ByteVector, baseTarget: ByteVector, generator: Address, balance: Long)", xs) + notImplemented[Id, EVALUATED]("calculateDelay(hitSource: ByteVector, generator: Address, balance: Long)", xs) } } } From d2794ebecee4b69b82da03395b7f1584be048b09 Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Tue, 5 Dec 2023 14:12:43 +0300 Subject: [PATCH 3/9] minBlockTime = 0 --- .../com/wavesplatform/transaction/smart/WavesEnvironment.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala b/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala index 5796bfb1c5..ce81011a8d 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala @@ -270,7 +270,7 @@ class WavesEnvironment( override def calculateDelay(hitSource: ByteStr, generator: ByteStr, balance: Long): Long = { val hit = Global.blake2b256(hitSource.arr ++ generator.arr).take(PoSCalculator.HitSize) val baseTarget = blockchain.lastBlockHeader.map(_.header.baseTarget).getOrElse(0L) - FairPoSCalculator.V2.calculateDelay(BigInt(1, hit), baseTarget, balance) + FairPoSCalculator(0, 0).calculateDelay(BigInt(1, hit), baseTarget, balance) } private def getRewards(generator: PublicKey, height: Int): Seq[(Address, Long)] = { From 802f9d88a24176ed8334780dcb4c2bd286cbedba Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Tue, 5 Dec 2023 14:19:37 +0300 Subject: [PATCH 4/9] Balance check --- .../v1/evaluator/ctx/impl/waves/Functions.scala | 3 +++ .../diffs/smart/predef/CalculateDelayTest.scala | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) 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 4bd8d27cd2..806300390f 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 @@ -1025,6 +1025,9 @@ object Functions { } else if (hitSource.size > MaxHitSourceLength) { val error = CommonError(s"Hit source bytes length = ${hitSource.size} exceeds limit = $MaxHitSourceLength") (error: ExecutionError).asLeft[EVALUATED].pure[F] + } else if (balance <= 0) { + val error = CommonError(s"Unexpected non-positive balance = $balance") + (error: ExecutionError).asLeft[EVALUATED].pure[F] } else { val delay = env.calculateDelay(hitSource, addressBytes, balance) (CONST_LONG(delay): EVALUATED).asRight[ExecutionError].pure[F] diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala index c27ea678ff..b7b868dd15 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala @@ -4,6 +4,7 @@ import com.wavesplatform.common.state.ByteStr import com.wavesplatform.db.WithDomain import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.lang.directives.values.V8 +import com.wavesplatform.lang.v1.compiler.Terms.CONST_LONG import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.test.* import com.wavesplatform.transaction.TxHelpers.* @@ -32,13 +33,19 @@ class CalculateDelayTest extends PropSpec with WithDomain { | | @Callable(i) | func error1() = { - | strict r = calculateDelay(base58'${ByteStr.fill(97)(1)}', i.caller, 0) + | strict r = calculateDelay(base58'${ByteStr.fill(97)(1)}', i.caller, 1) | [] | } | | @Callable(i) | func error2() = { - | strict r = calculateDelay(lastBlock.generationSignature, Address(base58'${ByteStr.fill(27)(1)}'), 0) + | strict r = calculateDelay(lastBlock.generationSignature, Address(base58'${ByteStr.fill(27)(1)}'), 1) + | [] + | } + | + | @Callable(i) + | func error3(balance: Int) = { + | strict r = calculateDelay(lastBlock.generationSignature, Address(base58''), balance) | [] | } """.stripMargin @@ -66,6 +73,8 @@ class CalculateDelayTest extends PropSpec with WithDomain { d.appendBlock(setScript(secondSigner, contract)) d.appendBlockE(invoke(func = Some("error1"))) should produce("Hit source bytes length = 97 exceeds limit = 96") d.appendBlockE(invoke(func = Some("error2"))) should produce("Address bytes length = 27 exceeds limit = 26") + d.appendBlockE(invoke(func = Some("error3"), args = Seq(CONST_LONG(-1)))) should produce("Unexpected non-positive balance = -1") + d.appendBlockE(invoke(func = Some("error3"), args = Seq(CONST_LONG(0)))) should produce("Unexpected non-positive balance = 0") } } } From 8a6782e4d0111d14668ababea71887500c3f3115 Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Tue, 5 Dec 2023 14:38:34 +0300 Subject: [PATCH 5/9] Function results --- .../smart/predef/CalculateDelayTest.scala | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala index b7b868dd15..9cd025320a 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala @@ -6,6 +6,7 @@ import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.lang.directives.values.V8 import com.wavesplatform.lang.v1.compiler.Terms.CONST_LONG import com.wavesplatform.lang.v1.compiler.TestCompiler +import com.wavesplatform.state.IntegerDataEntry import com.wavesplatform.test.* import com.wavesplatform.transaction.TxHelpers.* @@ -30,6 +31,15 @@ class CalculateDelayTest extends PropSpec with WithDomain { | IntegerEntry("largest", largest) | ] | } + | + | @Callable(i) + | func results() = + | [ + | IntegerEntry("1", calculateDelay(base58'', Address(base58''), 1)), + | IntegerEntry("2", calculateDelay(base58'${ByteStr.fill(96)(1)}', Address(base58'${ByteStr.fill(26)(1)}'), ${Int.MaxValue})), + | IntegerEntry("3", calculateDelay(base58'${ByteStr.fill(96)(1)}', Address(base58'${ByteStr.fill(26)(1)}'), ${50_000L * Int.MaxValue})), + | IntegerEntry("4", calculateDelay(base58'${ByteStr.fill(96)(1)}', Address(base58'${ByteStr.fill(26)(1)}'), ${75_000L * Int.MaxValue})) + | ] | | @Callable(i) | func error1() = { @@ -68,6 +78,19 @@ class CalculateDelayTest extends PropSpec with WithDomain { } } + property("results") { + withDomain(TransactionStateSnapshot, AddrWithBalance.enoughBalances(secondSigner)) { d => + d.appendBlock(setScript(secondSigner, contract)) + d.appendBlock(invoke(func = Some("results"))) + d.liquidSnapshot.accountData.head._2.values.toSeq shouldBe Seq( + IntegerDataEntry("1", 1612717), + IntegerDataEntry("2", 44183), + IntegerDataEntry("3", 1), + IntegerDataEntry("4", 0) + ) + } + } + property("errors of calculateDelay()") { withDomain(TransactionStateSnapshot, AddrWithBalance.enoughBalances(secondSigner)) { d => d.appendBlock(setScript(secondSigner, contract)) From 0ccd881900383fdfa248e8067bf98b5020d14fb0 Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Tue, 5 Dec 2023 14:57:44 +0300 Subject: [PATCH 6/9] Fixed error --- .../lang/v1/repl/node/ErrorMessageEnvironment.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/ErrorMessageEnvironment.scala b/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/ErrorMessageEnvironment.scala index 42d24757ad..41876c6afd 100644 --- a/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/ErrorMessageEnvironment.scala +++ b/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/ErrorMessageEnvironment.scala @@ -34,7 +34,7 @@ case class ErrorMessageEnvironment[F[_]](message: String) extends Environment[F] override def addressFromString(address: String): Either[String, Recipient.Address] = unavailable override def addressFromPublicKey(publicKey: ByteStr): Either[String, Address] = unavailable override def accountScript(addressOrAlias: Recipient): F[Option[Script]] = unavailable - override def calculateDelay(hitSource: ByteStr, bt: Long, generator: ByteStr, balance: Long): Long = unavailable + override def calculateDelay(hitSource: ByteStr, generator: ByteStr, balance: Long): Long = unavailable override def callScript( dApp: Address, func: String, From 8f53325822ac7bb24417e2ace00592a05f4ea85f Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Tue, 5 Dec 2023 15:23:47 +0300 Subject: [PATCH 7/9] Reduced number of arguments to 2 --- .../v1/EnvironmentFunctionsBenchmark.scala | 2 +- .../state/CalculateDelayBenchmark.scala | 8 ++-- lang/doc/v8/funcs/blockchain-functions.hjson | 4 +- .../wavesplatform/lang/utils/package.scala | 2 +- .../evaluator/ctx/impl/waves/Functions.scala | 9 +---- .../lang/v1/traits/Environment.scala | 2 +- .../scala/com/wavesplatform/lang/Common.scala | 6 +-- .../transaction/smart/WavesEnvironment.scala | 11 ++++-- .../smart/predef/CalculateDelayTest.scala | 37 ++++++++----------- .../repl/node/ErrorMessageEnvironment.scala | 2 +- .../v1/repl/node/http/WebEnvironment.scala | 2 +- .../environments/TrackedDAppEnvironment.scala | 4 +- 12 files changed, 41 insertions(+), 48 deletions(-) diff --git a/benchmark/src/test/scala/com/wavesplatform/lang/v1/EnvironmentFunctionsBenchmark.scala b/benchmark/src/test/scala/com/wavesplatform/lang/v1/EnvironmentFunctionsBenchmark.scala index 849d2a0777..bf14f6b9b1 100644 --- a/benchmark/src/test/scala/com/wavesplatform/lang/v1/EnvironmentFunctionsBenchmark.scala +++ b/benchmark/src/test/scala/com/wavesplatform/lang/v1/EnvironmentFunctionsBenchmark.scala @@ -132,7 +132,7 @@ object EnvironmentFunctionsBenchmark { override def accountScript(addressOrAlias: Recipient): Option[Script] = ??? - override def calculateDelay(hitSource: ByteStr, baseTarget: Long, generator: ByteStr, balance: Long): Long = ??? + override def calculateDelay(generator: ByteStr, balance: Long): Long = ??? def callScript( dApp: Address, diff --git a/benchmark/src/test/scala/com/wavesplatform/state/CalculateDelayBenchmark.scala b/benchmark/src/test/scala/com/wavesplatform/state/CalculateDelayBenchmark.scala index 950a124a95..00c84d1797 100644 --- a/benchmark/src/test/scala/com/wavesplatform/state/CalculateDelayBenchmark.scala +++ b/benchmark/src/test/scala/com/wavesplatform/state/CalculateDelayBenchmark.scala @@ -25,24 +25,24 @@ class CalculateDelayBenchmark { @Benchmark def calculateDelay1(bh: Blackhole, st: St): Unit = - bh.consume(st.environment.calculateDelay(ByteStr.empty, 0, ByteStr.empty, 0)) + bh.consume(st.environment.calculateDelay(ByteStr.empty, 0)) @Benchmark def calculateDelay2(bh: Blackhole, st: St): Unit = bh.consume( - st.environment.calculateDelay(ByteStr.fill(96)(127), Long.MaxValue, ByteStr.fill(26)(127), Long.MaxValue) + st.environment.calculateDelay(ByteStr.fill(26)(127), Long.MaxValue) ) @Benchmark def calculateDelay3(bh: Blackhole, st: St): Unit = bh.consume( - st.environment.calculateDelay(ByteStr.fill(96)(-128), Long.MinValue, ByteStr.fill(26)(-128), Long.MinValue) + st.environment.calculateDelay(ByteStr.fill(26)(-128), Long.MinValue) ) @Benchmark def calculateDelay4(bh: Blackhole, st: St): Unit = bh.consume( - st.environment.calculateDelay(ByteStr.fill(32)(32), 123456, ByteStr.fill(26)(32), 100_000_000) + st.environment.calculateDelay(ByteStr.fill(26)(32), 100_000_000) ) } diff --git a/lang/doc/v8/funcs/blockchain-functions.hjson b/lang/doc/v8/funcs/blockchain-functions.hjson index f5cd8722fc..b8500b8be5 100644 --- a/lang/doc/v8/funcs/blockchain-functions.hjson +++ b/lang/doc/v8/funcs/blockchain-functions.hjson @@ -72,9 +72,9 @@ } { name: "calculateDelay" - params: [ "ByteVector", "Address", "Int" ] + params: [ "Address", "Int" ] doc: "Calculates mining delay using Fair PoS calculator." - paramsDoc: [ "hit source", "generator address", "generator balance" ] + paramsDoc: [ "generator address", "generator balance" ] complexity: 1 } ] diff --git a/lang/shared/src/main/scala/com/wavesplatform/lang/utils/package.scala b/lang/shared/src/main/scala/com/wavesplatform/lang/utils/package.scala index 1c244dd1e5..23200066f5 100644 --- a/lang/shared/src/main/scala/com/wavesplatform/lang/utils/package.scala +++ b/lang/shared/src/main/scala/com/wavesplatform/lang/utils/package.scala @@ -53,7 +53,7 @@ package object utils { override def addressFromString(address: String): Either[String, Recipient.Address] = ??? override def addressFromPublicKey(publicKey: ByteStr): Either[String, Address] = ??? override def accountScript(addressOrAlias: Recipient): Option[Script] = ??? - override def calculateDelay(hs: ByteStr, gt: ByteStr, b: Long): Long = ??? + override def calculateDelay(gt: ByteStr, b: Long): Long = ??? override def callScript( dApp: Address, func: String, 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 806300390f..5782452f29 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 @@ -1002,7 +1002,6 @@ object Functions { val calculateDelay: NativeFunction[Environment] = { val args = Seq( - ("hit source", BYTESTR), ("generator", addressType), ("balance", LONG) ) @@ -1013,23 +1012,19 @@ object Functions { LONG, args* ) { - val MaxHitSourceLength = 96 new ContextfulNativeFunction.Simple[Environment]("calculateDelay", LONG, args) { override def evaluate[F[_]: Monad](env: Environment[F], args: List[EVALUATED]): F[Either[ExecutionError, EVALUATED]] = args match { - case CONST_BYTESTR(hitSource) :: CaseObj(`addressType`, fields) :: CONST_LONG(balance) :: Nil => + case CaseObj(`addressType`, fields) :: CONST_LONG(balance) :: Nil => val addressBytes = fields("bytes").asInstanceOf[CONST_BYTESTR].bs if (addressBytes.size > AddressLength) { val error = CommonError(s"Address bytes length = ${addressBytes.size} exceeds limit = $AddressLength") (error: ExecutionError).asLeft[EVALUATED].pure[F] - } else if (hitSource.size > MaxHitSourceLength) { - val error = CommonError(s"Hit source bytes length = ${hitSource.size} exceeds limit = $MaxHitSourceLength") - (error: ExecutionError).asLeft[EVALUATED].pure[F] } else if (balance <= 0) { val error = CommonError(s"Unexpected non-positive balance = $balance") (error: ExecutionError).asLeft[EVALUATED].pure[F] } else { - val delay = env.calculateDelay(hitSource, addressBytes, balance) + val delay = env.calculateDelay(addressBytes, balance) (CONST_LONG(delay): EVALUATED).asRight[ExecutionError].pure[F] } case xs => diff --git a/lang/shared/src/main/scala/com/wavesplatform/lang/v1/traits/Environment.scala b/lang/shared/src/main/scala/com/wavesplatform/lang/v1/traits/Environment.scala index d66e7cad2d..315a118499 100644 --- a/lang/shared/src/main/scala/com/wavesplatform/lang/v1/traits/Environment.scala +++ b/lang/shared/src/main/scala/com/wavesplatform/lang/v1/traits/Environment.scala @@ -50,5 +50,5 @@ trait Environment[F[_]] { availableComplexity: Int, reentrant: Boolean ): Coeval[F[(Either[ValidationError, (EVALUATED, Log[F])], Int)]] - def calculateDelay(hitSource: ByteStr, generator: ByteStr, balance: Long): Long + def calculateDelay(generator: ByteStr, balance: Long): Long } diff --git a/lang/testkit/src/main/scala/com/wavesplatform/lang/Common.scala b/lang/testkit/src/main/scala/com/wavesplatform/lang/Common.scala index da202558c3..ed520803c2 100644 --- a/lang/testkit/src/main/scala/com/wavesplatform/lang/Common.scala +++ b/lang/testkit/src/main/scala/com/wavesplatform/lang/Common.scala @@ -9,10 +9,10 @@ import com.wavesplatform.lang.v1.CTX import com.wavesplatform.lang.v1.compiler.Terms.* import com.wavesplatform.lang.v1.compiler.Types.* import com.wavesplatform.lang.v1.evaluator.Contextful.NoContext -import com.wavesplatform.lang.v1.evaluator.{EvaluatorV1, Log} import com.wavesplatform.lang.v1.evaluator.EvaluatorV1.* import com.wavesplatform.lang.v1.evaluator.ctx.* -import com.wavesplatform.lang.v1.evaluator.ctx.impl.{EnvironmentFunctions, PureContext, *} +import com.wavesplatform.lang.v1.evaluator.ctx.impl.* +import com.wavesplatform.lang.v1.evaluator.{EvaluatorV1, Log} import com.wavesplatform.lang.v1.traits.domain.Recipient.Address import com.wavesplatform.lang.v1.traits.domain.{BlockInfo, Recipient, ScriptAssetInfo, Tx} import com.wavesplatform.lang.v1.traits.{DataType, Environment} @@ -96,7 +96,7 @@ object Common { def addressFromString(address: String): Either[String, Recipient.Address] = ??? def addressFromPublicKey(publicKey: ByteStr): Either[String, Address] = ??? def accountScript(addressOrAlias: Recipient): Option[Script] = ??? - def calculateDelay(hs: ByteStr, gt: ByteStr, b: Long): Long = ??? + def calculateDelay(gt: ByteStr, b: Long): Long = ??? def callScript( dApp: Address, func: String, diff --git a/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala b/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala index ce81011a8d..f4eb97e1a6 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/smart/WavesEnvironment.scala @@ -22,8 +22,8 @@ import com.wavesplatform.lang.v1.traits.* import com.wavesplatform.lang.v1.traits.domain.* import com.wavesplatform.lang.v1.traits.domain.Recipient.* import com.wavesplatform.lang.{Global, ValidationError} -import com.wavesplatform.state.BlockRewardCalculator.CurrentBlockRewardPart import com.wavesplatform.state.* +import com.wavesplatform.state.BlockRewardCalculator.CurrentBlockRewardPart import com.wavesplatform.state.diffs.invoke.InvokeScriptDiff.validateIntermediateBalances import com.wavesplatform.state.diffs.invoke.{InvokeScript, InvokeScriptDiff, InvokeScriptTransactionLike} import com.wavesplatform.transaction.Asset.* @@ -267,9 +267,14 @@ class WavesEnvironment( reentrant: Boolean ): Coeval[(Either[ValidationError, (EVALUATED, Log[Id])], Int)] = ??? - override def calculateDelay(hitSource: ByteStr, generator: ByteStr, balance: Long): Long = { - val hit = Global.blake2b256(hitSource.arr ++ generator.arr).take(PoSCalculator.HitSize) + override def calculateDelay(generator: ByteStr, balance: Long): Long = { val baseTarget = blockchain.lastBlockHeader.map(_.header.baseTarget).getOrElse(0L) + val hitSource = + blockchain + .vrf(blockchain.height) + .orElse(blockchain.lastBlockHeader.map(_.header.generationSignature)) + .getOrElse(ByteStr.empty) + val hit = Global.blake2b256(hitSource.arr ++ generator.arr).take(PoSCalculator.HitSize) FairPoSCalculator(0, 0).calculateDelay(BigInt(1, hit), baseTarget, balance) } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala index 9cd025320a..150a11ab3b 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala @@ -22,9 +22,9 @@ class CalculateDelayTest extends PropSpec with WithDomain { | let address1 = i.caller | let address2 = Address(base58'${signer(2).toAddress}') | let address3 = Address(base58'${signer(3).toAddress}') - | let lowest = calculateDelay(hitSource, address1, 10 * 1000 * 1000) - | let medium = calculateDelay(hitSource, address2, 30 * 1000 * 1000) - | let largest = calculateDelay(hitSource, address3, 90 * 1000 * 1000) + | let lowest = calculateDelay(address1, 10 * 1000 * 1000) + | let medium = calculateDelay(address2, 30 * 1000 * 1000) + | let largest = calculateDelay(address3, 90 * 1000 * 1000) | [ | IntegerEntry("lowest", lowest), | IntegerEntry("medium", medium), @@ -35,27 +35,21 @@ class CalculateDelayTest extends PropSpec with WithDomain { | @Callable(i) | func results() = | [ - | IntegerEntry("1", calculateDelay(base58'', Address(base58''), 1)), - | IntegerEntry("2", calculateDelay(base58'${ByteStr.fill(96)(1)}', Address(base58'${ByteStr.fill(26)(1)}'), ${Int.MaxValue})), - | IntegerEntry("3", calculateDelay(base58'${ByteStr.fill(96)(1)}', Address(base58'${ByteStr.fill(26)(1)}'), ${50_000L * Int.MaxValue})), - | IntegerEntry("4", calculateDelay(base58'${ByteStr.fill(96)(1)}', Address(base58'${ByteStr.fill(26)(1)}'), ${75_000L * Int.MaxValue})) + | IntegerEntry("1", calculateDelay(Address(base58''), 1)), + | IntegerEntry("2", calculateDelay(Address(base58'${ByteStr.fill(26)(1)}'), ${Int.MaxValue})), + | IntegerEntry("3", calculateDelay(Address(base58'${ByteStr.fill(26)(1)}'), ${100_000L * Int.MaxValue})), + | IntegerEntry("4", calculateDelay(Address(base58'${ByteStr.fill(26)(1)}'), ${200_000L * Int.MaxValue})) | ] | | @Callable(i) | func error1() = { - | strict r = calculateDelay(base58'${ByteStr.fill(97)(1)}', i.caller, 1) + | strict r = calculateDelay(Address(base58'${ByteStr.fill(27)(1)}'), 1) | [] | } | | @Callable(i) - | func error2() = { - | strict r = calculateDelay(lastBlock.generationSignature, Address(base58'${ByteStr.fill(27)(1)}'), 1) - | [] - | } - | - | @Callable(i) - | func error3(balance: Int) = { - | strict r = calculateDelay(lastBlock.generationSignature, Address(base58''), balance) + | func error2(balance: Int) = { + | strict r = calculateDelay(Address(base58''), balance) | [] | } """.stripMargin @@ -83,8 +77,8 @@ class CalculateDelayTest extends PropSpec with WithDomain { d.appendBlock(setScript(secondSigner, contract)) d.appendBlock(invoke(func = Some("results"))) d.liquidSnapshot.accountData.head._2.values.toSeq shouldBe Seq( - IntegerDataEntry("1", 1612717), - IntegerDataEntry("2", 44183), + IntegerDataEntry("1", 1418883), + IntegerDataEntry("2", 70064), IntegerDataEntry("3", 1), IntegerDataEntry("4", 0) ) @@ -94,10 +88,9 @@ class CalculateDelayTest extends PropSpec with WithDomain { property("errors of calculateDelay()") { withDomain(TransactionStateSnapshot, AddrWithBalance.enoughBalances(secondSigner)) { d => d.appendBlock(setScript(secondSigner, contract)) - d.appendBlockE(invoke(func = Some("error1"))) should produce("Hit source bytes length = 97 exceeds limit = 96") - d.appendBlockE(invoke(func = Some("error2"))) should produce("Address bytes length = 27 exceeds limit = 26") - d.appendBlockE(invoke(func = Some("error3"), args = Seq(CONST_LONG(-1)))) should produce("Unexpected non-positive balance = -1") - d.appendBlockE(invoke(func = Some("error3"), args = Seq(CONST_LONG(0)))) should produce("Unexpected non-positive balance = 0") + d.appendBlockE(invoke(func = Some("error1"))) should produce("Address bytes length = 27 exceeds limit = 26") + d.appendBlockE(invoke(func = Some("error2"), args = Seq(CONST_LONG(-1)))) should produce("Unexpected non-positive balance = -1") + d.appendBlockE(invoke(func = Some("error2"), args = Seq(CONST_LONG(0)))) should produce("Unexpected non-positive balance = 0") } } } diff --git a/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/ErrorMessageEnvironment.scala b/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/ErrorMessageEnvironment.scala index 41876c6afd..6b9ea189fb 100644 --- a/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/ErrorMessageEnvironment.scala +++ b/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/ErrorMessageEnvironment.scala @@ -34,7 +34,7 @@ case class ErrorMessageEnvironment[F[_]](message: String) extends Environment[F] override def addressFromString(address: String): Either[String, Recipient.Address] = unavailable override def addressFromPublicKey(publicKey: ByteStr): Either[String, Address] = unavailable override def accountScript(addressOrAlias: Recipient): F[Option[Script]] = unavailable - override def calculateDelay(hitSource: ByteStr, generator: ByteStr, balance: Long): Long = unavailable + override def calculateDelay(generator: ByteStr, balance: Long): Long = unavailable override def callScript( dApp: Address, func: String, diff --git a/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/http/WebEnvironment.scala b/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/http/WebEnvironment.scala index 7b519bdaac..fda0c55de0 100644 --- a/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/http/WebEnvironment.scala +++ b/repl/shared/src/main/scala/com/wavesplatform/lang/v1/repl/node/http/WebEnvironment.scala @@ -147,7 +147,7 @@ private[repl] case class WebEnvironment(settings: NodeConnectionSettings, client override def accountScript(addressOrAlias: Recipient): Future[Option[Script]] = ??? - override def calculateDelay(hitSource: ByteStr, baseTarget: Long, generator: ByteStr, balance: Long): Long = ??? + override def calculateDelay(generator: ByteStr, balance: Long): Long = ??? override def callScript( dApp: Address, diff --git a/ride-runner/src/main/scala/com/wavesplatform/ride/runner/environments/TrackedDAppEnvironment.scala b/ride-runner/src/main/scala/com/wavesplatform/ride/runner/environments/TrackedDAppEnvironment.scala index 9e6607b193..750b6b76d2 100644 --- a/ride-runner/src/main/scala/com/wavesplatform/ride/runner/environments/TrackedDAppEnvironment.scala +++ b/ride-runner/src/main/scala/com/wavesplatform/ride/runner/environments/TrackedDAppEnvironment.scala @@ -30,8 +30,8 @@ class TrackedDAppEnvironment(underlying: DAppEnvironment, tracker: DAppEnvironme override def invocationRoot: DAppEnvironment.InvocationTreeTracker = underlying.invocationRoot - override def calculateDelay(hitSource: ByteStr, baseTarget: Long, generator: ByteStr, balance: Long): Long = - underlying.calculateDelay(hitSource, baseTarget, generator, balance) + override def calculateDelay(generator: ByteStr, balance: Long): Long = + underlying.calculateDelay(generator, balance) // Functions those need Blockchain override def height: Id[Long] = { From a963474428c2ea8d0ee4b1068dbcc8a2a8cf0003 Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Tue, 5 Dec 2023 15:24:27 +0300 Subject: [PATCH 8/9] Adapted test --- .../scala/com/wavesplatform/lang/compiler/DecompilerTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/tests/src/test/scala/com/wavesplatform/lang/compiler/DecompilerTest.scala b/lang/tests/src/test/scala/com/wavesplatform/lang/compiler/DecompilerTest.scala index 4228979c5d..f8f31be7e6 100644 --- a/lang/tests/src/test/scala/com/wavesplatform/lang/compiler/DecompilerTest.scala +++ b/lang/tests/src/test/scala/com/wavesplatform/lang/compiler/DecompilerTest.scala @@ -1118,7 +1118,7 @@ class DecompilerTest extends PropSpec { } property("calculateDelay()") { - val script = "calculateDelay(base58'aaa', Address(base58'bbb'), 456)" + val script = "calculateDelay(Address(base58'bbb'), 456)" assertDecompile(script, script, V8) } From d5103a5b5fb6d4b4eafe2fa0afd25f9ef0001f5f Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Tue, 5 Dec 2023 15:26:19 +0300 Subject: [PATCH 9/9] Corrected error message --- .../lang/v1/evaluator/ctx/impl/waves/Functions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5782452f29..d748f02c83 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 @@ -1028,7 +1028,7 @@ object Functions { (CONST_LONG(delay): EVALUATED).asRight[ExecutionError].pure[F] } case xs => - notImplemented[Id, EVALUATED]("calculateDelay(hitSource: ByteVector, generator: Address, balance: Long)", xs) + notImplemented[Id, EVALUATED]("calculateDelay(generator: Address, balance: Long)", xs) } } }