Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions consensus/XDPoS/engines/engine_v1/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -708,9 +708,9 @@ func (x *XDPoS_v1) Prepare(chain consensus.ChainReader, header *types.Header) er
if err != nil {
return err
}
if number%x.config.Epoch != 0 {
x.lock.RLock()

x.lock.RLock()
if number%x.config.Epoch != 0 {
// Gather all the proposals that make sense voting on
addresses := make([]common.Address, 0, len(x.proposals))
for address, authorize := range x.proposals {
Expand All @@ -727,14 +727,16 @@ func (x *XDPoS_v1) Prepare(chain consensus.ChainReader, header *types.Header) er
copy(header.Nonce[:], utils.NonceDropVote)
}
}
x.lock.RUnlock()
}
signer := x.signer
x.lock.RUnlock()

parent := chain.GetHeader(header.ParentHash, number-1)
if parent == nil {
return consensus.ErrUnknownAncestor
}
// Set the correct difficulty
header.Difficulty = x.calcDifficulty(chain, parent, x.signer)
header.Difficulty = x.calcDifficulty(chain, parent, signer)
Copy link
Collaborator

@gzliudan gzliudan Mar 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this version ?

	if number%x.config.Epoch != 0 {
		// Gather all the proposals that make sense voting on
		addresses := make([]common.Address, 0, len(x.proposals))
		for address, authorize := range x.proposals {
			if snap.validVote(address, authorize) {
				addresses = append(addresses, address)
			}
		}
		// If there's pending proposals, cast a vote on them
		if len(addresses) > 0 {
			header.Coinbase = addresses[rand.Intn(len(addresses))]
			if x.proposals[header.Coinbase] {
				copy(header.Nonce[:], utils.NonceAuthVote)
			} else {
				copy(header.Nonce[:], utils.NonceDropVote)
			}
		}
	}

	parent := chain.GetHeader(header.ParentHash, number-1)
	if parent == nil {
		return consensus.ErrUnknownAncestor
	}

	// Set the correct difficulty
	x.lock.RLock()
	signer := x.signer
	x.lock.RUnlock()
	header.Difficulty = x.calcDifficulty(chain, parent, signer)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The locks are already in the code before, i'm not sure what values it's locking, probably x.proposals. I prefer not to change the original logic as it would involve unnecessary riskks

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can refer the struct and other codes:

lock   sync.RWMutex    // Protects the signer fields

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure i understand what you mean above.
What's i'm referring to is that the lock is already within the original if statement.
image

I do not intend to change the behaviour of the original code hence move the signer := x.signer right before the Runlock in the original code. This would be the smallest change that would be required to achieve the same goal

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lock field protects signer field.

log.Debug("CalcDifficulty ", "number", header.Number, "difficulty", header.Difficulty)
// Ensure the extra data has all it's components
if len(header.Extra) < utils.ExtraVanity {
Expand Down Expand Up @@ -956,7 +958,10 @@ func (x *XDPoS_v1) Seal(chain consensus.ChainReader, block *types.Block, stop <-
// that a new block should have based on the previous blocks in the chain and the
// current signer.
func (x *XDPoS_v1) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
return x.calcDifficulty(chain, parent, x.signer)
x.lock.Lock()
signer := x.signer
x.lock.Unlock()
return x.calcDifficulty(chain, parent, signer)
}

func (x *XDPoS_v1) calcDifficulty(chain consensus.ChainReader, parent *types.Header, signer common.Address) *big.Int {
Expand Down