mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
verify validators info at checkpoint block
This commit is contained in:
parent
7ebdbeed64
commit
161053b345
2 changed files with 53 additions and 27 deletions
|
|
@ -35,4 +35,5 @@ var (
|
||||||
|
|
||||||
ErrNotXDPoS = errors.New("XDPoS not found in config")
|
ErrNotXDPoS = errors.New("XDPoS not found in config")
|
||||||
|
|
||||||
|
ErrNotFoundM1 = errors.New("list M1 not found ")
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"bytes"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
@ -211,36 +212,13 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
|
|
||||||
// Hook will process when preparing block.
|
// Hook will process when preparing block.
|
||||||
c.HookPrepare = func(header *types.Header, signers []common.Address) error {
|
c.HookPrepare = func(header *types.Header, signers []common.Address) error {
|
||||||
client, err := eth.blockchain.GetClient()
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail to connect IPC client for penalty.", "error", err)
|
|
||||||
}
|
|
||||||
number := header.Number.Int64()
|
number := header.Number.Int64()
|
||||||
// Check m2 exists on chaindb.
|
|
||||||
// Get secrets and opening at epoc block checkpoint.
|
|
||||||
if number > 0 && number%common.EpocBlockRandomize == 0 {
|
if number > 0 && number%common.EpocBlockRandomize == 0 {
|
||||||
var candidates []int64
|
validators, err := GetValidators(eth.blockchain, signers)
|
||||||
lenSigners := int64(len(signers))
|
if err != nil {
|
||||||
|
return err
|
||||||
if lenSigners > 0 {
|
|
||||||
for _, addr := range signers {
|
|
||||||
random, err := contracts.GetRandomizeFromContract(client, addr)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail to get random m2 from contract.", "error", err)
|
|
||||||
}
|
|
||||||
candidates = append(candidates, random)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get randomize m2 list.
|
|
||||||
m2, err := contracts.GenM2FromRandomize(candidates, lenSigners)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Can not get m2 from randomize SC", "error", err)
|
|
||||||
}
|
|
||||||
if len(m2) > 0 {
|
|
||||||
header.Validators = contracts.BuildValidatorFromM2(m2)
|
|
||||||
log.Debug("New set Validators", "m2", m2, "number", header.Number.Uint64())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
header.Validators = validators
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -330,6 +308,19 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
c.VerifyValidators = func(header *types.Header, signers []common.Address) error {
|
||||||
|
number := header.Number.Int64()
|
||||||
|
if number > 0 && number%common.EpocBlockRandomize == 0 {
|
||||||
|
validators, err := GetValidators(eth.blockchain, signers)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !bytes.Equal(header.Validators, validators) {
|
||||||
|
return XDPoS.ErrInvalidCheckpointValidators
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return eth, nil
|
return eth, nil
|
||||||
|
|
@ -605,4 +596,38 @@ func (s *Ethereum) Stop() error {
|
||||||
close(s.shutdownChan)
|
close(s.shutdownChan)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetValidators(bc *core.BlockChain, masternodes []common.Address) ([]byte, error) {
|
||||||
|
if bc.Config().XDPoS == nil {
|
||||||
|
return nil, core.ErrNotXDPoS
|
||||||
|
}
|
||||||
|
client, err := bc.GetClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Check m2 exists on chaindb.
|
||||||
|
// Get secrets and opening at epoc block checkpoint.
|
||||||
|
|
||||||
|
var candidates []int64
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
lenSigners := int64(len(masternodes))
|
||||||
|
if lenSigners > 0 {
|
||||||
|
for _, addr := range masternodes {
|
||||||
|
random, err := contracts.GetRandomizeFromContract(client, addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
candidates = append(candidates, random)
|
||||||
|
}
|
||||||
|
// Get randomize m2 list.
|
||||||
|
m2, err := contracts.GenM2FromRandomize(candidates, lenSigners)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return contracts.BuildValidatorFromM2(m2), nil
|
||||||
|
}
|
||||||
|
return nil, core.ErrNotFoundM1
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue