diff --git a/build.sbt b/build.sbt index d0bf068b..499d53ad 100644 --- a/build.sbt +++ b/build.sbt @@ -80,3 +80,5 @@ buildTarballsForDocker := { baseDirectory.value / "docker" / "target" / "consensus-client.tgz" ) } + +Test / unmanagedJars += file("src/test/lib/waves-all.jar") diff --git a/src/main/scala/units/Bridge.scala b/src/main/scala/units/Bridge.scala index d040f2f7..5760258c 100644 --- a/src/main/scala/units/Bridge.scala +++ b/src/main/scala/units/Bridge.scala @@ -7,7 +7,7 @@ import com.wavesplatform.utils.EthEncoding import org.web3j.abi.datatypes.Event import org.web3j.abi.datatypes.generated.{Bytes20, Int64} import org.web3j.abi.{FunctionReturnDecoder, TypeEncoder, TypeReference} -import units.client.http.model.GetLogsResponseEntry +import units.client.engine.model.GetLogsResponseEntry import units.eth.Gwei import java.math.BigInteger diff --git a/src/main/scala/units/ConsensusClient.scala b/src/main/scala/units/ConsensusClient.scala index 4177ea8c..38f0ce9f 100644 --- a/src/main/scala/units/ConsensusClient.scala +++ b/src/main/scala/units/ConsensusClient.scala @@ -16,7 +16,6 @@ import net.ceedubs.ficus.Ficus.* import org.slf4j.LoggerFactory import sttp.client3.HttpClientSyncBackend import units.client.engine.{EngineApiClient, HttpEngineApiClient} -import units.client.http.{EcApiClient, HttpEcApiClient} import units.client.{JwtAuthenticationBackend, LoggingBackend} import units.network.* @@ -28,7 +27,6 @@ class ConsensusClient( config: ClientConfig, context: ExtensionContext, engineApiClient: EngineApiClient, - httpApiClient: EcApiClient, blockObserver: BlocksObserver, allChannels: DefaultChannelGroup, globalScheduler: Scheduler, @@ -42,7 +40,6 @@ class ConsensusClient( deps.config, context, deps.engineApiClient, - deps.httpApiClient, deps.blockObserver, deps.allChannels, deps.globalScheduler, @@ -54,7 +51,6 @@ class ConsensusClient( private[units] val elu = new ELUpdater( - httpApiClient, engineApiClient, context.blockchain, context.utx, @@ -123,14 +119,13 @@ class ConsensusClientDependencies(context: ExtensionContext) extends AutoCloseab httpClientBackend } ) - val httpApiClient = new HttpEcApiClient(config, httpClientBackend) val allChannels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE) val peerDatabase = new PeerDatabaseImpl(config.network) val messageObserver = new MessageObserver() private val networkServer = NetworkServer( config, - new HistoryReplier(httpApiClient, engineApiClient)(globalScheduler), + new HistoryReplier(engineApiClient)(globalScheduler), peerDatabase, messageObserver, allChannels, diff --git a/src/main/scala/units/ELUpdater.scala b/src/main/scala/units/ELUpdater.scala index eb98944d..3c342df4 100644 --- a/src/main/scala/units/ELUpdater.scala +++ b/src/main/scala/units/ELUpdater.scala @@ -33,8 +33,6 @@ import units.client.engine.EngineApiClient import units.client.engine.EngineApiClient.PayloadId import units.client.engine.model.* import units.client.engine.model.Withdrawal.WithdrawalIndex -import units.client.http.EcApiClient -import units.client.http.model.EcBlock import units.eth.{EmptyL2Block, EthAddress, EthereumConstants} import units.network.BlocksObserverImpl.BlockWithChannel import units.util.HexBytesConverter @@ -45,7 +43,6 @@ import scala.concurrent.duration.* import scala.util.* class ELUpdater( - httpApiClient: EcApiClient, engineApiClient: EngineApiClient, blockchain: Blockchain, utx: UtxPool, @@ -265,7 +262,7 @@ class ELUpdater( fixedFinalizedBlock = if (finalizedBlock.height > rollbackBlock.parentBlock.height) rollbackBlock.parentBlock else finalizedBlock _ <- confirmBlock(rollbackBlock.hash, fixedFinalizedBlock.hash) _ <- confirmBlock(target, fixedFinalizedBlock) - lastEcBlock <- httpApiClient.getLastExecutionBlock + lastEcBlock <- engineApiClient.getLastExecutionBlock _ <- Either.cond( targetHash == lastEcBlock.hash, (), @@ -451,14 +448,14 @@ class ELUpdater( else { val finalizedBlock = chainContractClient.getFinalizedBlock logger.debug(s"Finalized block is ${finalizedBlock.hash}") - httpApiClient.getBlockByHash(finalizedBlock.hash) match { + engineApiClient.getBlockByHash(finalizedBlock.hash) match { case Left(error) => logger.error(s"Could not load finalized block", error) case Right(Some(finalizedEcBlock)) => logger.trace(s"Finalized block ${finalizedBlock.hash} is at height ${finalizedEcBlock.height}") (for { newEpochInfo <- calculateEpochInfo mainChainInfo <- chainContractClient.getMainChainInfo.toRight("Can't get main chain info") - lastEcBlock <- httpApiClient.getLastExecutionBlock.leftMap(_.message) + lastEcBlock <- engineApiClient.getLastExecutionBlock.leftMap(_.message) } yield { logger.trace(s"Following main chain ${mainChainInfo.id}") val fullValidationStatus = FullValidationStatus( @@ -620,7 +617,7 @@ class ELUpdater( val finalizedBlock = chainContractClient.getFinalizedBlock val options = chainContractClient.getOptions logger.debug(s"Finalized block is ${finalizedBlock.hash}") - httpApiClient.getBlockByHash(finalizedBlock.hash) match { + engineApiClient.getBlockByHash(finalizedBlock.hash) match { case Left(error) => logger.error(s"Could not load finalized block", error) case Right(Some(finalizedEcBlock)) => logger.trace(s"Finalized block ${finalizedBlock.hash} is at height ${finalizedEcBlock.height}") @@ -722,7 +719,7 @@ class ELUpdater( private def requestBlock(hash: BlockHash): BlockRequestResult = { logger.debug(s"Requesting block $hash") - httpApiClient.getBlockByHash(hash) match { + engineApiClient.getBlockByHash(hash) match { case Right(Some(block)) => BlockRequestResult.BlockExists(block) case Right(None) => requestAndProcessBlock(hash) @@ -788,7 +785,7 @@ class ELUpdater( ): Option[Working[FollowingChain]] = { @tailrec def findLastEcBlock(curBlock: ContractBlock): EcBlock = { - httpApiClient.getBlockByHash(curBlock.hash) match { + engineApiClient.getBlockByHash(curBlock.hash) match { case Right(Some(block)) => block case Right(_) => chainContractClient.getBlock(curBlock.parentHash) match { @@ -877,7 +874,7 @@ class ELUpdater( private def waitForSyncCompletion(target: ContractBlock): Unit = scheduler.scheduleOnce(5.seconds)(state match { case SyncingToFinalizedBlock(finalizedBlockHash) if finalizedBlockHash == target.hash => logger.debug(s"Checking if EL has synced to ${target.hash} on height ${target.height}") - httpApiClient.getLastExecutionBlock match { + engineApiClient.getLastExecutionBlock match { case Left(error) => logger.error(s"Sync to ${target.hash} was not completed, error=${error.message}") setState("23", Starting) @@ -1209,11 +1206,11 @@ class ELUpdater( private def mkRollbackBlock(rollbackTargetBlockId: BlockHash): Job[RollbackBlock] = for { targetBlockFromContract <- Right(chainContractClient.getBlock(rollbackTargetBlockId)) targetBlockOpt <- targetBlockFromContract match { - case None => httpApiClient.getBlockByHash(rollbackTargetBlockId) + case None => engineApiClient.getBlockByHash(rollbackTargetBlockId) case x => Right(x) } targetBlock <- Either.fromOption(targetBlockOpt, ClientError(s"Can't find block $rollbackTargetBlockId neither on a contract, nor in EC")) - parentBlock <- httpApiClient.getBlockByHash(targetBlock.parentHash) + parentBlock <- engineApiClient.getBlockByHash(targetBlock.parentHash) parentBlock <- Either.fromOption(parentBlock, ClientError(s"Can't find parent block $rollbackTargetBlockId in execution client")) rollbackBlockOpt <- engineApiClient.applyNewPayload(EmptyL2Block.mkExecutionPayload(parentBlock)) rollbackBlock <- Either.fromOption(rollbackBlockOpt, ClientError("Rollback block hash is not defined as latest valid hash")) @@ -1226,7 +1223,7 @@ class ELUpdater( } private def getLastWithdrawalIndex(hash: BlockHash): Job[WithdrawalIndex] = - httpApiClient.getBlockByHash(hash).flatMap { + engineApiClient.getBlockByHash(hash).flatMap { case None => Left(ClientError(s"Can't find $hash block on EC during withdrawal search")) case Some(ecBlock) => ecBlock.withdrawals.lastOption match { @@ -1239,7 +1236,7 @@ class ELUpdater( private def getElToClTransfersRootHash(hash: BlockHash, elBridgeAddress: EthAddress): Job[Digest] = for { - elRawLogs <- httpApiClient.getLogs(hash, Bridge.ElSentNativeEventTopic) + elRawLogs <- engineApiClient.getLogs(hash, Bridge.ElSentNativeEventTopic) rootHash <- { val relatedElRawLogs = elRawLogs.filter(x => x.address == elBridgeAddress && x.topics.contains(Bridge.ElSentNativeEventTopic)) Bridge @@ -1413,7 +1410,7 @@ class ELUpdater( if (fullValidationStatus.validated.contains(lastContractBlock.hash)) Right(BlockForValidation.NotFound) else if (lastContractBlock.height <= finalizedBlock.height) Right(BlockForValidation.SkippedFinalized(lastContractBlock)) else - httpApiClient + engineApiClient .getBlockByHash(lastContractBlock.hash) .map { case Some(ecBlock) => BlockForValidation.Found(lastContractBlock, ecBlock) diff --git a/src/main/scala/units/NetworkL2Block.scala b/src/main/scala/units/NetworkL2Block.scala index c8ae1a9c..3e6cdf45 100644 --- a/src/main/scala/units/NetworkL2Block.scala +++ b/src/main/scala/units/NetworkL2Block.scala @@ -5,13 +5,12 @@ import com.wavesplatform.account.PrivateKey import com.wavesplatform.common.state.ByteStr import com.wavesplatform.crypto import com.wavesplatform.crypto.{DigestLength, SignatureLength} +import org.web3j.abi.datatypes.generated.Uint256 +import play.api.libs.json.{JsObject, Json} import units.client.L2BlockLike -import units.client.engine.model.Withdrawal -import units.client.http.model.EcBlock +import units.client.engine.model.{EcBlock, Withdrawal} import units.eth.EthAddress import units.util.HexBytesConverter.* -import org.web3j.abi.datatypes.generated.Uint256 -import play.api.libs.json.{JsObject, Json} // TODO Refactor to eliminate a manual deserialization, e.g. (raw: JsonObject, parsed: ParsedBlockL2) class NetworkL2Block private ( diff --git a/src/main/scala/units/client/engine/EngineApiClient.scala b/src/main/scala/units/client/engine/EngineApiClient.scala index 25444b9d..ba9f5b09 100644 --- a/src/main/scala/units/client/engine/EngineApiClient.scala +++ b/src/main/scala/units/client/engine/EngineApiClient.scala @@ -1,13 +1,12 @@ package units.client.engine +import play.api.libs.json.* import units.client.engine.EngineApiClient.PayloadId import units.client.engine.model.* import units.eth.EthAddress import units.{BlockHash, Job} -import play.api.libs.json.* trait EngineApiClient { - def forkChoiceUpdate(blockHash: BlockHash, finalizedBlockHash: BlockHash): Job[String] // TODO Replace String with an appropriate type def forkChoiceUpdateWithPayloadId( @@ -24,6 +23,18 @@ trait EngineApiClient { def applyNewPayload(payload: JsObject): Job[Option[BlockHash]] def getPayloadBodyByHash(hash: BlockHash): Job[Option[JsObject]] + + def getBlockByNumber(number: BlockNumber): Job[Option[EcBlock]] + + def getBlockByHash(hash: BlockHash): Job[Option[EcBlock]] + + def getBlockByHashJson(hash: BlockHash, fullTxs: Boolean = false): Job[Option[JsObject]] + + def getLastExecutionBlock: Job[EcBlock] + + def blockExists(hash: BlockHash): Job[Boolean] + + def getLogs(hash: BlockHash, topic: String): Job[List[GetLogsResponseEntry]] } object EngineApiClient { diff --git a/src/main/scala/units/client/engine/HttpEngineApiClient.scala b/src/main/scala/units/client/engine/HttpEngineApiClient.scala index d1fadc95..440b496f 100644 --- a/src/main/scala/units/client/engine/HttpEngineApiClient.scala +++ b/src/main/scala/units/client/engine/HttpEngineApiClient.scala @@ -1,5 +1,9 @@ package units.client.engine +import cats.syntax.either.* +import cats.syntax.traverse.* +import play.api.libs.json.* +import sttp.client3.* import units.client.JsonRpcClient import units.client.engine.EngineApiClient.PayloadId import units.client.engine.HttpEngineApiClient.* @@ -7,8 +11,6 @@ import units.client.engine.model.* import units.client.engine.model.ForkChoiceUpdatedRequest.ForkChoiceAttributes import units.eth.EthAddress import units.{BlockHash, ClientConfig, ClientError, Job} -import play.api.libs.json.* -import sttp.client3.* import scala.concurrent.duration.{DurationInt, FiniteDuration} @@ -17,7 +19,10 @@ class HttpEngineApiClient(val config: ClientConfig, val backend: SttpBackend[Ide val apiUrl = uri"http://${config.executionClientAddress}:${config.engineApiPort}" def forkChoiceUpdate(blockHash: BlockHash, finalizedBlockHash: BlockHash): Job[String] = { - sendEngineRequest[ForkChoiceUpdatedRequest, ForkChoiceUpdatedResponse](ForkChoiceUpdatedRequest(blockHash, finalizedBlockHash, None), BlockExecutionTimeout) + sendEngineRequest[ForkChoiceUpdatedRequest, ForkChoiceUpdatedResponse]( + ForkChoiceUpdatedRequest(blockHash, finalizedBlockHash, None), + BlockExecutionTimeout + ) .flatMap { case ForkChoiceUpdatedResponse(PayloadStatus(status, _, _), None) if status == "SYNCING" || status == "VALID" => Right(status) case ForkChoiceUpdatedResponse(PayloadStatus(_, _, Some(validationError)), _) => @@ -72,6 +77,41 @@ class HttpEngineApiClient(val config: ClientConfig, val backend: SttpBackend[Ide .map(_.value.headOption.flatMap(_.asOpt[JsObject])) } + def getBlockByNumber(number: BlockNumber): Job[Option[EcBlock]] = { + for { + json <- getBlockByNumberJson(number.str) + blockMeta <- json.traverse(parseJson[EcBlock](_)) + } yield blockMeta + } + + def getBlockByHash(hash: BlockHash): Job[Option[EcBlock]] = { + sendRequest[GetBlockByHashRequest, EcBlock](GetBlockByHashRequest(hash, fullTxs = false)) + .leftMap(err => ClientError(s"Error getting block by hash $hash: $err")) + } + + def getBlockByHashJson(hash: BlockHash, fullTxs: Boolean = false): Job[Option[JsObject]] = { + sendRequest[GetBlockByHashRequest, JsObject](GetBlockByHashRequest(hash, fullTxs)) + .leftMap(err => ClientError(s"Error getting block json by hash $hash: $err")) + } + + def getLastExecutionBlock: Job[EcBlock] = for { + lastEcBlockOpt <- getBlockByNumber(BlockNumber.Latest) + lastEcBlock <- Either.fromOption(lastEcBlockOpt, ClientError("Impossible: EC doesn't have blocks")) + } yield lastEcBlock + + def blockExists(hash: BlockHash): Job[Boolean] = + getBlockByHash(hash).map(_.isDefined) + + private def getBlockByNumberJson(number: String): Job[Option[JsObject]] = { + sendRequest[GetBlockByNumberRequest, JsObject](GetBlockByNumberRequest(number)) + .leftMap(err => ClientError(s"Error getting block by number $number: $err")) + } + + override def getLogs(hash: BlockHash, topic: String): Job[List[GetLogsResponseEntry]] = + sendRequest[GetLogsRequest, List[GetLogsResponseEntry]](GetLogsRequest(hash, List(topic))) + .leftMap(err => ClientError(s"Error getting block logs by hash $hash: $err")) + .map(_.getOrElse(List.empty)) + private def sendEngineRequest[A: Writes, B: Reads](request: A, timeout: FiniteDuration): Job[B] = { sendRequest(request, timeout) match { case Right(response) => response.toRight(ClientError(s"Unexpected engine API empty response")) diff --git a/src/main/scala/units/client/http/model/BlockNumber.scala b/src/main/scala/units/client/engine/model/BlockNumber.scala similarity index 87% rename from src/main/scala/units/client/http/model/BlockNumber.scala rename to src/main/scala/units/client/engine/model/BlockNumber.scala index aba476cb..d70c603e 100644 --- a/src/main/scala/units/client/http/model/BlockNumber.scala +++ b/src/main/scala/units/client/engine/model/BlockNumber.scala @@ -1,4 +1,4 @@ -package units.client.http.model +package units.client.engine.model import units.util.HexBytesConverter diff --git a/src/main/scala/units/client/http/model/EcBlock.scala b/src/main/scala/units/client/engine/model/EcBlock.scala similarity index 95% rename from src/main/scala/units/client/http/model/EcBlock.scala rename to src/main/scala/units/client/engine/model/EcBlock.scala index fff78809..595e611f 100644 --- a/src/main/scala/units/client/http/model/EcBlock.scala +++ b/src/main/scala/units/client/engine/model/EcBlock.scala @@ -1,14 +1,13 @@ -package units.client.http.model +package units.client.engine.model -import units.BlockHash -import units.client.L2BlockLike -import units.client.engine.model.Withdrawal -import units.eth.EthAddress -import units.util.HexBytesConverter.* import org.web3j.abi.datatypes.generated.Uint256 import play.api.libs.functional.syntax.* import play.api.libs.json.* import play.api.libs.json.Format.GenericFormat +import units.BlockHash +import units.client.L2BlockLike +import units.eth.EthAddress +import units.util.HexBytesConverter.* /** Block in EC API, not a payload of Engine API! See BlockHeader in besu. * @param timestamp diff --git a/src/main/scala/units/client/http/model/GetBlockByHashRequest.scala b/src/main/scala/units/client/engine/model/GetBlockByHashRequest.scala similarity index 92% rename from src/main/scala/units/client/http/model/GetBlockByHashRequest.scala rename to src/main/scala/units/client/engine/model/GetBlockByHashRequest.scala index 236a385d..913dc896 100644 --- a/src/main/scala/units/client/http/model/GetBlockByHashRequest.scala +++ b/src/main/scala/units/client/engine/model/GetBlockByHashRequest.scala @@ -1,4 +1,4 @@ -package units.client.http.model +package units.client.engine.model import units.BlockHash import play.api.libs.json.{Json, Writes} diff --git a/src/main/scala/units/client/http/model/GetBlockByNumberRequest.scala b/src/main/scala/units/client/engine/model/GetBlockByNumberRequest.scala similarity index 91% rename from src/main/scala/units/client/http/model/GetBlockByNumberRequest.scala rename to src/main/scala/units/client/engine/model/GetBlockByNumberRequest.scala index 5be68cc9..f3fedd61 100644 --- a/src/main/scala/units/client/http/model/GetBlockByNumberRequest.scala +++ b/src/main/scala/units/client/engine/model/GetBlockByNumberRequest.scala @@ -1,4 +1,4 @@ -package units.client.http.model +package units.client.engine.model import play.api.libs.json.{Json, Writes} diff --git a/src/main/scala/units/client/http/model/GetLogsRequest.scala b/src/main/scala/units/client/engine/model/GetLogsRequest.scala similarity index 94% rename from src/main/scala/units/client/http/model/GetLogsRequest.scala rename to src/main/scala/units/client/engine/model/GetLogsRequest.scala index f10461a3..23feea7a 100644 --- a/src/main/scala/units/client/http/model/GetLogsRequest.scala +++ b/src/main/scala/units/client/engine/model/GetLogsRequest.scala @@ -1,4 +1,4 @@ -package units.client.http.model +package units.client.engine.model import units.BlockHash import play.api.libs.json.{Json, Writes} diff --git a/src/main/scala/units/client/http/model/GetLogsResponseEntry.scala b/src/main/scala/units/client/engine/model/GetLogsResponseEntry.scala similarity index 91% rename from src/main/scala/units/client/http/model/GetLogsResponseEntry.scala rename to src/main/scala/units/client/engine/model/GetLogsResponseEntry.scala index 03c04041..247eddbf 100644 --- a/src/main/scala/units/client/http/model/GetLogsResponseEntry.scala +++ b/src/main/scala/units/client/engine/model/GetLogsResponseEntry.scala @@ -1,4 +1,4 @@ -package units.client.http.model +package units.client.engine.model import units.eth.EthAddress import play.api.libs.json.{Json, Reads} diff --git a/src/main/scala/units/client/http/EcApiClient.scala b/src/main/scala/units/client/http/EcApiClient.scala deleted file mode 100644 index 0ef612bd..00000000 --- a/src/main/scala/units/client/http/EcApiClient.scala +++ /dev/null @@ -1,19 +0,0 @@ -package units.client.http - -import units.client.http.model.* -import units.{BlockHash, Job} -import play.api.libs.json.JsObject - -trait EcApiClient { - def getBlockByNumber(number: BlockNumber): Job[Option[EcBlock]] - - def getBlockByHash(hash: BlockHash): Job[Option[EcBlock]] - - def getBlockByHashJson(hash: BlockHash, fullTxs: Boolean = false): Job[Option[JsObject]] - - def getLastExecutionBlock: Job[EcBlock] - - def blockExists(hash: BlockHash): Job[Boolean] - - def getLogs(hash: BlockHash, topic: String): Job[List[GetLogsResponseEntry]] -} diff --git a/src/main/scala/units/client/http/HttpEcApiClient.scala b/src/main/scala/units/client/http/HttpEcApiClient.scala deleted file mode 100644 index 52ceb3ee..00000000 --- a/src/main/scala/units/client/http/HttpEcApiClient.scala +++ /dev/null @@ -1,48 +0,0 @@ -package units.client.http - -import cats.syntax.either.* -import cats.syntax.traverse.* -import units.client.JsonRpcClient -import units.client.http.model.* -import units.{BlockHash, ClientConfig, ClientError, Job} -import play.api.libs.json.JsObject -import sttp.client3.* - -class HttpEcApiClient(val config: ClientConfig, val backend: SttpBackend[Identity, ?]) extends EcApiClient with JsonRpcClient { - - val apiUrl = uri"http://${config.executionClientAddress}:${config.httpApiPort}" - - def getBlockByNumber(number: BlockNumber): Job[Option[EcBlock]] = { - for { - json <- getBlockByNumberJson(number.str) - blockMeta <- json.traverse(parseJson[EcBlock](_)) - } yield blockMeta - } - - def getBlockByHash(hash: BlockHash): Job[Option[EcBlock]] = { - sendRequest[GetBlockByHashRequest, EcBlock](GetBlockByHashRequest(hash, fullTxs = false)) - .leftMap(err => ClientError(s"Error getting block by hash $hash: $err")) - } - - def getBlockByHashJson(hash: BlockHash, fullTxs: Boolean = false): Job[Option[JsObject]] = { - sendRequest[GetBlockByHashRequest, JsObject](GetBlockByHashRequest(hash, fullTxs)) - .leftMap(err => ClientError(s"Error getting block json by hash $hash: $err")) - } - - def getLastExecutionBlock: Job[EcBlock] = for { - lastEcBlockOpt <- getBlockByNumber(BlockNumber.Latest) - lastEcBlock <- Either.fromOption(lastEcBlockOpt, ClientError("Impossible: EC doesn't have blocks")) - } yield lastEcBlock - - def blockExists(hash: BlockHash): Job[Boolean] = - getBlockByHash(hash).map(_.isDefined) - - private def getBlockByNumberJson(number: String): Job[Option[JsObject]] = { - sendRequest[GetBlockByNumberRequest, JsObject](GetBlockByNumberRequest(number)) - .leftMap(err => ClientError(s"Error getting block by number $number: $err")) - } - override def getLogs(hash: BlockHash, topic: String): Job[List[GetLogsResponseEntry]] = - sendRequest[GetLogsRequest, List[GetLogsResponseEntry]](GetLogsRequest(hash, List(topic))) - .leftMap(err => ClientError(s"Error getting block logs by hash $hash: $err")) - .map(_.getOrElse(List.empty)) -} diff --git a/src/main/scala/units/eth/EmptyL2Block.scala b/src/main/scala/units/eth/EmptyL2Block.scala index dcdee6e4..f0165c66 100644 --- a/src/main/scala/units/eth/EmptyL2Block.scala +++ b/src/main/scala/units/eth/EmptyL2Block.scala @@ -1,11 +1,11 @@ package units.eth -import units.BlockHash -import units.client.http.model.EcBlock -import units.util.HexBytesConverter import org.web3j.abi.datatypes.generated.Uint256 import org.web3j.rlp.{RlpEncoder, RlpList, RlpString} import play.api.libs.json.{JsObject, Json} +import units.BlockHash +import units.client.engine.model.EcBlock +import units.util.HexBytesConverter object EmptyL2Block { case class Params( diff --git a/src/main/scala/units/network/HistoryReplier.scala b/src/main/scala/units/network/HistoryReplier.scala index 8758df44..04db98ba 100644 --- a/src/main/scala/units/network/HistoryReplier.scala +++ b/src/main/scala/units/network/HistoryReplier.scala @@ -1,24 +1,20 @@ package units.network import cats.syntax.either.* -import units.client.engine.EngineApiClient -import units.client.http.EcApiClient -import units.util.BlockToPayloadMapper -import units.{BlockHash, ClientError, NetworkL2Block} import com.wavesplatform.network.id import com.wavesplatform.utils.ScorexLogging import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter} import monix.execution.Scheduler +import units.client.engine.EngineApiClient +import units.util.BlockToPayloadMapper +import units.{BlockHash, ClientError, NetworkL2Block} import scala.concurrent.Future import scala.util.{Failure, Success} @Sharable -class HistoryReplier(httpApiClient: EcApiClient, engineApiClient: EngineApiClient)(implicit sc: Scheduler) - extends ChannelInboundHandlerAdapter - with ScorexLogging { - +class HistoryReplier(engineApiClient: EngineApiClient)(implicit sc: Scheduler) extends ChannelInboundHandlerAdapter with ScorexLogging { private def respondWith(ctx: ChannelHandlerContext, value: Future[Message]): Unit = value.onComplete { case Failure(e) => log.debug(s"${id(ctx)} Error processing request", e) @@ -46,7 +42,7 @@ class HistoryReplier(httpApiClient: EcApiClient, engineApiClient: EngineApiClien private def loadBlockL2(hash: BlockHash): Future[Either[ClientError, NetworkL2Block]] = Future { for { - blockJsonOpt <- httpApiClient.getBlockByHashJson(hash) + blockJsonOpt <- engineApiClient.getBlockByHashJson(hash) blockJson <- Either.fromOption(blockJsonOpt, ClientError("block not found")) payloadBodyJsonOpt <- engineApiClient.getPayloadBodyByHash(hash) payloadBodyJson <- Either.fromOption(payloadBodyJsonOpt, ClientError("payload body not found")) diff --git a/src/test/scala/units/BaseIntegrationTestSuite.scala b/src/test/scala/units/BaseIntegrationTestSuite.scala index 1cc382c4..af0122c3 100644 --- a/src/test/scala/units/BaseIntegrationTestSuite.scala +++ b/src/test/scala/units/BaseIntegrationTestSuite.scala @@ -11,7 +11,7 @@ import com.wavesplatform.utils.ScorexLogging import org.scalatest.freespec.AnyFreeSpec import org.scalatest.{BeforeAndAfterAll, EitherValues, OptionValues} import units.Bridge.ElSentNativeEvent -import units.client.http.model.GetLogsResponseEntry +import units.client.engine.model.GetLogsResponseEntry import units.eth.{EthAddress, Gwei} import units.test.CustomMatchers import units.util.HexBytesConverter diff --git a/src/test/scala/units/BlockFullValidationTestSuite.scala b/src/test/scala/units/BlockFullValidationTestSuite.scala index 69b3c164..9aff63b0 100644 --- a/src/test/scala/units/BlockFullValidationTestSuite.scala +++ b/src/test/scala/units/BlockFullValidationTestSuite.scala @@ -4,7 +4,7 @@ import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.transaction.TxHelpers import units.ELUpdater.State.ChainStatus.{FollowingChain, WaitForNewChain} import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex -import units.client.http.model.{EcBlock, GetLogsResponseEntry} +import units.client.engine.model.{EcBlock, GetLogsResponseEntry} import units.eth.EthAddress import units.util.HexBytesConverter diff --git a/src/test/scala/units/BlockIssuesForgingTestSuite.scala b/src/test/scala/units/BlockIssuesForgingTestSuite.scala index a1cec3b2..d17cfb10 100644 --- a/src/test/scala/units/BlockIssuesForgingTestSuite.scala +++ b/src/test/scala/units/BlockIssuesForgingTestSuite.scala @@ -6,7 +6,7 @@ import com.wavesplatform.wallet.Wallet import units.ELUpdater.State.ChainStatus.{FollowingChain, Mining, WaitForNewChain} import units.ELUpdater.WaitRequestedBlockTimeout import units.client.contract.HasConsensusLayerDappTxHelpers.defaultFees -import units.client.http.model.EcBlock +import units.client.engine.model.EcBlock import scala.concurrent.duration.DurationInt diff --git a/src/test/scala/units/ExtensionDomain.scala b/src/test/scala/units/ExtensionDomain.scala index 9c969969..75d4b432 100644 --- a/src/test/scala/units/ExtensionDomain.scala +++ b/src/test/scala/units/ExtensionDomain.scala @@ -41,7 +41,7 @@ import units.ELUpdater.State.{ChainStatus, Working} import units.ExtensionDomain.* import units.client.contract.HasConsensusLayerDappTxHelpers import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex -import units.client.http.model.{EcBlock, TestEcBlocks} +import units.client.engine.model.{EcBlock, TestEcBlocks} import units.client.{L2BlockLike, TestEcClients} import units.eth.{EthAddress, EthereumConstants, Gwei} import units.network.TestBlocksObserver @@ -122,7 +122,6 @@ class ExtensionDomain( l2Config, extensionContext, ecClients.engineApi, - ecClients.ecApi, blockObserver, allChannels, globalScheduler, diff --git a/src/test/scala/units/TestEcBlockBuilder.scala b/src/test/scala/units/TestEcBlockBuilder.scala index 817d6453..d8d6e899 100644 --- a/src/test/scala/units/TestEcBlockBuilder.scala +++ b/src/test/scala/units/TestEcBlockBuilder.scala @@ -2,8 +2,7 @@ package units import org.web3j.abi.datatypes.generated.Uint256 import units.client.TestEcClients -import units.client.engine.model.Withdrawal -import units.client.http.model.{EcBlock, GetLogsResponseEntry} +import units.client.engine.model.{EcBlock, GetLogsResponseEntry, Withdrawal} import units.eth.{EthAddress, EthereumConstants, Gwei} import java.nio.charset.StandardCharsets diff --git a/src/test/scala/units/client/TestEcClients.scala b/src/test/scala/units/client/TestEcClients.scala index 01004425..8c00ce77 100644 --- a/src/test/scala/units/client/TestEcClients.scala +++ b/src/test/scala/units/client/TestEcClients.scala @@ -9,10 +9,8 @@ import play.api.libs.json.JsObject import units.ELUpdater.calculateRandao import units.client.TestEcClients.* import units.client.engine.EngineApiClient.PayloadId -import units.client.engine.model.Withdrawal +import units.client.engine.model.* import units.client.engine.{EngineApiClient, LoggedEngineApiClient} -import units.client.http.model.* -import units.client.http.{EcApiClient, LoggedEcApiClient} import units.collections.ListOps.* import units.eth.{EthAddress, EthereumConstants} import units.{BlockHash, Job, NetworkL2Block} @@ -143,12 +141,8 @@ class TestEcClients private ( }.asRight override def getPayloadBodyByHash(hash: BlockHash): Job[Option[JsObject]] = - ecApi.getBlockByHashJson(hash) - } - } + getBlockByHashJson(hash) - val ecApi = LoggedEcApiClient { - new EcApiClient { override def getBlockByNumber(number: BlockNumber): Job[Option[EcBlock]] = number match { case BlockNumber.Latest => currChain.headOption.asRight diff --git a/src/test/scala/units/client/engine/LoggedEngineApiClient.scala b/src/test/scala/units/client/engine/LoggedEngineApiClient.scala index 21100cf9..138dbce7 100644 --- a/src/test/scala/units/client/engine/LoggedEngineApiClient.scala +++ b/src/test/scala/units/client/engine/LoggedEngineApiClient.scala @@ -2,7 +2,7 @@ package units.client.engine import play.api.libs.json.JsObject import units.client.engine.EngineApiClient.PayloadId -import units.client.engine.model.Withdrawal +import units.client.engine.model.* import units.eth.EthAddress import units.{BlockHash, HasJobLogging, Job} @@ -29,6 +29,20 @@ class LoggedEngineApiClient(underlying: EngineApiClient) extends EngineApiClient override def getPayloadBodyByHash(hash: BlockHash): Job[Option[JsObject]] = wrap(s"getPayloadBodyByHash($hash)", underlying.getPayloadBodyByHash(hash)) + + override def getBlockByNumber(number: BlockNumber): Job[Option[EcBlock]] = wrap(s"getBlockByNumber($number)", underlying.getBlockByNumber(number)) + + override def getBlockByHash(hash: BlockHash): Job[Option[EcBlock]] = wrap(s"getBlockByHash($hash)", underlying.getBlockByHash(hash)) + + override def getBlockByHashJson(hash: BlockHash, fullTxs: Boolean): Job[Option[JsObject]] = + wrap(s"getBlockByHashJson($hash, fullTxs=$fullTxs)", underlying.getBlockByHashJson(hash, fullTxs)) + + override def getLastExecutionBlock: Job[EcBlock] = wrap("getLastExecutionBlock", underlying.getLastExecutionBlock) + + override def blockExists(hash: BlockHash): Job[Boolean] = wrap(s"blockExists($hash)", underlying.blockExists(hash)) + + override def getLogs(hash: BlockHash, topic: String): Job[List[GetLogsResponseEntry]] = + wrap(s"getLogs($hash, $topic)", underlying.getLogs(hash, topic)) } object LoggedEngineApiClient { diff --git a/src/test/scala/units/client/http/model/TestEcBlocks.scala b/src/test/scala/units/client/engine/model/TestEcBlocks.scala similarity index 96% rename from src/test/scala/units/client/http/model/TestEcBlocks.scala rename to src/test/scala/units/client/engine/model/TestEcBlocks.scala index d0fe70aa..389f9d91 100644 --- a/src/test/scala/units/client/http/model/TestEcBlocks.scala +++ b/src/test/scala/units/client/engine/model/TestEcBlocks.scala @@ -1,4 +1,4 @@ -package units.client.http.model +package units.client.engine.model import com.wavesplatform.account.SeedKeyPair import com.wavesplatform.common.utils.EitherExt2 diff --git a/src/test/scala/units/client/http/LoggedEcApiClient.scala b/src/test/scala/units/client/http/LoggedEcApiClient.scala deleted file mode 100644 index e1b340c1..00000000 --- a/src/test/scala/units/client/http/LoggedEcApiClient.scala +++ /dev/null @@ -1,25 +0,0 @@ -package units.client.http - -import play.api.libs.json.JsObject -import units.client.http.model.{BlockNumber, EcBlock, GetLogsResponseEntry} -import units.{BlockHash, HasJobLogging, Job} - -class LoggedEcApiClient(underlying: EcApiClient) extends EcApiClient with HasJobLogging { - override def getBlockByNumber(number: BlockNumber): Job[Option[EcBlock]] = wrap(s"getBlockByNumber($number)", underlying.getBlockByNumber(number)) - - override def getBlockByHash(hash: BlockHash): Job[Option[EcBlock]] = wrap(s"getBlockByHash($hash)", underlying.getBlockByHash(hash)) - - override def getBlockByHashJson(hash: BlockHash, fullTxs: Boolean): Job[Option[JsObject]] = - wrap(s"getBlockByHashJson($hash, fullTxs=$fullTxs)", underlying.getBlockByHashJson(hash, fullTxs)) - - override def getLastExecutionBlock: Job[EcBlock] = wrap("getLastExecutionBlock", underlying.getLastExecutionBlock) - - override def blockExists(hash: BlockHash): Job[Boolean] = wrap(s"blockExists($hash)", underlying.blockExists(hash)) - - override def getLogs(hash: BlockHash, topic: String): Job[List[GetLogsResponseEntry]] = - wrap(s"getLogs($hash, $topic)", underlying.getLogs(hash, topic)) -} - -object LoggedEcApiClient { - def apply(underlying: EcApiClient): EcApiClient = new LoggedEcApiClient(underlying) -} diff --git a/src/test/scala/units/eth/EmptyL2BlockTestSuite.scala b/src/test/scala/units/eth/EmptyL2BlockTestSuite.scala index ae3de91c..c965af99 100644 --- a/src/test/scala/units/eth/EmptyL2BlockTestSuite.scala +++ b/src/test/scala/units/eth/EmptyL2BlockTestSuite.scala @@ -5,7 +5,7 @@ import org.scalatest.freespec.AnyFreeSpec import org.web3j.abi.datatypes.generated.Uint256 import play.api.libs.json.Json import units.BlockHash -import units.client.http.model.EcBlock +import units.client.engine.model.EcBlock import units.eth.EmptyL2Block.Params class EmptyL2BlockTestSuite extends AnyFreeSpec with BaseSuite {