From 638db93b2b4b3ae18683b2ea25cc6a55911a4ba0 Mon Sep 17 00:00:00 2001 From: Ivan Mashonskii Date: Wed, 4 Oct 2023 14:19:31 +0300 Subject: [PATCH] NODE-2609 Add test --- .../com/wavesplatform/it/api/model.scala | 7 +- .../it/sync/BlockChallengeSuite.scala | 91 ++++++++++++++----- 2 files changed, 72 insertions(+), 26 deletions(-) diff --git a/node-it/src/test/scala/com/wavesplatform/it/api/model.scala b/node-it/src/test/scala/com/wavesplatform/it/api/model.scala index e7499cc0a5..38f32255fd 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/api/model.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/api/model.scala @@ -333,7 +333,8 @@ case class TransactionInfo( transfers: Option[Seq[Transfer]], totalAmount: Option[Long], expression: Option[String], - stateChanges: Option[StateChangesDetails] + stateChanges: Option[StateChangesDetails], + applicationStatus: Option[String] ) extends TxInfo object TransactionInfo { implicit val transactionReads: Reads[TransactionInfo] = @@ -363,6 +364,7 @@ object TransactionInfo { totalAmount <- (jsv \ "totalAmount").validateOpt[Long] expression <- (jsv \ "expression").validateOpt[String] stateChanges <- (jsv \ "stateChanges").validateOpt[StateChangesDetails] + applicationStatus <- (jsv \ "applicationStatus").validateOpt[String] } yield TransactionInfo( _type, id, @@ -387,7 +389,8 @@ object TransactionInfo { transfers, totalAmount, expression, - stateChanges + stateChanges, + applicationStatus ) ) } diff --git a/node-it/src/test/scala/com/wavesplatform/it/sync/BlockChallengeSuite.scala b/node-it/src/test/scala/com/wavesplatform/it/sync/BlockChallengeSuite.scala index 47f60068c8..ee9ca74b85 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/sync/BlockChallengeSuite.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/sync/BlockChallengeSuite.scala @@ -1,21 +1,24 @@ package com.wavesplatform.it.sync import com.typesafe.config.Config -import com.wavesplatform.account.{AddressScheme, KeyPair} +import com.wavesplatform.account.KeyPair import com.wavesplatform.block.Block import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.consensus.FairPoSCalculator -import com.wavesplatform.crypto +import com.wavesplatform.{TestValues, crypto} import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.it.api.Block as ApiBlock -import com.wavesplatform.it.{BaseFunSuite, NodeConfigs, TransferSending} +import com.wavesplatform.it.{BaseFunSuite, Node, NodeConfigs, TransferSending} import com.wavesplatform.it.api.AsyncNetworkApi.NodeAsyncNetworkApi import com.wavesplatform.it.api.SyncHttpApi.* +import com.wavesplatform.lang.directives.values.V8 +import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.network.RawBytes import com.wavesplatform.transaction.Asset.Waves -import com.wavesplatform.transaction.{Proofs, Transaction, TxPositiveAmount} -import com.wavesplatform.transaction.transfer.TransferTransaction +import com.wavesplatform.transaction.assets.exchange.OrderType +import com.wavesplatform.transaction.transfer.MassTransferTransaction.ParsedTransfer +import com.wavesplatform.transaction.{Transaction, TxHelpers, TxNonNegativeAmount} import scala.concurrent.Await import scala.concurrent.duration.* @@ -24,40 +27,38 @@ class BlockChallengeSuite extends BaseFunSuite with TransferSending { override def nodeConfigs: Seq[Config] = NodeConfigs.newBuilder .overrideBase(_.quorum(4)) - .overrideBase(_.preactivatedFeatures(BlockchainFeatures.TransactionStateSnapshot.id.toInt -> 0)) + .overrideBase(_.minAssetInfoUpdateInterval(0)) + .overrideBase( + _.preactivatedFeatures( + BlockchainFeatures.SynchronousCalls.id.toInt -> 0, + BlockchainFeatures.RideV6.id.toInt -> 0, + BlockchainFeatures.ConsensusImprovements.id.toInt -> 0, + BlockchainFeatures.TransactionStateSnapshot.id.toInt -> 0 + ) + ) .withDefault(1) .withSpecial(1, _.lightNode) .withSpecial(2, _.nonMiner) .buildNonConflicting() - test("NODE-1167. All nodes should receive and apply block with challenge") { + test("NODE-1167, NODE-1174, NODE-1175. All nodes should receive and apply block with challenge") { val challenger = nodes.head + val sender = nodes(1) val malicious = nodes.last val height = challenger.height val lastBlock = challenger.blockAt(height) - val txs = (1 to 3).map { idx => - TransferTransaction( - 3.toByte, - challenger.publicKey, - malicious.keyPair.toAddress, - Waves, - TxPositiveAmount.unsafeFrom(100000000 * (idx + 1)), - Waves, - TxPositiveAmount.unsafeFrom(1000000), - ByteStr.empty, - System.currentTimeMillis(), - Proofs.empty, - AddressScheme.current.chainId - ).signWith(challenger.keyPair.privateKey) - } - val invalidBlock = createBlockWithInvalidStateHash(lastBlock, height, malicious.keyPair, txs) + val elidedTransfer = TxHelpers.transfer(malicious.keyPair, amount = malicious.balance(malicious.address).balance + 200000000) + val txs = createTxs(challenger, sender, nodes(2)) :+ elidedTransfer + val invalidBlock = createBlockWithInvalidStateHash(lastBlock, height, malicious.keyPair, txs) waitForBlockTime(invalidBlock) Await.ready(challenger.sendByNetwork(RawBytes.fromBlock(invalidBlock)), 2.minutes) txs.foreach { tx => - nodes.waitForTransaction(tx.id().toString) + val txInfo = nodes.waitForTransaction(tx.id().toString) + val expectedStatus = if (tx.id() == elidedTransfer.id()) "elided" else "succeeded" + txInfo.applicationStatus shouldBe Some(expectedStatus) } val challengingIds = nodes.map { node => @@ -133,4 +134,46 @@ class BlockChallengeSuite extends BaseFunSuite with TransferSending { if (timeout > 0) Thread.sleep(timeout) } + + private def createTxs(challenger: Node, sender: Node, dApp: Node): Seq[Transaction] = { + val dAppScript = TestCompiler(V8).compileContract( + s""" + |@Callable(i) + |func foo() = [] + |""".stripMargin + ) + val assetScript = TestCompiler(V8).compileAsset("true") + + val issue = TxHelpers.issue(sender.keyPair) + val issueSmart = TxHelpers.issue(sender.keyPair, name = "smart", script = Some(assetScript)) + val lease = TxHelpers.lease(sender.keyPair) + + Seq( + issue, + issueSmart, + TxHelpers.setScript(dApp.keyPair, dAppScript), + TxHelpers.burn(issue.asset, sender = sender.keyPair), + TxHelpers.createAlias("alias", sender.keyPair), + TxHelpers.dataSingle(sender.keyPair), + TxHelpers.exchange( + TxHelpers.order(OrderType.BUY, issue.asset, Waves, sender = sender.keyPair, matcher = sender.keyPair), + TxHelpers.order(OrderType.SELL, issue.asset, Waves, sender = sender.keyPair, matcher = sender.keyPair), + sender.keyPair + ), + TxHelpers.invoke(dApp.keyPair.toAddress, Some("foo"), invoker = sender.keyPair), + lease, + TxHelpers.leaseCancel(lease.id(), sender.keyPair), + TxHelpers + .massTransfer( + sender.keyPair, + Seq(ParsedTransfer(challenger.keyPair.toAddress, TxNonNegativeAmount.unsafeFrom(1))), + fee = TestValues.fee + ), + TxHelpers.reissue(issue.asset, sender.keyPair), + TxHelpers.setAssetScript(sender.keyPair, issueSmart.asset, assetScript, fee = 200000000), + TxHelpers.transfer(sender.keyPair, challenger.keyPair.toAddress, 1), + TxHelpers.sponsor(issue.asset, sender = sender.keyPair), + TxHelpers.updateAssetInfo(issue.assetId, sender = sender.keyPair) + ) + } }