Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import coop.rchain.blockstorage.dag.BlockDagStorage.DeployId
import coop.rchain.casper.protocol.{BlockMessage, DeployData}
import coop.rchain.crypto.signatures.Signed
import coop.rchain.models.BlockHash.BlockHash
import coop.rchain.models.BlockMetadata
import coop.rchain.models.{BlockMetadata, FringeData}

trait BlockDagStorage[F[_]] {

def getRepresentation: F[DagRepresentation]

def insert(blockMetadata: BlockMetadata, block: BlockMessage, isSync: Boolean = false): F[Unit]
def insert(
blockMetadata: BlockMetadata,
block: BlockMessage,
isSync: Boolean = false
): F[Unit]

def lookup(blockHash: BlockHash): F[Option[BlockMetadata]]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ final case class Message[M, S](
parents: Set[M],
fringe: Set[M],
// Cache of seen message ids
seen: View[S]
seen: View[S],
ejections: Set[S] = Set.empty[S]
) {
override def hashCode(): Int = this.id.hashCode()
}
Expand Down Expand Up @@ -151,7 +152,14 @@ final case class Finalizer[M, S](msgMap: Map[M, Message[M, S]]) {
def calculateFinalization(
justifications: Set[Message[M, S]],
bondsMap: Map[S, Long]
): (Set[Message[M, S]], List[Set[Message[M, S]]]) = {
): (Set[Message[M, S]], Either[Set[S], List[Set[Message[M, S]]]]) = {
def missingSenders(prevFringe: Set[Message[M, S]]): Set[S] = {
val minMsgs = justifications.toList.flatMap(p => (p +: selfParents(p, prevFringe)).lastOption)
// Include ancestors of minimum messages as next layer
val nextLayer = calculateNextLayer(minMsgs)
bondsMap.keySet -- nextLayer.keySet
}

// Calculate next fringe from previous fringe
def nextFringe(prevFringe: Set[Message[M, S]]): Option[Set[Message[M, S]]] =
for {
Expand All @@ -177,10 +185,12 @@ final case class Finalizer[M, S](msgMap: Map[M, Message[M, S]]) {
// Latest fringe seen from justifications
val parentFringe = msgMap.latestFringe(justifications)

val missing = missingSenders(parentFringe)

// Find top most fringe
// - multiple fringes can be finalized at once
val newFringes = LazyList.unfold(parentFringe)(nextFringe(_).map(nf => (nf, nf)))

(parentFringe, newFringes.toList)
(parentFringe, missing.isEmpty.guard[Option].as(newFringes.toList).toRight(missing))
}
}
53 changes: 53 additions & 0 deletions casper/src/main/resources/Pos.rhox
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,59 @@ in {
}
}
} |
// Private method which transfers all of a validator's rewards + bond to the Coop vault.
// Slash expects (Boolean, Either[Nil, String]) on returnCh.
contract PoS(@"eject", @ejectedValidator, @sysAuthToken, returnCh) = {
new isValidTokenCh, revAddressOps(`rho:rev:address`) in {
sysAuthTokenOps!("check", sysAuthToken, *isValidTokenCh) |
for (@isValid <- isValidTokenCh) {
if (isValid) {
new stateProcessCh in {
runMVar!(*stateCh, *stateProcessCh, *returnCh) |
for (@state, stateUpdateCh <- stateProcessCh) {
new valBondCh, valRewardCh, posAuthKeyCh, revAddrCh in {
// Takes the stake of slashed validator
// - transfer stake of ejected validator from PoS to validators vault
// - update state
valBondCh!(state.get("allBonds").get(ejectedValidator)) |
@RevVault!("unforgeableAuthKey", posVaultUnf, *posAuthKeyCh) |
revAddressOps!("fromPublicKey", ejectedValidator, *revAddrCh) |
for (@valBond <- valBondCh ; @posAuthKey <- posAuthKeyCh; @target <- revAddrCh) {
// Transfers ejected funds from PoS vault to validators vault, then updates state.
new transferDoneCh in {
@posVault!(
"transfer",
target,
valBond,
posAuthKey,
*transferDoneCh
) |
// FIXME handle transfer failing case
for (_ <- transferDoneCh) {
// Sets slashed validator's committed rewards and bond to 0 in state.
// Moves slashed validator to withdrawers map with no quarantine period.
stateUpdateCh!({
"allBonds" : state.get("allBonds").set(ejectedValidator, 0),
"activeValidators": state.get("activeValidators").delete(ejectedValidator),
"committedRewards" : state.get("committedRewards").delete(ejectedValidator),
"withdrawers" : state.get("withdrawers"),
"pendingWithdrawers": state.get("pendingWithdrawers"),
"randomImages" : state.get("randomImages"),
"randomNumbers" : state.get("randomNumbers")
},
(true, Nil))
}
}
}
}
}
}
} else {
returnCh!((false, "Invalid system auth token"))
}
}
}
} |
// Private method which signals the end of block processing.
contract PoS(@"closeBlock", @sysAuthToken, ackCh) = {
new isValidTokenCh in {
Expand Down
Loading