Skip to content

Commit

Permalink
Added ElBridgeClient, moving classes
Browse files Browse the repository at this point in the history
  • Loading branch information
vsuharnikov committed Oct 28, 2024
1 parent dfc14fe commit 2e6bb88
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 15 deletions.
3 changes: 2 additions & 1 deletion consensus-client-it/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import java.time.format.DateTimeFormatter
description := "Consensus client integration tests"

libraryDependencies ++= Seq(
"org.testcontainers" % "testcontainers" % "1.20.2"
"org.testcontainers" % "testcontainers" % "1.20.2",
"org.web3j" % "core" % "4.9.8"
).map(_ % Test)

val logsDirectory = taskKey[File]("The directory for logs") // Evaluates every time, so it recreates the logs directory
Expand Down
3 changes: 3 additions & 0 deletions consensus-client-it/src/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
<logger name="org.testcontainers" level="WARN"/>
<logger name="org.testcontainers.utility" level="ERROR"/>

<!-- Web3j -->
<logger name="org.web3j.protocol" level="INFO"/>

<root level="TRACE">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package units.network
package units

import com.google.common.primitives.{Bytes, Ints}
import com.wavesplatform.account.{Address, AddressScheme, KeyPair, SeedKeyPair}
import com.wavesplatform.account.{AddressScheme, KeyPair, SeedKeyPair}
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.common.utils.EitherExt2
import com.wavesplatform.crypto
Expand All @@ -11,10 +11,11 @@ import org.scalatest.concurrent.Eventually
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import org.scalatest.{BeforeAndAfterAll, EitherValues, OptionValues}
import org.web3j.crypto.Credentials
import units.client.contract.HasConsensusLayerDappTxHelpers
import units.client.engine.model.BlockNumber
import units.docker.{EcContainer, Networks, WavesNodeContainer}
import units.eth.{EthAddress, Gwei}
import units.network.test.docker.{EcContainer, Networks, WavesNodeContainer}
import units.test.CustomMatchers

import java.nio.charset.StandardCharsets
Expand Down Expand Up @@ -44,13 +45,19 @@ trait BaseItTestSuite
number = 1,
ip = Networks.ipForNode(3),
baseSeed = "devnet-1",
chainContractAddress = Address.fromString("3FdaanzgX4roVgHevhq8L8q42E7EZL9XTQr", expectedChainId = Some('D'.toByte)).explicitGet(),
chainContractAddress = chainContractAddress,
ecEngineApiUrl = s"http://${ec1.hostName}:${EcContainer.EnginePort}"
)

protected val miner1Account = mkKeyPair("devnet-1", 0)
protected val miner1RewardAddress = EthAddress.unsafeFrom("0x7dbcf9c6c3583b76669100f9be3caf6d722bc9f9")

protected val clRichAccount1 = mkKeyPair("devnet-0", 0)
protected val clRichAccount2 = mkKeyPair("devnet-0", 1)

protected val elRichAccount1 = Credentials.create("8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63")
protected val elRichAccount2 = Credentials.create("ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f")

override def beforeAll(): Unit = {
BaseItTestSuite.init()
super.beforeAll()
Expand Down
15 changes: 15 additions & 0 deletions consensus-client-it/src/test/scala/units/BridgeTestSuite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package units

class BridgeTestSuite extends BaseItTestSuite {
"L2-379 Checking balances in EL->CL transfers" in {
val sendResult = ec1.elBridge.sendNative(elRichAccount1, clRichAccount1.toAddress, BigInt("1000000000000000000"))
Thread.sleep(60000)

// waves1.api.broadcastAndWait(
// chainContract.withdraw(
// )
// )
}

"L2-380 Checking balances in CL->EL transfers" in {}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package units.network
package units

import com.wavesplatform.common.utils.EitherExt2
import units.client.engine.model.BlockNumber
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package units.network.test.docker
package units.docker

import com.wavesplatform.utils.LoggerFacade
import org.slf4j.LoggerFactory
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package units.network.test.docker
package units.docker

import com.typesafe.config.{ConfigFactory, ConfigValueFactory}
import net.ceedubs.ficus.Ficus.toFicusConfig
import org.testcontainers.containers.BindMode
import org.testcontainers.containers.Network.NetworkImpl
import org.testcontainers.utility.DockerImageName
import org.web3j.protocol.Web3j
import org.web3j.protocol.http.HttpService
import sttp.client3.HttpClientSyncBackend
import units.ClientConfig
import units.client.engine.{HttpEngineApiClient, LoggedEngineApiClient}
import units.network.test.docker.BaseContainer.{ConfigsDir, DefaultLogsDir}
import units.network.test.docker.EcContainer.{EnginePort, RpcPort, mkConfig}
import units.docker.BaseContainer.{ConfigsDir, DefaultLogsDir}
import units.docker.EcContainer.{EnginePort, RpcPort, mkConfig}
import units.el.ElBridgeClient
import units.eth.EthAddress
import units.http.OkHttpLogger

class EcContainer(network: NetworkImpl, hostName: String, ip: String) extends BaseContainer(hostName) {
protected override val container = new GenericContainer(DockerImageName.parse("hyperledger/besu:latest"))
Expand All @@ -35,7 +40,19 @@ class EcContainer(network: NetworkImpl, hostName: String, ip: String) extends Ba
private val httpClientBackend = HttpClientSyncBackend()
lazy val engineApi = new LoggedEngineApiClient(new HttpEngineApiClient(mkConfig(container.getHost, enginePort), httpClientBackend))

lazy val web3j = Web3j.build(
new HttpService(
s"http://${container.getHost}:$rpcPort",
HttpService.getOkHttpClientBuilder
.addInterceptor(OkHttpLogger)
.build()
)
)

lazy val elBridge = new ElBridgeClient(web3j, EthAddress.unsafeFrom("0x0000000000000000000000000000000000006a7e"))

override def stop(): Unit = {
web3j.shutdown()
httpClientBackend.close()
super.stop()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package units.network.test.docker
package units.docker

import org.testcontainers.containers.GenericContainer as JGenericContrainer
import org.testcontainers.utility.DockerImageName
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package units.network.test.docker
package units.docker

import com.github.dockerjava.api.command.CreateNetworkCmd
import com.github.dockerjava.api.model.Network.Ipam
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package units.network.test.docker
package units.docker

import com.wavesplatform.account.Address
import com.wavesplatform.api.NodeHttpApi
Expand All @@ -8,8 +8,8 @@ import org.testcontainers.containers.Network.NetworkImpl
import org.testcontainers.utility.DockerImageName
import sttp.client3.{HttpClientSyncBackend, UriContext}
import units.client.HttpChainContractClient
import units.network.test.docker.BaseContainer.{ConfigsDir, DefaultLogsDir}
import units.network.test.docker.WavesNodeContainer.ApiPort
import units.docker.BaseContainer.{ConfigsDir, DefaultLogsDir}
import units.docker.WavesNodeContainer.ApiPort

import java.nio.charset.StandardCharsets
import scala.jdk.CollectionConverters.MapHasAsJava
Expand Down
56 changes: 56 additions & 0 deletions consensus-client-it/src/test/scala/units/el/ElBridgeClient.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package units.el

import com.wavesplatform.account.Address
import com.wavesplatform.utils.{EthEncoding, ScorexLogging}
import org.web3j.abi.datatypes.generated.Bytes20
import org.web3j.abi.datatypes.{Type, Function as Web3Function}
import org.web3j.crypto.{Credentials, RawTransaction, TransactionEncoder}
import org.web3j.protocol.Web3j
import org.web3j.protocol.core.DefaultBlockParameterName
import org.web3j.protocol.core.methods.response.EthSendTransaction
import org.web3j.tx.gas.DefaultGasProvider
import org.web3j.utils.Numeric
import units.eth.EthAddress

import java.util.concurrent.ThreadLocalRandom
import scala.jdk.CollectionConverters.SeqHasAsJava

class ElBridgeClient(web3j: Web3j, val address: EthAddress) extends ScorexLogging {
def sendNative(sender: Credentials, recipient: Address, amountInEther: BigInt): EthSendTransaction = {
val currRequestId = ThreadLocalRandom.current().nextInt(10000, 100000).toString

val senderAddress = sender.getAddress
log.debug(s"[$currRequestId] sendNative($senderAddress->$recipient: $amountInEther Ether)")

val recipientAddressHex = Numeric.toHexString(recipient.publicKeyHash)
val data = org.web3j.abi.FunctionEncoder.encode(
new Web3Function(
"sendNative",
List[Type[?]](new Bytes20(EthEncoding.toBytes(recipientAddressHex))).asJava,
List.empty.asJava
)
)

val ethGetTransactionCount = web3j
.ethGetTransactionCount(senderAddress, DefaultBlockParameterName.LATEST)
.send()
val nonce = ethGetTransactionCount.getTransactionCount

val transaction = RawTransaction.createTransaction(
nonce,
DefaultGasProvider.GAS_PRICE,
DefaultGasProvider.GAS_LIMIT,
address.hex,
amountInEther.bigInteger,
data
)

val signedMessage = TransactionEncoder.signMessage(transaction, sender)
val hexValue = Numeric.toHexString(signedMessage)
val r = web3j.ethSendRawTransaction(hexValue).send()

log.debug(s"[$currRequestId] txn=${r.getTransactionHash}")
r
}

}
37 changes: 37 additions & 0 deletions consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package units.http

import com.wavesplatform.utils.ScorexLogging
import okhttp3.{Interceptor, Request, Response}

import java.util.concurrent.ThreadLocalRandom
import scala.util.Try

object OkHttpLogger extends Interceptor with ScorexLogging {
override def intercept(chain: Interceptor.Chain): Response = {
val currRequestId = ThreadLocalRandom.current().nextInt(10000, 100000).toString
val req = chain.request()
log.debug(s"[$currRequestId] ${req.url()} ${readRequestBody(req)}")
val res = chain.proceed(req)
log.debug(s"[$currRequestId] ${res.code()}: ${readResponseBody(res)}")
res
}

private def readRequestBody(request: Request) = request.body() match {
case null => "null"
case body =>
val buffer = new okio.Buffer()
Try {
body.writeTo(buffer)
buffer.readUtf8()
}.getOrElse("Could not read body")
}

private def readResponseBody(response: Response) = response.body() match {
case null => "null"
case body =>
val source = body.source()
source.request(Long.MaxValue) // Buffer the entire body.
val buffer = source.buffer().clone()
buffer.readUtf8()
}
}

0 comments on commit 2e6bb88

Please sign in to comment.