diff --git a/consensus/posv/posv.go b/consensus/posv/posv.go index d571ffe554..40e1381845 100644 --- a/consensus/posv/posv.go +++ b/consensus/posv/posv.go @@ -211,7 +211,8 @@ type Posv struct { signFn clique.SignerFn // Signer function to authorize hashes with lock sync.RWMutex // Protects the signer fields - HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) error + HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) error + HookPrepare func(header *types.Header, signers []common.Address) error } // New creates a Posv proof-of-stake-voting consensus engine with the initial @@ -654,6 +655,12 @@ func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error if header.Time.Int64() < time.Now().Unix() { header.Time = big.NewInt(time.Now().Unix()) } + + if c.HookPrepare != nil { + signers := snap.signers() + c.HookPrepare(header, signers) + } + return nil } diff --git a/eth/backend.go b/eth/backend.go index 191d9aeaad..9499b7dea8 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -209,6 +209,42 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { } eth.protocolManager.fetcher.SetImportedHook(importedHook) + // Hook will process when preparing block. + 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() + // Check m2 exists on chaindb. + // Get secrets and opening at epoc block checkpoint. + if number > 0 && number%common.EpocBlockRandomize == 0 { + var candidates []int64 + lenSigners := int64(len(signers)) + + 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) + } + } + } + + return nil + } + // Hook reward for posv validator. c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) error { client, err := eth.blockchain.GetClient() @@ -252,39 +288,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { } } - // Check m2 exists on chaindb. - // Get secrets and opening at epoc block checkpoint. - if number > 0 && number%common.EpocBlockRandomize == 0 { - var candidates []int64 - // Get signers from snapshot. - snap, err := c.GetSnapshot(eth.blockchain, chain.CurrentHeader()) - if err != nil { - log.Error("Fail to get snapshot for get secret and opening.", "error", err) - return err - } - signers := snap.Signers - lenSigners := int64(len(signers)) - - 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) - } - } - } - return nil } }