From ce57e96580b2594a3127ce106d52cf9f97719bfd Mon Sep 17 00:00:00 2001 From: Vyatcheslav Suharnikov Date: Tue, 25 Jul 2023 16:40:34 +0400 Subject: [PATCH] NODE-2599 Public key in AccountScriptInfo (#3862) --- .../api/grpc/AccountsApiGrpcImpl.scala | 6 ++-- .../api/grpc/test/AccountsApiGrpcSpec.scala | 31 +++++++++++++++++-- .../wavesplatform/it/api/SyncGrpcApi.scala | 2 +- .../InvokeScriptTransactionGrpcSuite.scala | 1 + .../main/resources/swagger-ui/openapi.yaml | 4 ++- .../api/http/AddressApiRoute.scala | 3 +- .../wavesplatform/http/AddressRouteSpec.scala | 7 +++++ project/Dependencies.scala | 15 +++++---- 8 files changed, 52 insertions(+), 17 deletions(-) diff --git a/grpc-server/src/main/scala/com/wavesplatform/api/grpc/AccountsApiGrpcImpl.scala b/grpc-server/src/main/scala/com/wavesplatform/api/grpc/AccountsApiGrpcImpl.scala index 996db68795b..e3e0590e7ca 100644 --- a/grpc-server/src/main/scala/com/wavesplatform/api/grpc/AccountsApiGrpcImpl.scala +++ b/grpc-server/src/main/scala/com/wavesplatform/api/grpc/AccountsApiGrpcImpl.scala @@ -64,10 +64,10 @@ class AccountsApiGrpcImpl(commonApi: CommonAccountsApi)(implicit sc: Scheduler) responseObserver.completeWith(responseStream) } - override def getScript(request: AccountRequest): Future[ScriptData] = Future { + override def getScript(request: AccountRequest): Future[ScriptResponse] = Future { commonApi.script(request.address.toAddress) match { - case Some(desc) => ScriptData(PBTransactions.toPBScript(Some(desc.script)), desc.script.expr.toString, desc.verifierComplexity) - case None => ScriptData() + case Some(desc) => ScriptResponse(PBTransactions.toPBScript(Some(desc.script)), desc.script.expr.toString, desc.verifierComplexity, desc.publicKey.toByteString) + case None => ScriptResponse() } } diff --git a/grpc-server/src/test/scala/com/wavesplatform/api/grpc/test/AccountsApiGrpcSpec.scala b/grpc-server/src/test/scala/com/wavesplatform/api/grpc/test/AccountsApiGrpcSpec.scala index 5eb54da52bf..2ae6285d46c 100644 --- a/grpc-server/src/test/scala/com/wavesplatform/api/grpc/test/AccountsApiGrpcSpec.scala +++ b/grpc-server/src/test/scala/com/wavesplatform/api/grpc/test/AccountsApiGrpcSpec.scala @@ -23,13 +23,16 @@ import com.wavesplatform.transaction.Asset.Waves import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.utils.DiffMatchers import monix.execution.Scheduler.Implicits.global - import org.scalatest.BeforeAndAfterAll +import scala.concurrent.Await +import scala.concurrent.duration.{DurationInt, FiniteDuration} + class AccountsApiGrpcSpec extends FreeSpec with BeforeAndAfterAll with DiffMatchers with WithDomain with GrpcApiHelpers { - val sender: KeyPair = TxHelpers.signer(1) - val recipient: KeyPair = TxHelpers.signer(2) + val sender: KeyPair = TxHelpers.signer(1) + val recipient: KeyPair = TxHelpers.signer(2) + val timeout: FiniteDuration = 2.minutes "GetBalances should work" in withDomain(DomainPresets.RideV6, AddrWithBalance.enoughBalances(sender)) { d => val grpcApi = getGrpcApi(d) @@ -71,6 +74,28 @@ class AccountsApiGrpcSpec extends FreeSpec with BeforeAndAfterAll with DiffMatch } } + "GetScript should work" in withDomain(DomainPresets.RideV6, AddrWithBalance.enoughBalances(sender)) { d => + val grpcApi = getGrpcApi(d) + + val script = TxHelpers.script( + s"""{-# STDLIB_VERSION 6 #-} + |{-# CONTENT_TYPE DAPP #-} + |{-# SCRIPT_TYPE ACCOUNT #-} + |@Callable(i) + |func foo(a: Int) = { ([], a == 42) }""".stripMargin + ) + + d.appendBlock(TxHelpers.setScript(sender, script)) + + val r = Await.result( + grpcApi.getScript(AccountRequest.of(ByteString.copyFrom(sender.toAddress.bytes))), + timeout + ) + + r.scriptBytes shouldBe ByteString.copyFrom(script.bytes().arr) + r.publicKey shouldBe ByteString.copyFrom(sender.publicKey.arr) + } + "GetActiveLeases should work" in withDomain(DomainPresets.RideV6, AddrWithBalance.enoughBalances(sender)) { d => val grpcApi = getGrpcApi(d) diff --git a/node-it/src/test/scala/com/wavesplatform/it/api/SyncGrpcApi.scala b/node-it/src/test/scala/com/wavesplatform/it/api/SyncGrpcApi.scala index 18f089a22fe..ce4224cd467 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/api/SyncGrpcApi.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/api/SyncGrpcApi.scala @@ -298,7 +298,7 @@ object SyncGrpcApi extends Assertions { maybeWaitForTransaction(sync(async(n).setScript(sender, script, fee, timestamp, version)), waitForTx) } - def scriptInfo(address: ByteString): ScriptData = { + def scriptInfo(address: ByteString): ScriptResponse = { accounts.getScript(AccountRequest.of(address)) } diff --git a/node-it/src/test/scala/com/wavesplatform/it/sync/grpc/InvokeScriptTransactionGrpcSuite.scala b/node-it/src/test/scala/com/wavesplatform/it/sync/grpc/InvokeScriptTransactionGrpcSuite.scala index 2a6c9409c67..6bbe813c69e 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/sync/grpc/InvokeScriptTransactionGrpcSuite.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/sync/grpc/InvokeScriptTransactionGrpcSuite.scala @@ -107,6 +107,7 @@ class InvokeScriptTransactionGrpcSuite extends GrpcBaseTransactionSuite { val scriptInfo = sender.scriptInfo(firstAddress) PBTransactions.toVanillaScript(scriptInfo.scriptBytes) shouldBe Some(script) + scriptInfo.publicKey shouldBe ByteString.copyFrom(firstAcc.publicKey.arr) } test("dApp caller invokes a nested function on a dApp") { diff --git a/node/src/main/resources/swagger-ui/openapi.yaml b/node/src/main/resources/swagger-ui/openapi.yaml index 7c4d3add272..c8e032ed50e 100644 --- a/node/src/main/resources/swagger-ui/openapi.yaml +++ b/node/src/main/resources/swagger-ui/openapi.yaml @@ -446,7 +446,7 @@ paths: type: object properties: address: - type: string + $ref: '#/components/schemas/Address' script: type: string format: byte @@ -480,6 +480,8 @@ paths: description: >- Extra fee for transactions sending on behalf of the account + publicKey: + $ref: '#/components/schemas/PublicKey' '/addresses/{address}': delete: tags: diff --git a/node/src/main/scala/com/wavesplatform/api/http/AddressApiRoute.scala b/node/src/main/scala/com/wavesplatform/api/http/AddressApiRoute.scala index d06d41b7c4f..3d8deba605a 100644 --- a/node/src/main/scala/com/wavesplatform/api/http/AddressApiRoute.scala +++ b/node/src/main/scala/com/wavesplatform/api/http/AddressApiRoute.scala @@ -84,7 +84,8 @@ case class AddressApiRoute( "complexity" -> maxComplexity, "verifierComplexity" -> verifierComplexity, "callableComplexities" -> callableComplexities, - "extraFee" -> (if (blockchain.hasPaidVerifier(address)) FeeValidation.ScriptExtraFee else 0L) + "extraFee" -> (if (blockchain.hasPaidVerifier(address)) FeeValidation.ScriptExtraFee else 0L), + "publicKey" -> scriptInfoOpt.map(_.publicKey.toString) ) } } diff --git a/node/src/test/scala/com/wavesplatform/http/AddressRouteSpec.scala b/node/src/test/scala/com/wavesplatform/http/AddressRouteSpec.scala index e6351f75a45..eea70d4cb2e 100644 --- a/node/src/test/scala/com/wavesplatform/http/AddressRouteSpec.scala +++ b/node/src/test/scala/com/wavesplatform/http/AddressRouteSpec.scala @@ -224,6 +224,7 @@ class AddressRouteSpec extends RouteSpec("/addresses") with PathMockFactory with (response \ "version").as[Int] shouldBe 1 (response \ "complexity").as[Long] shouldBe 123 (response \ "extraFee").as[Long] shouldBe FeeValidation.ScriptExtraFee + (response \ "publicKey").as[String] shouldBe allAccounts(1).publicKey.toString } (commonAccountApi.script _).expects(allAccounts(2).toAddress).returning(None).once() @@ -238,6 +239,7 @@ class AddressRouteSpec extends RouteSpec("/addresses") with PathMockFactory with (response \ "version").asOpt[Int] shouldBe None (response \ "complexity").as[Long] shouldBe 0 (response \ "extraFee").as[Long] shouldBe 0 + (response \ "publicKey").asOpt[String] shouldBe None } val contractWithMeta = DApp( @@ -288,6 +290,7 @@ class AddressRouteSpec extends RouteSpec("/addresses") with PathMockFactory with (response \ "verifierComplexity").as[Long] shouldBe 11 (response \ "callableComplexities").as[Map[String, Long]] shouldBe callableComplexities - "verify" (response \ "extraFee").as[Long] shouldBe FeeValidation.ScriptExtraFee + (response \ "publicKey").as[String] shouldBe allAccounts(3).publicKey.toString } Get(routePath(s"/scriptInfo/${allAddresses(3)}/meta")) ~> route ~> check { @@ -354,6 +357,7 @@ class AddressRouteSpec extends RouteSpec("/addresses") with PathMockFactory with (response \ "verifierComplexity").as[Long] shouldBe 0 (response \ "callableComplexities").as[Map[String, Long]] shouldBe contractWithoutVerifierComplexities (response \ "extraFee").as[Long] shouldBe FeeValidation.ScriptExtraFee + (response \ "publicKey").as[String] shouldBe allAccounts(6).publicKey.toString } } @@ -373,6 +377,7 @@ class AddressRouteSpec extends RouteSpec("/addresses") with PathMockFactory with (response \ "complexity").as[Long] shouldBe 201 (response \ "verifierComplexity").as[Long] shouldBe 201 (response \ "extraFee").as[Long] shouldBe FeeValidation.ScriptExtraFee + (response \ "publicKey").as[String] shouldBe allAccounts(1).publicKey.toString } (blockchain.accountScript _).when(allAddresses(2)).returns(info(199, 2)) @@ -383,6 +388,7 @@ class AddressRouteSpec extends RouteSpec("/addresses") with PathMockFactory with (response \ "complexity").as[Long] shouldBe 199 (response \ "verifierComplexity").as[Long] shouldBe 199 (response \ "extraFee").as[Long] shouldBe 0 + (response \ "publicKey").as[String] shouldBe allAccounts(2).publicKey.toString } (blockchain.accountScript _).when(allAddresses(3)).returns(None) @@ -393,6 +399,7 @@ class AddressRouteSpec extends RouteSpec("/addresses") with PathMockFactory with (response \ "complexity").as[Long] shouldBe 0 (response \ "verifierComplexity").as[Long] shouldBe 0 (response \ "extraFee").as[Long] shouldBe 0 + (response \ "publicKey").asOpt[String] shouldBe None } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index bcb5cf04df0..e914e67af7e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -1,12 +1,11 @@ -import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ -import sbt.Keys._ -import sbt.{Def, _} +import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport.* +import sbt.{Def, *} //noinspection TypeAnnotation object Dependencies { // Node protobuf schemas private[this] val protoSchemasLib = - "com.wavesplatform" % "protobuf-schemas" % "1.4.5" classifier "protobuf-src" intransitive () + "com.wavesplatform" % "protobuf-schemas" % "1.4.6-SNAPSHOT" classifier "protobuf-src" intransitive () def akkaModule(module: String): ModuleID = "com.typesafe.akka" %% s"akka-$module" % "2.6.21" @@ -38,9 +37,9 @@ object Dependencies { val catsCore = catsModule("core", "2.9.0") val shapeless = Def.setting("com.chuusai" %%% "shapeless" % "2.3.10") - val playJson = "com.typesafe.play" %% "play-json" % "2.9.4" - - val scalaTest = "org.scalatest" %% "scalatest" % "3.2.16" % Test + val playJson = "com.typesafe.play" %% "play-json" % "2.9.4" + + val scalaTest = "org.scalatest" %% "scalatest" % "3.2.16" % Test val scalaJsTest = Def.setting("com.lihaoyi" %%% "utest" % "0.8.1" % Test) val sttp3 = "com.softwaremill.sttp.client3" % "core_2.13" % "3.5.2" // 3.6.x and later is built for Java 11 @@ -125,7 +124,7 @@ object Dependencies { kamonModule("executors"), "org.influxdb" % "influxdb-java" % "2.23", googleGuava, - "com.google.code.findbugs" % "jsr305" % "3.0.2" % Compile, // javax.annotation stubs + "com.google.code.findbugs" % "jsr305" % "3.0.2" % Compile, // javax.annotation stubs playJson, akkaModule("actor"), akkaModule("stream"),