Skip to content

[ETCM-251] faucet healthcheck #768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Nov 6, 2020
Merged

Conversation

biandratti
Copy link
Contributor

@biandratti biandratti commented Oct 29, 2020

Description

Add json rpc behavior in “faucet”. So we change httpServer to jsonRpcServer.

  • We change the resource from sendFunds.
  • And add a new resource from the status of “faucet”, that today it’s return value “FaucetUnavailable”. In other tasks we complete the status from faucet.

Proposed Solution

I added a new JsonRpc controller called "JsonRpcBaseController'', it's extended for the clases JsonRpcController and FaucetJsonRpcController. It is the way to decouple both controllers.

Important Changes Introduced

  • Change the endpoint from the request send funds of "faucet". Before it worked with "rest", now it will work with "json rpc".
    Before => [POST] {host}/faucet?address={account_id}
    Today => We use json rpc with "method": "faucet_sendFunds" and account_id as parameters.
    New endpoint was documented in the file "insomnia_workspace.json".

  • Before for the resource "send Funds'' we had a validation for the next request from the same ip address. We validated the limit time between requests form the same ip address. This validation was removed because it is not necessary, this sholud be part of DNS protection.

Testing

json Rpc regression

@biandratti biandratti added the BREAKS API Affects services that interacts with APIs label Nov 3, 2020
@biandratti biandratti changed the title WIP [ETCM-251] faucet healthcheck [ETCM-251] faucet healthcheck Nov 3, 2020
Copy link
Contributor

@mmrozek mmrozek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks nice. Minor comments only

Future.successful(errorResponse(req, JsonRpcError.MethodNotFound))
def handleRequest: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case req =>
val notFoundFn: PartialFunction[JsonRpcRequest, Task[JsonRpcResponse]] = { case _ =>
Task(errorResponse(req, JsonRpcError.MethodNotFound))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Task.now(errorResponse(req, JsonRpcError.MethodNotFound))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I applied it in other cases too.

@@ -32,11 +33,11 @@ class FaucetRpcService(rpcClient: RpcClient, keyStore: KeyStore, config: FaucetC
case Right(txId) =>
val txIdHex = s"0x${ByteStringUtils.hash2string(txId)}"
log.info(s"Sending ${config.txValue} ETH to ${sendFundsRequest.address} in tx: $txIdHex.")
Future.successful(Right(SendFundsResponse(txId)))
Task(Right(SendFundsResponse(txId)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto


case Left(err) =>
log.error(s"An error occurred while using faucet: $err")
Future.successful(Left(JsonRpcError.InternalError))
Task(Left(JsonRpcError.InternalError))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

handleFn(request)
.flatTap {
case JsonRpcResponse(_, _, Some(JsonRpcError(_, _, _)), _) =>
Task(JsonRpcControllerMetrics.MethodsErrorCounter.increment())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Contributor

@mmrozek mmrozek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

val Web3 = "web3"
val Net = "net"
val Personal = "personal"
val Daedalus = "daedalus"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could already remove this option

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but is ok to leave as it is in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will present this change in the next task.

import io.iohk.ethereum.jsonrpc.serialization.{JsonEncoder, JsonMethodDecoder}
import org.json4s.JsonAST.{JArray, JObject, JString}

object FaucetMethodsImplicits extends JsonMethodsImplicits {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a name that would tell us more what exactly those implicits do e.g. FaucetJsonCodecs ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, is true, I will change the name in the next task 252.

@biandratti biandratti merged commit 272e9ad into develop Nov 6, 2020
case Right(txId) =>
val txIdHex = s"0x${ByteStringUtils.hash2string(txId)}"
log.info(s"Sending ${config.txValue} ETC to ${sendFundsRequest.address} in tx: $txIdHex.")
Task.now(Right(SendFundsResponse(txId)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder can we wrap the whole sendFunds into Task?


implicit val sendFundsRequestDecoder: JsonMethodDecoder[SendFundsRequest] = {
case Some(JArray((input: JString) :: Nil)) => extractAddress(input).map(SendFundsRequest)
case _ => Left(InvalidParams())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about adding more details. Sth like:

  implicit val sendFundsRequestDecoder: JsonMethodDecoder[SendFundsRequest] = {
    case Some(JArray((input: JString) :: Nil)) => extractAddress(input).map(SendFundsRequest)
    case other => Left(InvalidParams(s"Wrong parameters $other"))

or maybe add some details like "Expected JSON array with single String".


trait ActorSystemBuilder {
def systemName: String
implicit lazy val system: ActorSystem = ActorSystem(systemName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about passing dependencies as parameters to class rather than mixing traits?

I find mixin traits to be hard to test/mock/keep track to release properly/reason about.
Maybe it would be possible to pass ActorSystem as implicit param whenever it is needed?

trait FaucetJsonRpcHealthCheckBuilder {
self: FaucetRpcServiceBuilder =>

val faucetJsonRpcHealthCheck = new FaucetJsonRpcHealthCheck(faucetRpcService)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO it would be easier to test/reason about if faucetJsonRpcHealthCheck would be passed as an argument to class rather than summon somewhere deep in the inheritance hierarchy (traits mixin).

trait ApisBuilder extends ApisBase {
object Apis {
val Faucet = "faucet"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that whole purpose of this trait and object inside is to have some place for constant Faucet. How about creating:

object FaucetApi {
  val Faucet = "faucet"
}

and just use it whenever it is needed. Or pass as parameter if this can have different values.

kapke pushed a commit that referenced this pull request Nov 16, 2020
* init refactor

* add refactor from JsonRpcController

* add refactor from JsonRpcController

* change rpc fuacet

* remove faucet api

* change faucet config

* fix test

* change properties

* add new endpoints from faucet

* remove config from limit request

* change name from JsonRpcBaseController

* fix test

* change faucet implicits

* change monix task -- add now

* remove configs from http

* fix test

* change test

Co-authored-by: Piotr Paradziński <[email protected]>
@dzajkowski dzajkowski deleted the ETCM-251-faucet-healthcheck branch April 9, 2021 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BREAKS API Affects services that interacts with APIs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants