From 8d9d0c5fe175c8f6511f3f9d4d669cb178c64243 Mon Sep 17 00:00:00 2001 From: Yoav Tock Date: Wed, 21 Feb 2024 15:13:30 +0200 Subject: [PATCH] Switch by replication policy Signed-off-by: Yoav Tock Change-Id: Iaecd27c0295748f94947f5af94a7385ca455f245 --- orderer/common/localconfig/config.go | 4 ++ orderer/common/localconfig/config_test.go | 1 + orderer/consensus/smartbft/chain.go | 55 ++++++++++++++++------- sampleconfig/orderer.yaml | 6 +++ 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/orderer/common/localconfig/config.go b/orderer/common/localconfig/config.go index 649f2e3a7b2..120ffd0d77b 100644 --- a/orderer/common/localconfig/config.go +++ b/orderer/common/localconfig/config.go @@ -68,6 +68,7 @@ type Cluster struct { ReplicationPullTimeout time.Duration ReplicationRetryTimeout time.Duration ReplicationMaxRetries int + ReplicationPolicy string // BFT: "simple" | "consensus" (default); etcdraft: ignored, always "simple" SendBufferSize int CertExpirationWarningThreshold time.Duration TLSHandshakeTimeShift time.Duration @@ -188,6 +189,7 @@ var Defaults = TopLevel{ ReplicationRetryTimeout: time.Second * 5, ReplicationPullTimeout: time.Second * 5, CertExpirationWarningThreshold: time.Hour * 24 * 7, + ReplicationPolicy: "consensus", // BFT default; on etcdraft it is ignored }, LocalMSPDir: "msp", LocalMSPID: "SampleOrg", @@ -332,6 +334,8 @@ func (c *TopLevel) completeInitialization(configDir string) { c.General.Cluster.ReplicationRetryTimeout = Defaults.General.Cluster.ReplicationRetryTimeout case c.General.Cluster.CertExpirationWarningThreshold == 0: c.General.Cluster.CertExpirationWarningThreshold = Defaults.General.Cluster.CertExpirationWarningThreshold + case c.General.Cluster.ReplicationPolicy == "": + c.General.Cluster.ReplicationPolicy = Defaults.General.Cluster.ReplicationPolicy case c.General.Profile.Enabled && c.General.Profile.Address == "": logger.Infof("Profiling enabled and General.Profile.Address unset, setting to %s", Defaults.General.Profile.Address) diff --git a/orderer/common/localconfig/config_test.go b/orderer/common/localconfig/config_test.go index 62d924dc8f9..1efb226743f 100644 --- a/orderer/common/localconfig/config_test.go +++ b/orderer/common/localconfig/config_test.go @@ -165,6 +165,7 @@ func TestClusterDefaults(t *testing.T) { cfg, err := cc.load() require.NoError(t, err) require.Equal(t, cfg.General.Cluster.ReplicationMaxRetries, Defaults.General.Cluster.ReplicationMaxRetries) + require.Equal(t, cfg.General.Cluster.ReplicationPolicy, Defaults.General.Cluster.ReplicationPolicy) } func TestConsensusConfig(t *testing.T) { diff --git a/orderer/consensus/smartbft/chain.go b/orderer/consensus/smartbft/chain.go index 72b3ad3a161..133103fbf11 100644 --- a/orderer/consensus/smartbft/chain.go +++ b/orderer/consensus/smartbft/chain.go @@ -209,22 +209,45 @@ func bftSmartConsensusBuild( // report cluster size c.Metrics.ClusterSize.Set(float64(clusterSize)) - sync := &Synchronizer{ // TODO make bft-synchro - selfID: rtc.id, - BlockToDecision: c.blockToDecision, - OnCommit: func(block *cb.Block) types.Reconfig { - c.pruneCommittedRequests(block) - return c.updateRuntimeConfig(block) - }, - Support: c.support, - BlockPuller: c.BlockPuller, - - ClusterSize: clusterSize, // TODO this must be dynamic as the cluster may change in size - Logger: c.Logger, - LatestConfig: func() (types.Configuration, []uint64) { - rtc := c.RuntimeConfig.Load().(RuntimeConfig) - return rtc.BFTConfig, rtc.Nodes - }, + var sync api.Synchronizer + switch c.localConfigCluster.ReplicationPolicy { + case "consensus": + sync = &Synchronizer{ // TODO make bft-synchronizer + selfID: rtc.id, + BlockToDecision: c.blockToDecision, + OnCommit: func(block *cb.Block) types.Reconfig { + c.pruneCommittedRequests(block) + return c.updateRuntimeConfig(block) + }, + Support: c.support, + BlockPuller: c.BlockPuller, + ClusterSize: clusterSize, + Logger: c.Logger, + LatestConfig: func() (types.Configuration, []uint64) { + rtc := c.RuntimeConfig.Load().(RuntimeConfig) + return rtc.BFTConfig, rtc.Nodes + }, + } + case "simple": + sync = &Synchronizer{ + selfID: rtc.id, + BlockToDecision: c.blockToDecision, + OnCommit: func(block *cb.Block) types.Reconfig { + c.pruneCommittedRequests(block) + return c.updateRuntimeConfig(block) + }, + Support: c.support, + BlockPuller: c.BlockPuller, + + ClusterSize: clusterSize, // TODO this must be dynamic as the cluster may change in size + Logger: c.Logger, + LatestConfig: func() (types.Configuration, []uint64) { + rtc := c.RuntimeConfig.Load().(RuntimeConfig) + return rtc.BFTConfig, rtc.Nodes + }, + } + default: + } channelDecorator := zap.String("channel", c.support.ChannelID()) diff --git a/sampleconfig/orderer.yaml b/sampleconfig/orderer.yaml index ee3ae31af41..36f70aa2a80 100644 --- a/sampleconfig/orderer.yaml +++ b/sampleconfig/orderer.yaml @@ -115,6 +115,12 @@ General: # ServerPrivateKey defines the file location of the private key of the TLS certificate. ServerPrivateKey: + # ReplicationPolicy defines how blocks are replicated between orderers. + # Permitted values: + # in BFT: "simple" | "consensus" (default); + # in etcdraft: ignored, (always "simple", regardless of value in config). + ReplicationPolicy: + # Bootstrap method: The method by which to obtain the bootstrap block # system channel is specified. The option can be one of: # "file" - path to a file containing the genesis block or config block of system channel