-
Notifications
You must be signed in to change notification settings - Fork 77
feat(code): Surface proposal and vote equivocation evidence #999
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
base: main
Are you sure you want to change the base?
Conversation
✅ Semver Check PassedGreat job! All semver violations have been resolved. This PR now complies with semantic versioning rules. If you made version updates, please ensure that:
|
If we want to inform the engine and the application of the equivocation that occurred during a height, we can simply add the evidence map to the What do you think? @romac @ancazamfir |
Codecov ReportAll modified and coverable lines are covered by tests ✅
✅ All tests successful. No failed tests found. Additional details and impacted files@@ Coverage Diff @@
## main #999 +/- ##
===========================
===========================
☔ View full report in Codecov by Sentry. |
1f4c5ec
to
f7c1b9c
Compare
perform!( | ||
co, | ||
Effect::Decide(certificate, extensions, Default::default()) | ||
Effect::Decide( |
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.
Can you add some evidence metrics above and also some error/warn logs?
Let't do this in a separate PR. We need to figure out if we send the actual equivocating votes/ proposals or just a statement "This node/address has equivocated". It depends on the app -- consensus trust level and if the app is "ready" to handle votes and proposals.
Yes, the latter is better. Not sure about clearing it though. So maybe we can check after applying a proposal or vote if "new" evidence is recorded in the driver. This is just for logging purposes at this point.
|
I opened https://github.com/informalsystems/malachite/pull/1009 which addresses some of my comments above and simplifies the implementation by only retrieving the evidence on decide, rather than emit events at the time when equivocation happens. |
I think we should postpone sending the evidence to the app in decide. It is not clear to me the evidence form that the app could digest. I was proposing above to do this in a different PR once we have a conversation with app devs. We should also log the evidence in consensus and update metrics. Ideally when it happens as the height may not decide and this information may prove important in debugging. |
@ancazamfir @romac What should this branch implement, then? Based on your perspectives, #1009 is already in better shape than this one. |
See my comment in #1009. |
…ien/equivocation-evidence
…n decide (#1009) * refactor(code): Simplify implementation by only checking for evidence on decide * feat: equivocation logs * fix: missing update * fix: debug -> warn * fix: show full proposal and vote * fix: temporary middlewares warnings --------- Co-authored-by: Bastien Faivre <[email protected]>
use crate::TestBuilder; | ||
|
||
#[tokio::test] | ||
pub async fn equivocation_proposer() { |
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.
@romac, the inject feature is not enough/complete. Indeed, injecting a ProposeValue
message does not work as the engine/driver will not consider two propose values; therefore, no conflicting proposals are sent. If we want to force receiving a proposal via a NetworkEvent
, it also does not work since we do not have access to the peer id and cannot sign the proposal.
Do you have an idea on how to fix this?
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.
Ah bummer… Let me think about it and I'll come back to you
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.
Maybe we can pass an unsigned message to inject
and use Node::get_signing_provider
to sign the message in the test framework?
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.
For that, we need to have access to the app instance (on which we can actually call get_signing_provider
), but I don't see where we can access it in the framework.
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.
Maybe an overkill but can you run once and collect the proposals from that run? And then run again (with same keys) and inject in the second run the proposal from the first?
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.
The other question, does it make sense to do the tests in a separate PR and merge this one as is?
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.
Maybe an overkill but can you run once and collect the proposals from that run? And then run again (with same keys) and inject in the second run the proposal from the first?
Do you mean hardcoding the messages? For example, for votes, retrieve data from such logs:
2025-05-13T12:08:41.926664Z DEBUG test{id=1}:node{id=2}: Event: Published(msg: Vote(SignedMessage { message: Vote { typ: Precommit, height: Height(2), round: Some(0), value: Val(ValueId(81418)), validator_address: Address(AD52C99C243AAB9755836D3055A4ECAA5A5D76C7), extension: None }, signature: Signature(Signature { R_bytes: "f75cf3e1a3ddafe8c340f8700b5e792f47c0fe3a0d364446ae206bf7f8c54e4b", s_bytes: "4610ac2c9868b57f50bdb9064d503e2145e22978dfbc67da9994bcf38224ce09" }) }))
That might work, but does the framework support specifying a key seed? @romac
I would likely prefer the inject approach, which might also be useful for other tests.
The other question, does it make sense to do the tests in a separate PR and merge this one as is?
That is technically possible, yes.
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.
Do you mean hardcoding the messages? For example, for votes, retrieve data from such logs:
I thought you could intercept the proposal (or vote) in the first run, save it in some test state and then inject it in the second run.
I would likely prefer the inject approach, which might also be useful for other tests.
You still do the inject but you need a properly signed (second) proposal
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.
Nifty idea, I'll give it a go next week!
Closes: #911
PR author checklist
For all contributors
RELEASE_NOTES.md
if the change warrants itBREAKING_CHANGES.md
if the change warrants itFor external contributors