Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Commit

Permalink
IBFT 2.0 (#650)
Browse files Browse the repository at this point in the history
* Remove v1 code

* Add skelton code of syncer v2

* Add PeerHeap in syncer package

* Fix build error

* Separate syncer and gRPC client to improve extensibility

* Remove NotifyStatus RPC call and add gossip

* Removed UpdateLatestBlock from IBFT

* Add retry mechanism in bulk sync

* Remove peer that failed to sync in bulk sync

* Add ID in gossip handler & remove peer from map on disconnection in syncer

* Add timeout in GettingStatuses

* Remove error check from stream.Recv

* Rename method

* Fix lint error

* Fix minor issue

* Subscribe connected event in syncer

* Clean up code

* Rename Status to SyncPeerStatus in proto

* Fix wrong order of checks in syncer

* Fix peerID type in syncer

* Fix build error

* Rename method in syncer

* Fix key in PeerMap of Syncer package

* Fix start progression in BulkSync

* Remove GetBlock from SyncPeerService

* Filter peer event in syncPeerClient

* Fix peer.ID conversion

* Fix lint error

* Feature/sync v2 watch sync implementation (#598)

* implement watchSync

* Fix some linter errors and resolve conflicts

* Rename newStatus channel

* wait for a new status on end watch sync

* Add guard to check ih bestPeer is not nil

* Rename isValidator to match module encapsulation

* Call watchSync on every newStatus

* Close stream after featching blocks

* Fix linter issues

* Syncer V2 Unit Tests (#605)

* implement watchSync

* Fix some linter errors and resolve conflicts

* Fix current failed tests

* Add mocks for sycer tests

* Add syncer unit tests

* Add PeerMap unit test

* Add SyncPeerService unit test

* Fix mockBlockchain in syncer

* Add bufcon in vendor

* Add client unittests in syncer

* Rename newStatus channel

* wait for a new status on end watch sync

* Add guard to check ih bestPeer is not nil

* Rename isValidator to match module encapsulation

* Call watchSync on every newStatus

* Add TestPeerConnectionUpdateEventCh

* Add unit tests for GetBlocks of SyncPeerClient

* Fix failed test

* Fix lint error

* Close stream after featching blocks

* Fix linter issues

* Fix failed tests

Co-authored-by: AleksaOpacic <[email protected]>

* Remove GetBlock from gRPC in syncer

* Rename logger name

* Add more logs revert later

* Add more logs revert later

* Fix initialization of sync.Mutex

* Fix codes based on reviews

* Add comments in Syncer

* Add syncer close

* Add timeout per block in GetBlocks

* Fix lint error

* Add comments in syncer

* Remove nolint

* fix linter issues

* Add comment in protoc

* add todo

* indentation

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* remove todo

* rename symbol

* add todo

* add todo

* add todo

* add todo

* add todo

* add todo

* rename package: backend

* rename interface

* rename struct

* rename file

* rename field

* reorder fields

* reorder func

* init syncer field in ctor

* remove description

* add stub file: backend_dummy.go

* add todo

* write BuildProposal

* write ID

* write MaxFaultyNodes

* add field currentValidatorset to Ibft

* write Quorum/MaxFaultyNodes

* add todo

* add Verifier impl/IsValidBlock

* write IsProposer

* write IsValidProposalHash

* write IsValidCommittedSeal

* add todo

* import go-ibft

* add todo

* add todo

* implement MessageCOnstructor interface

* implement IsValidSender

* implement InsertBlock

* add todo

* add todo

* add consensus field (go-ibft)

* add new start method

* add RunSequence in start method

* update currentValidatorSet on init

* update currentValidatorSet when processing headers

* block time based transaciton execution

* setup transport protocol with new ibft

* gossip protoIBFT messages

* rewire logic for new consensus

* working impl

* add cache to snapshot store and rewrite ibft start method

* refactor consensus into separate struct

* cleanup

* clean up verifier.go

* remove todo

* clean up ibft wrapper

* clean up messages.go

* cleanup

* clean up package

* upgrade buildPrePrepareMessage

* upgrade buildPrepareMessage

* upgrade BuildCommitMessage

* upgrade buildRoundChangeMessage

* remove log

* improve log

* update interface signature

* remove backend logger name

* Cleanup after package import

* Revise the test server ready condition

* Resolve commit message seal issue

* Resolve failing E2E tests

* Provide backwards compatibility with the legacy seals

* Resolve linting errors

* Add source for dev consensus

* Add constant for restore

* Add constant for the syncer

* Drop BulkSync

* Add error log for block building

* Upgrade the go-ibft package version

* Add filter for stale insertion events

* Merge

* Add signer extraction in the txpool

* Remove unused hooks

* Deprecate legacy round timeout flag

Co-authored-by: kourin <[email protected]>
Co-authored-by: OpacicAleksa <[email protected]>
Co-authored-by: Milos Zivkovic <[email protected]>
  • Loading branch information
4 people authored Aug 3, 2022
1 parent 31f8abc commit 39a6abd
Show file tree
Hide file tree
Showing 81 changed files with 4,691 additions and 4,957 deletions.
8 changes: 6 additions & 2 deletions archive/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ import (
"github.com/0xPolygon/polygon-edge/types"
)

const (
restore = "restore"
)

type blockchainInterface interface {
SubscribeEvents() blockchain.Subscription
Genesis() types.Hash
GetBlockByNumber(uint64, bool) (*types.Block, bool)
GetHashByNumber(uint64) types.Hash
WriteBlock(*types.Block) error
WriteBlock(*types.Block, string) error
VerifyFinalizedBlock(*types.Block) error
}

Expand Down Expand Up @@ -78,7 +82,7 @@ func importBlocks(chain blockchainInterface, blockStream *blockStream, progressi
return err
}

if err := chain.WriteBlock(nextBlock); err != nil {
if err := chain.WriteBlock(nextBlock, restore); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion archive/restore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (m *mockChain) GetHashByNumber(num uint64) types.Hash {
return b.Hash()
}

func (m *mockChain) WriteBlock(block *types.Block) error {
func (m *mockChain) WriteBlock(block *types.Block, _ string) error {
m.blocks = append(m.blocks, block)

return nil
Expand Down
26 changes: 15 additions & 11 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ type Blockchain struct {
stream *eventStream // Event subscriptions

gpAverage *gasPriceAverage // A reference to the average gas price

writeLock sync.Mutex
}

// gasPriceAverage keeps track of the average gas price (rolling average)
Expand All @@ -88,6 +90,7 @@ type Verifier interface {
PreStateCommit(header *types.Header, txn *state.Transition) error
}

// TODO: this should be part of Verifier (consensus)
type Executor interface {
ProcessBlock(parentRoot types.Hash, block *types.Block, blockCreator types.Address) (*state.Transition, error)
}
Expand Down Expand Up @@ -859,15 +862,15 @@ func (b *Blockchain) executeBlockTransactions(block *types.Block) (*BlockResult,

// WriteBlock writes a single block to the local blockchain.
// It doesn't do any kind of verification, only commits the block to the DB
func (b *Blockchain) WriteBlock(block *types.Block) error {
// Log the information
b.logger.Info(
"write block",
"num",
block.Number(),
"parent",
block.ParentHash(),
)
func (b *Blockchain) WriteBlock(block *types.Block, source string) error {
b.writeLock.Lock()
defer b.writeLock.Unlock()

if block.Number() <= b.Header().Number {
b.logger.Info("block already inserted", "block", block.Number(), "source", source)

return nil
}

header := block.Header

Expand All @@ -876,7 +879,7 @@ func (b *Blockchain) WriteBlock(block *types.Block) error {
}

// Write the header to the chain
evnt := &Event{}
evnt := &Event{Source: source}
if err := b.writeHeaderImpl(evnt, header); err != nil {
return err
}
Expand Down Expand Up @@ -906,8 +909,9 @@ func (b *Blockchain) WriteBlock(block *types.Block) error {

logArgs := []interface{}{
"number", header.Number,
"txs", len(block.Transactions),
"hash", header.Hash,
"txns", len(block.Transactions),
"parent", header.ParentHash,
}

if prevHeader, ok := b.GetHeaderByNumber(header.Number - 1); ok {
Expand Down
6 changes: 0 additions & 6 deletions blockchain/storage/testing.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package storage

import (
"fmt"
"math/big"
"reflect"
"testing"
Expand Down Expand Up @@ -416,11 +415,6 @@ func testWriteCanonicalHeader(t *testing.T, m PlaceholderStorage) {
assert.NoError(t, err)

if !reflect.DeepEqual(h, hh) {
fmt.Println("-- valid --")
fmt.Println(h)
fmt.Println("-- found --")
fmt.Println(hh)

t.Fatal("bad header")
}

Expand Down
1 change: 0 additions & 1 deletion command/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package genesis

import (
"fmt"

"github.com/0xPolygon/polygon-edge/command"
"github.com/0xPolygon/polygon-edge/command/helper"
"github.com/0xPolygon/polygon-edge/consensus/ibft"
Expand Down
2 changes: 1 addition & 1 deletion command/genesis/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (p *genesisParams) initIBFTExtraData() {

ibftExtra := &ibft.IstanbulExtra{
Validators: p.ibftValidators,
Seal: []byte{},
ProposerSeal: []byte{},
CommittedSeal: [][]byte{},
}

Expand Down
2 changes: 1 addition & 1 deletion command/ibft/propose/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package propose
import (
"context"
"errors"
ibftOp "github.com/0xPolygon/polygon-edge/consensus/ibft/proto"

"github.com/0xPolygon/polygon-edge/command"
"github.com/0xPolygon/polygon-edge/command/helper"
ibftOp "github.com/0xPolygon/polygon-edge/consensus/ibft/proto"
"github.com/0xPolygon/polygon-edge/types"
)

Expand Down
11 changes: 3 additions & 8 deletions command/server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ type Config struct {
LogLevel string `json:"log_level" yaml:"log_level"`
RestoreFile string `json:"restore_file" yaml:"restore_file"`
BlockTime uint64 `json:"block_time_s" yaml:"block_time_s"`
IBFTBaseTimeout uint64 `json:"ibft_base_time_s" yaml:"ibft_base_time_s"`
Headers *Headers `json:"headers" yaml:"headers"`
LogFilePath string `json:"log_to" yaml:"log_to"`
JSONRPCBatchRequestLimit uint64 `json:"json_rpc_batch_request_limit" yaml:"json_rpc_batch_request_limit"`
Expand Down Expand Up @@ -65,9 +64,6 @@ const (
// minimum block generation time in seconds
DefaultBlockTime uint64 = 2

// IBFT timeout in seconds
DefaultIBFTBaseTimeout uint64 = 10

// Multiplier to get IBFT timeout from block time
// timeout is calculated when IBFT timeout is not specified
BlockTimeMultiplierForTimeout uint64 = 5
Expand Down Expand Up @@ -103,10 +99,9 @@ func DefaultConfig() *Config {
PriceLimit: 0,
MaxSlots: 4096,
},
LogLevel: "INFO",
RestoreFile: "",
BlockTime: DefaultBlockTime,
IBFTBaseTimeout: DefaultIBFTBaseTimeout,
LogLevel: "INFO",
RestoreFile: "",
BlockTime: DefaultBlockTime,
Headers: &Headers{
AccessControlAllowOrigins: []string{"*"},
},
Expand Down
20 changes: 0 additions & 20 deletions command/server/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (

var (
errInvalidBlockTime = errors.New("invalid block time specified")
errWrongIBFTBaseTimeout = errors.New("IBFT base timeout needs to be higher than block time")
errDataDirectoryUndefined = errors.New("data directory not defined")
)

Expand Down Expand Up @@ -55,10 +54,6 @@ func (p *serverParams) initRawParams() error {
return err
}

if err := p.initIBFTBaseTimeout(); err != nil {
return err
}

if p.isDevMode {
p.initDevMode()
}
Expand All @@ -77,21 +72,6 @@ func (p *serverParams) initBlockTime() error {
return nil
}

func (p *serverParams) initIBFTBaseTimeout() error {
if p.rawConfig.IBFTBaseTimeout == 0 {
// Calculate from block time
p.rawConfig.IBFTBaseTimeout = p.rawConfig.BlockTime * config.BlockTimeMultiplierForTimeout

return nil
}

if p.rawConfig.IBFTBaseTimeout <= p.rawConfig.BlockTime {
return errWrongIBFTBaseTimeout
}

return nil
}

func (p *serverParams) initDataDirLocation() error {
if p.rawConfig.DataDir == "" {
return errDataDirectoryUndefined
Expand Down
28 changes: 17 additions & 11 deletions command/server/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,18 @@ const (
secretsConfigFlag = "secrets-config"
restoreFlag = "restore"
blockTimeFlag = "block-time"
ibftBaseTimeoutFlag = "ibft-base-timeout"
devIntervalFlag = "dev-interval"
devFlag = "dev"
corsOriginFlag = "access-control-allow-origins"
logFileLocationFlag = "log-to"
)

// Flags that are deprecated, but need to be preserved for
// backwards compatibility with existing scripts
const (
ibftBaseTimeoutFlagLEGACY = "ibft-base-timeout"
)

const (
unsetPeersValue = -1
)
Expand Down Expand Up @@ -78,6 +83,8 @@ type serverParams struct {
jsonRPCBatchLengthLimit uint64
jsonRPCBlockRangeLimit uint64

ibftBaseTimeoutLegacy uint64

genesisConfig *chain.Chain
secretsConfig *secrets.SecretsManagerConfig

Expand Down Expand Up @@ -158,15 +165,14 @@ func (p *serverParams) generateConfig() *server.Config {
MaxOutboundPeers: p.rawConfig.Network.MaxOutboundPeers,
Chain: p.genesisConfig,
},
DataDir: p.rawConfig.DataDir,
Seal: p.rawConfig.ShouldSeal,
PriceLimit: p.rawConfig.TxPool.PriceLimit,
MaxSlots: p.rawConfig.TxPool.MaxSlots,
SecretsManager: p.secretsConfig,
RestoreFile: p.getRestoreFilePath(),
BlockTime: p.rawConfig.BlockTime,
IBFTBaseTimeout: p.rawConfig.IBFTBaseTimeout,
LogLevel: hclog.LevelFromString(p.rawConfig.LogLevel),
LogFilePath: p.logFileLocation,
DataDir: p.rawConfig.DataDir,
Seal: p.rawConfig.ShouldSeal,
PriceLimit: p.rawConfig.TxPool.PriceLimit,
MaxSlots: p.rawConfig.TxPool.MaxSlots,
SecretsManager: p.secretsConfig,
RestoreFile: p.getRestoreFilePath(),
BlockTime: p.rawConfig.BlockTime,
LogLevel: hclog.LevelFromString(p.rawConfig.LogLevel),
LogFilePath: p.logFileLocation,
}
}
26 changes: 15 additions & 11 deletions command/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,17 +186,6 @@ func setFlags(cmd *cobra.Command) {
"minimum block time in seconds (at least 1s)",
)

cmd.Flags().Uint64Var(
&params.rawConfig.IBFTBaseTimeout,
ibftBaseTimeoutFlag,
// Calculate from block time if it is not given
0,
fmt.Sprintf(
"base IBFT timeout in seconds, it needs to be larger than block time. (block time * %d) is set if it's zero",
config.BlockTimeMultiplierForTimeout,
),
)

cmd.Flags().StringArrayVar(
&params.corsAllowedOrigins,
corsOriginFlag,
Expand Down Expand Up @@ -226,9 +215,24 @@ func setFlags(cmd *cobra.Command) {
"write all logs to the file at specified location instead of writing them to console",
)

setLegacyFlags(cmd)
setDevFlags(cmd)
}

// setLegacyFlags sets the legacy flags to preserve backwards compatibility
// with running partners
func setLegacyFlags(cmd *cobra.Command) {
// Legacy IBFT base timeout flag
cmd.Flags().Uint64Var(
&params.ibftBaseTimeoutLegacy,
ibftBaseTimeoutFlagLEGACY,
0,
"",
)

_ = cmd.Flags().MarkHidden(ibftBaseTimeoutFlagLEGACY)
}

func setDevFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(
&params.isDevMode,
Expand Down
37 changes: 17 additions & 20 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,36 +46,33 @@ type Consensus interface {

// Config is the configuration for the consensus
type Config struct {
// Logger to be used by the backend
// Logger to be used by the consensus
Logger *log.Logger

// Params are the params of the chain and the consensus
Params *chain.Params

// Config defines specific configuration parameters for the backend
// Config defines specific configuration parameters for the consensus
Config map[string]interface{}

// Path is the directory path for the consensus protocol tos tore information
Path string
}

type ConsensusParams struct {
Context context.Context
Seal bool
Config *Config
Txpool *txpool.TxPool
Network *network.Server
Blockchain *blockchain.Blockchain
Executor *state.Executor
Grpc *grpc.Server
Logger hclog.Logger
Metrics *Metrics
SecretsManager secrets.SecretsManager
BlockTime uint64
IBFTBaseTimeout uint64
type Params struct {
Context context.Context
Seal bool
Config *Config
TxPool *txpool.TxPool
Network *network.Server
Blockchain *blockchain.Blockchain
Executor *state.Executor
Grpc *grpc.Server
Logger hclog.Logger
Metrics *Metrics
SecretsManager secrets.SecretsManager
BlockTime uint64
}

// Factory is the factory function to create a discovery backend
type Factory func(
*ConsensusParams,
) (Consensus, error)
// Factory is the factory function to create a discovery consensus
type Factory func(*Params) (Consensus, error)
Loading

0 comments on commit 39a6abd

Please sign in to comment.