diff --git a/consensus-client-it/build.sbt b/consensus-client-it/build.sbt index 03df1e85..43ad5d97 100644 --- a/consensus-client-it/build.sbt +++ b/consensus-client-it/build.sbt @@ -30,28 +30,29 @@ inConfig(Test)( testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-fFWD", ((Test / logsDirectory).value / "summary.log").toString), parallelExecution := true, testGrouping := { - val javaHomeValue = (test / javaHome).value - val logDirectoryValue = (Test / logsDirectory).value - val envVarsValue = (Test / envVars).value - val javaOptionsValue = (Test / javaOptions).value + val javaHomeVal = (test / javaHome).value + val baseLogDirVal = (Test / logsDirectory).value + val envVarsVal = (Test / envVars).value + val javaOptionsVal = (Test / javaOptions).value val tests = (Test / definedTests).value tests.zipWithIndex.map { case (suite, i) => + val suiteLogDir = baseLogDirVal / suite.name.replaceAll("""(\w)\w*\.""", "$1.") // foo.bar.Baz -> f.b.Baz Group( suite.name, Seq(suite), Tests.SubProcess( ForkOptions( - javaHome = javaHomeValue, + javaHome = javaHomeVal, outputStrategy = (Test / outputStrategy).value, bootJars = Vector.empty[java.io.File], workingDirectory = Option((Test / baseDirectory).value), runJVMOptions = Vector( - s"-Dcc.it.logs.dir=${logDirectoryValue / suite.name.replaceAll("""(\w)\w*\.""", "$1.")}" // foo.bar.Baz -> f.b.Baz - ) ++ javaOptionsValue, + s"-Dcc.it.logs.dir=$suiteLogDir" + ) ++ javaOptionsVal, connectInput = false, - envVars = envVarsValue + envVars = envVarsVal ) ) ) diff --git a/consensus-client-it/src/test/scala/com/wavesplatform/api/NodeHttpApi.scala b/consensus-client-it/src/test/scala/com/wavesplatform/api/NodeHttpApi.scala index 20fb5703..671346fe 100644 --- a/consensus-client-it/src/test/scala/com/wavesplatform/api/NodeHttpApi.scala +++ b/consensus-client-it/src/test/scala/com/wavesplatform/api/NodeHttpApi.scala @@ -28,14 +28,6 @@ class NodeHttpApi(apiUri: Uri, backend: SttpBackend[Identity, ?]) extends HasRet protected override implicit val patienceConfig: PatienceConfig = PatienceConfig(timeout = averageBlockDelay, interval = 1.second) - def print(message: String): Unit = - basicRequest - .post(uri"$apiUri/debug/print") - .body(Json.obj("message" -> message)) - .header(`X-Api-Key`.name, ApiKeyValue) - .response(ignore) - .send(backend) - def waitForHeight(atLeast: Int): Int = { val loggingOptions: LoggingOptions = LoggingOptions() log.debug(s"${loggingOptions.prefix} waitForHeight($atLeast)") @@ -182,6 +174,24 @@ class NodeHttpApi(apiUri: Uri, backend: SttpBackend[Identity, ?]) extends HasRet case Left(DeserializationException(body, error)) => failRetry(s"failed to parse response $body: $error") case Right(r) => r.peers.length } + + def createWalletAddress(): Unit = { + implicit val loggingOptions: LoggingOptions = LoggingOptions() + basicRequest + .post(uri"$apiUri/addresses") + .header(`X-Api-Key`.name, ApiKeyValue) + .response(asString) + .tag(LoggingOptionsTag, loggingOptions) + .send(backend) + } + + def print(message: String): Unit = + basicRequest + .post(uri"$apiUri/debug/print") + .body(Json.obj("message" -> message)) + .header(`X-Api-Key`.name, ApiKeyValue) + .response(ignore) + .send(backend) } object NodeHttpApi { diff --git a/consensus-client-it/src/test/scala/units/Accounts.scala b/consensus-client-it/src/test/scala/units/Accounts.scala index 50b1486d..71540d02 100644 --- a/consensus-client-it/src/test/scala/units/Accounts.scala +++ b/consensus-client-it/src/test/scala/units/Accounts.scala @@ -11,11 +11,14 @@ import java.nio.charset.StandardCharsets trait Accounts { val chainContractAccount: KeyPair = mkKeyPair("devnet cc 1", 0) - val miner1Account = mkKeyPair("devnet-1", 0) - val miner1RewardAddress = EthAddress.unsafeFrom("0x7dbcf9c6c3583b76669100f9be3caf6d722bc9f9") + val miner11Account = mkKeyPair("devnet-1", 0) + val miner11RewardAddress = EthAddress.unsafeFrom("0x7dbcf9c6c3583b76669100f9be3caf6d722bc9f9") - val miner2Account = mkKeyPair("devnet-2", 0) - val miner2RewardAddress = EthAddress.unsafeFrom("0xcf0b9e13fdd593f4ca26d36afcaa44dd3fdccbed") + val miner12Account = mkKeyPair("devnet-1", 1) + val miner12RewardAddress = EthAddress.unsafeFrom("0x7dbcf9c6c3583b76669100f9be3caf6d722bc9f0") + + val miner21Account = mkKeyPair("devnet-2", 0) + val miner21RewardAddress = EthAddress.unsafeFrom("0xcf0b9e13fdd593f4ca26d36afcaa44dd3fdccbed") val clRichAccount1 = mkKeyPair("devnet rich", 0) val clRichAccount2 = mkKeyPair("devnet rich", 1) diff --git a/consensus-client-it/src/test/scala/units/BridgeC2ETestSuite.scala b/consensus-client-it/src/test/scala/units/BridgeC2ETestSuite.scala index 7d009f04..89c76e7c 100644 --- a/consensus-client-it/src/test/scala/units/BridgeC2ETestSuite.scala +++ b/consensus-client-it/src/test/scala/units/BridgeC2ETestSuite.scala @@ -4,7 +4,7 @@ import com.wavesplatform.transaction.TxHelpers import units.client.engine.model.BlockNumber import units.eth.EthAddress -class BridgeC2ETestSuite extends OneNodeTestSuite { +class BridgeC2ETestSuite extends OneNodeTestSuite with OneNodeTestSuite.OneMiner { protected val clSender = clRichAccount1 protected val elReceiver = elRichAccount1 protected val elReceiverAddress = EthAddress.unsafeFrom(elReceiver.getAddress) diff --git a/consensus-client-it/src/test/scala/units/BridgeE2CTestSuite.scala b/consensus-client-it/src/test/scala/units/BridgeE2CTestSuite.scala index dd39fb8e..91286d3d 100644 --- a/consensus-client-it/src/test/scala/units/BridgeE2CTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/BridgeE2CTestSuite.scala @@ -1,7 +1,5 @@ package units -import com.wavesplatform.account.KeyPair -import com.wavesplatform.api.http.ApiError.ScriptExecutionError import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.utils.EthEncoding import org.web3j.protocol.core.DefaultBlockParameterName @@ -10,7 +8,7 @@ import org.web3j.protocol.exceptions.TransactionException import org.web3j.utils.Convert import units.el.ElBridgeClient -class BridgeE2CTestSuite extends OneNodeTestSuite { +class BridgeE2CTestSuite extends OneNodeTestSuite with OneNodeTestSuite.OneMiner { protected val elSender = elRichAccount1 protected val clRecipient = clRichAccount1 protected val userAmount = 1 @@ -46,7 +44,7 @@ class BridgeE2CTestSuite extends OneNodeTestSuite { } withClue("2. More than MAX_AMOUNT_IN_WEI: ") { - val maxAmountInWei = BigInt(Long.MaxValue) + val maxAmountInWei = BigInt(Long.MaxValue) * tenGwei val biggerAmount = (maxAmountInWei / tenGwei + 1) * tenGwei val e = sendNativeInvalid(biggerAmount) val encodedRevertReason = e.getTransactionReceipt.get().getRevertReason @@ -96,25 +94,6 @@ class BridgeE2CTestSuite extends OneNodeTestSuite { waves1.chainContract.getBlock(blockHash).get.height } - val currFinalizedHeight = waves1.chainContract.getFinalizedBlock.height - if (currFinalizedHeight >= blockConfirmationHeight) - fail(s"Can't continue the test: the block ($blockConfirmationHeight) is already finalized ($currFinalizedHeight)") - - log.info("Trying to withdraw before finalization") - def withdraw(sender: KeyPair = clRecipient) = chainContract.withdraw( - sender = sender, - blockHash = BlockHash(sendTxnReceipt.getBlockHash), - merkleProof = transferProofs, - transferIndexInBlock = sendTxnLogIndex, - amount = wavesAmount - ) - - withClue("2. Withdraws from non-finalized blocks are denied: ") { - val attempt1 = waves1.api.broadcast(withdraw()).left.value - attempt1.error shouldBe ScriptExecutionError.Id - attempt1.message should include("is not finalized") - } - log.info(s"Wait block $blockHash ($blockConfirmationHeight) finalization") retry { val currFinalizedHeight = waves1.chainContract.getFinalizedBlock.height @@ -131,7 +110,15 @@ class BridgeE2CTestSuite extends OneNodeTestSuite { def receiverBalance: Long = waves1.api.balance(clRecipient.toAddress, waves1.chainContract.token) val receiverBalanceBefore = receiverBalance - waves1.api.broadcastAndWait(withdraw()) + waves1.api.broadcastAndWait( + chainContract.withdraw( + sender = clRecipient, + blockHash = BlockHash(sendTxnReceipt.getBlockHash), + merkleProof = transferProofs, + transferIndexInBlock = sendTxnLogIndex, + amount = wavesAmount + ) + ) val balanceAfter = receiverBalance balanceAfter shouldBe (receiverBalanceBefore + wavesAmount) diff --git a/consensus-client-it/src/test/scala/units/OneNodeTestSuite.scala b/consensus-client-it/src/test/scala/units/OneNodeTestSuite.scala index 3a74d0ed..3a20541d 100644 --- a/consensus-client-it/src/test/scala/units/OneNodeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/OneNodeTestSuite.scala @@ -54,21 +54,57 @@ trait OneNodeTestSuite extends BaseItTestSuite { log.info(s"Token id: ${waves1.chainContract.token}") - log.info("Waves miner #1 join") - val joinMiner1Result = waves1.api.broadcastAndWait( - chainContract.join( - minerAccount = miner1Account, - elRewardAddress = miner1RewardAddress - ) - ) - - val epoch1Number = joinMiner1Result.height + 1 - log.info(s"Wait for #$epoch1Number epoch") - waves1.api.waitForHeight(epoch1Number) + joinMiners() } + protected def joinMiners(): Unit + override protected def print(text: String): Unit = { super.print(text) waves1.api.print(text) } } + +object OneNodeTestSuite { + trait OneMiner { this: OneNodeTestSuite => + override protected def joinMiners(): Unit = { + log.info("EL miner #1 join") + val joinMiner1Result = waves1.api.broadcastAndWait( + chainContract.join( + minerAccount = miner11Account, + elRewardAddress = miner11RewardAddress + ) + ) + + val epoch1Number = joinMiner1Result.height + 1 + log.info(s"Wait for #$epoch1Number epoch") + waves1.api.waitForHeight(epoch1Number) + } + } + + trait TwoMiners { this: OneNodeTestSuite => + override protected def joinMiners(): Unit = { + waves1.api.createWalletAddress() // Init miner2Account + + log.info("EL miner #1 join") + waves1.api.broadcastAndWait( + chainContract.join( + minerAccount = miner11Account, + elRewardAddress = miner11RewardAddress + ) + ) + + log.info("EL miner #2 join") + val joinMiner2Result = waves1.api.broadcastAndWait( + chainContract.join( + minerAccount = miner12Account, + elRewardAddress = miner12RewardAddress + ) + ) + + val epoch1Number = joinMiner2Result.height + 1 + log.info(s"Wait for #$epoch1Number epoch") + waves1.api.waitForHeight(epoch1Number) + } + } +} diff --git a/consensus-client-it/src/test/scala/units/RewardTestSuite.scala b/consensus-client-it/src/test/scala/units/RewardTestSuite.scala index 29b41e49..ab7478bd 100644 --- a/consensus-client-it/src/test/scala/units/RewardTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/RewardTestSuite.scala @@ -3,7 +3,7 @@ package units import com.wavesplatform.common.utils.EitherExt2 import units.client.engine.model.BlockNumber -class RewardTestSuite extends OneNodeTestSuite { +class RewardTestSuite extends OneNodeTestSuite with OneNodeTestSuite.OneMiner { "L2-234 The reward for a previous epoch is in the first block withdrawals" in { val epoch1FirstEcBlock = retry { ec1.engineApi.getBlockByNumber(BlockNumber.Number(1)).explicitGet().get @@ -39,7 +39,7 @@ class RewardTestSuite extends OneNodeTestSuite { } withClue("Expected reward receiver: ") { - epoch2FirstEcBlock.withdrawals(0).address shouldBe miner1RewardAddress + epoch2FirstEcBlock.withdrawals(0).address shouldBe miner11RewardAddress } } } diff --git a/consensus-client-it/src/test/scala/units/TwoNodesTestSuite.scala b/consensus-client-it/src/test/scala/units/TwoNodesTestSuite.scala index 2b0e4aff..63b2f4ae 100644 --- a/consensus-client-it/src/test/scala/units/TwoNodesTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/TwoNodesTestSuite.scala @@ -97,16 +97,16 @@ trait TwoNodesTestSuite extends BaseItTestSuite { log.info("Waves miner #1 join") waves1.api.broadcastAndWait( chainContract.join( - minerAccount = miner1Account, - elRewardAddress = miner1RewardAddress + minerAccount = miner11Account, + elRewardAddress = miner11RewardAddress ) ) log.info("Waves miner #2 join") val joinMiner2Result = waves1.api.broadcastAndWait( chainContract.join( - minerAccount = miner2Account, - elRewardAddress = miner2RewardAddress + minerAccount = miner21Account, + elRewardAddress = miner21RewardAddress ) ) diff --git a/consensus-client-it/src/test/scala/units/docker/BaseContainer.scala b/consensus-client-it/src/test/scala/units/docker/BaseContainer.scala index 6f9a75e4..6f2ab8f6 100644 --- a/consensus-client-it/src/test/scala/units/docker/BaseContainer.scala +++ b/consensus-client-it/src/test/scala/units/docker/BaseContainer.scala @@ -4,7 +4,7 @@ import com.wavesplatform.utils.LoggerFacade import org.slf4j.LoggerFactory import org.testcontainers.containers.wait.strategy.DockerHealthcheckWaitStrategy -import java.nio.file.Path +import java.nio.file.{Files, Path} abstract class BaseContainer(val hostName: String) { protected lazy val log = LoggerFacade(LoggerFactory.getLogger(s"${getClass.getSimpleName}.$hostName")) @@ -27,7 +27,9 @@ abstract class BaseContainer(val hostName: String) { } object BaseContainer { - val ConfigsDir: Path = Path.of(System.getProperty("cc.it.configs.dir")) - val DefaultLogsDir: Path = Path.of(System.getProperty("cc.it.logs.dir")) + val ConfigsDir: Path = Path.of(System.getProperty("cc.it.configs.dir")) + val DefaultLogsDir: Path = Path.of(System.getProperty("cc.it.logs.dir")) + Files.createDirectories(DefaultLogsDir) + val WavesDockerImage: String = System.getProperty("cc.it.docker.image") } diff --git a/consensus-client-it/src/test/scala/units/docker/WavesNodeContainer.scala b/consensus-client-it/src/test/scala/units/docker/WavesNodeContainer.scala index 31f6d3f0..bea893ff 100644 --- a/consensus-client-it/src/test/scala/units/docker/WavesNodeContainer.scala +++ b/consensus-client-it/src/test/scala/units/docker/WavesNodeContainer.scala @@ -1,6 +1,6 @@ package units.docker -import com.google.common.io.Files as GFiles +import com.google.common.io.Files import com.google.common.primitives.{Bytes, Ints} import com.wavesplatform.account.{Address, KeyPair, SeedKeyPair} import com.wavesplatform.api.{LoggingBackend, NodeHttpApi} @@ -30,7 +30,7 @@ class WavesNodeContainer( genesisConfigPath: Path ) extends BaseContainer(s"wavesnode-$number") { private val logFile = new File(s"$DefaultLogsDir/waves-$number.log") - GFiles.touch(logFile) + Files.touch(logFile) protected override val container = new GenericContainer(DockerImageName.parse(WavesDockerImage)) .withNetwork(network) diff --git a/local-network/configs/ec-common/genesis.json b/local-network/configs/ec-common/genesis.json index d9cbe0fe..310fa591 100644 --- a/local-network/configs/ec-common/genesis.json +++ b/local-network/configs/ec-common/genesis.json @@ -29,12 +29,12 @@ "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": { "privateKey": "0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", "//": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", - "balance": "0xad78ebc5ac6200000" + "balance": "0x2540be4000000000000000000" }, "0xf17f52151EbEF6C7334FAD080c5704D77216b732": { "privateKey": "0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", "//": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", - "balance": "90000000000000000000000" + "balance": "0x2540be4000000000000000001" }, "0x0000000000000000000000000000000000006a7e": { "//1": "Bridge contract. To get new code, run: bridge-compile.sh",