vote: check consensus key match vote key before voting (#1858)
This commit is contained in:
parent
a0cb4d0377
commit
6af6162297
@ -155,5 +155,5 @@ type PoSA interface {
|
||||
GetJustifiedNumberAndHash(chain ChainHeaderReader, header *types.Header) (uint64, common.Hash, error)
|
||||
GetFinalizedHeader(chain ChainHeaderReader, header *types.Header) *types.Header
|
||||
VerifyVote(chain ChainHeaderReader, vote *types.VoteEnvelope) error
|
||||
IsActiveValidatorAt(chain ChainHeaderReader, header *types.Header) bool
|
||||
IsActiveValidatorAt(chain ChainHeaderReader, header *types.Header, checkVoteKeyFn func(bLSPublicKey *types.BLSPublicKey) bool) bool
|
||||
}
|
||||
|
@ -1205,7 +1205,7 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
|
||||
return blk, receipts, nil
|
||||
}
|
||||
|
||||
func (p *Parlia) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header) bool {
|
||||
func (p *Parlia) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header, checkVoteKeyFn func(bLSPublicKey *types.BLSPublicKey) bool) bool {
|
||||
number := header.Number.Uint64()
|
||||
snap, err := p.snapshot(chain, number-1, header.ParentHash, nil)
|
||||
if err != nil {
|
||||
@ -1213,8 +1213,9 @@ func (p *Parlia) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *
|
||||
return false
|
||||
}
|
||||
validators := snap.Validators
|
||||
_, ok := validators[p.val]
|
||||
return ok
|
||||
validatorInfo, ok := validators[p.val]
|
||||
|
||||
return ok && (checkVoteKeyFn == nil || (validatorInfo != nil && checkVoteKeyFn(&validatorInfo.VoteAddress)))
|
||||
}
|
||||
|
||||
// VerifyVote will verify: 1. If the vote comes from valid validators 2. If the vote's sourceNumber and sourceHash are correct
|
||||
|
@ -1,7 +1,9 @@
|
||||
package vote
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
@ -97,6 +99,7 @@ func (voteManager *VoteManager) loop() {
|
||||
dlEventCh := events.Chan()
|
||||
|
||||
startVote := true
|
||||
var once sync.Once
|
||||
for {
|
||||
select {
|
||||
case ev := <-dlEventCh:
|
||||
@ -132,11 +135,22 @@ func (voteManager *VoteManager) loop() {
|
||||
|
||||
curHead := cHead.Block.Header()
|
||||
// Check if cur validator is within the validatorSet at curHead
|
||||
if !voteManager.engine.IsActiveValidatorAt(voteManager.chain, curHead) {
|
||||
if !voteManager.engine.IsActiveValidatorAt(voteManager.chain, curHead,
|
||||
func(bLSPublicKey *types.BLSPublicKey) bool {
|
||||
return bytes.Equal(voteManager.signer.PubKey[:], bLSPublicKey[:])
|
||||
}) {
|
||||
log.Debug("cur validator is not within the validatorSet at curHead")
|
||||
continue
|
||||
}
|
||||
|
||||
// Add VoteKey to `miner-info`
|
||||
once.Do(func() {
|
||||
minerInfo := metrics.Get("miner-info")
|
||||
if minerInfo != nil {
|
||||
minerInfo.(metrics.Label).Value()["VoteKey"] = common.Bytes2Hex(voteManager.signer.PubKey[:])
|
||||
}
|
||||
})
|
||||
|
||||
// Vote for curBlockHeader block.
|
||||
vote := &types.VoteData{
|
||||
TargetNumber: curHead.Number.Uint64(),
|
||||
@ -174,7 +188,7 @@ func (voteManager *VoteManager) loop() {
|
||||
}
|
||||
case event := <-voteManager.syncVoteCh:
|
||||
voteMessage := event.Vote
|
||||
if voteManager.eth.IsMining() || !voteManager.signer.UsingKey(&voteMessage.VoteAddress) {
|
||||
if voteManager.eth.IsMining() || !bytes.Equal(voteManager.signer.PubKey[:], voteMessage.VoteAddress[:]) {
|
||||
continue
|
||||
}
|
||||
if err := voteManager.journal.WriteVote(voteMessage); err != nil {
|
||||
|
@ -99,11 +99,11 @@ func (m *mockInvalidPOSA) VerifyVote(chain consensus.ChainHeaderReader, vote *ty
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockPOSA) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header) bool {
|
||||
func (m *mockPOSA) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header, checkVoteKeyFn func(bLSPublicKey *types.BLSPublicKey) bool) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *mockInvalidPOSA) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header) bool {
|
||||
func (m *mockInvalidPOSA) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header, checkVoteKeyFn func(bLSPublicKey *types.BLSPublicKey) bool) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package vote
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -28,7 +27,7 @@ var votesSigningErrorCounter = metrics.NewRegisteredCounter("votesSigner/error",
|
||||
|
||||
type VoteSigner struct {
|
||||
km *keymanager.IKeymanager
|
||||
pubKey [48]byte
|
||||
PubKey [48]byte
|
||||
}
|
||||
|
||||
func NewVoteSigner(blsPasswordPath, blsWalletPath string) (*VoteSigner, error) {
|
||||
@ -39,7 +38,7 @@ func NewVoteSigner(blsPasswordPath, blsWalletPath string) (*VoteSigner, error) {
|
||||
}
|
||||
if !dirExists {
|
||||
log.Error("BLS wallet did not exists.")
|
||||
return nil, fmt.Errorf("BLS wallet did not exists.")
|
||||
return nil, fmt.Errorf("BLS wallet did not exists")
|
||||
}
|
||||
|
||||
walletPassword, err := ioutil.ReadFile(blsPasswordPath)
|
||||
@ -76,13 +75,13 @@ func NewVoteSigner(blsPasswordPath, blsWalletPath string) (*VoteSigner, error) {
|
||||
|
||||
return &VoteSigner{
|
||||
km: &km,
|
||||
pubKey: pubKeys[0],
|
||||
PubKey: pubKeys[0],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (signer *VoteSigner) SignVote(vote *types.VoteEnvelope) error {
|
||||
// Sign the vote, fetch the first pubKey as validator's bls public key.
|
||||
pubKey := signer.pubKey
|
||||
pubKey := signer.PubKey
|
||||
blsPubKey, err := bls.PublicKeyFromBytes(pubKey[:])
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "convert public key from bytes to bls failed")
|
||||
@ -105,7 +104,3 @@ func (signer *VoteSigner) SignVote(vote *types.VoteEnvelope) error {
|
||||
copy(vote.Signature[:], signature.Marshal()[:])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (signer *VoteSigner) UsingKey(bLSPublicKey *types.BLSPublicKey) bool {
|
||||
return bytes.Equal(signer.pubKey[:], bLSPublicKey[:])
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/internal/shutdowncheck"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/miner"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
@ -568,8 +569,12 @@ func (s *Ethereum) StartMining(threads int) error {
|
||||
log.Error("Etherbase account unavailable locally", "err", err)
|
||||
return fmt.Errorf("signer missing: %v", err)
|
||||
}
|
||||
|
||||
parlia.Authorize(eb, wallet.SignData, wallet.SignTx)
|
||||
|
||||
minerInfo := metrics.Get("miner-info")
|
||||
if minerInfo != nil {
|
||||
minerInfo.(metrics.Label).Value()["Etherbase"] = eb.String()
|
||||
}
|
||||
}
|
||||
// If mining is started, we can disable the transaction rejection mechanism
|
||||
// introduced to speed sync times.
|
||||
|
Loading…
Reference in New Issue
Block a user