Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove istanbul validator and istanbul snapshot #190

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2150,18 +2150,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
return i, events, coalescedLogs, err
}
}

// update governance CurrentSet if it is at an epoch block
if bc.engine.CreateSnapshot(bc, block.NumberU64(), block.Hash(), nil) != nil {
return i, events, coalescedLogs, err
}

// update governance parameters
if istanbul, ok := bc.engine.(consensus.Istanbul); ok {
if err = istanbul.UpdateParam(block.NumberU64()); err != nil {
return i, events, coalescedLogs, err
}
}
}
// Append a single chain head event if we've progressed the chain
if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
Expand Down
13 changes: 1 addition & 12 deletions consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,17 +375,6 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainReader, header *type
return c.verifySeal(chain, header, parents)
}

// CreateSnapshot does not return a snapshot but creates a new snapshot if not exists at a given point in time
func (c *Clique) CreateSnapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) error {
_, err := c.snapshot(chain, number, hash, parents)
return err
}

// GetKaiaHeadersForSnapshotApply is not used for Clique engine
func (c *Clique) GetKaiaHeadersForSnapshotApply(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) ([]*types.Header, error) {
return nil, nil
}

// snapshot retrieves the authorization snapshot at a given point in time.
func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) {
// Search for a snapshot in memory or on disk for checkpoints
Expand Down Expand Up @@ -593,7 +582,7 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro
return nil
}

func (c *Clique) InitSnapshot() {}
func (c *Clique) PurgeCache() {}

func (c *Clique) Initialize(chain consensus.ChainReader, header *types.Header, state *state.StateDB) {
}
Expand Down
17 changes: 3 additions & 14 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ type ChainReader interface {
// GetBlock retrieves a block from the database by hash and number.
GetBlock(hash common.Hash, number uint64) *types.Block

// State() retrieves statedb
// State retrieves statedb
State() (*state.StateDB, error)

// StateAt() retrieves statedb on a particular point in time
// StateAt retrieves statedb on a particular point in time
StateAt(root common.Hash) (*state.StateDB, error)
}

Expand Down Expand Up @@ -128,18 +128,10 @@ type Engine interface {
// Protocol returns the protocol for this consensus
Protocol() Protocol

// TODO-kaiax-valset: delete CreateSnapshot which is called after post insert block
// e.g. insertChain, worker.wait, New()
// CreateSnapshot does not return a snapshot but creates a new snapshot if not exists at a given point in time.
CreateSnapshot(chain ChainReader, number uint64, hash common.Hash, parents []*types.Header) error

// GetKaiaHeadersForSnapshotApply returns the headers need to be applied to calculate snapshot for the given block number.
GetKaiaHeadersForSnapshotApply(chain ChainReader, number uint64, hash common.Hash, parents []*types.Header) ([]*types.Header, error)

// GetConsensusInfo returns consensus information regarding the given block number.
GetConsensusInfo(block *types.Block) (ConsensusInfo, error)

InitSnapshot()
PurgeCache()
}

// PoW is a consensus engine based on proof-of-work.
Expand Down Expand Up @@ -178,9 +170,6 @@ type Istanbul interface {
// SetChain sets chain of the Istanbul backend
SetChain(chain ChainReader)

// UpdateParam updates the governance parameter
UpdateParam(num uint64) error

RegisterKaiaxModules(mGov gov.GovModule, mStaking staking.StakingModule, mValset valset.ValsetModule)

kaiax.ConsensusModuleHost
Expand Down
12 changes: 1 addition & 11 deletions consensus/gxhash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,6 @@ func (gxhash *Gxhash) PreprocessHeaderVerification(headers []*types.Header) (cha
panic("this method is not used for PoW engine")
}

// CreateSnapshot is not used for PoW engine.
func (gxhash *Gxhash) CreateSnapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) error {
return nil
}

// GetKaiaHeadersForSnapshotApply is not used for PoW engine.
func (gxhash *Gxhash) GetKaiaHeadersForSnapshotApply(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) ([]*types.Header, error) {
return nil, nil
}

// GetConsensusInfo is not used for PoW engine.
func (gxhash *Gxhash) GetConsensusInfo(block *types.Block) (consensus.ConsensusInfo, error) {
return consensus.ConsensusInfo{}, nil
Expand Down Expand Up @@ -350,7 +340,7 @@ func calcBlockScoreHomestead(time uint64, parent *types.Header) *big.Int {
return x
}

func (gxhash *Gxhash) InitSnapshot() {}
func (gxhash *Gxhash) PurgeCache() {}

// VerifySeal implements consensus.Engine, checking whether the given block satisfies
// the PoW blockscore requirements.
Expand Down
60 changes: 0 additions & 60 deletions consensus/istanbul/backend/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,27 +47,6 @@ type API struct {
istanbul *backend
}

// GetSnapshot retrieves the state snapshot at a given block.
// TODO-kaia-valset: consider deprecation of GetSnapshot
func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) {
// Retrieve the requested block number (or current if none requested)
header, err := headerByRpcNumber(api.chain, number)
if err != nil {
return nil, err
}
return checkStatesAndGetSnapshot(api.chain, api.istanbul, header.Number.Uint64(), header.Hash())
}

// GetSnapshotAtHash retrieves the state snapshot at a given block.
// TODO-kaia-valset: consider deprecation of GetSnapshotAtHash
func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) {
header := api.chain.GetHeaderByHash(hash)
if header == nil {
return nil, errUnknownBlock
}
return checkStatesAndGetSnapshot(api.chain, api.istanbul, header.Number.Uint64(), header.Hash())
}

// GetValidators retrieves the list of qualified validators with the given block number.
func (api *API) GetValidators(number *rpc.BlockNumber) ([]common.Address, error) {
header, err := headerByRpcNumber(api.chain, number)
Expand Down Expand Up @@ -286,13 +265,6 @@ func (api *APIExtension) GetBlockWithConsensusInfoByNumber(number *rpc.BlockNumb
}
blockHash := block.Hash()

if blockNumber > 0 {
err := checkStatesForSnapshot(api.chain, api.istanbul, blockNumber-1, block.ParentHash())
if err != nil {
return nil, err
}
}

cInfo, err := api.istanbul.GetConsensusInfo(block)
if err != nil {
logger.Error("Getting the proposer and validators failed.", "blockHash", blockHash, "err", err)
Expand Down Expand Up @@ -369,13 +341,6 @@ func (api *APIExtension) GetBlockWithConsensusInfoByHash(blockHash common.Hash)
return nil, fmt.Errorf("the block does not exist (block hash: %s)", blockHash.String())
}

if block.NumberU64() > 0 {
err := checkStatesForSnapshot(api.chain, api.istanbul, block.NumberU64()-1, block.ParentHash())
if err != nil {
return nil, err
}
}

cInfo, err := api.istanbul.GetConsensusInfo(block)
if err != nil {
logger.Error("Getting the proposer and validators failed.", "blockHash", blockHash, "err", err)
Expand Down Expand Up @@ -489,28 +454,3 @@ func headerByRpcNumber(chain consensus.ChainReader, number *rpc.BlockNumber) (*t
}
return header, nil
}

// Checks the all states for snapshot creation at the given block number
func checkStatesForSnapshot(chain consensus.ChainReader, istBackend *backend, number uint64, hash common.Hash) error {
headers, err := istBackend.GetKaiaHeadersForSnapshotApply(chain, number, hash, nil)
if err != nil {
return err
}

for _, header := range headers {
if _, err := chain.StateAt(header.Root); err != nil {
return err
}
}
return nil
}

// Checks the all states for snapshot creation at the given block number and returns the snapshot if all states exist
func checkStatesAndGetSnapshot(chain consensus.ChainReader, istBackend *backend, number uint64, hash common.Hash) (*Snapshot, error) {
err := checkStatesForSnapshot(chain, istBackend, number, hash)
if err != nil {
return nil, err
}

return istBackend.snapshot(chain, number, hash, nil, false)
}
97 changes: 66 additions & 31 deletions consensus/istanbul/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import (
"github.com/kaiachain/kaia/consensus"
"github.com/kaiachain/kaia/consensus/istanbul"
istanbulCore "github.com/kaiachain/kaia/consensus/istanbul/core"
"github.com/kaiachain/kaia/consensus/istanbul/validator"
"github.com/kaiachain/kaia/crypto"
"github.com/kaiachain/kaia/crypto/bls"
"github.com/kaiachain/kaia/event"
Expand Down Expand Up @@ -67,7 +66,6 @@ type BackendOpts struct {
}

func New(opts *BackendOpts) consensus.Istanbul {
recents, _ := lru.NewARC(inmemorySnapshots)
recentMessages, _ := lru.NewARC(inmemoryPeers)
knownMessages, _ := lru.NewARC(inmemoryMessages)
backend := &backend{
Expand All @@ -79,7 +77,6 @@ func New(opts *BackendOpts) consensus.Istanbul {
logger: logger.NewWith(),
db: opts.DB,
commitCh: make(chan *types.Result, 1),
recents: recents,
candidates: make(map[common.Address]bool),
coreStarted: false,
recentMessages: recentMessages,
Expand Down Expand Up @@ -127,8 +124,6 @@ type backend struct {
candidates map[common.Address]bool
// Protects the signer fields
candidatesLock sync.RWMutex
// Snapshots for recent block to speed up reorgs
recents *lru.ARCCache // TODO-kaiax: Remove snapshot cache

// event subscription for ChainHeadEvent event
broadcaster consensus.Broadcaster
Expand Down Expand Up @@ -383,32 +378,6 @@ func (sb *backend) HasPropsal(hash common.Hash, number *big.Int) bool {
return sb.chain.GetHeader(hash, number.Uint64()) != nil
}

// ParentValidators implements istanbul.Backend.GetParentValidators
func (sb *backend) ParentValidators(proposal istanbul.Proposal) istanbul.ValidatorSet {
if block, ok := proposal.(*types.Block); ok {
return sb.getValidators(block.Number().Uint64()-1, block.ParentHash())
}

// TODO-Kaia-Governance The following return case should not be called. Refactor it to error handling.
return validator.NewValidatorSet(nil, nil,
istanbul.ProposerPolicy(sb.chain.Config().Istanbul.ProposerPolicy),
sb.chain.Config().Istanbul.SubGroupSize,
sb.chain)
}

func (sb *backend) getValidators(number uint64, hash common.Hash) istanbul.ValidatorSet {
snap, err := sb.snapshot(sb.chain, number, hash, nil, false)
if err != nil {
logger.Error("Snapshot not found.", "err", err)
// TODO-Kaia-Governance The following return case should not be called. Refactor it to error handling.
return validator.NewValidatorSet(nil, nil,
istanbul.ProposerPolicy(sb.chain.Config().Istanbul.ProposerPolicy),
sb.chain.Config().Istanbul.SubGroupSize,
sb.chain)
}
return snap.ValSet
}

func (sb *backend) LastProposal() (istanbul.Proposal, common.Address) {
block := sb.currentBlock()

Expand All @@ -432,3 +401,69 @@ func (sb *backend) HasBadProposal(hash common.Hash) bool {
}
return sb.hasBadBlock(hash)
}

func (sb *backend) GetValidatorSet(num uint64) (*istanbul.BlockValSet, error) {
council, err := sb.valsetModule.GetCouncil(num)
if err != nil {
return nil, err
}

demoted, err := sb.valsetModule.GetDemotedValidators(num)
if err != nil {
return nil, err
}

return istanbul.NewBlockValSet(council, demoted), nil
}

func (sb *backend) GetCommitteeState(num uint64) (*istanbul.RoundCommitteeState, error) {
header := sb.chain.GetHeaderByNumber(num)
if header == nil {
return nil, errUnknownBlock
}

return sb.GetCommitteeStateByRound(num, uint64(header.Round()))
}

func (sb *backend) GetCommitteeStateByRound(num uint64, round uint64) (*istanbul.RoundCommitteeState, error) {
blockValSet, err := sb.GetValidatorSet(num)
if err != nil {
return nil, err
}

committee, err := sb.valsetModule.GetCommittee(num, round)
if err != nil {
return nil, err
}

proposer, err := sb.valsetModule.GetProposer(num, round)
if err != nil {
return nil, err
}

committeeSize := sb.govModule.GetParamSet(num).CommitteeSize
return istanbul.NewRoundCommitteeState(blockValSet, committeeSize, committee, proposer), nil
}

// GetProposer implements istanbul.Backend.GetProposer
func (sb *backend) GetProposer(number uint64) common.Address {
if h := sb.chain.GetHeaderByNumber(number); h != nil {
a, _ := sb.Author(h)
return a
}
return common.Address{}
}

func (sb *backend) GetRewardAddress(num uint64, nodeId common.Address) common.Address {
sInfo, err := sb.stakingModule.GetStakingInfo(num)
if err != nil {
return common.Address{}
}

for idx, id := range sInfo.NodeIds {
if id == nodeId {
return sInfo.RewardAddrs[idx]
}
}
return common.Address{}
}
20 changes: 2 additions & 18 deletions consensus/istanbul/backend/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"bytes"
"crypto/ecdsa"
"math/big"
"strings"
"testing"
"time"

Expand All @@ -41,25 +40,10 @@ import (
)

var (
testCommitteeSize = uint64(21)
testSigningData = []byte("dummy data")
maxBlockNum = int64(100)
testSigningData = []byte("dummy data")
maxBlockNum = int64(100)
)

type keys []*ecdsa.PrivateKey

func (slice keys) Len() int {
return len(slice)
}

func (slice keys) Less(i, j int) bool {
return strings.Compare(crypto.PubkeyToAddress(slice[i].PublicKey).String(), crypto.PubkeyToAddress(slice[j].PublicKey).String()) < 0
}

func (slice keys) Swap(i, j int) {
slice[i], slice[j] = slice[j], slice[i]
}

func getTestConfig() *params.ChainConfig {
config := params.TestChainConfig.Copy()
config.Governance = params.GetDefaultGovernanceConfig()
Expand Down
Loading
Loading