diff --git a/consensus-client-it/build.sbt b/consensus-client-it/build.sbt
index b446338a..5ad09114 100644
--- a/consensus-client-it/build.sbt
+++ b/consensus-client-it/build.sbt
@@ -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
diff --git a/consensus-client-it/src/test/resources/logback-test.xml b/consensus-client-it/src/test/resources/logback-test.xml
index a7ce880b..1a2e690a 100644
--- a/consensus-client-it/src/test/resources/logback-test.xml
+++ b/consensus-client-it/src/test/resources/logback-test.xml
@@ -28,6 +28,9 @@
+
+
+
diff --git a/consensus-client-it/src/test/scala/units/network/BaseItTestSuite.scala b/consensus-client-it/src/test/scala/units/BaseItTestSuite.scala
similarity index 86%
rename from consensus-client-it/src/test/scala/units/network/BaseItTestSuite.scala
rename to consensus-client-it/src/test/scala/units/BaseItTestSuite.scala
index ec290c1c..7f3f91ae 100644
--- a/consensus-client-it/src/test/scala/units/network/BaseItTestSuite.scala
+++ b/consensus-client-it/src/test/scala/units/BaseItTestSuite.scala
@@ -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
@@ -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
@@ -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()
diff --git a/consensus-client-it/src/test/scala/units/BridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/BridgeTestSuite.scala
new file mode 100644
index 00000000..c6ec691b
--- /dev/null
+++ b/consensus-client-it/src/test/scala/units/BridgeTestSuite.scala
@@ -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 {}
+}
diff --git a/consensus-client-it/src/test/scala/units/network/RewardTestSuite.scala b/consensus-client-it/src/test/scala/units/RewardTestSuite.scala
similarity index 98%
rename from consensus-client-it/src/test/scala/units/network/RewardTestSuite.scala
rename to consensus-client-it/src/test/scala/units/RewardTestSuite.scala
index fbc4ada8..374728f9 100644
--- a/consensus-client-it/src/test/scala/units/network/RewardTestSuite.scala
+++ b/consensus-client-it/src/test/scala/units/RewardTestSuite.scala
@@ -1,4 +1,4 @@
-package units.network
+package units
import com.wavesplatform.common.utils.EitherExt2
import units.client.engine.model.BlockNumber
diff --git a/consensus-client-it/src/test/scala/units/network/test/docker/BaseContainer.scala b/consensus-client-it/src/test/scala/units/docker/BaseContainer.scala
similarity index 95%
rename from consensus-client-it/src/test/scala/units/network/test/docker/BaseContainer.scala
rename to consensus-client-it/src/test/scala/units/docker/BaseContainer.scala
index f42e791b..098c49db 100644
--- a/consensus-client-it/src/test/scala/units/network/test/docker/BaseContainer.scala
+++ b/consensus-client-it/src/test/scala/units/docker/BaseContainer.scala
@@ -1,4 +1,4 @@
-package units.network.test.docker
+package units.docker
import com.wavesplatform.utils.LoggerFacade
import org.slf4j.LoggerFactory
diff --git a/consensus-client-it/src/test/scala/units/network/test/docker/EcContainer.scala b/consensus-client-it/src/test/scala/units/docker/EcContainer.scala
similarity index 79%
rename from consensus-client-it/src/test/scala/units/network/test/docker/EcContainer.scala
rename to consensus-client-it/src/test/scala/units/docker/EcContainer.scala
index 70131e03..15736a96 100644
--- a/consensus-client-it/src/test/scala/units/network/test/docker/EcContainer.scala
+++ b/consensus-client-it/src/test/scala/units/docker/EcContainer.scala
@@ -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"))
@@ -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()
}
diff --git a/consensus-client-it/src/test/scala/units/network/test/docker/GenericContainer.scala b/consensus-client-it/src/test/scala/units/docker/GenericContainer.scala
similarity index 89%
rename from consensus-client-it/src/test/scala/units/network/test/docker/GenericContainer.scala
rename to consensus-client-it/src/test/scala/units/docker/GenericContainer.scala
index 7c3f4152..7704cf02 100644
--- a/consensus-client-it/src/test/scala/units/network/test/docker/GenericContainer.scala
+++ b/consensus-client-it/src/test/scala/units/docker/GenericContainer.scala
@@ -1,4 +1,4 @@
-package units.network.test.docker
+package units.docker
import org.testcontainers.containers.GenericContainer as JGenericContrainer
import org.testcontainers.utility.DockerImageName
diff --git a/consensus-client-it/src/test/scala/units/network/test/docker/Networks.scala b/consensus-client-it/src/test/scala/units/docker/Networks.scala
similarity index 96%
rename from consensus-client-it/src/test/scala/units/network/test/docker/Networks.scala
rename to consensus-client-it/src/test/scala/units/docker/Networks.scala
index d27b15ed..5027f624 100644
--- a/consensus-client-it/src/test/scala/units/network/test/docker/Networks.scala
+++ b/consensus-client-it/src/test/scala/units/docker/Networks.scala
@@ -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
diff --git a/consensus-client-it/src/test/scala/units/network/test/docker/WavesNodeContainer.scala b/consensus-client-it/src/test/scala/units/docker/WavesNodeContainer.scala
similarity index 93%
rename from consensus-client-it/src/test/scala/units/network/test/docker/WavesNodeContainer.scala
rename to consensus-client-it/src/test/scala/units/docker/WavesNodeContainer.scala
index 819b5080..0ac5d9b4 100644
--- a/consensus-client-it/src/test/scala/units/network/test/docker/WavesNodeContainer.scala
+++ b/consensus-client-it/src/test/scala/units/docker/WavesNodeContainer.scala
@@ -1,4 +1,4 @@
-package units.network.test.docker
+package units.docker
import com.wavesplatform.account.Address
import com.wavesplatform.api.NodeHttpApi
@@ -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
diff --git a/consensus-client-it/src/test/scala/units/el/ElBridgeClient.scala b/consensus-client-it/src/test/scala/units/el/ElBridgeClient.scala
new file mode 100644
index 00000000..99b09d19
--- /dev/null
+++ b/consensus-client-it/src/test/scala/units/el/ElBridgeClient.scala
@@ -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
+ }
+
+}
diff --git a/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala b/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala
new file mode 100644
index 00000000..360a7a0a
--- /dev/null
+++ b/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala
@@ -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()
+ }
+}