Skip to content

Commit

Permalink
PM-3146: Ignore Prepare if High Q.C. is older than Commit Q.C.
Browse files Browse the repository at this point in the history
  • Loading branch information
aakoshh committed Apr 15, 2021
1 parent f82a114 commit a290d81
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
1 change: 1 addition & 0 deletions metronome/core/src/io/iohk/metronome/core/Tagger.scala
Expand Up @@ -16,6 +16,7 @@ import shapeless.tag, tag.@@
trait Tagger[U] {
trait Tag
type Tagged = U @@ Tag

def apply(underlying: U): Tagged =
tag[Tag][U](underlying)
}
Expand Down
Expand Up @@ -65,11 +65,23 @@ class ConsensusService[F[_]: Timer: Concurrent, N, A <: Agreement: Block](
event: Event.MessageReceived[A]
): F[Option[Validated[Event.MessageReceived[A]]]] =
stateRef.get.flatMap { state =>
state.validateMessage(event) match {
state
.validateMessage(event)
.map(m => m: Event.MessageReceived[A]) match {
case Left(error) =>
// TODO: Trace invalid message received.
protocolError(error).as(none)

case Right(
Event.MessageReceived(
sender,
message @ Message.Prepare(_, _, highQC)
)
) if state.commitQC.viewNumber > highQC.viewNumber =>
// The sender is building on a block that is older than the committed one.
// This could be an attack, forcing us to re-download blocks we already pruned.
protocolError(ProtocolError.UnsafeExtension[A](sender, message))
.as(none)

case Right(valid) if valid.message.viewNumber < state.viewNumber =>
// TODO: Trace that obsolete message was received.
// TODO: Also collect these for the round so we can realise if we're out of sync.
Expand All @@ -84,7 +96,7 @@ class ConsensusService[F[_]: Timer: Concurrent, N, A <: Agreement: Block](
case Right(valid) =>
// We know that the message is to/from the leader and it's properly signed,
// althought it may not match our current state, which we'll see later.
valid.some.pure[F]
validated(valid).some.pure[F]
}
}

Expand Down Expand Up @@ -370,8 +382,13 @@ class ConsensusService[F[_]: Timer: Concurrent, N, A <: Agreement: Block](
} >> executeBlocks
}

private def validated(event: Event[A]) =
private def validated(event: Event[A]): Validated[Event[A]] =
Validated[Event[A]](event)

private def validated(
event: Event.MessageReceived[A]
): Validated[Event.MessageReceived[A]] =
Validated[Event.MessageReceived[A]](event)
}

object ConsensusService {
Expand Down

0 comments on commit a290d81

Please sign in to comment.