mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 01:43:47 +00:00
consensus/istanbul: common Istanbul interfaces and types
This commit is contained in:
parent
94ec62c544
commit
d9b440a0de
8 changed files with 493 additions and 4 deletions
73
consensus/istanbul/backend.go
Normal file
73
consensus/istanbul/backend.go
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
// Copyright 2017 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package istanbul
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Backend provides application specific functions for Istanbul core
|
||||||
|
type Backend interface {
|
||||||
|
// Address returns the owner's address
|
||||||
|
Address() common.Address
|
||||||
|
|
||||||
|
// Validators returns the validator set
|
||||||
|
Validators(proposal Proposal) ValidatorSet
|
||||||
|
|
||||||
|
// EventMux returns the event mux in backend
|
||||||
|
EventMux() *event.TypeMux
|
||||||
|
|
||||||
|
// Broadcast sends a message to all validators (include self)
|
||||||
|
Broadcast(valSet ValidatorSet, payload []byte) error
|
||||||
|
|
||||||
|
// Gossip sends a message to all validators (exclude self)
|
||||||
|
Gossip(valSet ValidatorSet, payload []byte) error
|
||||||
|
|
||||||
|
// Commit delivers an approved proposal to backend.
|
||||||
|
// The delivered proposal will be put into blockchain.
|
||||||
|
Commit(proposal Proposal, seals [][]byte) error
|
||||||
|
|
||||||
|
// Verify verifies the proposal. If a consensus.ErrFutureBlock error is returned,
|
||||||
|
// the time difference of the proposal and current time is also returned.
|
||||||
|
Verify(Proposal) (time.Duration, error)
|
||||||
|
|
||||||
|
// Sign signs input data with the backend's private key
|
||||||
|
Sign([]byte) ([]byte, error)
|
||||||
|
|
||||||
|
// CheckSignature verifies the signature by checking if it's signed by
|
||||||
|
// the given validator
|
||||||
|
CheckSignature(data []byte, addr common.Address, sig []byte) error
|
||||||
|
|
||||||
|
// LastProposal retrieves latest committed proposal and the address of proposer
|
||||||
|
LastProposal() (Proposal, common.Address)
|
||||||
|
|
||||||
|
// HasPropsal checks if the combination of the given hash and height matches any existing blocks
|
||||||
|
HasPropsal(hash common.Hash, number *big.Int) bool
|
||||||
|
|
||||||
|
// GetProposer returns the proposer of the given block height
|
||||||
|
GetProposer(number uint64) common.Address
|
||||||
|
|
||||||
|
// ParentValidators returns the validator set of the given proposal's parent block
|
||||||
|
ParentValidators(proposal Proposal) ValidatorSet
|
||||||
|
|
||||||
|
// HasBadBlock returns whether the block with the hash is a bad block
|
||||||
|
HasBadProposal(hash common.Hash) bool
|
||||||
|
}
|
||||||
|
|
@ -24,17 +24,15 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
RequestTimeout uint64 `toml:",omitempty"` // The timeout for each Istanbul round in milliseconds. This timeout should be larger than BlockPauseTime.
|
RequestTimeout uint64 `toml:",omitempty"` // The timeout for each Istanbul round in milliseconds.
|
||||||
BlockPeriod uint64 `toml:",omitempty"` // Default minimum difference between two consecutive block's timestamps in second
|
BlockPeriod uint64 `toml:",omitempty"` // Default minimum difference between two consecutive block's timestamps in second
|
||||||
BlockPauseTime uint64 `toml:",omitempty"` // Pause time when zero tx in previous block, values should be larger than istanbul_block_period
|
ProposerPolicy ProposerPolicy `toml:",omitempty"` // The policy for proposer selection
|
||||||
ProposerPolicy ProposerPolicy `toml:",omitempty"` // The policy for proposer, the detail is not determined
|
|
||||||
Epoch uint64 `toml:",omitempty"` // The number of blocks after which to checkpoint and reset the pending votes
|
Epoch uint64 `toml:",omitempty"` // The number of blocks after which to checkpoint and reset the pending votes
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultConfig = &Config{
|
var DefaultConfig = &Config{
|
||||||
RequestTimeout: 10000,
|
RequestTimeout: 10000,
|
||||||
BlockPeriod: 1,
|
BlockPeriod: 1,
|
||||||
BlockPauseTime: 2,
|
|
||||||
ProposerPolicy: RoundRobin,
|
ProposerPolicy: RoundRobin,
|
||||||
Epoch: 30000,
|
Epoch: 30000,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
29
consensus/istanbul/errors.go
Normal file
29
consensus/istanbul/errors.go
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2017 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package istanbul
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrUnauthorizedAddress is returned when given address cannot be found in
|
||||||
|
// current validator set.
|
||||||
|
ErrUnauthorizedAddress = errors.New("unauthorized address")
|
||||||
|
// ErrStoppedEngine is returned if the engine is stopped
|
||||||
|
ErrStoppedEngine = errors.New("stopped engine")
|
||||||
|
// ErrStartedEngine is returned if the engine is already started
|
||||||
|
ErrStartedEngine = errors.New("started engine")
|
||||||
|
)
|
||||||
31
consensus/istanbul/events.go
Normal file
31
consensus/istanbul/events.go
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2017 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package istanbul
|
||||||
|
|
||||||
|
// RequestEvent is posted to propose a proposal
|
||||||
|
type RequestEvent struct {
|
||||||
|
Proposal Proposal
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageEvent is posted for Istanbul engine communication
|
||||||
|
type MessageEvent struct {
|
||||||
|
Payload []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// FinalCommittedEvent is posted when a proposal is committed
|
||||||
|
type FinalCommittedEvent struct {
|
||||||
|
}
|
||||||
147
consensus/istanbul/types.go
Normal file
147
consensus/istanbul/types.go
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
// Copyright 2017 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package istanbul
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Proposal supports retrieving height and serialized block to be used during Istanbul consensus.
|
||||||
|
type Proposal interface {
|
||||||
|
// Number retrieves the sequence number of this proposal.
|
||||||
|
Number() *big.Int
|
||||||
|
|
||||||
|
// Hash retrieves the hash of this proposal.
|
||||||
|
Hash() common.Hash
|
||||||
|
|
||||||
|
EncodeRLP(w io.Writer) error
|
||||||
|
|
||||||
|
DecodeRLP(s *rlp.Stream) error
|
||||||
|
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
Proposal Proposal
|
||||||
|
}
|
||||||
|
|
||||||
|
// View includes a round number and a sequence number.
|
||||||
|
// Sequence is the block number we'd like to commit.
|
||||||
|
// Each round has a number and is composed by 3 steps: preprepare, prepare and commit.
|
||||||
|
//
|
||||||
|
// If the given block is not accepted by validators, a round change will occur
|
||||||
|
// and the validators start a new round with round+1.
|
||||||
|
type View struct {
|
||||||
|
Round *big.Int
|
||||||
|
Sequence *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeRLP serializes b into the Ethereum RLP format.
|
||||||
|
func (v *View) EncodeRLP(w io.Writer) error {
|
||||||
|
return rlp.Encode(w, []interface{}{v.Round, v.Sequence})
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.
|
||||||
|
func (v *View) DecodeRLP(s *rlp.Stream) error {
|
||||||
|
var view struct {
|
||||||
|
Round *big.Int
|
||||||
|
Sequence *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Decode(&view); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.Round, v.Sequence = view.Round, view.Sequence
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) String() string {
|
||||||
|
return fmt.Sprintf("{Round: %d, Sequence: %d}", v.Round.Uint64(), v.Sequence.Uint64())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cmp compares v and y and returns:
|
||||||
|
// -1 if v < y
|
||||||
|
// 0 if v == y
|
||||||
|
// +1 if v > y
|
||||||
|
func (v *View) Cmp(y *View) int {
|
||||||
|
if v.Sequence.Cmp(y.Sequence) != 0 {
|
||||||
|
return v.Sequence.Cmp(y.Sequence)
|
||||||
|
}
|
||||||
|
if v.Round.Cmp(y.Round) != 0 {
|
||||||
|
return v.Round.Cmp(y.Round)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type Preprepare struct {
|
||||||
|
View *View
|
||||||
|
Proposal Proposal
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeRLP serializes b into the Ethereum RLP format.
|
||||||
|
func (b *Preprepare) EncodeRLP(w io.Writer) error {
|
||||||
|
return rlp.Encode(w, []interface{}{b.View, b.Proposal})
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.
|
||||||
|
func (b *Preprepare) DecodeRLP(s *rlp.Stream) error {
|
||||||
|
var preprepare struct {
|
||||||
|
View *View
|
||||||
|
Proposal *types.Block
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Decode(&preprepare); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.View, b.Proposal = preprepare.View, preprepare.Proposal
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Subject struct {
|
||||||
|
View *View
|
||||||
|
Digest common.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeRLP serializes b into the Ethereum RLP format.
|
||||||
|
func (b *Subject) EncodeRLP(w io.Writer) error {
|
||||||
|
return rlp.Encode(w, []interface{}{b.View, b.Digest})
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.
|
||||||
|
func (b *Subject) DecodeRLP(s *rlp.Stream) error {
|
||||||
|
var subject struct {
|
||||||
|
View *View
|
||||||
|
Digest common.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Decode(&subject); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.View, b.Digest = subject.View, subject.Digest
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Subject) String() string {
|
||||||
|
return fmt.Sprintf("{View: %v, Digest: %v}", b.View, b.Digest.String())
|
||||||
|
}
|
||||||
71
consensus/istanbul/types_test.go
Normal file
71
consensus/istanbul/types_test.go
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright 2017 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package istanbul
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestViewCompare(t *testing.T) {
|
||||||
|
// test equality
|
||||||
|
srvView := &View{
|
||||||
|
Sequence: big.NewInt(2),
|
||||||
|
Round: big.NewInt(1),
|
||||||
|
}
|
||||||
|
tarView := &View{
|
||||||
|
Sequence: big.NewInt(2),
|
||||||
|
Round: big.NewInt(1),
|
||||||
|
}
|
||||||
|
if r := srvView.Cmp(tarView); r != 0 {
|
||||||
|
t.Errorf("source(%v) should be equal to target(%v): have %v, want %v", srvView, tarView, r, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test larger Sequence
|
||||||
|
tarView = &View{
|
||||||
|
Sequence: big.NewInt(1),
|
||||||
|
Round: big.NewInt(1),
|
||||||
|
}
|
||||||
|
if r := srvView.Cmp(tarView); r != 1 {
|
||||||
|
t.Errorf("source(%v) should be larger than target(%v): have %v, want %v", srvView, tarView, r, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test larger Round
|
||||||
|
tarView = &View{
|
||||||
|
Sequence: big.NewInt(2),
|
||||||
|
Round: big.NewInt(0),
|
||||||
|
}
|
||||||
|
if r := srvView.Cmp(tarView); r != 1 {
|
||||||
|
t.Errorf("source(%v) should be larger than target(%v): have %v, want %v", srvView, tarView, r, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test smaller Sequence
|
||||||
|
tarView = &View{
|
||||||
|
Sequence: big.NewInt(3),
|
||||||
|
Round: big.NewInt(1),
|
||||||
|
}
|
||||||
|
if r := srvView.Cmp(tarView); r != -1 {
|
||||||
|
t.Errorf("source(%v) should be smaller than target(%v): have %v, want %v", srvView, tarView, r, -1)
|
||||||
|
}
|
||||||
|
tarView = &View{
|
||||||
|
Sequence: big.NewInt(2),
|
||||||
|
Round: big.NewInt(2),
|
||||||
|
}
|
||||||
|
if r := srvView.Cmp(tarView); r != -1 {
|
||||||
|
t.Errorf("source(%v) should be smaller than target(%v): have %v, want %v", srvView, tarView, r, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
60
consensus/istanbul/utils.go
Normal file
60
consensus/istanbul/utils.go
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright 2017 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package istanbul
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RLPHash(v interface{}) (h common.Hash) {
|
||||||
|
hw := sha3.NewKeccak256()
|
||||||
|
rlp.Encode(hw, v)
|
||||||
|
hw.Sum(h[:0])
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSignatureAddress gets the signer address from the signature
|
||||||
|
func GetSignatureAddress(data []byte, sig []byte) (common.Address, error) {
|
||||||
|
// 1. Keccak data
|
||||||
|
hashData := crypto.Keccak256(data)
|
||||||
|
// 2. Recover public key
|
||||||
|
pubkey, err := crypto.SigToPub(hashData, sig)
|
||||||
|
if err != nil {
|
||||||
|
return common.Address{}, err
|
||||||
|
}
|
||||||
|
return crypto.PubkeyToAddress(*pubkey), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckValidatorSignature(valSet ValidatorSet, data []byte, sig []byte) (common.Address, error) {
|
||||||
|
// 1. Get signature address
|
||||||
|
signer, err := GetSignatureAddress(data, sig)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to get signer address", "err", err)
|
||||||
|
return common.Address{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Check validator
|
||||||
|
if _, val := valSet.GetByAddress(signer); val != nil {
|
||||||
|
return val.Address(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return common.Address{}, ErrUnauthorizedAddress
|
||||||
|
}
|
||||||
80
consensus/istanbul/validator.go
Normal file
80
consensus/istanbul/validator.go
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright 2017 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package istanbul
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Validator interface {
|
||||||
|
// Address returns address
|
||||||
|
Address() common.Address
|
||||||
|
|
||||||
|
// String representation of Validator
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type Validators []Validator
|
||||||
|
|
||||||
|
func (slice Validators) Len() int {
|
||||||
|
return len(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slice Validators) Less(i, j int) bool {
|
||||||
|
return strings.Compare(slice[i].String(), slice[j].String()) < 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slice Validators) Swap(i, j int) {
|
||||||
|
slice[i], slice[j] = slice[j], slice[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type ValidatorSet interface {
|
||||||
|
// Calculate the proposer
|
||||||
|
CalcProposer(lastProposer common.Address, round uint64)
|
||||||
|
// Return the validator size
|
||||||
|
Size() int
|
||||||
|
// Return the validator array
|
||||||
|
List() []Validator
|
||||||
|
// Get validator by index
|
||||||
|
GetByIndex(i uint64) Validator
|
||||||
|
// Get validator by given address
|
||||||
|
GetByAddress(addr common.Address) (int, Validator)
|
||||||
|
// Get current proposer
|
||||||
|
GetProposer() Validator
|
||||||
|
// Check whether the validator with given address is a proposer
|
||||||
|
IsProposer(address common.Address) bool
|
||||||
|
// Add validator
|
||||||
|
AddValidator(address common.Address) bool
|
||||||
|
// Remove validator
|
||||||
|
RemoveValidator(address common.Address) bool
|
||||||
|
// Copy validator set
|
||||||
|
Copy() ValidatorSet
|
||||||
|
// Get the maximum number of faulty nodes
|
||||||
|
F() int
|
||||||
|
// Get proposer policy
|
||||||
|
Policy() ProposerPolicy
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type ProposalSelector func(ValidatorSet, common.Address, uint64) Validator
|
||||||
Loading…
Reference in a new issue