diff --git a/node-it/src/test/scala/com/wavesplatform/it/async/MicroblocksGenerationSuite.scala b/node-it/src/test/scala/com/wavesplatform/it/async/MicroblocksGenerationSuite.scala index f14a72b6c59..c84c1be859b 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/async/MicroblocksGenerationSuite.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/async/MicroblocksGenerationSuite.scala @@ -22,10 +22,7 @@ class MicroblocksGenerationSuite extends BaseFreeSpec with TransferSending { block <- miner.blockAt(2) } yield { block.transactions.size shouldBe maxTxs - - val blockTxs = block.transactions.map(_.id) - val diff = uploadedTxs.map(_.id).toSet -- blockTxs - diff shouldBe empty + block.transactions.map(_.id) should contain theSameElementsAs uploadedTxs.map(_.id).toSet }, 3.minutes ) diff --git a/node-it/src/test/scala/com/wavesplatform/it/async/WideStateGenerationSuite.scala b/node-it/src/test/scala/com/wavesplatform/it/async/WideStateGenerationSuite.scala index 2ef4a1f2e21..a9688616178 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/async/WideStateGenerationSuite.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/async/WideStateGenerationSuite.scala @@ -1,14 +1,13 @@ package com.wavesplatform.it.async -import java.util.concurrent.TimeoutException - import com.typesafe.config.{Config, ConfigFactory} -import com.wavesplatform.it._ -import com.wavesplatform.it.api.AsyncHttpApi._ -import com.wavesplatform.it.util._ +import com.wavesplatform.it.* +import com.wavesplatform.it.api.AsyncHttpApi.* +import com.wavesplatform.it.util.* +import java.util.concurrent.TimeoutException import scala.concurrent.Future.traverse -import scala.concurrent.duration._ +import scala.concurrent.duration.* import scala.concurrent.{Await, Future} @LoadTest @@ -66,15 +65,14 @@ class WideStateGenerationSuite extends BaseFreeSpec with WaitForHeight2 with Tra } yield () val limit = GlobalTimer.instance.schedule(Future.failed(new TimeoutException("Time is out for test")), 18.minutes) - val testWithDumps = Future.firstCompletedOf(Seq(test, limit)).recoverWith { - case e => - for { - _ <- dumpBalances() - dumps <- traverse(nodes)(dumpBlockChain) - } yield { - log.debug(dumps.mkString("Dumps:\n", "\n\n", "\n")) - throw e - } + val testWithDumps = Future.firstCompletedOf(Seq(test, limit)).recoverWith { case e => + for { + _ <- dumpBalances() + dumps <- traverse(nodes)(dumpBlockChain) + } yield { + log.debug(dumps.mkString("Dumps:\n", "\n\n", "\n")) + throw e + } } Await.result(testWithDumps, 18.minutes) @@ -84,12 +82,9 @@ class WideStateGenerationSuite extends BaseFreeSpec with WaitForHeight2 with Tra for { height <- node.height blocks <- node.blockSeq(1, height) - } yield { + } yield withClue(s"all transactions in node") { val txsInBlockchain = blocks.flatMap(_.transactions.map(_.id)) - val diff = txIds -- txsInBlockchain - withClue(s"all transactions in node") { - diff shouldBe empty - } + txIds -- txsInBlockchain shouldBe empty } } @@ -99,7 +94,7 @@ class WideStateGenerationSuite extends BaseFreeSpec with WaitForHeight2 with Tra }.map(_.toMap) .map { r => log.debug(s"""Balances: - |${r.map { case (config, balance) => s"${config.getString("address")} -> $balance" }.mkString("\n")}""".stripMargin) + |${r.map { case (config, balance) => s"${config.getString("address")} -> $balance" }.mkString("\n")}""".stripMargin) r } } diff --git a/node/src/main/scala/com/wavesplatform/state/StateSnapshot.scala b/node/src/main/scala/com/wavesplatform/state/StateSnapshot.scala index f3782f27070..22f2ee7d90f 100644 --- a/node/src/main/scala/com/wavesplatform/state/StateSnapshot.scala +++ b/node/src/main/scala/com/wavesplatform/state/StateSnapshot.scala @@ -329,7 +329,7 @@ object StateSnapshot { } .map(_.toMap) - private def assetStatics(issuedAssets: VectorMap[IssuedAsset, NewAssetInfo]): VectorMap[IssuedAsset, AssetStatic] = + def assetStatics(issuedAssets: VectorMap[IssuedAsset, NewAssetInfo]): VectorMap[IssuedAsset, AssetStatic] = issuedAssets.map { case (asset, info) => asset -> AssetStatic( diff --git a/node/src/test/scala/com/wavesplatform/BlockchainStubHelpers.scala b/node/src/test/scala/com/wavesplatform/BlockchainStubHelpers.scala index 55ff44fe6b6..bb990d1d03b 100644 --- a/node/src/test/scala/com/wavesplatform/BlockchainStubHelpers.scala +++ b/node/src/test/scala/com/wavesplatform/BlockchainStubHelpers.scala @@ -6,7 +6,6 @@ import com.wavesplatform.block.SignedBlockHeader import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.* import com.wavesplatform.features.{BlockchainFeature, BlockchainFeatures} -import com.wavesplatform.history.SnapshotOps.* import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.lang.ValidationError import com.wavesplatform.lang.script.Script @@ -148,12 +147,9 @@ trait BlockchainStubHelpers { self: MockFactoryBase => ) } - def transactionDiffer(time: Time = SystemTime, withFailed: Boolean = false)(tx: Transaction): TracedResult[ValidationError, Diff] = { - val snapshot = - if (withFailed) TransactionDiffer(Some(time.correctedTime()), time.correctedTime())(blockchain, tx) - else TransactionDiffer.forceValidate(Some(time.correctedTime()), time.correctedTime())(blockchain, tx) - snapshot.map(_.toDiff(blockchain)) - } + def transactionDiffer(time: Time = SystemTime, withFailed: Boolean = false)(tx: Transaction): TracedResult[ValidationError, StateSnapshot] = + if (withFailed) TransactionDiffer(Some(time.correctedTime()), time.correctedTime())(blockchain, tx) + else TransactionDiffer.forceValidate(Some(time.correctedTime()), time.correctedTime())(blockchain, tx) def transactionPublisher(time: Time = SystemTime): TransactionPublisher = (tx: Transaction, _: Option[Channel]) => { val differ = transactionDiffer(time) _ diff --git a/node/src/test/scala/com/wavesplatform/db/WithState.scala b/node/src/test/scala/com/wavesplatform/db/WithState.scala index 42bba1cb503..f80301d13b4 100644 --- a/node/src/test/scala/com/wavesplatform/db/WithState.scala +++ b/node/src/test/scala/com/wavesplatform/db/WithState.scala @@ -12,8 +12,7 @@ import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.events.BlockchainUpdateTriggers import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.features.BlockchainFeatures.LightNode -import com.wavesplatform.history.SnapshotOps.TransactionStateSnapshotExt -import com.wavesplatform.history.{Domain, SnapshotOps} +import com.wavesplatform.history.Domain import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.lagonaki.mocks.TestBlock.BlockWithSigner import com.wavesplatform.lang.ValidationError @@ -24,8 +23,10 @@ import com.wavesplatform.settings.{TestFunctionalitySettings as TFS, *} import com.wavesplatform.state.diffs.{BlockDiffer, ENOUGH_AMT} import com.wavesplatform.state.reader.SnapshotBlockchain import com.wavesplatform.state.utils.TestRocksDB -import com.wavesplatform.state.{Blockchain, BlockchainUpdaterImpl, Diff, NgState, Portfolio, StateSnapshot, TxStateSnapshotHashBuilder} +import com.wavesplatform.state.{Blockchain, BlockchainUpdaterImpl, NgState, StateSnapshot, TxStateSnapshotHashBuilder} import com.wavesplatform.test.* +import com.wavesplatform.transaction.Asset.Waves +import com.wavesplatform.transaction.TxHelpers.defaultAddress import com.wavesplatform.transaction.smart.script.trace.TracedResult import com.wavesplatform.transaction.{BlockchainUpdater, GenesisTransaction, Transaction, TxHelpers} import com.wavesplatform.{NTPTime, TestHelpers} @@ -112,7 +113,7 @@ trait WithState extends BeforeAndAfterAll with DBCacheSettings with Matchers wit fs: FunctionalitySettings = TFS.Enabled, enableExecutionLog: Boolean = false )( - assertion: Either[ValidationError, Diff] => Unit + assertion: Either[ValidationError, StateSnapshot] => Unit ): Unit = withTestState(fs) { (bcu, state) => assertDiffEi(preconditions, block, bcu, state, enableExecutionLog)(assertion) } @@ -124,7 +125,7 @@ trait WithState extends BeforeAndAfterAll with DBCacheSettings with Matchers wit state: RocksDBWriter, enableExecutionLog: Boolean )( - assertion: Either[ValidationError, Diff] => Unit + assertion: Either[ValidationError, StateSnapshot] => Unit ): Unit = { def differ(blockchain: Blockchain, b: Block) = BlockDiffer.fromBlock( @@ -150,8 +151,11 @@ trait WithState extends BeforeAndAfterAll with DBCacheSettings with Matchers wit preconditionBlock ) } - val totalDiff1 = blockWithComputedStateHash(block.block, block.signer, bcu).resultE.flatMap(differ(state, _)) - assertion(totalDiff1.map(_.snapshot.toDiff(state))) + val snapshot = + blockWithComputedStateHash(block.block, block.signer, bcu).resultE + .flatMap(differ(state, _)) + .map(_.snapshot) + assertion(snapshot) } def assertDiffEiTraced( @@ -160,7 +164,7 @@ trait WithState extends BeforeAndAfterAll with DBCacheSettings with Matchers wit fs: FunctionalitySettings = TFS.Enabled, enableExecutionLog: Boolean = false )( - assertion: TracedResult[ValidationError, Diff] => Unit + assertion: TracedResult[ValidationError, StateSnapshot] => Unit ): Unit = withTestState(fs) { (bcu, state) => def getCompBlockchain(blockchain: Blockchain) = { val reward = if (blockchain.height > 0) bcu.computeNextReward else None @@ -196,17 +200,17 @@ trait WithState extends BeforeAndAfterAll with DBCacheSettings with Matchers wit ) } - val totalDiff1 = + val snapshot1 = (blockWithComputedStateHash(block.block, block.signer, bcu) match { case right @ TracedResult(Right(_), _, _) => right.copy(trace = Nil) case err => err }).flatMap(differ(state, state.lastBlock, _)) - assertion(totalDiff1.map(_.snapshot.toDiff(state))) + assertion(snapshot1.map(_.snapshot)) } private def assertDiffAndState(preconditions: Seq[BlockWithSigner], block: BlockWithSigner, fs: FunctionalitySettings, withNg: Boolean)( - assertion: (Diff, Blockchain) => Unit + assertion: (StateSnapshot, Blockchain) => Unit ): Unit = withTestState(fs) { (bcu, state) => def getCompBlockchain(blockchain: Blockchain) = if (withNg && fs.preActivatedFeatures.get(BlockchainFeatures.BlockReward.id).exists(_ <= blockchain.height)) { @@ -226,8 +230,8 @@ trait WithState extends BeforeAndAfterAll with DBCacheSettings with Matchers wit preconditions.foldLeft[Option[Block]](None) { (prevBlock, curBlock) => val preconditionBlock = blockWithComputedStateHash(curBlock.block, curBlock.signer, bcu).resultE.explicitGet() - val BlockDiffer.Result(diff, fees, totalFee, _, _, computedStateHash) = differ(state, prevBlock, preconditionBlock).explicitGet() - state.append(diff, fees, totalFee, None, preconditionBlock.header.generationSignature, computedStateHash, preconditionBlock) + val BlockDiffer.Result(snapshot, fees, totalFee, _, _, computedStateHash) = differ(state, prevBlock, preconditionBlock).explicitGet() + state.append(snapshot, fees, totalFee, None, preconditionBlock.header.generationSignature, computedStateHash, preconditionBlock) Some(preconditionBlock) } @@ -245,22 +249,19 @@ trait WithState extends BeforeAndAfterAll with DBCacheSettings with Matchers wit checkedBlock.header.generationSignature, Map() ) - val cb = SnapshotBlockchain(state, ngState) - val diff = snapshot.toDiff(state) - assertion(diff, cb) - + val cb = SnapshotBlockchain(state, ngState) + assertion(snapshot, cb) state.append(snapshot, fees, totalFee, None, checkedBlock.header.generationSignature, computedStateHash, checkedBlock) - - assertion(diff, state) + assertion(snapshot, state) } def assertNgDiffState(preconditions: Seq[BlockWithSigner], block: BlockWithSigner, fs: FunctionalitySettings = TFS.Enabled)( - assertion: (Diff, Blockchain) => Unit + assertion: (StateSnapshot, Blockchain) => Unit ): Unit = assertDiffAndState(preconditions, block, fs, withNg = true)(assertion) def assertDiffAndState(preconditions: Seq[BlockWithSigner], block: BlockWithSigner, fs: FunctionalitySettings = TFS.Enabled)( - assertion: (Diff, Blockchain) => Unit + assertion: (StateSnapshot, Blockchain) => Unit ): Unit = assertDiffAndState(preconditions, block, fs, withNg = false)(assertion) @@ -288,9 +289,8 @@ trait WithState extends BeforeAndAfterAll with DBCacheSettings with Matchers wit val checkedBlock = blockWithComputedStateHash(block.block, block.signer, bcu).resultE.explicitGet() differ(state, checkedBlock).map { result => - val snapshot = SnapshotOps.fromDiff(result.snapshot.toDiff(state), state).explicitGet() state.append( - snapshot, + result.snapshot, result.carry, result.totalFee, None, @@ -302,11 +302,15 @@ trait WithState extends BeforeAndAfterAll with DBCacheSettings with Matchers wit }) } - def assertBalanceInvariant(diff: Diff): Unit = { - val portfolioDiff = diff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - portfolioDiff.balance shouldBe 0 - portfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - all(portfolioDiff.assets.values) shouldBe 0 + def assertBalanceInvariant(snapshot: StateSnapshot, db: RocksDBWriter, rewardAndFee: Long = 0): Unit = { + snapshot.balances.toSeq + .map { + case ((`defaultAddress`, Waves), balance) => Waves -> (balance - db.balance(defaultAddress, Waves) - rewardAndFee) + case ((address, asset), balance) => asset -> (balance - db.balance(address, asset)) + } + .groupMap(_._1)(_._2) + .foreach { case (_, balances) => balances.sum shouldBe 0 } + snapshot.leaseBalances.foreach { case (address, balance) => balance shouldBe db.leaseBalance(address) } } def assertLeft(preconditions: Seq[BlockWithSigner], block: BlockWithSigner, fs: FunctionalitySettings = TFS.Enabled)(errorMessage: String): Unit = diff --git a/node/src/test/scala/com/wavesplatform/features/RideV6FailRejectTest.scala b/node/src/test/scala/com/wavesplatform/features/RideV6FailRejectTest.scala index 53d9a623e2d..a3d1f9edf93 100644 --- a/node/src/test/scala/com/wavesplatform/features/RideV6FailRejectTest.scala +++ b/node/src/test/scala/com/wavesplatform/features/RideV6FailRejectTest.scala @@ -888,8 +888,8 @@ class RideV6FailRejectTest extends FreeSpec with WithDomain with OptionValues wi def failTxTest(invoke: Transaction): Unit = { val complexity = ContractLimits.FailFreeInvokeComplexity + 1 test(complexity) { d => - val diff = d.createDiffE(invoke).value - val (_, scriptResult) = diff.scriptResults.headOption.value + val snapshot = d.createDiffE(invoke).value + val (_, scriptResult) = snapshot.scriptResults.headOption.value scriptResult.error.value.text should include(testCase.rejectError) d.appendBlock(invoke) diff --git a/node/src/test/scala/com/wavesplatform/history/BlockRewardSpec.scala b/node/src/test/scala/com/wavesplatform/history/BlockRewardSpec.scala index 70a25d1eae6..1ace799fb1e 100644 --- a/node/src/test/scala/com/wavesplatform/history/BlockRewardSpec.scala +++ b/node/src/test/scala/com/wavesplatform/history/BlockRewardSpec.scala @@ -268,8 +268,8 @@ class BlockRewardSpec extends FreeSpec with WithDomain { "when NG state is empty" in forAll(ngEmptyScenario) { case (miner1, miner2, b2s, b3, m3s) => withDomain(rewardSettings) { d => b2s.foldLeft[Option[Block]](None) { (prevBlock, curBlock) => - val BlockDiffer.Result(diff, carryFee, totalFee, _, _, computedStateHash) = differ(d.rocksDBWriter, prevBlock, curBlock) - d.rocksDBWriter.append(diff, carryFee, totalFee, None, curBlock.header.generationSignature, computedStateHash, curBlock) + val BlockDiffer.Result(snapshot, carryFee, totalFee, _, _, computedStateHash) = differ(d.rocksDBWriter, prevBlock, curBlock) + d.rocksDBWriter.append(snapshot, carryFee, totalFee, None, curBlock.header.generationSignature, computedStateHash, curBlock) Some(curBlock) } diff --git a/node/src/test/scala/com/wavesplatform/history/Domain.scala b/node/src/test/scala/com/wavesplatform/history/Domain.scala index 8ddd0a031d6..f4995c52392 100644 --- a/node/src/test/scala/com/wavesplatform/history/Domain.scala +++ b/node/src/test/scala/com/wavesplatform/history/Domain.scala @@ -15,7 +15,6 @@ import com.wavesplatform.database.{DBExt, Keys, RDB, RocksDBWriter} import com.wavesplatform.events.BlockchainUpdateTriggers import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.features.BlockchainFeatures.{BlockV5, LightNode, RideV6} -import com.wavesplatform.history.SnapshotOps.TransactionStateSnapshotExt import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.lang.ValidationError import com.wavesplatform.lang.script.Script @@ -60,15 +59,14 @@ case class Domain(rdb: RDB, blockchainUpdater: BlockchainUpdaterImpl, rocksDBWri val posSelector: PoSSelector = PoSSelector(blockchainUpdater, None) - val transactionDiffer: Transaction => TracedResult[ValidationError, Diff] = - TransactionDiffer(blockchain.lastBlockTimestamp, System.currentTimeMillis())(blockchain, _).map(_.toDiff(blockchain)) + val transactionDiffer: Transaction => TracedResult[ValidationError, StateSnapshot] = + TransactionDiffer(blockchain.lastBlockTimestamp, System.currentTimeMillis())(blockchain, _) - val transactionDifferWithLog: Transaction => TracedResult[ValidationError, Diff] = + val transactionDifferWithLog: Transaction => TracedResult[ValidationError, StateSnapshot] = TransactionDiffer(blockchain.lastBlockTimestamp, System.currentTimeMillis(), enableExecutionLog = true)(blockchain, _) - .map(_.toDiff(blockchain)) - def createDiffE(tx: Transaction): Either[ValidationError, Diff] = transactionDiffer(tx).resultE - def createDiff(tx: Transaction): Diff = createDiffE(tx).explicitGet() + def createDiffE(tx: Transaction): Either[ValidationError, StateSnapshot] = transactionDiffer(tx).resultE + def createDiff(tx: Transaction): StateSnapshot = createDiffE(tx).explicitGet() lazy val utxPool: UtxPoolImpl = new UtxPoolImpl(SystemTime, blockchain, settings.utxSettings, settings.maxTxErrorLogSize, settings.minerSettings.enable) @@ -123,7 +121,7 @@ case class Domain(rdb: RDB, blockchainUpdater: BlockchainUpdaterImpl, rocksDBWri def commonTransactionsApi(challenger: Option[BlockChallenger]): CommonTransactionsApi = CommonTransactionsApi( - blockchainUpdater.bestLiquidSnapshot.map(diff => Height(blockchainUpdater.height) -> diff), + blockchainUpdater.bestLiquidSnapshot.map(Height(blockchainUpdater.height) -> _), rdb, blockchain, utxPool, @@ -175,8 +173,8 @@ case class Domain(rdb: RDB, blockchainUpdater: BlockchainUpdaterImpl, rocksDBWri .getOrElse(TestBlock.create(Nil).block) } - def liquidDiff: Diff = - blockchainUpdater.bestLiquidSnapshot.orEmpty.toDiff(rocksDBWriter) + def liquidSnapshot: StateSnapshot = + blockchainUpdater.bestLiquidSnapshot.orEmpty def microBlocks: Vector[MicroBlock] = blockchain.microblockIds.reverseIterator.flatMap(blockchain.microBlock).to(Vector) @@ -211,7 +209,7 @@ case class Domain(rdb: RDB, blockchainUpdater: BlockchainUpdaterImpl, rocksDBWri AddressTransactions .allAddressTransactions( rdb, - blockchainUpdater.bestLiquidSnapshot.map(diff => Height(blockchainUpdater.height) -> diff), + blockchainUpdater.bestLiquidSnapshot.map(Height(blockchainUpdater.height) -> _), address, None, Set.empty, @@ -259,7 +257,7 @@ case class Domain(rdb: RDB, blockchainUpdater: BlockchainUpdaterImpl, rocksDBWri def appendAndAssertFailed(tx: Transaction, message: String): Block = { appendBlock(tx) assert(!blockchain.transactionSucceeded(tx.id()), s"should fail: $tx") - liquidDiff.errorMessage(tx.id()).get.text should include(message) + liquidSnapshot.errorMessage(tx.id()).get.text should include(message) lastBlock } diff --git a/node/src/test/scala/com/wavesplatform/history/SnapshotOps.scala b/node/src/test/scala/com/wavesplatform/history/SnapshotOps.scala deleted file mode 100644 index 185f5ad708a..00000000000 --- a/node/src/test/scala/com/wavesplatform/history/SnapshotOps.scala +++ /dev/null @@ -1,109 +0,0 @@ -package com.wavesplatform.history - -import cats.data.Ior -import com.wavesplatform.account.Address -import com.wavesplatform.common.state.ByteStr -import com.wavesplatform.common.utils.EitherExt2 -import com.wavesplatform.lang.ValidationError -import com.wavesplatform.protobuf.ByteStringExt -import com.wavesplatform.state.* -import com.wavesplatform.state.reader.LeaseDetails -import com.wavesplatform.transaction.Asset.IssuedAsset - -import scala.collection.immutable.VectorMap - -object SnapshotOps { - implicit class TransactionStateSnapshotExt(val s: StateSnapshot) extends AnyVal { - def toDiff(blockchain: Blockchain): Diff = - Diff.withTransactions( - s.transactions.values.toVector, - portfolios(blockchain), - issuedAssets, - updatedAssets, - s.aliases, - orderFills(blockchain), - s.leaseStates.map(l => (l._1, LeaseDetails(l._2.sender, l._2.recipient, l._2.amount, l._2.status, ByteStr.empty, 0))), - s.accountScripts, - s.assetScripts.view.mapValues(Some(_)).toMap, - s.accountData, - s.sponsorships, - scriptsRun = 0, - s.scriptsComplexity, - s.scriptResults, - s.ethereumTransactionMeta - ) - - private def portfolios(blockchain: Blockchain): Map[Address, Portfolio] = - Portfolio.combine(balancePortfolios(blockchain), leasePortfolios(blockchain)).explicitGet() - - private def balancePortfolios(blockchain: Blockchain): Map[Address, Portfolio] = - s.balances - .foldLeft(Map[Address, Portfolio]()) { case (portfolios, ((address, asset), balance)) => - val balanceDiff = balance - blockchain.balance(address, asset) - if (balanceDiff != 0) { - val portfolio = Portfolio.build(asset, balanceDiff) - Portfolio.combine(portfolios, Map(address -> portfolio)).explicitGet() - } else - portfolios - } - - private def leasePortfolios(blockchain: Blockchain): Map[Address, Portfolio] = - s.leaseBalances - .map { case (address, current) => - val init = blockchain.leaseBalance(address) - address -> Portfolio(lease = LeaseBalance(in = current.in - init.in, out = current.out - init.out)) - } - - private def issuedAssets: VectorMap[IssuedAsset, NewAssetInfo] = - VectorMap[IssuedAsset, NewAssetInfo]() ++ s.assetStatics.map { case (asset, pbStatic) => - val static = AssetStaticInfo( - asset.id, - pbStatic.sourceTransactionId.toTxId, - pbStatic.issuerPublicKey.toPublicKey, - pbStatic.decimals, - pbStatic.nft - ) - asset -> NewAssetInfo(static, s.assetNamesAndDescriptions(asset), s.assetVolumes(asset)) - } - - private def updatedAssets: Map[IssuedAsset, Ior[AssetInfo, AssetVolumeInfo]] = - (s.assetVolumes.keySet ++ s.assetNamesAndDescriptions.keySet) - .filterNot(issuedAssets.contains) - .map { asset => - val info = - (s.assetNamesAndDescriptions.get(asset), s.assetVolumes.get(asset)) match { - case (Some(dynamic), Some(volume)) => Ior.Both(dynamic, volume) - case (Some(dynamic), None) => Ior.Left(dynamic) - case (None, Some(volume)) => Ior.Right(volume) - case _ => ??? - } - asset -> info - } - .toMap - - private def orderFills(blockchain: Blockchain): Map[ByteStr, VolumeAndFee] = - s.orderFills.map { case (orderId, info) => - val init = blockchain.filledVolumeAndFee(orderId) - orderId -> VolumeAndFee(info.volume - init.volume, info.fee - init.fee) - } - } - - def fromDiff(diff: Diff, blockchain: Blockchain): Either[ValidationError, StateSnapshot] = - StateSnapshot.build( - blockchain, - diff.portfolios, - diff.orderFills, - diff.issuedAssets, - diff.updatedAssets, - diff.assetScripts.collect { case (asset, Some(info)) => (asset, info) }, - diff.sponsorship, - diff.leaseState.map(l => (l._1, LeaseSnapshot(l._2.sender, l._2.recipient, l._2.amount, l._2.status))), - diff.aliases, - diff.accountData, - diff.scripts, - diff.scriptResults, - diff.ethereumTransactionMeta, - diff.scriptsComplexity, - VectorMap() ++ diff.transactions.map(info => info.transaction.id() -> info).toMap - ) -} diff --git a/node/src/test/scala/com/wavesplatform/http/TransactionsRouteSpec.scala b/node/src/test/scala/com/wavesplatform/http/TransactionsRouteSpec.scala index ad6aca80e59..fcd39a0b456 100644 --- a/node/src/test/scala/com/wavesplatform/http/TransactionsRouteSpec.scala +++ b/node/src/test/scala/com/wavesplatform/http/TransactionsRouteSpec.scala @@ -421,7 +421,7 @@ class TransactionsRouteSpec val differ = blockchain.stub.transactionDiffer().andThen(_.resultE.explicitGet()) val transaction = EthTxGenerator.generateEthTransfer(TxHelpers.defaultEthSigner, TxHelpers.secondAddress, 10, Waves) - val diff = differ(transaction) + val snapshot = differ(transaction) val transactionsApi = stub[CommonTransactionsApi] (transactionsApi.transactionById _) .when(transaction.id()) @@ -432,8 +432,8 @@ class TransactionsRouteSpec transaction, Status.Succeeded, 15L, - diff.ethereumTransactionMeta.values.headOption, - diff.scriptResults.values.headOption + snapshot.ethereumTransactionMeta.values.headOption, + snapshot.scriptResults.values.headOption ) ) ) @@ -479,7 +479,7 @@ class TransactionsRouteSpec val differ = blockchain.stub.transactionDiffer().andThen(_.resultE.explicitGet()) val transaction = EthTxGenerator.generateEthInvoke(TxHelpers.defaultEthSigner, TxHelpers.secondAddress, "test", Nil, Nil) - val diff = differ(transaction) + val snapshot = differ(transaction) val transactionsApi = stub[CommonTransactionsApi] (transactionsApi.transactionById _) .when(transaction.id()) @@ -490,8 +490,8 @@ class TransactionsRouteSpec transaction, Status.Succeeded, 15L, - diff.ethereumTransactionMeta.values.headOption, - diff.scriptResults.values.headOption + snapshot.ethereumTransactionMeta.values.headOption, + snapshot.scriptResults.values.headOption ) ) ) diff --git a/node/src/test/scala/com/wavesplatform/state/Diff.scala b/node/src/test/scala/com/wavesplatform/state/Diff.scala deleted file mode 100755 index d71987f26b0..00000000000 --- a/node/src/test/scala/com/wavesplatform/state/Diff.scala +++ /dev/null @@ -1,182 +0,0 @@ -package com.wavesplatform.state - -import cats.data.Ior -import cats.implicits.{catsSyntaxEitherId, catsSyntaxSemigroup, toTraverseOps} -import com.google.common.hash.{BloomFilter, Funnels} -import com.wavesplatform.account.{Address, Alias, PublicKey} -import com.wavesplatform.common.state.ByteStr -import com.wavesplatform.database.protobuf.EthereumTransactionMeta -import com.wavesplatform.state.reader.LeaseDetails -import com.wavesplatform.transaction.Asset.IssuedAsset -import com.wavesplatform.transaction.Transaction - -import scala.collection.immutable.VectorMap -import scala.util.chaining.* - -case class Diff( - transactions: Vector[NewTransactionInfo], - portfolios: Map[Address, Portfolio], - issuedAssets: VectorMap[IssuedAsset, NewAssetInfo], - updatedAssets: Map[IssuedAsset, Ior[AssetInfo, AssetVolumeInfo]], - aliases: Map[Alias, Address], - orderFills: Map[ByteStr, VolumeAndFee], - leaseState: Map[ByteStr, LeaseDetails], - scripts: Map[PublicKey, Option[AccountScriptInfo]], - assetScripts: Map[IssuedAsset, Option[AssetScriptInfo]], - accountData: Map[Address, Map[String, DataEntry[?]]], - sponsorship: Map[IssuedAsset, Sponsorship], - scriptsRun: Int, - scriptsComplexity: Long, - scriptResults: Map[ByteStr, InvokeScriptResult], - ethereumTransactionMeta: Map[ByteStr, EthereumTransactionMeta], - transactionFilter: Option[BloomFilter[Array[Byte]]] -) { - def containsTransaction(txId: ByteStr): Boolean = - transactions.nonEmpty && transactionFilter.exists(_.mightContain(txId.arr)) && transactions.exists(_.transaction.id() == txId) - - def transaction(txId: ByteStr): Option[NewTransactionInfo] = - if (transactions.nonEmpty && transactionFilter.exists(_.mightContain(txId.arr))) - transactions.find(_.transaction.id() == txId) - else None - - def combineF(newer: Diff): Either[String, Diff] = - for { - portfolios <- Portfolio.combine(portfolios, newer.portfolios) - orderFills <- { - val combinedOrders = - orderFills.toSeq - .traverse { case kv @ (orderId, value) => - newer.orderFills.get(orderId).fold(kv.asRight[String])(value.combineE(_).map(orderId -> _)) - } - .map(_.toMap) - combinedOrders.map(co => co ++ newer.orderFills.filterNot { case (id, _) => co.contains(id) }) - } - newTransactions = if (transactions.isEmpty) newer.transactions else transactions ++ newer.transactions - newFilter = transactionFilter match { - case Some(bf) => - newer.transactions.foreach(nti => bf.put(nti.transaction.id().arr)) - Some(bf) - case None => - newer.transactionFilter - } - } yield Diff( - transactions = newTransactions, - portfolios = portfolios, - issuedAssets = issuedAssets ++ newer.issuedAssets, - updatedAssets = updatedAssets |+| newer.updatedAssets, - aliases = aliases ++ newer.aliases, - orderFills = orderFills, - leaseState = leaseState ++ newer.leaseState, - scripts = scripts ++ newer.scripts, - assetScripts = assetScripts ++ newer.assetScripts, - accountData = Diff.combine(accountData, newer.accountData), - sponsorship = sponsorship.combine(newer.sponsorship), - scriptsRun = scriptsRun + newer.scriptsRun, - scriptResults = scriptResults.combine(newer.scriptResults), - scriptsComplexity = scriptsComplexity + newer.scriptsComplexity, - ethereumTransactionMeta = ethereumTransactionMeta ++ newer.ethereumTransactionMeta, - transactionFilter = newFilter - ) -} - -object Diff { - def apply( - portfolios: Map[Address, Portfolio] = Map.empty, - issuedAssets: VectorMap[IssuedAsset, NewAssetInfo] = VectorMap.empty, - updatedAssets: Map[IssuedAsset, Ior[AssetInfo, AssetVolumeInfo]] = Map.empty, - aliases: Map[Alias, Address] = Map.empty, - orderFills: Map[ByteStr, VolumeAndFee] = Map.empty, - leaseState: Map[ByteStr, LeaseDetails] = Map.empty, - scripts: Map[PublicKey, Option[AccountScriptInfo]] = Map.empty, - assetScripts: Map[IssuedAsset, Option[AssetScriptInfo]] = Map.empty, - accountData: Map[Address, Map[String, DataEntry[?]]] = Map.empty, - sponsorship: Map[IssuedAsset, Sponsorship] = Map.empty, - scriptsRun: Int = 0, - scriptsComplexity: Long = 0, - scriptResults: Map[ByteStr, InvokeScriptResult] = Map.empty, - ethereumTransactionMeta: Map[ByteStr, EthereumTransactionMeta] = Map.empty - ): Diff = - new Diff( - Vector.empty, - portfolios, - issuedAssets, - updatedAssets, - aliases, - orderFills, - leaseState, - scripts, - assetScripts, - accountData, - sponsorship, - scriptsRun, - scriptsComplexity, - scriptResults, - ethereumTransactionMeta, - None - ) - - def withTransactions( - nti: Vector[NewTransactionInfo], - portfolios: Map[Address, Portfolio] = Map.empty, - issuedAssets: VectorMap[IssuedAsset, NewAssetInfo] = VectorMap.empty, - updatedAssets: Map[IssuedAsset, Ior[AssetInfo, AssetVolumeInfo]] = Map.empty, - aliases: Map[Alias, Address] = Map.empty, - orderFills: Map[ByteStr, VolumeAndFee] = Map.empty, - leaseState: Map[ByteStr, LeaseDetails] = Map.empty, - scripts: Map[PublicKey, Option[AccountScriptInfo]] = Map.empty, - assetScripts: Map[IssuedAsset, Option[AssetScriptInfo]] = Map.empty, - accountData: Map[Address, Map[String, DataEntry[?]]] = Map.empty, - sponsorship: Map[IssuedAsset, Sponsorship] = Map.empty, - scriptsRun: Int = 0, - scriptsComplexity: Long = 0, - scriptResults: Map[ByteStr, InvokeScriptResult] = Map.empty, - ethereumTransactionMeta: Map[ByteStr, EthereumTransactionMeta] = Map.empty - ): Diff = - new Diff( - nti, - portfolios, - issuedAssets, - updatedAssets, - aliases, - orderFills, - leaseState, - scripts, - assetScripts, - accountData, - sponsorship, - scriptsRun, - scriptsComplexity, - scriptResults, - ethereumTransactionMeta, - mkFilterForTransactions(nti.map(_.transaction)*) - ) - - val empty: Diff = Diff() - - private def combine[K, IK, IV](first: Map[K, Map[IK, IV]], second: Map[K, Map[IK, IV]]): Map[K, Map[IK, IV]] = { - if (first.isEmpty) { - second - } else { - first ++ second.map { case (k, innerMap) => - k -> first.get(k).fold(innerMap)(_ ++ innerMap) - } - } - } - - private def mkFilter() = - BloomFilter.create[Array[Byte]](Funnels.byteArrayFunnel(), 10000, 0.01f) - - private def mkFilterForTransactions(tx: Transaction*) = - Some( - mkFilter().tap(bf => - tx.foreach { t => - bf.put(t.id().arr) - } - ) - ) - - implicit class DiffExt(private val d: Diff) extends AnyVal { - def errorMessage(txId: ByteStr): Option[InvokeScriptResult.ErrorMessage] = - d.scriptResults.get(txId).flatMap(_.error) - } -} diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/AssetTransactionsDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/AssetTransactionsDiffTest.scala index 8786f5d65ef..1994f86aee0 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/AssetTransactionsDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/AssetTransactionsDiffTest.scala @@ -24,7 +24,8 @@ import com.wavesplatform.state.diffs.TransactionDiffer.TransactionValidationErro import com.wavesplatform.state.diffs.smart.smartEnabledFS import com.wavesplatform.test.* import com.wavesplatform.test.DomainPresets.* -import com.wavesplatform.transaction.Asset.IssuedAsset +import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} +import com.wavesplatform.transaction.TxHelpers.defaultAddress import com.wavesplatform.transaction.TxValidationError.GenericError import com.wavesplatform.transaction.assets.* import com.wavesplatform.transaction.transfer.* @@ -42,7 +43,7 @@ class AssetTransactionsDiffTest extends PropSpec with BlocksTransactionsHelpers val issue = TxHelpers.issue(master, 100, reissuable = isReissuable, version = TxVersion.V1) val asset = IssuedAsset(issue.id()) - val reissue = TxHelpers.reissue(asset, master, 50, version = TxVersion.V1) + val reissue = TxHelpers.reissue(asset, master, 50, version = TxVersion.V1, fee = 1.waves) val burn = TxHelpers.burn(asset, 10, master, version = TxVersion.V1) ((genesis, issue), (reissue, burn)) @@ -50,15 +51,27 @@ class AssetTransactionsDiffTest extends PropSpec with BlocksTransactionsHelpers property("Issue+Reissue+Burn do not break waves invariant and updates state") { val ((gen, issue), (reissue, burn)) = issueReissueBurnTxs(isReissuable = true) - assertDiffAndState(Seq(TestBlock.create(Seq(gen, issue))), TestBlock.create(Seq(reissue, burn))) { case (blockDiff, newState) => - val totalPortfolioDiff = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - - totalPortfolioDiff.balance shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - totalPortfolioDiff.assets shouldBe Map(reissue.asset -> (reissue.quantity.value - burn.quantity.value)) - - val totalAssetVolume = issue.quantity.value + reissue.quantity.value - burn.quantity.value - newState.balance(issue.sender.toAddress, reissue.asset) shouldEqual totalAssetVolume + withDomain(RideV3) { d => + d.appendBlock(gen) + d.appendBlock(issue) + d.appendBlock(reissue, burn) + val assetQuantityDiff = reissue.quantity.value - burn.quantity.value + d.liquidSnapshot.balances.toSeq + .map { + case ((`defaultAddress`, Waves), amount) => + val carryFee = (-issue.fee.value + reissue.fee.value + burn.fee.value) / 5 * 3 + Waves -> (amount - d.rocksDBWriter.balance(defaultAddress, Waves) + carryFee) + case ((address, asset), amount) => + asset -> (amount - d.rocksDBWriter.balance(address, asset)) + } + .groupMap(_._1)(_._2) + .foreach { + case (asset, Seq(balanceDiff)) if asset == reissue.asset => balanceDiff shouldBe assetQuantityDiff + case (_, balanceDiff) => balanceDiff.sum shouldBe 0 + } + val resultQuantity = issue.quantity.value + assetQuantityDiff + d.liquidSnapshot.assetVolumes.view.mapValues(_.volume).toMap shouldBe Map(reissue.asset -> resultQuantity) + d.balance(issue.sender.toAddress, reissue.asset) shouldEqual resultQuantity } } @@ -249,7 +262,7 @@ class AssetTransactionsDiffTest extends PropSpec with BlocksTransactionsHelpers Height @@ 2 ) ) - blockDiff.transaction(issue.id()) shouldBe defined + blockDiff.transactions.get(issue.id()) shouldBe defined newState.transactionInfo(issue.id()).isDefined shouldBe true } } @@ -257,8 +270,8 @@ class AssetTransactionsDiffTest extends PropSpec with BlocksTransactionsHelpers property("Can transfer when script evaluates to TRUE") { val (gen, issue, transfer, _, _) = genesisIssueTransferReissue("true") assertDiffAndState(Seq(TestBlock.create(gen)), TestBlock.create(Seq(issue, transfer)), smartEnabledFS) { case (blockDiff, newState) => - val totalPortfolioDiff = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.assets(IssuedAsset(issue.id())) shouldEqual issue.quantity.value + val asset = IssuedAsset(issue.id()) + blockDiff.balances.collect { case ((_, `asset`), quantity) => quantity }.sum shouldEqual issue.quantity.value newState.balance(newState.resolveAlias(transfer.recipient).explicitGet(), IssuedAsset(issue.id())) shouldEqual transfer.amount.value } } @@ -320,12 +333,7 @@ class AssetTransactionsDiffTest extends PropSpec with BlocksTransactionsHelpers ) assertDiffEi(blocks, TestBlock.create(Seq(update), Block.ProtoBlockVersion), assetInfoUpdateEnabled) { ei => - val info = ei - .explicitGet() - .updatedAssets(update.assetId) - .left - .get - + val info = ei.explicitGet().assetNamesAndDescriptions(update.assetId) info.name.toStringUtf8 shouldEqual update.name info.description.toStringUtf8 shouldEqual update.description } @@ -403,8 +411,8 @@ class AssetTransactionsDiffTest extends PropSpec with BlocksTransactionsHelpers val (genesis1, issue1, _, _, _) = genesisIssueTransferReissue(exprV4WithComplexityBetween3000And4000, V4) assertDiffAndState(Seq(TestBlock.create(genesis1)), TestBlock.create(Seq(issue1)), rideV4Activated) { case (blockDiff, _) => - val totalPortfolioDiff = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.assets(IssuedAsset(issue1.id())) shouldEqual issue1.quantity.value + val asset = IssuedAsset(issue1.id()) + blockDiff.balances.collect { case ((_, `asset`), quantity) => quantity }.sum shouldEqual issue1.quantity.value } val (genesis2, issue2, _, _, _) = genesisIssueTransferReissue(exprV4WithComplexityAbove4000, V4) @@ -467,7 +475,7 @@ class AssetTransactionsDiffTest extends PropSpec with BlocksTransactionsHelpers db.appendBlock(preparingTxs*) val tx = scriptedTx() db.appendBlock(tx) - db.liquidDiff.errorMessage(tx.id()) shouldBe None + db.liquidSnapshot.errorMessage(tx.id()) shouldBe None } withDomain(domainSettingsWithFS(settings(checkNegative = true))) { db => diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/BalanceDiffValidationTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/BalanceDiffValidationTest.scala index dc64f34548e..3106324e0dd 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/BalanceDiffValidationTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/BalanceDiffValidationTest.scala @@ -40,8 +40,8 @@ class BalanceDiffValidationTest extends PropSpec with WithState { Seq(TestBlock.create(Seq(genesis, masterTransfersToAlice, aliceLeasesToBob, masterLeasesToAlice))), TestBlock.create(Seq(aliceTransfersMoreThanOwnsMinusLeaseOut)), settings - ) { totalDiffEi => - totalDiffEi.explicitGet() + ) { snapshotEi => + snapshotEi.explicitGet() } } @@ -59,8 +59,8 @@ class BalanceDiffValidationTest extends PropSpec with WithState { ), TestBlock.create(Seq(aliceTransfersMoreThanOwnsMinusLeaseOut)), settings - ) { totalDiffEi => - totalDiffEi should produce("trying to spend leased money") + ) { snapshotEi => + snapshotEi should produce("trying to spend leased money") } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/BlockDifferTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/BlockDifferTest.scala index d8453155046..1983fbc5e04 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/BlockDifferTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/BlockDifferTest.scala @@ -14,7 +14,7 @@ import com.wavesplatform.mining.{MinerImpl, MiningConstraint} import com.wavesplatform.settings.FunctionalitySettings import com.wavesplatform.state.diffs.BlockDiffer.Result import com.wavesplatform.state.reader.SnapshotBlockchain -import com.wavesplatform.state.{Blockchain, Diff, StateSnapshot, TxStateSnapshotHashBuilder} +import com.wavesplatform.state.{Blockchain, StateSnapshot, TxStateSnapshotHashBuilder} import com.wavesplatform.test.* import com.wavesplatform.test.node.* import com.wavesplatform.transaction.TxValidationError.InvalidStateHash @@ -303,7 +303,7 @@ class BlockDifferTest extends FreeSpec with WithDomain { } } - private def assertDiff(blocks: Seq[BlockWithSigner], ngAtHeight: Int)(assertion: (Diff, Blockchain) => Unit): Unit = { + private def assertDiff(blocks: Seq[BlockWithSigner], ngAtHeight: Int)(assertion: (StateSnapshot, Blockchain) => Unit): Unit = { val fs = FunctionalitySettings( featureCheckBlocksPeriod = ngAtHeight / 2, blocksForFeatureActivation = 1, diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/CreateAliasTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/CreateAliasTransactionDiffTest.scala index 0b8a11fbc91..31483e179a6 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/CreateAliasTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/CreateAliasTransactionDiffTest.scala @@ -2,22 +2,24 @@ package com.wavesplatform.state.diffs import com.wavesplatform.account.Alias import com.wavesplatform.common.utils.EitherExt2 -import com.wavesplatform.db.WithState +import com.wavesplatform.db.WithDomain import com.wavesplatform.features.BlockchainFeatures -import com.wavesplatform.history.SnapshotOps +import com.wavesplatform.features.BlockchainFeatures.SmartAccounts import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.settings.{FunctionalitySettings, TestFunctionalitySettings} import com.wavesplatform.state.* import com.wavesplatform.state.utils.addressTransactions import com.wavesplatform.test.* -import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} +import com.wavesplatform.test.DomainPresets.{NG, RideV3, WavesSettingsOps} +import com.wavesplatform.transaction.Asset.Waves +import com.wavesplatform.transaction.TxHelpers.defaultAddress import com.wavesplatform.transaction.assets.IssueTransaction import com.wavesplatform.transaction.lease.LeaseTransaction import com.wavesplatform.transaction.transfer.TransferTransaction import com.wavesplatform.transaction.{Asset, CreateAliasTransaction, GenesisTransaction, TransactionType, TxHelpers, TxVersion} import monix.execution.Scheduler.Implicits.global -class CreateAliasTransactionDiffTest extends PropSpec with WithState { +class CreateAliasTransactionDiffTest extends PropSpec with WithDomain { val fs: FunctionalitySettings = TestFunctionalitySettings.Enabled.copy( @@ -39,16 +41,16 @@ class CreateAliasTransactionDiffTest extends PropSpec with WithState { TxHelpers.createAlias(alias.name, master, fee = fee, version = TxVersion.V1) ) val sameAliasTxs = Seq( - TxHelpers.createAlias(alias.name, master, fee = fee + 1), - TxHelpers.createAlias(alias.name, master, fee = fee + 1, version = TxVersion.V1) + TxHelpers.createAlias(alias.name, master, fee = fee + 100), + TxHelpers.createAlias(alias.name, master, fee = fee + 100, version = TxVersion.V1) ) val sameAliasOtherSenderTxs = Seq( - TxHelpers.createAlias(alias.name, other, fee = fee + 2), - TxHelpers.createAlias(alias.name, other, fee = fee + 2, version = TxVersion.V1) + TxHelpers.createAlias(alias.name, other, fee = fee + 200), + TxHelpers.createAlias(alias.name, other, fee = fee + 200, version = TxVersion.V1) ) val anotherAliasTxs = Seq( - TxHelpers.createAlias(alias2.name, master, fee = fee + 3), - TxHelpers.createAlias(alias2.name, master, fee = fee + 3, version = TxVersion.V1) + TxHelpers.createAlias(alias2.name, master, fee = fee + 300), + TxHelpers.createAlias(alias2.name, master, fee = fee + 300, version = TxVersion.V1) ) for { @@ -61,28 +63,28 @@ class CreateAliasTransactionDiffTest extends PropSpec with WithState { property("can create and resolve aliases preserving waves invariant") { preconditionsAndAliasCreations.foreach { case (gen, aliasTx, _, _, anotherAliasTx) => - assertDiffAndState(Seq(TestBlock.create(Seq(gen, aliasTx))), TestBlock.create(Seq(anotherAliasTx)), fs) { case (blockDiff, newState) => - val totalPortfolioDiff = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.balance shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - + withDomain(RideV3) { d => + d.appendBlock(gen) + d.appendBlock(aliasTx) + d.appendBlock(anotherAliasTx) + d.liquidSnapshot.balances.collect { + case ((`defaultAddress`, Waves), balance) => + val carryFee = (anotherAliasTx.fee.value - aliasTx.fee.value) / 5 * 3 + balance - d.rocksDBWriter.balance(defaultAddress) + carryFee + case ((address, Waves), balance) => + balance - d.rocksDBWriter.balance(address) + }.sum shouldBe 0 val senderAcc = anotherAliasTx.sender.toAddress - blockDiff.aliases shouldBe Map(anotherAliasTx.alias -> senderAcc) - + d.liquidSnapshot.aliases shouldBe Map(anotherAliasTx.alias -> senderAcc) addressTransactions( rdb, - Some(Height(newState.height + 1) -> SnapshotOps.fromDiff(blockDiff, newState).explicitGet()), + Some(Height(d.blockchain.height + 1) -> d.liquidSnapshot), senderAcc, Set(TransactionType.CreateAlias), None - ).collect { case (_, cat: CreateAliasTransaction) => - cat.alias - }.toSet shouldBe Set( - anotherAliasTx.alias, - aliasTx.alias - ) - newState.resolveAlias(aliasTx.alias) shouldBe Right(senderAcc) - newState.resolveAlias(anotherAliasTx.alias) shouldBe Right(senderAcc) + ).collect { case (_, cat: CreateAliasTransaction) => cat.alias }.toSet shouldBe Set(anotherAliasTx.alias, aliasTx.alias) + d.blockchain.resolveAlias(aliasTx.alias) shouldBe Right(senderAcc) + d.blockchain.resolveAlias(anotherAliasTx.alias) shouldBe Right(senderAcc) } } } @@ -92,7 +94,6 @@ class CreateAliasTransactionDiffTest extends PropSpec with WithState { assertDiffEi(Seq(TestBlock.create(Seq(gen, aliasTx))), TestBlock.create(Seq(sameAliasTx)), fs) { blockDiffEi => blockDiffEi should produce("AlreadyInTheState") } - assertDiffEi(Seq(TestBlock.create(Seq(gen, aliasTx))), TestBlock.create(Seq(sameAliasOtherSenderTx)), fs) { blockDiffEi => blockDiffEi should produce("AlreadyInTheState") } @@ -129,13 +130,13 @@ class CreateAliasTransactionDiffTest extends PropSpec with WithState { property("Can transfer to alias") { preconditionsTransferLease.foreach { case (genesis, issue1, issue2, aliasTx, transfer, _) => - assertDiffAndState(Seq(TestBlock.create(genesis :+ issue1 :+ issue2 :+ aliasTx)), TestBlock.create(Seq(transfer))) { case (blockDiff, _) => + withDomain(NG.addFeatures(SmartAccounts)) { d => + d.appendBlock(genesis*) + d.appendBlock(issue1, issue2, aliasTx) + d.appendBlock(transfer) if (transfer.sender.toAddress != aliasTx.sender.toAddress) { - val recipientPortfolioDiff = blockDiff.portfolios(aliasTx.sender.toAddress) - transfer.assetId match { - case aid @ IssuedAsset(_) => recipientPortfolioDiff shouldBe Portfolio.build(aid, transfer.amount.value) - case Waves => recipientPortfolioDiff shouldBe Portfolio(transfer.amount.value) - } + d.liquidSnapshot.balances((aliasTx.sender.toAddress, transfer.assetId)) shouldBe + transfer.amount.value + d.rocksDBWriter.balance(aliasTx.sender.toAddress, transfer.assetId) } } } @@ -145,8 +146,8 @@ class CreateAliasTransactionDiffTest extends PropSpec with WithState { preconditionsTransferLease.foreach { case (genesis, issue1, issue2, aliasTx, _, lease) => assertDiffEi(Seq(TestBlock.create(genesis :+ issue1 :+ issue2 :+ aliasTx)), TestBlock.create(Seq(lease))) { blockDiffEi => if (lease.sender.toAddress != aliasTx.sender.toAddress) { - val recipientPortfolioDiff = blockDiffEi.explicitGet().portfolios(aliasTx.sender.toAddress) - recipientPortfolioDiff shouldBe Portfolio(0, LeaseBalance(lease.amount.value, 0)) + blockDiffEi.explicitGet().balances.get((aliasTx.sender.toAddress, Waves)) shouldBe None + blockDiffEi.explicitGet().leaseBalances(aliasTx.sender.toAddress) shouldBe LeaseBalance(lease.amount.value, 0) } else { blockDiffEi should produce("Cannot lease to self") } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/DataTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/DataTransactionDiffTest.scala index 4ddaaff042d..3295bf319ed 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/DataTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/DataTransactionDiffTest.scala @@ -2,15 +2,17 @@ package com.wavesplatform.state.diffs import com.wavesplatform.account.KeyPair import com.wavesplatform.common.state.ByteStr -import com.wavesplatform.db.WithState +import com.wavesplatform.db.WithDomain import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.lagonaki.mocks.TestBlock.create as block import com.wavesplatform.settings.TestFunctionalitySettings import com.wavesplatform.state.{BinaryDataEntry, BooleanDataEntry, IntegerDataEntry} import com.wavesplatform.test.* +import com.wavesplatform.test.DomainPresets.RideV3 +import com.wavesplatform.transaction.Asset.Waves import com.wavesplatform.transaction.{GenesisTransaction, TxHelpers} -class DataTransactionDiffTest extends PropSpec with WithState { +class DataTransactionDiffTest extends PropSpec with WithDomain { val fs = TestFunctionalitySettings.Enabled.copy(preActivatedFeatures = Map(BlockchainFeatures.DataTransaction.id -> 0)) @@ -41,34 +43,38 @@ class DataTransactionDiffTest extends PropSpec with WithState { } val (genesisTx, items, txs) = setup - val sender = txs.head.sender - val genesis = block(Seq(genesisTx)) - val blocks = txs.map(tx => block(Seq(tx))) + val sender = txs.head.sender.toAddress val item1 = items.head - assertDiffAndState(Seq(genesis), blocks(0), fs) { - case (totalDiff, state) => - assertBalanceInvariant(totalDiff) - state.balance(sender.toAddress) shouldBe (ENOUGH_AMT - txs(0).fee.value) - state.accountData(sender.toAddress, item1.key) shouldBe Some(item1) + withDomain(RideV3) { d => + d.appendBlock(genesisTx) + d.appendBlock(txs(0)) + d.liquidSnapshot.balances((sender, Waves)) shouldBe (ENOUGH_AMT - txs(0).fee.value) + d.liquidSnapshot.accountData(sender)(item1.key) shouldBe item1 + val carryFee = -txs(0).fee.value * 3 / 5 + assertBalanceInvariant(d.liquidSnapshot, d.rocksDBWriter, carryFee) } val item2 = items(1) - assertDiffAndState(Seq(genesis, blocks(0)), blocks(1), fs) { - case (totalDiff, state) => - assertBalanceInvariant(totalDiff) - state.balance(sender.toAddress) shouldBe (ENOUGH_AMT - txs.take(2).map(_.fee.value).sum) - state.accountData(sender.toAddress, item1.key) shouldBe Some(item1) - state.accountData(sender.toAddress, item2.key) shouldBe Some(item2) + withDomain(RideV3) { d => + d.appendBlock(genesisTx) + d.appendBlock(txs(0), txs(1)) + d.liquidSnapshot.balances((sender, Waves)) shouldBe (ENOUGH_AMT - txs.take(2).map(_.fee.value).sum) + d.liquidSnapshot.accountData(sender)(item1.key) shouldBe item1 + d.liquidSnapshot.accountData(sender)(item2.key) shouldBe item2 + val carryFee = -(txs(0).fee.value + txs(1).fee.value) * 3 / 5 + assertBalanceInvariant(d.liquidSnapshot, d.rocksDBWriter, carryFee) } val item3 = items(2) - assertDiffAndState(Seq(genesis, blocks(0), blocks(1)), blocks(2), fs) { - case (totalDiff, state) => - assertBalanceInvariant(totalDiff) - state.balance(sender.toAddress) shouldBe (ENOUGH_AMT - txs.map(_.fee.value).sum) - state.accountData(sender.toAddress, item1.key) shouldBe Some(item3) - state.accountData(sender.toAddress, item2.key) shouldBe Some(item2) + withDomain(RideV3) { d => + d.appendBlock(genesisTx) + d.appendBlock(txs(0), txs(1), txs(2)) + d.liquidSnapshot.balances((sender, Waves)) shouldBe (ENOUGH_AMT - txs.map(_.fee.value).sum) + d.liquidSnapshot.accountData(sender)(item1.key) shouldBe item3 + d.liquidSnapshot.accountData(sender)(item2.key) shouldBe item2 + val carryFee = -(txs(0).fee.value + txs(1).fee.value + txs(2).fee.value) * 3 / 5 + assertBalanceInvariant(d.liquidSnapshot, d.rocksDBWriter, carryFee) } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/EthereumTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/EthereumTransactionDiffTest.scala index fb9831b2464..1c403c22e20 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/EthereumTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/EthereumTransactionDiffTest.scala @@ -4,25 +4,24 @@ import com.wavesplatform.TestValues import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.crypto.EthereumKeyLength -import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.db.WithDomain +import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.lang.directives.values.V6 +import com.wavesplatform.lang.v1.ContractLimits.MaxInvokeScriptSizeInBytes import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.settings.RewardsVotingSettings -import com.wavesplatform.state.{Diff, Portfolio} +import com.wavesplatform.state.diffs.TransactionDiffer.TransactionValidationError import com.wavesplatform.test.* import com.wavesplatform.test.DomainPresets.* import com.wavesplatform.transaction.Asset.Waves +import com.wavesplatform.transaction.EthTxGenerator.Arg import com.wavesplatform.transaction.EthereumTransaction.Transfer import com.wavesplatform.transaction.TxValidationError.GenericError import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment -import com.wavesplatform.transaction.{Asset, EthTxGenerator, EthereumTransaction, TxHelpers} import com.wavesplatform.transaction.utils.EthConverters.* -import EthTxGenerator.Arg -import com.wavesplatform.lang.v1.ContractLimits.MaxInvokeScriptSizeInBytes -import com.wavesplatform.state.diffs.TransactionDiffer.TransactionValidationError +import com.wavesplatform.transaction.{Asset, EthTxGenerator, EthereumTransaction, TxHelpers} import com.wavesplatform.utils.{DiffMatchers, EthEncoding, JsonMatchers} import org.web3j.crypto.{Bip32ECKeyPair, RawTransaction} import play.api.libs.json.Json @@ -93,29 +92,28 @@ class EthereumTransactionDiffTest extends FlatSpec with WithDomain with DiffMatc val recipient = TxHelpers.address(2) val issuer = TxHelpers.signer(3) - val fee = TestValues.fee - val feeDiff = Diff(portfolios = Map(senderKp.toWavesAddress -> Portfolio.waves(fee))) - - withDomain(DomainPresets.RideV6.copy(rewardsSettings = RewardsVotingSettings(None)), Seq(AddrWithBalance(senderKp.toWavesAddress))) { d => - val wavesTransfer = EthTxGenerator.generateEthTransfer(senderKp, recipient, 1.waves, Waves, fee) - assertBalanceInvariant(d.createDiff(wavesTransfer).combineF(feeDiff).explicitGet()) + val fee = TestValues.fee + withDomain(RideV6.copy(rewardsSettings = RewardsVotingSettings(None)), Seq(AddrWithBalance(senderKp.toWavesAddress))) { d => + val wavesTransfer = EthTxGenerator.generateEthTransfer(senderKp, recipient, 1.waves, Waves, fee) val transferPayload = wavesTransfer.payload.asInstanceOf[Transfer] d.appendAndAssertSucceed(wavesTransfer) + val rewardAndFee = 6.waves - wavesTransfer.fee * 3 / 5 + assertBalanceInvariant(d.liquidSnapshot, d.rocksDBWriter, rewardAndFee) d.blockchain.balance(recipient) shouldBe transferPayload.amount d.blockchain.balance(senderKp.toWavesAddress) shouldBe ENOUGH_AMT - transferPayload.amount - fee } - withDomain(DomainPresets.RideV6, Seq(AddrWithBalance(senderKp.toWavesAddress), AddrWithBalance(issuer.toAddress))) { d => + withDomain(RideV6, Seq(AddrWithBalance(senderKp.toWavesAddress), AddrWithBalance(issuer.toAddress))) { d => val issue = TxHelpers.issue(issuer) val nativeTransfer = TxHelpers.transfer(issuer, senderKp.toWavesAddress, issue.quantity.value, issue.asset) val assetTransfer = EthTxGenerator.generateEthTransfer(senderKp, recipient, issue.quantity.value, issue.asset, fee) d.appendBlock(issue, nativeTransfer) - assertBalanceInvariant(d.createDiff(assetTransfer).combineF(feeDiff).explicitGet()) - d.appendAndAssertSucceed(assetTransfer) + val rewardAndFee = 6.waves + (issue.fee.value + nativeTransfer.fee.value - assetTransfer.fee) * 3 / 5 + assertBalanceInvariant(d.liquidSnapshot, d.rocksDBWriter, rewardAndFee) d.blockchain.balance(recipient) shouldBe 0L d.blockchain.balance(recipient, issue.asset) shouldBe issue.quantity.value d.blockchain.balance(senderKp.toWavesAddress) shouldBe ENOUGH_AMT - assetTransfer.fee @@ -306,23 +304,23 @@ class EthereumTransactionDiffTest extends FlatSpec with WithDomain with DiffMatc Seq(Payment(321, issue.asset)) ) - val diff = d.transactionDiffer(invoke).resultE.explicitGet() - diff should containAppliedTx(invoke.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson("""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | } ], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val snapshot = d.transactionDiffer(invoke).resultE.explicitGet() + snapshot should containAppliedTx(invoke.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson("""{ + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | } ], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + |}""".stripMargin) } } @@ -395,23 +393,23 @@ class EthereumTransactionDiffTest extends FlatSpec with WithDomain with DiffMatc Seq(), Seq(Payment(321, issue.asset)) ) - val diff = d.transactionDiffer(invoke).resultE.explicitGet() - diff should containAppliedTx(invoke.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson("""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | } ], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val snapshot = d.transactionDiffer(invoke).resultE.explicitGet() + snapshot should containAppliedTx(invoke.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson("""{ + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | } ], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + |}""".stripMargin) } } @@ -438,24 +436,27 @@ class EthereumTransactionDiffTest extends FlatSpec with WithDomain with DiffMatc d.appendBlock(setScript) - val invoke = EthTxGenerator.generateEthInvoke(invoker, dApp.toAddress, "deposit", Seq(), Seq()) - val diff = d.transactionDiffer(invoke).resultE.explicitGet() - diff should containAppliedTx(invoke.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson("""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | } ], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val invoke = EthTxGenerator.generateEthInvoke(invoker, dApp.toAddress, "deposit", Seq(), Seq()) + val snapshot = d.transactionDiffer(invoke).resultE.explicitGet() + snapshot should containAppliedTx(invoke.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson( + """ { + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | } ], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + | } + """.stripMargin + ) } } @@ -526,23 +527,23 @@ class EthereumTransactionDiffTest extends FlatSpec with WithDomain with DiffMatc Seq(), Seq(Payment(321, issue.asset)) ) - val diff = d.transactionDiffer(invoke).resultE.explicitGet() - diff should containAppliedTx(invoke.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson("""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | } ], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val snapshot = d.transactionDiffer(invoke).resultE.explicitGet() + snapshot should containAppliedTx(invoke.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson("""{ + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | } ], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + |}""".stripMargin) } } @@ -580,28 +581,28 @@ class EthereumTransactionDiffTest extends FlatSpec with WithDomain with DiffMatc Seq(), Nil ) - val diff = d.transactionDiffer(invoke).resultE.explicitGet() - diff should containAppliedTx(invoke.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson(s"""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | }, - | { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : "${issue.asset}", - | "amount" : 123 - | }], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val snapshot = d.transactionDiffer(invoke).resultE.explicitGet() + snapshot should containAppliedTx(invoke.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson(s"""{ + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | }, + | { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : "${issue.asset}", + | "amount" : 123 + | }], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + |}""".stripMargin) } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ExchangeTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ExchangeTransactionDiffTest.scala index 94bc8008ade..28084f99e83 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ExchangeTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ExchangeTransactionDiffTest.scala @@ -27,6 +27,7 @@ import com.wavesplatform.test.* import com.wavesplatform.test.DomainPresets.* import com.wavesplatform.transaction.* import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} +import com.wavesplatform.transaction.TxHelpers.defaultAddress import com.wavesplatform.transaction.TxValidationError.{AccountBalanceError, GenericError} import com.wavesplatform.transaction.assets.IssueTransaction import com.wavesplatform.transaction.assets.exchange.* @@ -40,6 +41,7 @@ import com.wavesplatform.{TestValues, TestWallet, crypto} import org.scalatest.{EitherValues, Inside} import org.web3j.crypto.Bip32ECKeyPair +import scala.concurrent.duration.* import scala.util.{Random, Try} class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain with EitherValues with TestWallet with EthHelpers { @@ -328,23 +330,27 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w } preconditionsAndExchange.foreach { case (genesis, issue1, issue2, exchange) => - assertDiffAndState( - Seq(TestBlock.create(genesis :+ issue1 :+ issue2)), - TestBlock.create(Seq(exchange), Block.ProtoBlockVersion), - fsWithOrderFeature - ) { case (blockDiff, _) => - val totalPortfolioDiff: Portfolio = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.balance shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - totalPortfolioDiff.assets.values.toSet should (be(Set()) or be(Set(0))) - - blockDiff.portfolios(exchange.sender.toAddress).balance shouldBe exchange.buyMatcherFee + exchange.sellMatcherFee - exchange.fee.value + withDomain(ScriptsAndSponsorship) { d => + d.appendBlock(genesis*) + d.appendBlock(issue1, issue2) + d.appendBlock(exchange) + d.liquidSnapshot.balances.toSeq + .map { + case ((`defaultAddress`, Waves), amount) => + val carryFee = (issue1.fee.value + issue2.fee.value - exchange.fee.value) * 3 / 5 + Waves -> (amount - d.rocksDBWriter.balance(defaultAddress, Waves) - carryFee) + case ((address, asset), amount) => + asset -> (amount - d.rocksDBWriter.balance(address, asset)) + } + .groupMap(_._1)(_._2) + .foreach { case (_, balances) => balances.sum shouldBe 0 } + d.liquidSnapshot.balances((exchange.sender.toAddress, Waves)) shouldBe + d.rocksDBWriter.balance(exchange.sender.toAddress) + exchange.buyMatcherFee + exchange.sellMatcherFee - exchange.fee.value } } } property("Preserves assets invariant (matcher's fee in one of the assets of the pair or in Waves), stores match info, rewards matcher") { - val preconditionsAndExchange: Seq[(Seq[GenesisTransaction], IssueTransaction, IssueTransaction, ExchangeTransaction)] = { val buyer = TxHelpers.signer(1) val seller = TxHelpers.signer(2) @@ -401,30 +407,35 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w } preconditionsAndExchange.foreach { case (genesis, issue1, issue2, exchange) => - assertDiffAndState( - Seq(TestBlock.create(genesis :+ issue1 :+ issue2)), - TestBlock.create(Seq(exchange), Block.ProtoBlockVersion), - fsWithOrderFeature - ) { case (blockDiff, _) => - val totalPortfolioDiff: Portfolio = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.balance shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - totalPortfolioDiff.assets.values.toSet shouldBe Set(0L) - - val matcherPortfolio = - blockDiff.portfolios.view - .filterKeys(_.toString == exchange.sender.toAddress.toString) - .values - .fold(Portfolio())(_.combine(_).explicitGet()) - - val restoredMatcherPortfolio = + withDomain(ScriptsAndSponsorship) { d => + d.appendBlock(genesis*) + d.appendBlock(issue1, issue2) + d.appendBlock(exchange) + d.liquidSnapshot.balances.toSeq + .map { + case ((`defaultAddress`, Waves), amount) => + val carryFee = (issue1.fee.value + issue2.fee.value - exchange.fee.value) * 3 / 5 + Waves -> (amount - d.rocksDBWriter.balance(defaultAddress, Waves) - carryFee) + case ((address, asset), amount) => + asset -> (amount - d.rocksDBWriter.balance(address, asset)) + } + .groupMap(_._1)(_._2) + .foreach { case (_, balances) => balances.sum shouldBe 0 } + + val sender = exchange.sender.toAddress + val expectedMatcherPortfolio = Seq( ExchangeTransactionDiff.getOrderFeePortfolio(exchange.buyOrder, exchange.buyMatcherFee), ExchangeTransactionDiff.getOrderFeePortfolio(exchange.sellOrder, exchange.sellMatcherFee), wavesPortfolio(-exchange.fee.value) ).fold(Portfolio())(_.combine(_).explicitGet()) - matcherPortfolio shouldBe restoredMatcherPortfolio + d.liquidSnapshot.balances.collect { + case ((`sender`, Waves), balance) => + balance - d.rocksDBWriter.balance(sender) shouldBe expectedMatcherPortfolio.balance + case ((`sender`, asset: IssuedAsset), balance) => + balance - d.rocksDBWriter.balance(sender, asset) shouldBe expectedMatcherPortfolio.assets(asset) + } } } } @@ -475,7 +486,6 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w } property("Preserves assets invariant (matcher's fee in separately issued asset), stores match info, rewards matcher (Orders V3 are used)") { - val preconditionsAndExchange = { val buyer = TxHelpers.signer(1) val seller = TxHelpers.signer(2) @@ -509,35 +519,41 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w matcher, version = TxVersion.V2 ) - (genesis, issue1, issue2, issue3, issue4, exchange) } } preconditionsAndExchange.foreach { case (genesis, issue1, issue2, issue3, issue4, exchange) => - assertDiffAndState( - Seq(TestBlock.create(genesis :+ issue1 :+ issue2 :+ issue3 :+ issue4)), - TestBlock.create(Seq(exchange), Block.ProtoBlockVersion), - fsWithOrderFeature - ) { case (blockDiff, _) => - val totalPortfolioDiff: Portfolio = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.balance shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - totalPortfolioDiff.assets.values.toSet shouldBe Set(0L) - - val matcherPortfolio = - blockDiff.portfolios.view - .filterKeys(_.toString == exchange.sender.toAddress.toString) - .values - .fold(Portfolio())(_.combine(_).explicitGet()) - - val restoredMatcherPortfolio = + withDomain(ScriptsAndSponsorship) { d => + d.appendBlock(genesis*) + d.appendBlock(issue1, issue2, issue3, issue4) + d.appendAndAssertSucceed(exchange) + + val carryFee = (issue1.fee.value + issue2.fee.value + issue3.fee.value + issue4.fee.value - exchange.fee.value) * 3 / 5 + d.liquidSnapshot.balances.toSeq + .map { + case ((`defaultAddress`, Waves), amount) => + Waves -> (amount - d.rocksDBWriter.balance(defaultAddress, Waves) - carryFee) + case ((address, asset), amount) => + asset -> (amount - d.rocksDBWriter.balance(address, asset)) + } + .groupMap(_._1)(_._2) + .foreach { case (_, balanceDiff) => balanceDiff.sum shouldBe 0 } + + val sender = exchange.sender.toAddress + val expectedMatcherPortfolio = Seq( ExchangeTransactionDiff.getOrderFeePortfolio(exchange.buyOrder, exchange.buyMatcherFee), ExchangeTransactionDiff.getOrderFeePortfolio(exchange.sellOrder, exchange.sellMatcherFee), wavesPortfolio(-exchange.fee.value) ).fold(Portfolio())(_.combine(_).explicitGet()) - matcherPortfolio shouldBe restoredMatcherPortfolio + + d.liquidSnapshot.balances.collect { + case ((`sender`, Waves), balance) => + balance - d.rocksDBWriter.balance(sender) shouldBe expectedMatcherPortfolio.balance + case ((`sender`, asset: IssuedAsset), balance) => + balance - d.rocksDBWriter.balance(sender, asset) shouldBe expectedMatcherPortfolio.assets(asset) + } } } } @@ -636,26 +652,25 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w } property("Total matcher's fee (sum of matcher's fees in exchange transactions) is less than or equal to order's matcher fee") { - val preconditions = oneBuyFewSellsPreconditions( - totalBuyMatcherFeeBoundaries = - (bigBuyOrderMatcherFee: Long) => - (bigBuyOrderMatcherFee - 1000L, bigBuyOrderMatcherFee), // sum of buyMatcherFee in ex trs <= specified in bigBuyOrder + totalBuyMatcherFeeBoundaries = identity, sellersTotalAmount = identity ) val (genesises, issueTx1, issueTx2, massTransfer, exchanges, bigBuyOrder) = preconditions - assertDiffAndState( - Seq(TestBlock.create(genesises), TestBlock.create(Seq(issueTx1, issueTx2, massTransfer), Block.ProtoBlockVersion)), - TestBlock.create(exchanges, Block.ProtoBlockVersion), - fsOrderMassTransfer - ) { case (blockDiff, _) => - val totalPortfolioDiff: Portfolio = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - - totalPortfolioDiff.balance shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - totalPortfolioDiff.assets.values.toSet shouldBe Set(0L) + withDomain(RideV3) { d => + d.appendBlock(genesises*) + d.appendBlock(issueTx1, issueTx2, massTransfer) + d.appendBlock(exchanges*) + val carryFee = (issueTx1.fee.value + issueTx2.fee.value + massTransfer.fee.value - exchanges.map(_.fee.value).sum) * 3 / 5 + d.liquidSnapshot.balances.toSeq + .map { + case ((`defaultAddress`, Waves), amount) => Waves -> (amount - d.rocksDBWriter.balance(defaultAddress, Waves) - carryFee) + case ((address, asset), amount) => asset -> (amount - d.rocksDBWriter.balance(address, asset)) + } + .groupMap(_._1)(_._2) + .foreach { case (_, balanceDiff) => balanceDiff.sum shouldBe 0 } val combinedPortfolio = exchanges.map(ex => getOrderFeePortfolio(bigBuyOrder, ex.buyMatcherFee)).fold(Portfolio())(_.combine(_).explicitGet()) @@ -673,8 +688,7 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w val preconditions = oneBuyFewSellsPreconditions( totalBuyMatcherFeeBoundaries = - (bigBuyOrderMatcherFee: Long) => - (bigBuyOrderMatcherFee + 1, bigBuyOrderMatcherFee + 100000L), // sum of buyMatcherFee in ex trs > specified in bigBuyOrder + (bigBuyOrderMatcherFee: Long) => bigBuyOrderMatcherFee + 100000L, // sum of buyMatcherFee in ex trs > specified in bigBuyOrder sellersTotalAmount = identity ) @@ -692,9 +706,8 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w val preconditions = oneBuyFewSellsPreconditions( - totalBuyMatcherFeeBoundaries = - (bigBuyOrderMatcherFee: Long) => (bigBuyOrderMatcherFee - 10000L, bigBuyOrderMatcherFee), // correct total buyMatcherFee in ex trs - sellersTotalAmount = (bigBuyOrderAmount: Long) => bigBuyOrderAmount + 10000L // sell orders overfill buy order + totalBuyMatcherFeeBoundaries = (bigBuyOrderMatcherFee: Long) => bigBuyOrderMatcherFee, // correct total buyMatcherFee in ex trs + sellersTotalAmount = (bigBuyOrderAmount: Long) => bigBuyOrderAmount + 10000L // sell orders overfill buy order ) val (genesises, issueTx1, issueTx2, massTransfer, exchanges, _) = preconditions @@ -762,17 +775,23 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w } preconditions.foreach { case (genesis, issue, exchange) => - assertDiffAndState( - Seq(TestBlock.create(genesis :+ issue)), - TestBlock.create(Seq(exchange), Block.ProtoBlockVersion), - fsWithOrderFeature - ) { case (blockDiff, _) => - val totalPortfolioDiff: Portfolio = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.balance shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - totalPortfolioDiff.assets.values.toSet shouldBe Set(0L) - - blockDiff.portfolios(exchange.sender.toAddress).balance shouldBe exchange.buyMatcherFee + exchange.sellMatcherFee - exchange.fee.value + withDomain(ScriptsAndSponsorship) { d => + d.appendBlock(genesis*) + d.appendBlock(issue) + d.appendBlock(exchange) + d.liquidSnapshot.balances.toSeq + .map { + case ((`defaultAddress`, Waves), amount) => + val carryFee = (issue.fee.value - exchange.fee.value) * 3 / 5 + Waves -> (amount - d.rocksDBWriter.balance(defaultAddress, Waves) - carryFee) + case ((address, asset), amount) => + asset -> (amount - d.rocksDBWriter.balance(address, asset)) + } + .groupMap(_._1)(_._2) + .foreach { case (_, balanceDiff) => balanceDiff.sum shouldBe 0 } + + d.liquidSnapshot.balances((exchange.sender.toAddress, Waves)) shouldBe + d.rocksDBWriter.balance(exchange.sender.toAddress, Waves) + exchange.buyMatcherFee + exchange.sellMatcherFee - exchange.fee.value } assertDiffEi( @@ -819,8 +838,8 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w TxHelpers.order(OrderType.BUY, issue.asset, Waves, amount = 1000000L, fee = MatcherFee, sender = buyer, matcher = matcher, version = Order.V1) val sell = TxHelpers.order(OrderType.SELL, issue.asset, Waves, fee = MatcherFee, sender = seller, matcher = matcher, version = Order.V1) val tx = createExTx(buy, sell, buy.price.value, matcher) - assertDiffAndState(Seq(TestBlock.create(genesis :+ issue)), TestBlock.create(Seq(tx)), fs) { case (blockDiff, state) => - blockDiff.portfolios(tx.sender.toAddress).balance shouldBe tx.buyMatcherFee + tx.sellMatcherFee - tx.fee.value + assertDiffAndState(Seq(TestBlock.create(genesis :+ issue)), TestBlock.create(Seq(tx)), fs) { case (snapshot, state) => + snapshot.balances((tx.sender.toAddress, Waves)) shouldBe tx.buyMatcherFee + tx.sellMatcherFee - tx.fee.value state.balance(tx.sender.toAddress) shouldBe 1L } } @@ -861,14 +880,14 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w version = Order.V1 ) val tx = createExTx(buy, sell, buy.price.value, matcher) - assertDiffEi(Seq(TestBlock.create(genesis :+ issue)), TestBlock.create(Seq(tx)), fsWithOrderFeature) { totalDiffEi => - inside(totalDiffEi) { case Left(TransactionValidationError(AccountBalanceError(errs), _)) => + assertDiffEi(Seq(TestBlock.create(genesis :+ issue)), TestBlock.create(Seq(tx)), fsWithOrderFeature) { snapshotEi => + inside(snapshotEi) { case Left(TransactionValidationError(AccountBalanceError(errs), _)) => errs should contain key seller.toAddress } } } - property("Diff for ExchangeTransaction works as expected and doesn't use rounding inside") { + property("StateSnapshot for ExchangeTransaction works as expected and doesn't use rounding inside") { val MatcherFee = 300000L val preconditions: (KeyPair, KeyPair, KeyPair, Seq[GenesisTransaction], IssueTransaction) = { @@ -917,14 +936,13 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w fee = buy.matcherFee.value, version = TxVersion.V1 ) - - assertDiffEi(Seq(TestBlock.create(genesis :+ issue)), TestBlock.create(Seq(tx))) { totalDiffEi => - inside(totalDiffEi) { case Right(diff) => - import diff.portfolios - portfolios(buyer.toAddress).balance shouldBe (-41L + 425532L) - portfolios(seller.toAddress).balance shouldBe (-300000L - 425532L) - portfolios(matcher.toAddress).balance shouldBe (+41L + 300000L - tx.fee.value) - } + withDomain(ScriptsAndSponsorship) { d => + d.appendBlock(genesis*) + d.appendBlock(issue) + d.appendBlock(tx) + d.liquidSnapshot.balances((buyer.toAddress, Waves)) shouldBe d.rocksDBWriter.balance(buyer.toAddress) - 41 + 425532 + d.liquidSnapshot.balances((seller.toAddress, Waves)) shouldBe d.rocksDBWriter.balance(seller.toAddress) - 300000 - 425532 + d.liquidSnapshot.balances((matcher.toAddress, Waves)) shouldBe d.rocksDBWriter.balance(seller.toAddress) + 41 + 300000 - tx.fee.value } } @@ -983,8 +1001,8 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w TestBlock.create(transfers), TestBlock.create(issueAndScripts) ) - assertDiffEi(preconBlocks, TestBlock.create(Seq(exchangeTx)), fsV2) { diff => - diff.isRight shouldBe true + assertDiffEi(preconBlocks, TestBlock.create(Seq(exchangeTx)), fsV2) { snapshot => + snapshot.isRight shouldBe true } } } @@ -1296,9 +1314,7 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w ) val test = TestBlock.create(Seq(exchangeTx)) if (o1.version == 2 && o2.version == 2) { - assertDiffEi(pretest, test, fs) { diff => - diff.explicitGet() - } + assertDiffEi(pretest, test, fs)(_.explicitGet()) } else { assertLeft(pretest, test, fs)("Can't process order with signature from scripted account") } @@ -1505,7 +1521,7 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w ) forAll(scenarios) { case (txWithV3, txWithV4AsV3, txWithV4, txWithV3V4AsV3, txWithV3V4, txWithV4AsV3V3, txWithV4V3) => - val portfolios = collection.mutable.ListBuffer[Map[Address, Portfolio]]() + val balances = collection.mutable.ListBuffer[Map[(Address, Asset), Long]]() Seq(txWithV3, txWithV4AsV3, txWithV4, txWithV3V4AsV3, txWithV3V4, txWithV4AsV3V3, txWithV4V3) .foreach { tx => @@ -1513,13 +1529,13 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w preconditions, TestBlock.create(Seq(tx), Block.ProtoBlockVersion), DomainPresets.RideV6.blockchainSettings.functionalitySettings - ) { case (blockDiff, _) => - portfolios += blockDiff.portfolios + ) { case (snapshot, _) => + balances += snapshot.balances } } // all portfolios built on the state and on the composite blockchain are equal - portfolios.distinct.size shouldBe 1 + balances.distinct.size shouldBe 1 } } @@ -1592,14 +1608,14 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w } scenario.foreach { case (preconditions, fixed, reversed) => - val portfolios = collection.mutable.ListBuffer[Map[Address, Portfolio]]() + val portfolios = collection.mutable.ListBuffer[Map[(Address, Asset), Long]]() - assertDiffAndState(preconditions, TestBlock.create(Seq(fixed)), fsWithBlockV5) { case (diff, _) => - portfolios += diff.portfolios + assertDiffAndState(preconditions, TestBlock.create(Seq(fixed)), fsWithBlockV5) { case (snapshot, _) => + portfolios += snapshot.balances } - assertDiffAndState(preconditions, TestBlock.create(Seq(reversed)), fsWithBlockV5) { case (diff, _) => - portfolios += diff.portfolios + assertDiffAndState(preconditions, TestBlock.create(Seq(reversed)), fsWithBlockV5) { case (snapshot, _) => + portfolios += snapshot.balances } portfolios.tail.forall(_ == portfolios.head) shouldBe true @@ -1669,33 +1685,35 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w assertDiffEi(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(exchange), Block.ProtoBlockVersion), fsWithOrderFeature) { ei => ei.left.value } - assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(exchange), Block.ProtoBlockVersion), fsWithBlockV5) { - case (diff, state) => - diff.scriptsComplexity shouldBe 1 // throw() - diff.portfolios(exchange.sender.toAddress).balance shouldBe -exchange.fee.value - diff.portfolios.get(exchange.buyOrder.sender.toAddress) shouldBe None - diff.portfolios.get(exchange.sellOrder.sender.toAddress) shouldBe None - - diff.scriptsComplexity shouldBe DiffsCommon - .countVerifierComplexity(Some(throwingScript), state, isAsset = true) - .explicitGet() - .get - ._2 - - buyerBalance.foreach { case (asset, balance) => - state.balance(exchange.buyOrder.sender.toAddress, asset) shouldBe balance - } - sellerBalance.foreach { case (asset, balance) => - state.balance(exchange.sellOrder.sender.toAddress, asset) shouldBe balance - } + withDomain(RideV4) { d => + d.appendBlock(genesisTxs*) + d.appendBlock(exchange) + d.liquidSnapshot.scriptsComplexity shouldBe 1 // throw() + d.liquidSnapshot + .balances((exchange.sender.toAddress, Waves)) shouldBe d.rocksDBWriter.balance(exchange.sender.toAddress, Waves) - exchange.fee.value + d.liquidSnapshot.balances.get((exchange.buyOrder.sender.toAddress, Waves)) shouldBe None + d.liquidSnapshot.balances.get((exchange.sellOrder.sender.toAddress, Waves)) shouldBe None + + d.liquidSnapshot.scriptsComplexity shouldBe DiffsCommon + .countVerifierComplexity(Some(throwingScript), d.blockchain, isAsset = true) + .explicitGet() + .get + ._2 - state.balance(exchange.sender.toAddress, Waves) shouldBe matcherBalance(Waves) - exchange.fee.value - matcherBalance.collect { case b @ (IssuedAsset(_), _) => b }.foreach { case (asset, balance) => - diff.portfolios(exchange.sender.toAddress).balanceOf(asset) shouldBe 0L - state.balance(exchange.sender.toAddress, asset) shouldBe balance - } + buyerBalance.foreach { case (asset, balance) => + d.balance(exchange.buyOrder.sender.toAddress, asset) shouldBe balance + } + sellerBalance.foreach { case (asset, balance) => + d.balance(exchange.sellOrder.sender.toAddress, asset) shouldBe balance + } - state.transactionInfo(exchange.id()).map(r => r._2 -> (r._1.status == Status.Succeeded)) shouldBe Some((exchange, false)) + d.balance(exchange.sender.toAddress, Waves) shouldBe matcherBalance(Waves) - exchange.fee.value + matcherBalance.collect { case b @ (IssuedAsset(_), _) => b }.foreach { case (asset, balance) => + d.liquidSnapshot.balances.get((exchange.sender.toAddress, asset)) shouldBe None + d.balance(exchange.sender.toAddress, asset) shouldBe balance + } + + d.blockchain.transactionInfo(exchange.id()).map(r => r._2 -> (r._1.status == Status.Succeeded)) shouldBe Some((exchange, false)) } } } @@ -1726,7 +1744,7 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w withDomain(RideV4) { d => d.appendBlock(Seq(amountAssetIssue, priceAssetIssue, order1FeeAssetIssue, order2FeeAssetIssue).distinct*) d.appendAndAssertFailed(exchange) - d.liquidDiff.scriptsComplexity shouldBe complexity + d.liquidSnapshot.scriptsComplexity shouldBe complexity } } @@ -1798,10 +1816,10 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w ) { d => d.appendBlock(Seq(tradeableAssetIssue, feeAssetIssue).distinct*) val newBlock = d.createBlock(2.toByte, Seq(exchange)) - val diff = BlockDiffer + val snapshot = BlockDiffer .fromBlock(d.blockchainUpdater, Some(d.lastBlock), newBlock, None, MiningConstraint.Unlimited, newBlock.header.generationSignature) .explicitGet() - diff.snapshot.scriptsComplexity shouldBe complexity + snapshot.snapshot.scriptsComplexity shouldBe complexity val feeUnits = FeeValidation.getMinFee(d.blockchainUpdater, exchange).explicitGet().minFeeInWaves / FeeValidation.FeeUnit if (complexity > 0) feeUnits shouldBe 7 @@ -1907,10 +1925,10 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w defaultSigner.publicKey, AssetPair(issue.asset, Waves), OrderType.BUY, - TxExchangeAmount.unsafeFrom(1), - TxOrderPrice.unsafeFrom(1), + TxExchangeAmount(1), + TxOrderPrice(1), System.currentTimeMillis(), - System.currentTimeMillis() + 10000, + System.currentTimeMillis() + 1.day.toMillis, TxMatcherFee.unsafeFrom(0.003.waves) ) val signedBuyOrder = buyOrder.copy( @@ -1973,8 +1991,8 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w defaultSigner.publicKey, AssetPair(issue.asset, Waves), OrderType.BUY, - TxExchangeAmount.unsafeFrom(1), - TxOrderPrice.unsafeFrom(1), + TxExchangeAmount(1), + TxOrderPrice(1), System.currentTimeMillis(), System.currentTimeMillis() + 10000, TxMatcherFee.unsafeFrom(0.003.waves) @@ -2184,7 +2202,7 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w totalMatcherFee: Long ): Seq[Order] = { val randomAmountsAndFees = - getSeqWithPredefinedSum(totalAmount, sellers.length) zip getSeqWithPredefinedSum(totalMatcherFee, sellers.length) + getSeqWithPredefinedSum(totalAmount, sellers.length) zip getSeqWithPredefinedSum(totalMatcherFee / 10, sellers.length).map(_ * 10) val sellers2AmountsAndFees = sellers zip randomAmountsAndFees @@ -2211,7 +2229,7 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w * function for manipulating of total sell orders amount */ def oneBuyFewSellsPreconditions( - totalBuyMatcherFeeBoundaries: Long => (Long, Long), + totalBuyMatcherFeeBoundaries: Long => Long, sellersTotalAmount: Long => Long ): (Seq[GenesisTransaction], IssueTransaction, IssueTransaction, MassTransferTransaction, Seq[ExchangeTransaction], Order) = { val matcher = TxHelpers.signer(1) @@ -2220,12 +2238,12 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w val buyer = TxHelpers.signer(sellOrdersCount + 2) val bigBuyOrderAmount = 3 * 100000L * 100000000L val price = 3 * 100000L - val bigBuyOrderMatcherFee = 100000L + val bigBuyOrderMatcherFee = 1000000L - val issue1 = TxHelpers.issue(buyer, Long.MaxValue - 1000L, name = "asset1") - val issue2 = TxHelpers.issue(buyer, Long.MaxValue - 1000L, name = "asset2") + val issue1 = TxHelpers.issue(buyer, Long.MaxValue - 1_000_000, name = "asset1") + val issue2 = TxHelpers.issue(buyer, Long.MaxValue - 1_000_000, name = "asset2") - val totalBuyMatcherFeeForExchangeTransactions = totalBuyMatcherFeeBoundaries(bigBuyOrderMatcherFee)._2 + val totalBuyMatcherFeeForExchangeTransactions = totalBuyMatcherFeeBoundaries(bigBuyOrderMatcherFee) val bigBuyOrder = TxHelpers.order( orderType = OrderType.BUY, @@ -2255,11 +2273,11 @@ class ExchangeTransactionDiffTest extends PropSpec with Inside with WithDomain w from = buyer, to = sellers.map(seller => ParsedTransfer(seller.toAddress, TxNonNegativeAmount.unsafeFrom(issue2.quantity.value / sellOrdersCount))), asset = issue2.asset, - fee = 1000L, + fee = 1_000_000, version = TxVersion.V1 ) - val buyMatcherFees = getSeqWithPredefinedSum(totalBuyMatcherFeeForExchangeTransactions, sellOrdersCount) + val buyMatcherFees = getSeqWithPredefinedSum(totalBuyMatcherFeeForExchangeTransactions / 10, sellOrdersCount).map(_ * 10) val exchanges = (sellOrders zip buyMatcherFees).map { case (sellOrder, buyMatcherFee) => TxHelpers.exchange( diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/GenesisTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/GenesisTransactionDiffTest.scala index a8b01f33b1d..081c29be129 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/GenesisTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/GenesisTransactionDiffTest.scala @@ -1,13 +1,13 @@ package com.wavesplatform.state.diffs -import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.db.WithDomain import com.wavesplatform.lagonaki.mocks.TestBlock -import com.wavesplatform.state.* import com.wavesplatform.test.* import com.wavesplatform.test.DomainPresets.RideV6 +import com.wavesplatform.transaction.Asset.Waves import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.TxHelpers.{defaultAddress, genesis} +import org.scalatest.exceptions.TestFailedException class GenesisTransactionDiffTest extends PropSpec with WithDomain { property("fails if height != 1") { @@ -17,17 +17,16 @@ class GenesisTransactionDiffTest extends PropSpec with WithDomain { } } - property("Diff establishes Waves invariant") { + property("StateSnapshot establishes Waves invariant") { val genesis = (1 to 10).map(idx => TxHelpers.genesis(TxHelpers.address(idx), 10000)) - assertDiffAndState(Seq.empty, TestBlock.create(genesis)) { (blockDiff, _) => - val totalPortfolio = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolio.balance shouldBe genesis.map(_.amount.value).sum - totalPortfolio.effectiveBalance(false).explicitGet() shouldBe genesis.map(_.amount.value).sum - totalPortfolio.assets shouldBe Map.empty - + blockDiff.balances.collect { + case ((_, Waves), amount) => amount + case ((_, asset), _) => throw new TestFailedException(s"unexpected $asset", 0) + }.sum shouldBe genesis.map(_.amount.value).sum + blockDiff.leaseBalances shouldBe empty genesis.foreach { gtx => - blockDiff.portfolios(gtx.recipient).balance shouldBe gtx.amount.value + blockDiff.balances((gtx.recipient, Waves)) shouldBe gtx.amount.value } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/LeaseTransactionsDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/LeaseTransactionsDiffTest.scala index d789f1853f5..be960af7373 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/LeaseTransactionsDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/LeaseTransactionsDiffTest.scala @@ -12,10 +12,13 @@ import com.wavesplatform.settings.TestFunctionalitySettings import com.wavesplatform.state.* import com.wavesplatform.test.* import com.wavesplatform.test.DomainPresets.* +import com.wavesplatform.transaction.Asset.Waves import com.wavesplatform.transaction.lease.{LeaseCancelTransaction, LeaseTransaction} import com.wavesplatform.transaction.transfer.* import com.wavesplatform.transaction.{GenesisTransaction, TxHelpers, TxVersion} +import scala.collection.immutable.VectorMap + class LeaseTransactionsDiffTest extends PropSpec with WithDomain { private val allowMultipleLeaseCancelTransactionUntilTimestamp = Long.MaxValue / 2 @@ -25,33 +28,33 @@ class LeaseTransactionsDiffTest extends PropSpec with WithDomain { def total(l: LeaseBalance): Long = l.in - l.out property("can lease/cancel lease preserving waves invariant") { - - val sunnyDayLeaseLeaseCancel: Seq[(GenesisTransaction, LeaseTransaction, LeaseCancelTransaction)] = { - val master = TxHelpers.signer(1) - val recipient = TxHelpers.signer(2) - - val genesis = TxHelpers.genesis(master.toAddress) - for { - lease <- Seq(TxHelpers.lease(master, recipient.toAddress), TxHelpers.lease(master, recipient.toAddress, version = TxVersion.V1)) - leaseCancel <- Seq(TxHelpers.leaseCancel(lease.id(), master), TxHelpers.leaseCancel(lease.id(), master, version = TxVersion.V1)) - } yield (genesis, lease, leaseCancel) - } - - sunnyDayLeaseLeaseCancel.foreach { case (genesis, lease, leaseCancel) => - assertDiffAndState(Seq(TestBlock.create(Seq(genesis))), TestBlock.create(Seq(lease))) { case (totalDiff, _) => - val totalPortfolioDiff = totalDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.balance shouldBe 0 - total(totalPortfolioDiff.lease) shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - totalPortfolioDiff.assets.values.foreach(_ shouldBe 0) + val sender = TxHelpers.signer(1) + val recipient = TxHelpers.signer(2) + val miner = TestBlock.defaultSigner.toAddress + val genesis = TxHelpers.genesis(sender.toAddress) + for { + lease <- Seq(TxHelpers.lease(sender, recipient.toAddress), TxHelpers.lease(sender, recipient.toAddress, version = TxVersion.V1)) + leaseCancel <- Seq(TxHelpers.leaseCancel(lease.id(), sender), TxHelpers.leaseCancel(lease.id(), sender, version = TxVersion.V1)) + } { + assertDiffAndState(Seq(TestBlock.create(Seq(genesis))), TestBlock.create(Seq(lease))) { case (snapshot, _) => + snapshot.balances shouldBe VectorMap( + (sender.toAddress, Waves) -> (genesis.amount.value - lease.fee.value), + (miner, Waves) -> lease.fee.value + ) + snapshot.leaseBalances shouldBe Map( + sender.toAddress -> LeaseBalance(0, lease.amount.value), + recipient.toAddress -> LeaseBalance(lease.amount.value, 0) + ) } - - assertDiffAndState(Seq(TestBlock.create(Seq(genesis, lease))), TestBlock.create(Seq(leaseCancel))) { case (totalDiff, _) => - val totalPortfolioDiff = totalDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.balance shouldBe 0 - total(totalPortfolioDiff.lease) shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 - totalPortfolioDiff.assets.values.foreach(_ shouldBe 0) + assertDiffAndState(Seq(TestBlock.create(Seq(genesis, lease))), TestBlock.create(Seq(leaseCancel))) { case (snapshot, _) => + snapshot.balances shouldBe VectorMap( + (miner, Waves) -> (lease.fee.value + leaseCancel.fee.value), + (sender.toAddress, Waves) -> (genesis.amount.value - lease.fee.value - leaseCancel.fee.value) + ) + snapshot.leaseBalances shouldBe Map( + sender.toAddress -> LeaseBalance.empty, + recipient.toAddress -> LeaseBalance.empty + ) } } } @@ -96,8 +99,8 @@ class LeaseTransactionsDiffTest extends PropSpec with WithDomain { property("cannot cancel lease twice after allowMultipleLeaseCancelTransactionUntilTimestamp") { disallowCancelTwice.foreach { case (preconditions, block) => - assertDiffEi(preconditions, block, settings) { totalDiffEi => - totalDiffEi should produce("Cannot cancel already cancelled lease") + assertDiffEi(preconditions, block, settings) { snapshotEi => + snapshotEi should produce("Cannot cancel already cancelled lease") } } } @@ -112,8 +115,8 @@ class LeaseTransactionsDiffTest extends PropSpec with WithDomain { property("can cancel lease twice before allowMultipleLeaseCancelTransactionUntilTimestamp") { allowCancelTwice.foreach { case (preconditions, block) => - assertDiffEi(preconditions, block, settings) { totalDiffEi => - totalDiffEi.explicitGet() + assertDiffEi(preconditions, block, settings) { snapshotEi => + snapshotEi.explicitGet() } } } @@ -133,8 +136,8 @@ class LeaseTransactionsDiffTest extends PropSpec with WithDomain { } setup.foreach { case (genesis, lease, leaseForward, ts) => - assertDiffEi(Seq(TestBlock.create(ts, Seq(genesis, lease))), TestBlock.create(ts, Seq(leaseForward)), settings) { totalDiffEi => - totalDiffEi should produce("Cannot lease more than own") + assertDiffEi(Seq(TestBlock.create(ts, Seq(genesis, lease))), TestBlock.create(ts, Seq(leaseForward)), settings) { snapshotEi => + snapshotEi should produce("Cannot lease more than own") } } } @@ -171,18 +174,23 @@ class LeaseTransactionsDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(blockTime, genesis :+ lease)), TestBlock.create(blockTime, Seq(unleaseOtherOrRecipient)), settings - ) { totalDiffEi => - totalDiffEi should produce("LeaseTransaction was leased by other sender") + ) { snapshotEi => + snapshotEi should produce("LeaseTransaction was leased by other sender") } } } property("can cancel lease of another sender and acquire leasing power before allowMultipleLeaseCancelTransactionUntilTimestamp") { cancelLeaseOfAnotherSender(unleaseByRecipient = false, repeatedCancelAllowed).foreach { case (genesis, lease, unleaseOther, blockTime) => - assertDiffAndState(Seq(TestBlock.create(genesis :+ lease)), TestBlock.create(blockTime, Seq(unleaseOther)), settings) { case (totalDiff, _) => - totalDiff.portfolios.get(lease.sender.toAddress) shouldBe None - total(totalDiff.portfolios(lease.recipient.asInstanceOf[Address]).lease) shouldBe -lease.amount.value - total(totalDiff.portfolios(unleaseOther.sender.toAddress).lease) shouldBe lease.amount.value + withDomain(ScriptsAndSponsorship.configure(_.copy(lastTimeBasedForkParameter = allowMultipleLeaseCancelTransactionUntilTimestamp))) { d => + d.appendBlock(genesis*) + d.appendBlock(lease) + d.appendBlock(TestBlock.create(blockTime, d.lastBlockId, Seq(unleaseOther)).block) + d.liquidSnapshot.balances.get((lease.sender.toAddress, Waves)) shouldBe None + val recipient = lease.recipient.asInstanceOf[Address] + val unleaser = unleaseOther.sender.toAddress + total(d.liquidSnapshot.leaseBalances(recipient)) shouldBe total(d.rocksDBWriter.leaseBalance(recipient)) - lease.amount.value + total(d.liquidSnapshot.leaseBalances(unleaser)) shouldBe total(d.rocksDBWriter.leaseBalance(unleaser)) + lease.amount.value } } } @@ -191,13 +199,13 @@ class LeaseTransactionsDiffTest extends PropSpec with WithDomain { "if recipient cancels lease, it doesn't change leasing component of mining power before allowMultipleLeaseCancelTransactionUntilTimestamp" ) { cancelLeaseOfAnotherSender(unleaseByRecipient = true, repeatedCancelAllowed).foreach { case (genesis, lease, unleaseRecipient, blockTime) => - assertDiffAndState( - Seq(TestBlock.create(blockTime, genesis :+ lease)), - TestBlock.create(blockTime, Seq(unleaseRecipient)), - settings - ) { case (totalDiff, _) => - totalDiff.portfolios.get(lease.sender.toAddress) shouldBe None - total(totalDiff.portfolios(unleaseRecipient.sender.toAddress).lease) shouldBe 0 + withDomain(ScriptsAndSponsorship.configure(_.copy(lastTimeBasedForkParameter = allowMultipleLeaseCancelTransactionUntilTimestamp))) { d => + d.appendBlock(genesis*) + d.appendBlock(lease) + d.appendBlock(TestBlock.create(blockTime, d.lastBlockId, Seq(unleaseRecipient)).block) + d.liquidSnapshot.balances.get((lease.sender.toAddress, Waves)) shouldBe None + val unleaser = unleaseRecipient.sender.toAddress + total(d.liquidSnapshot.leaseBalances(unleaser)) shouldBe total(d.rocksDBWriter.leaseBalance(unleaser)) } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/MassTransferTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/MassTransferTransactionDiffTest.scala index 5ad175a2321..1a534bb85cc 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/MassTransferTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/MassTransferTransactionDiffTest.scala @@ -3,16 +3,17 @@ package com.wavesplatform.state.diffs import com.wavesplatform.account.{Address, Alias, KeyPair} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2 -import com.wavesplatform.db.WithState +import com.wavesplatform.db.WithDomain import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.lagonaki.mocks.TestBlock.create as block import com.wavesplatform.settings.{FunctionalitySettings, TestFunctionalitySettings} import com.wavesplatform.test.* +import com.wavesplatform.test.DomainPresets.ScriptsAndSponsorship import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.transfer.MassTransferTransaction.ParsedTransfer import com.wavesplatform.transaction.{Asset, GenesisTransaction, TxHelpers, TxNonNegativeAmount, TxVersion} -class MassTransferTransactionDiffTest extends PropSpec with WithState { +class MassTransferTransactionDiffTest extends PropSpec with WithDomain { val fs: FunctionalitySettings = TestFunctionalitySettings.Enabled.copy(preActivatedFeatures = Map(BlockchainFeatures.MassTransfer.id -> 0)) @@ -35,42 +36,45 @@ class MassTransferTransactionDiffTest extends PropSpec with WithState { Seq(Some(issue.id()), None).map { issueIdOpt => val maybeAsset = Asset.fromCompatId(issueIdOpt) - val transfer = TxHelpers.massTransfer(master, transfers, maybeAsset, version = TxVersion.V1) + val transfer = TxHelpers.massTransfer(master, transfers, maybeAsset, fee = 1.waves, version = TxVersion.V1) (genesis, issue, transfer) } } - setup.foreach { - case (genesis, issue, transfer) => - assertDiffAndState(Seq(block(Seq(genesis, issue))), block(Seq(transfer)), fs) { - case (totalDiff, newState) => - assertBalanceInvariant(totalDiff) - - val totalAmount = transfer.transfers.map(_.amount.value).sum - val fees = issue.fee.value + transfer.fee.value + setup.foreach { case (genesis, issue, transfer) => + withDomain(ScriptsAndSponsorship) { d => + d.appendBlock(genesis) + d.appendBlock(issue) + d.appendBlock(transfer) + + val carryFee = (issue.fee.value - transfer.fee.value) * 3 / 5 + assertBalanceInvariant(d.liquidSnapshot, d.rocksDBWriter, carryFee) + + val totalAmount = transfer.transfers.map(_.amount.value).sum + val fees = issue.fee.value + transfer.fee.value + transfer.assetId match { + case aid @ IssuedAsset(_) => + d.balance(transfer.sender.toAddress) shouldBe ENOUGH_AMT - fees + d.balance(transfer.sender.toAddress, aid) shouldBe ENOUGH_AMT - totalAmount + case Waves => + d.balance(transfer.sender.toAddress) shouldBe ENOUGH_AMT - fees - totalAmount + } + for (ParsedTransfer(recipient, amount) <- transfer.transfers) { + if (transfer.sender.toAddress != recipient) { transfer.assetId match { case aid @ IssuedAsset(_) => - newState.balance(transfer.sender.toAddress) shouldBe ENOUGH_AMT - fees - newState.balance(transfer.sender.toAddress, aid) shouldBe ENOUGH_AMT - totalAmount + d.balance(recipient.asInstanceOf[Address], aid) shouldBe amount.value case Waves => - newState.balance(transfer.sender.toAddress) shouldBe ENOUGH_AMT - fees - totalAmount - } - for (ParsedTransfer(recipient, amount) <- transfer.transfers) { - if (transfer.sender.toAddress != recipient) { - transfer.assetId match { - case aid @ IssuedAsset(_) => - newState.balance(recipient.asInstanceOf[Address], aid) shouldBe amount.value - case Waves => - newState.balance(recipient.asInstanceOf[Address]) shouldBe amount.value - } - } + d.balance(recipient.asInstanceOf[Address]) shouldBe amount.value } + } } + } } } - import com.wavesplatform.transaction.transfer.MassTransferTransaction.{MaxTransferCount => Max} + import com.wavesplatform.transaction.transfer.MassTransferTransaction.MaxTransferCount as Max Seq(0, 1, Max) foreach testDiff // test edge cases testDiff(5) } @@ -79,7 +83,7 @@ class MassTransferTransactionDiffTest extends PropSpec with WithState { val setup = { val (genesis, master) = baseSetup val recipient = Alias.create("alias").explicitGet() - val transfer = TxHelpers.massTransfer(master, Seq(ParsedTransfer(recipient, TxNonNegativeAmount.unsafeFrom(100000L))), version = TxVersion.V1) + val transfer = TxHelpers.massTransfer(master, Seq(ParsedTransfer(recipient, TxNonNegativeAmount.unsafeFrom(100000L))), version = TxVersion.V1) (genesis, transfer) } @@ -120,11 +124,10 @@ class MassTransferTransactionDiffTest extends PropSpec with WithState { } } - setup.foreach { - case (genesis, transfer) => - assertDiffEi(Seq(block(Seq(genesis))), block(Seq(transfer)), fs) { blockDiffEi => - blockDiffEi should produce("Attempt to transfer unavailable funds") - } + setup.foreach { case (genesis, transfer) => + assertDiffEi(Seq(block(Seq(genesis))), block(Seq(transfer)), fs) { blockDiffEi => + blockDiffEi should produce("Attempt to transfer unavailable funds") + } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/PaymentTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/PaymentTransactionDiffTest.scala index 5cf85cf7ea7..135bc57fdd6 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/PaymentTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/PaymentTransactionDiffTest.scala @@ -1,10 +1,8 @@ package com.wavesplatform.state.diffs -import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.db.WithState import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.settings.{FunctionalitySettings, TestFunctionalitySettings} -import com.wavesplatform.state.* import com.wavesplatform.test.* import com.wavesplatform.transaction.{GenesisTransaction, PaymentTransaction, TxHelpers} @@ -23,12 +21,11 @@ class PaymentTransactionDiffTest extends PropSpec with WithState { val settings: FunctionalitySettings = TestFunctionalitySettings.Enabled.copy(blockVersion3AfterHeight = 2) - property("Diff doesn't break invariant before block version 3") { - preconditionsAndPayments.foreach { case ((genesis, paymentV2, _)) => - assertDiffAndState(Seq(TestBlock.create(Seq(genesis))), TestBlock.create(Seq(paymentV2)), settings) { (blockDiff, newState) => - val totalPortfolioDiff: Portfolio = blockDiff.portfolios.values.fold(Portfolio())(_.combine(_).explicitGet()) - totalPortfolioDiff.balance shouldBe 0 - totalPortfolioDiff.effectiveBalance(false).explicitGet() shouldBe 0 + property("StateSnapshot doesn't break invariant before block version 3") { + preconditionsAndPayments.foreach { case (genesis, paymentV2, _) => + assertDiffAndState(Seq(TestBlock.create(Seq(genesis))), TestBlock.create(Seq(paymentV2)), settings) { (blockDiff, blockchain) => + blockDiff.balances.map { case ((address, asset), amount) => blockchain.balance(address, asset) - amount }.sum shouldBe 0 + blockDiff.leaseBalances shouldBe empty } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/SetScriptTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/SetScriptTransactionDiffTest.scala index 20641ba4523..bd8296a5d23 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/SetScriptTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/SetScriptTransactionDiffTest.scala @@ -435,7 +435,7 @@ class SetScriptTransactionDiffTest extends PropSpec with WithDomain { withDomain(domainSettingsWithFS(settings()), balances) { db => val tx = setScript() db.appendBlock(tx) - db.liquidDiff.errorMessage(tx.id()) shouldBe None + db.liquidSnapshot.errorMessage(tx.id()) shouldBe None } withDomain(domainSettingsWithFS(settings(checkNegative = true)), balances) { db => diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/DiffProduceError.scala b/node/src/test/scala/com/wavesplatform/state/diffs/SnapshotProduceError.scala similarity index 73% rename from node/src/test/scala/com/wavesplatform/state/diffs/DiffProduceError.scala rename to node/src/test/scala/com/wavesplatform/state/diffs/SnapshotProduceError.scala index 1412039e6e2..aabc0577707 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/DiffProduceError.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/SnapshotProduceError.scala @@ -1,13 +1,13 @@ package com.wavesplatform.state.diffs -import com.wavesplatform.state.Diff +import com.wavesplatform.state.StateSnapshot import org.scalatest.matchers.{MatchResult, Matcher} -class DiffProduceError(errorMessage: String, requireFailed: Boolean) extends Matcher[Either[_, _]] { +class SnapshotProduceError(errorMessage: String, requireFailed: Boolean) extends Matcher[Either[_, _]] { override def apply(ei: Either[_, _]): MatchResult = { ei match { - case r @ Right(diff: Diff) => - diff.scriptResults.values.find(_.error.exists(_.text.contains(errorMessage))) match { + case r @ Right(snapshot: StateSnapshot) => + snapshot.scriptResults.values.find(_.error.exists(_.text.contains(errorMessage))) match { case Some(_) => MatchResult(matches = true, "", "", Vector.empty) case None => MatchResult(matches = false, "expecting Left(...{0}...) but got {1}", "got expected error", IndexedSeq(errorMessage, r)) } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/SponsorshipDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/SponsorshipDiffTest.scala index 4d281bf0267..85dc1cff51b 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/SponsorshipDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/SponsorshipDiffTest.scala @@ -36,16 +36,16 @@ class SponsorshipDiffTest extends PropSpec with WithState { val cancel = TxHelpers.sponsor(issue.asset, None, master, fee = sponsorTxFee) val setupBlocks = Seq(block(Seq(genesis, issue))) - assertDiffAndState(setupBlocks, block(Seq(sponsor)), s) { case (diff, state) => - diff.sponsorship shouldBe Map(sponsor.asset -> SponsorshipValue(sponsor.minSponsoredAssetFee.get.value)) + assertDiffAndState(setupBlocks, block(Seq(sponsor)), s) { case (snapshot, state) => + snapshot.sponsorships shouldBe Map(sponsor.asset -> SponsorshipValue(sponsor.minSponsoredAssetFee.get.value)) state.assetDescription(sponsor.asset).map(_.sponsorship) shouldBe sponsor.minSponsoredAssetFee.map(_.value) } - assertDiffAndState(setupBlocks, block(Seq(sponsor, sponsor1)), s) { case (diff, state) => - diff.sponsorship shouldBe Map(sponsor.asset -> SponsorshipValue(sponsor1.minSponsoredAssetFee.get.value)) + assertDiffAndState(setupBlocks, block(Seq(sponsor, sponsor1)), s) { case (snapshot, state) => + snapshot.sponsorships shouldBe Map(sponsor.asset -> SponsorshipValue(sponsor1.minSponsoredAssetFee.get.value)) state.assetDescription(sponsor.asset).map(_.sponsorship) shouldBe sponsor1.minSponsoredAssetFee.map(_.value) } - assertDiffAndState(setupBlocks, block(Seq(sponsor, sponsor1, cancel)), s) { case (diff, state) => - diff.sponsorship shouldBe Map(sponsor.asset -> SponsorshipValue(0)) + assertDiffAndState(setupBlocks, block(Seq(sponsor, sponsor1, cancel)), s) { case (snapshot, state) => + snapshot.sponsorships shouldBe Map(sponsor.asset -> SponsorshipValue(0)) state.assetDescription(sponsor.asset).map(_.sponsorship) shouldBe Some(0) } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/TransferDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/TransferDiffTest.scala index 6273361c430..e8458dfb992 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/TransferDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/TransferDiffTest.scala @@ -2,22 +2,23 @@ package com.wavesplatform.state.diffs import com.wavesplatform.account.Address import com.wavesplatform.common.utils.EitherExt2 -import com.wavesplatform.db.WithState +import com.wavesplatform.db.WithDomain import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.lang.script.v1.ExprScript import com.wavesplatform.lang.v1.compiler.Terms.CONST_BOOLEAN import com.wavesplatform.settings.TestFunctionalitySettings +import com.wavesplatform.state.diffs.FeeValidation.FeeUnit import com.wavesplatform.test.* +import com.wavesplatform.test.DomainPresets.ScriptsAndSponsorship import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.TxValidationError.GenericError import com.wavesplatform.transaction.assets.* import com.wavesplatform.transaction.transfer.* import com.wavesplatform.transaction.{Asset, GenesisTransaction, TxHelpers, TxValidationError, TxVersion} -class TransferDiffTest extends PropSpec with WithState { - - val preconditionsAndTransfer: Seq[(GenesisTransaction, IssueTransaction, IssueTransaction, TransferTransaction)] = { +class TransferDiffTest extends PropSpec with WithDomain { + private val preconditionsAndTransfer = { val master = TxHelpers.signer(1) val recipient = TxHelpers.signer(2) @@ -30,25 +31,32 @@ class TransferDiffTest extends PropSpec with WithState { maybeAsset1 <- Seq(None, Some(issue1.id())).map(Asset.fromCompatId) maybeAsset2 <- Seq(None, Some(issue2.id())).map(Asset.fromCompatId) maybeFeeAsset <- Seq(maybeAsset1, maybeAsset2) + sponsor1 = TxHelpers.sponsor(IssuedAsset(issue1.id()), minSponsoredAssetFee = Some(FeeUnit), sender = master) + sponsor2 = TxHelpers.sponsor(IssuedAsset(issue2.id()), minSponsoredAssetFee = Some(FeeUnit), sender = master) transferV1 = TxHelpers.transfer(master, recipient.toAddress, asset = maybeAsset1, feeAsset = maybeFeeAsset, version = TxVersion.V1) transferV2 = TxHelpers.transfer(master, recipient.toAddress, asset = maybeAsset1, feeAsset = maybeFeeAsset) transfer <- Seq(transferV1, transferV2) - } yield (genesis, issue1, issue2, transfer) + } yield (genesis, sponsor1, sponsor2, issue1, issue2, transfer) } property("transfers assets to recipient preserving waves invariant") { - preconditionsAndTransfer.foreach { case (genesis, issue1, issue2, transfer) => - assertDiffAndState(Seq(TestBlock.create(Seq(genesis, issue1, issue2))), TestBlock.create(Seq(transfer))) { case (totalDiff, newState) => - assertBalanceInvariant(totalDiff) + preconditionsAndTransfer.foreach { case (genesis, sponsor1, sponsor2, issue1, issue2, transfer) => + withDomain(ScriptsAndSponsorship) { d => + d.appendBlock(genesis) + d.appendBlock(issue1, issue2, sponsor1, sponsor2) + d.appendBlock(transfer) + + val carryFee = (sponsor1.fee.value + sponsor2.fee.value + issue1.fee.value + issue2.fee.value - transfer.fee.value) * 3 / 5 + assertBalanceInvariant(d.liquidSnapshot, d.rocksDBWriter, carryFee) - val recipient: Address = transfer.recipient.asInstanceOf[Address] + val recipient = transfer.recipient.asInstanceOf[Address] if (transfer.sender.toAddress != recipient) { transfer.assetId match { case aid @ IssuedAsset(_) => - newState.balance(recipient) shouldBe 0 - newState.balance(recipient, aid) shouldBe transfer.amount.value + d.balance(recipient) shouldBe 0 + d.balance(recipient, aid) shouldBe transfer.amount.value case Waves => - newState.balance(recipient) shouldBe transfer.amount.value + d.balance(recipient) shouldBe transfer.amount.value } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/TransferTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/TransferTransactionDiffTest.scala index 7dcf114daeb..1b7d9dd4b66 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/TransferTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/TransferTransactionDiffTest.scala @@ -1,12 +1,9 @@ package com.wavesplatform.state.diffs -import com.wavesplatform.TestValues -import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.db.WithDomain import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.lang.directives.values.V1 import com.wavesplatform.settings.RewardsVotingSettings -import com.wavesplatform.state.{Diff, Portfolio} import com.wavesplatform.test.{NumericExt, PropSpec} import com.wavesplatform.transaction.TxValidationError.GenericError import com.wavesplatform.transaction.{TxHelpers, TxValidationError, TxVersion} @@ -17,13 +14,12 @@ class TransferTransactionDiffTest extends PropSpec with WithDomain { val sender = TxHelpers.secondAddress val senderKp = TxHelpers.secondSigner val recipient = TxHelpers.address(2) - val feeDiff = Diff(portfolios = Map(sender -> Portfolio.waves(TestValues.fee))) withDomain(DomainPresets.mostRecent.copy(rewardsSettings = RewardsVotingSettings(None)), AddrWithBalance.enoughBalances(senderKp)) { d => val wavesTransfer = TxHelpers.transfer(senderKp, recipient) - assertBalanceInvariant(d.createDiff(wavesTransfer).combineF(feeDiff).explicitGet()) - d.appendAndAssertSucceed(wavesTransfer) + val rewardFee = 6.waves - wavesTransfer.fee.value * 3 / 5 + assertBalanceInvariant(d.liquidSnapshot, d.rocksDBWriter, rewardFee) d.blockchain.balance(recipient) shouldBe wavesTransfer.amount.value d.blockchain.balance(sender) shouldBe ENOUGH_AMT - wavesTransfer.amount.value - wavesTransfer.fee.value } @@ -31,9 +27,9 @@ class TransferTransactionDiffTest extends PropSpec with WithDomain { withDomain(DomainPresets.mostRecent, AddrWithBalance.enoughBalances(senderKp)) { d => val asset = d.helpers.issueAsset(senderKp) val assetTransfer = TxHelpers.transfer(senderKp, recipient, asset = asset, amount = 1000) - assertBalanceInvariant(d.createDiff(assetTransfer).combineF(feeDiff).explicitGet()) - d.appendAndAssertSucceed(assetTransfer) + val rewardAndFee = 6.waves + (1.waves - assetTransfer.fee.value) * 3 / 5 + assertBalanceInvariant(d.liquidSnapshot, d.rocksDBWriter, rewardAndFee) d.blockchain.balance(recipient) shouldBe 0L d.blockchain.balance(recipient, asset) shouldBe 1000L d.blockchain.balance(sender) shouldBe ENOUGH_AMT - assetTransfer.fee.value - 1.waves diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/BigIntInvokeTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/BigIntInvokeTest.scala index f0e177fe71b..f30fc5b9a79 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/BigIntInvokeTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/BigIntInvokeTest.scala @@ -147,14 +147,14 @@ class BigIntInvokeTest extends PropSpec with Inside with WithState with DBCacheS d.appendBlock(preparingTxs*) d.appendBlock(invoke) - d.liquidDiff.errorMessage(invoke.id()) shouldBe None - inside(d.liquidDiff.scriptResults.toSeq) { case Seq((_, call1)) => + d.liquidSnapshot.errorMessage(invoke.id()) shouldBe None + inside(d.liquidSnapshot.scriptResults.toSeq) { case Seq((_, call1)) => inside(call1.invokes) { case Seq(call2) => call2.stateChanges.error shouldBe empty call2.stateChanges.invokes shouldBe empty } } - d.liquidDiff.accountData.head._2("key").value shouldBe 1 + d.liquidSnapshot.accountData.head._2("key").value shouldBe 1 } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/CallableV4DiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/CallableV4DiffTest.scala index 3bff19bce34..e4db887802e 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/CallableV4DiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/CallableV4DiffTest.scala @@ -106,7 +106,7 @@ class CallableV4DiffTest extends PropSpec with WithDomain with EitherValues { } } - property("diff contains delete entries") { + property("snapshot contains delete entries") { val deleteEntryDApp = dApp( """ | [ @@ -131,8 +131,8 @@ class CallableV4DiffTest extends PropSpec with WithDomain with EitherValues { Seq(TestBlock.create(genesis :+ setScript)), TestBlock.create(Seq(invoke)), features - ) { case (diff, _) => - diff.accountData(master.toAddress) shouldBe + ) { case (snapshot, _) => + snapshot.accountData(master.toAddress) shouldBe Map( "key1" -> EmptyDataEntry("key1"), "key2" -> EmptyDataEntry("key2") @@ -389,9 +389,9 @@ class CallableV4DiffTest extends PropSpec with WithDomain with EitherValues { Seq(TestBlock.create(genesis :+ setScript)), TestBlock.create(Seq(invoke)), features - ) { case (diff, blockchain) => - val asset = diff.issuedAssets.head._1 - diff.sponsorship shouldBe Map(asset -> SponsorshipValue(minSponsoredAssetFee)) + ) { case (snapshot, blockchain) => + val asset = snapshot.assetStatics.head._1 + snapshot.sponsorships shouldBe Map(asset -> SponsorshipValue(minSponsoredAssetFee)) blockchain.assetDescription(asset).map(_.sponsorship) shouldBe Some(minSponsoredAssetFee) } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeAffectedAddressTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeAffectedAddressTest.scala index 27df11b5e25..5faafa6d041 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeAffectedAddressTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeAffectedAddressTest.scala @@ -28,7 +28,7 @@ class InvokeAffectedAddressTest extends PropSpec with WithDomain { d.appendAndAssertFailed(invoke(secondAddress)) else d.appendAndAssertSucceed(invoke(secondAddress)) - d.liquidDiff.transactions.head.affected shouldBe Set(defaultAddress, secondAddress) + d.liquidSnapshot.transactions.head._2.affected shouldBe Set(defaultAddress, secondAddress) } } } @@ -42,7 +42,7 @@ class InvokeAffectedAddressTest extends PropSpec with WithDomain { d.appendAndAssertFailed(invoke(Alias.create("alias").explicitGet())) else d.appendAndAssertSucceed(invoke(Alias.create("alias").explicitGet())) - d.liquidDiff.transactions.head.affected shouldBe Set(defaultAddress, secondAddress) + d.liquidSnapshot.transactions.head._2.affected shouldBe Set(defaultAddress, secondAddress) } } } @@ -55,10 +55,10 @@ class InvokeAffectedAddressTest extends PropSpec with WithDomain { d.appendBlock(setScript(secondSigner, dApp(failed))) if (failed) { d.appendBlock(aliasTx, invokeTx) - d.liquidDiff.errorMessage(invokeTx.id()) shouldBe defined + d.liquidSnapshot.errorMessage(invokeTx.id()) shouldBe defined } else d.appendAndAssertSucceed(aliasTx, invokeTx) - d.liquidDiff.transaction(invokeTx.id()).get.affected shouldBe Set(defaultAddress, secondAddress) + d.liquidSnapshot.transactions(invokeTx.id()).affected shouldBe Set(defaultAddress, secondAddress) } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeAssetChecksTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeAssetChecksTest.scala index 0deaa036309..46774919df5 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeAssetChecksTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeAssetChecksTest.scala @@ -8,11 +8,8 @@ import com.wavesplatform.db.{DBCacheSettings, WithDomain, WithState} import com.wavesplatform.lang.directives.values.{V4, V5} import com.wavesplatform.lang.script.ContractScript.ContractScriptImpl import com.wavesplatform.lang.v1.compiler.TestCompiler -import com.wavesplatform.state.InvokeScriptResult.ErrorMessage -import com.wavesplatform.state.TxMeta.Status -import com.wavesplatform.state.{Diff, InvokeScriptResult, NewTransactionInfo, Portfolio, StateSnapshot} import com.wavesplatform.test.* -import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} +import com.wavesplatform.transaction.Asset.IssuedAsset import com.wavesplatform.transaction.TxHelpers import com.wavesplatform.transaction.TxHelpers.{invoke, secondSigner, setScript} import org.scalatest.{EitherValues, Inside} @@ -49,71 +46,18 @@ class InvokeAssetChecksTest extends PropSpec with Inside with WithState with DBC activated <- Seq(true, false) func <- Seq("invalidLength", "unexisting") } { - { - val miner = TxHelpers.signer(0).toAddress - val invoker = TxHelpers.signer(1) - val master = TxHelpers.signer(2) - val balances = AddrWithBalance.enoughBalances(invoker, master) - val setScriptTx = TxHelpers.setScript(master, dApp) - val invoke = TxHelpers.invoke(master.toAddress, Some(func), invoker = invoker) - - val dAppAddress = master.toAddress - - def invokeInfo(succeeded: Boolean): Vector[NewTransactionInfo] = - Vector( - NewTransactionInfo( - invoke, - StateSnapshot.empty, - Set(invoke.senderAddress, dAppAddress), - if (succeeded) Status.Succeeded else Status.Failed, - 8 - ) - ) - - val expectedResult = - if (activated) { - val expectingMessage = - if (func == "invalidLength") - lengthError - else - nonExistentError - Diff.withTransactions( - invokeInfo(false), - portfolios = Map( - invoke.senderAddress -> Portfolio(-invoke.fee.value), - miner -> Portfolio((setScriptTx.fee.value * 0.6 + invoke.fee.value * 0.4).toLong + 6.waves) - ), - scriptsComplexity = 8, - scriptResults = Map(invoke.id() -> InvokeScriptResult(error = Some(ErrorMessage(1, expectingMessage)))) - ) - } else { - val asset = if (func == "invalidLength") invalidLengthAsset else nonExistentAsset - Diff.withTransactions( - invokeInfo(true), - portfolios = Map( - invoke.senderAddress -> Portfolio(-invoke.fee.value), - miner -> Portfolio((setScriptTx.fee.value * 0.6 + invoke.fee.value * 0.4).toLong + 6.waves) - ), - scriptsComplexity = 8, - scriptResults = Map( - invoke.id() -> InvokeScriptResult( - transfers = Seq( - InvokeScriptResult.Payment(invoke.senderAddress, Waves, 0), - InvokeScriptResult.Payment(invoke.senderAddress, asset, 0) - ) - ) - ) - ) - } - - def noSnapshot(d: Diff) = - d.copy(transactions = d.transactions.map(_.copy(snapshot = StateSnapshot.empty))) - - withDomain(if (activated) RideV5 else RideV4, balances) { d => - d.appendBlock(setScriptTx) - d.appendBlock(invoke) - noSnapshot(d.liquidDiff) shouldBe expectedResult - } + val invoker = TxHelpers.signer(1) + val master = TxHelpers.signer(2) + val balances = AddrWithBalance.enoughBalances(invoker, master) + val setScriptTx = TxHelpers.setScript(master, dApp) + withDomain(if (activated) RideV5 else RideV4, balances) { d => + d.appendBlock(setScriptTx) + val invoke = TxHelpers.invoke(master.toAddress, Some(func), invoker = invoker) + if (activated) { + val expectingMessage = if (func == "invalidLength") lengthError else nonExistentError + d.appendAndAssertFailed(invoke, expectingMessage) + } else + d.appendAndAssertSucceed(invoke) } } } @@ -270,7 +214,7 @@ class InvokeAssetChecksTest extends PropSpec with Inside with WithState with DBC ) d.appendBlock(setScript(secondSigner, dApp)) d.appendAndAssertSucceed(invoke(fee = invokeFee(issues = 2))) - d.liquidDiff.issuedAssets.size shouldBe 2 + d.liquidSnapshot.assetStatics.size shouldBe 2 } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeFeeTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeFeeTest.scala index c593439d168..92972e2b417 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeFeeTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeFeeTest.scala @@ -5,14 +5,11 @@ import com.wavesplatform.db.WithDomain import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.lang.directives.values.* import com.wavesplatform.lang.v1.compiler.TestCompiler -import com.wavesplatform.state.Portfolio import com.wavesplatform.state.diffs.FeeValidation.FeeUnit import com.wavesplatform.test.* -import com.wavesplatform.transaction.Asset.IssuedAsset +import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.TxHelpers.* -import scala.collection.immutable.VectorMap - class InvokeFeeTest extends PropSpec with WithDomain { import DomainPresets.* @@ -73,9 +70,9 @@ class InvokeFeeTest extends PropSpec with WithDomain { val transferTx = transfer(issuer, invoker.toAddress, asset = asset) d.appendBlock(issueTx, sponsorTx, transferTx, setScript(dAppAcc, dApp)) d.appendAndAssertFailed(invoke(invoker = invoker, dApp = dAppAcc.toAddress, fee = invokeFee / coeff, feeAssetId = asset)) - d.liquidDiff.portfolios(invoker.toAddress) shouldBe Portfolio.build(asset, -invokeFee / coeff) - d.liquidDiff.portfolios(issuer.toAddress) shouldBe Portfolio(-invokeFee, assets = VectorMap(asset -> invokeFee / coeff)) - d.liquidDiff.portfolios.get(dAppAcc.toAddress) shouldBe None + d.liquidSnapshot.balances((invoker.toAddress, asset)) shouldBe d.rocksDBWriter.balance(invoker.toAddress, asset) - invokeFee / coeff + d.liquidSnapshot.balances((issuer.toAddress, asset)) shouldBe d.rocksDBWriter.balance(issuer.toAddress, asset) + invokeFee / coeff + d.liquidSnapshot.balances.get((dAppAcc.toAddress, Waves)) shouldBe None } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeReissueTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeReissueTest.scala index 6e9d4358bf7..05af2670086 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeReissueTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeReissueTest.scala @@ -61,7 +61,7 @@ class InvokeReissueTest extends PropSpec with WithDomain { ) d.appendBlock(setScript(secondSigner, dApp)) d.appendBlock(invoke(fee = invokeFee(issues = 1))) - val asset = d.liquidDiff.issuedAssets.head._1 + val asset = d.liquidSnapshot.assetStatics.head._1 d.appendBlock(reissue(asset, secondSigner, 234)) d.blockchain.assetDescription(asset).get.totalVolume shouldBe 1234 } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptActionLimitsTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptActionLimitsTest.scala index 6dd756e3aa8..9334726c04d 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptActionLimitsTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptActionLimitsTest.scala @@ -57,8 +57,8 @@ class InvokeScriptActionLimitsTest extends PropSpec with WithDomain with DBCache ) assertDiffAndState(Seq(TestBlock.create(preparingTxs1)), TestBlock.create(Seq(invoke1), Block.ProtoBlockVersion), features(version)) { - case (diff, bc) => - diff.scriptResults(invoke1.id()).error shouldBe None + case (snapshot, bc) => + snapshot.scriptResults(invoke1.id()).error shouldBe None bc.accountData(masterAddress, "key") shouldBe Some(IntegerDataEntry("key", 1)) bc.accountData(serviceAddress1, "bar") shouldBe Some(IntegerDataEntry("bar", 1)) } @@ -97,8 +97,8 @@ class InvokeScriptActionLimitsTest extends PropSpec with WithDomain with DBCache ) assertDiffAndState(Seq(TestBlock.create(preparingTxs1)), TestBlock.create(Seq(invoke1), Block.ProtoBlockVersion), features(version)) { - case (diff, bc) => - diff.scriptResults(invoke1.id()).error shouldBe None + case (snapshot, bc) => + snapshot.scriptResults(invoke1.id()).error shouldBe None bc.accountData(masterAddress, "key") shouldBe Some(IntegerDataEntry("key", 1)) bc.accountData(serviceAddress1, "bar") shouldBe Some(IntegerDataEntry("bar", 1)) } @@ -133,8 +133,8 @@ class InvokeScriptActionLimitsTest extends PropSpec with WithDomain with DBCache assetAndDataActionsServiceContract(V6, ContractLimits.MaxAssetScriptActionsAmountV6, ContractLimits.MaxWriteSetSize / 2) ) - assertDiffAndState(Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), features(V6)) { case (diff, bc) => - diff.scriptResults(invoke.id()).error shouldBe None + assertDiffAndState(Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), features(V6)) { case (snapshot, bc) => + snapshot.scriptResults(invoke.id()).error shouldBe None bc.accountData(masterAddress, "key") shouldBe Some(IntegerDataEntry("key", 1)) bc.accountData(serviceAddress, "bar") shouldBe Some(IntegerDataEntry("bar", 1)) } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptTransactionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptTransactionDiffTest.scala index c7576526253..fed8004e3c6 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptTransactionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/InvokeScriptTransactionDiffTest.scala @@ -64,14 +64,14 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa .foreach(v => withDomain(settingsForRide(v))(assertion(v, _))) private def testDiffTraced(preconditions: Seq[BlockWithSigner], block: BlockWithSigner, from: StdLibVersion = V3, to: StdLibVersion)( - assertion: ((StdLibVersion, TracedResult[ValidationError, Diff])) => Unit + assertion: ((StdLibVersion, TracedResult[ValidationError, StateSnapshot])) => Unit ): Unit = allVersions .filter(v => v >= from && v <= to) .foreach(v => assertDiffEiTraced(preconditions, block, settingsForRide(v).blockchainSettings.functionalitySettings)(r => assertion((v, r)))) private def testDiff(preconditions: Seq[BlockWithSigner], block: BlockWithSigner, from: StdLibVersion = V3, to: StdLibVersion = lastVersion)( - assertion: Either[ValidationError, Diff] => Unit + assertion: Either[ValidationError, StateSnapshot] => Unit ): Unit = testDiffTraced(preconditions, block, from, to)(assertion.compose(_._2.resultE)) @@ -81,7 +81,7 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa from: StdLibVersion, to: StdLibVersion = lastVersion )( - assertion: (Diff, Blockchain) => Unit + assertion: (StateSnapshot, Blockchain) => Unit ): Unit = allVersions .filter(v => v >= from && v <= to) @@ -462,10 +462,10 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa val (_, setScript, ci) = preconditionsAndSetContract(dataContract(version)) d.appendBlock(setScript) d.appendBlock(ci) - d.liquidDiff.scriptsComplexity should be > 0L + d.liquidSnapshot.scriptsComplexity should be > 0L d.blockchain.accountData(dAppAddress, "sender").get.value shouldBe ByteStr(ci.sender.toAddress.bytes) d.blockchain.accountData(dAppAddress, "argument").get.value shouldBe ci.funcCallOpt.get.args.head.asInstanceOf[CONST_BYTESTR].bs - d.liquidDiff.transaction(ci.id()).get.affected.contains(setScript.sender.toAddress) shouldBe true + d.liquidSnapshot.transactions(ci.id()).affected.contains(setScript.sender.toAddress) shouldBe true } ) } @@ -496,10 +496,10 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa val (_, setScript, ci) = preconditionsAndSetContract(dAppWithTransfers(version = version)) d.appendBlock(setScript) d.appendBlock(ci) - d.liquidDiff.scriptsComplexity should be > 0L - d.liquidDiff.portfolios(thirdAddress).balance shouldBe amount - d.liquidDiff.portfolios(setScript.sender.toAddress).balance shouldBe -amount - d.liquidDiff.transaction(ci.id()) shouldBe defined + d.liquidSnapshot.scriptsComplexity should be > 0L + d.liquidSnapshot.balances((thirdAddress, Waves)) shouldBe amount + d.liquidSnapshot.balances((setScript.sender.toAddress, Waves)) shouldBe d.rocksDBWriter.balance(setScript.sender.toAddress, Waves) - amount + d.liquidSnapshot.transactions.get(ci.id()) shouldBe defined } ) } @@ -512,10 +512,10 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa val (_, setScript, ci) = preconditionsAndSetContract(dAppWithTransfers(version = version)) d.appendBlock(setScript) d.appendBlock(ci) - d.liquidDiff.scriptsComplexity should be > 0L - d.liquidDiff.portfolios(thirdAddress).balance shouldBe amount - d.liquidDiff.portfolios(setScript.sender.toAddress).balance shouldBe -amount - d.liquidDiff.transaction(ci.id()) shouldBe defined + d.liquidSnapshot.scriptsComplexity should be > 0L + d.liquidSnapshot.balances((thirdAddress, Waves)) shouldBe amount + d.liquidSnapshot.balances((setScript.sender.toAddress, Waves)) shouldBe d.rocksDBWriter.balance(setScript.sender.toAddress, Waves) - amount + d.liquidSnapshot.transactions.get(ci.id()) shouldBe defined } ) } @@ -531,8 +531,8 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa from = V4 ) { case (blockDiff, _) => blockDiff.scriptsComplexity should be > 0L - blockDiff.portfolios(thirdAddress) shouldBe Portfolio.waves(amount) - blockDiff.transaction(ci.id()) shouldBe defined + blockDiff.balances((thirdAddress, Waves)) shouldBe ENOUGH_AMT - createAlias.fee.value + amount + blockDiff.transactions.get(ci.id()) shouldBe defined } } @@ -590,7 +590,7 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa withDomain(settingsForRide(version), AddrWithBalance.enoughBalances(dApp, invoker)) { d => d.appendBlock(setScript, createAlias) d.appendAndAssertSucceed(ci) - d.liquidDiff.scriptsComplexity should be > 0L + d.liquidSnapshot.scriptsComplexity should be > 0L d.balance(thirdAddress, Waves) shouldBe amount d.appendBlockE(fakeCi) should produce("does not exist") } @@ -637,7 +637,7 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa d.appendBlock(genesis*) d.appendBlock(issue, setScript) d.appendBlock(ci) - inside(d.liquidDiff.scriptResults.toSeq) { case Seq((_, i: InvokeScriptResult)) => + inside(d.liquidSnapshot.scriptResults.toSeq) { case Seq((_, i: InvokeScriptResult)) => i.transfers.size shouldBe 1 } d.blockchain.balance(thirdAddress, Waves) shouldBe amount @@ -686,10 +686,10 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa ) withDomain(settingsForRide(version), AddrWithBalance.enoughBalances(dApp, invoker)) { d => d.appendBlock(asset, setScript) - val tracedDiff = d.transactionDiffer(ci) + val tracedSnapshot = d.transactionDiffer(ci) val message = if (version == V3) "TransactionNotAllowedByScript" else "Transaction is not allowed by script of the asset" - tracedDiff.resultE should produceRejectOrFailedDiff(message) - inside(tracedDiff.trace) { case List(_, AssetVerifierTrace(assetId, Some(tne: TransactionNotAllowedByScript), _)) => + tracedSnapshot.resultE should produceRejectOrFailedDiff(message) + inside(tracedSnapshot.trace) { case List(_, AssetVerifierTrace(assetId, Some(tne: TransactionNotAllowedByScript), _)) => assetId shouldBe asset.id() tne.isAssetScript shouldBe true } @@ -710,7 +710,7 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa ) d.appendBlock(issue, setScript) d.appendBlock(ci) - d.liquidDiff.scriptsComplexity should be > 0L + d.liquidSnapshot.scriptsComplexity should be > 0L d.balance(dAppAddress, asset) shouldBe (issue.quantity.value - amount) d.balance(thirdAddress, asset) shouldBe amount } @@ -741,9 +741,9 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa val (_, setScript, ci) = preconditionsAndSetContract(contract, fee = TestValues.invokeFee(2)) withDomain(settingsForRide(version), AddrWithBalance.enoughBalances(dApp, invoker)) { d => d.appendBlock(issue1, issue2, setScript) - val tracedDiff = d.transactionDiffer(ci) - tracedDiff.resultE should produceRejectOrFailedDiff("Transaction is not allowed by script") - inside(tracedDiff.trace) { + val tracedSnapshot = d.transactionDiffer(ci) + tracedSnapshot.resultE should produceRejectOrFailedDiff("Transaction is not allowed by script") + inside(tracedSnapshot.trace) { case List( InvokeScriptTrace(_, `dAppAddress`, functionCall, Right(scriptResult), _, _), AssetVerifierTrace(allowedAssetId, None, _), @@ -774,9 +774,9 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa ) withDomain(settingsForRide(version), AddrWithBalance.enoughBalances(dApp, invoker)) { d => d.appendBlock(transferringAsset, attachedAsset, setScript) - val tracedDiff = d.transactionDiffer(ci) - tracedDiff.resultE should produceRejectOrFailedDiff(s"Transaction is not allowed by script of the asset ${transferringAsset.id()}") - inside(tracedDiff.trace) { + val tracedSnapshot = d.transactionDiffer(ci) + tracedSnapshot.resultE should produceRejectOrFailedDiff(s"Transaction is not allowed by script of the asset ${transferringAsset.id()}") + inside(tracedSnapshot.trace) { case List( InvokeScriptTrace(_, _, _, Right(scriptResults), _, _), AssetVerifierTrace(transferringAssetId, Some(_), _) @@ -864,8 +864,8 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa val t = TxHelpers.transfer(dApp, invokerAddress, sponsorIssue.quantity.value / 2, sponsorAsset) d.appendBlock(sponsorIssue, t, sponsor, setScript) d.appendBlock(ci) - d.liquidDiff.scriptsComplexity should be > 0L - d.liquidDiff.errorMessage(ci.id()) shouldBe None + d.liquidSnapshot.scriptsComplexity should be > 0L + d.liquidSnapshot.errorMessage(ci.id()) shouldBe None d.balance(thirdAddress, Waves) shouldBe amount d.balance(ci.sender.toAddress, sponsorAsset) shouldBe (sponsorIssue.quantity.value / 2 - ci.fee.value) d.balance(dAppAddress, sponsorAsset) shouldBe (sponsorIssue.quantity.value - sponsorIssue.quantity.value / 2 + ci.fee.value) @@ -928,7 +928,7 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa d.appendBlockE(ci) should produceRejectOrFailedDiff(error) } else { d.appendBlock(ci) - d.liquidDiff.errorMessage(ci.id()).get.text shouldBe error + d.liquidSnapshot.errorMessage(ci.id()).get.text shouldBe error } } } @@ -943,7 +943,7 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa d.appendBlock(genesis*) d.appendBlock(setScript) d.appendBlock(ci) - d.liquidDiff.errorMessage(ci.id()) shouldBe None + d.liquidSnapshot.errorMessage(ci.id()) shouldBe None } } @@ -956,12 +956,12 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa d.appendBlock(genesis*) if (version == V3) { d.appendBlock(setScript, ci) - d.liquidDiff.errorMessage(ci.id()) shouldBe None + d.liquidSnapshot.errorMessage(ci.id()) shouldBe None } else if (version >= V6) { d.appendBlockE(setScript, ci) should produceRejectOrFailedDiff("Data entry key should not be empty") } else { d.appendBlock(setScript, ci) - d.liquidDiff.errorMessage(ci.id()).map(_.text) shouldBe Some("Data entry key should not be empty") + d.liquidSnapshot.errorMessage(ci.id()).map(_.text) shouldBe Some("Data entry key should not be empty") } } } @@ -1299,15 +1299,15 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa TestCompiler(V4).compileContract(script) } - property("duplicate issuing asset should produce diff error") { + property("duplicate issuing asset should produce snapshot error") { val genesis1Tx = TxHelpers.genesis(dAppAddress) val genesis2Tx = TxHelpers.genesis(invokerAddress) val setScriptTx = TxHelpers.setScript(dApp, doubleIssueContract) val invoke = TxHelpers.invoke(dAppAddress, Some("f"), fee = TestValues.invokeFee(issues = 2)) testDiff(Seq(TestBlock.create(Seq(genesis1Tx, genesis2Tx, setScriptTx))), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), from = V4) { inside(_) { - case Right(diff) => - diff.scriptResults(invoke.id()).error.get.text should include("is already issued") + case Right(snapshot) => + snapshot.scriptResults(invoke.id()).error.get.text should include("is already issued") case Left(TransactionValidationError(InvokeRejectError(error, _), _)) => error should include("is already issued") } } @@ -1326,7 +1326,7 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa d.appendAndAssertSucceed(ci) ci.feeAssetId shouldBe sponsorAsset ci.dApp shouldBe ci.sender.toAddress - d.liquidDiff.portfolios(ci.sender.toAddress).balanceOf(sponsorAsset) shouldBe 0L + d.liquidSnapshot.balances.get((ci.sender.toAddress, sponsorAsset)) shouldBe None } } } @@ -1384,8 +1384,7 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), from = V4, to = V5 - ) { case (diff, state) => - diff.portfolios(invoke.sender.toAddress).balanceOf(invoke.feeAssetId) + ) { case (_, state) => state.balance(invoke.sender.toAddress, invoke.feeAssetId) shouldBe invoke.feeAssetId.fold(g2Tx.amount.value)(_ => sponsorIssue.quantity.value ) - invoke.fee.value @@ -1461,11 +1460,11 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa .foreach { arg => val invoke = TxHelpers.invoke(dAppAddress, Some("sameComplexity"), args = List(CONST_STRING(arg).explicitGet())) testDiffAndState(Seq(TestBlock.create(Seq(gTx1, gTx2, ssTx, iTx))), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), from = V4) { - case (diff, _) => + case (snapshot, _) => if (arg == "ok") - diff.errorMessage(invoke.id()) shouldBe empty + snapshot.errorMessage(invoke.id()) shouldBe empty else - diff.errorMessage(invoke.id()) shouldBe defined + snapshot.errorMessage(invoke.id()) shouldBe defined } } @@ -1514,9 +1513,9 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa val genesisTxs = Seq(gTx1, gTx2) ++ invokerScriptTx ++ iTxs ++ tTxs ++ saTxs :+ ssTx testDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), from = V4, to = V5) { - case (diff, _) => - diff.errorMessage(invoke.id()) shouldBe defined - diff.scriptsComplexity should be > 0L + case (snapshot, _) => + snapshot.errorMessage(invoke.id()) shouldBe defined + snapshot.scriptsComplexity should be > 0L } testDiff(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), from = V6) { _ should produce("Transaction is not allowed by script of the asset") @@ -1551,8 +1550,8 @@ class InvokeScriptTransactionDiffTest extends PropSpec with WithDomain with DBCa val invoke = TxHelpers.invoke(dAppAddress, Some("foo"), payments = payments) testDiffAndState(Seq(TestBlock.create(Seq(gTx1, gTx2, alias, ssTx))), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), from = V5) { - case (diff, bc) => - diff.errorMessage(invoke.id()) shouldBe None + case (snapshot, bc) => + snapshot.errorMessage(invoke.id()) shouldBe None val hash = ByteStr(com.wavesplatform.lang.Global.blake2b256(script.bytes().arr)) bc.accountData(dAppAddress, "hash1").get.value shouldBe hash bc.accountData(dAppAddress, "hash2").get.value shouldBe hash diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/LeaseActionDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/LeaseActionDiffTest.scala index 3f952dad9ac..3ee74a82db6 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/LeaseActionDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/LeaseActionDiffTest.scala @@ -1,5 +1,6 @@ package com.wavesplatform.state.diffs.ci +import cats.Id import com.wavesplatform.account.{Address, Alias} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2 @@ -14,11 +15,12 @@ import com.wavesplatform.lang.v1.ContractLimits import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.lang.v1.traits.domain.{Lease, Recipient} import com.wavesplatform.settings.{FunctionalitySettings, TestFunctionalitySettings} +import com.wavesplatform.state.LeaseBalance import com.wavesplatform.state.diffs.FeeValidation.{FeeConstants, FeeUnit} import com.wavesplatform.state.diffs.{ENOUGH_AMT, produceRejectOrFailedDiff} -import com.wavesplatform.state.{LeaseBalance, Portfolio} import com.wavesplatform.test.* import com.wavesplatform.test.DomainPresets.* +import com.wavesplatform.transaction.Asset.Waves import com.wavesplatform.transaction.TxHelpers.{defaultAddress, invoke, lease, secondAddress, secondSigner, setScript} import com.wavesplatform.transaction.lease.{LeaseCancelTransaction, LeaseTransaction} import com.wavesplatform.transaction.smart.InvokeScriptTransaction @@ -481,22 +483,20 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.portfolios(invoker) shouldBe Portfolio(-invoke.fee.value, LeaseBalance(leaseAmount, out = 0)) - diff.portfolios(dAppAcc) shouldBe Portfolio(0, LeaseBalance(in = 0, leaseAmount)) + ) { case (snapshot, _) => + snapshot.leaseBalances(invoker) shouldBe LeaseBalance(leaseAmount, out = 0) + snapshot.leaseBalances(dAppAcc) shouldBe LeaseBalance(in = 0, leaseAmount) } } property(s"Lease action cancelled by LeaseCancelTransaction") { val (preparingTxs, invoke, _, dAppAcc, invoker, _, leaseCancelTx) = leasePreconditions(cancelLeaseActionByTx = true) - assertDiffAndState( - Seq(TestBlock.create(preparingTxs)), - TestBlock.create(Seq(invoke, leaseCancelTx)), - v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()) shouldBe empty - diff.portfolios(invoker) shouldBe Portfolio(-invoke.fee.value) - diff.portfolios(dAppAcc) shouldBe Portfolio(-leaseCancelTx.fee.value) + withDomain(RideV5) { d => + d.appendBlock(preparingTxs*) + d.appendBlock(invoke, leaseCancelTx) + d.liquidSnapshot.errorMessage(invoke.id()) shouldBe empty + d.liquidSnapshot.balances((invoker, Waves)) shouldBe d.rocksDBWriter.balance(invoker) - invoke.fee.value + d.liquidSnapshot.balances((dAppAcc, Waves)) shouldBe d.rocksDBWriter.balance(dAppAcc) - leaseCancelTx.fee.value } } @@ -506,8 +506,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe "InvalidAddress(Wrong addressBytes length: expected: 26, actual: 0)" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe "InvalidAddress(Wrong addressBytes length: expected: 26, actual: 0)" } } @@ -517,8 +517,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe "InvalidAddress(Wrong addressBytes length: expected: 26, actual: 10)" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe "InvalidAddress(Wrong addressBytes length: expected: 26, actual: 10)" } } @@ -531,8 +531,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe "InvalidAddress(Bad address checksum)" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe "InvalidAddress(Bad address checksum)" } } @@ -542,8 +542,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe "Alias 'alias:T:alias2' does not exists." + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe "Alias 'alias:T:alias2' does not exists." } } @@ -553,8 +553,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe s"Alias should contain only following characters: ${Alias.AliasAlphabet}" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe s"Alias should contain only following characters: ${Alias.AliasAlphabet}" } } @@ -564,8 +564,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe "NonPositiveAmount(0,waves)" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe "NonPositiveAmount(0,waves)" } } @@ -599,8 +599,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe s"Cannot lease more than own: Balance: $dAppBalance, already leased: 0" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe s"Cannot lease more than own: Balance: $dAppBalance, already leased: 0" } } @@ -613,8 +613,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs.toList ::: leaseTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe s"Cannot lease more than own: Balance: ${dAppBalance - leaseFromDApp.fee.value}, already leased: ${leaseFromDApp.amount.value}" } } @@ -627,9 +627,9 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => + ) { case (snapshot, _) => val id = Lease.calculateId(Lease(recipient, amount, nonce = 0), invoke.id()) - diff.errorMessage(invoke.id()).get.text shouldBe s"Lease with id=$id is already in the state" + snapshot.errorMessage(invoke.id()).get.text shouldBe s"Lease with id=$id is already in the state" } } @@ -639,8 +639,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe "Cannot lease to self" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe "Cannot lease to self" } } @@ -650,8 +650,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe "Cannot lease to self" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe "Cannot lease to self" } } @@ -677,11 +677,11 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), features(version) - ) { case (diff, _) => - diff.errorMessage(invoke.id()) shouldBe empty - diff.portfolios(invoker) shouldBe Portfolio(-invoke.fee.value) - diff.portfolios(dAppAcc) shouldBe Portfolio(lease = LeaseBalance(in = 0, out = amount * limit)) - diff.portfolios(recipient) shouldBe Portfolio(lease = LeaseBalance(in = amount * limit, out = 0)) + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()) shouldBe empty + snapshot.balances((invoker, Waves)) shouldBe ENOUGH_AMT - invoke.fee.value + snapshot.leaseBalances(dAppAcc) shouldBe LeaseBalance(in = 0, out = amount * limit) + snapshot.leaseBalances(recipient) shouldBe LeaseBalance(in = amount * limit, out = 0) } } @@ -749,8 +749,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text should include("is already in the state") + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text should include("is already in the state") } } @@ -763,24 +763,25 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()) shouldBe empty - diff.portfolios(invoker) shouldBe Portfolio(-invoke.fee.value) - diff.portfolios(dAppAcc) shouldBe Portfolio(lease = LeaseBalance(in = 0, out = amount)) - diff.portfolios(recipient) shouldBe Portfolio(lease = LeaseBalance(in = amount, 0)) + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()) shouldBe empty + snapshot.balances((invoker, Waves)) shouldBe ENOUGH_AMT - invoke.fee.value + snapshot.leaseBalances(dAppAcc) shouldBe LeaseBalance(in = 0, out = amount) + snapshot.leaseBalances(recipient) shouldBe LeaseBalance(in = amount, 0) } } property(s"LeaseCancel action for lease performed via LeaseTransaction") { val (preparingTxs, invoke, _, dAppAcc, invoker, leaseTxs, _) = leasePreconditions(useLeaseCancelDApp = true) val leaseFromDApp = leaseTxs.head - assertDiffAndState( - Seq(TestBlock.create(preparingTxs ++ leaseTxs)), - TestBlock.create(Seq(invoke)), - v5Features - ) { case (diff, _) => - diff.portfolios(invoker) shouldBe Portfolio(-invoke.fee.value, LeaseBalance(in = -leaseFromDApp.amount.value, 0)) - diff.portfolios(dAppAcc) shouldBe Portfolio(0, LeaseBalance(0, out = -leaseFromDApp.amount.value)) + withDomain(RideV5) { d => + d.appendBlock(preparingTxs*) + d.appendBlock(leaseTxs*) + d.appendAndAssertSucceed(invoke) + d.liquidSnapshot + .leaseBalances(invoker) shouldBe d.rocksDBWriter.leaseBalance(invoker).combineF[Id](LeaseBalance(in = -leaseFromDApp.amount.value, 0)) + d.liquidSnapshot + .leaseBalances(dAppAcc) shouldBe d.rocksDBWriter.leaseBalance(dAppAcc).combineF[Id](LeaseBalance(0, out = -leaseFromDApp.amount.value)) } } @@ -791,8 +792,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe s"Lease with id=$leaseId not found" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe s"Lease with id=$leaseId not found" } } @@ -803,8 +804,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe s"Lease id=$leaseId has invalid length = 1 byte(s) while expecting 32" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe s"Lease id=$leaseId has invalid length = 1 byte(s) while expecting 32" } } @@ -815,8 +816,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs :+ leaseTx)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text should include("LeaseTransaction was leased by other sender") + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text should include("LeaseTransaction was leased by other sender") } } @@ -828,9 +829,9 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => + ) { case (snapshot, _) => val leaseId = Lease.calculateId(Lease(recipient, amount, nonce = 0), invoke.id()) - diff.errorMessage(invoke.id()).get.text shouldBe s"Duplicate LeaseCancel id(s): $leaseId" + snapshot.errorMessage(invoke.id()).get.text shouldBe s"Duplicate LeaseCancel id(s): $leaseId" } } @@ -840,8 +841,8 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs ++ leaseTxs ++ List(leaseCancelTx))), TestBlock.create(Seq(invoke)), v5Features - ) { case (diff, _) => - diff.errorMessage(invoke.id()).get.text shouldBe "Cannot cancel already cancelled lease" + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()).get.text shouldBe "Cannot cancel already cancelled lease" } } @@ -850,14 +851,18 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { val (preparingTxs, invoke, _, dAppAcc, invoker, ltx, _) = leasePreconditions(useLeaseCancelDApp = true, leaseCancelCount = ContractLimits.MaxCallableActionsAmountBeforeV6(version), version = version) val leaseTxs = ltx.init - assertDiffAndState( - Seq(TestBlock.create(preparingTxs ++ leaseTxs)), - TestBlock.create(Seq(invoke)), - features(version) - ) { case (diff, _) => - diff.errorMessage(invoke.id()) shouldBe empty - diff.portfolios(invoker) shouldBe Portfolio(-invoke.fee.value, LeaseBalance(in = -leaseTxs.map(_.amount.value).sum, out = 0)) - diff.portfolios(dAppAcc) shouldBe Portfolio(0, LeaseBalance(in = 0, out = -leaseTxs.map(_.amount.value).sum)) + withDomain(settingsForRide(version)) { d => + d.appendBlock(preparingTxs*) + d.appendBlock(leaseTxs*) + d.appendAndAssertSucceed(invoke) + d.liquidSnapshot.leaseBalances(invoker) shouldBe + d.rocksDBWriter + .leaseBalance(invoker) + .combineF[Id](LeaseBalance(in = -leaseTxs.map(_.amount.value).sum, out = 0)) + d.liquidSnapshot.leaseBalances(dAppAcc) shouldBe + d.rocksDBWriter + .leaseBalance(dAppAcc) + .combineF[Id](LeaseBalance(in = 0, out = -leaseTxs.map(_.amount.value).sum)) } } @@ -899,11 +904,12 @@ class LeaseActionDiffTest extends PropSpec with WithDomain { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), features(version) - ) { case (diff, _) => - diff.errorMessage(invoke.id()) shouldBe empty - diff.portfolios(invoker) shouldBe Portfolio(-invoke.fee.value) - diff.portfolios(dAppAcc) shouldBe Portfolio(-transfersCount, lease = LeaseBalance(in = 0, out = leaseAmount)) - diff.portfolios(recipient) shouldBe Portfolio(transfersCount, lease = LeaseBalance(in = leaseAmount, out = 0)) + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()) shouldBe empty + snapshot.balances((invoker, Waves)) shouldBe ENOUGH_AMT - invoke.fee.value + snapshot.leaseBalances.get(invoker) shouldBe None + snapshot.leaseBalances(dAppAcc) shouldBe LeaseBalance(in = 0, out = leaseAmount) + snapshot.leaseBalances(recipient) shouldBe LeaseBalance(in = leaseAmount, out = 0) } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/MultiPaymentInvokeDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/MultiPaymentInvokeDiffTest.scala index ff70c57978b..020e5ca314c 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/MultiPaymentInvokeDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/MultiPaymentInvokeDiffTest.scala @@ -10,11 +10,11 @@ import com.wavesplatform.lang.script.Script import com.wavesplatform.lang.v1.ContractLimits import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.settings.{Constants, TestFunctionalitySettings} -import com.wavesplatform.state.Diff +import com.wavesplatform.state.StateSnapshot import com.wavesplatform.state.TxMeta.Status import com.wavesplatform.state.diffs.* import com.wavesplatform.test.* -import com.wavesplatform.transaction.Asset.IssuedAsset +import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.assets.IssueTransaction import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment import com.wavesplatform.transaction.smart.{InvokeScriptTransaction, SetScriptTransaction} @@ -34,19 +34,14 @@ class MultiPaymentInvokeDiffTest extends PropSpec with WithState { Seq(TestBlock.create(genesis ++ issues ++ Seq(setDApp, setVerifier))), TestBlock.create(Seq(ci)), features - ) { case (diff, blockchain) => - val assetBalance = issues - .map(_.id()) - .map(IssuedAsset(_)) - .map(asset => asset -> blockchain.balance(dAppAcc.toAddress, asset)) - .filter(_._2 != 0) - .toMap - - diff.portfolios(dAppAcc.toAddress).assets shouldBe assetBalance - diff.portfolios(dAppAcc.toAddress).balance shouldBe -wavesTransfer - diff.portfolios(invoker.toAddress).balance shouldBe wavesTransfer - fee + ) { case (snapshot, blockchain) => + issues.foreach { tx => + val asset = IssuedAsset(tx.id()) + blockchain.balance(dAppAcc.toAddress, asset) shouldBe snapshot.balances((dAppAcc.toAddress, asset)) + } + snapshot.balances((dAppAcc.toAddress, Waves)) shouldBe ENOUGH_AMT - setDApp.fee.value - wavesTransfer + snapshot.balances((invoker.toAddress, Waves)) shouldBe ENOUGH_AMT - setVerifier.fee.value - issues.map(_.fee.value).sum - fee + wavesTransfer } - } } @@ -61,15 +56,11 @@ class MultiPaymentInvokeDiffTest extends PropSpec with WithState { Seq(TestBlock.create(genesis ++ issues ++ Seq(setDApp, setVerifier))), TestBlock.create(Seq(ci)), features - ) { case (diff, blockchain) => - val assetBalance = issues - .map(_.id()) - .map(IssuedAsset(_)) - .map(asset => asset -> blockchain.balance(dAppAcc.toAddress, asset)) - .filter(_._2 != 0) - .toMap - - diff.portfolios(dAppAcc.toAddress).assets shouldBe assetBalance + ) { case (snapshot, blockchain) => + issues.foreach { tx => + val asset = IssuedAsset(tx.id()) + blockchain.balance(dAppAcc.toAddress, asset) shouldBe snapshot.balances((dAppAcc.toAddress, asset)) + } } } } @@ -91,7 +82,7 @@ class MultiPaymentInvokeDiffTest extends PropSpec with WithState { TestBlock.create(Seq(ci)), features )(_ should matchPattern { - case Right(diff: Diff) if diff.transactions.exists(_.status != Status.Succeeded) => + case Right(snapshot: StateSnapshot) if snapshot.transactions.exists(_._2.status != Status.Succeeded) => }) } } @@ -145,17 +136,13 @@ class MultiPaymentInvokeDiffTest extends PropSpec with WithState { Seq(TestBlock.create(genesis ++ issues ++ Seq(setDApp, setVerifier))), TestBlock.create(Seq(ci)), features - ) { case (diff, blockchain) => - val assetBalance = issues - .map(_.id()) - .map(IssuedAsset(_)) - .map(asset => asset -> blockchain.balance(dAppAcc.toAddress, asset)) - .filter(_._2 != 0) - .toMap - - diff.portfolios(dAppAcc.toAddress).assets shouldBe assetBalance - diff.portfolios(dAppAcc.toAddress).balance shouldBe -wavesTransfer - diff.portfolios(invoker.toAddress).balance shouldBe wavesTransfer - fee + ) { case (snapshot, blockchain) => + issues.foreach { tx => + val asset = IssuedAsset(tx.id()) + snapshot.balances((dAppAcc.toAddress, asset)) shouldBe blockchain.balance(dAppAcc.toAddress, asset) + } + snapshot.balances((dAppAcc.toAddress, Waves)) shouldBe ENOUGH_AMT - setDApp.fee.value - wavesTransfer + snapshot.balances((invoker.toAddress, Waves)) shouldBe ENOUGH_AMT - setVerifier.fee.value - issues.map(_.fee.value).sum - fee + wavesTransfer } } } @@ -186,8 +173,8 @@ class MultiPaymentInvokeDiffTest extends PropSpec with WithState { ): Seq[ (Seq[GenesisTransaction], SetScriptTransaction, SetScriptTransaction, InvokeScriptTransaction, List[IssueTransaction], KeyPair, KeyPair, Long) ] = { - val master = TxHelpers.signer(0) - val invoker = TxHelpers.signer(1) + val master = TxHelpers.signer(1) + val invoker = TxHelpers.signer(2) val fee = if (withEnoughFee) TxHelpers.ciFee(ContractLimits.MaxAttachedPaymentAmount + 1) else TxHelpers.ciFee(1) @@ -256,8 +243,8 @@ class MultiPaymentInvokeDiffTest extends PropSpec with WithState { TestBlock.create(Seq(ci)), features ) { - case Right(diff: Diff) => - val errMsg = diff.scriptResults(diff.transactions.head.transaction.id()).error.get.text + case Right(snapshot: StateSnapshot) => + val errMsg = snapshot.scriptResults(snapshot.transactions.head._2.transaction.id()).error.get.text message(oldVersion.id, maybeFailedAssetId).r.findFirstIn(errMsg) shouldBe defined case l @ Left(_) => diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/RideV5FailRejectTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/RideV5FailRejectTest.scala index f204213cb01..2bb47c91b46 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/RideV5FailRejectTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/RideV5FailRejectTest.scala @@ -8,11 +8,11 @@ import com.wavesplatform.lang.directives.values.* import com.wavesplatform.lang.script.v1.ExprScript.ExprScriptImpl import com.wavesplatform.lang.v1.compiler.Terms.TRUE import com.wavesplatform.lang.v1.compiler.TestCompiler +import com.wavesplatform.state.StringDataEntry import com.wavesplatform.state.TxMeta.Status import com.wavesplatform.state.diffs.FeeValidation.{FeeConstants, FeeUnit} -import com.wavesplatform.state.{Portfolio, StringDataEntry} import com.wavesplatform.test.* -import com.wavesplatform.transaction.Asset.IssuedAsset +import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.TxHelpers.* import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment import com.wavesplatform.transaction.{TransactionType, TxHelpers} @@ -166,19 +166,20 @@ class RideV5FailRejectTest extends PropSpec with WithDomain { d.appendBlock(setScript(secondSigner, dApp)) d.appendBlock(invokeTx) d.blockchain.transactionInfo(invokeTx.id()).get._1.status == Status.Succeeded shouldBe false - d.liquidDiff.sponsorship shouldBe Map() - d.liquidDiff.leaseState shouldBe Map() - d.liquidDiff.issuedAssets shouldBe Map() - d.liquidDiff.updatedAssets shouldBe Map() - d.liquidDiff.accountData shouldBe Map() + d.liquidSnapshot.sponsorships shouldBe Map() + d.liquidSnapshot.leaseStates shouldBe Map() + d.liquidSnapshot.assetStatics shouldBe Map() + d.liquidSnapshot.assetNamesAndDescriptions shouldBe Map() + d.liquidSnapshot.accountData shouldBe Map() d.blockchain.accountData(secondAddress, "old").get.value shouldBe "value" - d.liquidDiff.portfolios shouldBe { + d.liquidSnapshot.balances shouldBe { val reward = d.blockchain.blockReward(d.blockchain.height).get val setScriptFee = FeeConstants(TransactionType.SetScript) * FeeUnit val previousBlockReward = (0.6 * setScriptFee).toLong val currentBlockReward = (0.4 * invokeFee).toLong - val total = reward + previousBlockReward + currentBlockReward - invokeFee - Map(defaultAddress -> Portfolio.waves(total)) + val balanceDiff = reward + previousBlockReward + currentBlockReward - invokeFee + val dbBalance = d.rocksDBWriter.balance(defaultAddress) + Map((defaultAddress, Waves) -> (dbBalance + balanceDiff)) } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/ScriptTransferTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/ScriptTransferTest.scala index cb2e3920165..aacbfc13383 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/ScriptTransferTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/ScriptTransferTest.scala @@ -90,7 +90,7 @@ class ScriptTransferTest extends PropSpec with WithDomain { val invokeTx = invoke() d.appendBlock(setScript(secondSigner, dApp)) d.appendBlockE(invokeTx) - d.liquidDiff.errorMessage(invokeTx.id()).get.text should include("key not found: asset") + d.liquidSnapshot.errorMessage(invokeTx.id()).get.text should include("key not found: asset") } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/InvokeScriptTransactionCrosscontractInvokeDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/InvokeScriptTransactionCrosscontractInvokeDiffTest.scala index ed20ca45b2a..1bee5f15f6b 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/InvokeScriptTransactionCrosscontractInvokeDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/InvokeScriptTransactionCrosscontractInvokeDiffTest.scala @@ -130,8 +130,8 @@ class InvokeScriptTransactionCrosscontractInvokeDiffTest forAll(scenario) { case (genesisTxs, invokeTx, secondDApp) => assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), fsWithV5) { - case (diff, bc) => - diff.errorMessage(invokeTx.id()) shouldBe None + case (snapshot, bc) => + snapshot.errorMessage(invokeTx.id()) shouldBe None bc.accountData(secondDApp, invokeEntry1Key) shouldBe Some(IntegerDataEntry(invokeEntry1Key, invokeEntry1Val)) bc.accountData(secondDApp, invokeEntry2Key) shouldBe Some(IntegerDataEntry(invokeEntry2Key, invokeEntry2NewVal)) @@ -215,8 +215,8 @@ class InvokeScriptTransactionCrosscontractInvokeDiffTest forAll(scenario) { case (genesisTxs, invokeTx, mainDApp) => assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), fsWithV5) { - case (diff, bc) => - diff.errorMessage(invokeTx.id()) shouldBe None + case (snapshot, bc) => + snapshot.errorMessage(invokeTx.id()) shouldBe None bc.accountData(mainDApp, invokeEntry1Key) shouldBe Some(IntegerDataEntry(invokeEntry1Key, invokeEntry1Val)) bc.accountData(mainDApp, invokeEntry2Key) shouldBe Some(IntegerDataEntry(invokeEntry2Key, invokeEntry2NewVal)) @@ -396,8 +396,8 @@ class InvokeScriptTransactionCrosscontractInvokeDiffTest forAll(scenario) { case (genesisTxs, invokeTx, thirdAcc, transferAsset, paymentAsset) => assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), fsWithV5) { - case (diff, bc) => - diff.errorMessage(invokeTx.id()) shouldBe None + case (snapshot, bc) => + snapshot.errorMessage(invokeTx.id()) shouldBe None bc.balance(thirdAcc, IssuedAsset(transferAsset)) shouldBe transferAssetAmount bc.balance(thirdAcc, IssuedAsset(paymentAsset)) shouldBe paymentAssetAmount diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppComplexityCountTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppComplexityCountTest.scala index f53b4dc645b..4802aa5ec18 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppComplexityCountTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppComplexityCountTest.scala @@ -16,7 +16,7 @@ import com.wavesplatform.state.Portfolio import com.wavesplatform.state.diffs.BlockDiffer.CurrentBlockFeePart import com.wavesplatform.state.diffs.{ENOUGH_AMT, ci} import com.wavesplatform.test.* -import com.wavesplatform.transaction.Asset.IssuedAsset +import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment import com.wavesplatform.transaction.smart.script.ScriptCompiler import com.wavesplatform.transaction.smart.{InvokeTransaction, SetScriptTransaction} @@ -168,52 +168,56 @@ class SyncDAppComplexityCountTest extends PropSpec with WithDomain { ): Unit = { val (preparingTxs, invokeTx, asset, lastCallingDApp) = scenario(dAppCount, withPayment, withThroughPayment, withThroughTransfer, withVerifier, raiseError, sequentialCalls, invokeExpression) - assertDiffEi( - Seq(TestBlock.create(preparingTxs), TestBlock.create(Seq.empty)), - TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), - features(invokeExpression) - ) { diffE => - if (reject) { - diffE shouldBe Symbol("left") - diffE should produce("Error raised") - } else { - val diff = diffE.explicitGet() - diff.scriptsComplexity shouldBe complexity - if (exceeding) - diff.errorMessage(invokeTx.id()).get.text should include("Invoke complexity limit = 26000 is exceeded") - else if (raiseError) - diff.errorMessage(invokeTx.id()).get.text should include("Error raised") - else - diff.errorMessage(invokeTx.id()) shouldBe None - - val dAppAddress = invokeTx.dApp.asInstanceOf[Address] - val basePortfolios = - Map(TestBlock.defaultSigner.toAddress -> Portfolio(CurrentBlockFeePart(invokeTx.fee.value))) |+| - Map(invokeTx.sender.toAddress -> Portfolio(-invokeTx.fee.value)) - val paymentsPortfolios = - Map(invokeTx.sender.toAddress -> Portfolio.build(asset, -1)) |+| - Map(dAppAddress -> Portfolio.build(asset, 1)) - val throughTransfersPortfolios = - Map(invokeTx.sender.toAddress -> Portfolio.build(asset, 1)) |+| - Map(lastCallingDApp -> Portfolio.build(asset, -1)) - val throughPaymentsPortfolios = - Map(lastCallingDApp -> Portfolio.build(asset, 1)) |+| - Map(dAppAddress -> Portfolio.build(asset, -1)) - - val overlappedPortfolio = Portfolio.build(asset, 0) - val emptyPortfolios = Map.empty[Address, Portfolio] - - val additionalPortfolios = - (if (withPayment) paymentsPortfolios else emptyPortfolios) |+| - (if (withThroughPayment) throughPaymentsPortfolios else emptyPortfolios) |+| - (if (withThroughTransfer) throughTransfersPortfolios else emptyPortfolios) - - val totalPortfolios = if (exceeding || raiseError) basePortfolios else basePortfolios |+| additionalPortfolios - - diff.portfolios.filter(_._2 != overlappedPortfolio) shouldBe - totalPortfolios - .filter(_._2 != overlappedPortfolio) - .map(p => p.copy(_2 = p._2.copy(assets = p._2.assets.filterNot(_._2 == 0)))) + withTestState(features(invokeExpression)) { (bu, db) => + assertDiffEi( + Seq(TestBlock.create(preparingTxs), TestBlock.create(Seq.empty)), + TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), + bu, + db, + enableExecutionLog = false + ) { diffE => + if (reject) { + diffE shouldBe Symbol("left") + diffE should produce("Error raised") + } else { + val snapshot = diffE.explicitGet() + snapshot.scriptsComplexity shouldBe complexity + if (exceeding) + snapshot.errorMessage(invokeTx.id()).get.text should include("Invoke complexity limit = 26000 is exceeded") + else if (raiseError) + snapshot.errorMessage(invokeTx.id()).get.text should include("Error raised") + else + snapshot.errorMessage(invokeTx.id()) shouldBe None + + val dAppAddress = invokeTx.dApp.asInstanceOf[Address] + val basePortfolios = + Map(TestBlock.defaultSigner.toAddress -> Portfolio(CurrentBlockFeePart(invokeTx.fee.value))) |+| + Map(invokeTx.sender.toAddress -> Portfolio(-invokeTx.fee.value)) + val paymentsPortfolios = + Map(invokeTx.sender.toAddress -> Portfolio.build(asset, -1)) |+| + Map(dAppAddress -> Portfolio.build(asset, 1)) + val throughTransfersPortfolios = + Map(invokeTx.sender.toAddress -> Portfolio.build(asset, 1)) |+| + Map(lastCallingDApp -> Portfolio.build(asset, -1)) + val throughPaymentsPortfolios = + Map(lastCallingDApp -> Portfolio.build(asset, 1)) |+| + Map(dAppAddress -> Portfolio.build(asset, -1)) + + val emptyPortfolios = Map.empty[Address, Portfolio] + val additionalPortfolios = + (if (withPayment) paymentsPortfolios else emptyPortfolios) |+| + (if (withThroughPayment) throughPaymentsPortfolios else emptyPortfolios) |+| + (if (withThroughTransfer) throughTransfersPortfolios else emptyPortfolios) + + val expectedPortfolios = if (exceeding || raiseError) basePortfolios else basePortfolios |+| additionalPortfolios + expectedPortfolios + .foreach { case (address, expectedPortfolio) => + expectedPortfolio.balance shouldBe snapshot.balances.get((address, Waves)).map(_ - db.balance(address)).getOrElse(0) + expectedPortfolio.assets.foreach { case (asset, balance) => + balance shouldBe snapshot.balances.get((address, asset)).map(_ - db.balance(address, asset)).getOrElse(0) + } + } + } } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppGeneratingBalanceTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppGeneratingBalanceTest.scala index 07aebadeb4e..492982797ae 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppGeneratingBalanceTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppGeneratingBalanceTest.scala @@ -35,10 +35,10 @@ class SyncDAppGeneratingBalanceTest extends PropSpec with WithDomain { d.appendBlock(setScript(defaultSigner, dApp), setScript(secondSigner, dApp)) d.appendAndAssertSucceed(invoke(secondAddress, invoker = secondSigner)) - d.liquidDiff.accountData.head._2.head._2.value shouldBe 0 + d.liquidSnapshot.accountData.head._2.head._2.value shouldBe 0 d.appendAndAssertSucceed(invoke(secondAddress, invoker = secondSigner)) - d.liquidDiff.accountData.head._2.head._2.value shouldBe amount + d.liquidSnapshot.accountData.head._2.head._2.value shouldBe amount } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppLeaseBalanceCheckTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppLeaseBalanceCheckTest.scala index eab3c890818..fdbba4048ec 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppLeaseBalanceCheckTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppLeaseBalanceCheckTest.scala @@ -70,7 +70,7 @@ class SyncDAppLeaseBalanceCheckTest extends PropSpec with WithDomain { if (bigComplexityDApp1 || bigComplexityDApp2) { d.appendBlock(invoke) - d.liquidDiff.errorMessage(invoke.txId).get.text should include("Cannot lease more than own: Balance: 0") + d.liquidSnapshot.errorMessage(invoke.txId).get.text should include("Cannot lease more than own: Balance: 0") } else { d.appendBlockE(invoke) should produce("Cannot lease more than own: Balance: 0") } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppLimits.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppLimits.scala index 3777f2dccb4..27b4ee28c4f 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppLimits.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppLimits.scala @@ -64,8 +64,8 @@ class SyncDAppLimits extends PropSpec with WithDomain with OptionValues with Eit val calls = complexityLimit / 2000 + 1 val invokeTx = TxHelpers.invoke(aliceAddr, Some("foo"), Seq(CONST_LONG(calls)), invoker = alice) - val diff = d.createDiffE(invokeTx).value - val (_, scriptResult) = diff.scriptResults.headOption.value + val snapshot = d.createDiffE(invokeTx).value + val (_, scriptResult) = snapshot.scriptResults.headOption.value scriptResult.error.value.text should include(s"Invoke complexity limit = $complexityLimit is exceeded") d.appendBlock(invokeTx) @@ -99,8 +99,8 @@ class SyncDAppLimits extends PropSpec with WithDomain with OptionValues with Eit val invokeTx = TxHelpers.invoke(aliceAddr, Some("foo"), Seq(CONST_LONG(101)), invoker = alice) - val diff = d.createDiffE(invokeTx).value - val (_, scriptResult) = diff.scriptResults.headOption.value + val snapshot = d.createDiffE(invokeTx).value + val (_, scriptResult) = snapshot.scriptResults.headOption.value scriptResult.error.value.text should include("DApp calls limit = 100 is exceeded") d.appendBlock(invokeTx) diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppNegativeIssueTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppNegativeIssueTest.scala index bce5c824764..4377f2733c8 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppNegativeIssueTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppNegativeIssueTest.scala @@ -67,7 +67,7 @@ class SyncDAppNegativeIssueTest extends PropSpec with WithDomain { d.appendBlock(preparingTxs*) if (bigComplexityDApp1 || bigComplexityDApp2) { d.appendBlock(invoke) - d.liquidDiff.errorMessage(invoke.txId).get.text should include("Invalid decimals") + d.liquidSnapshot.errorMessage(invoke.txId).get.text should include("Invalid decimals") } else { d.appendBlockE(invoke) should produce("Invalid decimals") d.appendBlock() diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppPaymentTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppPaymentTest.scala index ce4064f7c02..d2be554298c 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppPaymentTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppPaymentTest.scala @@ -10,7 +10,6 @@ import com.wavesplatform.lang.directives.values.V5 import com.wavesplatform.lang.script.Script import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.lang.v1.evaluator.ctx.impl.GlobalValNames -import com.wavesplatform.state.Portfolio import com.wavesplatform.state.diffs.{ENOUGH_AMT, produceRejectOrFailedDiff} import com.wavesplatform.test.* import com.wavesplatform.test.DomainPresets.* @@ -34,8 +33,8 @@ class SyncDAppPaymentTest extends PropSpec with WithDomain { d.appendBlock(invoke1) d.blockchain.transactionSucceeded(invoke1.id.value()) shouldBe true - d.liquidDiff.portfolios(dApp1) shouldBe Portfolio.build(asset, 1) - d.liquidDiff.portfolios(dApp2) shouldBe Portfolio.build(asset, -1) + d.liquidSnapshot.balances((dApp1, asset)) shouldBe d.rocksDBWriter.balance(dApp1, asset) + 1 + d.liquidSnapshot.balances((dApp2, asset)) shouldBe d.rocksDBWriter.balance(dApp2, asset) - 1 val invoke2 = invoke() d.appendBlockE(invoke2) should produce { diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppRecursionTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppRecursionTest.scala index 32a135f3f4e..eea40a4817c 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppRecursionTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppRecursionTest.scala @@ -109,9 +109,9 @@ class SyncDAppRecursionTest extends PropSpec with WithDomain with Inside { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), features(invokeExpression) - ) { case (diff, _) => - diff.errorMessage(invoke.id()) shouldBe None - inside(diff.scriptResults.toSeq) { case Seq((_, call1)) => + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id()) shouldBe None + inside(snapshot.scriptResults.toSeq) { case Seq((_, call1)) => inside(call1.invokes) { case Seq(call2) => inside(call2.stateChanges.invokes) { case Seq(call3) => call3.stateChanges.error shouldBe empty @@ -308,9 +308,9 @@ class SyncDAppRecursionTest extends PropSpec with WithDomain with Inside { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), features() - ) { case (diff, _) => - diff.errorMessage(invoke.id.value()) shouldBe None - inside(diff.scriptResults.toSeq) { case Seq((_, call1)) => + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id.value()) shouldBe None + inside(snapshot.scriptResults.toSeq) { case Seq((_, call1)) => inside(call1.invokes) { case Seq(call2) => inside(call2.stateChanges.invokes) { case Seq(call3) => inside(call3.stateChanges.invokes) { case Seq(call4) => @@ -352,9 +352,9 @@ class SyncDAppRecursionTest extends PropSpec with WithDomain with Inside { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), features() - ) { case (diff, _) => - diff.errorMessage(invoke.id.value()) shouldBe None - inside(diff.scriptResults.toSeq) { case Seq((_, call1)) => + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id.value()) shouldBe None + inside(snapshot.scriptResults.toSeq) { case Seq((_, call1)) => inside(call1.invokes) { case Seq(call2) => inside(call2.stateChanges.invokes) { case Seq(call3) => inside(call3.stateChanges.invokes) { case Seq(call4) => @@ -394,9 +394,9 @@ class SyncDAppRecursionTest extends PropSpec with WithDomain with Inside { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), features() - ) { case (diff, _) => - diff.errorMessage(invoke.id.value()) shouldBe None - inside(diff.scriptResults.toSeq) { case Seq((_, call1)) => + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id.value()) shouldBe None + inside(snapshot.scriptResults.toSeq) { case Seq((_, call1)) => inside(call1.invokes) { case Seq(call2) => inside(call2.stateChanges.invokes) { case Seq(call3) => inside(call3.stateChanges.invokes) { case Seq(call4) => @@ -476,9 +476,9 @@ class SyncDAppRecursionTest extends PropSpec with WithDomain with Inside { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), features() - ) { case (diff, _) => - diff.errorMessage(invoke.id.value()) shouldBe None - inside(diff.scriptResults.toSeq) { case Seq((_, call1)) => + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id.value()) shouldBe None + inside(snapshot.scriptResults.toSeq) { case Seq((_, call1)) => inside(call1.invokes) { case Seq(call2) => inside(call2.stateChanges.invokes) { case Seq(call3) => inside(call3.stateChanges.invokes) { case Seq(call4) => @@ -565,9 +565,9 @@ class SyncDAppRecursionTest extends PropSpec with WithDomain with Inside { Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invoke)), features() - ) { case (diff, _) => - diff.errorMessage(invoke.id.value()) shouldBe None - inside(diff.scriptResults.toSeq) { case Seq((_, call1)) => + ) { case (snapshot, _) => + snapshot.errorMessage(invoke.id.value()) shouldBe None + inside(snapshot.scriptResults.toSeq) { case Seq((_, call1)) => inside(call1.invokes) { case Seq(call21, call22) => inside(call21.stateChanges.invokes) { case Seq(call31) => call31.stateChanges.error shouldBe empty diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppReissueTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppReissueTest.scala index 665ceabed83..ba46aeb05bf 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppReissueTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppReissueTest.scala @@ -102,7 +102,7 @@ class SyncDAppReissueTest extends PropSpec with WithDomain { if (bigComplexityDApp1 || bigComplexityDApp2) { d.appendBlock(invoke) - d.liquidDiff.errorMessage(invoke.txId).get.text should include("Asset was issued by other address") + d.liquidSnapshot.errorMessage(invoke.txId).get.text should include("Asset was issued by other address") } else { d.appendBlockE(invoke) should produce("Asset was issued by other address") } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppTransferTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppTransferTest.scala index 9aa6f375b8f..c393500a034 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppTransferTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncDAppTransferTest.scala @@ -18,7 +18,7 @@ import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.lang.v1.evaluator.FunctionIds.CREATE_LIST import com.wavesplatform.lang.v1.evaluator.ctx.impl.GlobalValNames import com.wavesplatform.protobuf.dapp.DAppMeta -import com.wavesplatform.state.diffs.produceRejectOrFailedDiff +import com.wavesplatform.state.diffs.{ENOUGH_AMT, produceRejectOrFailedDiff} import com.wavesplatform.test.* import com.wavesplatform.test.DomainPresets.* import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} @@ -108,10 +108,10 @@ class SyncDAppTransferTest extends PropSpec with WithDomain with Inside { } property("invoking ScriptTransfer in sync call results in accounts state") { - val invoker = TxHelpers.signer(0) - val invokerDApp = TxHelpers.signer(1) - val senderDApp = TxHelpers.signer(2) - val recipient = TxHelpers.signer(3) + val invoker = TxHelpers.signer(1) + val invokerDApp = TxHelpers.signer(2) + val senderDApp = TxHelpers.signer(3) + val recipient = TxHelpers.signer(4) val transferAmount = 10.waves @@ -131,17 +131,17 @@ class SyncDAppTransferTest extends PropSpec with WithDomain with Inside { call2.stateChanges.invokes shouldBe empty } } - blockDiff.portfolios(recipient.toAddress).balance shouldBe transferAmount - blockDiff.portfolios(senderDApp.toAddress).balance shouldBe -transferAmount - blockDiff.transaction(invoke.id()) shouldBe defined + blockDiff.balances((recipient.toAddress, Waves)) shouldBe transferAmount + blockDiff.balances((senderDApp.toAddress, Waves)) shouldBe ENOUGH_AMT - setSenderScript.fee.value - transferAmount + blockDiff.transactions.get(invoke.id()) shouldBe defined } } property("invoking default func ScriptTransfer in sync call results in accounts state") { - val invoker = TxHelpers.signer(0) - val invokerDApp = TxHelpers.signer(1) - val senderDApp = TxHelpers.signer(2) - val recipient = TxHelpers.signer(3) + val invoker = TxHelpers.signer(1) + val invokerDApp = TxHelpers.signer(2) + val senderDApp = TxHelpers.signer(3) + val recipient = TxHelpers.signer(4) val transferAmount = 10.waves @@ -161,9 +161,9 @@ class SyncDAppTransferTest extends PropSpec with WithDomain with Inside { call2.stateChanges.invokes shouldBe empty } } - blockDiff.portfolios(recipient.toAddress).balance shouldBe transferAmount - blockDiff.portfolios(senderDApp.toAddress).balance shouldBe -transferAmount - blockDiff.transaction(invoke.id()) shouldBe defined + blockDiff.balances((recipient.toAddress, Waves)) shouldBe transferAmount + blockDiff.balances((senderDApp.toAddress, Waves)) shouldBe ENOUGH_AMT - setSenderScript.fee.value - transferAmount + blockDiff.transactions.get(invoke.id()) shouldBe defined } } @@ -184,10 +184,10 @@ class SyncDAppTransferTest extends PropSpec with WithDomain with Inside { } property("ScriptTransfer in sync call is allowed if funds were received from attached payment") { - val invoker = TxHelpers.signer(0) - val invokerDApp = TxHelpers.signer(1) - val senderDApp = TxHelpers.signer(2) - val recipient = TxHelpers.signer(3) + val invoker = TxHelpers.signer(1) + val invokerDApp = TxHelpers.signer(2) + val senderDApp = TxHelpers.signer(3) + val recipient = TxHelpers.signer(4) val transferAmount = 10.waves @@ -210,9 +210,9 @@ class SyncDAppTransferTest extends PropSpec with WithDomain with Inside { call2.stateChanges.invokes shouldBe empty } } - blockDiff.portfolios(recipient.toAddress).balance shouldBe transferAmount - blockDiff.portfolios(invokerDApp.toAddress).balance shouldBe -transferAmount - blockDiff.transaction(invoke.id()) shouldBe defined + blockDiff.balances((recipient.toAddress, Waves)) shouldBe transferAmount + blockDiff.balances((invokerDApp.toAddress, Waves)) shouldBe ENOUGH_AMT - setSenderScript.fee.value - transferAmount + blockDiff.transactions.get(invoke.id()) shouldBe defined } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeActionsTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeActionsTest.scala index 40eb6e81083..e573d9caf04 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeActionsTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeActionsTest.scala @@ -3,13 +3,14 @@ package com.wavesplatform.state.diffs.ci.sync import com.wavesplatform.TestValues.invokeFee import com.wavesplatform.db.WithDomain import com.wavesplatform.db.WithState.AddrWithBalance -import com.wavesplatform.lang.directives.values._ +import com.wavesplatform.lang.directives.values.* import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.test.{PropSpec, produce} -import com.wavesplatform.transaction.TxHelpers._ +import com.wavesplatform.transaction.Asset.Waves +import com.wavesplatform.transaction.TxHelpers.* class SyncInvokeActionsTest extends PropSpec with WithDomain { - import DomainPresets._ + import DomainPresets.* private val dApp1Signer = secondSigner private val dApp1Address = secondAddress @@ -68,9 +69,9 @@ class SyncInvokeActionsTest extends PropSpec with WithDomain { ) d.appendBlock(setScript(dApp1Signer, dApp1), setScript(dApp2Signer, dApp2)) d.appendAndAssertSucceed(invoke(dApp1Address, fee = invokeFee(issues = 1))) - d.liquidDiff.portfolios.get(dApp1Address) shouldBe empty - d.liquidDiff.portfolios.get(dApp2Address) shouldBe empty - d.liquidDiff.portfolios(defaultAddress).assets.head._2 shouldBe 1000 + d.liquidSnapshot.balances.get((dApp1Address, Waves)) shouldBe empty + d.liquidSnapshot.balances.get((dApp2Address, Waves)) shouldBe empty + d.liquidSnapshot.balances.collect { case ((address, asset), amount) if address == defaultAddress && asset != Waves => amount}.head shouldBe 1000 } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeDiffTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeDiffTest.scala index 6fdfbfc872e..040ce701672 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeDiffTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeDiffTest.scala @@ -68,8 +68,8 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val invoke = TxHelpers.invoke(dAppAddress, Some("foo"), Nil, payments) assertDiffAndState(Seq(TestBlock.create(Seq(gTx1, gTx2, ssTx))), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { - case (diff, bc) => - diff.errorMessage(invoke.id()) shouldBe None + case (snapshot, bc) => + snapshot.errorMessage(invoke.id()) shouldBe None bc.accountData(dAppAddress, "key") shouldBe Some(IntegerDataEntry("key", 1)) bc.accountData(dAppAddress, "bar") shouldBe Some(IntegerDataEntry("bar", 1)) } @@ -109,10 +109,10 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val invoke = TxHelpers.invoke(dAppAddress, Some("foo"), Nil, payments) assertDiffAndState(Seq(TestBlock.create(Seq(gTx1, gTx2, ssTx))), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { - case (diff, _) => - diff.errorMessage(invoke.id()) shouldBe None - diff.scriptsComplexity shouldBe 108 - inside(diff.scriptResults.toSeq) { case Seq((_, call1)) => + case (snapshot, _) => + snapshot.errorMessage(invoke.id()) shouldBe None + snapshot.scriptsComplexity shouldBe 108 + inside(snapshot.scriptResults.toSeq) { case Seq((_, call1)) => inside(call1.invokes) { case Seq(call2) => call2.stateChanges.error shouldBe empty call2.stateChanges.invokes shouldBe empty @@ -187,11 +187,11 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val invoke = TxHelpers.invoke(dAppAddress, Some("foo"), Nil, payments, fee = TestValues.invokeFee(issues = 1)) val genesisTxs = Seq(gTx1, gTx2, gTx3, aliasTx, ssTx1, ssTx) - assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (diff, bc) => - diff.scriptResults(invoke.id()).error shouldBe None - val l = diff.scriptResults(invoke.id()).leases(0) - val l1 = diff.scriptResults(invoke.id()).leases(1) - val l2 = diff.scriptResults(invoke.id()).leaseCancels(0) + assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (snapshot, bc) => + snapshot.scriptResults(invoke.id()).error shouldBe None + val l = snapshot.scriptResults(invoke.id()).leases(0) + val l1 = snapshot.scriptResults(invoke.id()).leases(1) + val l2 = snapshot.scriptResults(invoke.id()).leaseCancels(0) l.amount shouldBe 13 l.recipient shouldBe thirdAcc.toAddress l1.amount shouldBe 23 @@ -266,11 +266,11 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val invoke = TxHelpers.invoke(dAppAddress, Some("foo"), payments = payments, fee = TestValues.invokeFee(issues = 1)) val genesisTxs = Seq(gTx1, gTx2, gTx3, aliasTx, ssTx1, ssTx) - assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (diff, bc) => - diff.scriptResults(invoke.id()).error shouldBe None - val l = diff.scriptResults(invoke.id()).leases(0) - val l1 = diff.scriptResults(invoke.id()).leases(1) - val l2 = diff.scriptResults(invoke.id()).leaseCancels(0) + assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (snapshot, bc) => + snapshot.scriptResults(invoke.id()).error shouldBe None + val l = snapshot.scriptResults(invoke.id()).leases(0) + val l1 = snapshot.scriptResults(invoke.id()).leases(1) + val l2 = snapshot.scriptResults(invoke.id()).leaseCancels(0) l.amount shouldBe 13 l.recipient shouldBe thirdAcc.toAddress l1.amount shouldBe 23 @@ -340,8 +340,8 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val payments = List(Payment(10L, Waves)) val invoke = TxHelpers.invoke(dAppAddress, Some("foo"), payments = payments, fee = TestValues.invokeFee(2)) val genesisTxs = Seq(gTx1, gTx2, gTx3, aliasTx, ssTx1, ssTx) - assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (diff, bc) => - val err = diff.scriptResults(invoke.id()).error.get + assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (snapshot, bc) => + val err = snapshot.scriptResults(invoke.id()).error.get err.code shouldBe FailedTransactionError.Cause.FeeForActions.code bc.accountData(dAppAddress, "key") shouldBe None bc.accountData(thirdAcc.toAddress, "bar") shouldBe None @@ -409,7 +409,7 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val invoke = TxHelpers.invoke(dAppAddress, Some("foo"), payments = payments, fee = TestValues.invokeFee(issues = 1)) val genesisTxs = Seq(gTx1, gTx2, gTx3, aliasTx, ssTx1, ssTx) - assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (diff, bc) => + assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (snapshot, bc) => bc.accountData(dAppAddress, "key") shouldBe Some(IntegerDataEntry("key", 1)) bc.accountData(thirdAcc.toAddress, "bar") shouldBe Some(IntegerDataEntry("bar", 1)) } @@ -481,7 +481,7 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val genesisTxs = Seq(gTx1, gTx2, gTx3, ssTx1, ssTx) - assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (diff, bc) => + assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (snapshot, bc) => bc.accountData(dAppAddress, "key") shouldBe Some(IntegerDataEntry("key", 1)) bc.accountData(thirdAcc.toAddress, "bar") shouldBe Some(IntegerDataEntry("bar", 1)) } @@ -1064,8 +1064,8 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val invoke = TxHelpers.invoke(dAppAddress, Some("foo"), payments = payments, fee = fee) val genesisTxs = Seq(gTx1, gTx2, gTx3, setServiceDApp, setClientDApp, paymentIssue, transferIssue) - assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (diff, bc) => - diff.errorMessage(invoke.id()) shouldBe None + assertDiffAndState(Seq(TestBlock.create(genesisTxs)), TestBlock.create(Seq(invoke), Block.ProtoBlockVersion), fsWithV5) { case (snapshot, bc) => + snapshot.errorMessage(invoke.id()) shouldBe None bc.accountData(dAppAddress, "key") shouldBe Some(IntegerDataEntry("key", 1)) bc.accountData(thirdAcc.toAddress, "bar") shouldBe Some(IntegerDataEntry("bar", 1)) @@ -1137,8 +1137,8 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val invokeTx = TxHelpers.invoke(dAppAddress, Some("foo"), payments = payments) val preparingTxs = Seq(gTx1, gTx2, gTx3, ssTxMain, ssTxSecond, dataTxSecond, dataTxSecond2) - assertDiffAndState(Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), fsWithV5) { case (diff, bc) => - diff.errorMessage(invokeTx.id()) shouldBe None + assertDiffAndState(Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), fsWithV5) { case (snapshot, bc) => + snapshot.errorMessage(invokeTx.id()) shouldBe None bc.accountData(thirdAddress, invokeEntry1Key) shouldBe Some(IntegerDataEntry(invokeEntry1Key, invokeEntry1Val)) bc.accountData(thirdAddress, invokeEntry2Key) shouldBe Some(IntegerDataEntry(invokeEntry2Key, invokeEntry2NewVal)) } @@ -1196,8 +1196,8 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val invokeTx = TxHelpers.invoke(dAppAddress, Some("foo"), payments = payments) val preparingTxs = Seq(gTx1, gTx2, ssTxMain, dataTxMain, dataTxMain2) - assertDiffAndState(Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), fsWithV5) { case (diff, bc) => - diff.errorMessage(invokeTx.id()) shouldBe None + assertDiffAndState(Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), fsWithV5) { case (snapshot, bc) => + snapshot.errorMessage(invokeTx.id()) shouldBe None bc.accountData(dAppAddress, invokeEntry1Key) shouldBe Some(IntegerDataEntry(invokeEntry1Key, invokeEntry1Val)) bc.accountData(dAppAddress, invokeEntry2Key) shouldBe Some(IntegerDataEntry(invokeEntry2Key, invokeEntry2NewVal)) } @@ -1300,8 +1300,8 @@ class SyncInvokeDiffTest extends PropSpec with WithDomain with DBCacheSettings w val invokeTx = TxHelpers.invoke(dAppAddress, Some("foo"), payments = payments) val preparingTxs = Seq(gTx1, gTx2, gTx3, gTx4, ssTxMain, ssTxSecond, ssTxThird, paymentIssue, transferIssue) - assertDiffAndState(Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), fsWithV5) { case (diff, bc) => - diff.errorMessage(invokeTx.id()) shouldBe None + assertDiffAndState(Seq(TestBlock.create(preparingTxs)), TestBlock.create(Seq(invokeTx), Block.ProtoBlockVersion), fsWithV5) { case (snapshot, bc) => + snapshot.errorMessage(invokeTx.id()) shouldBe None bc.balance(thirdAcc.toAddress, IssuedAsset(transferIssue.id())) shouldBe transferAssetAmount bc.balance(thirdAcc.toAddress, IssuedAsset(paymentIssue.id())) shouldBe paymentAssetAmount } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeFailAndRejectTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeFailAndRejectTest.scala index 305aeee3481..3b5dd17e357 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeFailAndRejectTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeFailAndRejectTest.scala @@ -7,11 +7,11 @@ import com.wavesplatform.lang.directives.values.* import com.wavesplatform.lang.script.v1.ExprScript.ExprScriptImpl import com.wavesplatform.lang.v1.compiler.Terms.TRUE import com.wavesplatform.lang.v1.compiler.TestCompiler +import com.wavesplatform.state.StringDataEntry import com.wavesplatform.state.TxMeta.Status import com.wavesplatform.state.diffs.FeeValidation.{FeeConstants, FeeUnit} -import com.wavesplatform.state.{Portfolio, StringDataEntry} import com.wavesplatform.test.{PropSpec, produce} -import com.wavesplatform.transaction.Asset.IssuedAsset +import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.TransactionType import com.wavesplatform.transaction.TxHelpers.* import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment @@ -76,19 +76,21 @@ class SyncInvokeFailAndRejectTest extends PropSpec with WithDomain { d.appendBlock(setScript(dApp2Signer, dApp2)) d.appendBlock(invokeTx) d.blockchain.transactionInfo(invokeTx.id()).get._1.status == Status.Succeeded shouldBe false - d.liquidDiff.sponsorship shouldBe Map() - d.liquidDiff.leaseState shouldBe Map() - d.liquidDiff.issuedAssets shouldBe Map() - d.liquidDiff.updatedAssets shouldBe Map() - d.liquidDiff.accountData shouldBe Map() + d.liquidSnapshot.sponsorships shouldBe Map() + d.liquidSnapshot.leaseStates shouldBe Map() + d.liquidSnapshot.assetStatics shouldBe Map() + d.liquidSnapshot.assetNamesAndDescriptions shouldBe Map() + d.liquidSnapshot.assetVolumes shouldBe Map() + d.liquidSnapshot.accountData shouldBe Map() d.blockchain.accountData(dApp2Address, "old").get.value shouldBe "value" - d.liquidDiff.portfolios shouldBe { + d.liquidSnapshot.balances shouldBe { val reward = d.blockchain.blockReward(d.blockchain.height).get val setScriptFee = FeeConstants(TransactionType.SetScript) * FeeUnit val previousBlockReward = (0.6 * setScriptFee).toLong val currentBlockReward = (0.4 * invokeFee).toLong - val total = reward + previousBlockReward + currentBlockReward - invokeFee - Map(defaultAddress -> Portfolio.waves(total)) + val balanceDiff = reward + previousBlockReward + currentBlockReward - invokeFee + val dbBalance = d.rocksDBWriter.balance(defaultAddress) + Map((defaultAddress, Waves) -> (balanceDiff + dbBalance)) } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeLeaseTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeLeaseTest.scala index f5a2165bf29..7f1f0695582 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeLeaseTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeLeaseTest.scala @@ -42,11 +42,11 @@ class SyncInvokeLeaseTest extends PropSpec with WithDomain { withDomain(RideV5, AddrWithBalance.enoughBalances(dApp1Signer)) { d => d.appendBlock(setScript(dApp1Signer, twoLeaseDApp(555))) d.appendAndAssertSucceed(invoke(dApp1Address)) - val lease1 = d.liquidDiff.leaseState.head._2 + val lease1 = d.liquidSnapshot.leaseStates.head._2 lease1.status shouldBe a[Cancelled] lease1.recipient shouldBe dApp2Address lease1.amount shouldBe 1 - val lease2 = d.liquidDiff.leaseState.last._2 + val lease2 = d.liquidSnapshot.leaseStates.last._2 lease2.status shouldBe Active lease2.recipient shouldBe dApp2Address lease2.amount shouldBe 555 @@ -57,7 +57,7 @@ class SyncInvokeLeaseTest extends PropSpec with WithDomain { withDomain(RideV5, AddrWithBalance.enoughBalances(dApp1Signer)) { d => d.appendBlock(setScript(dApp1Signer, twoLeaseDApp(1))) d.appendAndAssertFailed(invoke(dApp1Address), "already in the state") - d.liquidDiff.leaseState shouldBe Map() + d.liquidSnapshot.leaseStates shouldBe Map() } } @@ -83,7 +83,7 @@ class SyncInvokeLeaseTest extends PropSpec with WithDomain { ) d.appendBlock(setScript(dApp1Signer, dApp)) d.appendAndAssertFailed(invoke(dApp1Address), "Cannot cancel already cancelled lease") - d.liquidDiff.leaseState shouldBe Map() + d.liquidSnapshot.leaseStates shouldBe Map() } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeTotalPaymentsTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeTotalPaymentsTest.scala index a3b0ae863da..58c6c383dd0 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeTotalPaymentsTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeTotalPaymentsTest.scala @@ -75,7 +75,7 @@ class SyncInvokeTotalPaymentsTest extends PropSpec with WithDomain { if (error) if (fail) { d.appendAndAssertFailed(tx) - d.liquidDiff.errorMessage(tx.id()).get.text should include("Invoke payments limit = 100 is exceeded") + d.liquidSnapshot.errorMessage(tx.id()).get.text should include("Invoke payments limit = 100 is exceeded") } else d.appendBlockE(tx) should produce("Invoke payments limit = 100 is exceeded") else diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeValidationTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeValidationTest.scala index 7b0559ec41a..bff3d5b6ff7 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeValidationTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/ci/sync/SyncInvokeValidationTest.scala @@ -228,7 +228,7 @@ class SyncInvokeValidationTest extends PropSpec with WithDomain { d.appendBlock(setScript(dApp1Signer, dApp1), setScript(dApp2Signer, dApp2), setScript(dApp3Signer, dApp3)) d.appendAndAssertSucceed(invoke(dApp1Address)) - d.liquidDiff.transactions.head.affected shouldBe Set(dApp1Address, dApp2Address, dApp3Address, defaultAddress) + d.liquidSnapshot.transactions.head._2.affected shouldBe Set(dApp1Address, dApp2Address, dApp3Address, defaultAddress) } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/freecall/InvokeExpressionTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/freecall/InvokeExpressionTest.scala index c74dc25897b..fad4021826c 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/freecall/InvokeExpressionTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/freecall/InvokeExpressionTest.scala @@ -10,10 +10,12 @@ import com.wavesplatform.lang.script.Script import com.wavesplatform.lang.script.v1.ExprScript import com.wavesplatform.lang.v1.ContractLimits import com.wavesplatform.lang.v1.compiler.TestCompiler +import com.wavesplatform.protobuf.ByteStringExt +import com.wavesplatform.protobuf.snapshot.TransactionStateSnapshot.AssetStatic import com.wavesplatform.state.diffs.FeeValidation.{FeeConstants, FeeUnit} import com.wavesplatform.state.diffs.ci.ciFee import com.wavesplatform.state.diffs.{ENOUGH_AMT, FeeValidation} -import com.wavesplatform.state.{BinaryDataEntry, BooleanDataEntry, NewAssetInfo} +import com.wavesplatform.state.{AssetInfo, AssetVolumeInfo, BinaryDataEntry, BooleanDataEntry} import com.wavesplatform.test.* import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.assets.{IssueTransaction, SponsorFeeTransaction} @@ -156,8 +158,8 @@ class InvokeExpressionTest extends PropSpec with ScalaCheckPropertyChecks with W d.appendBlock(invoke) d.blockchain.accountData(invoke.sender.toAddress, "check").get shouldBe BooleanDataEntry("check", true) d.blockchain.accountData(invoke.sender.toAddress, "transactionId").get shouldBe BinaryDataEntry("transactionId", invoke.txId) - d.liquidDiff.issuedAssets.size shouldBe 1 - checkAsset(invoke, d.liquidDiff.issuedAssets.head._2) + d.liquidSnapshot.assetStatics.size shouldBe 1 + checkAsset(invoke, d.liquidSnapshot.assetStatics.head._2, d.liquidSnapshot.assetNamesAndDescriptions.head._2, d.liquidSnapshot.assetVolumes.head._2) } } @@ -324,21 +326,23 @@ class InvokeExpressionTest extends PropSpec with ScalaCheckPropertyChecks with W withDomain(ContinuationTransaction) { d => d.appendBlock(genesisTxs*) d.appendBlock(invoke) - d.liquidDiff.errorMessage(invoke.id.value()).get.text should include("Explicit script termination") + d.liquidSnapshot.errorMessage(invoke.id.value()).get.text should include("Explicit script termination") } } private[this] def checkAsset( invoke: InvokeExpressionTransaction, - asset: NewAssetInfo + static: AssetStatic, + info: AssetInfo, + volume: AssetVolumeInfo ): Assertion = { - asset.dynamic.name.toStringUtf8 shouldBe TestAssetName - asset.dynamic.description.toStringUtf8 shouldBe TestAssetDesc - asset.volume.volume shouldBe TestAssetVolume - asset.volume.isReissuable shouldBe TestAssetReissuable - asset.static.decimals shouldBe TestAssetDecimals - asset.static.nft shouldBe false - asset.static.issuer shouldBe invoke.sender + info.name.toStringUtf8 shouldBe TestAssetName + info.description.toStringUtf8 shouldBe TestAssetDesc + volume.volume shouldBe TestAssetVolume + volume.isReissuable shouldBe TestAssetReissuable + static.decimals shouldBe TestAssetDecimals + static.nft shouldBe false + static.issuerPublicKey.toPublicKey shouldBe invoke.sender } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/package.scala b/node/src/test/scala/com/wavesplatform/state/diffs/package.scala index 2b4c14025d4..cbb712e2a95 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/package.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/package.scala @@ -3,5 +3,5 @@ package com.wavesplatform.state package object diffs { val ENOUGH_AMT: Long = Long.MaxValue / 3 - def produceRejectOrFailedDiff(errorMessage: String, requireFailed: Boolean = false): DiffProduceError = new DiffProduceError(errorMessage, requireFailed) + def produceRejectOrFailedDiff(errorMessage: String, requireFailed: Boolean = false): SnapshotProduceError = new SnapshotProduceError(errorMessage, requireFailed) } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/DiffComplexityCountTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/DiffComplexityCountTest.scala index ef7d4936d51..e37b5749635 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/DiffComplexityCountTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/DiffComplexityCountTest.scala @@ -21,7 +21,8 @@ class DiffComplexityCountTest extends PropSpec with Inside with WithState with D private val activationHeight = 4 - private val fsWithV5 = TestFunctionalitySettings.Enabled.copy(preActivatedFeatures = Map( + private val fsWithV5 = TestFunctionalitySettings.Enabled.copy( + preActivatedFeatures = Map( BlockchainFeatures.SmartAccounts.id -> 0, BlockchainFeatures.SmartAssets.id -> 0, BlockchainFeatures.Ride4DApps.id -> 0, @@ -30,7 +31,9 @@ class DiffComplexityCountTest extends PropSpec with Inside with WithState with D BlockchainFeatures.BlockReward.id -> 0, BlockchainFeatures.BlockV5.id -> 0, BlockchainFeatures.SynchronousCalls.id -> activationHeight - ), estimatorPreCheckHeight = Int.MaxValue) + ), + estimatorPreCheckHeight = Int.MaxValue + ) // ~1900 complexity val groth: String = @@ -57,23 +60,23 @@ class DiffComplexityCountTest extends PropSpec with Inside with WithState with D private def dApp(asset: IssuedAsset): Script = TestCompiler(V4).compileContract( s""" - | {-# STDLIB_VERSION 4 #-} - | {-# CONTENT_TYPE DAPP #-} - | {-# SCRIPT_TYPE ACCOUNT #-} - | - | @Callable(i) - | func default() = { - | strict cond = - | if (true) - | then true - | else ($groth) - | - | [ - | ScriptTransfer(i.caller, 1, base58'$asset'), - | Burn(base58'$asset', 1), - | Reissue(base58'$asset', 1, true) - | ] - | } + | {-# STDLIB_VERSION 4 #-} + | {-# CONTENT_TYPE DAPP #-} + | {-# SCRIPT_TYPE ACCOUNT #-} + | + | @Callable(i) + | func default() = { + | strict cond = + | if (true) + | then true + | else ($groth) + | + | [ + | ScriptTransfer(i.caller, 1, base58'$asset'), + | Burn(base58'$asset', 1), + | Reissue(base58'$asset', 1, true) + | ] + | } """.stripMargin ) @@ -95,15 +98,15 @@ class DiffComplexityCountTest extends PropSpec with Inside with WithState with D (balances, Seq(issue, transfer1, setVerifier, setDApp), invokeFromScripted) } - property(s"evaluated complexity is used for diff instead of estimated one after activation ${BlockchainFeatures.SynchronousCalls}") { + property(s"evaluated complexity is used instead of estimated one after activation ${BlockchainFeatures.SynchronousCalls}") { val (balances, preparingTxs, invoke) = paymentPreconditions withDomain(domainSettingsWithFS(fsWithV5), balances) { d => d.appendBlock(preparingTxs*) val invoke1 = invoke() d.appendBlock(invoke1) - d.liquidDiff.errorMessage(invoke1.id()) shouldBe empty - d.liquidDiff.scriptsComplexity shouldBe 11459 // 3 actions + 2 payments + verifier = 6 * 1900 = 11400 + d.liquidSnapshot.errorMessage(invoke1.id()) shouldBe empty + d.liquidSnapshot.scriptsComplexity shouldBe 11459 // 3 actions + 2 payments + verifier = 6 * 1900 = 11400 // for dApp evaluated complexity is always used after implementation of the snapshots d.appendBlock() @@ -111,8 +114,8 @@ class DiffComplexityCountTest extends PropSpec with Inside with WithState with D val invoke2 = invoke() d.appendBlock(invoke2) - d.liquidDiff.errorMessage(invoke2.id()) shouldBe empty - d.liquidDiff.scriptsComplexity shouldBe 17 + d.liquidSnapshot.errorMessage(invoke2.id()) shouldBe empty + d.liquidSnapshot.scriptsComplexity shouldBe 17 } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/EstimationSwitchTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/EstimationSwitchTest.scala index ed6e94e50cb..3b2ee6609cd 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/EstimationSwitchTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/EstimationSwitchTest.scala @@ -45,13 +45,13 @@ class EstimationSwitchTest extends PropSpec with WithDomain with TransactionGenB d.appendBlock(genesis1, genesis2) d.appendBlock(setScript(), invoke()) - d.liquidDiff.scripts.head._2.get.complexitiesByEstimator(3)("default") shouldBe 5 - d.liquidDiff.scriptsComplexity shouldBe 7 + d.liquidSnapshot.accountScripts.head._2.get.complexitiesByEstimator(3)("default") shouldBe 5 + d.liquidSnapshot.scriptsComplexity shouldBe 7 // bigger than estimator because of ignoring predefined user function complexities d.appendBlock(setScript(), invoke()) - d.liquidDiff.scripts.head._2.get.complexitiesByEstimator(3)("default") shouldBe 1 - d.liquidDiff.scriptsComplexity shouldBe 1 + d.liquidSnapshot.accountScripts.head._2.get.complexitiesByEstimator(3)("default") shouldBe 1 + d.liquidSnapshot.scriptsComplexity shouldBe 1 // condition decreased by 1, // accessing to ref ([] = nil) decreased by 1, // != decreased by 4 (because of using predefined user function complexities) diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/MaxCallableComplexityTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/MaxCallableComplexityTest.scala index 4af4a6af511..025bcd8807e 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/MaxCallableComplexityTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/MaxCallableComplexityTest.scala @@ -41,8 +41,8 @@ class MaxCallableComplexityTest extends PropSpec with WithDomain with Transactio val setLargeScript = SetScriptTransaction.selfSigned(TxVersion.V2, dApp, Some(largeScript(V6, 300)), 0.022.waves, ts).explicitGet() d.appendBlock(genDApp, genInvoker, setScript) - val invokeDiff = d.transactionDiffer(invokeScript(invoker, dApp.toAddress, "test")).resultE.explicitGet() - invokeDiff.scriptsComplexity shouldBe 51585 + val invokeSnapshot = d.transactionDiffer(invokeScript(invoker, dApp.toAddress, "test")).resultE.explicitGet() + invokeSnapshot.scriptsComplexity shouldBe 51585 d.appendAndCatchError(setLargeScript).toString should include("Contract function (test) is too complex: 54301 > 52000") } } @@ -61,8 +61,8 @@ class MaxCallableComplexityTest extends PropSpec with WithDomain with Transactio val setInvokeScript = SetScriptTransaction.selfSigned(TxVersion.V2, invokeDApp, Some(invokeScript(V5, largeDApp.toAddress)), 0.01.waves, ts).explicitGet() d.appendBlock(genInvoker, genLargeDApp, genInvokeDApp, setLargeScript, setInvokeScript) - val invokeDiff = d.transactionDiffer(invokeScript(invoker, invokeDApp.toAddress, "invokeTest")).resultE.explicitGet() - invokeDiff.scriptsComplexity shouldBe 18177 + val invokeSnapshot = d.transactionDiffer(invokeScript(invoker, invokeDApp.toAddress, "invokeTest")).resultE.explicitGet() + invokeSnapshot.scriptsComplexity shouldBe 18177 } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/SmartAccountFeeTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/SmartAccountFeeTest.scala index df1a4d5b85f..6aeebc0de3f 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/SmartAccountFeeTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/SmartAccountFeeTest.scala @@ -136,8 +136,8 @@ class SmartAccountFeeTest extends PropSpec with WithDomain { notEnoughPaidVerifierTxs.foreach(tx => appendAndAssertNotEnoughFee(tx(), d)) d.appendAndAssertSucceed(freeVerifierTxs.map(_())*) - d.liquidDiff.scriptsComplexity should be > 0L - d.liquidDiff.scriptResults.size shouldBe 2 + d.liquidSnapshot.scriptsComplexity should be > 0L + d.liquidSnapshot.scriptResults.size shouldBe 2 } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/eth/EthereumInvokeTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/eth/EthereumInvokeTest.scala index 482414a7f50..ca0ce7c2cb7 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/eth/EthereumInvokeTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/eth/EthereumInvokeTest.scala @@ -13,7 +13,6 @@ import com.wavesplatform.lang.script.v1.ExprScript import com.wavesplatform.lang.v1.compiler.{Terms, TestCompiler} import com.wavesplatform.lang.v1.evaluator.ctx.impl.GlobalValNames import com.wavesplatform.lang.v1.traits.domain.AttachedPayments.* -import com.wavesplatform.state.Portfolio import com.wavesplatform.state.diffs.ENOUGH_AMT import com.wavesplatform.state.diffs.ci.ciFee import com.wavesplatform.state.diffs.smart.predef.{assertProvenPart, provenPart} @@ -150,14 +149,19 @@ class EthereumInvokeTest extends PropSpec with WithDomain with EthHelpers with I d.appendBlock(preparingTxs*) d.appendBlock(ethInvoke) - d.liquidDiff.errorMessage(ethInvoke.id()) shouldBe None - d.liquidDiff.accountData(dApp)("check").value shouldBe true - if (syncCall) d.liquidDiff.accountData(dApp2)("check").value shouldBe true + d.liquidSnapshot.errorMessage(ethInvoke.id()) shouldBe None + d.liquidSnapshot.accountData(dApp)("check").value shouldBe true + if (syncCall) d.liquidSnapshot.accountData(dApp2)("check").value shouldBe true - val assetsPortfolio = assets.map(Portfolio.build(_, paymentAmount)).fold(Portfolio())((p1, p2) => p1.combine(p2).explicitGet()) - d.liquidDiff.portfolios.getOrElse(dApp, Portfolio()) shouldBe assetsPortfolio - d.liquidDiff.portfolios(ethInvoke.senderAddress()) shouldBe Portfolio(-ethInvoke.underlying.getGasPrice.longValue()).minus(assetsPortfolio) - inside(d.liquidDiff.scriptResults.toSeq) { case Seq((_, call1)) => + val ethSender = ethInvoke.senderAddress() + assets.foreach { asset => + d.liquidSnapshot.balances((dApp, asset)) shouldBe d.rocksDBWriter.balance(dApp, asset) + paymentAmount + d.liquidSnapshot.balances((ethSender, asset)) shouldBe d.rocksDBWriter.balance(ethSender, asset) - paymentAmount + } + d.liquidSnapshot.balances.get((dApp, Waves)) shouldBe None + d.liquidSnapshot.balances((ethSender, Waves)) shouldBe d.rocksDBWriter.balance(ethSender) - ethInvoke.underlying.getGasPrice.longValue() + + inside(d.liquidSnapshot.scriptResults.toSeq) { case Seq((_, call1)) => if (syncCall) inside(call1.invokes) { case Seq(call2) => call2.stateChanges.error shouldBe empty diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/eth/EthereumTransferSmartTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/eth/EthereumTransferSmartTest.scala index 42e07a22471..1964204c44f 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/eth/EthereumTransferSmartTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/eth/EthereumTransferSmartTest.scala @@ -10,7 +10,6 @@ import com.wavesplatform.lang.directives.DirectiveDictionary import com.wavesplatform.lang.directives.values.{StdLibVersion, V3, V6} import com.wavesplatform.lang.v1.compiler.TestCompiler import com.wavesplatform.lang.v1.evaluator.ctx.impl.GlobalValNames -import com.wavesplatform.state.Portfolio import com.wavesplatform.state.diffs.ENOUGH_AMT import com.wavesplatform.state.diffs.smart.predef.{assertProvenPart, provenPart} import com.wavesplatform.test.* @@ -21,7 +20,6 @@ import com.wavesplatform.transaction.transfer.TransferTransaction import com.wavesplatform.transaction.{Asset, ERC20Address, EthTxGenerator, EthereumTransaction, TxHelpers} import com.wavesplatform.utils.EthHelpers -import scala.collection.immutable.VectorMap import scala.math.Ordering.Implicits.infixOrderingOps class EthereumTransferSmartTest extends PropSpec with WithDomain with EthHelpers { @@ -95,15 +93,21 @@ class EthereumTransferSmartTest extends PropSpec with WithDomain with EthHelpers d.appendBlock(setVerifier()) d.appendBlock(ProtoBlockVersion, ethTransfer) - val transferPortfolio = Portfolio.build(asset, transferAmount) - d.liquidDiff.portfolios(recipient.toAddress) shouldBe transferPortfolio - d.liquidDiff.portfolios(ethSender) shouldBe Portfolio.waves(-ethTransfer.underlying.getGasLimit.longValue()).minus(transferPortfolio) + d.liquidSnapshot.balances((recipient.toAddress, asset)) shouldBe d.rocksDBWriter.balance(recipient.toAddress, asset) + transferAmount + if (asset == Waves) + d.liquidSnapshot.balances((ethSender, Waves)) shouldBe + d.rocksDBWriter.balance(ethSender, Waves) - ethTransfer.underlying.getGasLimit.longValue() - transferAmount + else { + d.liquidSnapshot.balances((ethSender, Waves)) shouldBe + d.rocksDBWriter.balance(ethSender, Waves) - ethTransfer.underlying.getGasLimit.longValue() + d.liquidSnapshot.balances((ethSender, asset)) shouldBe d.rocksDBWriter.balance(ethSender, asset) - transferAmount + } d.appendBlock() if (version >= V6) { d.appendBlock(setVerifier()) // just for account script execution - d.liquidDiff.scriptsComplexity should be > 0L + d.liquidSnapshot.scriptsComplexity should be > 0L } else if (version >= V3) { (the[Exception] thrownBy d.appendBlock(setVerifier())).getMessage should include( "value() called on unit value on function 'transferTransactionById' call" @@ -137,14 +141,14 @@ class EthereumTransferSmartTest extends PropSpec with WithDomain with EthHelpers d.appendBlock(issue, preTransfer) d.appendBlock(ProtoBlockVersion, ethTransfer) - d.liquidDiff.errorMessage(ethTransfer.id()) shouldBe None - d.liquidDiff.portfolios(recipient.toAddress) shouldBe Portfolio.build(asset, transferAmount) - d.liquidDiff.portfolios(ethTransfer.senderAddress()) shouldBe Portfolio( - -ethTransfer.underlying.getGasPrice.longValue(), - assets = VectorMap(asset -> -transferAmount) - ) + d.liquidSnapshot.errorMessage(ethTransfer.id()) shouldBe None + d.liquidSnapshot.scriptsComplexity should be > 0L - d.liquidDiff.scriptsComplexity should be > 0L + d.liquidSnapshot.balances((recipient.toAddress, asset)) shouldBe transferAmount + d.liquidSnapshot.balances((ethTransfer.senderAddress(), Waves)) shouldBe + d.rocksDBWriter.balance(ethTransfer.senderAddress(), Waves) - ethTransfer.underlying.getGasPrice.longValue() + d.liquidSnapshot.balances((ethTransfer.senderAddress(), asset)) shouldBe + d.rocksDBWriter.balance(ethTransfer.senderAddress(), asset) - transferAmount } } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala index c9df847c920..af47ac69af1 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/CalculateDelayTest.scala @@ -50,7 +50,7 @@ class CalculateDelayTest extends PropSpec with WithDomain { val minDelays = (1 to 200).map { _ => d.appendBlock(invoke()) - d.liquidDiff.accountData(secondAddress).values.minBy(_.value.asInstanceOf[Long]).key + d.liquidSnapshot.accountData(secondAddress).values.minBy(_.value.asInstanceOf[Long]).key } val lowestIsMiner = minDelays.count(_ == "lowest") val mediumIsMiner = minDelays.count(_ == "medium") diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/RideCreateMerkleRootTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/RideCreateMerkleRootTest.scala index 98b1f992c85..1288d0837a0 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/RideCreateMerkleRootTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/RideCreateMerkleRootTest.scala @@ -42,7 +42,7 @@ class RideCreateMerkleRootTest extends PropSpec with WithDomain { val invokeTx = invoke(func = Some("merkle"), args = Seq(digests, id, index)) d.appendBlock(d.createBlock(blockVersion, Seq(invokeTx))) - d.liquidDiff.scriptResults.head._2.error shouldBe None + d.liquidSnapshot.scriptResults.head._2.error shouldBe None d.blockchain.accountData(secondAddress, "root").get.value shouldBe root } } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/BalancesV4Test.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/BalancesV4Test.scala index ed46169e843..87ea7cef5c4 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/BalancesV4Test.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/BalancesV4Test.scala @@ -1,11 +1,11 @@ package com.wavesplatform.state.diffs.smart.scenarios import cats.syntax.semigroup.* +import com.wavesplatform.api.common.CommonAccountsApi import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.db.WithState import com.wavesplatform.features.BlockchainFeatures -import com.wavesplatform.history.SnapshotOps import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.lang.Global import com.wavesplatform.lang.directives.DirectiveSet @@ -95,13 +95,12 @@ class BalancesV4Test extends PropSpec with WithState { Seq(TestBlock.create(b)), TestBlock.create(Seq(ci)), rideV4Activated - ) { case (d, s) => + ) { case (snapshot, blockchain) => val apiBalance = - com.wavesplatform.api.common - .CommonAccountsApi(() => SnapshotBlockchain(s, SnapshotOps.fromDiff(d, s).explicitGet()), rdb, s) + CommonAccountsApi(() => SnapshotBlockchain(blockchain, snapshot), rdb, blockchain) .balanceDetails(acc1.toAddress) .explicitGet() - val data = d.accountData(dapp.toAddress) + val data = snapshot.accountData(dapp.toAddress) data("available") shouldBe IntegerDataEntry("available", apiBalance.available) apiBalance.available shouldBe 16 * Constants.UnitsInWave data("regular") shouldBe IntegerDataEntry("regular", apiBalance.regular) diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/OneProofForNonScriptedAccountTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/OneProofForNonScriptedAccountTest.scala index e917798d072..921b02d846f 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/OneProofForNonScriptedAccountTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/OneProofForNonScriptedAccountTest.scala @@ -27,7 +27,7 @@ class OneProofForNonScriptedAccountTest extends PropSpec with WithState { val (genesis, _, transfer) = s val transferWithExtraProof = transfer.copy(proofs = Proofs(Seq(ByteStr.empty, ByteStr(Array(1: Byte))))) assertDiffEi(Seq(TestBlock.create(Seq(genesis))), TestBlock.create(Seq(transferWithExtraProof)), smartEnabledFS)( - totalDiffEi => totalDiffEi should produce("must have exactly 1 proof") + snapshotEi => snapshotEi should produce("must have exactly 1 proof") ) } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/OnlyTransferIsAllowedTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/OnlyTransferIsAllowedTest.scala index 6959cea1241..d2dbe0db4c3 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/OnlyTransferIsAllowedTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/OnlyTransferIsAllowedTest.scala @@ -37,7 +37,7 @@ class OnlyTransferIsAllowedTest extends PropSpec with WithState { val (genesis, script, lease, transfer) = preconditions(transferAllowed) assertDiffAndState(Seq(TestBlock.create(Seq(genesis, script))), TestBlock.create(Seq(transfer)), smartEnabledFS) { case _ => () } assertDiffEi(Seq(TestBlock.create(Seq(genesis, script))), TestBlock.create(Seq(lease)), smartEnabledFS)( - totalDiffEi => totalDiffEi should produce("TransactionNotAllowedByScript") + snapshotEi => snapshotEi should produce("TransactionNotAllowedByScript") ) } diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/TransactionFieldAccessTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/TransactionFieldAccessTest.scala index fa52ffda1e8..8b391e58313 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/TransactionFieldAccessTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/scenarios/TransactionFieldAccessTest.scala @@ -47,7 +47,7 @@ class TransactionFieldAccessTest extends PropSpec with WithState { val (genesis, setScript, lease, transfer) = preconditionsTransferAndLease(script) assertDiffAndState(Seq(TestBlock.create(Seq(genesis, setScript))), TestBlock.create(Seq(transfer)), smartEnabledFS) { case _ => () } assertDiffEi(Seq(TestBlock.create(Seq(genesis, setScript))), TestBlock.create(Seq(lease)), smartEnabledFS)( - totalDiffEi => totalDiffEi should produce("TransactionNotAllowedByScript") + snapshotEi => snapshotEi should produce("TransactionNotAllowedByScript") ) } } diff --git a/node/src/test/scala/com/wavesplatform/state/snapshot/TxStateSnapshotHashSpec.scala b/node/src/test/scala/com/wavesplatform/state/snapshot/TxStateSnapshotHashSpec.scala index 9ed626dccda..eb25b4b1ebc 100644 --- a/node/src/test/scala/com/wavesplatform/state/snapshot/TxStateSnapshotHashSpec.scala +++ b/node/src/test/scala/com/wavesplatform/state/snapshot/TxStateSnapshotHashSpec.scala @@ -1,6 +1,5 @@ package com.wavesplatform.state.snapshot -import cats.data.Ior import com.google.common.primitives.{Ints, Longs, UnsignedBytes} import com.wavesplatform.account.{AddressScheme, Alias} import com.wavesplatform.common.state.ByteStr @@ -8,14 +7,13 @@ import com.wavesplatform.common.utils.* import com.wavesplatform.crypto.DigestLength import com.wavesplatform.db.WithDomain import com.wavesplatform.db.WithState.AddrWithBalance -import com.wavesplatform.history.SnapshotOps import com.wavesplatform.lang.v1.estimator.ScriptEstimatorV1 import com.wavesplatform.state.* import com.wavesplatform.state.TxMeta.Status.* import com.wavesplatform.state.TxStateSnapshotHashBuilder.{KeyType, TxStatusInfo} import com.wavesplatform.state.reader.LeaseDetails import com.wavesplatform.test.* -import com.wavesplatform.transaction.Asset.IssuedAsset +import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.transaction.TxHelpers.invoke import com.wavesplatform.transaction.smart.script.ScriptCompiler import com.wavesplatform.transaction.{AssetIdLength, TxHelpers} @@ -37,8 +35,8 @@ class TxStateSnapshotHashSpec extends PropSpec with WithDomain { private val leaseId1 = ByteStr.fill(DigestLength)(6) private val leaseId2 = ByteStr.fill(DigestLength)(7) - private val leaseDetails1 = LeaseDetails(TxHelpers.signer(1).publicKey, address2, 1.waves, LeaseDetails.Status.Active, leaseId1, 2) - private val leaseDetails2 = LeaseDetails(TxHelpers.signer(1).publicKey, address2, 1.waves, LeaseDetails.Status.Cancelled(1, None), leaseId2, 2) + private val leaseDetails1 = LeaseSnapshot(TxHelpers.signer(1).publicKey, address2, 1.waves, LeaseDetails.Status.Active) + private val leaseDetails2 = LeaseSnapshot(TxHelpers.signer(1).publicKey, address2, 1.waves, LeaseDetails.Status.Cancelled(1, None)) private val addr1Balance = 10.waves private val addr2Balance = 20.waves @@ -92,29 +90,46 @@ class TxStateSnapshotHashSpec extends PropSpec with WithDomain { private val dataEntry = StringDataEntry("key", "value") - private val diff = Diff( - portfolios = Map(address1 -> addr1PortfolioDiff, address2 -> addr2PortfolioDiff), - issuedAssets = VectorMap(assetId1 -> assetInfo1, assetId2 -> assetInfo2, assetId3 -> assetInfo3, assetId4 -> assetInfo4), - updatedAssets = Map( - assetId1 -> Ior.Both(updatedAssetInfo1, updatedAssetVolumeInfo1), - assetId2 -> Ior.Left(updatedAssetInfo2), - assetId3 -> Ior.Right(updatedAssetVolumeInfo3) + private val snapshot = StateSnapshot( + balances = VectorMap( + (address1, Waves) -> (addr1PortfolioDiff.balance + addr1Balance), + (address2, assetId1) -> addr2PortfolioDiff.assets.head._2 + ), + leaseBalances = Map(address1 -> addr1PortfolioDiff.lease), + assetStatics = StateSnapshot.assetStatics( + VectorMap( + assetId1 -> assetInfo1, + assetId2 -> assetInfo2, + assetId3 -> assetInfo3, + assetId4 -> assetInfo4 + ) + ), + assetVolumes = VectorMap( + assetId1 -> updatedAssetVolumeInfo1, + assetId2 -> assetInfo2.volume, + assetId3 -> updatedAssetVolumeInfo3, + assetId4 -> assetInfo4.volume + ), + assetNamesAndDescriptions = VectorMap( + assetId1 -> updatedAssetInfo1, + assetId2 -> updatedAssetInfo2, + assetId3 -> assetInfo3.dynamic, + assetId4 -> assetInfo4.dynamic ), aliases = Map(addr1Alias1 -> address1, addr2Alias -> address2, addr1Alias2 -> address1), orderFills = Map(orderId -> volumeAndFee), - leaseState = Map(leaseId1 -> leaseDetails1, leaseId2 -> leaseDetails2), - scripts = Map(TxHelpers.signer(2).publicKey -> Some(accountScriptInfo)), - assetScripts = Map(assetId1 -> Some(assetScriptInfo)), + leaseStates = Map(leaseId1 -> leaseDetails1, leaseId2 -> leaseDetails2), + accountScripts = Map(TxHelpers.signer(2).publicKey -> Some(accountScriptInfo)), + assetScripts = Map(assetId1 -> assetScriptInfo), accountData = Map(address1 -> Map(dataEntry.key -> dataEntry)), - sponsorship = Map(assetId1 -> sponsorship) + sponsorships = Map(assetId1 -> sponsorship) ) def hash(bs: Seq[Array[Byte]]): ByteStr = ByteStr(com.wavesplatform.crypto.fastHash(bs.reduce(_ ++ _))) property("correctly create transaction state snapshot hash from snapshot") { - withDomain(DomainPresets.RideV6, balances = Seq(AddrWithBalance(address1, addr1Balance), AddrWithBalance(address2, addr2Balance))) { d => - val snapshot = SnapshotOps.fromDiff(diff, d.blockchain).explicitGet() - val tx = invoke() + withDomain(DomainPresets.RideV6, balances = Seq(AddrWithBalance(address1, addr1Balance), AddrWithBalance(address2, addr2Balance))) { _ => + val tx = invoke() testHash(snapshot, Some(TxStatusInfo(tx.id(), Succeeded)), Array()) testHash(snapshot, Some(TxStatusInfo(tx.id(), Failed)), tx.id().arr :+ 1) testHash(snapshot, Some(TxStatusInfo(tx.id(), Elided)), tx.id().arr :+ 2) diff --git a/node/src/test/scala/com/wavesplatform/state/utils/package.scala b/node/src/test/scala/com/wavesplatform/state/utils/package.scala index 12cecbbd777..dcb7a10e423 100644 --- a/node/src/test/scala/com/wavesplatform/state/utils/package.scala +++ b/node/src/test/scala/com/wavesplatform/state/utils/package.scala @@ -15,13 +15,13 @@ package object utils { def addressTransactions( rdb: RDB, - diff: => Option[(Height, StateSnapshot)], + snapshot: => Option[(Height, StateSnapshot)], address: Address, types: Set[Transaction.Type], fromId: Option[ByteStr] )(implicit s: Scheduler): Seq[(Height, Transaction)] = AddressTransactions - .allAddressTransactions(rdb, diff, address, None, types, fromId) + .allAddressTransactions(rdb, snapshot, address, None, types, fromId) .map { case (tm, tx, _) => tm.height -> tx } .toListL .runSyncUnsafe() diff --git a/node/src/test/scala/com/wavesplatform/transaction/TxHelpers.scala b/node/src/test/scala/com/wavesplatform/transaction/TxHelpers.scala index e1aebcc9597..2c91c553678 100644 --- a/node/src/test/scala/com/wavesplatform/transaction/TxHelpers.scala +++ b/node/src/test/scala/com/wavesplatform/transaction/TxHelpers.scala @@ -36,12 +36,12 @@ object TxHelpers { def signer(i: Int): SeedKeyPair = KeyPair(Ints.toByteArray(i)) def address(i: Int): Address = signer(i).toAddress - def defaultSigner: SeedKeyPair = signer(0) - def defaultAddress: Address = defaultSigner.toAddress - def secondSigner: SeedKeyPair = signer(1) - def secondAddress: Address = secondSigner.toAddress + val defaultSigner: SeedKeyPair = signer(0) + val defaultAddress: Address = defaultSigner.toAddress + val secondSigner: SeedKeyPair = signer(1) + val secondAddress: Address = secondSigner.toAddress - def defaultEthSigner: ECKeyPair = defaultSigner.toEthKeyPair + val defaultEthSigner: ECKeyPair = defaultSigner.toEthKeyPair def accountSeqGenerator(numberAccounts: Int, amount: Long): Seq[ParsedTransfer] = { val firstAccountNum = 100 diff --git a/node/src/test/scala/com/wavesplatform/transaction/assets/exchange/EthOrderSpec.scala b/node/src/test/scala/com/wavesplatform/transaction/assets/exchange/EthOrderSpec.scala index 16080b9d343..d5884cfe62a 100644 --- a/node/src/test/scala/com/wavesplatform/transaction/assets/exchange/EthOrderSpec.scala +++ b/node/src/test/scala/com/wavesplatform/transaction/assets/exchange/EthOrderSpec.scala @@ -6,7 +6,6 @@ import com.wavesplatform.test.{FlatSpec, TestTime} import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} import com.wavesplatform.BlockchainStubHelpers import com.wavesplatform.common.utils.* -import com.wavesplatform.history.SnapshotOps.TransactionStateSnapshotExt import com.wavesplatform.state.diffs.TransactionDiffer import com.wavesplatform.transaction.{TxExchangeAmount, TxHelpers, TxMatcherFee, TxOrderPrice, TxVersion} import com.wavesplatform.utils.{DiffMatchers, EthEncoding, EthHelpers, JsonMatchers} @@ -142,8 +141,8 @@ class EthOrderSpec val differ = blockchain.stub.transactionDiffer(TestTime(100)) _ val transaction = TxHelpers.exchange(ethBuyOrder, ethSellOrder, price = 100, version = TxVersion.V3, timestamp = 100) - val diff = differ(transaction).resultE.explicitGet() - diff should containAppliedTx(transaction.id()) + val snapshot = differ(transaction).resultE.explicitGet() + snapshot should containAppliedTx(transaction.id()) } it should "work in exchange transaction with an old order" in { @@ -175,8 +174,8 @@ class EthOrderSpec val differ = TransactionDiffer(Some(1L), 100L)(blockchain, _) val transaction = TxHelpers.exchange(buyOrder, ethSellOrder, price = 100, version = TxVersion.V3, timestamp = 100) - val diff = differ(transaction).resultE.explicitGet().toDiff(blockchain) - diff should containAppliedTx(transaction.id()) + val snapshot = differ(transaction).resultE.explicitGet() + snapshot should containAppliedTx(transaction.id()) } it should "recover valid ids of exchange tx" in { @@ -354,8 +353,8 @@ class EthOrderSpec val differ = TransactionDiffer(Some(1L), 100L)(blockchain, _) val transaction = TxHelpers.exchange(buyOrder, ethSellOrder, price = 100, version = TxVersion.V3, timestamp = 100) - val diff = differ(transaction).resultE.explicitGet().toDiff(blockchain) - diff should containAppliedTx(transaction.id()) + val snapshot = differ(transaction).resultE.explicitGet() + snapshot should containAppliedTx(transaction.id()) } it should "work in exchange transaction with matcher script" in { @@ -393,8 +392,8 @@ class EthOrderSpec val differ = blockchain.stub.transactionDiffer(TestTime(100)) _ val transaction = TxHelpers.exchange(ethBuyOrder, ethSellOrder, price = 100, version = TxVersion.V3, timestamp = 100) - val diff = differ(transaction).resultE.explicitGet() - diff should containAppliedTx(transaction.id()) + val snapshot = differ(transaction).resultE.explicitGet() + snapshot should containAppliedTx(transaction.id()) } it should "be serialized correctly to EIP-712 json with and without attachment (NODE-996)" in { diff --git a/node/src/test/scala/com/wavesplatform/transaction/smart/EthereumTransactionSpec.scala b/node/src/test/scala/com/wavesplatform/transaction/smart/EthereumTransactionSpec.scala index 339036b83a2..c3d1e65655e 100644 --- a/node/src/test/scala/com/wavesplatform/transaction/smart/EthereumTransactionSpec.scala +++ b/node/src/test/scala/com/wavesplatform/transaction/smart/EthereumTransactionSpec.scala @@ -4,7 +4,6 @@ import com.wavesplatform.account.AddressScheme import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.* import com.wavesplatform.features.BlockchainFeatures -import com.wavesplatform.state.Portfolio import com.wavesplatform.state.diffs.produceRejectOrFailedDiff import com.wavesplatform.test.{FlatSpec, TestTime, produce} import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} @@ -106,9 +105,14 @@ class EthereumTransactionSpec val transfer = EthTxGenerator.generateEthTransfer(senderAccount, recipientAddress, LongMaxMinusFee, Waves) val assetTransfer = EthTxGenerator.generateEthTransfer(senderAccount, recipientAddress, Long.MaxValue, TestAsset) - differ(transfer).combineF(differ(assetTransfer)).explicitGet().portfolios shouldBe Map( - senderAddress -> Portfolio.build(-Long.MaxValue, TestAsset, -Long.MaxValue), - recipientAddress -> Portfolio.build(LongMaxMinusFee, TestAsset, Long.MaxValue) + differ(assetTransfer).balances shouldBe Map( + (senderAddress, TestAsset) -> 0, + (senderAddress, Waves) -> (LongMaxMinusFee + transfer.fee.longValue()), + (recipientAddress, TestAsset) -> Long.MaxValue + ) + differ(transfer).balances shouldBe Map( + (senderAddress, Waves) -> transfer.fee.longValue(), + (recipientAddress, Waves) -> LongMaxMinusFee ) } @@ -236,23 +240,23 @@ class EthereumTransactionSpec ), Seq(Payment(321, IssuedAsset(ByteStr(EthStubBytes32)))) ) - val diff = differ(transaction).resultE.explicitGet() - diff should containAppliedTx(transaction.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson("""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | } ], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val snapshot = differ(transaction).resultE.explicitGet() + snapshot should containAppliedTx(transaction.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson("""{ + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | } ], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + |}""".stripMargin) } it should "not work with union type" in { @@ -291,8 +295,8 @@ class EthereumTransactionSpec Seq(Payment(321, IssuedAsset(ByteStr(EthStubBytes32)))) ) - val diff = differ(transaction).resultE - diff should produce("Function not defined: 1f9773e9") + val snapshot = differ(transaction).resultE + snapshot should produce("Function not defined: 1f9773e9") } it should "work with no arguments" in { @@ -332,23 +336,23 @@ class EthereumTransactionSpec Seq(), Seq(Payment(321, IssuedAsset(ByteStr(EthStubBytes32)))) ) - val diff = differ(transaction).resultE.explicitGet() - diff should containAppliedTx(transaction.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson("""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | } ], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val snapshot = differ(transaction).resultE.explicitGet() + snapshot should containAppliedTx(transaction.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson("""{ + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | } ], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + |}""".stripMargin) } it should "work with no payments" in { @@ -382,23 +386,23 @@ class EthereumTransactionSpec val differ = blockchain.stub.transactionDiffer(TestTime(System.currentTimeMillis())) val transaction = EthTxGenerator.generateEthInvoke(invokerAccount, dAppAccount.toAddress, "deposit", Seq(), Seq()) - val diff = differ(transaction).resultE.explicitGet() - diff should containAppliedTx(transaction.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson("""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | } ], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val snapshot = differ(transaction).resultE.explicitGet() + snapshot should containAppliedTx(transaction.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson("""{ + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | } ], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + |}""".stripMargin) } it should "fail with max+1 payments" in { @@ -478,23 +482,23 @@ class EthereumTransactionSpec Seq(), Seq(Payment(321, IssuedAsset(ByteStr(EthStubBytes32)))) ) - val diff = differ(transaction).resultE.explicitGet() - diff should containAppliedTx(transaction.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson("""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | } ], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val snapshot = differ(transaction).resultE.explicitGet() + snapshot should containAppliedTx(transaction.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson("""{ + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | } ], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + |}""".stripMargin) } it should "return money in transfers asset+waves" in { @@ -535,28 +539,28 @@ class EthereumTransactionSpec Seq(), Nil ) - val diff = differ(transaction).resultE.explicitGet() - diff should containAppliedTx(transaction.id()) - Json.toJson(diff.scriptResults.values.head) should matchJson(s"""{ - | "data" : [ ], - | "transfers" : [ { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : null, - | "amount" : 123 - | }, - | { - | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", - | "asset" : "$TestAsset", - | "amount" : 123 - | }], - | "issues" : [ ], - | "reissues" : [ ], - | "burns" : [ ], - | "sponsorFees" : [ ], - | "leases" : [ ], - | "leaseCancels" : [ ], - | "invokes" : [ ] - |}""".stripMargin) + val snapshot = differ(transaction).resultE.explicitGet() + snapshot should containAppliedTx(transaction.id()) + Json.toJson(snapshot.scriptResults.values.head) should matchJson(s"""{ + | "data" : [ ], + | "transfers" : [ { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : null, + | "amount" : 123 + | }, + | { + | "address" : "3NByUD1YE9SQPzmf2KqVqrjGMutNSfc4oBC", + | "asset" : "$TestAsset", + | "amount" : 123 + | }], + | "issues" : [ ], + | "reissues" : [ ], + | "burns" : [ ], + | "sponsorFees" : [ ], + | "leases" : [ ], + | "leaseCancels" : [ ], + | "invokes" : [ ] + |}""".stripMargin) } it should "test minimum fee" in { diff --git a/node/src/test/scala/com/wavesplatform/utils/DiffMatchers.scala b/node/src/test/scala/com/wavesplatform/utils/DiffMatchers.scala index 45b07ec9eba..27eded1744f 100644 --- a/node/src/test/scala/com/wavesplatform/utils/DiffMatchers.scala +++ b/node/src/test/scala/com/wavesplatform/utils/DiffMatchers.scala @@ -1,25 +1,24 @@ package com.wavesplatform.utils import com.wavesplatform.common.state.ByteStr -import com.wavesplatform.state.Diff -import com.wavesplatform.state.TxMeta.Status +import com.wavesplatform.state.StateSnapshot +import com.wavesplatform.state.TxMeta.Status.Succeeded import org.scalatest.matchers.{MatchResult, Matcher} trait DiffMatchers { def containAppliedTx(transactionId: ByteStr) = new DiffAppliedTxMatcher(transactionId, true) def containFailedTx(transactionId: ByteStr) = new DiffAppliedTxMatcher(transactionId, false) - class DiffAppliedTxMatcher(transactionId: ByteStr, shouldBeApplied: Boolean) extends Matcher[Diff] { - override def apply(diff: Diff): MatchResult = { - val isApplied = diff.transaction(transactionId) match { - case Some(nt) if nt.status == Status.Succeeded => true - case _ => false + class DiffAppliedTxMatcher(transactionId: ByteStr, shouldBeApplied: Boolean) extends Matcher[StateSnapshot] { + override def apply(snapshot: StateSnapshot): MatchResult = { + val isApplied = snapshot.transactions.get(transactionId) match { + case Some(nt) if nt.status == Succeeded => true + case _ => false } - MatchResult( shouldBeApplied == isApplied, - s"$transactionId was not ${if (shouldBeApplied) "applied" else "failed"}: $diff", - s"$transactionId was ${if (shouldBeApplied) "applied" else "failed"}: $diff" + s"$transactionId was not ${if (shouldBeApplied) "applied" else "failed"}: $snapshot", + s"$transactionId was ${if (shouldBeApplied) "applied" else "failed"}: $snapshot" ) } } diff --git a/node/src/test/scala/com/wavesplatform/utx/UtxPoolSpecification.scala b/node/src/test/scala/com/wavesplatform/utx/UtxPoolSpecification.scala index 5c2668e3827..936cbb22f35 100644 --- a/node/src/test/scala/com/wavesplatform/utx/UtxPoolSpecification.scala +++ b/node/src/test/scala/com/wavesplatform/utx/UtxPoolSpecification.scala @@ -14,7 +14,7 @@ import com.wavesplatform.db.WithState.AddrWithBalance import com.wavesplatform.events.UtxEvent import com.wavesplatform.features.BlockchainFeatures import com.wavesplatform.history.Domain.BlockchainUpdaterExt -import com.wavesplatform.history.{DefaultWavesSettings, SnapshotOps, randomSig, settingsWithFeatures} +import com.wavesplatform.history.{DefaultWavesSettings, randomSig, settingsWithFeatures} import com.wavesplatform.lagonaki.mocks.TestBlock import com.wavesplatform.lang.directives.values.* import com.wavesplatform.lang.script.Script @@ -1011,7 +1011,7 @@ class UtxPoolSpecification extends FreeSpec with MockFactory with BlocksTransact } "cleanup" - { - "doesnt take the composite diff into account" in withDomain() { d => + "doesnt take the composite snapshot into account" in withDomain() { d => d.helpers.creditWavesToDefaultSigner(11.waves) val transfers = Seq.fill(10)(TxHelpers.transfer(amount = 10.waves)) transfers.foreach(tx => d.utxPool.addTransaction(tx, verify = false)) @@ -1024,7 +1024,7 @@ class UtxPoolSpecification extends FreeSpec with MockFactory with BlocksTransact val transfer1 = TxHelpers.transfer(amount = 10.waves) val transfer2 = TxHelpers.transfer(amount = 10.waves) // Double spend - d.utxPool.priorityPool.setPriorityDiffs(Seq(SnapshotOps.fromDiff(d.createDiff(transfer1), d.blockchain).explicitGet())) + d.utxPool.priorityPool.setPriorityDiffs(Seq(d.createDiff(transfer1))) d.utxPool.addTransaction(transfer2, verify = false) d.utxPool.cleanUnconfirmed() diff --git a/node/src/test/scala/com/wavesplatform/utx/UtxPriorityPoolSpecification.scala b/node/src/test/scala/com/wavesplatform/utx/UtxPriorityPoolSpecification.scala index 1d6970800ad..a4d174b353f 100644 --- a/node/src/test/scala/com/wavesplatform/utx/UtxPriorityPoolSpecification.scala +++ b/node/src/test/scala/com/wavesplatform/utx/UtxPriorityPoolSpecification.scala @@ -107,7 +107,7 @@ class UtxPriorityPoolSpecification extends FreeSpec with SharedDomain { domain.utxPool.priorityPool.priorityTransactions shouldBe empty } - "continues packing when priority diff contains no valid transactions" in { + "continues packing when priority snapshot contains no valid transactions" in { val bob = nextKeyPair domain.appendBlock( TxHelpers.transfer(alice, bob.toAddress, 10.02.waves, fee = 0.001.waves),