revert HookValidator, HookPenalty, HookVerifyMNs; only keep HookReward go the new way

This commit is contained in:
Tuna 2019-01-10 11:42:23 +07:00
parent 804debede4
commit 4455673db4
3 changed files with 68 additions and 21 deletions

View file

@ -225,9 +225,9 @@ type Posv struct {
lock sync.RWMutex // Protects the signer fields
HookReward func(state *state.StateDB, chain consensus.ChainReader, header *types.Header) (error, map[string]interface{})
HookPenalty func(state *state.StateDB, chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
HookValidator func(state *state.StateDB, header *types.Header, signers []common.Address) ([]byte, error)
HookVerifyMNs func(state *state.StateDB, header *types.Header, signers []common.Address) error
HookPenalty func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
HookValidator func(header *types.Header, signers []common.Address) ([]byte, error)
HookVerifyMNs func(header *types.Header, signers []common.Address) error
}
// New creates a PoSV proof-of-stake-voting consensus engine with the initial
@ -392,7 +392,7 @@ func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, state *state.S
if number%c.config.Epoch == 0 {
penPenalties := []common.Address{}
if c.HookPenalty != nil {
penPenalties, err = c.HookPenalty(state, chain, number)
penPenalties, err = c.HookPenalty(chain, number)
if err != nil {
return err
}
@ -417,7 +417,7 @@ func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, state *state.S
return errInvalidCheckpointSigners
}
if c.HookVerifyMNs != nil {
err := c.HookVerifyMNs(state, header, signers)
err := c.HookVerifyMNs(header, signers)
if err != nil {
return err
}
@ -776,7 +776,7 @@ func (c *Posv) Prepare(chain consensus.ChainReader, state *state.StateDB, header
masternodes := snap.GetSigners()
if number >= c.config.Epoch && number%c.config.Epoch == 0 {
if c.HookPenalty != nil {
penMasternodes, err := c.HookPenalty(state, chain, number)
penMasternodes, err := c.HookPenalty(chain, number)
if err != nil {
return err
}
@ -799,7 +799,7 @@ func (c *Posv) Prepare(chain consensus.ChainReader, state *state.StateDB, header
header.Extra = append(header.Extra, masternode[:]...)
}
if c.HookValidator != nil {
validators, err := c.HookValidator(state, header, masternodes)
validators, err := c.HookValidator(header, masternodes)
if err != nil {
return err
}

View file

@ -41,6 +41,9 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
)
const (
@ -199,10 +202,39 @@ func GetSignersFromContract(state *state.StateDB, block *types.Block) ([]common.
return GetSigners(state, block), nil
}
// Get signers signed for blockNumber from blockSigner contract.
func GetSignersFromContract1(addrBlockSigner common.Address, client bind.ContractBackend, blockHash common.Hash) ([]common.Address, error) {
blockSigner, err := contract.NewBlockSigner(addrBlockSigner, client)
if err != nil {
log.Error("Fail get instance of blockSigner", "error", err)
return nil, err
}
opts := new(bind.CallOpts)
addrs, err := blockSigner.GetSigners(opts, blockHash)
if err != nil {
log.Error("Fail get block signers", "error", err)
return nil, err
}
return addrs, nil
}
// Get random from randomize contract.
func GetRandomizeFromContract(state *state.StateDB, addrMasternode common.Address) (int64, error) {
secrets := GetSecret(state, addrMasternode)
opening := GetOpening(state, addrMasternode)
func GetRandomizeFromContract(client bind.ContractBackend, addrMasternode common.Address) (int64, error) {
randomize, err := randomizeContract.NewTomoRandomize(common.HexToAddress(common.RandomizeSMC), client)
if err != nil {
log.Error("Fail to get instance of randomize", "error", err)
}
opts := new(bind.CallOpts)
secrets, err := randomize.GetSecret(opts, addrMasternode)
if err != nil {
log.Error("Fail get secrets from randomize", "error", err)
}
opening, err := randomize.GetOpening(opts, addrMasternode)
if err != nil {
log.Error("Fail get opening from randomize", "error", err)
}
return DecryptRandomizeFromSecretsAndOpening(secrets, opening)
}

View file

@ -230,9 +230,9 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
eth.protocolManager.fetcher.SetAppendM2HeaderHook(appendM2HeaderHook)
// Hook prepares validators M2 for the current epoch at checkpoint block
c.HookValidator = func(state *state.StateDB, header *types.Header, signers []common.Address) ([]byte, error) {
c.HookValidator = func(header *types.Header, signers []common.Address) ([]byte, error) {
start := time.Now()
validators, err := GetValidators(state, signers)
validators, err := GetValidators(eth.blockchain, signers)
if err != nil {
return []byte{}, err
}
@ -242,20 +242,23 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
// Hook scans for bad masternodes and decide to penalty them
c.HookPenalty = func(state *state.StateDB, chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error) {
c.HookPenalty = func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error) {
client, err := eth.blockchain.GetClient()
if err != nil {
return nil, err
}
prevEpoc := blockNumberEpoc - chain.Config().Posv.Epoch
if prevEpoc >= 0 {
start := time.Now()
prevHeader := chain.GetHeaderByNumber(prevEpoc)
penSigners := c.GetMasternodes(chain, prevHeader)
if len(penSigners) > 0 {
blockSignerAddr := common.HexToAddress(common.BlockSigners)
// Loop for each block to check missing sign.
for i := prevEpoc; i < blockNumberEpoc; i++ {
bHeader := chain.GetHeaderByNumber(i)
bHash := bHeader.Hash()
block := chain.GetBlock(bHash, i)
blockHeader := chain.GetHeaderByNumber(i)
if len(penSigners) > 0 {
signedMasternodes, err := contracts.GetSignersFromContract(state, block)
signedMasternodes, err := contracts.GetSignersFromContract1(blockSignerAddr, client, blockHeader.Hash())
if err != nil {
return nil, err
}
@ -327,11 +330,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
// Hook verifies masternodes set
c.HookVerifyMNs = func(state *state.StateDB, header *types.Header, signers []common.Address) error {
c.HookVerifyMNs = func(header *types.Header, signers []common.Address) error {
number := header.Number.Int64()
if number > 0 && number%common.EpocBlockRandomize == 0 {
start := time.Now()
validators, err := GetValidators(state, signers)
validators, err := GetValidators(eth.blockchain, signers)
log.Debug("Time Calculated HookVerifyMNs ", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start)))
if err != nil {
return err
@ -342,6 +345,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
return nil
}
eth.txPool.IsMasterNode = func(address common.Address) bool {
currentHeader := eth.blockchain.CurrentHeader()
snap, err := c.GetSnapshot(eth.blockchain, currentHeader)
@ -631,14 +635,25 @@ func (s *Ethereum) Stop() error {
return nil
}
func GetValidators(state *state.StateDB, masternodes []common.Address) ([]byte, error) {
func GetValidators(bc *core.BlockChain, masternodes []common.Address) ([]byte, error) {
if bc.Config().Posv == nil {
return nil, core.ErrNotPoSV
}
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(state, addr)
random, err := contracts.GetRandomizeFromContract(client, addr)
if err != nil {
return nil, err
}