From aaae45b0bb90f3d6ece3ef8368f279bea06def2d Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Fri, 31 Oct 2025 13:08:22 +0300 Subject: [PATCH 01/31] Store block delay on chain contract # Conflicts: # src/main/scala/units/ELUpdater.scala --- .../units/BaseBlockValidationSuite.scala | 2 +- .../scala/units/BaseDockerTestSuite.scala | 8 +-- contracts/waves/src/main.ride | 5 +- src/main/scala/units/ClientConfig.scala | 1 - src/main/scala/units/ELUpdater.scala | 68 ++++++++----------- .../client/contract/ChainContractClient.scala | 39 ++++++++--- .../contract/ChainContractOptions.scala | 12 ++-- src/main/scala/units/eth/Gwei.scala | 17 ++--- src/test/scala/units/BaseTestSuite.scala | 21 +++--- .../scala/units/ClientConfigTestSuite.scala | 3 - src/test/scala/units/ExtensionDomain.scala | 11 +-- src/test/scala/units/RegistryTestSuite.scala | 3 +- src/test/scala/units/TestSettings.scala | 1 + .../HasConsensusLayerDappTxHelpers.scala | 6 +- 14 files changed, 100 insertions(+), 97 deletions(-) diff --git a/consensus-client-it/src/test/scala/units/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/BaseBlockValidationSuite.scala index 0595f122..5b127b72 100644 --- a/consensus-client-it/src/test/scala/units/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/BaseBlockValidationSuite.scala @@ -66,7 +66,7 @@ trait BaseBlockValidationSuite extends BaseDockerTestSuite { if (elParentBlock.height - 1 <= EthereumConstants.GenesisBlockHeight) Right(-1L) else ec1.engineApi.getLastWithdrawalIndex(elParentBlock.parentHash) }).explicitGet() - Withdrawal(elWithdrawalIndexBefore + 1, elParentBlock.minerRewardL2Address, chainContractOptions.miningReward) + Withdrawal(elWithdrawalIndexBefore + 1, elParentBlock.minerRewardL2Address, chainContractOptions.miningReward.newValue) } protected final def mkSimulatedBlock( diff --git a/consensus-client-it/src/test/scala/units/BaseDockerTestSuite.scala b/consensus-client-it/src/test/scala/units/BaseDockerTestSuite.scala index 7bf0d3eb..a675bcb5 100644 --- a/consensus-client-it/src/test/scala/units/BaseDockerTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/BaseDockerTestSuite.scala @@ -94,13 +94,7 @@ trait BaseDockerTestSuite step("Setup chain contract") val genesisBlock = ec1.engineApi.getBlockByNumber(BlockNumber.Number(0)).explicitGet().getOrElse(fail("No EL genesis block")) waves1.api.broadcastAndWait( - ChainContract.setup( - genesisBlock = genesisBlock, - elMinerReward = rewardAmount.amount.longValue(), - daoAddress = None, - daoReward = 0, - invoker = chainContractAccount - ) + ChainContract.setup(genesisBlock, rewardAmount.amount.longValue(), None, 0, 2, invoker = chainContractAccount) ) log.info(s"Native token id: ${chainContract.nativeTokenId}") diff --git a/contracts/waves/src/main.ride b/contracts/waves/src/main.ride index 8ef88edd..2f0cb87e 100644 --- a/contracts/waves/src/main.ride +++ b/contracts/waves/src/main.ride @@ -1082,7 +1082,7 @@ func enableTokenTransfers(standardBridgeAddress: String, wavesERC20AddressHex: S # genesisBlockHashHex without 0x @Callable(i) -func setup(genesisBlockHashHex: String, minerRewardInGwei: Int, daoAddress: String, daoReward: Int) = { +func setup(genesisBlockHashHex: String, minerRewardInGwei: Int, daoAddress: String, daoReward: Int, blockDelayInSeconds: Int) = { if (isContractSetup()) then throw("The contract has been already set up") else if (i.originCaller != this) then throw("Only owner of chain contract can do this") else if (minerRewardInGwei < 0) then throw("The miner reward must be nonnegative") @@ -1122,7 +1122,8 @@ func setup(genesisBlockHashHex: String, minerRewardInGwei: Int, daoAddress: Stri StringEntry(finalizedBlockKey, genesisBlockHashHex), issue, StringEntry(tokenIdKey, tokenId.toBase58String()), - StringEntry(elNativeBridgeAddressKey, "0x0000000000000000000000000000000000006a7e") + StringEntry(elNativeBridgeAddressKey, "0x0000000000000000000000000000000000006a7e"), + IntegerEntry("blockDelay", blockDelayInSeconds) ] ++ daoEntries } } diff --git a/src/main/scala/units/ClientConfig.scala b/src/main/scala/units/ClientConfig.scala index 883193e2..bddcd30e 100644 --- a/src/main/scala/units/ClientConfig.scala +++ b/src/main/scala/units/ClientConfig.scala @@ -14,7 +14,6 @@ case class ClientConfig( executionClientAddress: String, apiRequestRetries: Int, apiRequestRetryWaitTime: FiniteDuration, - blockDelay: FiniteDuration, firstBlockMinDelay: FiniteDuration, blockSyncRequestTimeout: FiniteDuration, network: NetworkSettings, diff --git a/src/main/scala/units/ELUpdater.scala b/src/main/scala/units/ELUpdater.scala index c04e0f3f..c40762f3 100644 --- a/src/main/scala/units/ELUpdater.scala +++ b/src/main/scala/units/ELUpdater.scala @@ -12,10 +12,10 @@ import com.wavesplatform.network.ChannelGroupExt import com.wavesplatform.state.diffs.FeeValidation.{FeeConstants, FeeUnit, ScriptExtraFee} import com.wavesplatform.state.diffs.TransactionDiffer.TransactionValidationError import com.wavesplatform.state.{Blockchain, BooleanDataEntry} +import com.wavesplatform.transaction.* import com.wavesplatform.transaction.TxValidationError.InvokeRejectError import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.smart.script.trace.TracedResult -import com.wavesplatform.transaction.* import com.wavesplatform.utils.{Time, UnsupportedFeature, forceStopApplication} import com.wavesplatform.wallet.Wallet import io.netty.channel.Channel @@ -189,7 +189,7 @@ class ELUpdater( val startC2ETransferIndex = lastC2ETransferIndex + 1 val rewardWithdrawal = prevEpochMinerRewardAddress - .map(Withdrawal(startElWithdrawalIndex, _, chainContractOptions.miningReward)) + .map(Withdrawal(startElWithdrawalIndex, _, chainContractOptions.miningReward.valueAtEpoch(epochInfo.number))) .toVector val strictC2ETransfersActivated = epochInfo.number >= chainContractClient.getStrictC2ETransfersActivationEpoch @@ -301,7 +301,7 @@ class ELUpdater( lastEcBlock <- engineApiClient.getLastExecutionBlock() willSimulateBlock = lastEcBlock.hash != parentBlock.hash currentUnixTs = time.correctedTime() / 1000 - nextBlockUnixTs = (parentBlock.timestamp + config.blockDelay.toSeconds).max( + nextBlockUnixTs = (parentBlock.timestamp + prevState.options.blockDelayInSeconds.valueAtEpoch(epochInfo.number)).max( currentUnixTs + // We don't collect transactions for simulated payload, thus we don't need to wait for firstBlockMinDelay (if (willSimulateBlock) 0 else config.firstBlockMinDelay.toSeconds) @@ -390,8 +390,9 @@ class ELUpdater( getAndApplyPayloadResult match { case Left(err) => logger.error(s"Failed to forge block at epoch ${epochInfo.number}: $err") case Right(networkBlock) => - val ecBlock = networkBlock.toEcBlock - val nextBlockUnixTs = (ecBlock.timestamp + config.blockDelay.toSeconds).max(time.correctedTime() / 1000) + val ecBlock = networkBlock.toEcBlock + val nextBlockUnixTs = + (ecBlock.timestamp + chainContractOptions.blockDelayInSeconds.valueAtEpoch(epochInfo.number)).max(time.correctedTime() / 1000) val nextMiningDataE = updateHeadAndStartBuildingPayload( epochInfo, ecBlock, @@ -1004,38 +1005,28 @@ class ELUpdater( } // Of a current epoch miner - private def validateBlockSignature(block: NetworkL2Block, epochInfo: Option[EpochInfo]): Result[Unit] = { - epochInfo match { - case Some(epochMeta) => - for { - _ <- Either.raiseUnless(block.minerRewardL2Address == epochMeta.rewardAddress) { - s"block miner ${block.minerRewardL2Address} doesn't equal to ${epochMeta.rewardAddress}" - } - signature <- Either.fromOption(block.signature, s"signature not found") - publicKey <- Either.fromOption( - chainContractClient.getMinerPublicKey(block.minerRewardL2Address), - s"public key for block miner ${block.minerRewardL2Address} not found" - ) - _ <- Either.raiseUnless(crypto.verify(signature, Json.toBytes(block.payload), publicKey, checkWeakPk = true)) { - s"invalid signature" - } - } yield () - case _ => Either.unit - } - } + private def validateBlockSignature(block: NetworkL2Block, epochInfo: EpochInfo): Result[Unit] = + for { + _ <- Either.raiseUnless(block.minerRewardL2Address == epochInfo.rewardAddress) { + s"block miner ${block.minerRewardL2Address} doesn't equal to ${epochInfo.rewardAddress}" + } + signature <- Either.fromOption(block.signature, s"signature not found") + publicKey <- Either.fromOption( + chainContractClient.getMinerPublicKey(block.minerRewardL2Address), + s"public key for block miner ${block.minerRewardL2Address} not found" + ) + _ <- Either.raiseUnless(crypto.verify(signature, Json.toBytes(block.payload), publicKey, checkWeakPk = true)) { + s"invalid signature" + } + } yield () - private def validateTimestamp(newNetworkBlock: NetworkL2Block, parentEcBlock: EcBlock): Result[Unit] = { - val minAppendTs = parentEcBlock.timestamp + config.blockDelay.toSeconds + private def validateTimestamp(newNetworkBlock: NetworkL2Block, parentEcBlock: EcBlock, epoch: Int): Result[Unit] = { + val minAppendTs = parentEcBlock.timestamp + chainContractClient.getOptions.blockDelayInSeconds.valueAtEpoch(epoch) Either.raiseUnless(newNetworkBlock.timestamp >= minAppendTs) { s"timestamp (${newNetworkBlock.timestamp}) of appended block must be greater or equal $minAppendTs, Δ${minAppendTs - newNetworkBlock.timestamp}s" } } - private def preValidateBlock(networkBlock: NetworkL2Block, parentBlock: EcBlock, epochInfo: Option[EpochInfo]): Result[Unit] = for { - _ <- validateTimestamp(networkBlock, parentBlock) - _ <- validateBlockSignature(networkBlock, epochInfo) - } yield () - private def getAltChainReferenceBlock(nodeChainInfo: ChainInfo, lastContractBlock: ContractBlock): Result[ContractBlock] = { if (nodeChainInfo.isMain) { for { @@ -1097,9 +1088,8 @@ class ELUpdater( processInvalidBlock(contractBlock, prevState, Some(nodeChainInfo)) } case contractBlock => - // We should check block signature based on epochInfo if block is not at contract yet - val epochInfo = Option.when(contractBlock.isEmpty)(prevState.epochInfo) - applyBlock(networkBlock, parentBlock, epochInfo) match { + (if (contractBlock.isEmpty) validateBlockSignature(networkBlock, prevState.epochInfo) else ().asRight[ClientError]) + .flatMap(_ => applyBlock(networkBlock, parentBlock, prevState.epochInfo)) match { case Right(_) => logger.debug(s"Block ${networkBlock.hash} successfully applied") broadcastAndConfirmBlock(networkBlock, ch, prevState, nodeChainInfo, returnToMainChainInfo) @@ -1560,13 +1550,13 @@ class ELUpdater( ): Result[Working[ChainStatus]] = { logger.trace(s"Trying to apply and do a full validation of block ${networkBlock.hash}") for { - _ <- applyBlock(networkBlock, parentBlock, epochInfo = None) // epochInfo is empty, because we don't need to validate a block signature + _ <- applyBlock(networkBlock, parentBlock, prevState.epochInfo) updatedState <- validateAppliedBlock(contractBlock, networkBlock.toEcBlock, prevState) } yield updatedState } - private def applyBlock(networkBlock: NetworkL2Block, parentBlock: EcBlock, epochInfo: Option[EpochInfo]): Result[Unit] = for { - _ <- preValidateBlock(networkBlock, parentBlock, epochInfo) + private def applyBlock(networkBlock: NetworkL2Block, parentBlock: EcBlock, epochInfo: EpochInfo): Result[Unit] = for { + _ <- validateTimestamp(networkBlock, parentBlock, epochInfo.number) _ <- engineApiClient.newPayload(networkBlock.payload) } yield () @@ -1594,7 +1584,9 @@ class ELUpdater( _ <- validateE2CTransfers(contractBlock, ecBlockLogs) _ <- validateAssetRegistryUpdate(ecBlockLogs, contractBlock, parentContractBlock, prevState.options) _ <- validateRandao(ecBlock, contractBlock.epoch) - miningReward = getMinerRewardAddress(contractBlock, parentContractBlock).map(MiningReward(_, prevState.options.miningReward)) + miningReward = getMinerRewardAddress(contractBlock, parentContractBlock).map( + MiningReward(_, prevState.options.miningReward.valueAtEpoch(contractBlock.epoch)) + ) updatedLastElWithdrawalIndex <- validateC2E( contractBlock, ecBlock, diff --git a/src/main/scala/units/client/contract/ChainContractClient.scala b/src/main/scala/units/client/contract/ChainContractClient.scala index 238b2cef..c32736c7 100644 --- a/src/main/scala/units/client/contract/ChainContractClient.scala +++ b/src/main/scala/units/client/contract/ChainContractClient.scala @@ -213,17 +213,34 @@ trait ChainContractClient { .orElse(getBinaryData(s"miner${rewardAddress.hexNoPrefix}PK")) .map(PublicKey(_)) - def getOptions: ChainContractOptions = ChainContractOptions( - miningReward = getLongData("minerReward") - .map(Gwei.ofRawGwei) - .getOrElse(throw new IllegalStateException("minerReward is empty on contract")), - elNativeBridgeAddress = getStringData("elBridgeAddress") - .map(EthAddress.unsafeFrom) - .getOrElse(throw new IllegalStateException("elBridgeAddress is empty on contract")), - elStandardBridgeAddress = getStringData("elStandardBridgeAddress") - .map(EthAddress.unsafeFrom), - assetTransfersActivationEpoch = getAssetTransfersActivationEpoch - ) + def getOptions: ChainContractOptions = { + val minerReward = extractData("minerReward") match { + case Some(IntegerDataEntry(value = reward)) => ValueAtEpoch(Gwei.ofRawGwei(0), Gwei.ofRawGwei(reward), 1) + case Some(StringDataEntry(value = rewards)) => + val Array(oldReward, newReward, changeEpoch) = rewards.split(Sep) + ValueAtEpoch(Gwei.ofRawGwei(oldReward.toLong), Gwei.ofRawGwei(newReward.toLong), changeEpoch.toInt) + case _ => throw new IllegalStateException("minerReward is empty on contract") + } + + val blockDelay = extractData("blockDelay") match { + case Some(IntegerDataEntry(value = delay)) => ValueAtEpoch(0, BigInt(delay).bigInteger.intValueExact(), 1) + case Some(StringDataEntry(value = delays)) => + val Array(oldDelay, newDelay, changeEpoch) = delays.split(Sep) + ValueAtEpoch(oldDelay.toInt, newDelay.toInt, changeEpoch.toInt) + case _ => throw new IllegalStateException("blockDelay is empty on contract") + } + + ChainContractOptions( + minerReward, + getStringData("elBridgeAddress") + .map(EthAddress.unsafeFrom) + .getOrElse(throw new IllegalStateException("elBridgeAddress is empty on contract")), + getStringData("elStandardBridgeAddress") + .map(EthAddress.unsafeFrom), + getAssetTransfersActivationEpoch, + blockDelay + ) + } private def getAssetTransfersActivationEpoch: Long = getLongData("assetTransfersActivationEpoch").getOrElse(Long.MaxValue) diff --git a/src/main/scala/units/client/contract/ChainContractOptions.scala b/src/main/scala/units/client/contract/ChainContractOptions.scala index 4df04dbc..c2419eab 100644 --- a/src/main/scala/units/client/contract/ChainContractOptions.scala +++ b/src/main/scala/units/client/contract/ChainContractOptions.scala @@ -5,14 +5,12 @@ import units.BlockHash import units.client.contract.ContractFunction.* import units.eth.{EthAddress, Gwei} -/** @note - * Make sure you have an activation gap: a new feature should not be activated suddenly during nearest blocks. - */ case class ChainContractOptions( - miningReward: Gwei, + miningReward: ValueAtEpoch[Gwei], elNativeBridgeAddress: EthAddress, elStandardBridgeAddress: Option[EthAddress], - assetTransfersActivationEpoch: Long + assetTransfersActivationEpoch: Long, + blockDelayInSeconds: ValueAtEpoch[Int] ) { def bridgeAddresses(epoch: Int): List[EthAddress] = { val before = List(elNativeBridgeAddress) @@ -35,3 +33,7 @@ case class ChainContractOptions( private def versionOf(epoch: Int): Int = if (epoch < assetTransfersActivationEpoch) 1 else 2 } + +case class ValueAtEpoch[A](oldValue: A, newValue: A, changeAtEpoch: Int) { + def valueAtEpoch(epoch: Int): A = if epoch < changeAtEpoch then oldValue else newValue +} \ No newline at end of file diff --git a/src/main/scala/units/eth/Gwei.scala b/src/main/scala/units/eth/Gwei.scala index f8b628c6..bb346181 100644 --- a/src/main/scala/units/eth/Gwei.scala +++ b/src/main/scala/units/eth/Gwei.scala @@ -5,21 +5,14 @@ import play.api.libs.json.Format import java.math.BigInteger -class Gwei private (val amount: BigInteger) { - def toHex: String = Numeric.toHexStringWithPrefix(amount) - - override def hashCode(): Int = amount.hashCode() - override def equals(that: Any): Boolean = that match { - case that: Gwei => this.amount.compareTo(that.amount) == 0 - case _ => false - } - override def toString: String = s"${amount.toString} Gwei" -} +opaque type Gwei = BigInteger object Gwei { - implicit val gweiFormat: Format[Gwei] = implicitly[Format[String]].bimap(ofRawGwei, _.toHex) + implicit val gweiFormat: Format[Gwei] = implicitly[Format[String]].bimap(ofRawGwei, Numeric.toHexStringWithPrefix) + + extension (g: Gwei) def amount: BigInteger = g def ofRawGwei(x: Long): Gwei = ofRawGwei(BigInteger.valueOf(x)) - def ofRawGwei(x: BigInteger): Gwei = new Gwei(x) + def ofRawGwei(x: BigInteger): Gwei = x def ofRawGwei(hex: String): Gwei = Gwei.ofRawGwei(Numeric.toBigInt(hex)) } diff --git a/src/test/scala/units/BaseTestSuite.scala b/src/test/scala/units/BaseTestSuite.scala index 136dd247..d853a6c8 100644 --- a/src/test/scala/units/BaseTestSuite.scala +++ b/src/test/scala/units/BaseTestSuite.scala @@ -23,6 +23,7 @@ import units.util.HexBytesConverter import java.nio.charset.StandardCharsets import java.util.concurrent.ThreadLocalRandom +import scala.concurrent.duration.DurationInt trait BaseTestSuite extends AnyFreeSpec @@ -49,7 +50,8 @@ trait BaseTestSuite d.ecGenesisBlock, ElMinerDefaultReward.amount.longValue(), defaultSettings.daoRewardAccount.map(_.toAddress), - defaultSettings.daoRewardAmount + defaultSettings.daoRewardAmount, + defaultSettings.blockDelayInSeconds ), if (settings.registerWwavesToken) d.ChainContract.enableTokenTransfersWithWaves( @@ -82,14 +84,15 @@ trait BaseTestSuite try { d = new ExtensionDomain( - rdb = new RDB(rdb.db, rdb.txMetaHandle, rdb.txHandle, rdb.txSnapshotHandle, rdb.apiHandle, Seq.empty), - blockchainUpdater = bcu, - rocksDBWriter = blockchain, - settings = settings.wavesSettings, - chainRegistryAccount = chainRegistryAccount, - nativeBridgeAddress = NativeBridgeAddress, - standardBridgeAddress = StandardBridgeAddress, - elMinerDefaultReward = ElMinerDefaultReward + new RDB(rdb.db, rdb.txMetaHandle, rdb.txHandle, rdb.txSnapshotHandle, rdb.apiHandle, Seq.empty), + bcu, + blockchain, + settings.wavesSettings, + chainRegistryAccount, + NativeBridgeAddress, + StandardBridgeAddress, + ElMinerDefaultReward, + defaultSettings.blockDelayInSeconds.seconds ) d.wallet.generateNewAccounts(2) // Enough for now diff --git a/src/test/scala/units/ClientConfigTestSuite.scala b/src/test/scala/units/ClientConfigTestSuite.scala index 339367b2..c6641c82 100644 --- a/src/test/scala/units/ClientConfigTestSuite.scala +++ b/src/test/scala/units/ClientConfigTestSuite.scala @@ -60,7 +60,6 @@ class ClientConfigTestSuite extends FlatSpec { | api-request-retries = 2 | api-request-retry-wait-time = 2s | - | block-delay = 6s | first-block-min-delay = 1s | block-sync-request-timeout = 500ms | @@ -82,7 +81,6 @@ class ClientConfigTestSuite extends FlatSpec { clientConfig.executionClientAddress shouldBe "http://ec-1:8551" clientConfig.apiRequestRetries shouldBe 2 clientConfig.apiRequestRetryWaitTime shouldBe 2.seconds - clientConfig.blockDelay shouldBe 6.seconds clientConfig.firstBlockMinDelay shouldBe 1.second clientConfig.blockSyncRequestTimeout shouldBe 500.millis clientConfig.miningEnable shouldBe true @@ -124,7 +122,6 @@ class ClientConfigTestSuite extends FlatSpec { clientConfig.executionClientAddress shouldBe "http://ec-1:8551" clientConfig.apiRequestRetries shouldBe 2 clientConfig.apiRequestRetryWaitTime shouldBe 2.seconds - clientConfig.blockDelay shouldBe 6.seconds clientConfig.blockSyncRequestTimeout shouldBe 500.millis clientConfig.miningEnable shouldBe true clientConfig.privateKeys shouldBe Seq.empty diff --git a/src/test/scala/units/ExtensionDomain.scala b/src/test/scala/units/ExtensionDomain.scala index dd667eab..1ace18e9 100644 --- a/src/test/scala/units/ExtensionDomain.scala +++ b/src/test/scala/units/ExtensionDomain.scala @@ -61,7 +61,8 @@ class ExtensionDomain( override val chainRegistryAccount: KeyPair, nativeBridgeAddress: EthAddress, standardBridgeAddress: EthAddress, - elMinerDefaultReward: Gwei + elMinerDefaultReward: Gwei, + blockDelay: FiniteDuration ) extends Domain(rdb, blockchainUpdater, rocksDBWriter, settings) with HasConsensusLayerDappTxHelpers with CustomMatchers @@ -77,7 +78,7 @@ class ExtensionDomain( parentHash = BlockHash(EthereumConstants.EmptyBlockHashHex), // see main.ride stateRoot = EthereumConstants.EmptyRootHashHex, height = 0, - timestamp = testTime.getTimestamp() / 1000 - l2Config.blockDelay.toSeconds, + timestamp = testTime.getTimestamp() / 1000 - blockDelay.toSeconds, minerRewardL2Address = EthAddress.empty, baseFeePerGas = Uint256.DEFAULT, gasLimit = 0, @@ -233,7 +234,7 @@ class ExtensionDomain( else { appendBlock() val generator = evaluatedComputedGenerator - if (generator == expectedElGenerator) testTime.advance(l2Config.blockDelay) + if (generator == expectedElGenerator) testTime.advance(blockDelay) else { log.debug(s"advanceNewBlocks: unexpected computed generator $generator") advanceNewBlocks(expectedElGenerator, attempts - 1) @@ -324,7 +325,7 @@ class ExtensionDomain( def advanceMiningRetry(): Unit = advanceElu(ELUpdater.MiningRetryInterval, "advanceMiningRetry") - def advanceMining(): Unit = advanceElu(l2Config.blockDelay, "advanceMining") + def advanceMining(): Unit = advanceElu(blockDelay, "advanceMining") def advanceElu(x: FiniteDuration, name: String = "advanceElu"): Unit = { log.trace(s"$name($x)") @@ -386,7 +387,7 @@ class ExtensionDomain( createEcBlockBuilder(hashPath, miner.elRewardAddress, parent) def createEcBlockBuilder(hashPath: String, minerRewardL2Address: EthAddress, parent: EcBlock): TestEcBlockBuilder = { - TestEcBlockBuilder(hashPath, ecClients, nativeBridgeAddress, standardBridgeAddress, elMinerDefaultReward, l2Config.blockDelay, parent = parent) + TestEcBlockBuilder(hashPath, ecClients, nativeBridgeAddress, standardBridgeAddress, elMinerDefaultReward, blockDelay, parent = parent) .updateBlock( _.copy( minerRewardL2Address = minerRewardL2Address, diff --git a/src/test/scala/units/RegistryTestSuite.scala b/src/test/scala/units/RegistryTestSuite.scala index cae5c54a..7e6d2504 100644 --- a/src/test/scala/units/RegistryTestSuite.scala +++ b/src/test/scala/units/RegistryTestSuite.scala @@ -48,7 +48,8 @@ class RegistryTestSuite extends BaseTestSuite { d.ecGenesisBlock, ElMinerDefaultReward.amount.longValue(), defaultSettings.daoRewardAccount.map(_.toAddress), - defaultSettings.daoRewardAmount + defaultSettings.daoRewardAmount, + defaultSettings.blockDelayInSeconds ) ) ++ settings.initialMiners.map { x => d.ChainContract.join(x.account, x.elRewardAddress) } diff --git a/src/test/scala/units/TestSettings.scala b/src/test/scala/units/TestSettings.scala index 82e8eafb..97b6cd65 100644 --- a/src/test/scala/units/TestSettings.scala +++ b/src/test/scala/units/TestSettings.scala @@ -15,6 +15,7 @@ case class TestSettings( additionalBalances: List[AddrWithBalance] = Nil, daoRewardAccount: Option[KeyPair] = None, daoRewardAmount: Long = 0, + blockDelayInSeconds: Int = 2, enableTokenTransfersEpoch: Int = 0, registerWwavesToken: Boolean = false // Almost never needed in unit tests, see TestEcClients, simulate ) { diff --git a/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala b/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala index 9da1d2d8..145508bb 100644 --- a/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala +++ b/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala @@ -57,7 +57,8 @@ trait HasConsensusLayerDappTxHelpers { elMinerReward: Long, daoAddress: Option[Address], daoReward: Long, - invoker: KeyPair = chainContractAccount + blockDelayInSeconds: Int, + invoker: KeyPair = chainContractAccount, ): InvokeScriptTransaction = TxHelpers.invoke( dApp = chainContractAddress, func = "setup".some, @@ -65,7 +66,8 @@ trait HasConsensusLayerDappTxHelpers { Terms.CONST_STRING(genesisBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_LONG(elMinerReward), Terms.CONST_STRING(daoAddress.fold("")(_.toString)).explicitGet(), - Terms.CONST_LONG(daoReward) + Terms.CONST_LONG(daoReward), + Terms.CONST_LONG(blockDelayInSeconds) ), fee = setupFee, invoker = invoker From ddaa4ee36ae69cfa49265e68eff9bee5fcbb1e45 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Sat, 1 Nov 2025 10:21:07 +0300 Subject: [PATCH 02/31] wip --- src/main/resources/application.conf | 6 ++---- .../scala/units/client/contract/ChainContractClient.scala | 4 ++-- .../scala/units/client/contract/ChainContractOptions.scala | 2 +- src/test/resources/application.conf | 1 - src/test/scala/units/ClientConfigTestSuite.scala | 1 - 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 1c96116a..5b3d941a 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -3,12 +3,10 @@ units { api-request-retries = 2 api-request-retry-wait-time = 2s - block-delay = 6s - # A minimal delay for a first block in a new epoch. # If a previous block was more than block-delay ago, we'd better wait some time to collect transactions instead of producing it immediately. - # We choose 2s, because it enough for collecting 100 transactions on machine with 4 Gb RAM and 2 GHz processor with 2 cores. - first-block-min-delay = 2s + # We choose 1s, because it enough for collecting 50 transactions on machine with 4 Gb RAM and 2 GHz processor with 2 cores. + first-block-min-delay = 1s block-sync-request-timeout = 500ms diff --git a/src/main/scala/units/client/contract/ChainContractClient.scala b/src/main/scala/units/client/contract/ChainContractClient.scala index c32736c7..1d8e1aa7 100644 --- a/src/main/scala/units/client/contract/ChainContractClient.scala +++ b/src/main/scala/units/client/contract/ChainContractClient.scala @@ -221,7 +221,7 @@ trait ChainContractClient { ValueAtEpoch(Gwei.ofRawGwei(oldReward.toLong), Gwei.ofRawGwei(newReward.toLong), changeEpoch.toInt) case _ => throw new IllegalStateException("minerReward is empty on contract") } - + val blockDelay = extractData("blockDelay") match { case Some(IntegerDataEntry(value = delay)) => ValueAtEpoch(0, BigInt(delay).bigInteger.intValueExact(), 1) case Some(StringDataEntry(value = delays)) => @@ -229,7 +229,7 @@ trait ChainContractClient { ValueAtEpoch(oldDelay.toInt, newDelay.toInt, changeEpoch.toInt) case _ => throw new IllegalStateException("blockDelay is empty on contract") } - + ChainContractOptions( minerReward, getStringData("elBridgeAddress") diff --git a/src/main/scala/units/client/contract/ChainContractOptions.scala b/src/main/scala/units/client/contract/ChainContractOptions.scala index c2419eab..62b99d85 100644 --- a/src/main/scala/units/client/contract/ChainContractOptions.scala +++ b/src/main/scala/units/client/contract/ChainContractOptions.scala @@ -36,4 +36,4 @@ case class ChainContractOptions( case class ValueAtEpoch[A](oldValue: A, newValue: A, changeAtEpoch: Int) { def valueAtEpoch(epoch: Int): A = if epoch < changeAtEpoch then oldValue else newValue -} \ No newline at end of file +} diff --git a/src/test/resources/application.conf b/src/test/resources/application.conf index 7bb1c414..d19b4836 100644 --- a/src/test/resources/application.conf +++ b/src/test/resources/application.conf @@ -10,7 +10,6 @@ units { api-request-retries = 2 api-request-retry-wait-time = 2s - block-delay = 6s block-sync-request-timeout = 500ms mining-enable = false diff --git a/src/test/scala/units/ClientConfigTestSuite.scala b/src/test/scala/units/ClientConfigTestSuite.scala index c6641c82..902900c9 100644 --- a/src/test/scala/units/ClientConfigTestSuite.scala +++ b/src/test/scala/units/ClientConfigTestSuite.scala @@ -100,7 +100,6 @@ class ClientConfigTestSuite extends FlatSpec { | api-request-retries = 2 | api-request-retry-wait-time = 2s | - | block-delay = 6s | first-block-min-delay = 1s | block-sync-request-timeout = 500ms | From 0dcfdd1e2768aed53b1f5ad19b2dad3c13e8d20c Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Sat, 1 Nov 2025 12:39:15 +0300 Subject: [PATCH 03/31] wip --- .../AssetInvalidAmountTestSuite.scala} | 6 +++--- .../AssetInvalidBridgeTestSuite.scala} | 6 +++--- .../AssetInvalidRecipientTestSuite.scala} | 6 +++--- .../AssetInvalidSenderTestSuite.scala} | 6 +++--- .../AssetInvalidTokenTestSuite.scala} | 6 +++--- .../validation/AssetValidTestSuite.scala} | 6 +++--- .../validation}/BaseBlockValidationSuite.scala | 4 ++-- .../NativeInvalidAmountTestSuite.scala} | 6 +++--- .../NativeInvalidBridgeTestSuite.scala} | 6 +++--- .../NativeInvalidRecipientTestSuite.scala} | 6 +++--- .../NativeInvalidSenderTestSuite.scala} | 6 +++--- .../NativeMissingDepositTestSuite.scala} | 6 +++--- .../NativeUnexpectedDepositTestSuite.scala} | 6 +++--- .../NativeUnexpectedWithdrawalTestSuite.scala} | 6 +++--- .../validation/NativeValidTestSuite.scala} | 6 +++--- .../validation/NoTransfersTestSuite.scala} | 6 +++--- src/main/scala/units/ELUpdater.scala | 4 ++-- src/main/scala/units/eth/EthAddress.scala | 18 +++++++----------- .../HasConsensusLayerDappTxHelpers.scala | 4 ++++ 19 files changed, 60 insertions(+), 60 deletions(-) rename consensus-client-it/src/test/scala/units/{BlockValidationAssetInvalidAmountTestSuite.scala => block/validation/AssetInvalidAmountTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationAssetInvalidBridgeTestSuite.scala => block/validation/AssetInvalidBridgeTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationAssetInvalidRecipientTestSuite.scala => block/validation/AssetInvalidRecipientTestSuite.scala} (96%) rename consensus-client-it/src/test/scala/units/{BlockValidationAssetInvalidSenderTestSuite.scala => block/validation/AssetInvalidSenderTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationAssetInvalidTokenTestSuite.scala => block/validation/AssetInvalidTokenTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationAssetValidTestSuite.scala => block/validation/AssetValidTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{ => block/validation}/BaseBlockValidationSuite.scala (99%) rename consensus-client-it/src/test/scala/units/{BlockValidationNativeInvalidAmountTestSuite.scala => block/validation/NativeInvalidAmountTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationNativeInvalidBridgeTestSuite.scala => block/validation/NativeInvalidBridgeTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationNativeInvalidRecipientTestSuite.scala => block/validation/NativeInvalidRecipientTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationNativeInvalidSenderTestSuite.scala => block/validation/NativeInvalidSenderTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationNativeMissingDepositTestSuite.scala => block/validation/NativeMissingDepositTestSuite.scala} (94%) rename consensus-client-it/src/test/scala/units/{BlockValidationNativeUnexpectedDepositTestSuite.scala => block/validation/NativeUnexpectedDepositTestSuite.scala} (94%) rename consensus-client-it/src/test/scala/units/{BlockValidationNativeUnexpectedWithdrawalTestSuite.scala => block/validation/NativeUnexpectedWithdrawalTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationNativeValidTestSuite.scala => block/validation/NativeValidTestSuite.scala} (95%) rename consensus-client-it/src/test/scala/units/{BlockValidationNoTransfersTestSuite.scala => block/validation/NoTransfersTestSuite.scala} (93%) diff --git a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidAmountTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala index c083df0c..7e32f238 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -10,9 +10,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.{BlockHash, TestNetworkClient} +import units.* -class BlockValidationAssetInvalidAmountTestSuite extends BaseBlockValidationSuite { +class AssetInvalidAmountTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid amount" in { val balanceBefore = terc20.getBalance(elRecipient) val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidBridgeTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala index cb04cfbd..38a54b84 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -10,9 +10,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.{BlockHash, TestNetworkClient} +import units.* -class BlockValidationAssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { +class AssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid standardBridgeAddress" in { val balanceBefore = terc20.getBalance(elRecipient) val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala similarity index 96% rename from consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidRecipientTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala index e47525e1..9f4c74d0 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -6,13 +6,13 @@ import com.wavesplatform.common.utils.EitherExt2.explicitGet import com.wavesplatform.lang.v1.compiler.Terms import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.smart.InvokeScriptTransaction -import units.BlockHash import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress +import units.* -class BlockValidationAssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { +class AssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid recipient address" in { val balanceBefore = terc20.getBalance(elRecipient) val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidSenderTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala index be99b86e..1d8fbb0a 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.account.* import com.wavesplatform.common.utils.EitherExt2.explicitGet @@ -8,9 +8,9 @@ import com.wavesplatform.transaction.smart.InvokeScriptTransaction import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex import units.client.engine.model.EcBlock import units.el.* -import units.{BlockHash, TestNetworkClient} +import units.* -class BlockValidationAssetInvalidSenderTestSuite extends BaseBlockValidationSuite { +class AssetInvalidSenderTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid sender address" in { val balanceBefore = terc20.getBalance(elRecipient) val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidTokenTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidTokenTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala index 09165d46..26801555 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationAssetInvalidTokenTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -10,9 +10,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.{BlockHash, TestNetworkClient} +import units.* -class BlockValidationAssetInvalidTokenTestSuite extends BaseBlockValidationSuite { +class AssetInvalidTokenTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid token address" in { val balanceBefore = terc20.getBalance(elRecipient) val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationAssetValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationAssetValidTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala index c2a0de3f..7e24d17c 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationAssetValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -10,9 +10,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.{BlockHash, TestNetworkClient} +import units.* -class BlockValidationAssetValidTestSuite extends BaseBlockValidationSuite { +class AssetValidTestSuite extends BaseBlockValidationSuite { "Valid block: asset token, correct transfer" in { val balanceBefore = terc20.getBalance(elRecipient) val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala similarity index 99% rename from consensus-client-it/src/test/scala/units/BaseBlockValidationSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala index 5b127b72..9413974e 100644 --- a/consensus-client-it/src/test/scala/units/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -14,12 +14,12 @@ import org.web3j.protocol.core.DefaultBlockParameterName import org.web3j.tx.RawTransactionManager import org.web3j.tx.gas.DefaultGasProvider import play.api.libs.json.* -import units.{BlockHash, ELUpdater} import units.client.engine.model.{EcBlock, Withdrawal} import units.docker.EcContainer import units.el.* import units.eth.{EmptyL2Block, EthAddress, EthereumConstants} import units.util.{BlockToPayloadMapper, HexBytesConverter} +import units.{BaseDockerTestSuite, BlockHash, ELUpdater, UnitsConvert} import scala.concurrent.duration.DurationInt import scala.jdk.OptionConverters.RichOptional diff --git a/consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidAmountTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala index fd36ab99..d253d045 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -11,9 +11,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.{BlockHash, TestNetworkClient} +import units.{BlockHash, NetworkL2Block, TestNetworkClient} -class BlockValidationNativeInvalidAmountTestSuite extends BaseBlockValidationSuite { +class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, invalid amount" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidBridgeTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala index b480dd28..9a715a32 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -11,9 +11,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.{BlockHash, TestNetworkClient} +import units.{BlockHash, NetworkL2Block, TestNetworkClient} -class BlockValidationNativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { +class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, invalid standard bridge address" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidRecipientTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala index 2c9052fc..65e03f9e 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -11,9 +11,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.{BlockHash, TestNetworkClient} +import units.{BlockHash, NetworkL2Block, TestNetworkClient} -class BlockValidationNativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { +class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, invalid recipient" in { val invalidRecipient = additionalMiner1RewardAddress diff --git a/consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidSenderTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala index 89221ea6..759b35ab 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationNativeInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.account.* import com.wavesplatform.common.utils.EitherExt2.explicitGet @@ -9,9 +9,9 @@ import org.web3j.protocol.core.DefaultBlockParameterName import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex import units.client.engine.model.EcBlock import units.el.* -import units.{BlockHash, TestNetworkClient} +import units.{BlockHash, NetworkL2Block, TestNetworkClient} -class BlockValidationNativeInvalidSenderTestSuite extends BaseBlockValidationSuite { +class NativeInvalidSenderTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, invalid sender" in { val invalidSender = additionalMiner1RewardAddress diff --git a/consensus-client-it/src/test/scala/units/BlockValidationNativeMissingDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala similarity index 94% rename from consensus-client-it/src/test/scala/units/BlockValidationNativeMissingDepositTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala index c1c88d59..b3b162fe 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationNativeMissingDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.account.* import com.wavesplatform.common.utils.EitherExt2.explicitGet @@ -8,9 +8,9 @@ import com.wavesplatform.transaction.smart.InvokeScriptTransaction import org.web3j.protocol.core.DefaultBlockParameterName import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex import units.client.engine.model.EcBlock -import units.{BlockHash, TestNetworkClient} +import units.{BlockHash, NetworkL2Block, TestNetworkClient} -class BlockValidationNativeMissingDepositTestSuite extends BaseBlockValidationSuite { +class NativeMissingDepositTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, missing deposited transaction" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationNativeUnexpectedDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala similarity index 94% rename from consensus-client-it/src/test/scala/units/BlockValidationNativeUnexpectedDepositTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala index cdcadd04..9b6c0382 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationNativeUnexpectedDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -11,9 +11,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.{BlockHash, TestNetworkClient} +import units.{BlockHash, NetworkL2Block, TestNetworkClient} -class BlockValidationNativeUnexpectedDepositTestSuite extends BaseBlockValidationSuite { +class NativeUnexpectedDepositTestSuite extends BaseBlockValidationSuite { "Invalid block: unexpected deposited transaction" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationNativeUnexpectedWithdrawalTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationNativeUnexpectedWithdrawalTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala index 07217b5f..16fcf2b9 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationNativeUnexpectedWithdrawalTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -11,9 +11,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.{EcBlock, Withdrawal} import units.el.* import units.eth.{EthAddress, Gwei} -import units.{BlockHash, TestNetworkClient} +import units.{BlockHash, NetworkL2Block, TestNetworkClient} -class BlockValidationNativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { +class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, unexpected extra withdrawal" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationNativeValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala similarity index 95% rename from consensus-client-it/src/test/scala/units/BlockValidationNativeValidTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala index a89556ab..11614b03 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationNativeValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.* import com.wavesplatform.account.* @@ -11,9 +11,9 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRoo import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.{BlockHash, TestNetworkClient} +import units.{BlockHash, NetworkL2Block, TestNetworkClient} -class BlockValidationNativeValidTestSuite extends BaseBlockValidationSuite { +class NativeValidTestSuite extends BaseBlockValidationSuite { "Valid block: native token, correct transfer" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/consensus-client-it/src/test/scala/units/BlockValidationNoTransfersTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala similarity index 93% rename from consensus-client-it/src/test/scala/units/BlockValidationNoTransfersTestSuite.scala rename to consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala index 676fe31a..4f355200 100644 --- a/consensus-client-it/src/test/scala/units/BlockValidationNoTransfersTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala @@ -1,4 +1,4 @@ -package units +package units.block.validation import com.wavesplatform.account.* import com.wavesplatform.common.utils.EitherExt2.explicitGet @@ -7,9 +7,9 @@ import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.smart.InvokeScriptTransaction import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex import units.client.engine.model.EcBlock -import units.{BlockHash, TestNetworkClient} +import units.{BlockHash, NetworkL2Block, TestNetworkClient} -class BlockValidationNoTransfersTestSuite extends BaseBlockValidationSuite { +class NoTransfersTestSuite extends BaseBlockValidationSuite { "Valid block: no transfers" in { val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() diff --git a/src/main/scala/units/ELUpdater.scala b/src/main/scala/units/ELUpdater.scala index c40762f3..c32bdf5a 100644 --- a/src/main/scala/units/ELUpdater.scala +++ b/src/main/scala/units/ELUpdater.scala @@ -1088,7 +1088,7 @@ class ELUpdater( processInvalidBlock(contractBlock, prevState, Some(nodeChainInfo)) } case contractBlock => - (if (contractBlock.isEmpty) validateBlockSignature(networkBlock, prevState.epochInfo) else ().asRight[ClientError]) + (if (contractBlock.isEmpty) validateBlockSignature(networkBlock, prevState.epochInfo) else ().asRight[String]) .flatMap(_ => applyBlock(networkBlock, parentBlock, prevState.epochInfo)) match { case Right(_) => logger.debug(s"Block ${networkBlock.hash} successfully applied") @@ -1857,7 +1857,7 @@ object ELUpdater { ) expectedAmount = WAmount(expectedTransfer.amount).scale(NativeTokenElDecimals - NativeTokenClDecimals) _ <- Either.raiseUnless(elTransferEvent.amount == expectedAmount)( - s"$errorPrefix: got amount: ${elTransferEvent.amount}, expected ${expectedAmount}" + s"$errorPrefix: got amount: ${elTransferEvent.amount}, expected $expectedAmount" ) } yield () } diff --git a/src/main/scala/units/eth/EthAddress.scala b/src/main/scala/units/eth/EthAddress.scala index 6b7316b2..15d48683 100644 --- a/src/main/scala/units/eth/EthAddress.scala +++ b/src/main/scala/units/eth/EthAddress.scala @@ -3,16 +3,7 @@ package units.eth import play.api.libs.json.* import units.util.HexBytesConverter -class EthAddress private (val hex: String) { - def hexNoPrefix: String = hex.drop(2) - - override def hashCode(): Int = hex.hashCode() - override def equals(that: Any): Boolean = that match { - case that: EthAddress => this.hex == that.hex - case _ => false - } - override def toString: String = hex -} +opaque type EthAddress = String object EthAddress { val AddressHexLength = 40 @@ -21,7 +12,12 @@ object EthAddress { val EmptyHex = "0x" + "0" * EthAddress.AddressHexLength val empty = unsafeFrom(EmptyHex) - implicit val ethAddressFormat: Format[EthAddress] = implicitly[Format[String]].bimap(unsafeFrom, _.hex) + extension (a: EthAddress) { + def hex: String = a + def hexNoPrefix: String = a.drop(2) + } + + given Format[EthAddress] = implicitly[Format[String]] def from(hex: String): Either[String, EthAddress] = { for { diff --git a/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala b/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala index 145508bb..9b0feb82 100644 --- a/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala +++ b/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala @@ -18,6 +18,8 @@ import units.client.contract.HasConsensusLayerDappTxHelpers.DefaultFees.ChainCon import units.eth.{EthAddress, EthereumConstants} import units.{BlockHash, ELUpdater} +import scala.annotation.targetName + trait HasConsensusLayerDappTxHelpers { def currentHitSource: ByteStr @@ -122,6 +124,7 @@ trait HasConsensusLayerDappTxHelpers { ): InvokeScriptTransaction = registerAsset(asset, erc20Address.hexNoPrefix, elDecimals, invoker) + @targetName("registerAssetHexString") def registerAsset(asset: IssuedAsset, erc20AddressHex: String, elDecimals: Int, invoker: KeyPair): InvokeScriptTransaction = registerAssets(List(asset), List(erc20AddressHex), List(elDecimals), invoker) @@ -162,6 +165,7 @@ trait HasConsensusLayerDappTxHelpers { invoker: KeyPair = chainContractAccount ): InvokeScriptTransaction = issueAndRegister(erc20Address.hexNoPrefix, elDecimals, name, description, clDecimals, invoker) + @targetName("issueAndRegisterHexString") def issueAndRegister( erc20AddressHex: String, elDecimals: Int, From 0dfb97b037591ab67824ffd2128094af438bc99a Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Wed, 5 Nov 2025 11:57:58 +0300 Subject: [PATCH 04/31] wip --- .github/workflows/check-pr.yml | 1 + consensus-client-it/build.sbt | 2 +- .../validation/AssetValidTestSuite.scala | 6 ++- .../validation/BaseBlockValidationSuite.scala | 39 +++---------------- 4 files changed, 13 insertions(+), 35 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 09a4fbbe..d1144f4f 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -56,6 +56,7 @@ jobs: sbt --no-colors --color=never --batch "scalafmtCheck;test;docker;consensus-client-it/test" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} + MAX_PARALLEL_SUITES: 4 - uses: scacap/action-surefire-report@5609ce4db72c09db044803b344a8968fd1f315da if: always() with: diff --git a/consensus-client-it/build.sbt b/consensus-client-it/build.sbt index c8bdfbd4..57fab9c2 100644 --- a/consensus-client-it/build.sbt +++ b/consensus-client-it/build.sbt @@ -58,7 +58,7 @@ Test / sourceGenerators += Def.task { val logsDirectory = taskKey[File]("The directory for logs") // Task to evaluate and recreate the logs directory every time Global / concurrentRestrictions := { - val threadNumber = Option(System.getenv("SBT_IT_TEST_THREADS")).fold(1)(_.toInt) + val threadNumber = Option(System.getenv("MAX_PARALLEL_SUITES")).fold(1)(_.toInt) Seq(Tags.limit(Tags.ForkedTestGroup, threadNumber)) } diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala index 7e24d17c..ee799795 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala @@ -4,6 +4,7 @@ import com.wavesplatform.* import com.wavesplatform.account.* import com.wavesplatform.common.utils.EitherExt2.explicitGet import com.wavesplatform.lang.v1.compiler.Terms +import com.wavesplatform.state.StringDataEntry import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.smart.InvokeScriptTransaction import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex @@ -15,7 +16,10 @@ import units.* class AssetValidTestSuite extends BaseBlockValidationSuite { "Valid block: asset token, correct transfer" in { val balanceBefore = terc20.getBalance(elRecipient) - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlockId = waves1.api.dataByKey(chainContractAddress, "chain_00000000").collect { + case s: StringDataEntry => BlockHash("0x" + s.value.split(",")(1)) + }.get + val elParentBlock: EcBlock = ec1.engineApi.getBlockByHash(elParentBlockId).explicitGet().get val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala index 9413974e..eefa5353 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala @@ -26,14 +26,12 @@ import scala.jdk.OptionConverters.RichOptional trait BaseBlockValidationSuite extends BaseDockerTestSuite { protected val setupMiner: SeedKeyPair = miner11Account // Leaves after setting up the contracts - protected val actingMiner: SeedKeyPair = miner12Account - protected val actingMinerRewardAddress: EthAddress = miner12RewardAddress + protected val actingMiner: SeedKeyPair = miner21Account + protected val actingMinerRewardAddress: EthAddress = miner21RewardAddress // Note: additional miners are needed to avoid the actingMiner having majority of the stake - protected val additionalMiner1: SeedKeyPair = miner21Account - protected val additionalMiner1RewardAddress: EthAddress = miner21RewardAddress - protected val additionalMiner2: SeedKeyPair = miner31Account - protected val additionalMiner2RewardAddress: EthAddress = miner31RewardAddress + protected val additionalMiner1: SeedKeyPair = miner12Account + protected val additionalMiner1RewardAddress: EthAddress = miner12RewardAddress // transfers protected val clSender: SeedKeyPair = clRichAccount1 @@ -215,40 +213,15 @@ trait BaseBlockValidationSuite extends BaseDockerTestSuite { log.debug(s"setupMiner: ${setupMiner.toAddress}") log.debug(s"actingMiner: ${actingMiner.toAddress}") log.debug(s"additionalMiner1: ${additionalMiner1.toAddress}") - log.debug(s"additionalMiner2: ${additionalMiner2.toAddress}") - step(s"additionalMiner1 join") - waves1.api.broadcastAndWait( - ChainContract.join( - minerAccount = additionalMiner1, - elRewardAddress = additionalMiner1RewardAddress - ) - ) - - step(s"Wait additionalMiner1 epoch") - chainContract.waitForMinerEpoch(additionalMiner1) + waves1.api.broadcastAndWait(ChainContract.join(additionalMiner1, additionalMiner1RewardAddress)) + waves1.api.broadcastAndWait(ChainContract.join(actingMiner, actingMinerRewardAddress)) step(s"setupMiner leave") eventually(interval(500 millis)) { waves1.api.broadcastAndWait(ChainContract.leave(setupMiner)) } - step(s"additionalMiner2 join") - waves1.api.broadcastAndWait( - ChainContract.join( - minerAccount = additionalMiner2, - elRewardAddress = additionalMiner2RewardAddress - ) - ) - - step(s"actingMiner join") - waves1.api.broadcastAndWait( - ChainContract.join( - minerAccount = actingMiner, - elRewardAddress = actingMinerRewardAddress - ) - ) - step(s"Wait actingMiner epoch") chainContract.waitForMinerEpoch(actingMiner) } From 6a837f6041ef851cbe868078b11d78448ced5609 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Wed, 5 Nov 2025 12:17:13 +0300 Subject: [PATCH 05/31] wip --- .github/workflows/check-pr.yml | 2 +- .sbtopts | 2 +- consensus-client-it/build.sbt | 29 ++++++++++++++++++++++++----- project/plugins.sbt | 5 +++-- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index d1144f4f..0d418880 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -53,7 +53,7 @@ jobs: - name: Run tests run: | forge --version - sbt --no-colors --color=never --batch "scalafmtCheck;test;docker;consensus-client-it/test" + sbt -Dcc.it.max-parallel-suites=4 --batch "scalafmtCheck;test;docker;consensus-client-it/test" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} MAX_PARALLEL_SUITES: 4 diff --git a/.sbtopts b/.sbtopts index 2a21302f..ccf701eb 100644 --- a/.sbtopts +++ b/.sbtopts @@ -1 +1 @@ --mem 2048 +--mem 2048 diff --git a/consensus-client-it/build.sbt b/consensus-client-it/build.sbt index 57fab9c2..a4a80d70 100644 --- a/consensus-client-it/build.sbt +++ b/consensus-client-it/build.sbt @@ -1,4 +1,5 @@ import com.github.sbt.git.SbtGit.git.gitCurrentBranch +import com.spotify.docker.client.DefaultDockerClient import org.web3j.codegen.SolidityFunctionWrapperGenerator import org.web3j.tx.Contract import play.api.libs.json.Json @@ -8,11 +9,12 @@ import java.io.FileInputStream import java.time.LocalDateTime import java.time.format.DateTimeFormatter import scala.sys.process.* +import scala.util.control.NonFatal description := "Consensus client integration tests" libraryDependencies ++= Seq( - "org.testcontainers" % "testcontainers" % "1.20.4", + "org.testcontainers" % "testcontainers" % "2.0.1", "org.web3j" % "core" % "4.9.8" ).map(_ % Test) @@ -57,10 +59,27 @@ Test / sourceGenerators += Def.task { val logsDirectory = taskKey[File]("The directory for logs") // Task to evaluate and recreate the logs directory every time -Global / concurrentRestrictions := { - val threadNumber = Option(System.getenv("MAX_PARALLEL_SUITES")).fold(1)(_.toInt) - Seq(Tags.limit(Tags.ForkedTestGroup, threadNumber)) -} +Global / concurrentRestrictions := Seq( + Tags.limit( + Tags.ForkedTestGroup, + Option(Integer.getInteger("cc.it.max-parallel-suites")) + .getOrElse[Integer] { + try { + val docker = DefaultDockerClient.fromEnv().build() + try { + val dockerCpu: Int = docker.info().cpus() + sLog.value.info(s"Docker CPU count: $dockerCpu") + dockerCpu * 2 + } finally docker.close() + } catch { + case NonFatal(_) => + sLog.value.warn(s"Could not connect to Docker, is the daemon running?") + sLog.value.info(s"System CPU count: ${EvaluateTask.SystemProcessors}") + EvaluateTask.SystemProcessors + } + } + ) +) inConfig(Test)( Seq( diff --git a/project/plugins.sbt b/project/plugins.sbt index 657f5b1a..cca14156 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,8 +4,9 @@ resolvers ++= Seq( ) libraryDependencies ++= Seq( - "org.web3j" % "codegen" % "4.9.8", - "com.typesafe.play" %% "play-json" % "2.10.6" + "org.web3j" % "codegen" % "4.9.8", + "com.typesafe.play" %% "play-json" % "2.10.8", + "com.spotify" % "docker-client" % "8.16.0" ) Seq( From f8c7b30179a96d14b89b159e026859353b6a556c Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Wed, 5 Nov 2025 12:52:17 +0300 Subject: [PATCH 06/31] wip --- .github/workflows/check-pr.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 0d418880..ce62e098 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -17,7 +17,6 @@ jobs: env: JAVA_OPTS: -Dfile.encoding=UTF-8 BRANCH_NAME: ${{ github.head_ref || github.ref_name }} - SBT_IT_TEST_THREADS: 2 services: docker: image: docker:latest @@ -53,10 +52,9 @@ jobs: - name: Run tests run: | forge --version - sbt -Dcc.it.max-parallel-suites=4 --batch "scalafmtCheck;test;docker;consensus-client-it/test" + sbt -Dcc.it.max-parallel-suites=2 --batch "scalafmtCheck;test;docker;consensus-client-it/test" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} - MAX_PARALLEL_SUITES: 4 - uses: scacap/action-surefire-report@5609ce4db72c09db044803b344a8968fd1f315da if: always() with: From 3da05e47dcad23ad63bd715c9a269ff51ac47deb Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Wed, 5 Nov 2025 14:51:58 +0300 Subject: [PATCH 07/31] wip --- .../validation/AssetInvalidAmountTestSuite.scala | 2 +- .../validation/AssetInvalidBridgeTestSuite.scala | 2 +- .../validation/AssetInvalidRecipientTestSuite.scala | 2 +- .../validation/AssetInvalidSenderTestSuite.scala | 2 +- .../block/validation/AssetInvalidTokenTestSuite.scala | 2 +- .../units/block/validation/AssetValidTestSuite.scala | 7 ++----- .../block/validation/BaseBlockValidationSuite.scala | 11 ++++++++++- .../validation/NativeInvalidAmountTestSuite.scala | 2 +- .../validation/NativeInvalidBridgeTestSuite.scala | 2 +- .../validation/NativeInvalidRecipientTestSuite.scala | 2 +- .../validation/NativeInvalidSenderTestSuite.scala | 2 +- .../validation/NativeMissingDepositTestSuite.scala | 2 +- .../validation/NativeUnexpectedDepositTestSuite.scala | 2 +- .../NativeUnexpectedWithdrawalTestSuite.scala | 2 +- .../units/block/validation/NativeValidTestSuite.scala | 2 +- .../units/block/validation/NoTransfersTestSuite.scala | 2 +- 16 files changed, 26 insertions(+), 20 deletions(-) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala index 7e32f238..107cda99 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala @@ -15,7 +15,7 @@ import units.* class AssetInvalidAmountTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid amount" in { val balanceBefore = terc20.getBalance(elRecipient) - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala index 38a54b84..5599c4a0 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala @@ -15,7 +15,7 @@ import units.* class AssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid standardBridgeAddress" in { val balanceBefore = terc20.getBalance(elRecipient) - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala index 9f4c74d0..cee09e3b 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala @@ -15,7 +15,7 @@ import units.* class AssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid recipient address" in { val balanceBefore = terc20.getBalance(elRecipient) - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala index 1d8fbb0a..134a3d75 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala @@ -13,7 +13,7 @@ import units.* class AssetInvalidSenderTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid sender address" in { val balanceBefore = terc20.getBalance(elRecipient) - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala index 26801555..a39a81e8 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala @@ -15,7 +15,7 @@ import units.* class AssetInvalidTokenTestSuite extends BaseBlockValidationSuite { "Invalid block: asset token, invalid token address" in { val balanceBefore = terc20.getBalance(elRecipient) - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala index ee799795..a159fdc6 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala @@ -7,19 +7,16 @@ import com.wavesplatform.lang.v1.compiler.Terms import com.wavesplatform.state.StringDataEntry import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.smart.InvokeScriptTransaction +import units.* import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress -import units.* class AssetValidTestSuite extends BaseBlockValidationSuite { "Valid block: asset token, correct transfer" in { val balanceBefore = terc20.getBalance(elRecipient) - val elParentBlockId = waves1.api.dataByKey(chainContractAddress, "chain_00000000").collect { - case s: StringDataEntry => BlockHash("0x" + s.value.split(",")(1)) - }.get - val elParentBlock: EcBlock = ec1.engineApi.getBlockByHash(elParentBlockId).explicitGet().get + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala index eefa5353..57747f51 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala @@ -5,7 +5,7 @@ import com.wavesplatform.account.* import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2.explicitGet import com.wavesplatform.crypto.Keccak256 -import com.wavesplatform.state.{Height, IntegerDataEntry} +import com.wavesplatform.state.{Height, IntegerDataEntry, StringDataEntry} import com.wavesplatform.transaction.Asset.IssuedAsset import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.{Asset, TxHelpers} @@ -239,4 +239,13 @@ trait BaseBlockValidationSuite extends BaseDockerTestSuite { transferAssetTokenToClSender() leaveSetupMinerAndJoinOthers() } + + protected def getMainChainLastBlock: EcBlock = { + val mainChainId = waves1.api.dataByKey(chainContractAddress, "mainChainId").collect { case i: IntegerDataEntry => i.value }.get + val elParentBlockId = waves1.api.dataByKey(chainContractAddress, f"chain_$mainChainId%08d").collect { + case s: StringDataEntry => BlockHash("0x" + s.value.split(",")(1)) + }.get + + ec1.engineApi.getBlockByHash(elParentBlockId).explicitGet().get + } } diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala index d253d045..723f84c2 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala @@ -16,7 +16,7 @@ import units.{BlockHash, NetworkL2Block, TestNetworkClient} class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, invalid amount" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala index 9a715a32..0ce3ef67 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala @@ -16,7 +16,7 @@ import units.{BlockHash, NetworkL2Block, TestNetworkClient} class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, invalid standard bridge address" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala index 65e03f9e..81973c47 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala @@ -18,7 +18,7 @@ class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { val invalidRecipient = additionalMiner1RewardAddress val ethBalanceBefore = ec1.web3j.ethGetBalance(invalidRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala index 759b35ab..e6e5bc04 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala @@ -16,7 +16,7 @@ class NativeInvalidSenderTestSuite extends BaseBlockValidationSuite { val invalidSender = additionalMiner1RewardAddress val ethBalanceBefore = ec1.web3j.ethGetBalance(invalidSender.toString, DefaultBlockParameterName.LATEST).send().getBalance - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala index b3b162fe..7683d3d4 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala @@ -13,7 +13,7 @@ import units.{BlockHash, NetworkL2Block, TestNetworkClient} class NativeMissingDepositTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, missing deposited transaction" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala index 9b6c0382..ded1d28e 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala @@ -16,7 +16,7 @@ import units.{BlockHash, NetworkL2Block, TestNetworkClient} class NativeUnexpectedDepositTestSuite extends BaseBlockValidationSuite { "Invalid block: unexpected deposited transaction" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala index 16fcf2b9..bda07b3d 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala @@ -16,7 +16,7 @@ import units.{BlockHash, NetworkL2Block, TestNetworkClient} class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { "Invalid block: native token, unexpected extra withdrawal" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val rewardWithdrawal = mkRewardWithdrawal(elParentBlock) val unexpectedWithdrawal = Withdrawal(rewardWithdrawal.index + 1, elRecipient, Gwei.ofRawGwei(3_000_000_000L)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala index 11614b03..ed1030d0 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala @@ -16,7 +16,7 @@ import units.{BlockHash, NetworkL2Block, TestNetworkClient} class NativeValidTestSuite extends BaseBlockValidationSuite { "Valid block: native token, correct transfer" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala index 4f355200..740374de 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala @@ -11,7 +11,7 @@ import units.{BlockHash, NetworkL2Block, TestNetworkClient} class NoTransfersTestSuite extends BaseBlockValidationSuite { "Valid block: no transfers" in { - val elParentBlock: EcBlock = ec1.engineApi.getLastExecutionBlock().explicitGet() + val elParentBlock: EcBlock = getMainChainLastBlock val withdrawals = Vector(mkRewardWithdrawal(elParentBlock)) From fb10a8a1f814bc0401c90f2e22920c9a726ddd61 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 6 Nov 2025 12:25:30 +0300 Subject: [PATCH 08/31] wip --- .../units/block/validation/AssetInvalidAmountTestSuite.scala | 2 +- .../units/block/validation/AssetInvalidBridgeTestSuite.scala | 2 +- .../block/validation/AssetInvalidRecipientTestSuite.scala | 2 +- .../units/block/validation/AssetInvalidTokenTestSuite.scala | 2 +- .../scala/units/block/validation/AssetValidTestSuite.scala | 3 +-- .../units/block/validation/BaseBlockValidationSuite.scala | 2 +- .../units/block/validation/NativeInvalidAmountTestSuite.scala | 2 +- .../units/block/validation/NativeInvalidBridgeTestSuite.scala | 2 +- .../block/validation/NativeInvalidRecipientTestSuite.scala | 2 +- .../block/validation/NativeUnexpectedDepositTestSuite.scala | 2 +- .../block/validation/NativeUnexpectedWithdrawalTestSuite.scala | 2 +- .../scala/units/block/validation/NativeValidTestSuite.scala | 2 +- src/main/scala/units/eth/EthAddress.scala | 2 ++ 13 files changed, 14 insertions(+), 13 deletions(-) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala index 107cda99..57cfd2c0 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala @@ -26,7 +26,7 @@ class AssetInvalidAmountTestSuite extends BaseBlockValidationSuite { transferIndex = 0L, standardBridgeAddress = StandardBridgeAddress, token = TErc20Address, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = elRecipient, amount = invalidAmount ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala index 5599c4a0..12d82a30 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala @@ -26,7 +26,7 @@ class AssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { transferIndex = 0L, standardBridgeAddress = invalidStandardBridgeAddress, token = TErc20Address, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = elRecipient, amount = EAmount(elAssetTokenAmount.bigInteger) ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala index cee09e3b..1e93b815 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala @@ -26,7 +26,7 @@ class AssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { transferIndex = 0L, standardBridgeAddress = StandardBridgeAddress, token = TErc20Address, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = invalidRecipientAddress, amount = EAmount(elAssetTokenAmount.bigInteger) ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala index a39a81e8..092a9c53 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala @@ -26,7 +26,7 @@ class AssetInvalidTokenTestSuite extends BaseBlockValidationSuite { transferIndex = 0L, standardBridgeAddress = StandardBridgeAddress, token = invalidTokenAddress, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = elRecipient, amount = EAmount(elAssetTokenAmount.bigInteger) ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala index a159fdc6..8b700588 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala @@ -4,7 +4,6 @@ import com.wavesplatform.* import com.wavesplatform.account.* import com.wavesplatform.common.utils.EitherExt2.explicitGet import com.wavesplatform.lang.v1.compiler.Terms -import com.wavesplatform.state.StringDataEntry import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.smart.InvokeScriptTransaction import units.* @@ -25,7 +24,7 @@ class AssetValidTestSuite extends BaseBlockValidationSuite { transferIndex = 0L, standardBridgeAddress = StandardBridgeAddress, token = TErc20Address, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = elRecipient, amount = EAmount(elAssetTokenAmount.bigInteger) ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala index 57747f51..642137b5 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala @@ -241,7 +241,7 @@ trait BaseBlockValidationSuite extends BaseDockerTestSuite { } protected def getMainChainLastBlock: EcBlock = { - val mainChainId = waves1.api.dataByKey(chainContractAddress, "mainChainId").collect { case i: IntegerDataEntry => i.value }.get + val mainChainId = waves1.api.dataByKey(chainContractAddress, "mainChainId").collect { case i: IntegerDataEntry => i.value }.getOrElse(0L) val elParentBlockId = waves1.api.dataByKey(chainContractAddress, f"chain_$mainChainId%08d").collect { case s: StringDataEntry => BlockHash("0x" + s.value.split(",")(1)) }.get diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala index 723f84c2..0df5dd5c 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala @@ -26,7 +26,7 @@ class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { StandardBridge.mkFinalizeBridgeETHTransaction( transferIndex = 0L, standardBridgeAddress = StandardBridgeAddress, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = elRecipient, amount = invalidAmount ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala index 0ce3ef67..2b3026e5 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala @@ -26,7 +26,7 @@ class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { StandardBridge.mkFinalizeBridgeETHTransaction( transferIndex = 0L, standardBridgeAddress = invalidStandardBridgeAddress, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = elRecipient, amount = clNativeTokenAmount.longValue ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala index 81973c47..d8a0c46a 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala @@ -26,7 +26,7 @@ class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { StandardBridge.mkFinalizeBridgeETHTransaction( transferIndex = 0L, standardBridgeAddress = StandardBridgeAddress, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = invalidRecipient, amount = clNativeTokenAmount.longValue ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala index ded1d28e..ae23fadc 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala @@ -24,7 +24,7 @@ class NativeUnexpectedDepositTestSuite extends BaseBlockValidationSuite { StandardBridge.mkFinalizeBridgeETHTransaction( transferIndex = 0L, standardBridgeAddress = StandardBridgeAddress, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = elRecipient, amount = clNativeTokenAmount.longValue ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala index bda07b3d..2d582a99 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala @@ -26,7 +26,7 @@ class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { StandardBridge.mkFinalizeBridgeETHTransaction( transferIndex = 0L, standardBridgeAddress = StandardBridgeAddress, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = elRecipient, amount = clNativeTokenAmount.longValue ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala index ed1030d0..516dad3a 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala @@ -24,7 +24,7 @@ class NativeValidTestSuite extends BaseBlockValidationSuite { StandardBridge.mkFinalizeBridgeETHTransaction( transferIndex = 0L, standardBridgeAddress = StandardBridgeAddress, - from = EthAddress.unsafeFrom(clSender.toAddress.bytes.drop(2).take(20)), + from = EthAddress.unsafeFrom(clSender.toAddress), to = elRecipient, amount = clNativeTokenAmount.longValue ) diff --git a/src/main/scala/units/eth/EthAddress.scala b/src/main/scala/units/eth/EthAddress.scala index 15d48683..cd03e6b5 100644 --- a/src/main/scala/units/eth/EthAddress.scala +++ b/src/main/scala/units/eth/EthAddress.scala @@ -1,5 +1,6 @@ package units.eth +import com.wavesplatform.account.Address import play.api.libs.json.* import units.util.HexBytesConverter @@ -34,4 +35,5 @@ object EthAddress { def unsafeFrom(hex: String): EthAddress = from(hex).left.map(new RuntimeException(_)).toTry.get def unsafeFrom(bytes: Array[Byte]): EthAddress = unsafeFrom(HexBytesConverter.toHex(bytes)) + def unsafeFrom(address: Address): EthAddress = unsafeFrom(address.bytes.slice(2, 22)) } From d873d2dd2240527da58ad58218433754a5b4ae73 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 6 Nov 2025 12:37:05 +0300 Subject: [PATCH 09/31] wip --- .github/workflows/check-pr.yml | 12 +----------- .../src/test/resources/logback-test.xml | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index ce62e098..0f79a7b5 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -17,14 +17,6 @@ jobs: env: JAVA_OPTS: -Dfile.encoding=UTF-8 BRANCH_NAME: ${{ github.head_ref || github.ref_name }} - services: - docker: - image: docker:latest - options: --privileged # Required for Docker-in-Docker - volumes: - - /var/run/docker.sock:/var/run/docker.sock - ports: - - 2375:2375 steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 @@ -50,9 +42,7 @@ jobs: which solc || echo "Solc not found in PATH" - uses: sbt/setup-sbt@v1 - name: Run tests - run: | - forge --version - sbt -Dcc.it.max-parallel-suites=2 --batch "scalafmtCheck;test;docker;consensus-client-it/test" + run: sbt -Dcc.it.max-parallel-suites=2 -Dcc.it.logs.stdout.level=OFF --batch "scalafmtCheck;test;docker;consensus-client-it/test" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} - uses: scacap/action-surefire-report@5609ce4db72c09db044803b344a8968fd1f315da diff --git a/consensus-client-it/src/test/resources/logback-test.xml b/consensus-client-it/src/test/resources/logback-test.xml index fc8fb696..d1e1c680 100644 --- a/consensus-client-it/src/test/resources/logback-test.xml +++ b/consensus-client-it/src/test/resources/logback-test.xml @@ -6,7 +6,7 @@ - DEBUG + ${cc.it.logs.stdout.level:-DEBUG} ${pattern} From cadbe8ce45c0c108035071673dde7cbe1af248bf Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 6 Nov 2025 12:46:46 +0300 Subject: [PATCH 10/31] wip --- .github/workflows/check-pr.yml | 2 +- consensus-client-it/build.sbt | 5 ++++- consensus-client-it/src/test/resources/logback-test.xml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 0f79a7b5..126116ad 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -42,7 +42,7 @@ jobs: which solc || echo "Solc not found in PATH" - uses: sbt/setup-sbt@v1 - name: Run tests - run: sbt -Dcc.it.max-parallel-suites=2 -Dcc.it.logs.stdout.level=OFF --batch "scalafmtCheck;test;docker;consensus-client-it/test" + run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=OFF --batch "scalafmtCheck;test;docker;consensus-client-it/test" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} - uses: scacap/action-surefire-report@5609ce4db72c09db044803b344a8968fd1f315da diff --git a/consensus-client-it/build.sbt b/consensus-client-it/build.sbt index a4a80d70..62b28ac9 100644 --- a/consensus-client-it/build.sbt +++ b/consensus-client-it/build.sbt @@ -9,6 +9,7 @@ import java.io.FileInputStream import java.time.LocalDateTime import java.time.format.DateTimeFormatter import scala.sys.process.* +import scala.sys.props import scala.util.control.NonFatal description := "Consensus client integration tests" @@ -81,6 +82,7 @@ Global / concurrentRestrictions := Seq( ) ) +val LogbackTestLevel = "logback.test.level" inConfig(Test)( Seq( logsDirectory := { @@ -93,7 +95,8 @@ inConfig(Test)( s"-Dlogback.configurationFile=${(Test / resourceDirectory).value}/logback-test.xml", // Fixes a logback blaming for multiple configs s"-Dcc.it.configs.dir=${baseDirectory.value.getParent}/local-network/configs", s"-Dcc.it.docker.image=consensus-client:${gitCurrentBranch.value}", - s"-Dcc.it.contracts.dir=${baseDirectory.value / ".." / "contracts" / "eth"}" + s"-Dcc.it.contracts.dir=${baseDirectory.value / ".." / "contracts" / "eth"}", + s"-D$LogbackTestLevel=${props.getOrElse(LogbackTestLevel, "TRACE")}" ), testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-fFWD", ((Test / logsDirectory).value / "summary.log").toString), fork := true, diff --git a/consensus-client-it/src/test/resources/logback-test.xml b/consensus-client-it/src/test/resources/logback-test.xml index d1e1c680..6c8c1486 100644 --- a/consensus-client-it/src/test/resources/logback-test.xml +++ b/consensus-client-it/src/test/resources/logback-test.xml @@ -6,7 +6,7 @@ - ${cc.it.logs.stdout.level:-DEBUG} + ${logback.test.level:-DEBUG} ${pattern} From 05b18ee9daac39bb35667e574d0723d31c67cc41 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 6 Nov 2025 13:15:07 +0300 Subject: [PATCH 11/31] wip --- .../block/validation/AssetInvalidAmountTestSuite.scala | 8 ++++---- .../block/validation/AssetInvalidBridgeTestSuite.scala | 8 ++++---- .../validation/AssetInvalidRecipientTestSuite.scala | 8 ++++---- .../block/validation/AssetInvalidSenderTestSuite.scala | 8 ++++---- .../block/validation/AssetInvalidTokenTestSuite.scala | 8 ++++---- .../units/block/validation/AssetValidTestSuite.scala | 4 ++-- .../block/validation/BaseBlockValidationSuite.scala | 6 ++---- .../validation/NativeInvalidAmountTestSuite.scala | 10 +++++----- .../validation/NativeInvalidBridgeTestSuite.scala | 10 +++++----- .../validation/NativeInvalidRecipientTestSuite.scala | 10 +++++----- .../validation/NativeInvalidSenderTestSuite.scala | 10 +++++----- .../validation/NativeMissingDepositTestSuite.scala | 10 +++++----- .../validation/NativeUnexpectedDepositTestSuite.scala | 8 ++++---- .../NativeUnexpectedWithdrawalTestSuite.scala | 10 +++++----- .../units/block/validation/NativeValidTestSuite.scala | 4 ++-- .../units/block/validation/NoTransfersTestSuite.scala | 4 ++-- 16 files changed, 62 insertions(+), 64 deletions(-) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala index 57cfd2c0..3b07240e 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala @@ -51,7 +51,7 @@ class AssetInvalidAmountTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -71,7 +71,7 @@ class AssetInvalidAmountTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -80,9 +80,9 @@ class AssetInvalidAmountTestSuite extends BaseBlockValidationSuite { val balanceAfter = terc20.getBalance(elRecipient) balanceAfter.longValue shouldBe balanceBefore.longValue - step("Assertion: EL height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be (simulatedBlockHash) } override def beforeAll(): Unit = setupForAssetTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala index 12d82a30..5d3a9153 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala @@ -51,7 +51,7 @@ class AssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -71,7 +71,7 @@ class AssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -80,9 +80,9 @@ class AssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { val balanceAfter = terc20.getBalance(elRecipient) balanceAfter.longValue shouldBe balanceBefore.longValue - step("Assertion: EL height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForAssetTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala index 1e93b815..30ab2437 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala @@ -51,7 +51,7 @@ class AssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -71,7 +71,7 @@ class AssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -80,9 +80,9 @@ class AssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { val balanceAfter = terc20.getBalance(elRecipient) balanceAfter.longValue shouldBe balanceBefore.longValue - step("Assertion: EL height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForAssetTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala index 134a3d75..3bf65fef 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala @@ -49,7 +49,7 @@ class AssetInvalidSenderTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -69,7 +69,7 @@ class AssetInvalidSenderTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -78,9 +78,9 @@ class AssetInvalidSenderTestSuite extends BaseBlockValidationSuite { val balanceAfter = terc20.getBalance(elRecipient) balanceAfter.longValue shouldBe balanceBefore.longValue - step("Assertion: EL height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForAssetTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala index 092a9c53..a452468d 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala @@ -51,7 +51,7 @@ class AssetInvalidTokenTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -71,7 +71,7 @@ class AssetInvalidTokenTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -80,9 +80,9 @@ class AssetInvalidTokenTestSuite extends BaseBlockValidationSuite { val balanceAfter = terc20.getBalance(elRecipient) balanceAfter.longValue shouldBe balanceBefore.longValue - step("Assertion: EL height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForAssetTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala index 8b700588..19587bc5 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala @@ -49,7 +49,7 @@ class AssetValidTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -69,7 +69,7 @@ class AssetValidTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } diff --git a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala index 642137b5..d148d7d7 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala @@ -71,7 +71,7 @@ trait BaseBlockValidationSuite extends BaseDockerTestSuite { elParentBlock: EcBlock, withdrawals: Seq[Withdrawal], depositedTransactions: Seq[DepositedTransaction] - ): (JsObject, String, ByteStr) = { + ): (JsObject, BlockHash, ByteStr) = { step("Building a simulated block") val feeRecipient = actingMinerRewardAddress @@ -102,9 +102,7 @@ trait BaseBlockValidationSuite extends BaseDockerTestSuite { ) ) - val simulatedBlockHash: String = (simulatedBlock \ "hash").as[String] - - (payload, simulatedBlockHash, hitSource) + (payload, (simulatedBlock \ "hash").as[BlockHash], hitSource) } protected def deployContractsAndActivateTransferFeatures(): Unit = { diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala index 0df5dd5c..1225e83f 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala @@ -51,7 +51,7 @@ class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -71,7 +71,7 @@ class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -79,7 +79,7 @@ class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -88,9 +88,9 @@ class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { val ethBalanceAfter = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance ethBalanceBefore shouldBe ethBalanceAfter - step("Assertion: While the block exists on EC1, the height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala index 2b3026e5..f7280087 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala @@ -51,7 +51,7 @@ class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -71,7 +71,7 @@ class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -79,7 +79,7 @@ class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -88,9 +88,9 @@ class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { val ethBalanceAfter = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance ethBalanceBefore shouldBe ethBalanceAfter - step("Assertion: While the block exists on EC1, the height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala index d8a0c46a..ebebe594 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala @@ -51,7 +51,7 @@ class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -71,7 +71,7 @@ class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -79,7 +79,7 @@ class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -88,9 +88,9 @@ class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { val ethBalanceAfter = ec1.web3j.ethGetBalance(invalidRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance ethBalanceBefore shouldBe ethBalanceAfter - step("Assertion: While the block exists on EC1, the height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala index e6e5bc04..3404b806 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala @@ -49,7 +49,7 @@ class NativeInvalidSenderTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -69,7 +69,7 @@ class NativeInvalidSenderTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -77,7 +77,7 @@ class NativeInvalidSenderTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -86,9 +86,9 @@ class NativeInvalidSenderTestSuite extends BaseBlockValidationSuite { val ethBalanceAfter = ec1.web3j.ethGetBalance(invalidSender.toString, DefaultBlockParameterName.LATEST).send().getBalance ethBalanceBefore shouldBe ethBalanceAfter - step("Assertion: While the block exists on EC1, the height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala index 7683d3d4..60b091c9 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala @@ -38,7 +38,7 @@ class NativeMissingDepositTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -58,7 +58,7 @@ class NativeMissingDepositTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -66,7 +66,7 @@ class NativeMissingDepositTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -75,9 +75,9 @@ class NativeMissingDepositTestSuite extends BaseBlockValidationSuite { val ethBalanceAfter = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance ethBalanceBefore shouldBe ethBalanceAfter - step("Assertion: While the block exists on EC1, the height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala index ae23fadc..17606d86 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala @@ -41,7 +41,7 @@ class NativeUnexpectedDepositTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -61,7 +61,7 @@ class NativeUnexpectedDepositTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -70,9 +70,9 @@ class NativeUnexpectedDepositTestSuite extends BaseBlockValidationSuite { val ethBalanceAfter = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance ethBalanceBefore shouldBe ethBalanceAfter - step("Assertion: While the block exists on EC1, the height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala index 2d582a99..259af984 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala @@ -51,7 +51,7 @@ class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -71,7 +71,7 @@ class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -79,7 +79,7 @@ class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } @@ -88,9 +88,9 @@ class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { val ethBalanceAfter = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance ethBalanceBefore shouldBe ethBalanceAfter - step("Assertion: While the block exists on EC1, the height doesn't grow") + step("Assertion: head is not moved to simulated block") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe elParentBlock.height.longValue + elBlockAfter.hash shouldNot be(simulatedBlockHash) } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala index 516dad3a..4e41cdb9 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala @@ -49,7 +49,7 @@ class NativeValidTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -69,7 +69,7 @@ class NativeValidTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } diff --git a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala index 740374de..72a4bf54 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala @@ -28,7 +28,7 @@ class NoTransfersTestSuite extends BaseBlockValidationSuite { dApp = chainContractAddress, func = Some("extendMainChain_v2"), args = List( - Terms.CONST_STRING(simulatedBlockHash.drop(2)).explicitGet(), + Terms.CONST_STRING(simulatedBlockHash.hexNoPrefix).explicitGet(), Terms.CONST_STRING(elParentBlock.hash.hexNoPrefix).explicitGet(), Terms.CONST_BYTESTR(hitSource).explicitGet(), Terms.CONST_STRING(EmptyE2CTransfersRootHashHex.drop(2)).explicitGet(), @@ -48,7 +48,7 @@ class NoTransfersTestSuite extends BaseBlockValidationSuite { step("Assertion: Block exists on EC1") eventually { ec1.engineApi - .getBlockByHash(BlockHash(simulatedBlockHash)) + .getBlockByHash(simulatedBlockHash) .explicitGet() .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) } From dd3e70b763ee37d0ebe09b245b3b3a09bf483b32 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 6 Nov 2025 13:35:07 +0300 Subject: [PATCH 12/31] wip --- .../test/scala/units/block/validation/AssetValidTestSuite.scala | 2 +- .../scala/units/block/validation/NativeValidTestSuite.scala | 2 +- .../scala/units/block/validation/NoTransfersTestSuite.scala | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala index 19587bc5..d5ef27b4 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala @@ -80,7 +80,7 @@ class AssetValidTestSuite extends BaseBlockValidationSuite { step("Assertion: EL height grows") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe (elParentBlock.height.longValue + 1) + elBlockAfter.hash shouldBe simulatedBlockHash } override def beforeAll(): Unit = setupForAssetTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala index 4e41cdb9..4b7eb560 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala @@ -80,7 +80,7 @@ class NativeValidTestSuite extends BaseBlockValidationSuite { step("Assertion: EL height grows") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe (elParentBlock.height.longValue + 1) + elBlockAfter.hash shouldBe simulatedBlockHash } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala index 72a4bf54..d4c7ac62 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala @@ -55,7 +55,7 @@ class NoTransfersTestSuite extends BaseBlockValidationSuite { step("Assertion: EL height grows") val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.height.longValue shouldBe (elParentBlock.height.longValue + 1) + elBlockAfter.hash shouldBe simulatedBlockHash } override def beforeAll(): Unit = setupForNativeTokenTransfer() From 2b90cd07b03b4bf112184f370e90ebd749149569 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 6 Nov 2025 14:06:17 +0300 Subject: [PATCH 13/31] wip --- .github/workflows/check-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 126116ad..e4473885 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -13,7 +13,7 @@ jobs: check-pr: name: Check PR runs-on: ubuntu-latest - timeout-minutes: 30 + timeout-minutes: 60 env: JAVA_OPTS: -Dfile.encoding=UTF-8 BRANCH_NAME: ${{ github.head_ref || github.ref_name }} From 86d70f5bd881973d3b36ee18697dec67ab446497 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 6 Nov 2025 14:50:28 +0300 Subject: [PATCH 14/31] wip --- .github/workflows/check-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index e4473885..2e7ddd4f 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -42,7 +42,7 @@ jobs: which solc || echo "Solc not found in PATH" - uses: sbt/setup-sbt@v1 - name: Run tests - run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=OFF --batch "scalafmtCheck;test;docker;consensus-client-it/test" + run: sbt -Dcc.it.max-parallel-suites=1 -Dlogback.test.level=DEBUG --batch "scalafmtCheck;test;docker;consensus-client-it/test" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} - uses: scacap/action-surefire-report@5609ce4db72c09db044803b344a8968fd1f315da From 8c332b984bc73ef7a09a3d5d215a650066832511 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 6 Nov 2025 15:56:29 +0300 Subject: [PATCH 15/31] wip --- .github/workflows/check-pr.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 2e7ddd4f..d965fe27 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -17,6 +17,14 @@ jobs: env: JAVA_OPTS: -Dfile.encoding=UTF-8 BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + services: + docker: + image: docker:latest + options: --privileged # Required for Docker-in-Docker + volumes: + - /var/run/docker.sock:/var/run/docker.sock + ports: + - 2375:2375 steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 @@ -42,7 +50,7 @@ jobs: which solc || echo "Solc not found in PATH" - uses: sbt/setup-sbt@v1 - name: Run tests - run: sbt -Dcc.it.max-parallel-suites=1 -Dlogback.test.level=DEBUG --batch "scalafmtCheck;test;docker;consensus-client-it/test" + run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=DEBUG --batch "scalafmtCheck;test;docker;consensus-client-it/test" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} - uses: scacap/action-surefire-report@5609ce4db72c09db044803b344a8968fd1f315da From 4111670a377b8a43da732256c882e8b7e746cde6 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Fri, 7 Nov 2025 13:32:09 +0300 Subject: [PATCH 16/31] wip --- .../validation/BaseBlockValidationSuite.scala | 4 ++-- .../test/scala/units/docker/BaseContainer.scala | 1 + .../test/scala/units/docker/DockerImages.scala | 2 +- .../scala/units/docker/WavesNodeContainer.scala | 12 ++++-------- .../src/test/scala/units/http/OkHttpLogger.scala | 2 +- contracts/waves/src/main.ride | 15 +++++++++++---- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala index d148d7d7..eb119c4e 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala @@ -237,13 +237,13 @@ trait BaseBlockValidationSuite extends BaseDockerTestSuite { transferAssetTokenToClSender() leaveSetupMinerAndJoinOthers() } - + protected def getMainChainLastBlock: EcBlock = { val mainChainId = waves1.api.dataByKey(chainContractAddress, "mainChainId").collect { case i: IntegerDataEntry => i.value }.getOrElse(0L) val elParentBlockId = waves1.api.dataByKey(chainContractAddress, f"chain_$mainChainId%08d").collect { case s: StringDataEntry => BlockHash("0x" + s.value.split(",")(1)) }.get - + ec1.engineApi.getBlockByHash(elParentBlockId).explicitGet().get } } 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 484f80e1..d0292e48 100644 --- a/consensus-client-it/src/test/scala/units/docker/BaseContainer.scala +++ b/consensus-client-it/src/test/scala/units/docker/BaseContainer.scala @@ -18,6 +18,7 @@ abstract class BaseContainer(val hostName: String) { } def stop(): Unit = { + container.getDockerClient.stopContainerCmd(container.getContainerId).exec() container.stop() } diff --git a/consensus-client-it/src/test/scala/units/docker/DockerImages.scala b/consensus-client-it/src/test/scala/units/docker/DockerImages.scala index a45be460..37dc1b8b 100644 --- a/consensus-client-it/src/test/scala/units/docker/DockerImages.scala +++ b/consensus-client-it/src/test/scala/units/docker/DockerImages.scala @@ -5,5 +5,5 @@ import units.test.TestEnvironment.WavesDockerImage object DockerImages { val WavesNode = parse(WavesDockerImage) - val OpGethExecutionClient = parse("ghcr.io/unitsnetwork/op-geth:v1.101603.0-1") + val OpGethExecutionClient = parse("ghcr.io/unitsnetwork/op-geth:1.6.3-race-detector") } 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 6c450967..fdda328b 100644 --- a/consensus-client-it/src/test/scala/units/docker/WavesNodeContainer.scala +++ b/consensus-client-it/src/test/scala/units/docker/WavesNodeContainer.scala @@ -66,7 +66,7 @@ class WavesNodeContainer( .withStopTimeout(5) // Otherwise we don't have logs in the end } - lazy val apiPort = container.getMappedPort(ApiPort) + lazy val apiPort = container.getMappedPort(ApiPort) lazy val unitsNetworkPort = container.getMappedPort(UnitsNetworkPort) lazy val api = new NodeHttpApi(uri"http://${container.getHost}:$apiPort", httpClientBackend) @@ -75,7 +75,7 @@ class WavesNodeContainer( } object WavesNodeContainer { - val ApiPort = 6869 + val ApiPort = 6869 val UnitsNetworkPort = 6865 val GenesisTemplateFile = new File(s"$ConfigsDir/wavesnode/genesis-template.conf") @@ -89,12 +89,8 @@ object WavesNodeContainer { val templateFile = ConfigsDir.resolve("wavesnode/genesis-template.conf").toAbsolutePath val origConfig = ConfigFactory.parseFile(templateFile.toFile) - val gap = 25.seconds // To force node mining at start, otherwise it schedules - val overrides = ConfigFactory.parseString( - s"""genesis-generator { - | timestamp = ${System.currentTimeMillis() - gap.toMillis} - |}""".stripMargin - ) + // To force node mining at start, otherwise it schedules + val overrides = ConfigFactory.parseString(s"genesis-generator.timestamp = ${System.currentTimeMillis() - 25.seconds.toMillis}") val genesisSettings = GenesisBlockGenerator.parseSettings(overrides.withFallback(origConfig)) diff --git a/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala b/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala index 8a2f4cc1..302e08e8 100644 --- a/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala +++ b/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala @@ -12,7 +12,7 @@ object OkHttpLogger extends Interceptor with ScorexLogging { val req = chain.request() val bodyStr = readRequestBody(req) - val currRequestId = (Json.parse(bodyStr) \ "id").asOpt[Long].getOrElse(LoggingUtil.currRequestId.toLong) + val currRequestId = (Json.parse(bodyStr) \ "id").as[Long] log.debug(s"[$currRequestId] ${req.method()} ${req.url()}: body=$bodyStr") val res = chain.proceed(req) log.debug(s"[$currRequestId] HTTP ${res.code()}: body=${readResponseBody(res)}") diff --git a/contracts/waves/src/main.ride b/contracts/waves/src/main.ride index 2f0cb87e..f55aa103 100644 --- a/contracts/waves/src/main.ride +++ b/contracts/waves/src/main.ride @@ -848,6 +848,12 @@ func join(rewardAddressHex: String) = { let normalizedRewardAddress = normalizeEthAddress(rewardAddressHex) strict checkNotOverride = ensureNotOverrideOtherMinerPk(normalizedRewardAddress) + let minerLeftKey = "miner_" + newMiner + "_left" + let minerCanJoinAtHeight = this.getInteger(minerLeftKey).valueOrElse(-20) + 20 + + strict minerCanJoin = height >= minerCanJoinAtHeight || + throw("Miner can join after height " + minerCanJoinAtHeight.toString()) + # Here is 980 complexity consumed, all code below spent more than 1000 of free complexity # If a miner changed the reward address, we need to delete the previous mapping @@ -863,7 +869,8 @@ func join(rewardAddressHex: String) = { [ StringEntry(allMinersKey, updatedAllMiners), StringEntry(minerRewardAddressKey(newMiner), "0x" + normalizedRewardAddress), - BinaryEntry(minerPkKey(normalizedRewardAddress), i.originCallerPublicKey) + BinaryEntry(minerPkKey(normalizedRewardAddress), i.originCallerPublicKey), + DeleteEntry(minerLeftKey) ] ++ deletePrevRewardAddressPk } @@ -877,9 +884,9 @@ func leave() = { let rewardAddrKey = minerRewardAddressKey(leavingMiner) strict prevRewardAddress = this.getString(rewardAddrKey).valueOrErrorMessage("miner has never joined") - if (thisEpochMiner == i.originCaller) then throw("designated miner can't leave") - else [ - StringEntry(allMinersKey, remainingMiners.makeString_2C(SEP)) + [ + StringEntry(allMinersKey, remainingMiners.makeString_2C(SEP)), + IntegerEntry("miner_" + leavingMiner + "_left", height) # TODO Get miner info at epoch start # DeleteEntry(rewardAddrKey), # Can cause empty miner reward address for next blocks # DeleteEntry(minerPkKey(prevRewardAddress)) From 1f97f54154379056a5880337a1b1871f93d3c098 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Mon, 10 Nov 2025 14:28:52 +0300 Subject: [PATCH 17/31] wip --- .../block/validation/AssetInvalidAmountTestSuite.scala | 2 ++ .../block/validation/AssetInvalidBridgeTestSuite.scala | 2 ++ .../block/validation/AssetInvalidRecipientTestSuite.scala | 2 ++ .../block/validation/AssetInvalidSenderTestSuite.scala | 2 ++ .../block/validation/AssetInvalidTokenTestSuite.scala | 2 ++ .../units/block/validation/AssetValidTestSuite.scala | 2 ++ .../units/block/validation/BaseBlockValidationSuite.scala | 8 +++++++- .../block/validation/NativeInvalidAmountTestSuite.scala | 2 ++ .../block/validation/NativeInvalidBridgeTestSuite.scala | 2 ++ .../validation/NativeInvalidRecipientTestSuite.scala | 2 ++ .../block/validation/NativeInvalidSenderTestSuite.scala | 2 ++ .../block/validation/NativeMissingDepositTestSuite.scala | 2 ++ .../validation/NativeUnexpectedDepositTestSuite.scala | 2 ++ .../validation/NativeUnexpectedWithdrawalTestSuite.scala | 2 ++ .../units/block/validation/NativeValidTestSuite.scala | 2 ++ .../units/block/validation/NoTransfersTestSuite.scala | 3 ++- 16 files changed, 37 insertions(+), 2 deletions(-) diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala index 3b07240e..b4dd9939 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala @@ -43,6 +43,8 @@ class AssetInvalidAmountTestSuite extends BaseBlockValidationSuite { clAssetTokenAmount ) ) + + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala index 5d3a9153..d16d9271 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala @@ -44,6 +44,8 @@ class AssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala index 30ab2437..a1f998eb 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala @@ -44,6 +44,8 @@ class AssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala index 3bf65fef..38c12e4f 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala @@ -42,6 +42,8 @@ class AssetInvalidSenderTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala index a452468d..4bd31592 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala @@ -44,6 +44,8 @@ class AssetInvalidTokenTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala index d5ef27b4..70b4a3db 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala @@ -42,6 +42,8 @@ class AssetValidTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala index eb119c4e..b271a64f 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala @@ -1,11 +1,12 @@ package units.block.validation +import com.google.common.primitives.Ints import com.wavesplatform.* import com.wavesplatform.account.* import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2.explicitGet import com.wavesplatform.crypto.Keccak256 -import com.wavesplatform.state.{Height, IntegerDataEntry, StringDataEntry} +import com.wavesplatform.state.{BinaryDataEntry, Height, IntegerDataEntry, StringDataEntry} import com.wavesplatform.transaction.Asset.IssuedAsset import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.{Asset, TxHelpers} @@ -246,4 +247,9 @@ trait BaseBlockValidationSuite extends BaseDockerTestSuite { ec1.engineApi.getBlockByHash(elParentBlockId).explicitGet().get } + + protected def getBlockEpoch(blockHash: BlockHash): Option[Height] = + waves1.api.dataByKey(chainContractAddress, s"block_$blockHash").collect { + case b: BinaryDataEntry => Height(Longs.fromByteArray(b.value.arr.slice(8, 16)).toInt) + } } diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala index 1225e83f..94070258 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala @@ -44,6 +44,8 @@ class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala index f7280087..5f875db8 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala @@ -44,6 +44,8 @@ class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala index ebebe594..1e711856 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala @@ -44,6 +44,8 @@ class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala index 3404b806..bbb5ea6e 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala @@ -42,6 +42,8 @@ class NativeInvalidSenderTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala index 60b091c9..53241de2 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala @@ -31,6 +31,8 @@ class NativeMissingDepositTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala index 17606d86..4e1d64d4 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala @@ -34,6 +34,8 @@ class NativeUnexpectedDepositTestSuite extends BaseBlockValidationSuite { // Note: No transfers on the chain contract in this test case + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala index 259af984..babee58e 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala @@ -44,6 +44,8 @@ class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala index 4b7eb560..ba659fbd 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala @@ -42,6 +42,8 @@ class NativeValidTestSuite extends BaseBlockValidationSuite { ) ) + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala index d4c7ac62..86d76f5c 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala @@ -18,7 +18,8 @@ class NoTransfersTestSuite extends BaseBlockValidationSuite { val depositedTransactions = Vector.empty val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - + + waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) // Note: No transfers on the chain contract in this test case step("Register the simulated block on the chain contract") From 2dd2fbb91f2c5e5088ec744f2aa37ecc5745cfba Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Mon, 10 Nov 2025 14:34:59 +0300 Subject: [PATCH 18/31] wip --- .../scala/units/block/validation/BaseBlockValidationSuite.scala | 2 +- .../src/test/scala/units/http/OkHttpLogger.scala | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala index b271a64f..780db422 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala @@ -1,6 +1,6 @@ package units.block.validation -import com.google.common.primitives.Ints +import com.google.common.primitives.Longs import com.wavesplatform.* import com.wavesplatform.account.* import com.wavesplatform.common.state.ByteStr diff --git a/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala b/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala index 302e08e8..9a6a7384 100644 --- a/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala +++ b/consensus-client-it/src/test/scala/units/http/OkHttpLogger.scala @@ -1,6 +1,5 @@ package units.http -import com.wavesplatform.api.LoggingUtil import com.wavesplatform.utils.ScorexLogging import okhttp3.{Interceptor, Request, Response} import play.api.libs.json.Json From 8d27808463115f8a0c735a9b2bed70ff81f6d380 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Mon, 10 Nov 2025 15:07:10 +0300 Subject: [PATCH 19/31] wip --- .github/workflows/check-pr.yml | 10 +--------- .../block/validation/AssetInvalidAmountTestSuite.scala | 5 ++--- .../block/validation/AssetInvalidBridgeTestSuite.scala | 3 +-- .../validation/AssetInvalidRecipientTestSuite.scala | 3 +-- .../block/validation/AssetInvalidSenderTestSuite.scala | 3 +-- .../block/validation/AssetInvalidTokenTestSuite.scala | 3 +-- .../units/block/validation/AssetValidTestSuite.scala | 3 +-- .../validation/NativeInvalidAmountTestSuite.scala | 3 +-- .../validation/NativeInvalidBridgeTestSuite.scala | 3 +-- .../validation/NativeInvalidRecipientTestSuite.scala | 3 +-- .../validation/NativeInvalidSenderTestSuite.scala | 3 +-- .../validation/NativeMissingDepositTestSuite.scala | 3 +-- .../validation/NativeUnexpectedDepositTestSuite.scala | 3 +-- .../NativeUnexpectedWithdrawalTestSuite.scala | 3 +-- .../units/block/validation/NativeValidTestSuite.scala | 3 +-- .../units/block/validation/NoTransfersTestSuite.scala | 3 +-- 16 files changed, 17 insertions(+), 40 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index d965fe27..19246cb4 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -17,14 +17,6 @@ jobs: env: JAVA_OPTS: -Dfile.encoding=UTF-8 BRANCH_NAME: ${{ github.head_ref || github.ref_name }} - services: - docker: - image: docker:latest - options: --privileged # Required for Docker-in-Docker - volumes: - - /var/run/docker.sock:/var/run/docker.sock - ports: - - 2375:2375 steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 @@ -47,7 +39,7 @@ jobs: wget https://binaries.soliditylang.org/linux-amd64/solc-linux-amd64-v0.8.29+commit.ab55807c -O /home/runner/.solc/v0.8.29/solc-static-linux echo "/home/runner/.solc" >> $GITHUB_PATH ln -sf /home/runner/.solc/v0.8.29/solc-static-linux /home/runner/.solc/solc - which solc || echo "Solc not found in PATH" + - run: which solc || echo "Solc not found in PATH" - uses: sbt/setup-sbt@v1 - name: Run tests run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=DEBUG --batch "scalafmtCheck;test;docker;consensus-client-it/test" diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala index b4dd9939..b1d688b9 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidAmountTestSuite.scala @@ -32,8 +32,6 @@ class AssetInvalidAmountTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -45,7 +43,8 @@ class AssetInvalidAmountTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) - + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) + step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( TxHelpers.invoke( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala index d16d9271..837bd8cc 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidBridgeTestSuite.scala @@ -32,8 +32,6 @@ class AssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -45,6 +43,7 @@ class AssetInvalidBridgeTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala index a1f998eb..4590b6e6 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidRecipientTestSuite.scala @@ -32,8 +32,6 @@ class AssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -45,6 +43,7 @@ class AssetInvalidRecipientTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala index 38c12e4f..7e49e814 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidSenderTestSuite.scala @@ -30,8 +30,6 @@ class AssetInvalidSenderTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -43,6 +41,7 @@ class AssetInvalidSenderTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala index 4bd31592..946eefd0 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetInvalidTokenTestSuite.scala @@ -32,8 +32,6 @@ class AssetInvalidTokenTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -45,6 +43,7 @@ class AssetInvalidTokenTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala index 70b4a3db..e55c8f5f 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala @@ -30,8 +30,6 @@ class AssetValidTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -43,6 +41,7 @@ class AssetValidTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala index 94070258..384ac578 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidAmountTestSuite.scala @@ -32,8 +32,6 @@ class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -45,6 +43,7 @@ class NativeInvalidAmountTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala index 5f875db8..c0715f98 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidBridgeTestSuite.scala @@ -32,8 +32,6 @@ class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -45,6 +43,7 @@ class NativeInvalidBridgeTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala index 1e711856..126dd648 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidRecipientTestSuite.scala @@ -32,8 +32,6 @@ class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -45,6 +43,7 @@ class NativeInvalidRecipientTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala index bbb5ea6e..5f206187 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeInvalidSenderTestSuite.scala @@ -30,8 +30,6 @@ class NativeInvalidSenderTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -43,6 +41,7 @@ class NativeInvalidSenderTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala index 53241de2..1e4c39f1 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeMissingDepositTestSuite.scala @@ -19,8 +19,6 @@ class NativeMissingDepositTestSuite extends BaseBlockValidationSuite { val depositedTransactions = Vector() - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -32,6 +30,7 @@ class NativeMissingDepositTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala index 4e1d64d4..269ad381 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedDepositTestSuite.scala @@ -30,11 +30,10 @@ class NativeUnexpectedDepositTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - // Note: No transfers on the chain contract in this test case waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala index babee58e..5c74b1df 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeUnexpectedWithdrawalTestSuite.scala @@ -32,8 +32,6 @@ class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -45,6 +43,7 @@ class NativeUnexpectedWithdrawalTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala index ba659fbd..3aacb212 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala @@ -30,8 +30,6 @@ class NativeValidTestSuite extends BaseBlockValidationSuite { ) ) - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - step("Transfer on the chain contract") waves1.api.broadcastAndWait( ChainContract.transfer( @@ -43,6 +41,7 @@ class NativeValidTestSuite extends BaseBlockValidationSuite { ) waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) step("Register the simulated block on the chain contract") waves1.api.broadcastAndWait( diff --git a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala index 86d76f5c..58f243ba 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala @@ -17,9 +17,8 @@ class NoTransfersTestSuite extends BaseBlockValidationSuite { val depositedTransactions = Vector.empty - val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) - waves1.api.waitForHeight(getBlockEpoch(elParentBlock.hash).get + 1) + val (payload, simulatedBlockHash, hitSource) = mkSimulatedBlock(elParentBlock, withdrawals, depositedTransactions) // Note: No transfers on the chain contract in this test case step("Register the simulated block on the chain contract") From b5c789fb6122cfab449a274f8fb8d163e3598ffa Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Tue, 11 Nov 2025 11:14:19 +0300 Subject: [PATCH 20/31] wip --- .github/workflows/check-pr.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 19246cb4..fe580d7c 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -37,9 +37,13 @@ jobs: run: | mkdir -p /home/runner/.solc/v0.8.29 wget https://binaries.soliditylang.org/linux-amd64/solc-linux-amd64-v0.8.29+commit.ab55807c -O /home/runner/.solc/v0.8.29/solc-static-linux - echo "/home/runner/.solc" >> $GITHUB_PATH ln -sf /home/runner/.solc/v0.8.29/solc-static-linux /home/runner/.solc/solc - - run: which solc || echo "Solc not found in PATH" + chmod +x /home/runner/.solc/solc + echo "/home/runner/.solc" >> $GITHUB_PATH + - run: | + echo $PATH + ls -la /home/runner/.solc + solc --version || echo "Solc not found in PATH" - uses: sbt/setup-sbt@v1 - name: Run tests run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=DEBUG --batch "scalafmtCheck;test;docker;consensus-client-it/test" From 1c0f422bc76b2dc97ff86cd72c9bc5530c70a99d Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Tue, 11 Nov 2025 11:47:22 +0300 Subject: [PATCH 21/31] wip --- .github/workflows/check-pr.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index fe580d7c..0880744b 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -25,25 +25,6 @@ jobs: java-version: '11' cache: 'sbt' - uses: foundry-rs/foundry-toolchain@v1 - - name: Cache solc - id: cache-solc - uses: actions/cache@v4 - with: - path: /home/runner/.solc - key: solc-v0.8.29 - restore-keys: solc- - - name: Get solc - if: ${{ steps.cache-solc.outputs.cache-hit != 'true' }} - run: | - mkdir -p /home/runner/.solc/v0.8.29 - wget https://binaries.soliditylang.org/linux-amd64/solc-linux-amd64-v0.8.29+commit.ab55807c -O /home/runner/.solc/v0.8.29/solc-static-linux - ln -sf /home/runner/.solc/v0.8.29/solc-static-linux /home/runner/.solc/solc - chmod +x /home/runner/.solc/solc - echo "/home/runner/.solc" >> $GITHUB_PATH - - run: | - echo $PATH - ls -la /home/runner/.solc - solc --version || echo "Solc not found in PATH" - uses: sbt/setup-sbt@v1 - name: Run tests run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=DEBUG --batch "scalafmtCheck;test;docker;consensus-client-it/test" From 04b6c46f6851930d7362fd685b9a4a1aaf86bb08 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Tue, 11 Nov 2025 13:32:02 +0300 Subject: [PATCH 22/31] wip --- .../com/wavesplatform/api/NodeHttpApi.scala | 2 +- .../EmptyEpochMinerEvictionTestSuite.scala | 31 +++++++++---------- .../test/scala/units/SyncingTestSuite.scala | 6 +++- 3 files changed, 21 insertions(+), 18 deletions(-) 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 86d584a8..d2ac1d24 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 @@ -251,7 +251,7 @@ class NodeHttpApi(apiUri: Uri, backend: SttpBackend[Identity, ?], apiKeyValue: S object NodeHttpApi { val DefaultApiKeyValue = "testapi" - case class BlockHeaderResponse(VRF: String) + case class BlockHeaderResponse(VRF: String, height: Int) object BlockHeaderResponse { implicit val blockHeaderResponseFormat: OFormat[BlockHeaderResponse] = Json.format[BlockHeaderResponse] } diff --git a/consensus-client-it/src/test/scala/units/EmptyEpochMinerEvictionTestSuite.scala b/consensus-client-it/src/test/scala/units/EmptyEpochMinerEvictionTestSuite.scala index 267755d3..e8ebf00d 100644 --- a/consensus-client-it/src/test/scala/units/EmptyEpochMinerEvictionTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/EmptyEpochMinerEvictionTestSuite.scala @@ -5,6 +5,9 @@ import com.wavesplatform.state.{Height, IntegerDataEntry, StringDataEntry} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.transaction.TxHelpers +import scala.concurrent.duration.* +import org.scalatest.concurrent.PatienceConfiguration.* + class EmptyEpochMinerEvictionTestSuite extends BaseDockerTestSuite { private val reporter = miner11Account private val idleMiner = miner21Account @@ -27,22 +30,18 @@ class EmptyEpochMinerEvictionTestSuite extends BaseDockerTestSuite { waves1.api.dataByKey(chainContractAddress, "allMiners").value shouldBe StringDataEntry("allMiners", s"${idleMiner.toAddress},${reporter.toAddress}") - val lastReportedHeight = Range - .inclusive(1, maxSkippedEpochCount) - .foldLeft(Height(0))((prevReportedHeight, _) => { - - // Wait for another idle miner epoch - waves1.api.waitForHeight(prevReportedHeight + 1) - chainContract.waitForMinerEpoch(idleMiner) - val lastWavesBlock = waves1.api.blockHeader(waves1.api.height()).value - val vrf = ByteStr.decodeBase58(lastWavesBlock.VRF).get - // Report empty epoch - val reportResult = waves1.api.broadcastAndWait(ChainContract.reportEmptyEpoch(reporter, vrf)) - reportResult.height - }) - - // Assertion: idle miner has been evicted - waves1.api.dataByKey(chainContractAddress, "allMiners").value shouldBe StringDataEntry("allMiners", s"${reporter.toAddress}") + val lastReportedHeight = eventually(Timeout(1.minute), Interval(2.seconds)) { + chainContract.waitForMinerEpoch(idleMiner) + + val lastWavesBlock = waves1.api.blockHeader(waves1.api.height()).value + + val vrf = ByteStr.decodeBase58(lastWavesBlock.VRF).get + // Report empty epoch + val h = waves1.api.broadcastAndWait(ChainContract.reportEmptyEpoch(reporter, vrf)).height + // Assertion: idle miner has been evicted + waves1.api.dataByKey(chainContractAddress, "allMiners").value shouldBe StringDataEntry("allMiners", s"${reporter.toAddress}") + h + } // Assertion: reporter started mining on the same epoch, in which the previous miner has been evicted val epochMeta = eventually { diff --git a/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala b/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala index 02c6b100..a5bb8b18 100644 --- a/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala @@ -10,6 +10,8 @@ import units.docker.EcContainer import java.math.BigInteger import scala.jdk.OptionConverters.RichOptional +import scala.concurrent.duration.DurationInt +import org.scalatest.concurrent.PatienceConfiguration.* class SyncingTestSuite extends BaseDockerTestSuite { private val elSender = elRichAccount1 @@ -42,7 +44,9 @@ class SyncingTestSuite extends BaseDockerTestSuite { waves1.api.rollback(Height(contractBlock.epoch - 1)) step("Wait for EL blocks") - while (ec1.web3j.ethBlockNumber().send().getBlockNumber.intValueExact() < elWaitHeight) Thread.sleep(3000) + eventually(Timeout(1.minute), Interval(10.seconds)) { + ec1.web3j.ethBlockNumber().send().getBlockNumber.intValueExact() should be >= elWaitHeight + } step("Waiting transactions 2 and 3 on EL") val txn2ReceiptAfterRb = waitForTxn(txn2Result) From 6fe89e06acea74db52b7e7a273411aaba28b0287 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Tue, 11 Nov 2025 15:29:04 +0300 Subject: [PATCH 23/31] wip --- .github/workflows/check-pr.yml | 2 +- .../src/test/scala/units/docker/DockerImages.scala | 2 +- .../src/test/scala/units/docker/OpGethContainer.scala | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 0880744b..f688d36d 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -27,7 +27,7 @@ jobs: - uses: foundry-rs/foundry-toolchain@v1 - uses: sbt/setup-sbt@v1 - name: Run tests - run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=DEBUG --batch "scalafmtCheck;test;docker;consensus-client-it/test" + run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=OFF --batch "scalafmtCheck;test;docker;consensus-client-it/test" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} - uses: scacap/action-surefire-report@5609ce4db72c09db044803b344a8968fd1f315da diff --git a/consensus-client-it/src/test/scala/units/docker/DockerImages.scala b/consensus-client-it/src/test/scala/units/docker/DockerImages.scala index 37dc1b8b..ec384e51 100644 --- a/consensus-client-it/src/test/scala/units/docker/DockerImages.scala +++ b/consensus-client-it/src/test/scala/units/docker/DockerImages.scala @@ -5,5 +5,5 @@ import units.test.TestEnvironment.WavesDockerImage object DockerImages { val WavesNode = parse(WavesDockerImage) - val OpGethExecutionClient = parse("ghcr.io/unitsnetwork/op-geth:1.6.3-race-detector") + val OpGethExecutionClient = parse("ghcr.io/unitsnetwork/op-geth:v1.6.3-racedetector") } diff --git a/consensus-client-it/src/test/scala/units/docker/OpGethContainer.scala b/consensus-client-it/src/test/scala/units/docker/OpGethContainer.scala index 75160577..3425fbd0 100644 --- a/consensus-client-it/src/test/scala/units/docker/OpGethContainer.scala +++ b/consensus-client-it/src/test/scala/units/docker/OpGethContainer.scala @@ -3,6 +3,7 @@ package units.docker import okhttp3.Interceptor import org.testcontainers.containers.BindMode import org.testcontainers.containers.Network.NetworkImpl +import org.testcontainers.images.PullPolicy import org.web3j.protocol.Web3j import org.web3j.protocol.http.HttpService import pdi.jwt.{JwtAlgorithm, JwtClaim, JwtJson} @@ -20,6 +21,7 @@ class OpGethContainer(network: NetworkImpl, number: Int, ip: String)(implicit ht extends EcContainer(number) { protected override val container = new GenericContainer(DockerImages.OpGethExecutionClient) + .withImagePullPolicy(PullPolicy.alwaysPull()) .withNetwork(network) .withExposedPorts(RpcPort, EnginePort) .withEnv("NODE_NUMBER", number.toString) From 034fcbc084c2fe1fb1f477af8cf8c56d66ab5b5f Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Tue, 11 Nov 2025 16:35:24 +0300 Subject: [PATCH 24/31] wip --- .github/workflows/check-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index f688d36d..7242520f 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -27,7 +27,7 @@ jobs: - uses: foundry-rs/foundry-toolchain@v1 - uses: sbt/setup-sbt@v1 - name: Run tests - run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=OFF --batch "scalafmtCheck;test;docker;consensus-client-it/test" + run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=OFF --batch "scalafmtCheck;docker;consensus-client-it/testOnly units.SyncingTestSuite" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} - uses: scacap/action-surefire-report@5609ce4db72c09db044803b344a8968fd1f315da From 69e1aed140ce864d9982260ae83ab6a8d9fcc56e Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Tue, 11 Nov 2025 19:46:43 +0300 Subject: [PATCH 25/31] wip --- .github/workflows/check-pr.yml | 2 +- .../scala/units/BaseDockerTestSuite.scala | 2 +- .../test/scala/units/SyncingTestSuite.scala | 28 +++++++++++++++++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index 7242520f..f688d36d 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -27,7 +27,7 @@ jobs: - uses: foundry-rs/foundry-toolchain@v1 - uses: sbt/setup-sbt@v1 - name: Run tests - run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=OFF --batch "scalafmtCheck;docker;consensus-client-it/testOnly units.SyncingTestSuite" + run: sbt -Dcc.it.max-parallel-suites=2 -Dlogback.test.level=OFF --batch "scalafmtCheck;test;docker;consensus-client-it/test" env: RUN_ID: ${{ github.head_ref }}-${{ github.run_number }}-${{ github.run_attempt }} - uses: scacap/action-surefire-report@5609ce4db72c09db044803b344a8968fd1f315da diff --git a/consensus-client-it/src/test/scala/units/BaseDockerTestSuite.scala b/consensus-client-it/src/test/scala/units/BaseDockerTestSuite.scala index a675bcb5..474b92a7 100644 --- a/consensus-client-it/src/test/scala/units/BaseDockerTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/BaseDockerTestSuite.scala @@ -46,7 +46,7 @@ trait BaseDockerTestSuite protected lazy val wavesGenesisConfigPath = generateWavesGenesisConfig() - private implicit val httpClientBackend: SttpBackend[Identity, Any] = new LoggingBackend(HttpClientSyncBackend()) + protected implicit val httpClientBackend: SttpBackend[Identity, Any] = new LoggingBackend(HttpClientSyncBackend()) /* * ipForNode(1) -> Ryuk diff --git a/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala b/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala index a5bb8b18..9408910c 100644 --- a/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala @@ -1,12 +1,12 @@ package units -import com.wavesplatform.state.Height +import com.wavesplatform.state.{Height, StringDataEntry} import com.wavesplatform.utils.EthEncoding import org.web3j.crypto.{RawTransaction, TransactionEncoder} import org.web3j.protocol.core.methods.response.{EthSendTransaction, TransactionReceipt} import org.web3j.tx.gas.DefaultGasProvider import org.web3j.utils.Convert -import units.docker.EcContainer +import units.docker.{EcContainer, Networks, WavesNodeContainer} import java.math.BigInteger import scala.jdk.OptionConverters.RichOptional @@ -17,6 +17,28 @@ class SyncingTestSuite extends BaseDockerTestSuite { private val elSender = elRichAccount1 private val amount = Convert.toWei("1", Convert.Unit.ETHER).toBigInteger + override protected lazy val waves1: WavesNodeContainer = new WavesNodeContainer( + network = network, + number = 1, + ip = Networks.ipForNode(3), + baseSeed = "devnet-2", + chainContractAddress = chainContractAddress, + ecEngineApiUrl = ec1.engineApiDockerUrl, + genesisConfigPath = wavesGenesisConfigPath + ) + + override def beforeAll(): Unit = { + super.beforeAll() + waves1.api.broadcast(ChainContract.join(miner21Account, miner21RewardAddress)) + + eventually { + waves1.api.dataByKey(chainContractAddress, "allMiners") match { + case Some(StringDataEntry(_, value)) => value.split(",").length shouldBe 2 + case _ => fail("not all miners have joined") + } + } + } + "L2-381 EL transactions appear after rollback" in { step("Send transaction 1") val txn1Result = sendTxn(0) @@ -44,7 +66,7 @@ class SyncingTestSuite extends BaseDockerTestSuite { waves1.api.rollback(Height(contractBlock.epoch - 1)) step("Wait for EL blocks") - eventually(Timeout(1.minute), Interval(10.seconds)) { + eventually(Timeout(2.minutes), Interval(10.seconds)) { ec1.web3j.ethBlockNumber().send().getBlockNumber.intValueExact() should be >= elWaitHeight } From ef582b3d420970d491779077abf36a8310363138 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Wed, 12 Nov 2025 10:58:08 +0300 Subject: [PATCH 26/31] wip --- .github/workflows/check-pr.yml | 2 +- .../src/test/scala/com/wavesplatform/api/NodeHttpApi.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index f688d36d..b5e89650 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -13,7 +13,7 @@ jobs: check-pr: name: Check PR runs-on: ubuntu-latest - timeout-minutes: 60 + timeout-minutes: 30 env: JAVA_OPTS: -Dfile.encoding=UTF-8 BRANCH_NAME: ${{ github.head_ref || github.ref_name }} 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 d2ac1d24..86d584a8 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 @@ -251,7 +251,7 @@ class NodeHttpApi(apiUri: Uri, backend: SttpBackend[Identity, ?], apiKeyValue: S object NodeHttpApi { val DefaultApiKeyValue = "testapi" - case class BlockHeaderResponse(VRF: String, height: Int) + case class BlockHeaderResponse(VRF: String) object BlockHeaderResponse { implicit val blockHeaderResponseFormat: OFormat[BlockHeaderResponse] = Json.format[BlockHeaderResponse] } From 8fbda9e65531b240ba6406cea0aec5693559ff76 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Wed, 12 Nov 2025 14:04:02 +0300 Subject: [PATCH 27/31] wip --- .github/workflows/check-pr.yml | 21 +++++++++++++++++++++ local-network/deploy/Dockerfile | 4 ---- local-network/deploy/deploy.py | 2 +- local-network/deploy/pyproject.toml | 2 +- local-network/restart.sh | 1 + 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index b5e89650..c677ed56 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -44,3 +44,24 @@ jobs: path: consensus-client-it/target/test-logs if-no-files-found: warn retention-days: 14 + + local-network: + name: Run Local Network tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + cache: 'sbt' + - uses: foundry-rs/foundry-toolchain@v1 + - uses: sbt/setup-sbt@v1 + - run: | + sbt --batch docker + cd local-network + ./restart.sh + env: + COMPOSE_PROFILES: tests diff --git a/local-network/deploy/Dockerfile b/local-network/deploy/Dockerfile index 5d237a86..9beecec9 100644 --- a/local-network/deploy/Dockerfile +++ b/local-network/deploy/Dockerfile @@ -8,8 +8,4 @@ RUN curl -L https://foundry.paradigm.xyz | bash && foundryup COPY pyproject.toml ./ RUN pip install --no-cache-dir . -# 0.8.29 is not supported on Apple ARM, see https://github.com/foundry-rs/foundry/issues/6665#issuecomment-2101885706 -# So we install this manually -RUN solc-select use 0.8.29 --always-install - CMD ["/bin/bash", "run.sh"] diff --git a/local-network/deploy/deploy.py b/local-network/deploy/deploy.py index 5d25c94e..ba7a6972 100755 --- a/local-network/deploy/deploy.py +++ b/local-network/deploy/deploy.py @@ -81,7 +81,7 @@ atomic_amount_for_each * cl_poor_accounts_number, reissuable=True, txFee=500_000, - ) + )["id"] waves.wait_for_approval(log, reissue_txn_id) log.info("Additional tokens issued") diff --git a/local-network/deploy/pyproject.toml b/local-network/deploy/pyproject.toml index bb16f36d..0a132749 100644 --- a/local-network/deploy/pyproject.toml +++ b/local-network/deploy/pyproject.toml @@ -8,7 +8,7 @@ version = "0.1" description = "Scripts and tests for a locally deployed Unit network" dependencies = [ "solc-select", - "units-network @ git+https://github.com/UnitsNetwork/examples.git", + "units-network @ git+https://github.com/UnitsNetwork/examples.git@block-delay-on-contract", ] readme = "README.md" requires-python = ">=3.9" diff --git a/local-network/restart.sh b/local-network/restart.sh index f2b9ed8b..2523beb1 100755 --- a/local-network/restart.sh +++ b/local-network/restart.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -eu DIR="$(cd "$(dirname "$0")" && pwd)" cd "${DIR}" || exit From b25323bd2d62f307943e716d62009fc84edeb9d1 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 13 Nov 2025 13:43:44 +0300 Subject: [PATCH 28/31] wip --- local-network/deploy/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local-network/deploy/pyproject.toml b/local-network/deploy/pyproject.toml index 0a132749..bb16f36d 100644 --- a/local-network/deploy/pyproject.toml +++ b/local-network/deploy/pyproject.toml @@ -8,7 +8,7 @@ version = "0.1" description = "Scripts and tests for a locally deployed Unit network" dependencies = [ "solc-select", - "units-network @ git+https://github.com/UnitsNetwork/examples.git@block-delay-on-contract", + "units-network @ git+https://github.com/UnitsNetwork/examples.git", ] readme = "README.md" requires-python = ">=3.9" From e5328c12e33e68474e2cfc441813c512f6937b5b Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Mon, 17 Nov 2025 09:54:56 +0300 Subject: [PATCH 29/31] wip --- .github/workflows/publish-docker-image.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml index 0074853f..4ad999d7 100644 --- a/.github/workflows/publish-docker-image.yml +++ b/.github/workflows/publish-docker-image.yml @@ -25,6 +25,8 @@ jobs: id-token: write steps: - uses: actions/checkout@v4 + - uses: proudust/gh-describe@70f72d4f6304ea053cf5a3d71c36211d5acc0c73 + id: ghd - uses: actions/setup-java@v4 with: distribution: 'temurin' @@ -38,8 +40,9 @@ jobs: echo type=sha echo EOF } >> "$GITHUB_OUTPUT" + echo "cc-version=$(echo ${{ steps.ghd.outputs.describe }} | cut -c 2-)" >> "$GITHUB_OUTPUT" id: tag-list - - run: sbt --batch buildTarballsForDocker + - run: sbt -Dproject.version=${{ steps.tag-list.outputs.cc-version }} --batch buildTarballsForDocker - uses: docker/login-action@v3 with: registry: ghcr.io From 5709160e628d8f6db21585442fc58720e5eb5a3b Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Wed, 19 Nov 2025 13:29:04 +0300 Subject: [PATCH 30/31] fixed mining scheduler --- src/main/scala/units/ELUpdater.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/units/ELUpdater.scala b/src/main/scala/units/ELUpdater.scala index c32bdf5a..3c7b421a 100644 --- a/src/main/scala/units/ELUpdater.scala +++ b/src/main/scala/units/ELUpdater.scala @@ -359,9 +359,9 @@ class ELUpdater( chainContractOptions: ChainContractOptions ): Unit = { def waitForRefApprovalOnCl: Option[FiniteDuration] = { - val timestampAheadTime = (timestamp - time.correctedTime() / 1000).max(0) + val timestampAheadTime = (timestamp * 1000 - time.correctedTime()).max(0) if (timestampAheadTime > 0) { - Some(timestampAheadTime.seconds) + Some(timestampAheadTime.millis) } else if (!chainContractClient.blockExists(referenceHash)) { Some(WaitForReferenceConfirmInterval) } else None @@ -476,7 +476,7 @@ class ELUpdater( } // TODO: See a comment about prepareAndApplyPayload call above - scheduler.scheduleOnceLabeled("forgeSecond", (nextBlockUnixTs - time.correctedTime() / 1000).min(1).seconds)( + scheduler.scheduleOnceLabeled("forgeSecond", (nextBlockUnixTs * 1000 - time.correctedTime()).min(200).millis)( tryToForgeNextBlock( payloadOrId = nextMiningData.payload, referenceHash = ecBlock.hash, From 85a2b4250d8873e9a6a7bfc7188fdbea856c9455 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Wed, 19 Nov 2025 15:57:01 +0300 Subject: [PATCH 31/31] update to latest node snapshot --- .github/workflows/check-pr.yml | 1 + build.sbt | 2 +- .../com/wavesplatform/api/NodeHttpApi.scala | 10 ++-- .../scala/units/AssetRegistryTestSuite.scala | 4 +- ...veTokenTransfersViaDepositsTestSuite.scala | 2 +- .../scala/units/ManyTransfersTestSuite.scala | 2 +- ...ultipleTransfersViaDepositsTestSuite.scala | 2 +- .../test/scala/units/SyncingTestSuite.scala | 2 +- .../validation/AssetValidTestSuite.scala | 17 +++--- .../validation/BaseBlockValidationSuite.scala | 2 +- .../validation/NativeValidTestSuite.scala | 17 +++--- .../validation/NoTransfersTestSuite.scala | 17 +++--- .../client/HttpChainContractClient.scala | 6 +- src/main/scala/units/ELUpdater.scala | 20 +++---- .../client/contract/ChainContractClient.scala | 59 ++++++++++--------- .../contract/ChainContractOptions.scala | 15 ++--- .../units/client/contract/ContractBlock.scala | 3 +- .../scala/units/el/DepositedTransaction.scala | 3 +- .../scala/units/C2ETransfersTestSuite.scala | 8 +-- src/test/scala/units/TestSettings.scala | 3 +- .../HasConsensusLayerDappTxHelpers.scala | 10 ++-- 21 files changed, 103 insertions(+), 102 deletions(-) diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index c677ed56..2f780ff3 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -47,6 +47,7 @@ jobs: local-network: name: Run Local Network tests + timeout-minutes: 10 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/build.sbt b/build.sbt index 4f8fc9cd..0358af1e 100644 --- a/build.sbt +++ b/build.sbt @@ -9,7 +9,7 @@ git.uncommittedSignifier := Some("DIRTY") inScope(Global)( Seq( onChangedBuildSource := ReloadOnSourceChanges, - scalaVersion := "3.7.3", + scalaVersion := "3.7.4", organization := "network.units", organizationName := "Units Network", resolvers ++= Seq(Resolver.sonatypeCentralSnapshots, Resolver.mavenLocal), 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 86d584a8..0e279a47 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 @@ -26,7 +26,7 @@ class NodeHttpApi(apiUri: Uri, backend: SttpBackend[Identity, ?], apiKeyValue: S extends IntegrationTestEventually with Matchers with ScorexLogging { - def blockHeader(atHeight: Int)(implicit loggingOptions: LoggingOptions = LoggingOptions()): Option[BlockHeaderResponse] = { + def blockHeader(atHeight: Height)(implicit loggingOptions: LoggingOptions = LoggingOptions()): Option[BlockHeaderResponse] = { if (loggingOptions.logRequest) log.debug(s"${loggingOptions.prefix} blockHeader($atHeight)") basicRequest .get(uri"$apiUri/blocks/headers/at/$atHeight") @@ -45,7 +45,7 @@ class NodeHttpApi(apiUri: Uri, backend: SttpBackend[Identity, ?], apiKeyValue: S } } - def waitForHeight(atLeast: Int)(implicit loggingOptions: LoggingOptions = LoggingOptions()): Height = { + def waitForHeight(atLeast: Height)(implicit loggingOptions: LoggingOptions = LoggingOptions()): Height = { if (loggingOptions.logCall) log.debug(s"${loggingOptions.prefix} waitForHeight($atLeast)") val subsequentLoggingOptions = loggingOptions.copy(logCall = false, logResult = false, logRequest = false) val currHeight = height()(using subsequentLoggingOptions) @@ -258,7 +258,8 @@ object NodeHttpApi { case class HeightResponse(height: Height) object HeightResponse { - implicit val heightResponseFormat: OFormat[HeightResponse] = Json.format[HeightResponse] + given Reads[Height] = Reads.IntReads.map(Height.apply) + given OFormat[HeightResponse] = Json.format[HeightResponse] } case class BroadcastResponse(id: String) @@ -268,7 +269,8 @@ object NodeHttpApi { case class TransactionInfoResponse(height: Height, applicationStatus: String) object TransactionInfoResponse { - implicit val transactionInfoResponseFormat: OFormat[TransactionInfoResponse] = Json.format[TransactionInfoResponse] + given Reads[Height] = Reads.IntReads.map(Height.apply) + given OFormat[TransactionInfoResponse] = Json.format[TransactionInfoResponse] } case class BalanceResponse(balance: Long) diff --git a/consensus-client-it/src/test/scala/units/AssetRegistryTestSuite.scala b/consensus-client-it/src/test/scala/units/AssetRegistryTestSuite.scala index c5303137..321b09d7 100644 --- a/consensus-client-it/src/test/scala/units/AssetRegistryTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/AssetRegistryTestSuite.scala @@ -1,5 +1,7 @@ package units +import com.wavesplatform.state.Height + class AssetRegistryTestSuite extends BaseDockerTestSuite { private val clRecipient = clRichAccount1 private val elSender = elRichAccount1 @@ -7,7 +9,7 @@ class AssetRegistryTestSuite extends BaseDockerTestSuite { private val userAmount = 1 private val elAmount = UnitsConvert.toAtomic(userAmount, 18) - private var activationEpoch = 0 + private var activationEpoch = Height(0) "WAVES and issued asset are not registered before activation" in { standardBridge.isRegistered(TErc20Address, ignoreExceptions = true) shouldBe false diff --git a/consensus-client-it/src/test/scala/units/C2ENativeTokenTransfersViaDepositsTestSuite.scala b/consensus-client-it/src/test/scala/units/C2ENativeTokenTransfersViaDepositsTestSuite.scala index f04550ce..ad15f888 100644 --- a/consensus-client-it/src/test/scala/units/C2ENativeTokenTransfersViaDepositsTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/C2ENativeTokenTransfersViaDepositsTestSuite.scala @@ -57,7 +57,7 @@ class C2ENativeTokenTransfersViaDepositsTestSuite extends BaseDockerTestSuite { waves1.api.broadcastAndWait( TxHelpers.dataEntry( chainContractAccount, - IntegerDataEntry("strictC2ETransfersActivationEpoch", activationEpoch) + IntegerDataEntry("strictC2ETransfersActivationEpoch", activationEpoch.toInt) ) ) diff --git a/consensus-client-it/src/test/scala/units/ManyTransfersTestSuite.scala b/consensus-client-it/src/test/scala/units/ManyTransfersTestSuite.scala index b0e736ae..175021d0 100644 --- a/consensus-client-it/src/test/scala/units/ManyTransfersTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/ManyTransfersTestSuite.scala @@ -183,7 +183,7 @@ class ManyTransfersTestSuite extends BaseDockerTestSuite { waves1.api.broadcastAndWait( TxHelpers.dataEntry( chainContractAccount, - IntegerDataEntry("strictC2ETransfersActivationEpoch", activationEpoch) + IntegerDataEntry("strictC2ETransfersActivationEpoch", activationEpoch.toInt) ) ) diff --git a/consensus-client-it/src/test/scala/units/MultipleTransfersViaDepositsTestSuite.scala b/consensus-client-it/src/test/scala/units/MultipleTransfersViaDepositsTestSuite.scala index 0c86c5f7..9138bed9 100644 --- a/consensus-client-it/src/test/scala/units/MultipleTransfersViaDepositsTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/MultipleTransfersViaDepositsTestSuite.scala @@ -196,7 +196,7 @@ class MultipleTransfersViaDepositsTestSuite extends BaseDockerTestSuite { waves1.api.broadcastAndWait( TxHelpers.dataEntry( chainContractAccount, - IntegerDataEntry("strictC2ETransfersActivationEpoch", activationEpoch) + IntegerDataEntry("strictC2ETransfersActivationEpoch", activationEpoch.toInt) ) ) diff --git a/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala b/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala index 9408910c..58b9c107 100644 --- a/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/SyncingTestSuite.scala @@ -63,7 +63,7 @@ class SyncingTestSuite extends BaseDockerTestSuite { step("Rollback CL") val elWaitHeight = ec1.web3j.ethBlockNumber().send().getBlockNumber.intValueExact() + 1 - waves1.api.rollback(Height(contractBlock.epoch - 1)) + waves1.api.rollback(contractBlock.epoch - 1) step("Wait for EL blocks") eventually(Timeout(2.minutes), Interval(10.seconds)) { diff --git a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala index e55c8f5f..e707ad3f 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/AssetValidTestSuite.scala @@ -6,12 +6,15 @@ import com.wavesplatform.common.utils.EitherExt2.explicitGet import com.wavesplatform.lang.v1.compiler.Terms import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.smart.InvokeScriptTransaction +import org.scalatest.concurrent.PatienceConfiguration.{Interval, Timeout} import units.* import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex import units.client.engine.model.EcBlock import units.el.* import units.eth.EthAddress +import scala.concurrent.duration.* + class AssetValidTestSuite extends BaseBlockValidationSuite { "Valid block: asset token, correct transfer" in { val balanceBefore = terc20.getBalance(elRecipient) @@ -67,21 +70,15 @@ class AssetValidTestSuite extends BaseBlockValidationSuite { NetworkL2Block.signed(payload, actingMiner.privateKey).explicitGet() ) - step("Assertion: Block exists on EC1") - eventually { - ec1.engineApi - .getBlockByHash(simulatedBlockHash) - .explicitGet() - .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) + step("Assertion: EL height grows") + eventually(Timeout(30.seconds), Interval(2.seconds)) { + val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() + elBlockAfter.hash shouldBe simulatedBlockHash } step("Assertion: Deposited transaction changes balances") val balanceAfter = terc20.getBalance(elRecipient) balanceAfter.longValue shouldBe (balanceBefore.longValue + elAssetTokenAmount.longValue) - - step("Assertion: EL height grows") - val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.hash shouldBe simulatedBlockHash } override def beforeAll(): Unit = setupForAssetTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala index 780db422..fdb2ea28 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/BaseBlockValidationSuite.scala @@ -123,7 +123,7 @@ trait BaseBlockValidationSuite extends BaseDockerTestSuite { waves1.api.broadcastAndWait( TxHelpers.dataEntry( chainContractAccount, - IntegerDataEntry("strictC2ETransfersActivationEpoch", activationEpoch) + IntegerDataEntry("strictC2ETransfersActivationEpoch", activationEpoch.toInt) ) ) diff --git a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala index 3aacb212..8da260ba 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NativeValidTestSuite.scala @@ -6,6 +6,7 @@ import com.wavesplatform.common.utils.EitherExt2.explicitGet import com.wavesplatform.lang.v1.compiler.Terms import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.smart.InvokeScriptTransaction +import org.scalatest.concurrent.PatienceConfiguration.{Interval, Timeout} import org.web3j.protocol.core.DefaultBlockParameterName import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex import units.client.engine.model.EcBlock @@ -13,6 +14,8 @@ import units.el.* import units.eth.EthAddress import units.{BlockHash, NetworkL2Block, TestNetworkClient} +import scala.concurrent.duration.* + class NativeValidTestSuite extends BaseBlockValidationSuite { "Valid block: native token, correct transfer" in { val ethBalanceBefore = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance @@ -67,21 +70,15 @@ class NativeValidTestSuite extends BaseBlockValidationSuite { NetworkL2Block.signed(payload, actingMiner.privateKey).explicitGet() ) - step("Assertion: Block exists on EC1") - eventually { - ec1.engineApi - .getBlockByHash(simulatedBlockHash) - .explicitGet() - .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) + step("Assertion: EL height grows") + eventually(Timeout(30.seconds), Interval(2.seconds)) { + val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() + elBlockAfter.hash shouldBe simulatedBlockHash } step("Assertion: Deposited transaction changes balances") val ethBalanceAfter = ec1.web3j.ethGetBalance(elRecipient.toString, DefaultBlockParameterName.LATEST).send().getBalance ethBalanceBefore.longValue shouldBe ethBalanceAfter.longValue - elNativeTokenAmount.longValue - - step("Assertion: EL height grows") - val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.hash shouldBe simulatedBlockHash } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala index 58f243ba..656d8d7b 100644 --- a/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/block/validation/NoTransfersTestSuite.scala @@ -5,10 +5,13 @@ import com.wavesplatform.common.utils.EitherExt2.explicitGet import com.wavesplatform.lang.v1.compiler.Terms import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.smart.InvokeScriptTransaction +import org.scalatest.concurrent.PatienceConfiguration.{Interval, Timeout} import units.client.contract.HasConsensusLayerDappTxHelpers.EmptyE2CTransfersRootHashHex import units.client.engine.model.EcBlock import units.{BlockHash, NetworkL2Block, TestNetworkClient} +import scala.concurrent.duration.* + class NoTransfersTestSuite extends BaseBlockValidationSuite { "Valid block: no transfers" in { val elParentBlock: EcBlock = getMainChainLastBlock @@ -45,17 +48,11 @@ class NoTransfersTestSuite extends BaseBlockValidationSuite { NetworkL2Block.signed(payload, actingMiner.privateKey).explicitGet() ) - step("Assertion: Block exists on EC1") - eventually { - ec1.engineApi - .getBlockByHash(simulatedBlockHash) - .explicitGet() - .getOrElse(fail(s"Block $simulatedBlockHash was not found on EC1")) - } - step("Assertion: EL height grows") - val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() - elBlockAfter.hash shouldBe simulatedBlockHash + eventually(Timeout(30.seconds), Interval(2.seconds)) { + val elBlockAfter = ec1.engineApi.getLastExecutionBlock().explicitGet() + elBlockAfter.hash shouldBe simulatedBlockHash + } } override def beforeAll(): Unit = setupForNativeTokenTransfer() diff --git a/consensus-client-it/src/test/scala/units/client/HttpChainContractClient.scala b/consensus-client-it/src/test/scala/units/client/HttpChainContractClient.scala index 05003f48..92db866c 100644 --- a/consensus-client-it/src/test/scala/units/client/HttpChainContractClient.scala +++ b/consensus-client-it/src/test/scala/units/client/HttpChainContractClient.scala @@ -5,7 +5,7 @@ import com.wavesplatform.account.{Address, KeyPair} import com.wavesplatform.api.LoggingBackend.LoggingOptions import com.wavesplatform.api.NodeHttpApi import com.wavesplatform.common.state.ByteStr -import com.wavesplatform.state.DataEntry +import com.wavesplatform.state.{DataEntry, Height} import com.wavesplatform.transaction.Asset.IssuedAsset import com.wavesplatform.utils.ScorexLogging import org.scalatest.OptionValues @@ -29,7 +29,7 @@ class HttpChainContractClient(api: NodeHttpApi, override val contract: Address) private val fiveBlocks = WavesNodeContainer.MaxBlockDelay * 5 lazy val nativeTokenId: IssuedAsset = IssuedAsset(ByteStr.decodeBase58(getStringData("tokenId").getOrElse(fail("Call setup first"))).get) - def getEpochFirstBlock(epochNumber: Int): Option[ContractBlock] = + def getEpochFirstBlock(epochNumber: Height): Option[ContractBlock] = getEpochMeta(epochNumber).flatMap { epochData => getEpochFirstBlock(epochData.lastBlockHash) } @@ -64,7 +64,7 @@ class HttpChainContractClient(api: NodeHttpApi, override val contract: Address) } // This is different from blockchain.height, because we wait this from a contract block - def waitForEpoch(atLeast: Int, chainId: Long = DefaultMainChainId): Unit = { + def waitForEpoch(atLeast: Height, chainId: Long = DefaultMainChainId): Unit = { log.debug(s"waitForEpoch($atLeast)") eventually { val lastBlock = getLastBlockMeta(chainId).value diff --git a/src/main/scala/units/ELUpdater.scala b/src/main/scala/units/ELUpdater.scala index 3c7b421a..c958808c 100644 --- a/src/main/scala/units/ELUpdater.scala +++ b/src/main/scala/units/ELUpdater.scala @@ -11,7 +11,7 @@ import com.wavesplatform.lang.v1.compiler.Terms.FUNCTION_CALL import com.wavesplatform.network.ChannelGroupExt import com.wavesplatform.state.diffs.FeeValidation.{FeeConstants, FeeUnit, ScriptExtraFee} import com.wavesplatform.state.diffs.TransactionDiffer.TransactionValidationError -import com.wavesplatform.state.{Blockchain, BooleanDataEntry} +import com.wavesplatform.state.{Blockchain, BooleanDataEntry, Height} import com.wavesplatform.transaction.* import com.wavesplatform.transaction.TxValidationError.InvokeRejectError import com.wavesplatform.transaction.smart.InvokeScriptTransaction @@ -369,7 +369,7 @@ class ELUpdater( state match { case origState @ Working(epochInfo = epochInfo, chainStatus = m: Mining) - if epochInfo.number == blockchain.height && m.currentPayload == payloadOrId => + if epochInfo.number == Height(blockchain.height) && m.currentPayload == payloadOrId => waitForRefApprovalOnCl match { case Some(waitingTime) => scheduler.scheduleOnceLabeled("waitForApproval", waitingTime) { @@ -609,7 +609,7 @@ class ELUpdater( case FollowingChain(_, Some(nextExpectedBlock)) => logger.debug(s"Waiting for block $nextExpectedBlock from peers") scheduler.scheduleOnceLabeled("nextCheck", WaitRequestedBlockTimeout) { - if (blockchain.height == prevState.epochInfo.number) { + if (Height(blockchain.height) == prevState.epochInfo.number) { check(missedBlock) } } @@ -626,7 +626,7 @@ class ELUpdater( prevState.chainStatus.nextExpectedBlock match { case Some(missedBlock) => scheduler.scheduleOnceLabeled("firstCheck", WaitRequestedBlockTimeout) { - if (blockchain.height == prevState.epochInfo.number) { + if (Height(blockchain.height) == prevState.epochInfo.number) { check(missedBlock) } } @@ -697,7 +697,7 @@ class ELUpdater( lazy val errorOrMinerChanged = newEpochInfo.forall(_.miner != prevState.epochInfo.miner) if ( - blockchain.height != prevState.epochInfo.number + Height(blockchain.height) != prevState.epochInfo.number || !blockchain.vrf(blockchain.height).contains(prevState.epochInfo.hitSource) || errorOrMinerChanged ) { @@ -994,8 +994,8 @@ class ELUpdater( logger.debug(s"Unexpected state on sync: $other") }) - private def validateRandao(block: EcBlock, epochNumber: Int): Result[Unit] = - blockchain.vrf(epochNumber) match { + private def validateRandao(block: EcBlock, epochNumber: Height): Result[Unit] = + blockchain.vrf(epochNumber.toInt) match { case None => s"VRF of $epochNumber epoch is empty".asLeft case Some(vrf) => val expectedPrevRandao = calculateRandao(vrf, block.parentHash) @@ -1020,7 +1020,7 @@ class ELUpdater( } } yield () - private def validateTimestamp(newNetworkBlock: NetworkL2Block, parentEcBlock: EcBlock, epoch: Int): Result[Unit] = { + private def validateTimestamp(newNetworkBlock: NetworkL2Block, parentEcBlock: EcBlock, epoch: Height): Result[Unit] = { val minAppendTs = parentEcBlock.timestamp + chainContractClient.getOptions.blockDelayInSeconds.valueAtEpoch(epoch) Either.raiseUnless(newNetworkBlock.timestamp >= minAppendTs) { s"timestamp (${newNetworkBlock.timestamp}) of appended block must be greater or equal $minAppendTs, Δ${minAppendTs - newNetworkBlock.timestamp}s" @@ -1395,7 +1395,7 @@ class ELUpdater( } yield Some(lastElWithdrawalIndex) private def prepareTransactions( - epochNumber: Int, + epochNumber: Height, chainContractOptions: ChainContractOptions, startAssetRegistryIndex: Int, endAssetRegistryIndexExcl: Int, @@ -1720,7 +1720,7 @@ object ELUpdater { val WaitRequestedBlockTimeout: FiniteDuration = 2.seconds private val MaxTransfersInLogs = 5 // Cut huge logs - case class EpochInfo(number: Int, miner: Address, rewardAddress: EthAddress, hitSource: ByteStr, prevEpochLastBlockHash: Option[BlockHash]) + case class EpochInfo(number: Height, miner: Address, rewardAddress: EthAddress, hitSource: ByteStr, prevEpochLastBlockHash: Option[BlockHash]) sealed trait State object State { diff --git a/src/main/scala/units/client/contract/ChainContractClient.scala b/src/main/scala/units/client/contract/ChainContractClient.scala index 1d8e1aa7..a960d0a6 100644 --- a/src/main/scala/units/client/contract/ChainContractClient.scala +++ b/src/main/scala/units/client/contract/ChainContractClient.scala @@ -6,7 +6,7 @@ import com.wavesplatform.common.state.ByteStr import com.wavesplatform.consensus.{FairPoSCalculator, PoSCalculator} import com.wavesplatform.lang.Global import com.wavesplatform.serialization.ByteBufferOps -import com.wavesplatform.state.{BinaryDataEntry, Blockchain, BooleanDataEntry, DataEntry, EmptyDataEntry, IntegerDataEntry, StringDataEntry} +import com.wavesplatform.state.* import com.wavesplatform.transaction.Asset import org.web3j.utils.Numeric.cleanHexPrefix import units.ELUpdater.EpochInfo @@ -70,7 +70,7 @@ trait ChainContractClient { val bb = ByteBuffer.wrap(blockMeta.arr) try { val chainHeight = bb.getLong() - val epoch = bb.getLong().toInt // blockMeta is set up in a chain contract and RIDE numbers are Longs + val epoch = Height(bb.getLong().toInt) // blockMeta is set up in a chain contract and RIDE numbers are Longs val parentHash = BlockHash(bb.getByteArray(BlockHashBytesSize)) val chainId = if (bb.remaining() >= 8) bb.getLong() else DefaultMainChainId @@ -124,12 +124,12 @@ trait ChainContractClient { def getMainChainId: Long = getMainChainIdOpt.getOrElse(DefaultMainChainId) - def getEpochMeta(epoch: Int): Option[EpochContractMeta] = getStringData(f"epoch_$epoch%08d").flatMap { s => + def getEpochMeta(epoch: Height): Option[EpochContractMeta] = getStringData(f"epoch_$epoch%08d").flatMap { s => val items = s.split(Sep) if (items.length == 3) for { a <- Address.fromString(items(0)).toOption e <- items(1).toIntOption - } yield EpochContractMeta(a, e, BlockHash(s"0x${items(2)}")) + } yield EpochContractMeta(a, Height(e), BlockHash(s"0x${items(2)}")) else None } @@ -179,10 +179,10 @@ trait ChainContractClient { } else None } - private def calculateEpochMiner(epochNumber: Int, blockchain: Blockchain): Either[String, Address] = + private def calculateEpochMiner(epochNumber: Height, blockchain: Blockchain): Either[String, Address] = for { - header <- blockchain.blockHeader(epochNumber).toRight(s"No header at height $epochNumber") - hitSource <- blockchain.hitSource(epochNumber).toRight(s"No VRF value at height $epochNumber") + header <- blockchain.blockHeader(epochNumber.toInt).toRight(s"No header at height $epochNumber") + hitSource <- blockchain.hitSource(epochNumber.toInt).toRight(s"No VRF value at height $epochNumber") miner <- getAllActualMiners .flatMap(miner => calculateMinerDelay(hitSource.arr, header.header.baseTarget, miner, blockchain)) .minByOption(_._2) @@ -191,10 +191,10 @@ trait ChainContractClient { } yield miner def calculateEpochInfo(blockchain: Blockchain): Either[String, EpochInfo] = { - val epochNumber = blockchain.height + val epochNumber = Height(blockchain.height) for { - _ <- blockchain.blockHeader(epochNumber).toRight(s"No header at epoch $epochNumber") - hitSource <- blockchain.hitSource(epochNumber).toRight(s"No hit source at epoch $epochNumber") + _ <- blockchain.blockHeader(epochNumber.toInt).toRight(s"No header at epoch $epochNumber") + hitSource <- blockchain.hitSource(epochNumber.toInt).toRight(s"No hit source at epoch $epochNumber") miner <- this.calculateEpochMiner(epochNumber, blockchain) rewardAddress <- this.getElRewardAddress(miner).toRight(s"No reward address for $miner") prevEpochLastBlockHash <- this.getPrevEpochLastBlockHash(epochNumber) @@ -215,18 +215,18 @@ trait ChainContractClient { def getOptions: ChainContractOptions = { val minerReward = extractData("minerReward") match { - case Some(IntegerDataEntry(value = reward)) => ValueAtEpoch(Gwei.ofRawGwei(0), Gwei.ofRawGwei(reward), 1) + case Some(IntegerDataEntry(value = reward)) => ValueAtEpoch(Gwei.ofRawGwei(0), Gwei.ofRawGwei(reward), Height(1)) case Some(StringDataEntry(value = rewards)) => val Array(oldReward, newReward, changeEpoch) = rewards.split(Sep) - ValueAtEpoch(Gwei.ofRawGwei(oldReward.toLong), Gwei.ofRawGwei(newReward.toLong), changeEpoch.toInt) + ValueAtEpoch(Gwei.ofRawGwei(oldReward.toLong), Gwei.ofRawGwei(newReward.toLong), Height(changeEpoch.toInt)) case _ => throw new IllegalStateException("minerReward is empty on contract") } val blockDelay = extractData("blockDelay") match { - case Some(IntegerDataEntry(value = delay)) => ValueAtEpoch(0, BigInt(delay).bigInteger.intValueExact(), 1) + case Some(IntegerDataEntry(value = delay)) => ValueAtEpoch(0, BigInt(delay).bigInteger.intValueExact(), Height(1)) case Some(StringDataEntry(value = delays)) => val Array(oldDelay, newDelay, changeEpoch) = delays.split(Sep) - ValueAtEpoch(oldDelay.toInt, newDelay.toInt, changeEpoch.toInt) + ValueAtEpoch(oldDelay.toInt, newDelay.toInt, Height(changeEpoch.toInt)) case _ => throw new IllegalStateException("blockDelay is empty on contract") } @@ -242,9 +242,10 @@ trait ChainContractClient { ) } - private def getAssetTransfersActivationEpoch: Long = getLongData("assetTransfersActivationEpoch").getOrElse(Long.MaxValue) + private def getActivationEpoch(key: String) = Height(getLongData(key).fold(Int.MaxValue)(v => BigInt(v).bigInteger.intValueExact())) - def getStrictC2ETransfersActivationEpoch: Long = getLongData("strictC2ETransfersActivationEpoch").getOrElse(Long.MaxValue) + private def getAssetTransfersActivationEpoch: Height = getActivationEpoch("assetTransfersActivationEpoch") + def getStrictC2ETransfersActivationEpoch: Height = getActivationEpoch("strictC2ETransfersActivationEpoch") private def getChainMeta(chainId: Long): Option[(Int, BlockHash)] = { val key = f"chain_$chainId%08d" @@ -296,13 +297,13 @@ trait ChainContractClient { // Native transfer, before strict transfers activation // {destElAddressHex with 0x}_{amount} case Array(EthAddress(destElAddress), NativeTransferAmount(amount)) => - ContractTransfer.NativeViaWithdrawal(atIndex, 0, destElAddress, amount) + ContractTransfer.NativeViaWithdrawal(atIndex, Height(0), destElAddress, amount) // Native transfer, after strict transfers activation // {epoch}_{destElAddressHex with 0x}_{fromClAddressHex with 0x}_{amount} case Array(Epoch(epoch), EthAddress(destElAddress), EthAddress(fromAddress), NativeTransferAmount(amount)) => - ContractTransfer.NativeViaDeposit(atIndex, epoch, fromAddress, destElAddress, amount) + ContractTransfer.NativeViaDeposit(atIndex, Height(epoch), fromAddress, destElAddress, amount) // Asset transfer, before strict transfers activation // {destElAddressHex with 0x}_{fromClAddressHex with 0x}_{amount}_{assetRegistryIndex} @@ -312,7 +313,7 @@ trait ChainContractClient { ContractTransfer.Asset( index = atIndex, - epoch = 0, + epoch = Height(0), from = fromAddress, to = destElAddress, amount = @@ -330,7 +331,7 @@ trait ChainContractClient { ContractTransfer.Asset( index = atIndex, - epoch = epoch, + epoch = Height(epoch), from = fromAddress, to = destElAddress, amount = @@ -367,10 +368,10 @@ trait ChainContractClient { .map(getRegisteredAssetData) .toList - private def getPrevEpochLastBlockHash(thisEpoch: Int): Either[String, Option[BlockHash]] = { + private def getPrevEpochLastBlockHash(thisEpoch: Height): Either[String, Option[BlockHash]] = { @tailrec - def loop(curEpochNumber: Int): Either[String, Option[BlockHash]] = { - if (curEpochNumber <= 0) { + def loop(curEpochNumber: Height): Either[String, Option[BlockHash]] = { + if (curEpochNumber <= Height(0)) { Left(s"Couldn't find previous epoch meta for epoch #$thisEpoch") } else { this.getEpochMeta(curEpochNumber) match { @@ -381,7 +382,7 @@ trait ChainContractClient { } this.getEpochMeta(thisEpoch) match { - case Some(epochMeta) if epochMeta.prevEpoch == 0 => + case Some(epochMeta) if epochMeta.prevEpoch == Height(0) => Right(None) case Some(epochMeta) => this @@ -477,17 +478,17 @@ object ChainContractClient { private class InconsistentContractData(message: String, cause: Throwable = null) extends IllegalStateException(s"Probably, you have to upgrade your client. $message", cause) - case class EpochContractMeta(miner: Address, prevEpoch: Int, lastBlockHash: BlockHash) + case class EpochContractMeta(miner: Address, prevEpoch: Height, lastBlockHash: BlockHash) enum ContractTransfer { val index: Long - val epoch: Int + val epoch: Height - case NativeViaWithdrawal(index: Long, epoch: Int, to: EthAddress, amount: Long) - case NativeViaDeposit(index: Long, epoch: Int, from: EthAddress, to: EthAddress, amount: Long) + case NativeViaWithdrawal(index: Long, epoch: Height, to: EthAddress, amount: Long) + case NativeViaDeposit(index: Long, epoch: Height, from: EthAddress, to: EthAddress, amount: Long) case Asset( index: Long, - epoch: Int, + epoch: Height, from: EthAddress, to: EthAddress, amount: EAmount, diff --git a/src/main/scala/units/client/contract/ChainContractOptions.scala b/src/main/scala/units/client/contract/ChainContractOptions.scala index 62b99d85..3cac8e01 100644 --- a/src/main/scala/units/client/contract/ChainContractOptions.scala +++ b/src/main/scala/units/client/contract/ChainContractOptions.scala @@ -1,6 +1,7 @@ package units.client.contract import com.wavesplatform.common.state.ByteStr +import com.wavesplatform.state.Height import units.BlockHash import units.client.contract.ContractFunction.* import units.eth.{EthAddress, Gwei} @@ -9,16 +10,16 @@ case class ChainContractOptions( miningReward: ValueAtEpoch[Gwei], elNativeBridgeAddress: EthAddress, elStandardBridgeAddress: Option[EthAddress], - assetTransfersActivationEpoch: Long, + assetTransfersActivationEpoch: Height, blockDelayInSeconds: ValueAtEpoch[Int] ) { - def bridgeAddresses(epoch: Int): List[EthAddress] = { + def bridgeAddresses(epoch: Height): List[EthAddress] = { val before = List(elNativeBridgeAddress) if (epoch < assetTransfersActivationEpoch) before else elStandardBridgeAddress.toList ::: before } - def startEpochChainFunction(epoch: Int, reference: BlockHash, vrf: ByteStr, chainInfo: Option[ChainInfo]): ContractFunction = + def startEpochChainFunction(epoch: Height, reference: BlockHash, vrf: ByteStr, chainInfo: Option[ChainInfo]): ContractFunction = chainInfo match { case Some(chainInfo) => if (chainInfo.isMain) ExtendMainChain(reference, vrf, versionOf(epoch)) @@ -28,12 +29,12 @@ case class ChainContractOptions( StartAltChain(reference, vrf, versionOf(epoch)) } - def appendFunction(epoch: Int, reference: BlockHash): AppendBlock = + def appendFunction(epoch: Height, reference: BlockHash): AppendBlock = AppendBlock(reference, versionOf(epoch)) - private def versionOf(epoch: Int): Int = if (epoch < assetTransfersActivationEpoch) 1 else 2 + private def versionOf(epoch: Height): Int = if (epoch < assetTransfersActivationEpoch) 1 else 2 } -case class ValueAtEpoch[A](oldValue: A, newValue: A, changeAtEpoch: Int) { - def valueAtEpoch(epoch: Int): A = if epoch < changeAtEpoch then oldValue else newValue +case class ValueAtEpoch[A](oldValue: A, newValue: A, changeAtEpoch: Height) { + def valueAtEpoch(epoch: Height): A = if epoch < changeAtEpoch then oldValue else newValue } diff --git a/src/main/scala/units/client/contract/ContractBlock.scala b/src/main/scala/units/client/contract/ContractBlock.scala index 530546b0..21688107 100644 --- a/src/main/scala/units/client/contract/ContractBlock.scala +++ b/src/main/scala/units/client/contract/ContractBlock.scala @@ -1,6 +1,7 @@ package units.client.contract import com.wavesplatform.common.merkle.Digest +import com.wavesplatform.state.Height import units.BlockHash import units.client.L2BlockLike import units.eth.EthAddress @@ -9,7 +10,7 @@ import units.util.HexBytesConverter.toHex case class ContractBlock( hash: BlockHash, parentHash: BlockHash, - epoch: Int, + epoch: Height, height: Long, minerRewardL2Address: EthAddress, chainId: Long, diff --git a/src/main/scala/units/el/DepositedTransaction.scala b/src/main/scala/units/el/DepositedTransaction.scala index bb137a53..297f7538 100644 --- a/src/main/scala/units/el/DepositedTransaction.scala +++ b/src/main/scala/units/el/DepositedTransaction.scala @@ -11,6 +11,7 @@ import units.eth.EthAddress import units.util.HexBytesConverter.* import java.math.BigInteger +import java.util /** @param sourceHash * Uniquely identifies the origin of the deposit @@ -65,7 +66,7 @@ case class DepositedTransaction( override def equals(obj: Any): Boolean = obj match { case that: DepositedTransaction => - this.sourceHash.sameElements(that.sourceHash) && + util.Arrays.equals(sourceHash, that.sourceHash) && this.from == that.from && this.to == that.to && this.mint == that.mint && diff --git a/src/test/scala/units/C2ETransfersTestSuite.scala b/src/test/scala/units/C2ETransfersTestSuite.scala index aa716dfe..879729b0 100644 --- a/src/test/scala/units/C2ETransfersTestSuite.scala +++ b/src/test/scala/units/C2ETransfersTestSuite.scala @@ -2,7 +2,7 @@ package units import com.wavesplatform.block.Block.BlockId import com.wavesplatform.db.WithState.AddrWithBalance -import com.wavesplatform.state.IntegerDataEntry +import com.wavesplatform.state.{Height, IntegerDataEntry} import com.wavesplatform.test.produce import com.wavesplatform.transaction.{Asset, TxHelpers} @@ -52,13 +52,13 @@ class C2ETransfersTestSuite extends BaseTestSuite { r should produce(s"Can't find in the registry: ${issueAssetTxn.id()}") } - "Can't register before activation" in withExtensionDomain(defaultSettings.copy(enableTokenTransfersEpoch = Int.MaxValue)) { d => + "Can't register before activation" in withExtensionDomain(defaultSettings.copy(enableTokenTransfersEpoch = Height(Int.MaxValue))) { d => d.appendMicroBlock(issueAssetTxn) val r = d.appendMicroBlockE(d.ChainContract.registerAsset(issueAsset, mkRandomEthAddress(), 8)) r should produce("Asset transfers must be activated") } - "Can't transfer WAVES before activation" in withExtensionDomain(defaultSettings.copy(enableTokenTransfersEpoch = Int.MaxValue)) { d => + "Can't transfer WAVES before activation" in withExtensionDomain(defaultSettings.copy(enableTokenTransfersEpoch = Height(Int.MaxValue))) { d => val r = d.appendMicroBlockE(d.ChainContract.transferUnsafe(transferSenderAccount, validTransferRecipient, Asset.Waves, 1_000_000)) r should produce("Asset transfers must be activated") } @@ -97,7 +97,7 @@ class C2ETransfersTestSuite extends BaseTestSuite { assetId: Option[Asset] = None, queueSize: Int = 0, register: Boolean = false - ): Either[Throwable, BlockId] = withExtensionDomain(defaultSettings.copy(enableTokenTransfersEpoch = if (register) 0 else Int.MaxValue)) { d => + ): Either[Throwable, BlockId] = withExtensionDomain(defaultSettings.copy(enableTokenTransfersEpoch = Height(if (register) 0 else Int.MaxValue))) { d => val amount = Long.MaxValue / 2 d.appendMicroBlock( issueAssetTxn, diff --git a/src/test/scala/units/TestSettings.scala b/src/test/scala/units/TestSettings.scala index 97b6cd65..42da68d5 100644 --- a/src/test/scala/units/TestSettings.scala +++ b/src/test/scala/units/TestSettings.scala @@ -4,6 +4,7 @@ import com.typesafe.config.ConfigFactory import com.wavesplatform.account.{Address, KeyPair, PrivateKey, SeedKeyPair} import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.settings.WavesSettings +import com.wavesplatform.state.Height import com.wavesplatform.test.{DomainPresets, NumericExt} import com.wavesplatform.transaction.utils.EthConverters.EthereumAddressExt import units.TestSettings.* @@ -16,7 +17,7 @@ case class TestSettings( daoRewardAccount: Option[KeyPair] = None, daoRewardAmount: Long = 0, blockDelayInSeconds: Int = 2, - enableTokenTransfersEpoch: Int = 0, + enableTokenTransfersEpoch: Height = Height(0), registerWwavesToken: Boolean = false // Almost never needed in unit tests, see TestEcClients, simulate ) { def finalAdditionalBalances: List[AddrWithBalance] = additionalBalances ++ diff --git a/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala b/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala index 9b0feb82..30bde978 100644 --- a/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala +++ b/src/test/scala/units/client/contract/HasConsensusLayerDappTxHelpers.scala @@ -7,7 +7,7 @@ import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2.explicitGet import com.wavesplatform.lang.v1.compiler.Terms import com.wavesplatform.lang.v1.compiler.Terms.{CONST_LONG, CONST_STRING} -import com.wavesplatform.state.{BooleanDataEntry, DataEntry, EmptyDataEntry, IntegerDataEntry, StringDataEntry} +import com.wavesplatform.state.{BooleanDataEntry, DataEntry, EmptyDataEntry, IntegerDataEntry, StringDataEntry, Height} import com.wavesplatform.test.NumericExt import com.wavesplatform.transaction.Asset.IssuedAsset import com.wavesplatform.transaction.smart.{InvokeScriptTransaction, SetScriptTransaction} @@ -75,20 +75,20 @@ trait HasConsensusLayerDappTxHelpers { invoker = invoker ) - def enableTokenTransfersWithWaves(standardBridge: EthAddress, wwaves: EthAddress, activationEpoch: Int): InvokeScriptTransaction = + def enableTokenTransfersWithWaves(standardBridge: EthAddress, wwaves: EthAddress, activationEpoch: Height): InvokeScriptTransaction = TxHelpers.invoke( chainContractAddress, Some("enableTokenTransfers"), - Seq(CONST_STRING(standardBridge.hexNoPrefix).explicitGet(), CONST_STRING(wwaves.hexNoPrefix).explicitGet(), CONST_LONG(activationEpoch)), + Seq(CONST_STRING(standardBridge.hexNoPrefix).explicitGet(), CONST_STRING(wwaves.hexNoPrefix).explicitGet(), CONST_LONG(activationEpoch.toInt)), invoker = chainContractAccount, fee = 0.009.waves ) - def enableTokenTransfers(standardBridge: EthAddress, activationEpoch: Int): DataTransaction = + def enableTokenTransfers(standardBridge: EthAddress, activationEpoch: Height): DataTransaction = TxHelpers.data( chainContractAccount, Seq( - IntegerDataEntry("assetTransfersActivationEpoch", activationEpoch), + IntegerDataEntry("assetTransfersActivationEpoch", activationEpoch.toInt), StringDataEntry("elStandardBridgeAddress", standardBridge.hex) ), fee = 0.009.waves