-
Notifications
You must be signed in to change notification settings - Fork 69
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
feat: block production misbehavior detection #1071
Conversation
@@ -171,8 +180,8 @@ | |||
}() | |||
|
|||
// P2P Sync. Subscribe to P2P received blocks events | |||
go uevent.MustSubscribe(ctx, m.Pubsub, "applyGossipedBlocksLoop", p2p.EventQueryNewGossipedBlock, m.onReceivedBlock, m.logger) | |||
go uevent.MustSubscribe(ctx, m.Pubsub, "applyBlockSyncBlocksLoop", p2p.EventQueryNewBlockSyncBlock, m.onReceivedBlock, m.logger) | |||
go uevent.MustSubscribe(ctx, m.Pubsub, "applyGossipedBlocksLoop", p2p.EventQueryNewGossipedBlock, m.OnReceivedBlock, m.logger) |
Check notice
Code scanning / CodeQL
Spawning a Go routine Note
go uevent.MustSubscribe(ctx, m.Pubsub, "applyGossipedBlocksLoop", p2p.EventQueryNewGossipedBlock, m.onReceivedBlock, m.logger) | ||
go uevent.MustSubscribe(ctx, m.Pubsub, "applyBlockSyncBlocksLoop", p2p.EventQueryNewBlockSyncBlock, m.onReceivedBlock, m.logger) | ||
go uevent.MustSubscribe(ctx, m.Pubsub, "applyGossipedBlocksLoop", p2p.EventQueryNewGossipedBlock, m.OnReceivedBlock, m.logger) | ||
go uevent.MustSubscribe(ctx, m.Pubsub, "applyBlockSyncBlocksLoop", p2p.EventQueryNewBlockSyncBlock, m.OnReceivedBlock, m.logger) |
Check notice
Code scanning / CodeQL
Spawning a Go routine Note
Please link the adr(s) and issue(s) |
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.
Looking good
Aside from comments on the code, the main thing here
- please over document everything wrt. security implications
- what is envisioned for fraud handler?
- dependence on accuracy of proposer addr
The fraud handler is going to need to check that everything is actually a fraud, rather than operator mistake (e.g. in wrong app-hash case) and that the fraud came from a particular slashable person. How do you envision that given the currently supplied data?
@@ -19,6 +19,18 @@ import ( | |||
// default minimum block max size allowed. not specific reason to set it to 10K, but we need to avoid no transactions can be included in a block. | |||
const minBlockMaxBytes = 10000 | |||
|
|||
type ExecutorI interface { |
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.
dont need I
suffix in go
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.
and interfaces should be defined in consumer package
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.
nvm it is already
func (f FreezeHandler) HandleFault(ctx context.Context, fault error) { | ||
uevent.MustPublish(ctx, f.m.Pubsub, &events.DataHealthStatus{Error: fault}, events.HealthStatusList) | ||
} |
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.
what is the intended behaviour?
This will just log the error string? what about dumping to file etc, is that coming in another pr?
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 never heard about those features
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 theory this is what was commented, to set the node freeze by sending the event.
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.
how does sending this event 'freeze' anything? what does freeze even mean?
if c.Height != header.Height { | ||
return NewErrInvalidBlockHeightFraud(c.Height, header.Height) | ||
} |
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.
invalid block height fraud is a bit undefined IMO
this is an invalid commit fraud
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.
let me know your preferred name
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.
why is there ErrFraudHeightMismatch and ErrInvalidBlockHeightFraud?
it's not clear what the intention is so hard to choose a name
invalid height is fine as a name but why are there two?
And the invalid height is only relevant when comparing to DA batch surely?
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.
One is for the header, the other from the commit.
func (c *Commit) ValidateWithHeader(proposerPubKey tmcrypto.PubKey, header *Header) error { | ||
if err := c.ValidateBasic(); err != nil { | ||
return err | ||
return NewErrInvalidSignatureFraud(err) |
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.
none of the frauds returned here will be caught in p2p case right? because there is no handler
Lines 83 to 86 in 88ba1fe
if err := gossipedBlock.Validate(v.proposerGetter.GetProposerPubKey()); err != nil { | |
v.logger.Error("Failed to validate gossiped block.", "height", gossipedBlock.Block.Header.Height, "error", err) | |
return false | |
} |
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 will when attemptApplyCachedBlocks
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.
but they are already rejected at p2p level by this code? so they will never reach it
type ErrLastHeaderHashMismatch struct { | ||
Expected [32]byte | ||
LastHeaderHash [32]byte | ||
} |
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.
don't you need more info to validate 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.
I did not heard that the error must contain all the info to validate. Is that documented?
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've asked @omritoptix for some confirmation that nothing was changed but I believe the original intention was that the frauds have to be actionable, so 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.
Looks like the scope has drifted a bit from what I originally understood
I've posted on slack to get this confirmed
https://dymensionworkspace.slack.com/archives/C07HV4329LJ/p1729509868648489
func (f FreezeHandler) HandleFault(ctx context.Context, fault error) { | ||
uevent.MustPublish(ctx, f.m.Pubsub, &events.DataHealthStatus{Error: fault}, events.HealthStatusList) | ||
} |
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.
how does sending this event 'freeze' anything? what does freeze even mean?
func (c *Commit) ValidateWithHeader(proposerPubKey tmcrypto.PubKey, header *Header) error { | ||
if err := c.ValidateBasic(); err != nil { | ||
return err | ||
return NewErrInvalidSignatureFraud(err) |
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.
but they are already rejected at p2p level by this code? so they will never reach it
nextHeight := state.NextHeight() | ||
if b.Header.Height != nextHeight { | ||
return NewErrFraudHeightMismatch(state.NextHeight(), b.Header.Height, b) | ||
} |
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.
ok can you please document that? defensive code is really hard to understand
type ErrLastHeaderHashMismatch struct { | ||
Expected [32]byte | ||
LastHeaderHash [32]byte | ||
} |
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've asked @omritoptix for some confirmation that nothing was changed but I believe the original intention was that the frauds have to be actionable, so yes
if c.Height != header.Height { | ||
return NewErrInvalidBlockHeightFraud(c.Height, header.Height) | ||
} |
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.
why is there ErrFraudHeightMismatch and ErrInvalidBlockHeightFraud?
it's not clear what the intention is so hard to choose a name
invalid height is fine as a name but why are there two?
And the invalid height is only relevant when comparing to DA batch surely?
PR Standards
#1070
https://www.notion.so/dymension/ADR-x-generic-Dymint-fraud-handling-7425a9ef065b458c989404c42be6a6cdhttps://www.notion.so/dymension/ADR-x-STF-fraud-detection-105a4a51f86a80f88225da364d798dddhttps://www.notion.so/dymension/ADR-x-timestamp-fraud-detection-105a4a51f86a80478c68d385b254459ehttps://www.notion.so/dymension/ADR-L2-Block-Production-Misbehavior-10da4a51f86a806ab08cf0a4e1cecc37
Opening a pull request should be able to meet the following requirements
--
PR naming convention: https://hackmd.io/@nZpxHZ0CT7O5ngTp0TP9mg/HJP_jrm7A
Close #XXX
<-- Briefly describe the content of this pull request -->
For Author:
godoc
commentsFor Reviewer:
After reviewer approval: