diff --git a/consensus-client-it/src/test/scala/units/network/BaseItTestSuite.scala b/consensus-client-it/src/test/scala/units/network/BaseItTestSuite.scala index ced811b6..ec290c1c 100644 --- a/consensus-client-it/src/test/scala/units/network/BaseItTestSuite.scala +++ b/consensus-client-it/src/test/scala/units/network/BaseItTestSuite.scala @@ -1,7 +1,8 @@ package units.network import com.google.common.primitives.{Bytes, Ints} -import com.wavesplatform.account.{Address, AddressScheme, SeedKeyPair} +import com.wavesplatform.account.{Address, AddressScheme, KeyPair, SeedKeyPair} +import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.crypto import com.wavesplatform.utils.ScorexLogging @@ -10,10 +11,14 @@ import org.scalatest.concurrent.Eventually import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers import org.scalatest.{BeforeAndAfterAll, EitherValues, OptionValues} +import units.client.contract.HasConsensusLayerDappTxHelpers +import units.client.engine.model.BlockNumber +import units.eth.{EthAddress, Gwei} import units.network.test.docker.{EcContainer, Networks, WavesNodeContainer} import units.test.CustomMatchers import java.nio.charset.StandardCharsets +import scala.concurrent.duration.DurationInt trait BaseItTestSuite extends AnyFreeSpec @@ -23,7 +28,14 @@ trait BaseItTestSuite with CustomMatchers with EitherValues with OptionValues - with Eventually { + with Eventually + with HasConsensusLayerDappTxHelpers { + override implicit val patienceConfig: PatienceConfig = PatienceConfig(timeout = 30.seconds, interval = 1.second) + + override val currentHitSource: ByteStr = ByteStr.empty + override val chainContractAccount: KeyPair = mkKeyPair("devnet-1", 2) + protected val rewardAmount: Gwei = Gwei.ofRawGwei(2_000_000_000L) + protected lazy val network = Networks.network protected lazy val ec1: EcContainer = new EcContainer(network, "ec-1", Networks.ipForNode(2)) // ipForNode(1) is assigned to Ryuk @@ -36,6 +48,9 @@ trait BaseItTestSuite ecEngineApiUrl = s"http://${ec1.hostName}:${EcContainer.EnginePort}" ) + protected val miner1Account = mkKeyPair("devnet-1", 0) + protected val miner1RewardAddress = EthAddress.unsafeFrom("0x7dbcf9c6c3583b76669100f9be3caf6d722bc9f9") + override def beforeAll(): Unit = { BaseItTestSuite.init() super.beforeAll() @@ -47,6 +62,8 @@ trait BaseItTestSuite waves1.start() waves1.waitReady() waves1.logPorts() + + setupNetwork() } override protected def afterAll(): Unit = { @@ -55,6 +72,37 @@ trait BaseItTestSuite super.afterAll() } + protected def setupNetwork(): Unit = { + log.info("Set script") + waves1.api.broadcastAndWait(chainContract.setScript()) + + log.info("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 + ) + ) + + log.info("Waves miner #1 join") + val joinMiner1Result = waves1.api.broadcastAndWait( + chainContract + .join( + minerAccount = miner1Account, + elRewardAddress = miner1RewardAddress + ) + ) + + val epoch1Number = joinMiner1Result.height + 1 + log.info(s"Wait for #$epoch1Number epoch") + waves1.api.waitForHeight(epoch1Number) + } + protected def mkKeyPair(seed: String, nonce: Int): SeedKeyPair = SeedKeyPair(crypto.secureHash(Bytes.concat(Ints.toByteArray(nonce), seed.getBytes(StandardCharsets.UTF_8)))) } diff --git a/consensus-client-it/src/test/scala/units/network/RewardTestSuite.scala b/consensus-client-it/src/test/scala/units/network/RewardTestSuite.scala new file mode 100644 index 00000000..fbc4ada8 --- /dev/null +++ b/consensus-client-it/src/test/scala/units/network/RewardTestSuite.scala @@ -0,0 +1,46 @@ +package units.network + +import com.wavesplatform.common.utils.EitherExt2 +import units.client.engine.model.BlockNumber + +class RewardTestSuite extends BaseItTestSuite { + "L2-234 The reward for a previous epoch is in the first block withdrawals" in { + val epoch1FirstEcBlock = eventually { + ec1.engineApi.getBlockByNumber(BlockNumber.Number(1)).explicitGet().get + } + + withClue("No reward for genesis block: ") { + epoch1FirstEcBlock.withdrawals shouldBe empty + } + + val epoch1FirstContractBlock = eventually { + waves1.chainContract.getBlock(epoch1FirstEcBlock.hash).getOrElse(fail(s"No first block ${epoch1FirstEcBlock.hash} confirmation")) + } + + val epoch1Number = epoch1FirstContractBlock.epoch + val epoch2Number = epoch1Number + 1 + + log.info(s"Wait for next epoch #$epoch2Number") + waves1.api.waitForHeight(epoch2Number) + + log.info(s"Wait for epoch #$epoch2Number data on chain contract") + val epoch2FirstContractBlock = eventually { + waves1.chainContract.getEpochFirstBlock(epoch2Number).get + } + + val epoch2FirstEcBlock = ec1.engineApi + .getBlockByHash(epoch2FirstContractBlock.hash) + .explicitGet() + .getOrElse(fail(s"Can't find ${epoch2FirstContractBlock.hash}")) + + epoch2FirstEcBlock.withdrawals should have length 1 + + withClue("Expected reward amount: ") { + epoch2FirstEcBlock.withdrawals(0).amount shouldBe rewardAmount + } + + withClue("Expected reward receiver: ") { + epoch2FirstEcBlock.withdrawals(0).address shouldBe miner1RewardAddress + } + } +} diff --git a/consensus-client-it/src/test/scala/units/network/reward/RewardTestSuite.scala b/consensus-client-it/src/test/scala/units/network/reward/RewardTestSuite.scala deleted file mode 100644 index 515ebfd5..00000000 --- a/consensus-client-it/src/test/scala/units/network/reward/RewardTestSuite.scala +++ /dev/null @@ -1,84 +0,0 @@ -package units.network.reward - -import com.wavesplatform.account.KeyPair -import com.wavesplatform.common.state.ByteStr -import com.wavesplatform.common.utils.EitherExt2 -import units.client.contract.HasConsensusLayerDappTxHelpers -import units.client.engine.model.BlockNumber -import units.eth.{EthAddress, Gwei} -import units.network.BaseItTestSuite - -import scala.concurrent.duration.DurationInt - -class RewardTestSuite extends BaseItTestSuite with HasConsensusLayerDappTxHelpers { - override implicit val patienceConfig: PatienceConfig = PatienceConfig(timeout = 30.seconds, interval = 1.second) - - // TODO move to base class - override def currentHitSource: ByteStr = ByteStr.empty - override val chainContractAccount: KeyPair = mkKeyPair("devnet-1", 2) - - "L2-234 The reward for a previous epoch is in the first block withdrawals" in { - log.info("Set script") - waves1.api.broadcastAndWait(chainContract.setScript()) - - log.info("Setup chain contract") - val rewardAmount = Gwei.ofRawGwei(2_000_000_000L) - 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 - ) - ) - - log.info("Waves miner #1 join") - val miner1RewardAddress = EthAddress.unsafeFrom("0x7dbcf9c6c3583b76669100f9be3caf6d722bc9f9") - val joinTxnResult = waves1.api.broadcastAndWait( - chainContract - .join( - minerAccount = mkKeyPair("devnet-1", 0), - elRewardAddress = miner1RewardAddress - ) - ) - - val epoch1Number = joinTxnResult.height + 1 // First mined epoch - val epoch2Number = joinTxnResult.height + 2 - - log.info(s"Wait for #$epoch2Number epoch") - waves1.api.waitForHeight(epoch2Number) - - log.info(s"Wait for epoch #$epoch2Number data on chain contract") - val epoch2FirstContractBlock = eventually { - waves1.chainContract.getEpochFirstBlock(epoch2Number).get - } - - val epoch2FirstEcBlock = ec1.engineApi - .getBlockByHash(epoch2FirstContractBlock.hash) - .explicitGet() - .getOrElse(fail(s"Can't find ${epoch2FirstContractBlock.hash}")) - - epoch2FirstEcBlock.withdrawals should have length 1 - - withClue("Expected reward amount: ") { - epoch2FirstEcBlock.withdrawals(0).amount shouldBe rewardAmount - } - - withClue("Expected reward receiver: ") { - epoch2FirstEcBlock.withdrawals(0).address shouldBe miner1RewardAddress - } - - val epoch1FirstContractBlock = waves1.chainContract.getEpochFirstBlock(epoch1Number).getOrElse(fail(s"No first block of epoch $epoch1Number")) - val epoch1FirstEcBlock = ec1.engineApi - .getBlockByHash(epoch1FirstContractBlock.hash) - .explicitGet() - .getOrElse(fail(s"Can't find ${epoch1FirstContractBlock.hash}")) - - withClue("No reward for genesis block: ") { - epoch1FirstEcBlock.withdrawals shouldBe empty - } - } -}