From 4455673db45271c0e79e35f8f85388849b52f972 Mon Sep 17 00:00:00 2001 From: Tuna Date: Thu, 10 Jan 2019 11:42:23 +0700 Subject: [PATCH] revert HookValidator, HookPenalty, HookVerifyMNs; only keep HookReward go the new way --- consensus/posv/posv.go | 14 +++++++------- contracts/utils.go | 38 +++++++++++++++++++++++++++++++++++--- eth/backend.go | 37 ++++++++++++++++++++++++++----------- 3 files changed, 68 insertions(+), 21 deletions(-) diff --git a/consensus/posv/posv.go b/consensus/posv/posv.go index c92371c846..912eb146d8 100644 --- a/consensus/posv/posv.go +++ b/consensus/posv/posv.go @@ -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 } diff --git a/contracts/utils.go b/contracts/utils.go index e04418df5e..00f8bac0ac 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -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) } diff --git a/eth/backend.go b/eth/backend.go index dae51e9582..f5a8c9b309 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -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 }