From c8480a90ff37228679876d2f0e6e157d325a0758 Mon Sep 17 00:00:00 2001 From: Alexis Hernandez Date: Sat, 14 Apr 2018 21:47:21 -0500 Subject: [PATCH] server: Fix corrupting balances while adding repeated blocks --- .../processors/BlockEventsProcessor.scala | 16 +++++++++++-- .../processors/BlockEventsProcessorSpec.scala | 23 +++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/server/app/com/xsn/explorer/processors/BlockEventsProcessor.scala b/server/app/com/xsn/explorer/processors/BlockEventsProcessor.scala index 6f2bb46..664b361 100644 --- a/server/app/com/xsn/explorer/processors/BlockEventsProcessor.scala +++ b/server/app/com/xsn/explorer/processors/BlockEventsProcessor.scala @@ -86,8 +86,20 @@ class BlockEventsProcessor @Inject() ( } def onMissingBlock(): FutureApplicationResult[Unit] = { - val command = DatabaseSeeder.CreateBlockCommand(newBlock, newTransactions) - databaseSeeder.insertPendingBlock(command) + blockDataHandler + .getBy(newBlock.hash) + .flatMap { + case Good(_) => + logger.info(s"The block ${newBlock.hash.string} is not missing but duplicated, ignoring") + Future.successful { Good(()) } + + case Bad(One(BlockNotFoundError)) => + val command = DatabaseSeeder.CreateBlockCommand(newBlock, newTransactions) + databaseSeeder.insertPendingBlock(command) + + case Bad(errors) => + Future.successful(Bad(errors)) + } } val result = for { diff --git a/server/test/com/xsn/explorer/processors/BlockEventsProcessorSpec.scala b/server/test/com/xsn/explorer/processors/BlockEventsProcessorSpec.scala index 6a2e84f..110e3e4 100644 --- a/server/test/com/xsn/explorer/processors/BlockEventsProcessorSpec.scala +++ b/server/test/com/xsn/explorer/processors/BlockEventsProcessorSpec.scala @@ -1,7 +1,7 @@ package com.xsn.explorer.processors -import com.xsn.explorer.data.anorm.dao.{BalancePostgresDAO, BlockPostgresDAO, TransactionPostgresDAO} -import com.xsn.explorer.data.anorm.{BlockPostgresDataHandler, DatabasePostgresSeeder} +import com.xsn.explorer.data.anorm.dao.{BalancePostgresDAO, BlockPostgresDAO, StatisticsPostgresDAO, TransactionPostgresDAO} +import com.xsn.explorer.data.anorm.{BlockPostgresDataHandler, DatabasePostgresSeeder, StatisticsPostgresDataHandler} import com.xsn.explorer.data.async.{BlockFutureDataHandler, DatabaseFutureSeeder} import com.xsn.explorer.data.common.PostgresDataHandlerSpec import com.xsn.explorer.helpers.Executors._ @@ -88,6 +88,25 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures verifyBlockchain(blocks) } } + + "processing a repeated missing block doesn't affect the balance" in { + val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7") + val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8") + val block3 = BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd") + + List(block1, block2, block3).map(dataHandler.upsert).foreach(_.isGood mustEqual true) + + whenReady(processor.newLatestBlock(block1.hash)) { result => + result.isGood mustEqual true + val blocks = List(block1, block2, block3) + verifyBlockchain(blocks) + + val statsDataHandler = new StatisticsPostgresDataHandler(database, new StatisticsPostgresDAO) + val stats = statsDataHandler.getStatistics().get + stats.totalSupply.isEmpty mustEqual true + stats.circulatingSupply.isEmpty mustEqual true + } + } } private def verifyBlockchain(blocks: List[Block]) = {