Skip to content
This repository has been archived by the owner on Apr 13, 2022. It is now read-only.

Commit

Permalink
Merge branch 'handle-db-issues-explicitly' into status-tracker
Browse files Browse the repository at this point in the history
  • Loading branch information
kushti committed Sep 15, 2021
2 parents 7d4a525 + 7b84e7d commit a5ba6db
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -474,16 +474,16 @@ class HybridHistory(val storage: HistoryStorage,
chainBack(storage.bestPosBlock, isGenesis).get.map(_._2).map(encoder.encodeId).mkString(",")
}

override def reportModifierIsValid(modifier: HybridBlock): HybridHistory = {
override def reportModifierIsValid(modifier: HybridBlock): Try[HybridHistory] = Try {
storage.updateValidity(modifier, Valid)
storage.update(modifier, None, isBest = true)

new HybridHistory(storage, settings, validators, statsLogger, timeProvider)
}

override def reportModifierIsInvalid(modifier: HybridBlock,
progressInfo: ProgressInfo[HybridBlock]): (HybridHistory,
ProgressInfo[HybridBlock]) = {
progressInfo: ProgressInfo[HybridBlock]): Try[(HybridHistory,
ProgressInfo[HybridBlock])] = Try {
storage.updateValidity(modifier, Invalid)

new HybridHistory(storage, settings, validators, statsLogger, timeProvider) ->
Expand Down
62 changes: 36 additions & 26 deletions src/main/scala/scorex/core/NodeViewHolder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ trait NodeViewHolder[TX <: Transaction, PMOD <: PersistentNodeViewModifier]
}
}

private def requestDownloads(pi: ProgressInfo[PMOD]): Unit =
protected def requestDownloads(pi: ProgressInfo[PMOD]): Unit =
pi.toDownload.foreach { case (tid, id) =>
context.system.eventStream.publish(DownloadRequest(tid, id))
}
Expand Down Expand Up @@ -206,7 +206,7 @@ trait NodeViewHolder[TX <: Transaction, PMOD <: PersistentNodeViewModifier]
**/

@tailrec
private def updateState(history: HIS,
protected final def updateState(history: HIS,
state: MS,
progressInfo: ProgressInfo[PMOD],
suffixApplied: IndexedSeq[PMOD]): (HIS, Try[MS], Seq[PMOD]) = {
Expand All @@ -222,14 +222,18 @@ trait NodeViewHolder[TX <: Transaction, PMOD <: PersistentNodeViewModifier]

stateToApplyTry match {
case Success(stateToApply) =>
val stateUpdateInfo = applyState(history, stateToApply, suffixTrimmed, progressInfo)

stateUpdateInfo.failedMod match {
case Some(_) =>
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val alternativeProgressInfo = stateUpdateInfo.alternativeProgressInfo.get
updateState(stateUpdateInfo.history, stateUpdateInfo.state, alternativeProgressInfo, stateUpdateInfo.suffix)
case None => (stateUpdateInfo.history, Success(stateUpdateInfo.state), stateUpdateInfo.suffix)
applyState(history, stateToApply, suffixTrimmed, progressInfo) match {
case Success(stateUpdateInfo) =>
stateUpdateInfo.failedMod match {
case Some(_) =>
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val alternativeProgressInfo = stateUpdateInfo.alternativeProgressInfo.get
updateState(stateUpdateInfo.history, stateUpdateInfo.state, alternativeProgressInfo, stateUpdateInfo.suffix)
case None =>
(stateUpdateInfo.history, Success(stateUpdateInfo.state), stateUpdateInfo.suffix)
}
case Failure(ex) =>
(history, Failure(ex), suffixTrimmed)
}
case Failure(e) =>
log.error("Rollback failed: ", e)
Expand All @@ -239,24 +243,30 @@ trait NodeViewHolder[TX <: Transaction, PMOD <: PersistentNodeViewModifier]
}
}

protected def applyState(history: HIS,
private def applyState(history: HIS,
stateToApply: MS,
suffixTrimmed: IndexedSeq[PMOD],
progressInfo: ProgressInfo[PMOD]): UpdateInformation = {
progressInfo: ProgressInfo[PMOD]): Try[UpdateInformation] = {
val updateInfoSample = UpdateInformation(history, stateToApply, None, None, suffixTrimmed)
progressInfo.toApply.foldLeft(updateInfoSample) { case (updateInfo, modToApply) =>
if (updateInfo.failedMod.isEmpty) {
updateInfo.state.applyModifier(modToApply) match {
case Success(stateAfterApply) =>
val newHis = history.reportModifierIsValid(modToApply)
context.system.eventStream.publish(SemanticallySuccessfulModifier(modToApply))
UpdateInformation(newHis, stateAfterApply, None, None, updateInfo.suffix :+ modToApply)
case Failure(e) =>
val (newHis, newProgressInfo) = history.reportModifierIsInvalid(modToApply, progressInfo)
context.system.eventStream.publish(SemanticallyFailedModification(modToApply, e))
UpdateInformation(newHis, updateInfo.state, Some(modToApply), Some(newProgressInfo), updateInfo.suffix)
}
} else updateInfo
progressInfo.toApply.foldLeft[Try[UpdateInformation]](Success(updateInfoSample)) {
case (f@Failure(ex), _) =>
log.error("Reporting modifier failed", ex)
f
case (success@Success(updateInfo), modToApply) =>
if (updateInfo.failedMod.isEmpty) {
updateInfo.state.applyModifier(modToApply) match {
case Success(stateAfterApply) =>
history.reportModifierIsValid(modToApply).map { newHis =>
context.system.eventStream.publish(SemanticallySuccessfulModifier(modToApply))
UpdateInformation(newHis, stateAfterApply, None, None, updateInfo.suffix :+ modToApply)
}
case Failure(e) =>
history.reportModifierIsInvalid(modToApply, progressInfo).map { case (newHis, newProgressInfo) =>
context.system.eventStream.publish(SemanticallyFailedModification(modToApply, e))
UpdateInformation(newHis, updateInfo.state, Some(modToApply), Some(newProgressInfo), updateInfo.suffix)
}
}
} else success
}
}

Expand Down Expand Up @@ -294,8 +304,8 @@ trait NodeViewHolder[TX <: Transaction, PMOD <: PersistentNodeViewModifier]

case Failure(e) =>
log.warn(s"Can`t apply persistent modifier (id: ${pmod.encodedId}, contents: $pmod) to minimal state", e)
// not publishing SemanticallyFailedModification as this is an internal error
updateNodeView(updatedHistory = Some(newHistory))
context.system.eventStream.publish(SemanticallyFailedModification(pmod, e))
}
} else {
requestDownloads(progressInfo)
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/scorex/core/consensus/History.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ trait History[PM <: PersistentNodeViewModifier, SI <: SyncInfo, HT <: History[PM
* Report that modifier is valid from point of view of the state component
*
* @param modifier - valid modifier
* @return modified history
* @return modified history, or failure if reporting was not successful
*/
def reportModifierIsValid(modifier: PM): HT
def reportModifierIsValid(modifier: PM): Try[HT]

/**
* Report that modifier is invalid from other nodeViewHolder components point of view
*
* @param modifier - invalid modifier
* @param progressInfo - what suffix failed to be applied because of an invalid modifier
* @return modified history and new progress info
* @return modified history and new progress info, or failure if reporting was not successful
*/
def reportModifierIsInvalid(modifier: PM, progressInfo: ProgressInfo[PM]): (HT, ProgressInfo[PM])
def reportModifierIsInvalid(modifier: PM, progressInfo: ProgressInfo[PM]): Try[(HT, ProgressInfo[PM])]


/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/scorex/core/network/NetworkController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class NetworkController(settings: NetworkSettings,
filterConnections(Broadcast, Version.initial).foreach { connectedPeer =>
connectedPeer.handlerRef ! CloseConnection
}
self ! Unbind
tcpManager ! Unbind
context stop self
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ trait HistoryTests[TX <: Transaction, PM <: PersistentNodeViewModifier, SI <: Sy
property(propertyNameGenerator("report semantically validation after appending valid modifier")) {
forAll(generatorWithValidModifier) { case (h, m) =>
h.append(m)
h.reportModifierIsValid(m)
h.reportModifierIsValid(m).get
h.isSemanticallyValid(m.id) shouldBe Valid
}
}
Expand Down

0 comments on commit a5ba6db

Please sign in to comment.