Skip to content

Commit

Permalink
Added a Difficulty check in Zone for stale broadcast
Browse files Browse the repository at this point in the history
  • Loading branch information
gameofpointers committed Oct 12, 2023
1 parent 07a08d0 commit de97793
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 2 deletions.
5 changes: 5 additions & 0 deletions consensus/blake3pow/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,11 @@ func (blake3pow *Blake3pow) IsDomCoincident(chain consensus.ChainHeaderReader, h
return order < common.NodeLocation.Context()
}

// VerifySeal returns the PowHash and the verifySeal output
func (blake3pow *Blake3pow) VerifySeal(header *types.Header) (common.Hash, error) {
return header.Hash(), blake3pow.verifySeal(header)
}

// verifySeal checks whether a block satisfies the PoW difficulty requirements,
// either using the usual blake3pow cache for it, or alternatively using a full DAG
// to make remote mining fast.
Expand Down
4 changes: 4 additions & 0 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ type Engine interface {
// dominant chain, or even that the claimed dominant difficulty is valid.
IsDomCoincident(chain ChainHeaderReader, header *types.Header) bool

// VerifySeal computes the PowHash and checks if work meets the difficulty
// requirement specified in header
VerifySeal(header *types.Header) (common.Hash, error)

// APIs returns the RPC APIs this consensus engine provides.
APIs(chain ChainHeaderReader) []rpc.API

Expand Down
5 changes: 5 additions & 0 deletions consensus/progpow/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,11 @@ func (progpow *Progpow) ComputePowLight(header *types.Header) (mixHash, powHash
return mixHash, powHash
}

// VerifySeal returns the PowHash and the verifySeal output
func (progpow *Progpow) VerifySeal(header *types.Header) (common.Hash, error) {
return progpow.verifySeal(header)
}

// verifySeal checks whether a block satisfies the PoW difficulty requirements,
// either using the usual progpow cache for it, or alternatively using a full DAG
// to make remote mining fast.
Expand Down
24 changes: 23 additions & 1 deletion eth/fetcher/block_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ type bodyRequesterFn func([]common.Hash) error
// headerVerifierFn is a callback type to verify a block's header for fast propagation.
type headerVerifierFn func(header *types.Header) error

// verifySealFn is a callback type to verify seal of a block header and get the PowHash
type verifySealFn func(header *types.Header) (common.Hash, error)

// blockBroadcasterFn is a callback type for broadcasting a block to connected peers.
type blockBroadcasterFn func(block *types.Block, propagate bool)

Expand All @@ -95,6 +98,9 @@ type currentIntrinsicSFn func() *big.Int
// currentSFn is a callback type to retrieve the current chain heads Entropy
type currentSFn func() *big.Int

// currentDifficultyFn is a callback type to retrieve the current chain heads difficulty
type currentDifficultyFn func() *big.Int

// peerDropFn is a callback type for dropping a peer detected as malicious.
type peerDropFn func(id string)

Expand Down Expand Up @@ -185,10 +191,12 @@ type BlockFetcher struct {
getBlock blockRetrievalFn // Retrieves a block from the local chain
writeBlock blockWriteFn // Writes the block to the DB
verifyHeader headerVerifierFn // Checks if a block's headers have a valid proof of work
verifySeal verifySealFn // Checks if blocks PoWHash meets the difficulty requirement
broadcastBlock blockBroadcasterFn // Broadcasts a block to connected peers
chainHeight chainHeightFn // Retrieves the current chain's height
currentIntrinsicS currentIntrinsicSFn // Retrieves the current headers intrinsic logS
currentS currentSFn // Retrieves the current heads logS
currentDifficulty currentDifficultyFn // Retrieves the current difficulty
dropPeer peerDropFn // Drops a peer for misbehaving
isBlockHashABadHash badHashCheckFn // Checks if the block hash exists in the bad hashes list

Expand All @@ -201,7 +209,7 @@ type BlockFetcher struct {
}

// NewBlockFetcher creates a block fetcher to retrieve blocks based on hash announcements.
func NewBlockFetcher(getBlock blockRetrievalFn, writeBlock blockWriteFn, verifyHeader headerVerifierFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, currentIntrinsicS currentIntrinsicSFn, currentS currentSFn, dropPeer peerDropFn, isBlockHashABadHash badHashCheckFn) *BlockFetcher {
func NewBlockFetcher(getBlock blockRetrievalFn, writeBlock blockWriteFn, verifyHeader headerVerifierFn, verifySeal verifySealFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, currentIntrinsicS currentIntrinsicSFn, currentS currentSFn, currentDifficulty currentDifficultyFn, dropPeer peerDropFn, isBlockHashABadHash badHashCheckFn) *BlockFetcher {
return &BlockFetcher{
notify: make(chan *blockAnnounce),
inject: make(chan *blockOrHeaderInject),
Expand All @@ -219,9 +227,11 @@ func NewBlockFetcher(getBlock blockRetrievalFn, writeBlock blockWriteFn, verifyH
getBlock: getBlock,
writeBlock: writeBlock,
verifyHeader: verifyHeader,
verifySeal: verifySeal,
broadcastBlock: broadcastBlock,
chainHeight: chainHeight,
currentIntrinsicS: currentIntrinsicS,
currentDifficulty: currentDifficulty,
currentS: currentS,
dropPeer: dropPeer,
isBlockHashABadHash: isBlockHashABadHash,
Expand Down Expand Up @@ -705,6 +715,18 @@ func (f *BlockFetcher) enqueue(peer string, header *types.Header, block *types.B
// the phase states accordingly.
func (f *BlockFetcher) ImportBlocks(peer string, block *types.Block, relay bool) {
hash := block.Hash()
nodeCtx := common.NodeLocation.Context()

powhash, err := f.verifySeal(block.Header())
if err != nil {
return
}
// Check if the Block is atleast half the current difficulty in Zone Context,
// this makes sure that the nodes don't listen to the forks with the PowHash
// with less than 50% of current difficulty
if nodeCtx == common.ZONE_CTX && new(big.Int).SetBytes(powhash.Bytes()).Cmp(new(big.Int).Div(f.currentDifficulty(), big.NewInt(2))) < 0 {
return
}

currentIntrinsicS := f.currentIntrinsicS()
maxAllowableEntropyDist := new(big.Int).Mul(currentIntrinsicS, big.NewInt(maxAllowableEntropyDist))
Expand Down
8 changes: 7 additions & 1 deletion eth/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ func newHandler(config *handlerConfig) (*handler, error) {
validator := func(header *types.Header) error {
return h.core.Engine().VerifyHeader(h.core, header)
}
verifySeal := func(header *types.Header) (common.Hash, error) {
return h.core.Engine().VerifySeal(header)
}
heighter := func() uint64 {
return h.core.CurrentHeader().NumberU64()
}
Expand All @@ -184,6 +187,9 @@ func newHandler(config *handlerConfig) (*handler, error) {
// broadcast distance only, ParentEntropy should suffice
return h.core.CurrentHeader().ParentEntropy()
}
currentDifficulty := func() *big.Int {
return h.core.CurrentHeader().Difficulty()
}
// writeBlock writes the block to the DB
writeBlock := func(block *types.Block) {
if nodeCtx == common.ZONE_CTX && block.NumberU64()-1 == h.core.CurrentHeader().NumberU64() && h.core.ProcessingState() {
Expand All @@ -193,7 +199,7 @@ func newHandler(config *handlerConfig) (*handler, error) {
}
h.core.WriteBlock(block)
}
h.blockFetcher = fetcher.NewBlockFetcher(h.core.GetBlockOrCandidateByHash, writeBlock, validator, h.BroadcastBlock, heighter, currentThresholdS, currentS, h.removePeer, h.core.IsBlockHashABadHash)
h.blockFetcher = fetcher.NewBlockFetcher(h.core.GetBlockOrCandidateByHash, writeBlock, validator, verifySeal, h.BroadcastBlock, heighter, currentThresholdS, currentS, currentDifficulty, h.removePeer, h.core.IsBlockHashABadHash)

// Only initialize the Tx fetcher in zone
if nodeCtx == common.ZONE_CTX && h.core.ProcessingState() {
Expand Down

0 comments on commit de97793

Please sign in to comment.