diff --git a/grpc-server/src/main/scala/com/wavesplatform/events/Repo.scala b/grpc-server/src/main/scala/com/wavesplatform/events/Repo.scala index c58817155e3..1ecfea396be 100644 --- a/grpc-server/src/main/scala/com/wavesplatform/events/Repo.scala +++ b/grpc-server/src/main/scala/com/wavesplatform/events/Repo.scala @@ -73,7 +73,7 @@ class Repo(db: DB, blocksApi: CommonBlocksApi)(implicit s: Scheduler) extends Bl db.put(keyForHeight(ls.keyBlock.height), ls.solidify().protobuf.update(_.append.block.optionalBlock := None).toByteArray) ) - val ba = BlockAppended.from(block, diff, blockchainBeforeWithMinerReward) + val ba = BlockAppended.from(block, diff, blockchainBeforeWithMinerReward, minerReward) liquidState = Some(LiquidState(ba, Seq.empty)) handlers.forEach(_.handleUpdate(ba)) } diff --git a/grpc-server/src/main/scala/com/wavesplatform/events/events.scala b/grpc-server/src/main/scala/com/wavesplatform/events/events.scala index 7439cd6fd48..52011f47c10 100644 --- a/grpc-server/src/main/scala/com/wavesplatform/events/events.scala +++ b/grpc-server/src/main/scala/com/wavesplatform/events/events.scala @@ -24,7 +24,7 @@ import com.wavesplatform.transaction.assets.exchange.ExchangeTransaction import com.wavesplatform.transaction.lease.LeaseTransaction import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.transfer.{MassTransferTransaction, TransferTransaction} -import com.wavesplatform.transaction.{Asset, Authorized, EthereumTransaction, GenesisTransaction} +import com.wavesplatform.transaction.{Asset, Authorized, EthereumTransaction} import scala.collection.mutable import scala.collection.mutable.ArrayBuffer @@ -557,21 +557,18 @@ final case class BlockAppended( } object BlockAppended { - def from(block: Block, diff: DetailedDiff, blockchainBeforeWithMinerReward: Blockchain): BlockAppended = { + def from(block: Block, diff: DetailedDiff, blockchainBeforeWithMinerReward: Blockchain, minerReward: Option[Long]): BlockAppended = { + val height = blockchainBeforeWithMinerReward.height val (blockStateUpdate, txsStateUpdates, txsMetadata, refAssets) = StateUpdate.container(blockchainBeforeWithMinerReward, diff, block.sender.toAddress) // updatedWavesAmount can change as a result of either genesis transactions or miner rewards - val updatedWavesAmount = blockchainBeforeWithMinerReward.height match { - // genesis case - case 0 => block.transactionData.collect { case GenesisTransaction(_, amount, _, _, _) => amount.value }.sum - // miner reward case - case height => blockchainBeforeWithMinerReward.wavesAmount(height).toLong - } + val wavesAmount = blockchainBeforeWithMinerReward.wavesAmount(height).toLong + val updatedWavesAmount = wavesAmount + minerReward.filter(_ => height > 0).getOrElse(0L) BlockAppended( block.id(), - blockchainBeforeWithMinerReward.height + 1, + height + 1, block, updatedWavesAmount, blockStateUpdate, diff --git a/grpc-server/src/test/scala/com/wavesplatform/events/BlockchainUpdatesSpec.scala b/grpc-server/src/test/scala/com/wavesplatform/events/BlockchainUpdatesSpec.scala index df1f428313c..7ef8910792f 100644 --- a/grpc-server/src/test/scala/com/wavesplatform/events/BlockchainUpdatesSpec.scala +++ b/grpc-server/src/test/scala/com/wavesplatform/events/BlockchainUpdatesSpec.scala @@ -14,6 +14,7 @@ import com.wavesplatform.events.protobuf.BlockchainUpdated.Rollback.RollbackType import com.wavesplatform.events.protobuf.BlockchainUpdated.Update import com.wavesplatform.events.protobuf.serde.* import com.wavesplatform.events.protobuf.{TransactionMetadata, BlockchainUpdated as PBBlockchainUpdated} +import com.wavesplatform.features.BlockchainFeatures.BlockReward import com.wavesplatform.history.Domain import com.wavesplatform.lang.directives.values.V5 import com.wavesplatform.lang.v1.FunctionHeader @@ -278,9 +279,74 @@ class BlockchainUpdatesSpec extends FreeSpec with WithBUDomain with ScalaFutures ) } - "should include correct waves amount" in withNEmptyBlocksSubscription(settings = currentSettings) { result => - val balances = result.collect { case b if b.update.isAppend => b.getAppend.getBlock.updatedWavesAmount } - balances shouldBe Seq(10000000000000000L, 10000000600000000L, 10000001200000000L) + "should include correct waves amount" - { + val totalWaves = 100_000_000_0000_0000L + val reward = 6_0000_0000 + + "on preactivated block reward" in { + val settings = currentSettings.setFeaturesHeight((BlockReward, 0)) + + withDomainAndRepo(settings) { case (d, repo) => + d.appendBlock() + d.blockchain.wavesAmount(1) shouldBe totalWaves + reward + repo.getBlockUpdate(1).getUpdate.vanillaAppend.updatedWavesAmount shouldBe totalWaves + reward + + d.appendBlock() + d.blockchain.wavesAmount(2) shouldBe totalWaves + reward * 2 + repo.getBlockUpdate(2).getUpdate.vanillaAppend.updatedWavesAmount shouldBe totalWaves + reward * 2 + } + } + + "on activation of block reward" in { + val settings = currentSettings.setFeaturesHeight((BlockReward, 3)) + + withNEmptyBlocksSubscription(settings = settings, count = 3) { result => + val balances = result.collect { case b if b.update.isAppend => b.getAppend.getBlock.updatedWavesAmount } + balances shouldBe Seq(totalWaves, totalWaves, totalWaves + reward, totalWaves + reward * 2) + } + + withDomainAndRepo(settings) { case (d, repo) => + d.appendBlock() + d.blockchain.wavesAmount(1) shouldBe totalWaves + repo.getBlockUpdate(1).getUpdate.vanillaAppend.updatedWavesAmount shouldBe totalWaves + + d.appendBlock() + d.blockchain.wavesAmount(2) shouldBe totalWaves + repo.getBlockUpdate(2).getUpdate.vanillaAppend.updatedWavesAmount shouldBe totalWaves + + d.appendBlock() + d.blockchain.wavesAmount(3) shouldBe totalWaves + reward + repo.getBlockUpdate(3).getUpdate.vanillaAppend.updatedWavesAmount shouldBe totalWaves + reward + + d.appendBlock() + d.blockchain.wavesAmount(4) shouldBe totalWaves + reward * 2 + repo.getBlockUpdate(4).getUpdate.vanillaAppend.updatedWavesAmount shouldBe totalWaves + reward * 2 + } + } + + "on rollbacks" in { + withDomainAndRepo(currentSettings) { case (d, repo) => + d.appendBlock() + + // block and micro append + val block = d.appendBlock() + block.sender shouldBe defaultSigner.publicKey + + d.appendMicroBlock(TxHelpers.transfer(defaultSigner)) + d.blockchain.wavesAmount(2) shouldBe totalWaves + reward * 2 + repo.getBlockUpdate(2).getUpdate.vanillaAppend.updatedWavesAmount shouldBe totalWaves + reward * 2 + + // micro rollback + d.appendKeyBlock(Some(block.id())) + d.blockchain.wavesAmount(3) shouldBe totalWaves + reward * 3 + repo.getBlockUpdate(3).getUpdate.vanillaAppend.updatedWavesAmount shouldBe totalWaves + reward * 3 + + // block rollback + d.rollbackTo(2) + d.blockchain.wavesAmount(2) shouldBe totalWaves + reward * 2 + repo.getBlockUpdate(2).getUpdate.vanillaAppend.updatedWavesAmount shouldBe totalWaves + reward * 2 + } + } } "should include correct heights" in withNEmptyBlocksSubscription(settings = currentSettings) { result => diff --git a/node/src/main/scala/com/wavesplatform/state/BlockchainUpdaterImpl.scala b/node/src/main/scala/com/wavesplatform/state/BlockchainUpdaterImpl.scala index cc5566aca6d..9696ecf1a2e 100644 --- a/node/src/main/scala/com/wavesplatform/state/BlockchainUpdaterImpl.scala +++ b/node/src/main/scala/com/wavesplatform/state/BlockchainUpdaterImpl.scala @@ -333,11 +333,11 @@ class BlockchainUpdaterImpl( block, hitSource, differResult.carry, - reward + None ) miner.scheduleMining(Some(tempBlockchain)) - blockchainUpdateTriggers.onProcessBlock(block, differResult.detailedDiff, reward, referencedBlockchain) + blockchainUpdateTriggers.onProcessBlock(block, differResult.detailedDiff, reward, this) leveldb.append(liquidDiffWithCancelledLeases, carry, totalFee, prevReward, prevHitSource, referencedForgedBlock) BlockStats.appended(referencedForgedBlock, referencedLiquidDiff.scriptsComplexity)