All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
sss.openstar.wallet.UtxoTracker.scala Maven / Gradle / Ivy
package sss.openstar.wallet
import akka.actor.{Actor, ActorContext, ActorLogging, ActorRef, Props}
import sss.openstar.balanceledger.{NewUtxo, UtxoChanges}
import sss.openstar.chains.Chains.GlobalChainIdMask
import sss.openstar.eventbus.EventPublish
import sss.openstar.ledger.LedgerId
import sss.openstar.network.MessageEventBus
import sss.openstar.network.MessageEventBus.EventSubscriptions
import sss.openstar.util.{ActorTryAndLog, Amount, IOExecutionContext}
import sss.openstar.wallet.UtxoTracker.{NewBalance, TrackWallet}
import sss.openstar.{BusEvent, Currency, UniqueNodeIdentifier}
object UtxoTracker {
case class NewBalance(ledgerId: LedgerId, nodeId: UniqueNodeIdentifier, balance: Amount) extends BusEvent
case class TrackWallet[C <: Currency](walletTracking: Wallet[C], initialBalance: Amount) extends BusEvent
def apply[C <: Currency](walletTracking: Seq[Wallet[C]],
ledgerId: LedgerId)
(implicit actorSystem: ActorContext,
messageEventBus: MessageEventBus,
chainId: GlobalChainIdMask,
ioExecutionContext: IOExecutionContext
): ActorRef = {
actorSystem.actorOf(
Props(classOf[UtxoTracker[C]],
walletTracking,
ledgerId: LedgerId,
messageEventBus,
chainId,
ioExecutionContext)
.withDispatcher("blocking-dispatcher"), s"UtxoTracker_${ledgerId.id}")
}
}
private class UtxoTracker[C <: Currency](walletTracking: Seq[Wallet[C]], ledgerId: LedgerId
)(
implicit messageEventBus: EventPublish with EventSubscriptions,
chainId: GlobalChainIdMask,
ioExecutionContext: IOExecutionContext
) extends Actor with ActorLogging with ActorTryAndLog {
log.info(s"UtxoTracker started $ledgerId")
override def preStart(): Unit = {
super.preStart()
messageEventBus.subscribe(classOf[UtxoChanges])
messageEventBus.subscribe(classOf[TrackWallet[C]])
walletTracking foreach (w => self ! TrackWallet(w, w.balance().get))
}
override def postStop(): Unit = {
log.warning(s"UtxoTracker down $ledgerId !!!!")
super.postStop()
}
override def receive: Receive = withWallets(Map.empty)
private def withWallets(wallets: Map[Wallet[C], Amount]): Receive = {
case t: TrackWallet[C @unchecked] if t.walletTracking.ledgerId == ledgerId =>
val newWallets = wallets + (t.walletTracking -> t.initialBalance)
context become withWallets(newWallets)
messageEventBus publish NewBalance(t.walletTracking.ledgerId, t.walletTracking.walletOwner, t.initialBalance)
case UtxoChanges(`ledgerId`, _, _, consumedSeq, emmittedSeq) => tryAndLog {
wallets foreach { case (wallet, _) =>
//log.debug(s"Checking Wallet ${wallet.ledgerId} ${wallet.walletOwner} ")
val walletsForUpdate = consumedSeq.map { consumed =>
wallet.confirmSpent(consumed.txIndx)
} collect {
case Some(_) => wallet
}
val allWalletsForUpdate = (
emmittedSeq
.collect {
case out: NewUtxo => out
}.map { emmitted =>
val r = wallet(emmitted.txIndx, emmitted.out)
r.foreach(l => log.info(s"Processing TX: ${wallet.walletOwner} applying ${emmitted.txIndx} ${l}"))
r
} collect {
case Some(_) => wallet
}).filterNot(walletsForUpdate.contains) ++ walletsForUpdate
allWalletsForUpdate.foreach { wallet =>
val newBalance = wallet.balance().get
val newWallets = wallets + (wallet -> newBalance)
context become withWallets(newWallets)
messageEventBus publish NewBalance(wallet.ledgerId, wallet.walletOwner, newBalance)
}
}
}
}
}