Skip to content

Commit

Permalink
server: Make block rewards optional and store masternode rewards
Browse files Browse the repository at this point in the history
  • Loading branch information
iBlackShadow committed Nov 2, 2019
1 parent fec0ea2 commit 6428091
Show file tree
Hide file tree
Showing 16 changed files with 210 additions and 75 deletions.
2 changes: 1 addition & 1 deletion server/app/com/xsn/explorer/data/LedgerDataHandler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ trait LedgerDataHandler[F[_]] {
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): F[Unit]

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class LedgerPostgresDataHandler @Inject()(
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): ApplicationResult[Unit] = {

// the filter is computed outside the transaction to avoid unnecessary locking
Expand Down Expand Up @@ -80,15 +80,15 @@ class LedgerPostgresDataHandler @Inject()(
block: Block.HasTransactions,
filter: GolombCodedSet,
tposContracts: List[TPoSContract],
rewards: BlockRewards
rewards: Option[BlockRewards]
)(implicit conn: Connection): Option[Unit] = {

val result = for {
// block
_ <- deleteBlockCascade(block.block).orElse(Some(()))
_ <- blockPostgresDAO.insert(block.block)
_ = blockFilterPostgresDAO.insert(block.hash, filter)
_ = blockRewardDAO.upsert(block.hash, rewards)
_ = rewards.foreach(blockRewardDAO.upsert(block.hash, _))

// batch insert
_ <- transactionPostgresDAO.insert(block.transactions, tposContracts)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,20 @@ class BlockRewardPostgresDAO {
getRewards(reward).foreach(r => upsert(blockhash, r._1, r._2))
}

def getBy(blockhash: Blockhash)(implicit conn: Connection): BlockRewards = {
def getBy(blockhash: Blockhash)(implicit conn: Connection): Option[BlockRewards] = {
val rewards = getRewards(blockhash)
rewards match {
case (r: BlockReward, RewardType.PoW) :: Nil =>
PoWBlockRewards(r)
case (r: BlockReward, RewardType.PoS) :: Nil =>
PoSBlockRewards(r, None)
case (ownerReward: BlockReward, RewardType.TPoSOwner) :: (merchantReward: BlockReward, RewardType.TPoSMerchant) :: Nil =>
TPoSBlockRewards(ownerReward, merchantReward, None)
case (merchantReward: BlockReward, RewardType.TPoSMerchant) :: (ownerReward: BlockReward, RewardType.TPoSOwner) :: Nil =>
TPoSBlockRewards(ownerReward, merchantReward, None)
case (r, RewardType.PoW) :: Nil =>
Some(PoWBlockRewards(r))
case (r, RewardType.PoS) :: Nil =>
Some(PoSBlockRewards(r, None))
case (r, RewardType.PoS) :: (masternode, RewardType.Masternode) :: Nil =>
Some(PoSBlockRewards(r, Some(masternode)))
case (owner, RewardType.TPoSOwner) :: (merchant, RewardType.TPoSMerchant) :: Nil =>
Some(TPoSBlockRewards(owner, merchant, None))
case (masternode, RewardType.Masternode) :: (owner, RewardType.TPoSOwner) :: (merchant, RewardType.TPoSMerchant) :: Nil =>
Some(TPoSBlockRewards(owner, merchant, Some(masternode)))
case Nil => None
case _ =>
throw new RuntimeException("Unknown reward type")
}
Expand Down Expand Up @@ -79,6 +82,7 @@ class BlockRewardPostgresDAO {
|SELECT address, value, type
|FROM block_rewards
|WHERE blockhash = {blockhash}
|ORDER BY type
""".stripMargin
).on(
"blockhash" -> blockhash.toBytesBE.toArray
Expand All @@ -88,13 +92,16 @@ class BlockRewardPostgresDAO {

private def getRewards(reward: BlockRewards): List[(BlockReward, RewardType)] = {
reward match {
case r: PoWBlockRewards => List((r.reward, RewardType.PoW))
case r: PoSBlockRewards => List((r.coinstake, RewardType.PoS))
case r: PoWBlockRewards =>
List((r.reward, RewardType.PoW))
case r: PoSBlockRewards =>
val rewards = List((r.coinstake, RewardType.PoS))

rewards ++ r.masternode.map((_, RewardType.Masternode))
case r: TPoSBlockRewards =>
List(
(r.owner, RewardType.TPoSOwner),
(r.merchant, RewardType.TPoSMerchant)
)
val rewards = List((r.owner, RewardType.TPoSOwner), (r.merchant, RewardType.TPoSMerchant))

rewards ++ r.masternode.map((_, RewardType.Masternode))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class LedgerFutureDataHandler @Inject()(
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
retryableFutureDataHandler.retrying {
Future {
Expand Down
1 change: 1 addition & 0 deletions server/app/com/xsn/explorer/models/RewardType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ object RewardType extends Enum[RewardType] {

final case object PoW extends RewardType("PoW")
final case object PoS extends RewardType("PoS")
final case object Masternode extends RewardType("MASTERNODE")
final case object TPoSOwner extends RewardType("TPoS_OWNER")
final case object TPoSMerchant extends RewardType("TPoS_MERCHANT")
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class BlockParallelChunkSynchronizer @Inject()(
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val start = System.currentTimeMillis()
val result = for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private[synchronizer] class LedgerSynchronizationOps @Inject()(
def getBlockData(rpcBlock: rpc.Block[_]): FutureApplicationResult[BlockData] = {
val result = for {
extractionMethod <- blockService.extractionMethod(rpcBlock).toFutureOr
rewards <- blockService.getBlockRewards(rpcBlock, extractionMethod).toFutureOr
rewards <- getBlockRewards(rpcBlock, extractionMethod).toFutureOr
data <- transactionCollectorService.collect(rpcBlock).toFutureOr
(transactions, contracts, filterFactory) = data
validContracts <- getValidContracts(contracts).toFutureOr
Expand All @@ -99,6 +99,16 @@ private[synchronizer] class LedgerSynchronizationOps @Inject()(
result.toFuture
}

private def getBlockRewards(
rpcBlock: rpc.Block[_],
extractionMethod: BlockExtractionMethod
): FutureApplicationResult[Option[BlockRewards]] = {
blockService.getBlockRewards(rpcBlock, extractionMethod).map {
case Good(reward) => Good(Some(reward))
case Bad(_) => Good(None)
}
}

private def getValidContracts(contracts: List[TPoSContract]): FutureApplicationResult[List[TPoSContract]] = {
val listF = contracts
.map { contract =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = state match {
case BlockSynchronizationState.StoringBlock =>
storeBlock(block, tposContracts, filterFactory, rewards)
Expand Down Expand Up @@ -56,7 +56,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val initialState = BlockSynchronizationState.StoringBlock
val nextState = BlockSynchronizationState.StoringBlockData
Expand All @@ -82,7 +82,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val nextState = BlockSynchronizationState.StoringTransactions
val filterF = Future { filterFactory() }
Expand Down Expand Up @@ -112,7 +112,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val nextState = BlockSynchronizationState.StoringOutputs
val storeTransactionsF = block.transactions.zipWithIndex.map {
Expand All @@ -138,7 +138,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val nextState = BlockSynchronizationState.StoringInputs
val storeOutputsF =
Expand All @@ -163,7 +163,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val nextState = BlockSynchronizationState.SpendingOutputs
val storeInputsF =
Expand All @@ -188,7 +188,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val nextState = BlockSynchronizationState.StoringAddressTransactionDetails
val spendOutputsF =
Expand All @@ -213,7 +213,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val nextState = BlockSynchronizationState.UpdatingTPoSContracts
val storeDetailsF =
Expand All @@ -238,7 +238,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val nextState = BlockSynchronizationState.StoringRewards

Expand Down Expand Up @@ -273,7 +273,7 @@ class BlockParallelChunkAddOps @Inject()(blockChunkRepository: BlockChunkReposit
block: Block.HasTransactions,
tposContracts: List[TPoSContract],
filterFactory: () => GolombCodedSet,
rewards: BlockRewards
rewards: Option[BlockRewards]
): FutureApplicationResult[Unit] = {
val nextState = BlockSynchronizationState.UpdatingBalances

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.xsn.explorer.models.values.TransactionId
package object synchronizer {

private[synchronizer] type BlockData =
(Block.HasTransactions, List[TPoSContract], () => GolombCodedSet, BlockRewards)
(Block.HasTransactions, List[TPoSContract], () => GolombCodedSet, Option[BlockRewards])

private[synchronizer] val ExcludedTransactions: List[TransactionId] =
List("e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468").flatMap(TransactionId.from)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ class BlockChunkPostgresRepository @Inject()(
maybe.map(x => Good(x)).getOrElse(throw new RuntimeException(s"Failed to rollback block $blockhash"))
}

override def upsertBlockReward(blockhash: Blockhash, reward: BlockRewards): ApplicationResult[Unit] = {
override def upsertBlockReward(blockhash: Blockhash, reward: Option[BlockRewards]): ApplicationResult[Unit] = {
withConnection { implicit conn =>
blockRewardDAO.upsert(blockhash, reward)
reward.foreach(blockRewardDAO.upsert(blockhash, _))
Good(())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ trait BlockChunkRepository[F[_]] {
*/
def atomicRollback(blockhash: Blockhash): F[Unit]

def upsertBlockReward(blockhash: Blockhash, reward: BlockRewards): F[Unit]
def upsertBlockReward(blockhash: Blockhash, reward: Option[BlockRewards]): F[Unit]
}

object BlockChunkRepository {
Expand Down Expand Up @@ -138,8 +138,9 @@ object BlockChunkRepository {
blocking.atomicRollback(blockhash)
}

override def upsertBlockReward(blockhash: Blockhash, reward: BlockRewards): FutureApplicationResult[Unit] = Future {
blocking.upsertBlockReward(blockhash, reward)
}
override def upsertBlockReward(blockhash: Blockhash, reward: Option[BlockRewards]): FutureApplicationResult[Unit] =
Future {
blocking.upsertBlockReward(blockhash, reward)
}
}
}
1 change: 1 addition & 0 deletions server/conf/evolutions/default/23.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ALTER TYPE BLOCK_SYNCHRONIZATION_STATE ADD VALUE 'STORING_REWARDS';
CREATE TYPE REWARD_TYPE AS ENUM (
'PoW',
'PoS',
'MASTERNODE',
'TPoS_OWNER',
'TPoS_MERCHANT'
);
Expand Down
Loading

0 comments on commit 6428091

Please sign in to comment.