-
Notifications
You must be signed in to change notification settings - Fork 216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Attestations refactoring #3806
Attestations refactoring #3806
Conversation
… constants 2 and 3
d92a26e
to
37c83c6
Compare
@@ -0,0 +1,14 @@ | |||
package coop.rchain.sdk.casper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure where is the best place to locate this functions. My motivation was to place it to sdk project as common project and in casper subfolder as stake is part of Casper algorithm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it can be in package object in casper folder. This is general logic which is used in many places.
Also it makes sense to add extensions/aliases for bonds map, when instead of full stake it is Map[Validator, Long]. This one can be a bit tricky because you have to account situation with equal stake. If you use conversion to Set you might lose some stake, I encountered this once. So just want to warn.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This package should be called consensus
because it's not Casper specific. Supermajority of stake is theoretical requirement for consensus safety.
@@ -130,7 +131,7 @@ final case class Finalizer[M, S](msgMap: Map[M, Message[M, S]]) { | |||
// Total stake | |||
val totalStake = bondsMap.values.toSeq.sum | |||
// Calculate if 2/3 of stake supporting next layer | |||
fullPartitionStake.toDouble / totalStake > 2d / 3 | |||
Stake.prevails(fullPartitionStake, totalStake) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In previous version greater (>
) comparsion operator and floating-point calculations were used . More correct is to use greater or equal (>=
) operator and integer calculations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wrong. As shown in the article Byzantine_fault (I was guided by the Russian version), the stake must be strictly greater than 2/3.
/** | ||
* Check if stake prevails threshold of 2/3 | ||
*/ | ||
def prevails(stake: Long, totalStake: Long): Boolean = 3 * stake >= 2 * totalStake |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not satisfied with this name but I couldn't find out more appropriate name. Anyway for me such functions is better then using magic constants directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a isSupermajority
. I think you are right to use >= here.
While majority is > 50, it is not enough for Byzantine settings https://en.wikipedia.org/wiki/Byzantine_fault. So to be sure that in non trusted environment some decision is made, we have to rely on supermajority, which is 2/3.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imagine large value for the stake with many validators. In that case Long (int64) values can overflow and calculation will be false. That's the reason why I used floats.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a
isSupermajority
. I think you are right to use >= here.
PTAL at this. I guess >
is more correct so I was wrong.
preState <- MultiParentCasper.getPreStateForNewBlock[F] | ||
preState <- MultiParentCasper.getPreStateForNewBlock[F] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was duplicated lines of code. I guess it was just mistake so I removed one of them.
preState.preStateHash, | ||
preState.justifications.map(_.blockHash), | ||
preState.fringeBondsMap, | ||
preState, | ||
preState.rejectedDeploys, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here rejectedDeploys
field is used, while the Proposer uses fringeRejectedDeploys
. I just want to pay attention. Is this correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be fringeRejectedDeploys
as in Proposer, you are spot on.
deploys <- for { | ||
dummy <- dummyDeployOpt.traverse { | ||
case (privateKey, term) => | ||
val deployData = ConstructDeploy.sourceDeployNow( | ||
source = term, | ||
sec = privateKey, | ||
vabn = nextBlockNum - 1, | ||
shardId = shardId | ||
) | ||
BlockDagStorage[F].addDeploy(deployData).as(List(deployData.sig)) | ||
} | ||
} yield Option(pooledOk).filter(_.nonEmpty).orElse(dummy).getOrElse(List.empty) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will add dummy deploy into deploy storage even if it is not required.
Maybe you can use OptionT instead of Option and declare dummy
as a suspended value (as in my initial code).
} | ||
hasDeploys = (b: BlockMessage) => b.state.systemDeploys.nonEmpty || b.state.deploys.nonEmpty | ||
dag <- BlockDagStorage[F].getRepresentation | ||
seen = (hash: BlockHash) => dag.dagMessageState.msgMap(hash).seen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can write this as dag.dagMessageState.msgMap(_: BlockHash).seen
@@ -0,0 +1,14 @@ | |||
package coop.rchain.sdk.casper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This package should be called consensus
because it's not Casper specific. Supermajority of stake is theoretical requirement for consensus safety.
/** | ||
* Check if stake prevails threshold of 2/3 | ||
*/ | ||
def prevails(stake: Long, totalStake: Long): Boolean = 3 * stake >= 2 * totalStake |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imagine large value for the stake with many validators. In that case Long (int64) values can overflow and calculation will be false. That's the reason why I used floats.
val bondsMap = preState.fringeBondsMap | ||
val blockNum = preState.justifications.map(_.blockNum).max + 1 | ||
val creatorsPk = id.publicKey | ||
val creatorsId = ByteString.copyFrom(creatorsPk.bytes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use extension to convert to ByteString.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
bors merge |
Build succeeded: |
Overview
This PR resolves some review issues for PR #3791 which is already merged.
Please make sure that this PR:
Bors cheat-sheet:
bors r+
runs integration tests and merges the PR (if it's approved),bors try
runs integration tests for the PR,bors delegate+
enables non-maintainer PR authors to run the above.