From 8edb67627e699505ffe5d8fd3233f2ade63ef1c6 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 23 Nov 2022 19:03:59 +0300 Subject: [PATCH 1/6] p2sRuleR --- .../ergoplatform/http/api/ScanApiRoute.scala | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala index a6110d1369..7dd3f03028 100644 --- a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala @@ -5,7 +5,7 @@ import akka.http.scaladsl.server.Route import io.circe.Encoder import org.ergoplatform._ import org.ergoplatform.nodeView.wallet._ -import org.ergoplatform.nodeView.wallet.scanning.ScanRequest +import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanRequest} import org.ergoplatform.settings.ErgoSettings import scorex.core.api.http.ApiError.BadRequest import scorex.core.api.http.ApiResponse @@ -13,7 +13,10 @@ import scorex.core.settings.RESTApiSettings import scala.util.{Failure, Success} import ScanEntities._ +import org.ergoplatform.ErgoBox.R1 import org.ergoplatform.wallet.Constants.ScanId +import sigmastate.Values.ByteArrayConstant +import sigmastate.serialization.ValueSerializer /** * This class contains methods to register / deregister and list external scans, and also to serve them. @@ -40,7 +43,8 @@ case class ScanApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings) unspentR ~ spentR ~ stopTrackingR ~ - addBoxR + addBoxR ~ + p2sRuleR } def registerR: Route = (path("register") & post & entity(as[ScanRequest])) { request => @@ -91,4 +95,18 @@ case class ScanApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings) case Success(_) => ApiResponse(scanIdsBox.box.id) } } + + def p2sRuleR: Route = (path("p2sRule") & post & entity(as[String])) { p2s => + addressEncoder.fromString(p2s) match { + case Success(p2sAddr) => + val scriptBytes = ByteArrayConstant(ValueSerializer.serialize(p2sAddr.script.toProposition(replaceConstants = true).propBytes)) + val trackingRule = EqualsScanningPredicate(R1, scriptBytes) + val request = ScanRequest(p2s, trackingRule, None, None) + withWalletOp(_.addScan(request).map(_.response)) { + case Failure(e) => BadRequest(s"Bad request $request. ${Option(e.getMessage).getOrElse(e.toString)}") + case Success(app) => ApiResponse(ScanIdWrapper(app.scanId)) + } + case Failure(e) => BadRequest(s"Can't parse $p2s. ${Option(e.getMessage).getOrElse(e.toString)}") + } + } } From 7f409fd4e1b57ff65565e692f01d7954fc6f1203 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Mon, 16 Jan 2023 14:18:38 +0300 Subject: [PATCH 2/6] openapi.yaml updated with /scan/p2srule --- src/main/resources/api/openapi.yaml | 37 ++++++++++++++++++- .../ergoplatform/http/api/ScanApiRoute.scala | 3 ++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml index f193638740..c16fbde333 100644 --- a/src/main/resources/api/openapi.yaml +++ b/src/main/resources/api/openapi.yaml @@ -1,7 +1,7 @@ openapi: "3.0.2" info: - version: "5.0.4" + version: "5.0.6" title: Ergo Node API description: API docs for Ergo Node. Models are shared between all Ergo products contact: @@ -5296,6 +5296,41 @@ paths: schema: $ref: '#/components/schemas/ApiError' + /scan/p2sRule: + post: + security: + - ApiKeyAuth: [api_key] + summary: Create custom scan to track P2S address + operationId: scriptP2SRule + tags: + - scan + requestBody: + required: true + content: + application/json: + schema: + type: string + example: '02c9e71790399816b3e40b2207e9ade19a9b7fe0600186cfb8e2b115bfdb34b57f38cd3c9f2890d11720eb3bb993993f00ededf812a590d2993df094a7ca4f0213e4820e1ab831eed5dc5c72665396d3a01d2a12900f1c3ab77700b284ae24fa8e8f7754f86f2282c795db6b0b17df1c29cc0552e59d01f7d777c638a813333277271c2f8b4d99d01ff0e6ee8695697bdd5b568089395620d7198c6093ce8bc59b928611b1b12452c05addaa42f4beff6a0a6fe90000000380d0dbc3f40210090402040005c801040205c8010500040004000e2003faf2cb329f2e90d6d23b58d91bbb6c046aa143261cc21f52fbe2824bfcbf04d807d601e4c6a70408d602b2a5730000d603e4c6a70601d604e4c6a7080ed605e4c6a70505d606e4c6a70705d60795720399c1a7c1720299c17202c1a7eb027201d1ededededededededed93c27202c2a793e4c672020408720193e4c6720205059572039d9c72057eb272047301000573029d9c72057eb2720473030005730494e4c672020601720393e4c672020705720693e4c67202080e720493e4c67202090ec5a79572039072079c720672059272079c72067205917207730595ef720393b1db630872027306d801d608b2db63087202730700ed938c7208017308938c7208027206c8df35000508cd030c8f9c4dc08f3c006fa85a47c9156dedbede000a8b764c6e374fd097e873ba0405c8a8c105010105dc8b020e0266608cdea8baf0380008cd030c8f9c4dc08f3c006fa85a47c9156dedbede000a8b764c6e374fd097e873ba04c8df350000c0843d1005040004000e36100204a00b08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304c8df350000' + responses: + '200': + description: Id of custom scan generated and registered + content: + application/json: + schema: + $ref: '#/components/schemas/ScanId' + '400': + description: Bad source + content: + application/json: + schema: + $ref: '#/components/schemas/ApiError' + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/ApiError' + /wallet/generateCommitments: post: security: diff --git a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala index 7dd3f03028..e59ac2739f 100644 --- a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala @@ -96,6 +96,9 @@ case class ScanApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings) } } + /** + * API method to get tracking rule corresponding to p2s address + */ def p2sRuleR: Route = (path("p2sRule") & post & entity(as[String])) { p2s => addressEncoder.fromString(p2s) match { case Success(p2sAddr) => From 8faca9696a349b4d07d603f52d83e8a6b0d54ada Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Mon, 16 Jan 2023 16:37:15 +0300 Subject: [PATCH 3/6] true address as an example, no interaction with wallet and not removing spent offchain for p2s --- src/main/resources/api/openapi.yaml | 2 +- src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml index c16fbde333..8c083784fe 100644 --- a/src/main/resources/api/openapi.yaml +++ b/src/main/resources/api/openapi.yaml @@ -5310,7 +5310,7 @@ paths: application/json: schema: type: string - example: '02c9e71790399816b3e40b2207e9ade19a9b7fe0600186cfb8e2b115bfdb34b57f38cd3c9f2890d11720eb3bb993993f00ededf812a590d2993df094a7ca4f0213e4820e1ab831eed5dc5c72665396d3a01d2a12900f1c3ab77700b284ae24fa8e8f7754f86f2282c795db6b0b17df1c29cc0552e59d01f7d777c638a813333277271c2f8b4d99d01ff0e6ee8695697bdd5b568089395620d7198c6093ce8bc59b928611b1b12452c05addaa42f4beff6a0a6fe90000000380d0dbc3f40210090402040005c801040205c8010500040004000e2003faf2cb329f2e90d6d23b58d91bbb6c046aa143261cc21f52fbe2824bfcbf04d807d601e4c6a70408d602b2a5730000d603e4c6a70601d604e4c6a7080ed605e4c6a70505d606e4c6a70705d60795720399c1a7c1720299c17202c1a7eb027201d1ededededededededed93c27202c2a793e4c672020408720193e4c6720205059572039d9c72057eb272047301000573029d9c72057eb2720473030005730494e4c672020601720393e4c672020705720693e4c67202080e720493e4c67202090ec5a79572039072079c720672059272079c72067205917207730595ef720393b1db630872027306d801d608b2db63087202730700ed938c7208017308938c7208027206c8df35000508cd030c8f9c4dc08f3c006fa85a47c9156dedbede000a8b764c6e374fd097e873ba0405c8a8c105010105dc8b020e0266608cdea8baf0380008cd030c8f9c4dc08f3c006fa85a47c9156dedbede000a8b764c6e374fd097e873ba04c8df350000c0843d1005040004000e36100204a00b08cd0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ea02d192a39a8cc7a701730073011001020402d19683030193a38cc7b2a57300000193c2b2a57301007473027303830108cdeeac93b1a57304c8df350000' + example: '4MQyML64GnzMxZgm' responses: '200': description: Id of custom scan generated and registered diff --git a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala index e59ac2739f..7272d5ef86 100644 --- a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala @@ -5,7 +5,7 @@ import akka.http.scaladsl.server.Route import io.circe.Encoder import org.ergoplatform._ import org.ergoplatform.nodeView.wallet._ -import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanRequest} +import org.ergoplatform.nodeView.wallet.scanning.{EqualsScanningPredicate, ScanRequest, ScanWalletInteraction} import org.ergoplatform.settings.ErgoSettings import scorex.core.api.http.ApiError.BadRequest import scorex.core.api.http.ApiResponse @@ -104,7 +104,7 @@ case class ScanApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings) case Success(p2sAddr) => val scriptBytes = ByteArrayConstant(ValueSerializer.serialize(p2sAddr.script.toProposition(replaceConstants = true).propBytes)) val trackingRule = EqualsScanningPredicate(R1, scriptBytes) - val request = ScanRequest(p2s, trackingRule, None, None) + val request = ScanRequest(p2s, trackingRule, Some(ScanWalletInteraction.Off), Some(true)) withWalletOp(_.addScan(request).map(_.response)) { case Failure(e) => BadRequest(s"Bad request $request. ${Option(e.getMessage).getOrElse(e.toString)}") case Success(app) => ApiResponse(ScanIdWrapper(app.scanId)) From 84ca2e9499c32060553cd2a39a7e46003ebc0640 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 6 Sep 2023 15:46:00 +0300 Subject: [PATCH 4/6] p2sRule test --- .../org/ergoplatform/http/api/ScanApiRoute.scala | 5 ++++- .../ergoplatform/http/routes/ScanApiRouteSpec.scala | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala index 7272d5ef86..157f0726ad 100644 --- a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala @@ -99,7 +99,8 @@ case class ScanApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings) /** * API method to get tracking rule corresponding to p2s address */ - def p2sRuleR: Route = (path("p2sRule") & post & entity(as[String])) { p2s => + def p2sRuleR: Route = (path("p2sRule") & post & entity(as[String])) { p2sRaw => + val p2s = fromJsonOrPlain(p2sRaw) addressEncoder.fromString(p2s) match { case Success(p2sAddr) => val scriptBytes = ByteArrayConstant(ValueSerializer.serialize(p2sAddr.script.toProposition(replaceConstants = true).propBytes)) @@ -113,3 +114,5 @@ case class ScanApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings) } } } + + diff --git a/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala b/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala index afee4a72b3..fb4956190f 100644 --- a/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala +++ b/src/test/scala/org/ergoplatform/http/routes/ScanApiRouteSpec.scala @@ -252,7 +252,6 @@ class ScanApiRouteSpec extends AnyFlatSpec } } - it should "stop tracking a box" in { val scanIdBoxId = ScanIdBoxId(ScanId @@ (51: Short), ADKey @@ Random.randomBytes(32)) @@ -261,4 +260,16 @@ class ScanApiRouteSpec extends AnyFlatSpec } } + it should "generate scan for p2s rule" in { + Post(prefix + "/p2sRule", "Ms7smJmdbakqfwNo") ~> route ~> check { + status shouldBe StatusCodes.OK + val res = responseAs[Json] + res.hcursor.downField("scanId").as[Int].toOption.isDefined shouldBe true + } + + Post(prefix + "/p2sRule", "s7smJmdbakqfwNo") ~> route ~> check { + status shouldBe StatusCodes.BadRequest + } + } + } From 5e3d80a710173a0b8bf84a1f58f40fe840f0ad61 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 8 Sep 2023 20:21:55 +0300 Subject: [PATCH 5/6] fixing scan --- src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala index 157f0726ad..446f13284b 100644 --- a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala @@ -16,7 +16,7 @@ import ScanEntities._ import org.ergoplatform.ErgoBox.R1 import org.ergoplatform.wallet.Constants.ScanId import sigmastate.Values.ByteArrayConstant -import sigmastate.serialization.ValueSerializer +import sigmastate.serialization.{ErgoTreeSerializer, ValueSerializer} /** * This class contains methods to register / deregister and list external scans, and also to serve them. @@ -103,7 +103,8 @@ case class ScanApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings) val p2s = fromJsonOrPlain(p2sRaw) addressEncoder.fromString(p2s) match { case Success(p2sAddr) => - val scriptBytes = ByteArrayConstant(ValueSerializer.serialize(p2sAddr.script.toProposition(replaceConstants = true).propBytes)) + val script = p2sAddr.script + val scriptBytes = ByteArrayConstant(ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(script)) val trackingRule = EqualsScanningPredicate(R1, scriptBytes) val request = ScanRequest(p2s, trackingRule, Some(ScanWalletInteraction.Off), Some(true)) withWalletOp(_.addScan(request).map(_.response)) { From 66c0d99252eb1eddbf5edd606aeb60e134248d21 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 8 Sep 2023 20:40:48 +0300 Subject: [PATCH 6/6] api method description improved --- src/main/resources/api/openapi.yaml | 2 +- src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/api/openapi.yaml b/src/main/resources/api/openapi.yaml index 92965223aa..af4b22671b 100644 --- a/src/main/resources/api/openapi.yaml +++ b/src/main/resources/api/openapi.yaml @@ -5554,7 +5554,7 @@ paths: post: security: - ApiKeyAuth: [api_key] - summary: Create custom scan to track P2S address + summary: Create and register a scan to track P2S address provided operationId: scriptP2SRule tags: - scan diff --git a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala index 446f13284b..f99af46995 100644 --- a/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala +++ b/src/main/scala/org/ergoplatform/http/api/ScanApiRoute.scala @@ -16,7 +16,7 @@ import ScanEntities._ import org.ergoplatform.ErgoBox.R1 import org.ergoplatform.wallet.Constants.ScanId import sigmastate.Values.ByteArrayConstant -import sigmastate.serialization.{ErgoTreeSerializer, ValueSerializer} +import sigmastate.serialization.ErgoTreeSerializer /** * This class contains methods to register / deregister and list external scans, and also to serve them.